Privacy Architecture
The shielded pool hides who owns which note, how much moves between notes, and which notes a spend consumes. This page states exactly what stays hidden, what each operation publishes, and what the servers a wallet talks to can learn.
What is hidden
| Hidden | Why |
|---|---|
| Who owns a note | The chain stores only its commitment, a hash with a random blinding |
| The value of a note created by a private transfer | It is inside the commitment and the encrypted memo |
| Which note a spend consumes | Its nullifier cannot be linked to a commitment without the owner's spending key |
| Which inputs fund which outputs | Nullifiers and new commitments are emitted as separate events |
| Who submitted a private transfer or unshield | Both are unsigned; no account signs or pays for them |
| A wallet's balance and history | They exist only on the user's device |
Every operation carries a zero-knowledge proof; see Notes and How Proofs Work.
What each operation makes public
| Operation | Public | Hidden |
|---|---|---|
| Shield | The depositing account, the amount, the asset, the new commitment, its encrypted memo, its leaf index, and the gas or fee paid | Who owns the new note |
| Private transfer | That a transfer happened, its fee, its asset_id, the root each input was proven against (and so the tree or trees it spent from), its nullifiers, and its two new commitments with their encrypted memos | Sender, recipient, every amount, and which notes were spent |
| Unshield | The recipient account, the amount it receives, the fee, the asset, the root, the nullifier, and whether a change note exists (its commitment and memo) | Which note was spent, its value, the change amount, and who owned it |
| Note disclosure | Nothing on-chain; the key is shared off-chain | Everything, except to whoever holds the key |
A transfer always creates two output commitments. It spends one or two notes; a one-note transfer fills the second input with a zero nullifier, so the number of real inputs is public.
A disclosure key reveals one note's value, asset, owner key and blinding to its holder, who can confirm the commitment is on-chain. It grants no power to spend and does not show whether the note is spent. See Disclosure Key Format.
What servers learn
A wallet also talks to a node and to the indexer. Most of its requests are the same for every wallet.
| The wallet needs | What it asks | Server | What the server learns |
|---|---|---|---|
| To find its notes | The commitment feed with encrypted memos, read in full from its last position and decrypted locally | Indexer | How far the wallet has scanned; nothing about which notes are its own |
| Which of its notes are spent | The whole spent-nullifier feed, matched locally | Indexer | Nothing per note |
| A Merkle path to spend a note | The tree's subtree roots, plus the aligned 1,024-leaf window holding the note when the wallet has not kept its block | Node, indexer | The subtree roots are the same for every wallet; a window request narrows the note to one of 1,024 leaves |
| Its activity history, after a Sync or Recover Notes | Nothing: the history is rebuilt from the notes, joining each note's spend and creation hashes from the feeds above | — | Nothing |
| To confirm its inputs are unspent before proving | The status of each input's nullifier | Node | Those nullifiers, seconds before the spend publishes them |
| To submit a spend | The unsigned extrinsic | Node | The spend, and the network address it came from |
| Where its new notes landed | The events of the landing block, whole | Node | Nothing new: that node already has the transaction |
| To confirm an imported backup or payment slip | Each imported note's commitment and nullifier | Node | Those commitments and nullifiers |
| To verify a disclosure key | The disclosed commitment | Node | Which commitment is being checked |
The wallet never asks a node for a note's Merkle proof, which would name the note being spent; it builds paths itself (see The Merkle Forest). It also keeps a newly found note out of its spendable balance until it has checked the note against the chain's root (see Note Discovery).
Sender identity
Whether a private transfer names its sender is the sender's choice, made per payment. The chain sees the same commitment and memo in every mode.
| Sender's choice | What the recipient learns | Linkability |
|---|---|---|
| Anonymous (default) | Nothing about the sender | None |
| Pseudonym | A name of 1–24 letters or digits, unverified | Payments under one pseudonym look related to that recipient |
| Address | The sender's privacy address, verified by the note's commitment; the recipient can pay it back | That sender's payments are linked to that recipient |
Third parties learn nothing in any mode: the claim is inside the encrypted memo. See Note Discovery.
Threat model
| Party | Can learn or do | Cannot |
|---|---|---|
| Anyone reading the chain | The per-operation table above; timing; tree sizes | Link a nullifier to a commitment, read a memo, or learn a transfer's amounts |
| A node operator | What it serves, including each spend's network address | Spend, forge or decrypt a note |
| The indexer operator | Which clients read which feeds, and when | Tell which notes a wallet owns |
| A block author | Omit a spend from its own blocks | Change a spend's fee, memos or outputs, which the proof binds |
| A recipient | Its note's value; the sender only if the sender chose to show it | See the sender's other notes |
| A viewing key holder | The notes that key covers | Spend them; see Keys & Identity |
Proof soundness rests on the trusted setup of the circuits' keys. The current setup has a single contributor; see Trusted Setup.
Limits
- The anonymity set is one tree. A note in a young, sparsely filled tree hides among fewer notes.
- The edges are public. A shield publishes its amount, which is the new note's value; an unshield publishes its amount and recipient. Matching amounts and timing can link the two.
- Roots reveal the tree. A spend from two trees reveals both and links them. An active-tree root was current within the last 300 blocks (see retention).
- Input count is public. A one-note transfer is distinguishable from a two-note one.
- Fees are public. The app pays the chain minimum, 0.001 ORB, so most spends carry the same fee.
- Network metadata is not hidden. The node that receives a spend sees where it came from.
- A disclosure key proves knowledge, not ownership. A note's sender can produce the same key.
- Only ORB moves. Every spend names its asset; today it is always asset
0.
Best practices
- Leave time between a shield and the unshield that follows it, and avoid matching or distinctive amounts.
- Unshield to an account other than the one you shielded from.
- Keep the default fee, and use Anonymous unless the recipient needs to know who paid.
- Share a disclosure key only with the party that needs it.
- Use a node you trust, or a network-level anonymizer, when a spend's network address matters.
Related
- Transaction Lifecycle — one operation end to end
- Notes — commitments, nullifiers and memos
- The Merkle Forest — trees, roots and local paths
- Note Discovery — memos, view tags and scanning
- Keys & Identity — spending and viewing keys
- Spend Fees — who is paid and how
- Spend Validity — every check a spend passes