Payjoin

A payjoin is a payment both sides put coins into. On-chain it looks like any other transaction, but it breaks the assumption chain analysis relies on most: that every input belongs to the payer. Fully Noded can pay payjoin invoices, and receive payjoins straight from your phone over Tor.

🧪 New. Payjoin (BIP78) is new in Fully Noded. Try it with small amounts first. If anything goes wrong, the normal payment goes through instead: a payjoin never blocks a payment.

Why it matters

  • Breaks clustering. Chain analysis assumes all of a transaction’s inputs belong to one person. In a payjoin, one of them is the receiver’s, so that assumption is wrong for every payjoin, and nobody can tell which transactions are payjoins.
  • Hides the amount. The receiver’s coin is added to their output, so the output’s value is no longer the amount paid.
  • Free consolidation. The receiver merges one of their coins into the payment without paying for a separate transaction.
  • No coordinator. Just the two of you: no server in the middle, no fees to anyone.

How it works

Payer                                          Receiver (your phone)
  1. signs a normal payment  ──over Tor──▶   2. checks it with their node
                                                adds one of their coins
  4. checks the proposal,     ◀──────────    3. signs only their coin,
     signs only their own coins                 sends the proposal back
  5. broadcasts the payjoin
  1. The receiver shows an invoice with a payjoin endpoint in it (pj= in the payment link). Wallets that don’t know payjoin simply ignore it and pay the address.
  2. The payer signs a normal payment and sends it to that endpoint. It’s a fully valid transaction: if the receiver never answers, it’s simply broadcast.
  3. The receiver adds one of their coins, signs only that coin and sends the proposal back.
  4. The payer checks the proposal against BIP78’s rules, signs only their own coins and broadcasts.

Receive a payjoin

On your wallet’s Receive screen, pick the Payjoin tab under Receive to. Fully Noded then:

  • starts a small payjoin listener inside the app, on this phone only,
  • asks Tor for a one-time onion address for it (the key is thrown away, so the address can never be reused or linked to another invoice),
  • checks its own onion through Tor until it answers, so live means payers really can reach it (usually under a minute).

While it sets up, the QR is hidden: a QR shown before the endpoint is live would just be paid normally. Cancel payjoin goes back to a regular address. Once live, the QR appears with a ⇄ PAYJOIN badge. Keep the screen open until you’re paid; the phone won’t auto-lock meanwhile. Turn on Always open on Payjoin to start every Receive screen this way.

When a payer connects, your node checks their payment (it must pay this invoice, be fully signed and pass testmempoolaccept), and Fully Noded adds a confirmed coin of yours of the same type, at a random position, sized like the payment so it doesn’t stand out. If the payer never broadcasts, a Broadcast the payer’s payment button appears after a couple of minutes.

Pay a payjoin invoice

  1. Scan or paste the payment request. If it offers payjoin, a Payjoin supported card says who the receiver is and whether it goes over Tor. BTCPay Server stores, Fully Noded and other BIP78 wallets all work.
  2. Create the transaction as usual. A ⇄ PAYJOIN INVOICE banner reminds you that signing will ask the receiver to join in.
  3. Sign. Your signed payment is kept as the fallback while a Payjoin screen shows each step live: contacting the receiver, their proposal, every safety check ticking off, signing your own inputs and your node’s mempool test. Skip payjoin, pay normally is there the whole time.
  4. Review and send. A summary shows what changed: inputs before and after, the receiver’s coin, the fee before and after. Nothing is broadcast until you tap Send.

What’s checked

Before you sign the receiver’s proposal, Fully Noded refuses it if anything is off:

  • your inputs and outputs are all still there, in order, with version, locktime and sequences unchanged,
  • the payment still pays the same address at least the same amount (Fully Noded never lets the receiver redirect it),
  • the fee never goes down, and any extra fee taken from your change stays within the limit you set: about one input’s worth at your fee rate,
  • no key paths or partial signatures from the receiver, and their inputs are finalized and of your script type,
  • then only your own inputs are signed, and the result must pass your node’s testmempoolaccept.

Error messages from the receiver are never shown as they are, since they could be used for phishing: only BIP78’s well-known errors, in Fully Noded’s own words.

What you need

  • A single-sig native segwit or Taproot wallet whose signer is on this device. Both sides sign again during the exchange, on the spot, so multisig and watch-only wallets pay and receive normally instead (Fully Noded tells you why).
  • A connection to your node, and Tor for receiving.

Full technical details: Payjoin.md · BIP78.

search previous next tag category expand menu location phone mail time cart zoom edit close