Swaps is currently an Early Access Product. Contact us to enable it for your organization.
- Swaps Early Access enabled for your organization
- A Turnkey API key pair
- A wallet account holding USDC on Base, plus ETH on Base for gas if you don’t sponsor
- An EVM wallet account in your parent organization to receive your fee payouts
1
Initialize the client
All requests go through the generic
request method of TurnkeyClient, stamped by your API key. Execution confirms asynchronously, so define a polling helper here as well.2
Configure your fee
One-time setup on your parent organization: your rate in basis points and the wallet account that collects it. The configuration applies to every swap under the parent organization, and quotes reflect it from this point on; without one, quotes carry a client fee of 0.
3
Request a quote
USDC has 6 decimals, so 100 USDC is
"100000000" raw units. Both chains derive from the CAIP-19 identifiers — matching prefixes here (eip155:8453) make this a same-chain swap.4
Show the user the quote
Quoted amounts are already net of all fees — Turnkey’s and yours — so
outputAmount is what the recipient receives. Check expiresAt before executing; an expired quote fails, and a fresh quote is more likely to fill.5
Execute the swap
Execution is pinned to the quote: pass its
quoteId and restate the economics the user was shown. Turnkey constructs the transaction, batches any required ERC-20 approval into it, signs with the wallet derived from the quote, and broadcasts. The signer is not resupplied here — it comes from the bound quote.With sponsor: false, the wallet pays its own gas. Set it to true to have Gas Station cover it (requires gas sponsorship enabled for your organization).6
Poll to settlement
ACTIVITY_STATUS_COMPLETED on the execute activity only means the swap was accepted and enqueued. Poll get_swap_status with the swapRequestId until it reports a terminal state — that’s the only place the actual settled amount appears.FAILED, error.reason is either ORIGIN_TRANSACTION_FAILED (never broadcast, or reverted onchain) or PROVIDER_FILL_FAILED (origin succeeded, provider could not fill). Refund details are enriched shortly after the status flips, so they may be absent on the first FAILED response. See What FAILED means.Going cross-chain
The same code runs a cross-chain swap — only theoutputToken changes. Give it a different CAIP-2 prefix — say USDC on Arbitrum, eip155:42161/erc20:<USDC_ON_ARBITRUM> — and the provider routes it across chains where it supports the pair. Asset identifiers come from list_supported_assets.
Two things differ after broadcast:
- The swap stays
PENDINGpast origin-chain inclusion until the destination leg settles, so poll every 5–10 seconds rather than every second. - On
COMPLETED,destinationTxHashescarries the destination-chain transactions.swapKindin the response tells you which model applied.
Dive deeper
Swaps overview
— Fee model, chains, routes, and the full API surface.
Enable swaps
— Fee configuration and the fee receiver.
Get a quote
— Quote fields, expiry, and slippage.
Execute a swap
— Gas sponsorship, approvals, and the trust boundary.
Track swap status
— Lifecycle states, failures, and refunds.