Clarifying RPA, “SRPA”, and Phase‑1 Confidential Assets on Bitcoin Cash
TL;DR
- RPA today (per imaginary_username’s spec and the Electron Cash implementation) uses paycodes plus ECDH to derive one‑time P2PKH/P2SH receive addresses. It’s entirely standard on‑chain, but requires special wallet logic and indexing to discover and track those outputs.
- The current work is a Phase‑1 demo on chipnet that combines:
- RPA‑style paycodes and child address derivation,
- A covenant + CashTokens NFT that binds an amount commitment and proof hash on‑chain,
- A “gift‑card” style flow: Alice → covenant → Bob → paycode‑derived address for Alice → Alice.
- This demo does not implement full SRPA as proposed by ABLA. Instead, it lays a backwards‑compatible foundation for “SRPA‑like” features:
- RPA‑style stealth identities that interact cleanly with covenants and confidential assets,
- Stronger amount privacy via ZK proofs in later phases,
- All while staying within standard P2PKH/P2SH + CashTokens on Bitcoin Cash.
- Future phases aim to:
- Move from “gift card” semantics to general‑purpose confidential assets,
- Replace the current ad‑hoc “txid hand‑off” with flows where ownership and correctness are proven entirely from keys + on‑chain commitments/ZK proofs, with no protocol‑specific indexers or OP_RETURN “beacons”,
- Provide a reference architecture any modern BCH wallet can adopt without new consensus rules or special address types.
What changed since the previous post
The original article used “SRPA” somewhat loosely and created confusion around:
- How SRPA relates to RPA as specified by imaginary_username,
- How “SRPA space” interacts with CashFusion and the UTXO model,
- Why “stealth change” would be desirable or how it would be implemented in practice.
This follow‑up:
- Clearly distinguishes RPA (today) from the Phase‑1 demo and the future “SRPA‑like” direction.
- Explicitly anchors the work in imaginary_username’s spec and the Electron Cash paycode implementation), to bulid from existing solutions and account for future integrations.
- Clarifies that the on‑chain format is standard: P2PKH / P2SH + CashTokens prefix, no new script types.
- Corrects the narrative around “SRPA space”:
- It is not a different UTXO model,
- It simply refers to UTXOs whose addresses are derived from paycodes and look like normal P2PKH on‑chain.
- Simplifies Phase‑1 behavior around change:
- In the current demo, change goes back to base wallets, not to stealth/SRPA change everywhere,
- The key demonstrated stealth step is Bob paying Alice to a paycode‑derived child address.
- Adds an explicit, high‑level comparison between:
- RPA today (as deployed in Electron Cash),
- The Phase‑1 confidential asset demo, and
- The intended future phases.
Design principles for this work
To make the goals explicit:
- Standard transactions only.
All confidential‑asset UTXOs are standard CashTokens outputs to P2PKH or P2SH. There are no special script types or consensus changes. - Privacy from commitments and proofs, not new opcodes.
Identity and amount privacy come from Pedersen commitments, proof hashes, and (in later phases) on‑chain ZK proof verification, not from hiding data in nonstandard address formats. - No protocol‑specific indexers or beacons.
Future phases are designed so that a wallet with:- its own keys, and
- a normal view of the blockchain
can determine when it is authorized to spend a confidential UTXO using on‑chain commitments + covenants + ZK proofs—without relying on extra “beacons”, OP_RETURN tags, or a dedicated off‑chain indexer service.
1. What RPA actually is today
Beta wallet type in Electron Cash added in 2021
1.1 The RPA spec in a nutshell
Reusable Payment Addresses (RPA) were proposed by imaginary_username in the “Reusable Payment Addresses” spec.
The essential ingredients:
- A paycode: a static, reusable identifier derived from a wallet’s keys.
- A derivation procedure that:
- Combines the paycode public key with some sender‑side randomness (via ECDH),
- Produces a one‑time address (usually P2PKH),
- Keeps that address unlinkable (on‑chain) to the underlying wallet pubkey.
On‑chain, those one‑time addresses are plain old P2PKH/P2SH. The magic is entirely in:
- How the sender derives the child address from the paycode, and
- How the receiver scans and recognizes which outputs belong to them.
1.2 How Electron Cash does it
Electron Cash ships a beta implementation of RPA in its rpa/paycode.py module.
Key properties:
- Special wallet logic
RPA is not “just another address format”. The wallet must:- Store paycodes and associated secrets,
- Derive candidate child addresses,
- Scan transactions and match outputs to those derived addresses,
- Maintain extra state/indexes to make this efficient.
- Wallet‑type specific
In practice you use a dedicated “paycode / RPA wallet” in Electron Cash. A generic BCH wallet that doesn’t know the RPA derivation rules cannot automatically discover or spend those outputs. - On‑chain, still standard
Despite all this, the transactions themselves are extremely boring:- Standard P2PKH/P2SH scripts,
- No special opcodes,
- No consensus rule changes.
That last point is important: RPA today already works entirely within standard BCH transactions. All the complexity lives in the wallet and the off‑chain derivation/indexing.
2. What I mean (and don’t mean) by “SRPA”
The term SRPA comes from ABLA’s proposal for Silent Reusable Payment Addresses.
Very roughly:
- Take the core idea of RPA (static identity → one‑time addresses),
- Add stronger privacy and better UX,
- Keep everything compatible with standard BCH transactions.
In my earlier post, I used “SRPA” a bit too loosely to describe the direction of my work, even though:
- I do not yet implement ABLA’s full SRPA proposal.
- The community doesn’t yet have a finalized SRPA spec.
- The code today is RPA‑style plus additional covenant / CashToken logic.
So, for this follow‑up:
- I’ll use RPA for the currently‑specified, Electron‑Cash‑style system.
- I’ll talk about “RPA‑style stealth identities + covenants + confidential assets” when I mean my current work.
- I’ll reserve “SRPA‑like” for the future direction:
a wallet‑friendly, beaconless experience that improves on RPA’s UX and tracking requirements without changing on‑chain formats.
SRPA’s intention, as I’m using the term here, is to go a step further than RPA by:
- Removing the need for extra “beacons” or protocol‑specific tracking infrastructure, and
- Implementing the same “static identity → one‑time address” effect entirely on‑chain using:
- plain P2PKH/P2SH Bitcoin Cash transactions,
- covenants,
- CashTokens NFTs, and
- zero‑knowledge proofs.
3. What Phase‑1 actually does (high‑level demo anatomy)
Phase‑1 is deliberately narrow. It’s not a full wallet, not a full SRPA implementation, and not a finished ZKP system.
Instead, it demonstrates a specific gift‑card‑style value transfer:
Alice locks some BCH into a covenant‑guarded NFT.
Bob, and only Bob, can redeem it.
Bob sends it back to a paycode‑derived one‑time address for Alice.
Alice proves she can re‑derive and spend that stealth output.
Everything happens on chipnet, and every transaction is built from:
- Standard P2PKH and P2SH scripts, plus
- The standard CashTokens token prefix (for the NFT).
No new opcodes, no new script types.
Here’s how the pieces fit together.
3.1 Base wallets & paycodes (RPA‑style identities)
The demo starts with two normal BCH wallets:
- Alice base wallet:
bchtest:qpdmgn6p67s4vezh8rzy0t4dqwte7kc3x53ls5pxfe - Bob base wallet:
bchtest:qps6dfu8mhmtpj9p8uusay5xxh2mc6k9ugarzuhldj
From their public keys, it derives paycodes:
- Alice paycode:
PM8TJQi7puENNvL87PcG... - Bob paycode:
PM8TJLg64Hzye5Y6YM9A...
These paycodes follow the same conceptual structure as im_uname’s RPA spec:
- Include a compressed secp256k1 pubkey,
- Plus extra data (chain code, flags, etc),
- Encoded for long‑term reuse (think “business card” style identifier).
The paycodes themselves never appear on‑chain. Every on‑chain payment uses a fresh address derived from them.
3.2 Step 1 – Alice → covenant (gift card creation)
Alice wants to create a “gift card” for Bob:
- She takes one of her own UTXOs (optionally consolidated first).
- She computes a covenant guard key as a one‑time child key derived from Bob’s paycode, using an RPA‑style derivation:
- Inputs: Alice’s funding key, Bob’s paycode pubkey, the funding outpoint, index = 0.
- Output: a guard hash160 that only Bob (via his paycode secrets) can later reconstruct.
- She builds a CashToken NFT:
- Category: derived from the txid of her input (standard CashTokens convention),
- Commitment: a Pedersen commitment to the amount,
- Metadata: includes the hash of an off‑chain Sigma range proof (proof that the amount is valid).
- She locks
100000sats + the NFT into a P2SH covenant output whose redeem script:- Enforces that the spender knows the correct guard key (Bob‑only),
- Enforces that the redeemed amount matches the committed amount.
The resulting funding transaction looks like this at a high level:
- Input[0]: Alice base wallet UTXO
- Output[0]: small P2PKH to Bob base wallet (explorer‑friendly marker)
- Output[1]: covenant P2SH + NFT + 100000 sats
- Output[2]: change back to Alice base wallet
Example (from a real run):
[1] Alice → covenant: lock NFT + amount under Bob-only guard
- Input[0]: from Alice base wallet (this UTXO could come from CashFusion).
- Output[0]: small marker → Bob base wallet (optional, for explorer UX).
- Output[1]: NFT + 100000 sats → covenant lock
• Guard key: one-time child derived from Bob’s paycode (RPA receiver side).
- Output[2]: change → Alice base wallet (no paycode-change yet in Phase 1).
Funding txid:
https://chipnet.chaingraph.cash/tx/fdd8f62cc671d107d1f64c2f52056d7c47f7f034ceb206ec02e63e50b7d8d354
You can think of Output[1] as a gift card UTXO:
- It’s tagged with a specific category and commitment,
- It says, effectively:
“Whoever can satisfy this covenant and prove they’re Bob may redeem these 100000 sats and pass them on.”
3.3 Step 2 – Bob → Alice (RPA‑derived return)
Off‑chain communicates to (like e2e chat or other private communication), Bob:
- Receives:
- Alice’s ephemeral pubkey (for ECDH),
- The encrypted amount,
- The funding txid (in this demo we pass it directly).
- Decrypts the amount (here:
100000sats) using his secret key + Alice’s ephemeral pubkey. - Reconstructs the covenant guard key (RPA receiver side):
- Uses his paycode secrets (scan/spend),
- Alice’s funding pubkey (from the scriptSig),
- The funding outpoint,
- Index = 0.
- Verifies locally that the Sigma proof and Pedersen commitment match the amount.
Then he builds a return transaction:
- Input[0]: the covenant UTXO (NFT + 100000 sats), unlocked with the one‑time guard key
- Input[1]: a fee UTXO from Bob’s base wallet
- Output[0]: NFT + 100000 sats to a fresh address derived from Alice’s paycode
- Output[1]: change back to Bob’s base wallet (in Phase‑1 we keep it simple here)
Concretely, Output[0] is a plain P2PKH to a one‑time child address like:
bchtest:qpw2e5zh9uhqqrs6z8afrnnemg8s2gfq3u5pqypst7
That address is derived from:
- Bob’s sender key (fee input),
- Alice’s paycode pubkey,
- Bob’s fee outpoint,
- Index = 0.
From a chain observer’s perspective:
- They see: “covenant spends → random P2PKH token output + some change”.
- They do not see Alice’s paycode or how this address relates to her.
Example from the demo summary:
[2] Bob → Alice: return NFT + amount to a paycode-derived one-time address
...
- Outputs:
output[0]: NFT + 100000 sats → one-time address from Alice’s paycode
bchtest:qpw2e5zh9uhqqrs6z8afrnnemg8s2gfq3u5pqypst7
output[1]: change → Bob base wallet: bchtest:qps6dfu8mhmtpj9p8uusay5xxh2mc6k9ugarzuhldj
Return txid:
https://chipnet.chaingraph.cash/tx/dbb44b08c1ea697d7550e7fa23a29e121cf14c674d3159516b75d537dd04d29e
3.4 Step 3 – Alice recognizes and spends the RPA child
To close the loop, Alice needs to show that she can:
- Recognize that
bchtest:qpw2e5zh...belongs to her, - Re‑derive the correct one‑time private key, and
- Spend that UTXO.
In the demo, she:
- Parses vout[0] of Bob’s transaction as a standard P2PKH:
- Extracts the hash160 from the script.
- Uses her paycode scan/spend keys and Bob’s sender pubkey + fee outpoint to derive the matching child key (RPA receiver side).
- Checks that
HASH160(derived pub) == hash from script. - Signs and spends that UTXO back to her base wallet.
This produces the “loop closure” transaction:
[3] Alice → Alice: spend the RPA-derived output back to her source wallet
...
- Output[0]: Alice base wallet:
bchtest:qpdmgn6p67s4vezh8rzy0t4dqwte7kc3x53ls5pxfe
RPA spend txid:
https://chipnet.chaingraph.cash/tx/d1be520ddef05313c44fa9292740f54beab70095b65e08314cc2d9c091b49161
At this point, the gift card UTXO has been:
Alice base → covenant (NFT + amount) → RPA‑derived Alice child → Alice base
All via standard P2PKH/P2SH + CashTokens.
4. How this compares to RPA today (and future phases)
Now that the demo is more concrete, we can compare:
4.1 RPA today (Electron Cash)
- On‑chain format
- Plain P2PKH / P2SH (no new opcodes).
- Identity model
- A paycode is a long‑lived stealth identity.
- Each incoming payment uses an ECDH‑derived one‑time address.
- Discovery & tracking
- Wallet must implement special logic:
- Store paycodes and view/spend secrets,
- Derive candidate addresses for each paycode,
- Scan transactions and match outputs.
- Implemented as a dedicated wallet type in Electron Cash, not generic.
- Wallet must implement special logic:
- Privacy
- On‑chain, derived addresses are unlinkable to the base pubkey.
- However:
- Amounts are still public,
- Wallets still rely on some off‑chain state/indexing to function,
- There’s no covenant tying amounts or proofs to specific outputs.
4.2 Phase-1 demo (what we have today)
Phase-1 is deliberately narrow. It’s a gift-card style confidential asset flow that runs on chipnet using only:
- Standard P2PKH and P2SH scripts, plus
- Standard CashTokens prefixes for NFTs (no new opcodes or consensus rules).
At a high level, the demo proves three things:
- RPA-style paycodes work cleanly with covenantsSo Phase-1 already shows: “paycodes + ECDH child keys + covenants can coexist in pure P2PKH/P2SH land.”
- Alice and Bob each have:
- A normal base wallet address (P2PKH), and
- A paycode derived from their wallet pubkeys.
- The demo uses RPA-style derivation in two places:
- To construct a Bob-only guard key for the covenant (child derived from Bob’s paycode).
- To construct a one-time child address for Alice when Bob returns funds.
- Alice and Bob each have:
- NFT commitments can bind off-chain proofs to on-chain UTXOsIn Phase-1, the chain still sees the cleartext amount (
100000sats), but the NFT commitment + covenant show how future phases can anchor ZK proofs on-chain without changing the transaction shape.- The covenant UTXO carries a CashTokens NFT whose:
categoryis derived from Alice’s funding transaction (standard CashTokens convention),commitmentis a Pedersen commitment to the logical amount (and proof metadata).
- Off-chain, Alice and Bob:
- Generate a Sigma range proof about that amount,
- Compute a hash of the proof & envelope, and
- Ensure the NFT commitment + covenant script are consistent with that data.
- [1] Alice → covenantThis UTXO behaves like a gift card UTXO locked to “Bob-only, under this NFT commitment”.
- Input: Alice base wallet UTXO.
- Output[0]: small “marker” P2PKH → Bob base wallet (explorer UX only).
- Output[1]: covenant P2SH + NFT + 100000 sats.
- Guard key is a one-time child derived from Bob’s paycode (RPA receiver side).
- Output[2]: change → Alice base wallet (no stealth/self-RPA change yet).
- [2] Bob → Alice (paycode-derived child)On-chain, output[0] is just a tokenized P2PKH to
bchtest:qpw2e5zh…that looks like any other address. The paycode relationship lives purely in the derivation.- Bob decrypts the amount using:
- Alice’s ephemeral pubkey, and
- His paycode-derived secrets.
- He reconstructs the covenant guard key via RPA logic and spends the covenant UTXO.
- Inputs:
- Input[0]: covenant P2SH (unlocked by RPA-derived child key).
- Input[1]: a fee UTXO from Bob’s base wallet.
- Outputs:
- Output[0]: NFT + 100000 sats → one-time child address from Alice’s paycode.
- Output[1]: change → Bob base wallet (plain P2PKH).
- Bob decrypts the amount using:
- [3] Alice (RPA child) → Alice base wallet
- Alice parses Bob’s transaction, inspects vout[0] as a standard P2PKH script, and extracts the hash160.
- Using:
- Her paycode scan/spend secrets, and
- Bob’s sender pubkey + fee outpoint,
- Index = 0,
she re-derives the one-time private key that matches that hash160.
- She spends that UTXO back to her base wallet in a token-preserving P2PKH spend.
- The covenant UTXO carries a CashTokens NFT whose:
The end-to-end flow is standard and backwards-compatibleThe concrete flow is:This proves that:
Base wallet → covenant (gift card) → RPA child → base wallet
can be implemented today using only standard P2PKH/P2SH + CashTokens outputs, with RPA-style derivation and NFT commitments binding off-chain proofs to on-chain UTXOs.
4.3 Future phases (stealth BCH + “SRPA-like” vision)
The long-term target has three layers, in this order of priority:
- Alice holds Bob’s paycode (a static identity).
- She derives a one-time child address for Bob via an RPA-style ECDH procedure.
- She may route the payment through a covenant that:
- Anchors an NFT commitment (identity + amount data),
- Enforces protocol rules via script and, eventually, ZK verification.
- P2PKH (or P2SH) with a standard CashTokens prefix,
- Indistinguishable on-chain from other tokenized P2PKH outputs.
- His paycode secrets, and
- The normal on-chain transaction data (no special beacons or protocol-specific indexers),
- Reconstruct the relevant one-time keys,
- Regenerate or verify the associated ZK proof (once those are added),
- Satisfy the covenant and spend the UTXO.
- Fully on-chain proofs of identity and correctnessTo support those stealth BCH payments (and more complex flows), later phases move from the current “txid passed out-of-band” demo to a model where:can determine that it is authorized to spend a confidential UTXO by:No protocol-specific indexers, no explicit beacons, and no nonstandard address types are required — just keys, the blockchain, and covenants that know how to validate a proof.
- Any wallet with the right keys, and
- Only the normal on-chain transaction data
- Regenerating or verifying ZK proofs against:
- The NFT commitment, and/or
- Script parameters encoded in the covenant, and
- Satisfying a covenant that encodes statements like:
- “This spender owns the paycode behind this identity,”
- “These input and output commitments balance,”
- “The amounts are within a valid range,” etc.
- Optional: extending the same machinery to other confidential assetsOnce we can do “BCH → covenant → stealth BCH” with on-chain proofs of identity and correctness, the exact same pattern can be reused for other application-level assets, if people want them:The important bit is that this “confidential asset” layer is optional and additive:
- Private vouchers or gift cards (generalizing the Phase-1 pattern),
- Credit-like instruments (BCH locked under repayment/usage rules),
- Tokenized rights / access passes (identity-gated redemptions),
- Multi-hop transfers where:
- Logical amounts are represented as Pedersen commitments in NFT commitments or script parameters,
- A ZK proof enforces conservation and range.
- It uses the same:
- P2PKH / P2SH + CashTokens transaction shape, and
- NFT commitment + covenant + ZKP pattern,
- But targets use cases beyond “Alice sends Bob BCH”.
First-class stealth BCH payments (Alice → Bob)The primary deliverable is:
“Given only Bob’s paycode, Alice can send BCH to Bob in a way that looks like an ordinary BCH (+ CashTokens) transaction on-chain, while Bob’s identity and address structure remain private.”
Concretely, in later phases:The resulting output is still just:Bob’s wallet, given:can:This is the plain p2p stealth transaction use case: Alice sends Bob BCH privately using only his paycode, with no new address types and no external index services.
4.4 Wallet-agnostic reference architecture
Across all phases, the design stays wallet-agnostic:
- On-chain, everything remains:
- Standard P2PKH / P2SH scripts,
- Standard CashTokens encoding for NFTs/FTs,
- No new consensus rules or exotic script types.
- Off-chain, a wallet that:can:without needing to adopt a special “SRPA-only” transaction type or a custom indexer.
- Understands paycodes + RPA-style derivation, and
- Implements the published covenant + NFT + proof format
- Offer stealth BCH payments using only paycodes, and
- Optionally support richer confidential-asset flows,
5. Addressing the “stealth change” & CashFusion confusion directly
One critique I received (fairly!) was:
“Why would someone use SRPA for its own change address?”
“What does it mean to ‘feed SRPA UTXOs into CashFusion’?”
A few clarifications:
- “SRPA space” is not a different UTXO model
It’s just a label for UTXOs that:They’re perfectly valid inputs and outputs for any wallet or protocol that understands standard P2PKH + CashTokens. There’s no separate ledger, pool, or nonstandard script type implied by the term.- Pay to addresses derived from paycodes, and
- Are indistinguishable on-chain from any other P2PKH.
- Stealth change is a standard privacy pattern
In systems like Monero, every transaction output—including change back to the sender—uses a one-time stealth address derived from the recipient’s public keys, so no fixed “home” address ever appears on-chain. In Liquid, Confidential Transactions blind the amount and asset type for all outputs (including change) using Pedersen commitments and range proofs, while still allowing nodes to verify conservation of value. The common goal is to avoid simple heuristics like: “This recognizable address must be change, therefore the other output is the real payment.” - Phase-1 keeps change simple on purpose
Earlier iterations of my write-up talked about routing all change back to paycode-derived addresses. That’s still a valid pattern in principle, but it muddied the explanation and raised questions around wallet support. In the current Phase-1 demo:The important stealth step demonstrated today is narrower and clearer: Bob → Alice uses a paycode-derived child address, not her base address. That’s all we need to prove the RPA-style flow and the covenant + NFT commitment wiring in this phase.- Alice’s covenant funding change goes back to her base wallet, and
- Bob’s return change goes back to his base wallet.
- What this means for Phase-1 scope
Phase-1 is intentionally conservative: it proves that RPA-style paycodes, covenants, and CashTokens NFTs can work together in a gift-card–style flow, all within standard P2PKH/P2SH transactions. Questions about how this will eventually interact with CashFusion, full-wallet scanning, or richer “stealth change everywhere” policies are explicitly left to later phases, once the basic confidential-asset pattern is solid and well-understood.
So the misunderstanding wasn’t about the UTXO model itself, but about my wording. Hopefully this follow‑up makes the mental model clearer.
6. Why this matters for RPA’s future
To answer a few key questions explicitly:
- Does RPA today require specific wallet logic and a specific wallet type?
Yes. Electron Cash’s RPA implementation relies on dedicated wallet code to store paycodes, derive child addresses, and scan for matches. A generic wallet won’t see those outputs as “mine” without that logic. - Does the Phase‑1 work intentionally stay in standard P2PKH/P2SH land?
Yes. The on‑chain pieces are:- P2PKH for all spendable outputs,
- P2SH for the covenant,
- CashTokens prefix to encode token category + NFT commitment.
There are no new consensus rules or script primitives needed beyond what BCH + CashTokens already provide.
- What does this buy us in the long run?
It sets up a reference architecture where:- Any wallet that:can interoperate with confidential assets and stealth identities without needing new transaction types or consensus changes.
- Understands paycodes,
- Implements RPA‑style derivation, and
- Knows the covenant/asset spec
- ZK proofs are generated off‑chain, but:
- Their commitments and hashes are anchored on‑chain,
- Covenants enforce correctness,
- The network remains lean and fully auditable.
- Any wallet that:can interoperate with confidential assets and stealth identities without needing new transaction types or consensus changes.
In other words:
Phase‑1 is not SRPA yet. It’s a gift‑card–style confidential asset built on RPA‑style identities and covenants, designed so that future SRPA‑like features (stronger privacy, better UX) can be added without changing the basic on‑chain format.
7. Current demo flow (for reference)
For those who want the concrete txids and addresses, here’s the latest compact run report for the Phase‑1 demo on chipnet:
=== Phase 1: Paycode → Covenant → RPA Return Demo (PZ-SQH) ===
[0] Base wallets and paycodes
Alice base wallet: bchtest:qpdmgn6p67s4vezh8rzy0t4dqwte7kc3x53ls5pxfe
Alice paycode: PM8TJQi7puENNvL87PcG...
Bob base wallet: bchtest:qps6dfu8mhmtpj9p8uusay5xxh2mc6k9ugarzuhldj
Bob paycode: PM8TJLg64Hzye5Y6YM9A...
(Paycodes are static identifiers derived from each wallet’s pubkey.
They are never used directly on-chain; each payment uses a fresh child address.)
[1] Alice → covenant: lock NFT + amount under Bob-only guard
- Input[0]: from Alice base wallet (this UTXO could come from CashFusion).
- Output[0]: small marker → Bob base wallet (optional, for explorer UX).
- Output[1]: NFT + 100000 sats → covenant lock
• Guard key: one-time child derived from Bob’s paycode (RPA receiver side).
- Output[2]: change → Alice base wallet (no paycode-change yet in Phase 1).
Funding txid:
fdd8f62cc671d107d1f64c2f52056d7c47f7f034ceb206ec02e63e50b7d8d354
[2] Bob → Alice: return NFT + amount to a paycode-derived one-time address
- Bob decrypts encrypted amount from Alice: 100000 sats.
- Bob reconstructs the covenant guard key using:
• his paycode secrets (scan/spend),
• Alice’s funding pubkey,
• the funding input outpoint,
• index = 0.
- Inputs:
input[0]: covenant P2SH (unlocked by Bob’s one-time child key)
input[1]: Bob fee UTXO from his base wallet: bchtest:qps6dfu8mhmtpj9p8uusay5xxh2mc6k9ugarzuhldj
- Outputs:
output[0]: NFT + 100000 sats → one-time address from Alice’s paycode
bchtest:qpw2e5zh9uhqqrs6z8afrnnemg8s2gfq3u5pqypst7
output[1]: change → Bob base wallet: bchtest:qps6dfu8mhmtpj9p8uusay5xxh2mc6k9ugarzuhldj
Return txid:
dbb44b08c1ea697d7550e7fa23a29e121cf14c674d3159516b75d537dd04d29e
Note:
The address Alice receives is not her base wallet address and not her paycode.
It’s a fresh child address derived from:
- Bob’s sender key (fee input),
- Alice’s paycode pubkey,
- Bob’s fee outpoint,
- index = 0.
To an outside observer, it looks like a random P2PKH token address.
[3] Alice → Alice: spend the RPA-derived output back to her source wallet
- Alice recognizes Bob’s payment as hers by scanning with her paycode keys.
- She derives the matching one-time private key and spends that UTXO.
- Input[0]: one-time P2PKH child from Alice paycode
(same address as TX [2] output[0])
- Output[0]: Alice base wallet:
bchtest:qpdmgn6p67s4vezh8rzy0t4dqwte7kc3x53ls5pxfe
RPA spend txid:
d1be520ddef05313c44fa9292740f54beab70095b65e08314cc2d9c091b49161
[4] UTXO consolidation (internal)
- Along the way, the demo may consolidate Alice or Bob’s UTXOs into
a single input to simplify the flow.
- This is an internal wallet hygiene step; it does not affect the paycode logic.
Explorer links:
[1] Alice → covenant:
https://chipnet.chaingraph.cash/tx/fdd8f62cc671d107d1f64c2f52056d7c47f7f034ceb206ec02e63e50b7d8d354
[2] Bob → Alice (paycode-derived child address):
https://chipnet.chaingraph.cash/tx/dbb44b08c1ea697d7550e7fa23a29e121cf14c674d3159516b75d537dd04d29e
[3] Alice (RPA child) → Alice (base wallet):
https://chipnet.chaingraph.cash/tx/d1be520ddef05313c44fa9292740f54beab70095b65e08314cc2d9c091b49161
If you’d like to support more of this kind of research and engineering, you can send a tip in Bitcoin Cash.
Scan to donate in Bitcoin Cash
bitcoincash:qr399w3awgzgf86520tajj9qjsf8jnwtmurfp9gymc
Every bit helps carve out time for the unglamorous parts of this work: writing specs, tightening scripts, building reference implementations, and iterating toward a privacy stack that’s actually deployable in wallets instead of just living in whitepapers.