Calculate Swap Rates

Overview

calculateRates is a method used to calculate and estimate swap results before executing an actual transaction. This method helps determine input/output token amounts, transaction fees, and other important parameters without spending gas.

Method Signature

sdk.Swap.calculateRates(params: CalculateRatesParams): CalculateRatesResult

Parameters

Parameter
Type
Description

decimalsA

number

Number of decimals for token A

decimalsB

number

Number of decimals for token B

a2b

boolean

Swap direction. true for A→B, false for B→A

byAmountIn

boolean

Calculation mode. true to specify input amount, false to specify output amount

amount

BN

Amount to swap (in smallest unit). Input amount if byAmountIn=true, output amount if byAmountIn=false

swapTicks

Tick[]

Array of tick data from the pool

currentPool

Pool

Current pool object containing pool state

Return Values

Field
Type
Description

estimatedAmountIn

BN

Estimated amount of tokens to be swapped in

estimatedAmountOut

BN

Estimated amount of tokens to be received

estimatedEndSqrtPrice

BN

Estimated sqrt price after swap

estimatedFeeAmount

BN

Estimated fee amount for the swap

isExceed

boolean

Whether the swap exceeds pool liquidity

extraComputeLimit

number

Additional compute units needed for transaction

amount

BN

The input amount used for calculation

aToB

boolean

Swap direction used in calculation

byAmountIn

boolean

Calculation mode used

Examples

Example 1: Calculate swap from token B to token A by specifying input amount

const pool = await sdk.Pool.getPool('0xc8d7a1503dc2f9f5b05449a87d8733593e2f0f3e7bffd90541252782e4d2ca20')

// Fetch current tick data
const swapTicks = await sdk.Pool.fetchTicks({
  pool_id: pool.poolAddress,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
})

// Calculate rates for swapping 80 token B to token A
const result = sdk.Swap.calculateRates({
  decimalsA: 6,
  decimalsB: 6,
  a2b: false,           // B to A swap
  byAmountIn: true,     // Specifying input amount
  amount: new BN('80000000'),  // 80 tokens with 6 decimals
  swapTicks: swapTicks,
  currentPool: pool,
})

console.log('Swap Calculation Results:')
console.log('Input Amount:', result.estimatedAmountIn.toString())
console.log('Output Amount:', result.estimatedAmountOut.toString())
console.log('Fee Amount:', result.estimatedFeeAmount.toString())
console.log('Exceeds Liquidity:', result.isExceed)

Example 2: Calculate swap from token A to token B by specifying output amount

const pool = await sdk.Pool.getPool('0xYOUR_POOL_ADDRESS')
const swapTicks = await sdk.Pool.fetchTicks({
  pool_id: pool.poolAddress,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
})

// Calculate how much token A needed to get exactly 100 token B
const result = sdk.Swap.calculateRates({
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,            // A to B swap
  byAmountIn: false,    // Specifying output amount
  amount: new BN('100000000'),  // Want exactly 100 token B
  swapTicks: swapTicks,
  currentPool: pool,
})

console.log('To receive', result.estimatedAmountOut.toString(), 'token B')
console.log('You need', result.estimatedAmountIn.toString(), 'token A')
console.log('Estimated fee:', result.estimatedFeeAmount.toString())

Example 3: Check for large swap impact

const pool = await sdk.Pool.getPool('0xYOUR_POOL_ADDRESS')
const swapTicks = await sdk.Pool.fetchTicks({
  pool_id: pool.poolAddress,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
})

// Try to swap a large amount
const largeAmount = new BN('1000000000000')  // 1M tokens with 6 decimals

const result = sdk.Swap.calculateRates({
  decimalsA: 6,
  decimalsB: 6,
  a2b: true,
  byAmountIn: true,
  amount: largeAmount,
  swapTicks: swapTicks,
  currentPool: pool,
})

if (result.isExceed) {
  console.log('⚠️ Warning: Swap exceeds available liquidity!')
  console.log('Maximum possible output:', result.estimatedAmountOut.toString())
} else {
  console.log('✅ Swap can be executed')
  console.log('Expected output:', result.estimatedAmountOut.toString())
}

// Check price impact
const priceImpact = calculatePriceImpact(
  pool.current_sqrt_price,
  result.estimatedEndSqrtPrice
)
console.log('Price impact:', priceImpact, '%')

Important Notes

  1. Amount Units: All amounts must be in the smallest unit (considering decimals). For example, 1 token with 6 decimals = 1000000.

  2. Tick Data: Always fetch fresh tick data before calculating rates to ensure accurate results:

    // Option 1: Fetch via API
    const swapTicks = await sdk.Pool.fetchTicks({
      pool_id: pool.poolAddress,
      coinTypeA: pool.coinTypeA,
      coinTypeB: pool.coinTypeB,
    })
    
    // Option 2: Fetch via RPC (if available)
    const swapTicks = await sdk.Pool.fetchTicksByRpc(pool.ticks_handle)
  3. Gas Estimation: Use extraComputeLimit to adjust transaction gas limits when executing the actual swap:

    const txOptions = {
      gasLimit: DEFAULT_GAS_LIMIT + result.extraComputeLimit
    }
  4. Slippage Protection: The calculated amounts are estimates. Always implement slippage tolerance when executing actual swaps:

    const slippageTolerance = 0.01  // 1%
    const minAmountOut = result.estimatedAmountOut * (1 - slippageTolerance)
  5. Error Handling: Always check isExceed before executing swaps to avoid failed transactions due to insufficient liquidity.

Last updated