Canonical data shape
BothTransact and TransactSwap use:
proof_bytes: 256-byte Groth16 proofpublic_inputs: 264-byte packed blob
root[32]publicAmount[8](signed LE)extDataHash[32]mintAddress[32]nullifiers[64]commitments[64]chainNoteHash[32]
Deposit flow (publicAmount > 0)
- SDK creates output UTXOs and generates proof inputs.
- SDK resolves Merkle data from chain.
- Transaction is submitted (direct signer path for deposit variants).
- Program verifies proof and appends commitments to the tree.
- SDK resolves commitment index and persists local proof context.
Withdraw/transfer flow
- SDK builds 2-in/2-out witness and computes nullifiers.
- SDK optionally ensures viewing-key registration.
- SDK submits the proof + public inputs and the resulting on-chain transaction lands.
- Program rejects reused nullifiers and enforces amount/fee constraints.
- Client polls transaction status until completed or failed.
Swap flow
- SDK generates proof for withdraw-like step with swap params.
TransactSwap(Tx1) opensSwapState.- Settlement path (Tx2) executes the swap and validates output min amount.
- Status includes
swap_phase, signatures, and error context. - Timeout/close paths can reclaim state if settlement cannot complete.
Reliability behaviors
- Stale root retries: SDK regenerates proofs when root history moved, on a bounded retry budget
- Nullifier preflight:
preflightNullifiersthrowsUtxoAlreadySpentErrorbefore a spend, in one batched RPC call - Settlement confirmation:
confirmTransactSettlementdecides from chain state whether a submission landed by polling input-nullifier PDAs; a verdict ofunknownmeans the SDK could not check and is never success - Direct-submission gating:
assertDirectSubmissionLandedthrowsSettlementVerificationErrorunless nullifier PDAs prove the transaction was applied, because a confirmed-looking status field is not proof - Swap refund recovery:
discoverSwapRefundsplusderiveSwapRefundAuthorizationre-derive and reclaim a stranded swap refund. Discovery is forward-looking only: it finds refunds whose authorization was derived from the wallet’snk, so an empty result is not proof that no stranded refund exists - Pending-deposit recovery:
loadPendingDepositsandcleanupStalePendingOperationspersist in-flight deposits so a crash or navigation away does not strand a note. Browser storage is used by default and the records carry spending secrets, so encrypt that storage in production