Receiver — publish a payjoin offer
The receiver creates the offer: how much PRL they want, where it goes, and the fee terms they accept. The offer becomes a template PSBT (zero inputs, one payment output) plus a query string a real payjoin endpoint would serve at ?v=2&….
Endpoint query string
A real payjoin server would serve this template at https://your-endpoint/payjoin with this query:
Offer envelope (send this to the sender)
Template PSBT (base64)
Honest limits
- This is a lab: it builds the exact BIP-78 offer a server would serve, but it is not a server. A production receiver endpoint must also authenticate the sender and rate-limit requests.
- Only PRL Taproot (
prl1…) addresses are accepted — never testnet or foreign prefixes.
Sender — validate, fund, sign the original
Paste the receiver's offer. The desk validates the template, then you fund it with your own UTXOs, pay an exact fee, and sign + finalize every input — that signed original is what BIP-78 says you hand to the receiver.
Your inputs
Enter UTXOs manually, or derive addresses from a mnemonic and look them up on the Pearl blockbook (live network call, clearly labeled).
Signed original (send this envelope to the receiver)
Original PSBT (base64)
Proposal — the receiver answers
Paste the sender's signed original. The desk re-verifies the sender's signatures, then the receiver adds their own input (signed + finalized), inserts it at a random position, and computes the exact fee split. Deductions from the payment output are bounded by maxadditionalfeecontribution — anything more is refused, loudly.
Receiver's contribution
Proposal envelope (send this back to the sender)
Proposal PSBT (base64)
Fee math (exact grains)
Verify — the sender's checklist
Paste the receiver's proposal (the original is carried over from the earlier tabs). The desk runs the full BIP-78 sender checklist — 15 checks, each PASS/FAIL with the exact reason. A failing proposal must never be signed.
| Check | Result | Detail |
|---|
Sign — finalize and broadcast
The proposal is re-verified first — verification failure refuses to sign, no exceptions. Then your sender inputs are re-signed with fresh SIGHASH_DEFAULT signatures and every input is finalized. Out comes the broadcast-ready transaction.
Final transaction (hex)
Final PSBT (base64)
Broadcast (live — Pearl mainnet via public blockbook)
This sends the real transaction to the real network. There is no undo.
Lab self-test
Runs the whole protocol in this page — offer → signed original → proposal → 15 checks → sign → final transaction — with the public BIP-39 test vectors (abandon … about / legal … yellow). No network, no real funds. Then re-verifies every witness signature against the final sighash independently.
What this is, honestly
- A BIP-78 lab, not a wallet and not a server. It performs the exact sender/receiver protocol steps with real cryptography (BIP-340/341, BIP-86, BIP-174) and refuses protocol violations loudly — but there is no payjoin endpoint here, no coin selection beyond what you enter, and no privacy beyond what one joined transaction buys you.
- Keys never leave the page. Mnemonics you type are used in-memory only. Wipe them when done. Nothing is stored: no localStorage, no cookies, no analytics.
- Network calls are opt-in and labeled. UTXO lookups, fee estimates, and broadcast use the public Pearl blockbook and are marked live where they appear.
- Broadcast is double-gated. The broadcast button stays disabled until you check the explicit confirmation box.