
Full recording. Plays from youtube-nocookie.com. Watch on YouTube
TL;DR
- Privacy keeps Bitcoin free, censorship-resistant and fungible. Without private payments it can be captured like gold.
- PayJoin mixes coins from the sender and the receiver in one transaction that looks completely normal.
- That breaks two chain-analysis guesses: all inputs belong to one person, and the big leftover is the change.
- PayJoin v2 needs no server of your own: a mailbox and a relay pass messages, and neither sees the whole picture.
Highlights
1Why privacy
Why a Privacy Track at all? You wouldn’t post your bank statements online. On Bitcoin, anyone can read your payments and your balance unless you take care. The track opened with three reasons privacy matters.
Why we need privacy
“If we don’t have private payments, Bitcoin as an asset will fail.”
Jeff Booth’s idea, quoted on the call: without private payments it can be captured and centralized like gold
2A real PayJoin, live
12,000 sats that don’t show up on the blockchain. A PayJoin of 12,000 sats from Bull Bitcoin to Cake Wallet was looked up on mempool.space during the call. No output said 12,000. The receiver had added one of their own coins, so the payment was hidden inside the transaction.
The transaction from the call
Where are the 12,000 sats?
Swipe to see the whole diagram →
Chain analysis can’t tell which story is true unless someone tells them. Here the sender did, live on the call.
A second PayJoin was sent to a co-host live at the end, and it arrived. Others on the call said theirs had failed, and figuring out why is on the list for part 2.
3How PayJoin works
The guesses it breaks. Chain analysis usually assumes two things: every input in a transaction belongs to the same person, and the big leftover output is the sender’s change. PayJoin puts a coin from the receiver into the transaction, so both guesses can be wrong. And unlike a CoinJoin, it looks like any normal payment, so it hides in the crowd.
Why it took years to get right. The obvious design is that the sender asks “I want to pay you X” and the receiver offers a coin. But a sender who asks again and again, without ever paying, learns every coin the receiver owns. This is called UTXO snooping. The real protocol fixes it by making the sender commit first:
PayJoin v1, step by step
The sender commits first, so snooping costs them
Swipe to see the whole diagram →
v1 vs v2. In v1 the receiver must run a web server open to the internet, which is why phone and desktop wallets struggled to receive. PayJoin v2 (“async PayJoin”) swaps that for two helpers run by others, and also hides the sender’s IP address from the receiver.
PayJoin v2
Messages go through a mailbox, like email
The one rule: the relay and the mailbox must be run by different people who don’t collude. Then neither sees the whole picture.
Key takeaways
1. PayJoin is not a sidechain or a fork. It is a way for two wallets to talk, the way email is a protocol. The end result is a normal Bitcoin transaction built in steps with PSBTs.
2. It is not instant privacy. One PayJoin won’t clean up coins that are already linked to you, and it only beats two of the chain-analysis guesses. It works best used again and again, together with other tools. The more people use it, the less chain analysis can trust any guess.
3. Try it yourself. Turn on PayJoin in Cake Wallet’s settings and copy the receive link (it’s long and contains pj=). Paste it into Bull Bitcoin and send. On the call only amounts over 10,000 sats went through, and not every try worked, so start small and check mempool.space.
Wallets mentioned on the call
Bull BitcoinSend and receive
Cake WalletSend and receive (turn it on in settings)
SparrowSend only (v1), so hardware wallets can pay through it
BTCPay ServerReceive on your own server (v1)
Resources shared
Reading
- Extreme Privacy, Michael Bazzell: privacy in every area of life: operating system, browser, Tor and more
- Bitcoin Fog verdict, IRS-CI (2024): this session’s chain-analysis case: a mixer run from 2011 to 2021, where the reports never say how the tracing worked
- BIP 78: PayJoin (v1): the original protocol, where the receiver runs a web server
- BIP 77: Async PayJoin (v2): mailbox directory plus an oblivious HTTP relay, no receiver server needed
- BIP 21: payment URIs: the bitcoin: link that carries the pj= PayJoin parameter
- BIP 174: PSBT: partially signed Bitcoin transactions, the data format PayJoin passes back and forth (they can be unsigned or fully signed too)
Tools
- payjoin.org: the PayJoin Dev Kit and docs
- mempool.space: used live to read the PayJoin transaction
- Blooket: the quiz Razor ran on the call
Wallets
- Bull Bitcoin: sends and receives PayJoin; used for the live demo
- Cake Wallet: turn PayJoin on in settings, then share the receive link
- Sparrow: can send PayJoin v1, so hardware wallets can pay through it, but can’t receive
- BTCPay Server: how merchants received PayJoin v1 with their own server
Code Orange
- Privacy Developer Track: every 1st and 3rd Tuesday: PayJoin, Silent Payments, Floresta, JoinMarket, Fedimint and more
- Code Review Club, 8 October: the follow-up session two days later
Ideas from the call: a guide to choosing the right privacy tool for each risk profile, a quiz leaderboard (opt out any time), and a capture-the-flag privacy challenge in about six months.
These notes are also on GitHub: code-orange-dev/session-notes. Free to share and reuse (CC0).