One complete flow
Bundle commitment
The client chooses a supported template before deposit. That template fixes the parent amount and two child slots. Their amounts add up to the deposited amount; a zero second slot represents a standalone note. The pool sees one bundle commitment, the deposit amount, timing, sender, and encrypted payload. Child secrets remain in the recovery envelope.Accepted root
Each inserted bundle commitment changes the Merkle root. A withdrawal witness proves two things together: the selected child belongs to the bundle, and the bundle commitment belongs to an accepted tree root. The private Merkle path and child secret stay in the client. The accepted root is public.Nullifier and sibling
Each active child has its own nullifier. A successful withdrawal records it and blocks a second spend of that child. The sibling was already committed at deposit and remains usable until its own nullifier is recorded.Public statement
The withdrawal proof fixes nine values in order:- Accepted root
- Child nullifier
- Public destination
- Gross child amount
- Fee
- Chain ID
- Verifying pool
- Proof context hash
- Encrypted payload hash