Transaction Lifecycle
This page follows value through the pool once: Alice unlocks her vault, shields ORB, pays Bob privately, and Bob withdraws. Each step says what the user does, what reaches the chain, and who sees what, and links to the page that owns the details.
Overview
1. Unlock
The user selects Sign and unlock on the Private Vault card and approves a signature in their public wallet.
The wallet derives every private key from that signature: the spending key, the viewing keys, and the key that encrypts the local vault. The same account on the same network always yields the same keys, so there is no seed phrase to back up. Lock vault wipes the keys from memory.
On-chain: nothing. Who sees what: no server sees the signature or the keys. See Keys & Identity and Private Vault.
2. Shield
The user selects Shield ORB and enters an amount.
The wallet builds a note to Alice's own address with a random blinding, encrypts its memo,
and proves on the device that the note's commitment opens to exactly that amount and asset. Alice's
public wallet then signs the shield call (or the precompile's shield from an EVM wallet) and
pays the gas.
On-chain: the amount moves from Alice's account to the pool account. The commitment becomes the
next leaf of the active tree, its memo is stored, and Shielded { depositor, amount, commitment, encrypted_memo, leaf_index } is emitted. The wallet reads the landing block's events and saves the
note with its leaf index.
Who sees what: everyone sees Alice's account, the amount, the asset and the new commitment; no one else learns who owns the note. See Shield and the shield circuit.
3. Finding a note
Before Alice can pay Bob, Bob shares his privacy address (orbpriv3:…). It carries the public keys
Alice needs to create a note only Bob can open and spend.
Every note the pool inserts carries a 180-byte encrypted memo. The memo's first byte is a view tag, derived from the secret shared between the memo's ephemeral key and the recipient's viewing key. A wallet computes that secret for each memo and decrypts only those whose tag matches. A memo that decrypts gives the note's value, blinding and sender identity, and the wallet recomputes the commitment to confirm it.
Bob's wallet finds his notes in one of two ways:
- Scanning. It reads the indexer's commitment feed from where it last stopped (Sync), or from the start of the pool (Recover Notes), and checks each memo locally.
- A payment slip. Alice can hand Bob a slip for the payment; Import Slip checks the note on chain and adds it at once.
Who sees what: the indexer serves the same feed to every wallet and learns nothing about which notes are Bob's. See Note Discovery and Payment Slips.
4. Private transfer
The user opens Private Transfer, enters an amount and Bob's privacy address, and chooses whether to show who paid: Anonymous, a pseudonym, or Alice's privacy address.
The wallet, with no further signature from Alice:
- Picks one or two of Alice's notes that cover the amount plus the fee.
- Asks the node whether their nullifiers are already spent.
- Builds each note's Merkle path locally from the tree's subtree roots and the note's 64-leaf block. See The Merkle Forest.
- Builds two output notes: Bob's, and Alice's change. Each gets an encrypted memo.
- Proves on the device that Alice owns the inputs, that they are in the trees, and that inputs equal outputs plus the fee.
- Submits
private_transferto the node unsigned.
Admission: the node checks the circuit version, then every check the block will run (fee at least 0.001 ORB, known roots, unspent nullifiers, memo shape, asset, new commitments), then the proof. The spend enters the transaction pool ordered by its fee, valid for 64 blocks. See Spend Validity.
In the block: the runtime repeats the checks and verifies the proof, records the nullifiers,
inserts both commitments, and credits the fee to the validator that authored the block. It emits
NullifiersSpent, CommitmentsInserted { leaf_indices } and FeeCredited. The fee stays in the
pool until claimed. Alice's wallet marks the inputs spent, places her change note from
leaf_indices, and shows a receipt with a payment slip.
Who sees what:
| Party | Learns |
|---|---|
| Anyone | That a transfer happened, its fee and asset, the roots it used, its nullifiers and its two new commitments |
| The node Alice uses | The nullifiers moments before they are published, and the network address of the submission |
| Bob | The value of his note, and Alice's identity only if she chose to show it |
See Private Transfer and Privacy Architecture.
5. Unshield
The user (Bob) opens Unshield ORB, enters an amount, and confirms the recipient account, which defaults to his connected account.
The wallet picks a note, builds its path, and proves that the note's value equals the amount
plus the fee plus the change. It submits unshield unsigned. A partial withdrawal creates a change
note with a full memo; a total one carries no memo.
On-chain: after the same admission checks, the amount moves from the pool to the recipient. The
fee stays in the pool, credited to the block author. The nullifier is recorded, the change note (if
any) becomes a new leaf, and Unshielded { nullifier, amount, recipient, change_commitment, change_encrypted_memo, change_leaf_index } and FeeCredited are emitted.
Who sees what: everyone sees the recipient account, the amount, the fee, the asset and whether change exists; no one learns which note was spent or its value. See Unshield and the unshield circuit.
6. Fee claim
The validator that authored those blocks has pending fees recorded for its account. It
withdraws them with a signed claim_fees(asset_id, amount) call. The pool pays the amount to the
signing account and emits FeesClaimed.
Who sees what: the claim is public, like any signed transfer. It names no spend. See Spend Fees.
Related
- System Overview — the parts involved
- Notes — commitments, nullifiers and memos
- The Merkle Forest — roots and local paths
- Spend Validity — every check at admission and in the block
- Spend Fees — who is paid and how
- Privacy Architecture — what each step reveals