SODAX Symbol
SODAX
BETA
Infrastructure formodern money
NewsPartners
News/Integrate with the SODAX SDK

Integrate with the SODAX SDK

Learn how to integrate the SODAX SDK step-by-step and unlock multichain DeFi with ease — covering intent swaps and money markets for 12+ blockchains.

SODAX Team
•August 11, 2025
Integrate with the SODAX SDK

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:

// using npm
npm install @sodax/sdk

// using pnpm
pnpm add @sodax/sdk

// using yarn
yarn 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:

// Initialize Sodax using default Sonic mainnet configurations (no fees)
const sodax = new Sodax();

// Partner fee can be defined as a percentage or a definite token amount.
// Fee is optional, you can leave it empty/undefined.
const partnerFeePercentage = {
  address: '0x...', // address to receive fee too
  percentage: 100, // 100 = 1%, 10000 = 100%
} satisfies PartnerFee;

const partnerFeeAmount = {
  address: '0x...', // address to receive fee too
  amount: 1000n, // definite amount denominated in token decimal precision
} satisfies PartnerFee;

// Use default config but put fee on solver (intent swaps)
const sodaxWithSolverFees = new Sodax({
  solver: { partnerFee: partnerFeePercentage },
});

// Use default config with fee on money market (borrows)
const sodaxWithMoneyMarketFees = new Sodax({
  moneyMarket: { partnerFee: partnerFeePercentage },
});

// or use default config with fees on both solver and money market
const sodaxWithFees = new Sodax({
  solver: { partnerFee: partnerFeePercentage },
  moneyMarket: { partnerFee: partnerFeePercentage },
});

Full Customization:

// example of custom solver config
const customSolverConfig = {
  intentsContract: '0x...',
  solverApiEndpoint: 'https://...',
  partnerFee: partnerFeePercentage, // or partnerFeeAmount
} satisfies SolverConfigParams;

// pre-defined default solver config per hub chain id (Sonic hub is the default)
const solverConfig: SolverConfigParams = getSolverConfig(SONIC_MAINNET_CHAIN_ID);

// example of custom money market config
const customMoneyMarketConfig = {
  lendingPool: '0x...',
  uiPoolDataProvider: '0x...',
  poolAddressesProvider: '0x...',
  bnUSD: '0x...',
  bnUSDVault: '0x...',
} satisfies MoneyMarketConfig;

// pre-defined default money market config per hub chain id (Sonic hub is the default)
const moneyMarketConfig = getMoneyMarketConfig(SONIC_MAINNET_CHAIN_ID);

// example of custom hub config
const hubConfig = {
  hubRpcUrl: 'https://rpc.soniclabs.com',
  chainConfig: getHubChainConfig(SONIC_MAINNET_CHAIN_ID),
} satisfies EvmHubProviderConfig;


// Initialize Sodax using custom/default configurations
const sodax = new Sodax({
  solver: solverConfig,
  moneyMarket: moneyMarketConfig,
  hubProviderConfig: hubConfig,
});


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:

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

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

import { 
 SPOKE_CHAIN_IDS,      // array of currently supported spoke chain ids
 supportedSpokeChains, // alias for SPOKE_CHAIN_IDS
 isValidSpokeChainId   // util function to check if certain chain ID is valid
} from '@sodax/sdk';

Example of creating an instance of EVM chain type Spoke Provider:

// BSC spoke chain provider of EVM type
const bscSpokeProvider: EvmSpokeProvider = new EvmSpokeProvider(
  evmWalletProvider, // connected wallet constructed using Wallet SDK or implementation of IEvmWalletProvider interface
  spokeChainConfig[BSC_MAINNET_CHAIN_ID], // connected chain config
);

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:

import { getSupportedSolverTokens, SpokeChainId, Token } from "@sodax/sdk"

// using spoke chain id to retrieve supported tokens for solver (intent swaps)
const supportedSolverTokens: readonly Token[] = getSupportedSolverTokens(spokeChainId);

// check if token address for given spoke chain id is supported in solver
const isSolverSupportedToken: boolean = isSolverSupportedToken(spokeChainId, token)

In order to create a successful swap you need to:

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

  2. Check allowance and approve the token spending if required

  3. Create a swap if you are satisfied with the given quote and allowance to transfer tokens is valid

Example quote request:

const quoteRequest = {
  token_src: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8', // ETH token on BSC
  token_dst: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f', // wBTC token on ARB
  token_src_blockchain_id: BSC_MAINNET_CHAIN_ID,           // src spoke chain id
  token_dst_blockchain_id: ARBITRUM_MAINNET_CHAIN_ID,      // dst spoke chain id
  amount: 1000n,            // amount of src token to swap
  quote_type: 'exact_input',// quote type: "exact_input" or "exact_output"
} satisfies SolverIntentQuoteRequest;

const result = await sodax.solver.getQuote(quoteRequest);

After you are satisfied with the quote you can create intent params as following:

const createIntentParams = {
  inputToken: '0x..',  // The address of the input token on spoke chain
  outputToken: '0x..',  // The address of the output token on spoke chain
  inputAmount: BigInt(1000000), // The amount of input tokens
  minOutputAmount: BigInt(900000), // min amount you are expecting to receive
  deadline: BigInt(0), // Optional timestamp after which intent expires (0 = no deadline)
  allowPartialFill: false, // Whether the intent can be partially filled
  srcChain: BSC_MAINNET_CHAIN_ID, // Chain ID where input tokens originate
  dstChain: ARBITRUM_MAINNET_CHAIN_ID, // Chain ID where output tokens should be delivered
  srcAddress: '0x..', // Source address (original address on spoke chain)
  dstAddress: '0x..', // Destination address (original address on spoke chain)
  solver: '0x0000000000000000000000000000000000000000', // Optional specific solver address (address(0) = any solver)
  data: '0x', // Additional arbitrary data
} 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:

// First check if approval is needed
const isApproved = await sodax.solver.isAllowanceValid(
  createIntentParams,
  bscSpokeProvider
);

if (!isApproved.ok) {
  // Handle error
  console.error('Failed to check allowance:', isApproved.error);
} else if (!isApproved.value) {
  // Approve Sodax to transfer your tokens
  const approveResult = await sodax.solver.approve(
    bscEthToken, // BSC ETH token address
    createIntentParams.inputAmount, // Amount to approve
    bscSpokeProvider
  );

  if (!approveResult.ok) {
    // Handle error
    console.error('Failed to approve tokens:', approveResult.error);
  } else {
    // wait for tx hash from approveResult.value to be mined before proceeding
  }
}

After allowance for SODAX to transfer your tokens is approved you can create swap as following:

const swapResult = await sodax.solver.swap(
    createIntentParams,
    bscSpokeProvider,
  );

  if (!swapResult.ok) {
    // handle error as described in Error Handling section
  }

  // txHash and created Intent data as Intent & FeeAmount type
  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:

const result = await sodax.solver.getStatus({
  intent_tx_hash: '0x...', // tx hash of create intent blockchain transaction
} satisfies SolverIntentStatusRequest);

Cancel swap intent:

const result = await sodax.solver.cancelIntent(
  intent,
  bscSpokeProvider,
  hubProvider,
  false, // true = get raw transaction, false = execute and return tx hash
);

if (result.ok) {
  console.log('[cancelIntent] txHash', txResult.value);
} else {
  // handle error
  console.error('[cancelIntent] error', txResult.error);
}


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:

// using spoke chain id to retrieve supported tokens address
const supportedMoneyMarketTokens: readonly Token[] = getSupportedMoneyMarketTokens(spokeChainId)

// check if token address for given spoke chain id is supported
const 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:

  1. Check allowance for the action and approve token transfer if needed

  2. Execute the action

Example flow of supply action execution:

  1. Create supply params:

const supplyParams: MoneyMarketSupplyParams = {
  token: '0x...', // Address of the token (spoke chain) to supply
  amount: 1000n, // Amount to supply (in token decimals)
  action: 'supply',
};
  1. Check allowance of supply action:

// Step 1: Check if allowance is sufficient
const allowanceCheck = await sodax.moneyMarket.isAllowanceValid(supplyParams, spokeProvider);

if (!allowanceCheck.ok) {
  console.error('Allowance check failed:', allowanceCheck.error);
  return;
}

// Step 2: Approve if allowance is insufficient
if (!allowanceCheck.value) {
  console.log('Insufficient allowance, approving...');
  
  const approveResult = await sodax.moneyMarket.approve(supplyParams, spokeProvider);
  
  if (!approveResult.ok) {
    console.error('Approval failed:', approveResult.error);
    return;
  }
  
  console.log('Approval successful:', approveResult.value);
}
  1. Once allowance is valid you can execute supply action on the money market as following:

// Step 3: Now you can proceed with supply
const supplyResult = await sodax.moneyMarket.supply(supplyParams, spokeProvider);

if (supplyResult.ok) {
  const [spokeTxHash, hubTxHash] = supplyResult.value;
  console.log('Supply successful:', { spokeTxHash, hubTxHash });
} else {
  console.error('Supply failed:', supplyResult.error);
}

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

Back arrowBack to News
SODAX SymbolSODAX
using soda
SODAX SwapHana WalletBalanced DeFi
partner portal
socials
NewsDiscordX (Twitter)Linktree
resources
DocumentationGithubSODAX ScanGlossaryBrand KitTermsCookie Settings