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

FAQ

1. Which chains does SODAX support?

SODAX runs on 20 chains across two families. EVM (12): Sonic (hub), Ethereum, Arbitrum, Base, BSC, Optimism, Polygon, Avalanche, HyperEVM, Lightlink, Redbelly, Kaia. Non-EVM (8): Solana, Sui, Stellar, ICON, Injective, NEAR, Stacks, Bitcoin. Reference any chain via ChainKeys.*. The legacy *_CHAIN_ID constants are deprecated.

Full list with relay IDs: Relayer API endpoints.

2. 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.

3. 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.

4. How do I override the hub RPC or contract addresses?

Pass a partial hub block to the constructor:

new Sodax({ hub: { rpcUrl: '<https://rpc.soniclabs.com>' } })

Read the merged config from sodax.instanceConfig.hub. Note that sodax.config.getHubChainConfig() returns the packaged snapshot, not your overrides.

Full config reference: Configure SDK.

SDK behaviour

5. Why don't SDK methods throw?

Every public method returns Result<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.

6. How should I handle errors properly?

Switch on the narrow error.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.

7. 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, Relayer API endpoints.

8. 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.

Swaps and intents

9. 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 (Solver).

10. 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.

11. Can I cancel an intent?

Yes. Call cancelIntent(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.

12. Are intents trustless? Can a solver run off with funds?

No. Solvers cannot exit with user funds. They lock collateral in the IntentFiller 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

13. 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.

14. 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 network for cross-chain price execution. The bridge supports three directions: spoke to hub, hub to spoke, and spoke to spoke.

See Bridge and Swaps (Solver).

15. How do I estimate gas across different chain families?

Build a raw tx with raw: 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.

16. Can I stake SODA from a non-EVM chain like Sui or Stellar?

Yes. Every StakingService 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

17. How do partner fees work and how do I claim them?

Set swaps.partnerFee, moneyMarket.partnerFee and bridge.partnerFee independently on SodaxConfig. 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.

18. 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.

19. How do I wire SODAX into my AI coding agent (Claude Code, Cursor, Codex)?

From your project root run npx skills@latest add icon-project/sodax-sdks/packages/skills. The CLI detects your tool (Claude Code, Cursor, Codex, Copilot) and installs AGENTS.md plus per-feature SKILL.md files into the conventional location. Point your agent rules at the installed AGENTS.md, not the GitHub main branch, so version drift does not corrupt the routing.

See AI Integration.

20. 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-byte keccak256 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.


Workshop notes: rewrite, cut, or expand any of these. Once locked, the answers can drop straight into the existing FAQ page on docs.sodax.com (currently a TODO stub).

Last updated