Solver API endpoints

Error handling conventions: Direct callers of SolverApiService (used by lower-level scripts and tests) still receive SolverErrorResponse with detail.code / detail.message. The swap module's postExecution wraps these into SodaxError with code EXTERNAL_API_ERROR; the original SolverIntentErrorCode is on result.error.context.solverCode and the full detail is on result.error.context.solverDetail — see SWAPS.mdarrow-up-right Error Handling.

Mainnet production

URL: https://api.sodax.com/v1/intentarrow-up-right

Mainnet staging

URL: https://staging-new-world.iconblockchain.xyzarrow-up-right

Note Staging endpoint contains features to be potentially released and is subject to frequent change!


Overview

The SODAX solver API drives the intent-based swap feature. SwapService (accessed via sodax.swaps) is the public entry point — it delegates all HTTP communication to the stateless SolverApiService class. External callers should use SwapService rather than calling SolverApiService directly.

Three endpoints are exposed:

Endpoint
Method
Purpose

/quote

POST

Get a price quote for a token pair and amount

/execute

POST

Notify the solver that an intent is live on the hub chain

/status

POST

Poll the execution status of a submitted intent


Error handling

All three solver methods return Promise<Result<T, SolverErrorResponse>>. On HTTP errors or network failures, result.ok is false and result.error is a SolverErrorResponse:

SolverIntentErrorCode is an enum defined in @sodax/sdk. On unhandled exceptions the code is SolverIntentErrorCode.UNKNOWN.

To branch on solver errors, inspect result.error.detail.code:


POST /quote — Get a price quote

Called via SwapService.getQuote(payload).

Request (SolverIntentQuoteRequest)

Field
Type
Description

token_src

string

Source token address on its spoke chain

token_dst

string

Destination token address on its spoke chain

token_src_blockchain_id

string

Source spoke chain relay ID (e.g. '0x38.bsc')

token_dst_blockchain_id

string

Destination spoke chain relay ID (e.g. '0xa4b1.arbitrum')

amount

bigint

Input amount in the source token's smallest unit

quote_type

string

'exact_input' or 'exact_output'

SwapService.getQuote automatically adjusts amount by the configured partner fee before forwarding to the solver, so the returned quoted_amount reflects the net output the user receives.

Token addresses are validated against the active ConfigService and translated to their hub (Sonic) equivalents before the request is sent.

Response (SolverIntentQuoteResponse)

quoted_amount is in the destination token's smallest unit.

Example


POST /execute — Notify solver of a live intent

Called via SwapService.postExecution(request). Invoked automatically by SwapService.swap() after the relay packet lands on the hub — call this manually only when orchestrating swap steps yourself.

Request (SolverExecutionRequest)

Field
Type
Description

intent_tx_hash

Hex

Hub-chain (Sonic) transaction hash where the intent was registered

The request is retried automatically on transient network failures.

Response (SolverExecutionResponse)

Example


POST /status — Poll intent execution status

Called via SwapService.getStatus(request).

Request (SolverIntentStatusRequest)

Field
Type
Description

intent_tx_hash

Hex

Hub-chain (Sonic) tx hash of the intent. This is the dst_tx_hash from the relay packet returned by swap() or relayTxAndWaitPacket.

Response (SolverIntentStatusResponse)

Field
Type
Description

status

SolverIntentStatusCode

Numeric status code (see below)

fill_tx_hash

string | undefined

Solver's fill tx hash — present only when status === SolverIntentStatusCode.SOLVED (3)

SolverIntentStatusCode is an enum in @sodax/sdk. The value 3 (SOLVED) indicates the solver has filled the intent.

Example


Full swap flow

SwapService.swap() orchestrates the complete lifecycle. The steps below show what happens internally and where each solver endpoint is called:

Polling intent status and waiting for fill delivery are separate steps the caller performs after swap() returns:

Complete example


Chain keys

Use ChainKeys.* from @sodax/sdk for all chain references. SpokeChainKey is the union of ChainKeys values. XToken.chainKey (not xChainId) carries the chain key on token objects.

Intent.srcChain and Intent.dstChain are bigint relay chain IDs (not chain keys) — use getIntentRelayChainId(chainKey) from @sodax/sdk to convert between them.


  • packages/sdk/src/swap/SolverApiService.ts — stateless HTTP client for the three solver endpoints

  • packages/sdk/src/swap/SwapService.ts — public service facade; use sodax.swaps

  • packages/sdk/src/swap/EvmSolverService.ts — EVM-level intent ABI encoding/decoding and event parsing

  • packages/sdk/docs/SWAPS.md — full swap feature documentation

  • packages/sdk/docs/ARCHITECTURE_REFACTOR_SUMMARY.md — v2 architecture reference (chain keys, Result<T>, error convention)

  • packages/sdk/CHAIN_ID_MIGRATION.md — mapping from old *_CHAIN_ID constants to ChainKeys.*

Last updated