1. Which chains does SODAX support?
SODAX runs on a hub-and-spoke network of mainnet chains. Sonic is the hub; spokes span EVM chains (Arbitrum, Avalanche, Base, BNB Chain, Ethereum, Hedera, Hyper, Kaia, LightLink, Optimism, Polygon, Redbelly, Robinhood Chain) and non-EVM chains (Bitcoin, ICON, Injective, Near, Solana, Stacks, Stellar, SUI) — both lists read live from the backend config API. Reference any chain viaChainKeys.*, which — together with the backend config — is the source of truth. The legacy *_CHAIN_ID constants were removed in v2; see Chain ID migration for the mapping.
Full list with relay IDs: Relayer API endpoints.
2. Is SODAX available on a testnet?
No — SODAX is mainnet-only. Every chain in the canonical@sodax/types config is a *_MAINNET entry; there are no testnet chain configs, RPC endpoints, or a network toggle, because SODAX’s cross-chain intents settle against real deployed contracts and live solver liquidity that only exist on mainnet. To build and test, use small amounts on mainnet and drive flows with the private-key wallet providers (see apps/node) rather than a testnet.
Full explanation and next steps: Is SODAX on Testnet?.
3. What is the difference between the hub and a spoke chain?
Sonic is the hub. All swap, lend, borrow, bridge and stake actions are coordinated by hub contracts (Intents, Asset Manager, Hub Wallet Factory). Spoke chains hold user funds and act as deposit and execution venues. The SODAX relayer carries cross-chain messages between them. Deep dives: Technical Overview, Asset Manager, Generalized Messaging Protocol.4. Do I need to call sodax.initialize() before using the SDK?
Not strictly. The constructor uses defaults packaged with the SDK version you installed. await sodax.initialize() fetches the latest tokens and chains from the backend API. Recommended for production, optional for prototypes. If it fails, the SDK falls back to packaged defaults rather than throwing.
See Configure SDK.
5. How do I override the hub RPC or contract addresses?
Pass a partialhub block to the constructor:
sodax.instanceConfig.hub. Note that sodax.config.getHubChainConfig() returns the packaged snapshot, not your overrides.
Full config reference: Configure SDK.
SDK behaviour
6. Why don’t SDK methods throw?
Every public method returnsResult<T, E> shaped as { ok: true, value } or { ok: false, error }. Do not wrap SDK calls in try/catch. Check result.ok first, then discriminate on result.error.code.
The pattern is canonical across modules: Backend API.
7. How should I handle errors properly?
Switch on the narrowerror.code union (for example VALIDATION_FAILED, RELAY_TIMEOUT, TX_SUBMIT_FAILED). Never branch on error.message, it is human-readable and may change. The original lower-level error is preserved on error.cause, structured metadata on error.context. Use the exported guards (isSwapError, isStakeOrchestrationError, isMigrateOrchestrationError, isPartnerError) in dapp code for cross-bundle type safety.
Per-module code tables: Swaps, Money Market, Bridge, Staking, Migration.
8. What should I do when a swap returns RELAY_TIMEOUT?
The spoke transaction landed but the hub packet has not arrived within the timeout window. The relay may still complete. Persist the spoke tx hash and poll the relayer API. Do not re-submit from the user side.
Error semantics: Make a swap (SDK), Relayer API endpoints.
9. What does TX_SUBMIT_FAILED mean?
The critical case. The spoke tx landed but the relay submission itself failed. Funds may be in flight. Persist the user’s input plus spoke tx hash and retry submission against the relay API. Do not retry the user-facing transaction.
Full code reference: Make a swap (SDK).
Swaps and intents
10. What is the difference between swap(), createIntent() and createLimitOrder()?
swap() is the recommended end-to-end path. It handles approval, intent creation, relay submission and solver notification automatically (signed execution only).
createIntent() is the lower-level primitive and supports both signed and raw modes (raw: true for custom signing flows).
createLimitOrder() produces an intent with no deadline. The user must cancel it manually.
Full method list: Swaps.
11. How do I get a swap quote and feed it into minOutputAmount?
Call sodax.swaps.getQuote(payload) with token_src, token_dst, source and destination ChainKeys, an amount in the token’s smallest unit, and quote_type: 'exact_input'. Use quoted_amount from the response to set minOutputAmount on the intent.
Walkthrough with code: Make a swap (SDK).
12. Can I cancel an intent?
Yes. CallcancelIntent(intent) on the Intents contract. The caller must be the creator, or the deadline must have passed. Intents with pending fills cannot be cancelled. Limit orders (deadline = 0) always require manual cancellation.
Contract interface: Intents.
13. Are intents trustless? Can a solver run off with funds?
No. Solvers cannot exit with user funds. They lock collateral in theIntentFiller contract on the destination spoke when filling. The hub is the source of truth for intent state and settlement, spokes act only as escrow and execution venues. Settlement reconciles cross-chain via the relay.
Detailed flow: Intents.
Lend, borrow, bridge, stake
14. Which actions actually need on-chain approval?
EVM spokes:supply and repay approve the Asset Manager contract.
Sonic hub: supply and repay approve the user’s hub router.
Stellar: supply, repay, withdraw, borrow all check and establish trustlines.
Borrow and withdraw on EVM and hub do not require approval. Most non-EVM chains require no on-chain approval at all.
Full matrix: Money Market.
15. How is the bridge different from a swap?
Bridge moves the same asset across chains using the hub vault, with no price discovery. Swap routes through the solver marketplace for cross-network price execution. The bridge supports three directions: spoke to hub, hub to spoke, and spoke to spoke. See Bridge and Swaps.16. How do I estimate gas across different chain families?
Build a raw tx withraw: true from any createIntent, createSupplyIntent, approve, etc. Then call the matching module’s estimateGas({ tx, chainKey }). The return shape depends on the chain family.
EVM, ICON, Stellar, Bitcoin, NEAR return a bigint. Sui returns { computationCost, storageCost, storageRebate, nonRefundableStorageFee }. Injective returns { gasWanted, gasUsed }. Stacks returns { low, medium, high } fee tiers. Solana returns number | undefined compute units.
Examples per chain: Estimate Gas.
17. Can I stake SODA from a non-EVM chain like Sui or Stellar?
Yes. EveryStakingService method accepts any SpokeChainKey as the source. If you pass ChainKeys.SONIC_MAINNET, the spoke and hub tx hashes are identical. Approval is required only on EVM spokes, the hub, and Stellar.
See Staking.
Monetization, integration, tooling
18. How do partner fees work and how do I claim them?
Set a global default with the top-levelfee, then override it per feature with swaps.partnerFee, moneyMarket.partnerFee, bridge.partnerFee and leverageYield.partnerFee on SodaxConfig — vault flows read the leverageYield slot, not swaps. getQuote deducts the swap partner fee from the input amount before forwarding to the solver, so no fee field appears in the request payload. Claim accrued fees via sodax.partners.feeClaim* methods, which return Result<T, PartnerError>.
Setup and claim flows: Monetize SDK.
19. When do I need the IntentRelayChainId versus ChainKeys?
The relay API identifies chains by a numeric IntentRelayChainId (for example BASE_MAINNET = 30n, SOLANA_MAINNET = 1n, BITCOIN_MAINNET = 627463n). The SDK converts internally. You only need getIntentRelayChainId(chainKey) when constructing raw relay requests directly, which is advanced usage.
Full mapping: Relayer API endpoints.
20. How do I wire SODAX into my AI coding agent (Claude Code, Cursor, Codex)?
From your project root runnpx skills@latest add icon-project/sodax-sdks/packages/skills. The CLI detects your tool (Claude Code, Cursor, Codex, Copilot) and installs five skill directories, each with its own SKILL.md, into the conventional discovery path (e.g. .claude/skills/sodax-<pkg>/). The CLI does not copy the package-level AGENTS.md — agents auto-discover the skills from SKILL.md frontmatter, so there is nothing to point your agent rules at. If you install via npm or a file: path instead, node_modules/@sodax/skills/AGENTS.md is the router.
See AI Integration.
21. What is hub wallet abstraction and when do I touch it directly?
The hub generates a deterministic user wallet on Sonic for every spoke address. For spoke chains with limited calldata, the SDK supports hashed calls: send a 32-bytekeccak256 payload to the hub, then execute the stored call later with the same data. The relayer handles this in normal flows. You only touch it directly when building custom orchestration or recovering stuck cross-chain executions.
See Hub Wallet Abstraction.
22. Can my AI agent query SODAX docs directly instead of web-searching?
Yes, two ways. This documentation site hosts an auto-generated MCP server atdocs.sodax.com/mcp that exposes a search tool over these pages — add it to your agent’s MCP config, or use the “Add to [agent]” option in the contextual menu on any page. For more than doc search, add the Builders MCP (https://builders.sodax.com/mcp): 40 tools giving the agent live chains, tokens, quotes, money market rates, intent lookups and these docs, over one endpoint.
See Builders MCP and AI Integration.