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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ferra.ag/integration/clmm/typescript-sdk/calculate-swap-rates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
