For the complete documentation index, see llms.txt. This page is also available as Markdown.

Swaps on Solana

Intent-based cross-network swaps from a Solana perspective: one signed transaction, solver-filled, settled across networks.

SODAX swaps are intents, not bridges. Your user signs one transaction on Solana that locks the input and declares what they want on the destination network. Solvers compete to fill it; the SODAX relayer carries proof between Solana, the hub (Sonic), and the destination. If nothing fills, the intent can be cancelled and funds recovered.

From your side it is one SDK call. From your user's side it is one Phantom prompt.

What this looks like on Solana

  • Source: the intent transaction is a normal Solana transaction signed by the user's wallet. ChainKeys.SOLANA_MAINNET ('solana') identifies the chain everywhere in the SDK.

  • Reach: any solver-compatible asset on any SODAX network is a valid destination, 137 assets as of July 2026. The on-Solana asset list only bounds what users hold on Solana itself, not what they can swap into.

  • No approvals: there is no ERC-20 style allowance on Solana. isAllowanceValid always returns true; you can go straight from quote to swap.

  • Settlement: output lands on the destination network at dstAddress. Swaps into Solana settle to the user's address as SPL balances.

  • Raw mode: methods that support raw: true return a SolanaRawTransaction when the source is Solana, TypeScript-narrowed from srcChainKey, if you want to control signing and broadcast yourself.

Quoting

The solver API quotes both directions:

const quoteResult = await sodax.swaps.getQuote({
  token_src: sol.address,             // token on Solana
  token_dst: usdc.address,            // token on the destination network
  token_src_blockchain_id: ChainKeys.SOLANA_MAINNET,
  token_dst_blockchain_id: ChainKeys.ARBITRUM_MAINNET,
  amount: 100_000_000n,
  quote_type: 'exact_input',          // or 'exact_output'
});

getQuote deducts any configured partner fee before quoting, so quoted_amount is the net output the user actually receives.

Fees

Using SODAX is free to integrate. Two fees can apply to a trade:

  • Base fee: a fixed 0.1% of the input, taken by the protocol. Not configurable; compute it ahead of time with getSolverFee(inputAmount).

  • Your fee: optional platform fee on top, set by you and paid to you. It is the only fee you control. Configure it at SDK setup and check it with getPartnerFee(inputAmount). See Monetize SDK.

Executing

Prefer swap(). It creates the intent on Solana, verifies it landed, submits it to the relay, waits for the packet on the hub, and notifies the solver:

Track progress with getStatus(request), and cancel unfilled intents with cancelIntent. Limit orders (intents without deadlines) work from Solana too, via createLimitOrder.

Orchestrating manually? One Solana-specific step

If you use createIntent + submitIntent instead of swap(), note that Solana (and Bitcoin) intents require relay extra data. Fetch it with getIntentSubmitTxExtraData and pass it as data in the relay submission:

swap() does this automatically; most integrations never touch it.

Error handling

Every method returns Result<T> instead of throwing. The core methods (swap, createIntent, postExecution) return a typed SodaxError union you can switch on by error.code.


Full reference, including raw mode, limit orders, cancellation, and the complete error-code table: Swaps (Solver).

Last updated