You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
payjoin-mailroom: let relay operators accept OHTTP gateway purposes other than BIP77 #2024
Please describe the feature you'd like to see added.
A config option for the OHTTP relay in payjoin-mailroom that lists the
gateway purposes the operator accepts, in addition to BIP77. For example:
[ohttp_relay]
# BIP77 is always accepted. Operators may opt in to other purposes.extra_allowed_purposes = ["LanternZero v0 4bca76ac-1094-4330-97df-03d5c81b576d"]
The prober would treat a gateway as allowed if its /.well-known/ohttp-gateway?allowed_purposes response lists any configured
purpose. Today it checks only MAGIC_BIP77_PURPOSE
(ohttp_relay/gateway_prober.rs).
Is your feature related to a problem, if so please describe it.
We're building Lantern Zero, an open-source (MIT/Apache-2.0) service that
gives Zcash wallets faster sync and payment notifications. All wallet
requests go over OHTTP through relays run by third parties: Zcash community
organizations, never the server operator.
We'd like those operators to run your relay rather than a new one we write.
It already has the hardening we'd otherwise have to reimplement: metadata
side-channel work (#1421), Retry-After handling in the prober (#1475), and
relay selection (#1514). The purpose check means it won't forward to our
gateway, and we don't want to claim the BIP77 purpose to get around that.
Describe the solution you'd like
Keep the opt-in model from [👣 TRACKING] Specify OHTTP relay <-> directory opt-in mechanism #472 as it is. The relay still forwards only to
gateways that declare a purpose, and only to purposes the operator chose.
BIP77 stays the default, so existing deployments don't change.
Replace Policy { bip77_allowed } with a check against the configured set.
We're happy to write the PR, with tests.
Optional, could be a separate issue: a way to run the relay without the
directory, for operators who only want to relay.
This also has an upside for Payjoin. A relay that carries more than one
protocol mixes their traffic, which gives each protocol's users a larger
crowd to hide in.
Describe any alternatives you've considered
Claiming the BIP77 purpose on our gateway: rejected. It would misuse
relay operators' consent.
Writing our own relay: workable, but it duplicates security-sensitive
code that you already maintain.
Forking payjoin-mailroom: the same duplication, with a maintenance
burden on top.
How did you find this option? I'm not opposed to it in principle. Is completely different OHTTP Gateway infrastructure required and this just uses the relay? or does this proposal use mailboxes too?
How we found it: we were looking for an open-source OHTTP relay that Zcash community organizations could run. payjoin/ohttp-relay was the obvious Rust option. We saw it had been archived and moved into payjoin-mailroom, and while reading the code we found the opt-in check from #472 in ohttp_relay/gateway_prober.rs.
Yes, the gateway is completely separate, and we only want the relay. Each Lantern Zero server runs its own RFC 9458 gateway at its origin root, the same layout the relay already expects:
GET /.well-known/ohttp-gateway: key configuration (RFC 9540)
GET /.well-known/ohttp-gateway?allowed_purposes: application/x-ohttp-allowed-purposes, in the u16-count format parse_alpn_encoded reads, listing only LanternZero v0 4bca76ac-1094-4330-97df-03d5c81b576d
POST /.well-known/ohttp-gateway: encapsulated requests
Wallets would POST to https://<relay>/https://<lantern-zero-host>, exactly as BIP77 clients do today.
No mailboxes and no directory. Lantern Zero is plain request and response between a wallet and its own server. For live updates the wallet long-polls its server for 25–30 s. That's the same shape as a BIP77 receiver polling a mailbox through the relay. Mailroom always starts the directory alongside the relay today, which is why we listed a relay-only mode as an optional follow-up.
Number of gateways: small. There's one per hosted or wallet-sponsored server. Self-hosted servers mostly use a Tor onion service instead of OHTTP, so we don't expect relays to probe many origins.
One question back: we have wallets fetch the key configuration through two different relays and compare the copies before using it. With mailroom, that would go through the CONNECT bootstrap tunnel, which also passes the purpose check. Is that tunnel fine for other protocols to use, and do you expect it to stay on by default?
A correction to the issue: I listed relay selection (#1514) as something the relay already has. It's an open PR for client-side selection, so it isn't a reason by itself. #1421 and #1475 are the relay hardening I meant.
If this works for you, I'm happy to open a PR. It would add a configured set of accepted purposes to RelayConfig, with BIP77 always included, and have the prober and parse_gateway_uri check against that set instead of Policy { bip77_allowed }. Tests would cover a non-BIP77 opt-in and the existing BIP77-only behavior. Do you have a preferred config shape, or should I follow the TOML in the issue?
Activity
DanGould commentedon Oct 31, 2026
How did you find this option? I'm not opposed to it in principle. Is completely different OHTTP Gateway infrastructure required and this just uses the relay? or does this proposal use mailboxes too?
gf5901 commentedon Oct 31, 2026
Thanks, Dan.
How we found it: we were looking for an open-source OHTTP relay that Zcash community organizations could run.
payjoin/ohttp-relaywas the obvious Rust option. We saw it had been archived and moved intopayjoin-mailroom, and while reading the code we found the opt-in check from #472 inohttp_relay/gateway_prober.rs.Yes, the gateway is completely separate, and we only want the relay. Each Lantern Zero server runs its own RFC 9458 gateway at its origin root, the same layout the relay already expects:
GET /.well-known/ohttp-gateway: key configuration (RFC 9540)GET /.well-known/ohttp-gateway?allowed_purposes:application/x-ohttp-allowed-purposes, in the u16-count formatparse_alpn_encodedreads, listing onlyLanternZero v0 4bca76ac-1094-4330-97df-03d5c81b576dPOST /.well-known/ohttp-gateway: encapsulated requestsWallets would POST to
https://<relay>/https://<lantern-zero-host>, exactly as BIP77 clients do today.No mailboxes and no directory. Lantern Zero is plain request and response between a wallet and its own server. For live updates the wallet long-polls its server for 25–30 s. That's the same shape as a BIP77 receiver polling a mailbox through the relay. Mailroom always starts the directory alongside the relay today, which is why we listed a relay-only mode as an optional follow-up.
Number of gateways: small. There's one per hosted or wallet-sponsored server. Self-hosted servers mostly use a Tor onion service instead of OHTTP, so we don't expect relays to probe many origins.
One question back: we have wallets fetch the key configuration through two different relays and compare the copies before using it. With mailroom, that would go through the
CONNECTbootstrap tunnel, which also passes the purpose check. Is that tunnel fine for other protocols to use, and do you expect it to stay on by default?A correction to the issue: I listed relay selection (#1514) as something the relay already has. It's an open PR for client-side selection, so it isn't a reason by itself. #1421 and #1475 are the relay hardening I meant.
If this works for you, I'm happy to open a PR. It would add a configured set of accepted purposes to
RelayConfig, with BIP77 always included, and have the prober andparse_gateway_uricheck against that set instead ofPolicy { bip77_allowed }. Tests would cover a non-BIP77 opt-in and the existing BIP77-only behavior. Do you have a preferred config shape, or should I follow the TOML in the issue?