Async Payjoin
Payjoin lets Bitcoin senders and receivers interact to make batched transactions. This document proposes a second, backwards-compatible, asynchronous version of the Payjoin protocol ("Version 2") relative to and described in [BIP 78](bip-0078.mediawiki) ("Version 1"). An untrusted third-party "directory server" replaces the requirement for a receiver to host a secure public endpoint for interactions. HTTP clients access the directory server using an asynchronous protocol and authenticated, encr
No reviewsSpecification
BIP: 77
Layer: Applications
Title: Async Payjoin
Authors: Dan Gould <d@ngould.dev>
Yuval Kogman <nothingmuch@woobling.org>
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0077
Status: Draft
Type: Specification
Assigned: 2023-08-08
License: BSD-2-Clause
Discussion: https://github.com/bitcoin/bips/pull/1483
https://gnusha.org/pi/bitcoindev/7B11AE34-27A7-46ED-95BF-66CA13BA26F3@ngould.dev/#t
https://gnusha.org/pi/bitcoindev/3C0A6E4C-444E-4E75-829C-1A21D8EE40E0@ngould.dev/#t
Version: 0.2.0
Requires: 21, 78, 173, 174
Copyright
This BIP is licensed under the 2-clause BSD license.
Abstract
Payjoin lets Bitcoin senders and receivers interact to make batched transactions.
This document proposes a second, backwards-compatible, asynchronous version of the Payjoin protocol ("Version 2") relative to and described in BIP 78 ("Version 1"). An untrusted third-party "directory server" replaces the requirement for a receiver to host a secure public endpoint for interactions. HTTP clients access the directory server using an asynchronous protocol and authenticated, encrypted payloads. The design preserves complete Payjoin receiver functionality, including payment output substitution. Authenticated encryption depends only on cryptographic primitives available in Bitcoin Core. Requests use Oblivious HTTP (OHTTP) to prevent the directory and other Payjoin clients from linking requests to client IP addresses.
Motivation
Satoshi Nakamoto pointed out one specific privacy risk in the whitepaper, that transactions with multiple inputs "necessarily reveal that their inputs were owned by the same owner." Payjoin addresses that risk, the common-input-ownership heuristic, by making it practical to spend inputs owned by multiple parties in one transaction.
While addressing Bitcoin's primal privacy risk, Payjoin input batching also improves on the widespread non-interactive output batching practice deployed by exchanges. When combined, the same movement of funds can use less block weight and save fees.
A natural application of Payjoin would be to combine getting paid with consolidating UTXOs into one transaction. But Payjoin can also secure transaction cut-through, allowing a sender to transfer funds to a receiver who also transfers funds to a third party in the same transaction. For example, deposits to an exchange may "cut through" in a single transaction that also satisfies withdrawals instead of with a second transaction that spends the deposited funds. Payjoin enables more blockspace-efficient transactions that reduce fees while addressing privacy risks.
However, BIP 78's requirements for Payjoin Version 1 have proven to be an obstacle to adoption. Version 1 receivers must host a secured public-facing HTTP server. Mobile and web environments limit the ability to fulfil such a requirement. Version 1 also requires synchronous communication. Both sender and receiver must be online simultaneously. Wallet developers regard these requirements as barriers to Payjoin adoption.
To address these limitations, our goal is to specify a practical coordination mechanism suitable for widespread implementation. This proposal leverages mature solutions to common problems, building on established web standards and proven Bitcoin primitives.
Overview
A Payjoin sender and receiver interact so that they may both contribute to a transaction. In this proposal, they exchange asynchronous end-to-end encrypted messages by relaying them to a store-and-forward directory server using OHTTP.
Before initiating the protocol, the receiver must secure communications with the directory by bootstrapping.
- The receiver initiates a Payjoin Session by sharing a Payjoin URI that includes the URL of an ephemeral mailbox hosted on the directory, where it can receive a message from the sender.
- The sender posts a message containing a fully signed fallback transaction, known as the Original PSBT, to the mailbox.
- The receiver gets this message and posts a message containing a Proposal PSBT to the sender's ephemeral mailbox, by updating the Original PSBT with appropriate inputs and/or outputs.
- The sender gets the Proposal PSBT, checks it, signs, and broadcasts the final transaction.
At any point, either party may choose to broadcast the fallback transaction described by the Original PSBT instead of proceeding. Because the Original PSBT and Proposal PSBT spend the same input(s) they are mutually exclusive and only one can be confirmed.
Messages are buffered in the directory, allowing both parties to tolerate temporary disconnections and resume communication by polling.
Async Payjoin Directory Mediated Sequence Diagram
+----------+ +------------+ +----------+ +----------+
| Receiver | | Directory | | Sender | | Network |
+----+-----+ +-----+------+ +----+-----+ +----+-----+
| | | |
| Payjoin URI (BIP21), out-of-band | |
+------------------------------------------------>| |
| | | |
| Poll GET: original PSBT (repeat until available) |
+- - - - - - - - - - - ->+ | |
| # POST: original PSBT | |
| #<-----------------------+ |
| 200 OK: original PSBT # | |
|<-----------------------+ | |
| | | |
| | Poll GET: proposal PSBT (repeat until available)
| +<- - - - - - - - - - - -+ |
| POST: proposal PSBT # | |
+-----------------------># | |
| # 200 OK: proposal PSBT | |
| +----------------------->| |
| | | |
| | | Broadcast payjoin |
| | +---------------------->|
| | | |
Specification
OHTTP Bootstrapping
Before initiating a Payjoin Session a receiver must first discover the directory's OHTTP Key Configuration, via an authenticated bootstrap mechanism. The key configuration contains information to establish Hybrid Public Key Encryption (HPKE) in order to secure communications between the client and the directory in lieu of TLS.
The bootstrap mechanism may vary by implementation but must follow OHTTP Consistency Requirements and should not reveal a receiver IP address to the directory. Some examples of suitable mechanisms include getting a key configuration from a Payjoin URI, a trusted application binary, or fetching using https-in-http CONNECT method, https-in-WebSocket, Tor, or a VPN.
Directory OHTTP Gateways MUST support RFC 9540 Key Configuration
Fetching
via GET request. RFC 9540 defines the
gateway location as /.well-known/ohttp-gateway.
Session Initiation
A receiver initiates a session by sharing a Payjoin URI. Because a URI contains sensitive information, such as a receiver address, it should be shared over a confidential channel.
Payjoin URI
Bitcoin URIs (BIP 21 or BIP 321) are a standard way to request bitcoin.
A Payjoin URI is a Bitcoin URI that contains a pj parameter. The pj
parameter value is a URL in both BIP 78 and BIP 77.
Senders that understand Bitcoin URI but don't support Payjoin will just
ignore the pj parameter and proceed to typical address-based
transaction flows.
A req-pj parameter may be used as a BIP 21 forwards compatibility reqparam instead of
pj to signal that Payjoin is required.
The parameter value must be uppercased and the parameter should be placed last in the URI.
Since BIP 78 payloads are neither encrypted nor authenticated,
a directory used for backwards-compatible payloads is known
as an "unsecured payjoin server" in BIP 78
parlance.
Backwards-compatible receivers MUST disable output substitution
by setting pjos=0 to prevent modification by a malicious directory.
Mailbox endpoint
In this proposal the URL in the pj parameter value is the mailbox
endpoint URL. Mailboxes are shared HTTP resources hosted by the
directory and serve as OHTTP Target Resources. Clients use these endpoints
to relay encrypted messages. They POST messages to and GET messages from
mailbox endpoints via OHTTP.
Senders that support BIP 78 but not this proposal may POST messages directly to mailbox endpoints for backwards compatibility.
Short ID
A Short ID identifies a mailbox based on its associated public key. The Short ID is the path component of the mailbox endpoint. One is derived by hashing the 33-byte compressed public key encoding with SHA-256, truncating it to 8 bytes (64 bits), and encoding it in uppercase using the bech32 character set (like a bech32 string without the HRP, separator and checksum).
Receiver fragment parameters
This proposal introduces session-specific parameters which the receiver shares encoded in the URI.
Instead of defining new Bitcoin URI parameters, the session-specific parameters are encoded in the fragment of the mailbox endpoint URL.
The # fragment separator character must be RFC 3986
percent-encoded
as %23, because it separates the
fragment of the mailbox endpoint URL included in the pj parameter, not the
fragment of the Bitcoin URI.
These session-specific parameters use a bech32-inspired encoding.
The HRP is used as the parameter key, followed by the '1' separator,
followed by the parameter value encoded using the bech32 character set in
uppercase. No checksum is used. Parameters are separated
by a - character.
The following parameters are defined, and must be provided in lexicographical order:
EX: specifies a session expiration in unix time.OH: encodes an alternate format of the OHTTP Key Configuration of the directory. It consists of a 33-byte compressed public key of the directory's OHTTP Gateway, prefixed by the 2-byte Key Identifier. A RFC 9458 Key Configuration is reconstructed by assuming the HPKE KEM ID and Symmetric Algorithms are fixed.RK: encodes the receiver key as a 33-byte compressed public key. Senders will initiate HPKE with the receiver using this key.
For example, a properly encoded endpoint Bitcoin URI looks like this
bitcoin:tb1q6q6de88mj8qkg0q5lupmpfexwnqjsr4d2gvx2p?amount=0.00666666&pjos=0&pj=HTTPS://PAYJO.IN/TXJCGKTKXLUUZ%23EX1WKV8CEC-OH1QYPM59NK2LXXS4890SUAXXYT25Z2VAPHP0X7YEYCJXGWAG6UG9ZU6NQ-RK1Q0DJS3VVDXWQQTLQ8022QGXSX7ML9PHZ6EDSF6AKEWQG758JPS2EV
Until 2026 implementations SHOULD also accept + as a fragment parameter
separator and not enforce parameter ordering requirements, for compatibility
with the previous version of this document.
Sender Original PSBT Messaging
The sender constructs the fallback transaction, a typical transaction spending funds to the receiver's address specified in the Payjoin URI. This transaction is serialized as a BIP 174 PSBTv0, satisfying the receiver checklist.
The Original PSBT MUST:
- Include complete UTXO data.
- Be fully signed.
- Exclude unnecessary fields such as global xpubs or keypath information.
- Be broadcastable.
The Original PSBT MAY:
- Include outputs unrelated to the sender-receiver transfer for batching purposes.
This Original PSBT is encoded as base64, followed by the query parameter string on a new line containing optional sender parameters.
The sender generates an ephemeral mailbox key. The corresponding public key is known as the reply key, and it is prepended to the base64 plaintext string, serialized in compressed form as 33 bytes.
This plaintext string is encrypted to the receiver key according to HPKE Base
mode.
The HPKE info string, used for domain separation, is PjV2MsgA. The
ciphertext ensures message secrecy and integrity when passed to the receiver
using the mailbox endpoint. The 16-byte authentication tag is appended to the
ciphertext.
RFC 9180 does not specify the wire format encoding of HPKE messages. To construct an HPKE payload, the secp256k1 public key from the DHKEM is encoded using ElligatorSwift in 64 bytes. Note that ElligatorSwift is only the wire format; when deriving shared secrets, the curve point is re-serialized in uncompressed form.
PjV2MsgA Byte Representation (7168 bytes total)
+---------------------------------------------------------------------------------------+
| ElligatorSwift | Ciphertext |
| (64 bytes) |
[Content truncated — view full spec at source]
Related Specs
Discussion (0 threads)
Loading discussions...