The immediate lane spends a note straight into a venue call, settled in one transaction. The owner is hidden and the amount is visible. There is no reserve step and no settle step.
One action, step by step
- 1Open your keysYour wallet signs one fixed request once, and your browser derives your keys from it. See Keys and backup.
- 2Read the logsThe browser reads pool logs, decrypts your notes and rebuilds the tree, so it builds the Merkle path itself.
- 3ProveA web worker builds the proof in this browser. The transaction circuit has about 32,000 constraints. The proof binds the adapter, the call data, each output's token, minimum and owner, the relayer, its fee and a deadline.
- 4SubmitA relayer simulates the call, sends the transaction and is paid from the note. A fee quote shows before anything is sent.
- 5SettleThe pool spends the note and hands the tokens to the adapter. The adapter runs the venue call and sends the output to custody. The pool measures it and writes the new note.
Adapters
| Adapter | What it does |
|---|---|
SwapAdapter | A private swap through the Router, across ZKDepth pools, public v4 pools and Pons curves, or down a Uniswap v3 path, where the deep WETH/USDG liquidity is |
DlmmAdapter | Bins in and out of a DLMM pair. The position is bin shares held as notes |
VaultAdapter | Deposit into and redeem from an ERC-4626 vault, and in and out of a DLMM vault through the venue's zap. The shares are held as notes, so they keep earning |
LaunchAdapter | Buys and sells on a launch's bonding curve |
PerpAdapter | Positions on the perps engine, each held as one note. See Private perps |
EthExitAdapter | Exits a WETH note as native ETH, so a fresh address can pay for its own gas |
The adapter is your choice, bound in the proof. The pool has no allowlist, and the web app lists the known adapters. An adapter holds nothing between calls: an action that leaves the spent token on it reverts, and anything sent to one any other way goes to the next action in that token, so never send tokens to an adapter. The client refuses a withdrawal to any of the pool's own contracts.
A relayer is more careful than the pool, as a hostile token or contract could waste its gas. By default it touches only what it can vouch for: the adapters and tokens of the deployment, launches of the launchpad, pairs of the venue's factory, and whatever its operator adds through RELAYER_ADAPTERS and RELAYER_TOKENS. So a route through a Pons curve or a hook it does not know is refused. An operator lifts a list by setting it to any. When a relayer refuses, the ticket shows why and offers the send from a fresh address.
What one proof can move
Adding to bins. One token per action: X into the bins above the active one, Y into those below, so both sides take two actions. An action covers up to 15 bins, in a shape you pick. You can also put some in the active bin, which pays the composition fee when the mix differs. Each bin comes out as its own note.
Removing from bins. One proof and one transaction per bin. Both tokens come out as notes. Swap fees stay in the bins and come out with the burn, so there is no separate fee claim.
Vaults. An LP vault takes one asset and pays it back. A DLMM vault takes one token through the zap, which swaps part of it into the other, and pays both tokens out. A stock vault takes two tokens and has no private lane. The perps vault has no synchronous exit, so a redeem reverts and the note stays unspent: its shares leave through a plain withdrawal to a fresh address, and the exit runs from there.
Range positions. A v4 range is two tokens in one position, so it stays public. From a private balance, use a swap and bin liquidity.
Launches
The curve's wallet limit counts the recipient. Inside the protected window each private buy goes through a fresh recipient, so the limit applies per buy and the protection fee is paid every time. Past the window, tokens go straight to custody.
A buy past the close is cut to fit, and the rest comes back as a note of the quote token. A buy that closes the curve also graduates it. Sells stay open until graduation. See Launchpad.
Paying the relayer
The fee comes from a private WETH note when the balance holds one, which keeps the token out of the fee. Otherwise it comes from the note's own token, if the relayer takes that token: WETH and USDG by default, and any other its operator lists.
Bin shares and positions pay a relayer only from private WETH, so a balance that relays them keeps a small WETH note. Otherwise the spend goes from a fresh address with no relayer fee.
A relayer limits requests per IP and attempts per note, and caps the gas of one transaction, at 12M by default.
A fresh address
If the relayer does not answer or will not take a spend, the ticket says so and offers a send from a fresh address derived from your keys. It needs a little ETH for gas and pays no relayer fee. You choose it each time: nothing falls back to it by itself, and it never uses your connected wallet. Funding it from your wallet links the two, so fund it with a private withdrawal of WETH as native ETH where you can.
When it fails
A failed minimum reverts the whole transaction, so the note stays unspent and you can try again, and the ticket says so. The relayer simulates before it sends, at the gas price it will pay. If a proof of a note reverts anyway, it waits an hour before it sends for that note again. A proof stops being valid 15 minutes after it was built, so a relayer cannot sit on one, and the note stays locked in your browser until then.
Nothing in the SDK leaves a trade unprotected by default. A vault or launch action takes its minimum from a quote, and a perp's limit comes from the oracle's price and slippageBps, 100 by default. To trade with no limit, say so with limitPrice: 0n. With no oracle price to go by, a perp call throws.
What the chain shows
A spent nullifier, the new commitments, the adapter and the trade itself: the token and amount going in, the route and its minimum in the call data, and each output's token and amount. The link back to your wallet is gone. What each lane shows has the table.
contracts/src/shielded/interfaces/IActionAdapter.solthe adapter interfacecontracts/src/shielded/adapters/SwapAdapter.solone adapter, in fullpackages/zk/src/lanes.tsevery private action from the browserapps/relayer/src/app.tsquotes and submission