Before you start
- Somewhere to store one secret per swap, encrypted, on your server or in the user’s app. Without the secret, a swap can’t complete and only refunds.
- A connection to each destination chain you support (an RPC endpoint), so you can check the solver’s tokens yourself.
- The user’s address on both chains. Refunds go to the source-chain address, so it must be one the user controls.
- An API key, for production. You can build and test without one: see Authentication and limits.
1
Create a secret
Generate 32 random bytes with a secure random generator. This secret is what completes the swap. Tern’s API calls it the Use a new secret for every swap. Tern refuses a hash that any earlier quote used (
fulfillment.Its SHA-256 hash is what you share with Tern up front. The API calls it the executionCondition.409 condition_reused), because one revealed secret would unlock every swap that shared it.2
Get a firm quote
When the user confirms the price, ask for a firm quote. It’s the same request as a price, plus three fields:
sender: the user’s address on the source chain, where any refund goes.recipient: the user’s address on the destination chain.executionCondition: the hash from step 1.
slippageBps: how far below the expected amount the user accepts, in case the solver has to buy the token they want. It’s 50 (0.5%) by default and at most 300 (3%). Add an Idempotency-Key header so a retried request returns the same quote.ididentifies this swap from now on. Store it with the secret.to.amountis what the user should receive. If the quote also hasto.minAmount, that’s the least they’ll receive: show both. See Amounts.expiresAtis the deadline to deposit, 30 minutes from now.executeis how the user deposits, in the next step.
3
Take the deposit
Before Once you have the deposit’s transaction hash, you can send it to
expiresAt, the user deposits in one of two ways.- From the user's wallet
- To a deposit address
- EVM chains: send
execute.transactionsin order fromsender. An approval is included only when it’s needed. USDT on Ethereum may get an extra approval of zero first, because that token requires it. - Starknet: send
execute.callstogether, as a single transaction, fromsender.
POST /v1/index so the status updates sooner. Tern finds the deposit either way.4
Wait for the solver
Check the swap’s status with At
GET /v1/quote/{id}, or receive it through webhooks. It moves from awaiting_deposit to deposit_confirmed once the deposit is confirmed, then to in_progress once the solver has locked the user’s tokens on the destination chain.in_progress, move to the next step. If the status becomes refunded or expired instead, the swap is over: see If something goes wrong. Track a swap covers how often to check and what each field means.5
Check the solver's tokens
Before you reveal the secret, confirm on the destination chain that the solver has really locked the user’s tokens. Use your own connection to the chain, not Tern’s status or a webhook: this check is what makes revealing safe.The solver locks the tokens in Tern’s escrow contract, in one or more locks tied to your hash. Check that:
- Every lock you count is still open, pays
recipient, holdsto.asset, and has at least 30 minutes before it expires. - Together they hold at least
to.minAmount, orto.amountif the quote has no minimum.
Prepared events that carry your hash. On EVM chains the hash is the event’s third indexed field (topics[3]), and escrows(escrowId) returns each lock’s amount and state (1 means still open). On Starknet the hash is a key of the Prepared event, and get_escrow(escrow_id) returns the same. The exact event formats are in the specification.If the solver locked less than the minimum, don’t reveal. Wait a few minutes for it to add the rest; if it doesn’t, the swap refunds.6
Reveal the secret
Send the secret from step 1 to Tern, with an Tern answers
Idempotency-Key:202 Accepted and pays the user on the destination chain. It runs the same checks first. If the solver’s tokens aren’t ready yet, it answers 409 destination_not_ready and does nothing: wait a few seconds and try again with the same key.Keep checking the status until it’s completed. destination.txHash is the transaction that paid the user.If something goes wrong
Next steps
Track a swap
Follow statuses and show users their swap history.
Webhooks
Get every status change sent to your server.
Refunds
Every way a swap can end without completing.
Errors
Every error and what to do about it.