The SODAX SDK gives you direct, simplified access to SODAX’s Unified Liquidity Layer — connecting liquidity across (a current) 12 chains and 6 tech stacks, with fast settlement and intent-based execution. To find out which ecosystems will be joining the SODAX SDK soon, you can browse our roadmap.
The SDK abstracts away cross-chain complexity, so you can integrate intent swaps, lending, and borrowing with a few lines of code, supporting both EVM and non-EVM networks. This guide walks you through a complete integration: from installation and configuration to enabling chains, executing swaps, and interacting with the money market. Build multichain DeFi without the headache.
Purpose for the core SDK:
- To enable usage of all SODAX features in a seamless way.
- To provide partners with a whole suite of functions required to complete specific user actions (e.g. swap).
- To abstract away the complexity of cross-chain logic, assembling of the low level transactions and other data structures. Users and partners do not need to know anything about how cross-chain infrastructure works.
- To provide configurations and constants as well as primitive type interfaces which enable dependency free (primitive types based only) interaction with our core SDK.
Step-by-step integration walkthrough
Process accurate as of Aug 7 2025: Code snippets are merely for illustration purposes, latest code may differ due to the active ongoing improvements.
1. Install @sodax/sdk NPM package
Currently SODAX SDK’s only support typescript and javascript environments.
Shell commands for installing the package using different package managers:
1// using npm2npm install @sodax/sdk34// using pnpm5pnpm add @sodax/sdk67// using yarn8yarn add @sodax/sdk
2. Instantiate SODAX instance
All SODAX core features (swap, money market) are reachable through SODAX instances which must be constructed as a class. A SODAX instance can be created with or without configuration - in this case default mainnet configuration is used. Using SODAX features requires only a single instance, thus we suggest you treat it as a singleton.
If you are a protocol integrating SODAX as part of your suite, you can monetize it by configuring a partner fee.
See examples on how to instantiate a default or customized SODAX instance below:
1// Initialize Sodax using default Sonic mainnet configurations (no fees)2const sodax = new Sodax();34// Partner fee can be defined as a percentage or a definite token amount.5// Fee is optional, you can leave it empty/undefined.6const partnerFeePercentage = {7 address: '0x...', // address to receive fee too8 percentage: 100, // 100 = 1%, 10000 = 100%9} satisfies PartnerFee;1011const partnerFeeAmount = {12 address: '0x...', // address to receive fee too13 amount: 1000n, // definite amount denominated in token decimal precision14} satisfies PartnerFee;1516// Use default config but put fee on solver (intent swaps)17const sodaxWithSolverFees = new Sodax({18 solver: { partnerFee: partnerFeePercentage },19});2021// Use default config with fee on money market (borrows)22const sodaxWithMoneyMarketFees = new Sodax({23 moneyMarket: { partnerFee: partnerFeePercentage },24});2526// or use default config with fees on both solver and money market27const sodaxWithFees = new Sodax({28 solver: { partnerFee: partnerFeePercentage },29 moneyMarket: { partnerFee: partnerFeePercentage },30});
Full Customization:
1// example of custom solver config2const customSolverConfig = {3 intentsContract: '0x...',4 solverApiEndpoint: 'https://...',5 partnerFee: partnerFeePercentage, // or partnerFeeAmount6} satisfies SolverConfigParams;78// pre-defined default solver config per hub chain id (Sonic hub is the default)9const solverConfig: SolverConfigParams = getSolverConfig(SONIC_MAINNET_CHAIN_ID);1011// example of custom money market config12const customMoneyMarketConfig = {13 lendingPool: '0x...',14 uiPoolDataProvider: '0x...',15 poolAddressesProvider: '0x...',16 bnUSD: '0x...',17 bnUSDVault: '0x...',18} satisfies MoneyMarketConfig;1920// pre-defined default money market config per hub chain id (Sonic hub is the default)21const moneyMarketConfig = getMoneyMarketConfig(SONIC_MAINNET_CHAIN_ID);2223// example of custom hub config24const hubConfig = {25 hubRpcUrl: 'https://rpc.soniclabs.com',26 chainConfig: getHubChainConfig(SONIC_MAINNET_CHAIN_ID),27} satisfies EvmHubProviderConfig;282930// Initialize Sodax using custom/default configurations31const sodax = new Sodax({32 solver: solverConfig,33 moneyMarket: moneyMarketConfig,34 hubProviderConfig: hubConfig,35});
3. Enable chains and connectivity
SODAX provides support for EVM (Arbitrum, Avalanche, Base, BSC, ...) and many non-EVM chains (Sui, Solana, Injective, ...). You can refer to SDK docs to see the up to date list of chains supported per each SODAX feature.
In SODAX SDK we name every supported chain on which SODAX features can be invoked as a “spoke chain” .The core chain is named “hub chain” because it is a hub for all of the spokes. In our case the hub is the Sonic chain. Partners should only have to deal with the spoke chains (Sonic is also treated as one) since our SDK abstracts away the complexity of dealing with hub chain logic.
If you want to interact with a specific selection of chains, you need to:
- Pick out chains (by ID) you want to support from predefined constants found in here. Note that SODAX uses custom chain IDs which may not reflect the “native” chain ID.
- Create a Spoke Provider instance for each of the chains you want to support. A Spoke provider is a logical entity representing a connection to a specific chain and should be treated as a singleton instance.
Available spoke chain configuration constants and utils:
1import {2 SPOKE_CHAIN_IDS, // array of currently supported spoke chain ids3 supportedSpokeChains, // alias for SPOKE_CHAIN_IDS4 isValidSpokeChainId // util function to check if certain chain ID is valid5} from '@sodax/sdk';
Example of creating an instance of EVM chain type Spoke Provider:
1// BSC spoke chain provider of EVM type2const bscSpokeProvider: EvmSpokeProvider = new EvmSpokeProvider(3 evmWalletProvider, // connected wallet constructed using Wallet SDK or implementation of IEvmWalletProvider interface4 spokeChainConfig[BSC_MAINNET_CHAIN_ID], // connected chain config5);
SODAX SDK enables you to choose whether to use our (Wallet SDK) or your custom implementation of wallet connectivity. Example implementation for each supported chain can be found inside wallet providers directory of the Wallet SDK.
4. Accessing SODAX features
At the time of writing this SODAX supports two main features: swap and money market.
Swap (Intents & Solver)
Swaps are enabled by intent and solver technology where the user initiates an intent and solver tries to solve it as efficiently as possible.
You should be able to retrieve all supported tokens per chain from our preconfigured constants.
All supported tokens per chain can be retrieved or verified as following:
1import { getSupportedSolverTokens, SpokeChainId, Token } from "@sodax/sdk"23// using spoke chain id to retrieve supported tokens for solver (intent swaps)4const supportedSolverTokens: readonly Token[] = getSupportedSolverTokens(spokeChainId);56// check if token address for given spoke chain id is supported in solver7const isSolverSupportedToken: boolean = isSolverSupportedToken(spokeChainId, token)
In order to create a successful swap you need to:
- Get a quote (kind of optional but advised in order to derive the minimal expected output amount and price). Request a Quote docs can be found here.
- Check allowance and approve the token spending if required
- Create a swap if you are satisfied with the given quote and allowance to transfer tokens is valid
Example quote request:
1const quoteRequest = {2 token_src: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', // ETH token on BSC3 token_dst: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', // wBTC token on ARB4 token_src_blockchain_id: BSC_MAINNET_CHAIN_ID, // src spoke chain id5 token_dst_blockchain_id: ARBITRUM_MAINNET_CHAIN_ID, // dst spoke chain id6 amount: 1000n, // amount of src token to swap7 quote_type: 'exact_input',// quote type: "exact_input" or "exact_output"8} satisfies SolverIntentQuoteRequest;910const result = await sodax.solver.getQuote(quoteRequest);
After you are satisfied with the quote you can create intent params as following:
1const createIntentParams = {2 inputToken: '0x..', // The address of the input token on spoke chain3 outputToken: '0x..', // The address of the output token on spoke chain4 inputAmount: BigInt(1000000), // The amount of input tokens5 minOutputAmount: BigInt(900000), // min amount you are expecting to receive6 deadline: BigInt(0), // Optional timestamp after which intent expires (0 = no deadline)7 allowPartialFill: false, // Whether the intent can be partially filled8 srcChain: BSC_MAINNET_CHAIN_ID, // Chain ID where input tokens originate9 dstChain: ARBITRUM_MAINNET_CHAIN_ID, // Chain ID where output tokens should be delivered10 srcAddress: '0x..', // Source address (original address on spoke chain)11 dstAddress: '0x..', // Destination address (original address on spoke chain)12 solver: '0x0000000000000000000000000000000000000000', // Optional specific solver address (address(0) = any solver)13 data: '0x', // Additional arbitrary data14} satisfies CreateIntentParams;
Once you have intent params established you should first make sure that SODAX has an allowance to transfer the token amount you want to swap.
Example on how to check allowance and approve if needed:
1// First check if approval is needed2const isApproved = await sodax.solver.isAllowanceValid(3 createIntentParams,4 bscSpokeProvider5);67if (!isApproved.ok) {8 // Handle error9 console.error('Failed to check allowance:', isApproved.error);10} else if (!isApproved.value) {11 // Approve Sodax to transfer your tokens12 const approveResult = await sodax.solver.approve(13 bscEthToken, // BSC ETH token address14 createIntentParams.inputAmount, // Amount to approve15 bscSpokeProvider16 );1718 if (!approveResult.ok) {19 // Handle error20 console.error('Failed to approve tokens:', approveResult.error);21 } else {22 // wait for tx hash from approveResult.value to be mined before proceeding23 }24}
After allowance for SODAX to transfer your tokens is approved you can create swap as following:
1const swapResult = await sodax.solver.swap(2 createIntentParams,3 bscSpokeProvider,4 );56 if (!swapResult.ok) {7 // handle error as described in Error Handling section8 }910 // txHash and created Intent data as Intent & FeeAmount type11 const [txHash, intent] = swapResult.value;
Error handling for swaps are very important and so we have implemented relevant guards to handle errors as described in the Handling Swap Errors section of the docs.
If you require higher customization of individual execution steps (create intent, relay tx) you can find more docs here. We also provide the ability to estimate gas for each kind of money market related action. You can find docs on how to do that here.
After a swap intent is created you can:
- Get intent status to check what state intent is currently in
- Cancel swap intent
Get intent status:
1const result = await sodax.solver.getStatus({2 intent_tx_hash: '0x...', // tx hash of create intent blockchain transaction3} satisfies SolverIntentStatusRequest);
Cancel swap intent:
1const result = await sodax.solver.cancelIntent(2 intent,3 bscSpokeProvider,4 hubProvider,5 false, // true = get raw transaction, false = execute and return tx hash6);78if (result.ok) {9 console.log('[cancelIntent] txHash', txResult.value);10} else {11 // handle error12 console.error('[cancelIntent] error', txResult.error);13}
Money market
The Money Market part of SDK provides abstractions to assist you with interacting with the cross-chain Money Market smart contracts.
You can retrieve all supported tokens per chain from our preconfigured constants.
All supported tokens per chain can be retrieved or verified as following:
1// using spoke chain id to retrieve supported tokens address2const supportedMoneyMarketTokens: readonly Token[] = getSupportedMoneyMarketTokens(spokeChainId)34// check if token address for given spoke chain id is supported5const isMoneyMarketSupportedToken: boolean = isMoneyMarketSupportedToken(spokeChainId, token)
Our money market supports the following user actions:
- Supply
- Borrow
- Repay
- Withdraw
In order to successfully use those features you need to:
- Check allowance for the action and approve token transfer if needed
- Execute the action
Example flow of supply action execution:
- Create supply params:
1const supplyParams: MoneyMarketSupplyParams = {2 token: '0x...', // Address of the token (spoke chain) to supply3 amount: 1000n, // Amount to supply (in token decimals)4 action: 'supply',5};
- Check allowance of supply action:
1// Step 1: Check if allowance is sufficient2const allowanceCheck = await sodax.moneyMarket.isAllowanceValid(supplyParams, spokeProvider);34if (!allowanceCheck.ok) {5 console.error('Allowance check failed:', allowanceCheck.error);6 return;7}89// Step 2: Approve if allowance is insufficient10if (!allowanceCheck.value) {11 console.log('Insufficient allowance, approving...');1213 const approveResult = await sodax.moneyMarket.approve(supplyParams, spokeProvider);1415 if (!approveResult.ok) {16 console.error('Approval failed:', approveResult.error);17 return;18 }1920 console.log('Approval successful:', approveResult.value);21}22
- Once allowance is valid you can execute supply action on the money market as following:
1// Step 3: Now you can proceed with supply2const supplyResult = await sodax.moneyMarket.supply(supplyParams, spokeProvider);34if (supplyResult.ok) {5 const [spokeTxHash, hubTxHash] = supplyResult.value;6 console.log('Supply successful:', { spokeTxHash, hubTxHash });7} else {8 console.error('Supply failed:', supplyResult.error);9}10
Flow for all other actions is very similar if not equal!
Need any help?
We provide the ability to estimate gas for each kind of money market related action, and extensive support for error handling of each action.
You can find gas estimation docs here.
You can find Error Handling docs here.
For any further issues or to reach out to our team during the integration process, you can provide your contact information through the form on our Gitbook, open an issue on our Github, or reach out directly to SODAX through Discord
.png%3F2025-07-07T15%3A52%3A05.568Z&w=3840&q=100)
SODAX SDKs (Core, Wallet, dApp Kit) allow partners to tap into fast, scalable DeFi with intent-based execution and deep cross-chain liquidity.
.png%3F2025-08-05T15%3A28%3A05.980Z&w=3840&q=100)
The SODAX SDK is fully integrated and ready for partners, with Solvers powering cross-chain intents-based execution through Protocol-Owned Liquidity.