Skip to main content
WalletSwaps runs same-chain and cross-chain swaps from a Server Wallet. A swap is quoted first, reviewed by your application, and only then confirmed, so no funds move on a quote alone. Swaps are durable. Progress continues across restarts, which means your application supplies storage and a scheduler rather than awaiting a single call. Import the swap surface from the SDK’s /trails entry point:

Configure the swap client

Four of these deserve attention:
  • assets is your own allowlist of tradable assets. A swap request naming an asset outside it is rejected, which is what keeps a caller from routing funds into an arbitrary token.
  • executor must be the same exclusive executor that your ordinary transfers use. Swaps and transfers debit the same wallet, so they have to serialize against each other. See storage and concurrency.
  • trails.apiKey is separate from your OMS publishable key and belongs only in your backend. Omitting trails raises SWAPS_UNAVAILABLE.
  • enabled must be true to start new swaps. When it is not, SWAPS_DISABLED is raised and existing swaps still progress.
EvmChainReader accepts one HTTPS RPC URL per chain. URLs carrying credentials or a fragment are rejected.

Quote a swap

amount is a decimal string in the origin asset’s base units, so '10000000' is 10 USDC at 6 decimals. Never pass a floating-point token amount. slippageBps accepts 10, 50, or 100. A same-chain swap uses the same call with one chainId on both sides. The wallet must be restored before quoting, otherwise WALLET_PENDING is raised.

Review and confirm

Quoting does not move funds. The swap stays in the quoted phase until you confirm it with the exact quote revision you reviewed. quote carries the terms your review should apply to:
If the quote changed since you read it, confirmSwap raises STALE_QUOTE rather than executing against terms you did not review. Re-read the swap, apply your rules to the new quote, and confirm that revision. Confirming is idempotent. A second call with the same revision returns the current state instead of starting another swap.

Drive and track progress

A confirmed swap advances through activation, funding, and settlement. Your application drives that work:
tick(limit) performs the work that is due and returns. nextAt on a swap view tells you when that swap next needs attention, or is null when it needs none. Funding a swap uses a sponsored transfer, so the wallet pays no gas. Use reconcileSwap(id) when a swap’s upstream result is uncertain. As with transfers, never start a second swap because a response was lost.

Phases

attention is not a failure. It means the swap cannot proceed without a decision from you, so surface it rather than retrying it.

Recovery

When a swap leaves funds short of the destination, prepareRecovery builds a recovery that returns them to the wallet, and confirmRecovery authorizes it. Recovery follows the same review-then-confirm shape as a swap, and it is restricted to the wallet’s own address and your reviewed assets. Recovery is available even when enabled is false, so turning off new swaps does not strand funds from existing ones.

Errors