Canonical transaction path
The active runtime path is UTXO transactions through:transactfor deposit/withdraw/transferswapWithChange/swapUtxofor swap flows- Relay endpoints
/transactand/transact_swap
Commitments and Merkle tree
Each deposit/output creates a Poseidon commitment and appends it to the on-chain Merkle tree.- Height:
32 - Root history:
100recent roots
- Leaf index
- Path elements/indices
- A root still present in root history
Nullifiers
Spending creates a nullifier. The program rejects a reused nullifier. This is the core double-spend guard for both note and UTXO flows.Stale-root retries
If your proof root is no longer in history, transactions can fail withRootNotFound (0x1001).
The SDK includes retry paths that:
- fetch fresh Merkle data
- regenerate proof
- resubmit
Fee model: gross, fee, net
Shared constants:- Fixed fee:
5_000_000lamports - Variable fee:
amount * 3 / 1000 - Minimum deposit:
10_000_000lamports
gross= absolute public withdrawal amountfee= fixed + variablenet=gross - fee
Proof data shapes
- UTXO transact and swap requests use
264-byte public inputs:root + publicAmount + extDataHash + mint + nullifiers + commitments + chainNoteHash. - Proof bytes are always
256bytes (Groth16).
Viewing key registration
- SDK/web enforce viewing-key registration by default before protocol transactions.
- Registration uses
POST /viewing-key/registerwith:- wallet pubkey
- 32-byte viewing key (
nk) - signature over fixed sign-in message
- Registration is cached in-process to avoid repeat calls.
Chain-native scanner and cache model
scanTransactionsreads chain transactions directly from RPC (no relay dependency).- It decrypts compact chain notes with viewing key
nkand verifieschainNoteHashintegrity. - It computes per-tx
gross,fee,netAmount, and running balance. - Web stores report snapshots in encrypted local storage and exposes explicit cache clear + rescan.
Related pages
- UTXO details: UTXO Transactions
- Program internals: Shield Pool Program
- Relay routes: Relay API