> For the complete documentation index, see [llms.txt](https://docs.ferra.ag/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ferra.ag/integration/clmm/typescript-sdk/calculate-swap-rates.md).

# 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

```typescript
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

```javascript
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

```javascript
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

```javascript
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:

   ```javascript
   // 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:

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

   ```javascript
   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.
