πŸ”„Swaps (Solver)

Swaps part of the SDK provides abstractions to assist you with interacting with the cross-chain Intent Smart Contracts, Solver and Relay API.

All swap operations are accessed through the swap property of a Sodax instance:

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

const sodax = new Sodax();

// All swap methods are available through sodax.swap
const quote = await sodax.swaps.getQuote(quoteRequest);

Using SDK Config and Constants

SDK includes predefined configurations of supported chains, tokens and other relevant information for the client to consume. All of the configurations are reachable through config property of Sodax instance (e.g. sodax.config)

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

const sodax = new Sodax();

// if you want dynamic (backend API based - contains latest tokens) configuration make sure to initialize instance before usage!
// by default configuration from specific SDK version you are using is used
await sodax.initialize();

// all supported spoke chains
const spokeChains: SpokeChainId[] = sodax.config.getSupportedSpokeChains();

// using spoke chain id to retrieve supported tokens for swap (solver intent swaps)
// NOTE: empty array indicates no tokens are supported, you should filter out empty arrays
const supportedSwapTokensForChainId: readonly Token[] = sodax.swaps.getSupportedSwapTokensByChainId(spokeChainId);

// object containing all supported swap tokens per chain ID
const supportedSwapTokensPerChain: Record<SpokeChainId, readonly Token[]> = sodax.swaps.getSupportedSwapTokens();

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

Please refer to SDK constants.tsarrow-up-right for more.

Available Methods

All swap methods are accessible through sodax.swaps:

Quote & Fee Methods

  • getQuote(request) - Request a quote from the solver API

  • getPartnerFee(inputAmount) - Calculate partner fee for a given input amount

  • getSolverFee(inputAmount) - Calculate solver fee (0.1%) for a given input amount

  • getSwapDeadline(offset?) - Get deadline timestamp for a swap

Intent Creation & Execution

  • swap(params) - Complete swap operation (recommended, handles all steps automatically)

  • createAndSubmitIntent(params) - Create and submit intent (alternative to swap)

  • createIntent(params) - Create intent only (for custom handling)

  • submitIntent(payload) - Submit intent to relay API (for custom handling)

  • postExecution(request) - Post execution to Solver API(for custom handling)

Intent Management

  • getIntent(txHash) - Retrieve intent from hub chain transaction hash

  • getFilledIntent(txHash) - Get the filled intent state from the hub chain transaction hash by parsing the IntentFilled event. Useful for obtaining the final exact output amount and state details after an intent has been executed.

  • getSolvedIntentPacket(params) - Get the intent delivery info about solved intent from the Relayer API.

  • getIntentHash(intent) - Get keccak256 hash of an intent

  • getStatus(request) - Get intent status from Solver API

  • cancelIntent(intent, spokeProvider, raw?) - Cancel an active intent

Token Approval

  • isAllowanceValid(params) - Check if token approval is needed

  • approve(params, raw?) - Approve tokens or request trustline (Stellar)

Utility Methods

  • getSupportedSwapTokensByChainId(chainId) - Get supported swap tokens for a chain

  • getSupportedSwapTokens() - Get all supported swap tokens per chain

  • SwapService.estimateGas(rawTx, spokeProvider) - Estimate gas for raw transactions (static method)

Initialising Spoke Provider

Refer to Initialising Spoke Provider section to see how BSC spoke provider used as bscSpokeProvider can be created.

Request a Quote

Requesting a quote should require you to just consume user input amount and converting it to the appropriate token amount (scaled by token decimals). All the required configurations (chain id [nid], token decimals and address) should be loaded as described in Using SDK Config and Constants.

Quoting API supports different types of quotes:

  • "exact_input": "amount" parameter is the amount the user want's to swap (e.g. the user is asking for a quote to swap 1 WETH to xxx SUI)

  • "exact_output": "amount" parameter is the final amount the user wants. (e.g. the user want's to swap WETH for SUI, but is asking how many WETH is going to cost to have 1 SUI)

Create Intent Params

Function Parameters Structure

All solver functions use object parameters for better readability and extensibility. The common parameter structure includes:

  • intentParams: The CreateIntentParams object containing swap details

  • spokeProvider: The spoke provider instance for the source chain. Can be a regular SpokeProvider (e.g., EvmSpokeProvider) or a raw spoke provider (e.g., EvmRawSpokeProvider) when you only have a wallet address. See HOW_TO_CREATE_A_SPOKE_PROVIDER.md for details on raw spoke providers.

  • fee: (Optional) Partner fee configuration. If not provided, uses the default partner fee from config. Note: Fees are now deducted from the input amount rather than added to it.

  • raw: (Optional) Whether to return raw transaction data instead of executing the transaction. Note: When using raw spoke providers, you must pass raw: true. Some methods like swap and createAndSubmitIntent do not support raw mode as they need to execute transactions.

  • timeout: (Optional) Timeout in milliseconds for relay operations (default: 60 seconds).

  • skipSimulation: (Optional) Whether to skip transaction simulation (default: false).

Raw Spoke Provider Support:

  • Methods that support raw mode: createIntent, approve, cancelIntent

  • Methods that do NOT support raw mode: swap, createAndSubmitIntent (these methods need to execute transactions and submit them to the relay API)

Get Fees

The swap service provides two fee calculation methods:

Get Partner Fee

The getPartnerFee function allows you to calculate the partner fee for a given input amount before creating an intent. This is useful for displaying fee information to users or calculating the total cost of a swap.

Note: If no partner fee is configured, the function returns 0n. The fee is deducted from the input amount, so the actual amount used for the swap will be inputAmount - partnerFee.

Get Solver Fee

The getSolverFee function calculates the solver fee (0.1% fee) for a given input amount. This is the standard fee charged by the solver service.

Get Swap Deadline

The getSwapDeadline function allows you to calculate a deadline timestamp for your swap by querying the hub chain's current block timestamp and adding a deadline offset. This is useful for setting expiration times for intents to prevent them from being executed after a certain period.

Note: The deadline is calculated as hub_chain_block_timestamp + deadline_offset. The default offset is 5 minutes (300 seconds), but you can customize this value based on your requirements. Setting a deadline helps prevent intents from being executed if market conditions change significantly.

Token Approval Flow

Before creating an intent, you need to ensure that the Asset Manager contract has permission to spend your tokens. Here's how to handle the approval flow:

Using Raw Spoke Providers with approve:

When using raw spoke providers, you can get raw approval transaction data:

Important: The approval amount is now the same as the inputAmount specified in your intent parameters. The fee is automatically deducted from this amount during intent creation, so you only need to approve the exact amount you want to swap.

Stellar Trustline Requirements

For Stellar-based swap operations, the allowance and approval system works differently:

  • Source Chain (Stellar): The standard isAllowanceValid and approve methods work as expected for EVM chains, but for Stellar as the source chain, these methods check and establish trustlines instead.

  • Destination Chain (Stellar): When Stellar is specified as the destination chain, frontends/clients need to manually establish trustlines before executing swaps. See Stellar Trustline Requirements for detailed information and code examples.

Estimate Gas for Raw Transactions

The estimateGas static method allows you to estimate the gas cost for raw transactions before executing them. This is particularly useful for intent creation and approval transactions to provide users with accurate gas estimates.

Note: This is a static method, so it can be called directly on SwapService. This method works with both regular and raw spoke providers.

Create And Submit Intent Order (Swap)

Creating Intent Order requires creating spoke provider for the chain that intent is going to be created on (srcChain).

Example for BSC -> ARB Intent Order:

The swap method is the recommended way to perform a complete swap operation. It handles all the steps automatically:

  1. Create intent deposit tx on spoke (source) chain

  2. Submit tx hash to relayer API

  3. Wait for relayer to relay tx data to the hub chain (Sonic)

  4. Post hub chain tx hash to the Solver API

Note: The swap method does NOT support raw mode (raw: true) because it needs to execute transactions and submit them to the relay API. If you need raw transaction data, use createIntent instead.

Create And Submit Intent (Alternative Method - Equal to Swap)

If you need more control over the process, you can use createAndSubmitIntent which is equivalent to swap:

Note: The createAndSubmitIntent method does NOT support raw mode (raw: true) because it needs to execute transactions and submit them to the relay API. If you need raw transaction data, use createIntent instead.

Create Intent Only

If you need to create an intent without automatically submitting it (for custom handling), use createIntent:

Using Raw Spoke Providers with createIntent:

When using raw spoke providers (e.g., EvmRawSpokeProvider), you must pass raw: true to get raw transaction data:

Important: When creating an intent, the fee is automatically deducted from the inputAmount specified in your createIntentParams. The actual amount used for the swap will be inputAmount - feeAmount. Make sure your inputAmount is sufficient to cover both the swap amount and the fee.

Submit Intent to Relay API

Submit the spoke chain transaction hash to the relay API for processing. This step is required after creating an intent on the spoke chain.

Note: This is typically handled automatically by the swap or createAndSubmitIntent methods. You only need to call this manually if you're using createIntent separately.

Post Execution to Solver API

Post execution of intent order transaction executed on hub chain to Solver API. This step is typically handled automatically by the swap or createAndSubmitIntent methods.

Note: This is usually called automatically after the intent is executed on the hub chain. You only need to call this manually if you're handling the flow step by step.

Get Intent Order

Retrieve intent data using transaction hash from the hub chain (destination transaction hash).

Get Filled Intent

Retrieve the intent state from a transaction hash on the hub chain. This method extracts the intent state from the IntentFilled event logs emitted when an intent is filled by a solver.

Note: The txHash should be the hub chain transaction hash where the intent was filled. This can be obtained from the solver execution response.

IntentState Structure:

  • exists: boolean - Whether the intent exists

  • remainingInput: bigint - Remaining input amount that hasn't been filled

  • receivedOutput: bigint - Amount of output tokens received

  • pendingPayment: boolean - Whether there is a pending payment

Note: This method throws an error if no filled intent is found for the given transaction hash. Make sure the transaction hash corresponds to a transaction that contains an IntentFilled event.

Cancel Intent Order

Active Intent Order can be cancelled using Intent. See Get Intent Order on how to obtain intent.

Note: Create intent functions also return intent data for convenience, so you can use the intent from the creation response.

Using Raw Spoke Providers with cancelIntent:

When using raw spoke providers, you can get raw cancel transaction data:

Get Intent Status

Retrieve status of intent from the Solver API.

Note: The intent_tx_hash should be the destination transaction hash (hub chain transaction hash), which can be obtained from intentDeliveryInfo.dstTxHash or the relay packet dst_tx_hash property.

Get Solved Intent Packet

Get the intent delivery info about solved intent from the Relayer API. Packet data contains info about the intent execution on the destination chain.

Note: This method should be called after getStatus returns a status of SOLVED (3). The fill_tx_hash from the status response is used as the fillTxHash parameter.

Get Intent Hash

Get Intent Hash (keccak256) used as an ID of intent in smart contract.

Error Handling

Error handling for Solver operations is more complex due to the multi-step nature of cross-chain intent creation and execution. The SDK provides specific error types and helper functions to help you handle different failure scenarios appropriately.

Error Types and Helper Functions

The SDK provides several helper functions to check error types:

Handling swap (a.k.a. createAndSubmitIntent) Errors

The swap function performs multiple operations in sequence, and each step can fail. The returned error type can be checked using the helper functions:

Handling createIntent Errors

The createIntent function has a simpler error structure since it only handles intent creation on spoke chain (source chain):

Last updated