> 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/damm/typescript-sdk/swap.md).

# Swap

### Get Swap Fee

Calculate swap fees before executing:

```typescript
const pool = await sdk.Pool.getPool(poolId)

// Fee rate from pool
console.log('Fee rate:', pool.feeRate)

// Get available fee tiers
const feeTiers = await sdk.Pool.getBaseFeesAvailable()

feeTiers.forEach(tier => {
  console.log(`Tick spacing: ${tier.tick_spacing}`)
  console.log(`Fee rate: ${tier.fee_rate / 10000000}%`)
})
```

#### Estimate Fee from PreSwap

```typescript
const preSwapResult = await sdk.Swap.preswap({
  pool: pool,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,
  byAmountIn: true,
  amount: '1000000000',
  currentSqrtPrice: pool.currentSqrtPrice
})

console.log('Estimated fee:', preSwapResult.estimatedFeeAmount)
```

***

### PreSwap

Calculate swap amounts and check price impact before executing trades.

#### Quick Start

```typescript
// Simulate swap before execution
const pool = await sdk.Pool.getPool(poolId)

const preSwapResult = await sdk.Swap.preswap({
  pool: pool,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 9,  // SUI decimals
  decimalsB: 6,  // USDC decimals
  a2b: true,     // SUI -> USDC
  byAmountIn: true,
  amount: '1000000000',  // 1 SUI
  currentSqrtPrice: pool.currentSqrtPrice
})

console.log({
  amountIn: preSwapResult.estimatedAmountIn,
  amountOut: preSwapResult.estimatedAmountOut,
  fee: preSwapResult.estimatedFeeAmount,
  priceAfter: preSwapResult.estimatedEndSqrtPrice
})
```

#### Single Pool PreSwap

```typescript
const params = {
  pool: pool,
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,           // Direction: A to B
  byAmountIn: true,    // Fix input amount
  amount: '1000000000',
  currentSqrtPrice: pool.currentSqrtPrice
}

const result = await sdk.Swap.preswap(params)

if (result.isExceed) {
  console.log('Swap exceeds pool liquidity')
}
```

#### Multi-Pool PreSwap

Find best pool for swap:

```typescript
const pools = ['0xpool1...', '0xpool2...', '0xpool3...']

const result = await sdk.Swap.preSwapWithMultiPool({
  poolAddresses: pools,
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  a2b: true,
  byAmountIn: true,
  amount: '1000000000'
})

console.log('Best pool:', result.poolAddress)
console.log('Best output:', result.estimatedAmountOut)
```

#### Calculate Price Impact

```typescript
// Local calculation with tick data (use fetchTicksByRpc for better performance)
const ticks = await sdk.Pool.fetchTicksByRpc(pool.ticksHandle)

const rateResult = sdk.Swap.calculateRates({
  currentPool: pool,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,
  byAmountIn: true,
  amount: new BN('1000000000'),
  swapTicks: ticks
})

console.log({
  priceImpact: rateResult.priceImpactPct.toFixed(2) + '%',
  isExceed: rateResult.isExceed,
  extraGas: rateResult.extraComputeLimit
})
```

#### Response Types

```typescript
// PreSwap result
interface PreSwapResult {
  poolAddress: string
  currentSqrtPrice: bigint
  estimatedAmountIn: string
  estimatedAmountOut: string
  estimatedEndSqrtPrice: string
  estimatedFeeAmount: string
  isExceed: boolean        // Exceeds liquidity
  amount: string
  aToB: boolean
  byAmountIn: boolean
}

// CalculateRates result (local calculation)
interface CalculateRatesResult {
  estimatedAmountIn: BN
  estimatedAmountOut: BN
  estimatedEndSqrtPrice: BN
  estimatedFeeAmount: BN
  isExceed: boolean
  extraComputeLimit: number
  priceImpactPct: number
  amount: BN
  aToB: boolean
  byAmountIn: boolean
}
```

````

### Check Slippage

```typescript
// 1. PreSwap to get expected output
const preSwap = await sdk.Swap.preswap(params)

// 2. Calculate minimum output with 1% slippage
const expectedOut = new BN(preSwap.estimatedAmountOut)
const minOutput = expectedOut.mul(new BN(99)).div(new BN(100))

console.log({
  expected: expectedOut.toString(),
  minimum: minOutput.toString()
})
````

#### Compare Pools

```typescript
const pools = await sdk.Pool.getPools()
const suiUsdcPools = pools.filter(p =>
  p.coinTypeA.includes('sui') &&
  p.coinTypeB.includes('usdc')
)

// Test each pool
const results = []
for (const pool of suiUsdcPools) {
  const result = await sdk.Swap.preswap({
    pool,
    coinTypeA: pool.coinTypeA,
    coinTypeB: pool.coinTypeB,
    decimalsA: 9,
    decimalsB: 6,
    a2b: true,
    byAmountIn: true,
    amount: '1000000000',
    currentSqrtPrice: pool.currentSqrtPrice
  })

  if (!result.isExceed) {
    results.push({
      pool: pool.poolAddress,
      output: result.estimatedAmountOut,
      fee: result.estimatedFeeAmount
    })
  }
}

// Find best rate
const best = results.sort((a, b) =>
  Number(b.output) - Number(a.output)
)[0]
```

#### Fix Output Amount

```typescript
// Want exactly 1000 USDC output
const params = {
  pool,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,
  byAmountIn: false,    // Fix output
  amount: '1000000000', // 1000 USDC
  currentSqrtPrice: pool.currentSqrtPrice
}

const result = await sdk.Swap.preswap(params)
console.log('Need SUI:', result.estimatedAmountIn)
```

***

### Swap

Execute token swaps on Ferra DAMM pools.

#### Quick Start

```typescript
// Simple swap: 1 SUI -> USDC
const swapParams = {
  pool_id: '0x...',
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  a2b: true,              // SUI -> USDC
  by_amount_in: true,     // Fix input amount
  amount: '1000000000',   // 1 SUI
  amount_limit: '990000', // Min 990 USDC (1% slippage)
}

const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)

const result = await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx,
  signer: keypair
})
```

#### Swap Parameters

| Parameter      | Type    | Description                                 |
| -------------- | ------- | ------------------------------------------- |
| pool\_id       | string  | Pool object ID                              |
| coinTypeA      | string  | Type of coin A                              |
| coinTypeB      | string  | Type of coin B                              |
| a2b            | boolean | Direction: true = A->B, false = B->A        |
| by\_amount\_in | boolean | true = fix input, false = fix output        |
| amount         | string  | Amount to swap                              |
| amount\_limit  | string  | Min output (if by\_amount\_in) or max input |

#### Swap Directions

**Swap A to B**

```typescript
const params = {
  pool_id: poolId,
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  a2b: true,              // SUI -> USDC
  by_amount_in: true,
  amount: '1000000000',   // Input: 1 SUI
  amount_limit: '990000'  // Min output: 990 USDC
}
```

**Swap B to A**

```typescript
const params = {
  pool_id: poolId,
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  a2b: false,             // USDC -> SUI
  by_amount_in: true,
  amount: '1000000',      // Input: 1000 USDC
  amount_limit: '990000000' // Min output: 0.99 SUI
}
```

#### Fix Output Amount

Get exactly the amount you want:

```typescript
const params = {
  pool_id: poolId,
  coinTypeA: '0x2::sui::SUI',
  coinTypeB: '0x...::usdc::USDC',
  a2b: true,
  by_amount_in: false,    // Fix output amount
  amount: '1000000',      // Want exactly 1000 USDC
  amount_limit: '1010000000' // Max input: 1.01 SUI
}
```

#### Calculate Slippage

```typescript
// 1. PreSwap to get expected amounts
const preSwap = await sdk.Swap.preswap({
  pool,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 9,
  decimalsB: 6,
  a2b: true,
  byAmountIn: true,
  amount: '1000000000',
  currentSqrtPrice: pool.currentSqrtPrice
})

// 2. Apply slippage (1%)
const slippage = 0.01
const expectedOut = Number(preSwap.estimatedAmountOut)
const minOutput = Math.floor(expectedOut * (1 - slippage))

// 3. Create swap transaction
const swapParams = {
  pool_id: pool.poolAddress,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  a2b: true,
  by_amount_in: true,
  amount: '1000000000',
  amount_limit: minOutput.toString()
}

const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
```

#### Gas Optimization (SUI)

Optimize gas when swapping SUI:

```typescript
const gasConfig = {
  byAmountIn: true,
  slippage: new Percentage(1, 100), // 1%
  decimalsA: 9,
  decimalsB: 6,
  swapTicks: ticks,
  currentPool: pool
}

const tx = await sdk.Swap.createSwapTransactionPayload(
  swapParams,
  gasConfig
)
```

#### Partner Swaps

Route fees to partners:

```typescript
const params = {
  ...swapParams,
  swap_partner: '0xpartner...' // Partner object ID
}

const tx = await sdk.Swap.createSwapTransactionPayload(params)
```

#### Advanced Usage

**Manual Coin Management**

```typescript
// Get swap transaction without auto-transfer
const { tx, coinABs } = await sdk.Swap.createSwapTransactionWithoutTransferCoinsPayload(swapParams)

// coinABs[0] = coin A after swap
// coinABs[1] = coin B after swap

// Custom handling
tx.transferObjects([coinABs[1]], recipient)

const result = await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx,
  signer: keypair
})
```

**Batch Swaps**

```typescript
// Execute swaps sequentially
const tx1 = await sdk.Swap.createSwapTransactionPayload(swap1Params)
const result1 = await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx1,
  signer: keypair
})

const tx2 = await sdk.Swap.createSwapTransactionPayload(swap2Params)
const result2 = await sdk.fullClient.signAndExecuteTransaction({
  transaction: tx2,
  signer: keypair
})
```

#### Complete Example

```typescript
async function swapTokens() {
  // 1. Get pool
  const pool = await sdk.Pool.getPool(poolId)

  // 2. Check current price
  const price = TickMath.sqrtPriceX64ToPrice(
    new BN(pool.currentSqrtPrice.toString()),
    9, // SUI decimals
    6  // USDC decimals
  )
  console.log('Current price:', price.toString())

  // 3. PreSwap simulation
  const preSwap = await sdk.Swap.preswap({
    pool,
    coinTypeA: pool.coinTypeA,
    coinTypeB: pool.coinTypeB,
    decimalsA: 9,
    decimalsB: 6,
    a2b: true,
    byAmountIn: true,
    amount: '1000000000',
    currentSqrtPrice: pool.currentSqrtPrice
  })

  // 4. Check if swap is viable
  if (preSwap.isExceed) {
    throw new Error('Insufficient liquidity')
  }

  // 5. Create swap with 0.5% slippage
  const minOutput = Math.floor(Number(preSwap.estimatedAmountOut) * 0.995)

  const swapParams = {
    pool_id: pool.poolAddress,
    coinTypeA: pool.coinTypeA,
    coinTypeB: pool.coinTypeB,
    a2b: true,
    by_amount_in: true,
    amount: '1000000000',
    amount_limit: minOutput.toString()
  }

  // 6. Execute swap
  const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)

  const result = await sdk.fullClient.signAndExecuteTransaction({
    transaction: tx,
    signer: keypair
  })

  console.log('Swap completed:', result.digest)
}
```

#### Error Handling

```typescript
try {
  const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
} catch (error) {
  if (error.code === 'InvalidSendAddress') {
    sdk.senderAddress = '0x...'
  }
  if (error.message.includes('Insufficient balance')) {
    console.log('Not enough tokens')
  }
  if (error.message.includes('Slippage exceeded')) {
    console.log('Price moved, increase slippage')
  }
}
```

#### Important Notes

* Always use `amount_limit` for slippage protection
* SDK automatically handles coin selection
* Excess coins are returned to sender
* Partner swaps share fees with partners
* Gas optimization available for SUI swaps
