Starknet’s privacy pool (STRK20) lets users hold tokens in a shielded balance that only their wallet can see. A private swap spends from that balance and puts the tokens bought into a new shielded balance. The trade itself happens in public, through Tern’s swap contract like any same-chain swap, but nothing on chain shows who made it or who received the tokens. Tern submits the transaction, so the user’s account never appears. This guide swaps 50 USDC for STRK from a shielded balance.

Before you start

The user needs:
  • a wallet that supports the STRK20 wallet API 0.10.3 or later (starknet.js WalletAccountV6);
  • a shielded balance of the token they’re selling, worth at least $20;
  • some shielded STRK to cover the transaction fee.
Users add tokens to their shielded balance with a deposit into the pool from their wallet. That deposit is public, like any transfer.
1

Get a price

Ask for a Starknet same-chain quote with "privacy": "shielded", and leave out sender and recipient. Since the request names no address, Tern never links the swap to a wallet.
The answer looks like any swap price, with two differences:
  • fees has a privacy line instead of network: the privacy pool’s fee and the gas to submit the transaction.
  • sourceGas is that same fee in STRK. The user’s shielded STRK must cover it, on top of any STRK they’re selling.
Below $20, the answer is 400 amount_too_small, because the pool’s fee would take too large a share.
2

Get the firm quote

When the user confirms, ask again with "firm": true:
execute.strk20 is the private transaction for the user’s wallet to prepare. It has four steps, called actions:
  1. Send the tokens being sold to TernPrivateSwap, Tern’s private swap contract.
  2. Pay the transaction fee, in STRK, to Tern’s submitter (the relayer).
  3. Open a new shielded balance for the tokens being bought, owned by the user.
  4. Run the swap, which deposits the tokens bought into that new balance.
Two placeholders need filling. The wallet fills in ${openNoteIds[0]} itself. Tern doesn’t know the user’s address, so you replace ${self} with the user’s Starknet address before the wallet prepares the transaction.The firm quote lasts about three minutes, which is enough time to prepare it.
3

Check it, then have the wallet prepare it

Before preparing, check the actions match what the user asked for, using the addresses you hard-coded from Contract addresses:
  • Action 1 sends exactly the amount being sold to TernPrivateSwap.
  • Action 2 pays STRK, no more than relayerFee.amount, to relayer.
  • Action 3 opens a balance of the token being bought, for the user.
  • Action 4 calls TernPrivateSwap. It sells exactly the amount asked, buys the token asked for at no less than to.minAmount, and names TernPrivateSwap as the recipient. Its data is the order, the route, and the new balance, nothing else.
Then ask the wallet to prepare the transaction without sending it. It produces a proof that the user is allowed to spend the balance:
This takes from a few seconds to a minute.
4

Submit it before expiresAt

Send the prepared transaction to Tern. Tern simulates it first, and submits it only if it goes through the privacy pool, pays the fee, and makes this exact swap.
Tern answers 202 Accepted with the swap’s id, its status, and the transaction hash once it’s been signed. Submitting the same quote again returns the same transaction.
5

Track it

GET /v1/quote/{id} shows completed once the swap confirms. The tokens bought appear in the user’s shielded balance the next time their wallet refreshes.Private swaps don’t name any address, so searching by address won’t find them. Keep their quote IDs yourself.

If something goes wrong

Costs

  • Tern’s fee, the same as on a public swap (protocol).
  • The transaction fee, in STRK (privacy): the privacy pool’s fee for each private transaction, plus the gas to submit it. The pool sets its own fee, and Tern reads it from the pool. Tern pays the pool when it submits and is repaid by action 2 in the same transaction.

What stays public, and what stays private

How it differs from a public swap

  • Starknet only, and on one chain only.
  • The swap must use the full amount sold. If it can’t, the transaction reverts and nothing is spent.
  • The firm quote names no address, and lasts about three minutes instead of one.