Preview. Requires
@avnu/avnu-sdk >= 4.1.0-next.2 and the Starknet privacy SDK. Questions? Reach out on Telegram.Prerequisite: the sell token must already be in your private balance. Deposit into the privacy pool first.
Setup
The snippets below assume a few objects are already wired up. Here is where each one comes from:| Identifier | Source |
|---|---|
getQuotes, quoteToCalls, serializeCalls | @avnu/avnu-sdk |
account | your Starknet account (e.g. starknet.js Account) |
transfers, provingBlockId, Open | the Starknet privacy SDK |
paymaster | the privacy SDK’s paymaster client, pointed at avnu’s paymaster endpoint |
POOL | the privacy pool address (from the SDK or the team) |
paymaster is the client that calls avnu’s paymaster service at starknet.paymaster.avnu.fi (or sepolia.paymaster.avnu.fi for testing). It is not starknet.js’s PaymasterRpc: that client only handles the standard invoke and deploy types, while private transactions use apply_action and invoke_and_apply_action, which the privacy SDK’s client builds and submits. For the sponsored and sponsored_private modes, give it your Portal API key, the same one used for gasfree.
How it works
A private swap is anapply_action transaction. No user signature is needed, since every call settles on-chain straight from the proof:
- Quote and private calls. Call
getQuotes, thenquoteToCalls({ private: true }). The backend setstakerAddress = executorand returns the inner swapcallsplus theexecutorAddress. - Build. Call
paymaster.buildTransactionwithfee_mode: "sponsored_private". The server returns thefee_action, the pool fee you need to withdraw in your chosen token. - Proof. Using the privacy SDK, withdraw the sell token to the executor, withdraw the pool fee, and open a note for the bought token, then
invokethe executor with the serialized swap calls. - Execute.
paymaster.executeTransactionrelays the proof. The relayer pays gas and the forwarder collects the pool fee.
Step by step
1. Quote and build private swap calls
Passprivate: true to quoteToCalls. The backend routes the swap through avnu’s executor and returns its address, so you do not set takerAddress on quoteToCalls yourself.
2. Build the sponsored-private transaction
CallbuildTransaction with the apply_action type and the sponsored_private fee mode. The pool_fee_token is the token you want to pay the pool fee in (here, STRK). The response’s fee_action tells you the recipient and amount to withdraw for the pool fee.
3. Build the proof
With the privacy SDK’stransfers builder, on the sell token withdraw the sellAmount to the executor, withdraw the pool fee (build.fee_action), and route any surplus back to the user. On the buy token, open a note to receive the output, then invoke the executor with the serialized swap calls and the opened note id.
Open is a privacy SDK sentinel that opens a note for the swap output, whose amount is only known after execution. See Setup for where transfers, paymaster, and the other objects come from.4. Execute
Relay the proof through the paymaster. No signature is needed forapply_action, since everything settles from the proof on-chain.
Full example
Sponsored Private Swap (STRK → ETH)
Key parameters
On
quoteToCalls, builds swap calls for private execution. The backend sets takerAddress = executor and returns executorAddress alongside the inner calls. Do not pass takerAddress to quoteToCalls when private: true.Use
sponsored_private so the relayer pays gas and the user pays the pool fee from their private balance. Only valid for private transaction types, otherwise it returns error 168.Token used to pay the pool fee (e.g. STRK, ETH, USDC). The paymaster converts the base STRK amount to this token via its price oracle and returns the result in
build.fee_action.amount.Related
Privacy Overview
Privacy pool, fee modes, and transaction types
Get Quotes
Fetch solver-optimized swap quotes