Withdraw
TL;DRWithdrawing spends a note out of the vault and releases the tokens to an SPL token
account. It is an on-chain action gated by a zero-knowledge proof: you prove the
note is in the tree and yours, the proof derives its unlinkable note-use tag
so it cannot be spent again, and the program transfers the tokens out. The withdrawal does not
reveal which deposit the value came from.
What a withdrawal does
A withdrawal is a zero-knowledge spend (see Shielded Pool). You produce a proof that the note exists under a recent Merkle root, that you own it, and that it is being paid to one specific destination; the vault program verifies the proof, records the note’s use tag as consumed, and releases the tokens to that account. Like a deposit, it is a direct on-chain action and does not involve the matching engine. You need the note’s plaintext (which you hold locally) and its Merkle leaf index. The SDK assembles the proof and the transaction.Using the SDK
What a withdrawal reveals
A withdrawal is a real token transfer out of the pool, so the amount and the destination account are visible on-chain, as they must be for the tokens to land. What stays hidden is the link to the rest of your activity: the published note-use tag is unlinkable to the note commitment, so an observer cannot tie the withdrawal back to the deposit or trade that produced the note.A note involved in an order
A resting order reserves its collateral commitment inside the venue, but does not create an on-chain lock merely by being accepted. Cancel the resting order before withdrawing the note so the venue cannot later match an order whose collateral you have removed. Once an order is matched and becomespending_settlement, the engine creates a
note-use-tag-keyed on-chain lock. The tag is proof-bound to the note but
cannot be matched to its public Merkle leaf without the private opening. A live
lock blocks withdrawal while the
settlement may still land. It carries an expiry, and at that slot it stops
blocking withdrawal or merge automatically—even if the expired lock account has
not yet been closed.
The permissionless release instruction and the engine’s sweeper only close an
expired lock and reclaim its rent; neither can release a live lock early. If
a withdrawal fails because of a lock, check its expiry and wait for that
bounded settlement window.