# Preswap

This text describes two primary methods for performing a swap function, each with distinct steps and calculation methods. The first method involves initially obtaining tick data, followed by performing calculations locally. The second method involves conducting a simulated swap and then obtaining the resultant data through an event on Sui.

There are three pre-calculation strategies for executing a swap:

1. Local Calculate

* local calculate swap result: use `sdk.Swap.calculateRates()`

2. Simulate swap then get result

* only calculate one pool swap result: use `sdk.Swap.preswap()`.
* calculate multi pool at the same time, use `sdk.Swap.preSwapWithMultiPool()`. It will select one best pool to do swap.

## Local calculate swap result

This method need to get ticks data and pool object first.

use `sdk.Swap.calculateRates` method.

#### Function input param

*Please refer to the original function for specific parameter types.*

* params: `CalculateRatesParams` object.
  * **`decimalsA`**: the decimal of coinA.
  * **`decimalsB`**: the decimal of coinB.
  * **`a2b`**: swap direction, `true` means swap from coinA to coinB, `false` means swap from coinB to CoinA.
  * **`byAmountIn`**: `true` means fixed the amount of input, `false` means fixed the amount of output.
  * **`amount`**: the amount of input (`byAmountIn` = `true`) or output (`byAmountIn` = `false`).
  * **`swapTicks`**:  the array of **`TickData`**`,`[get them by **`sdk.Pool.fetchTicks()`**](https://cetus-1.gitbook.io/cetus-developer-docs/developer/via-sdk/get-ticks#id-1.-batch-retrieve-ticks-by-pool-id).
  * **`pool`**: the **`pool`** object, [get it by **`sdk.Pool.getPool()`**](https://cetus-1.gitbook.io/cetus-developer-docs/developer/via-sdk/get-clmm-pools#id-3.-retrieve-one-pool).

#### Example

<pre class="language-ts"><code class="lang-ts">import BN from 'bn.js'
import { adjustForSlippage, d, initCetusSDK, Percentage, TransactionUtil } from '@cetusprotocol/cetus-sui-clmm-sdk'

const sdk = initCetusSDK({ network: 'mainnet' })
<strong>
</strong><strong>const a2b = false
</strong>const pool = await sdk.Pool.getPool('0x6fd4915e6d8d3e2ba6d81787046eb948ae36fdfc75dad2e24f0d4aaa2417a416')
const byAmountIn = false
const amount = new BN(80000000000000)

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

// const swapTicks =  await  sdk.Pool.fetchTicksByRpc(pool.ticks_handle)

console.log("swapTicks length: ", swapTicks.length);

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

console.log('calculateRates###res###', {
  estimatedAmountIn: res.estimatedAmountIn.toString(),
  estimatedAmountOut: res.estimatedAmountOut.toString(),
  estimatedEndSqrtPrice: res.estimatedEndSqrtPrice.toString(),
  estimatedFeeAmount: res.estimatedFeeAmount.toString(),
  isExceed: res.isExceed,
  extraComputeLimit: res.extraComputeLimit,
  amount: res.amount.toString(),
  aToB: res.aToB,
  byAmountIn: res.byAmountIn,
})

console.log('swap: ', transferTxn)
</code></pre>

## Preswap by simulation transaction

## preSwap

use `sdk.Swap.preswap` method.

#### Function input param

*Please refer to the original function for specific parameter types.*

* **`pool`**: pool object, you can get it by `sdk.Pool.getPool()` method.
* **`currentSqrtPrice`**: pool's current\_sqrt\_price.
* **`coinTypeA`**: the coin type address about coinA.
* **`coinTypeB`**: the coin type address about coinB.
* **`decimalsA`**: the decimal of coinA.
* **`decimalsB`**: the decimal of coinB.
* **`a2b`**: swap direction, `true` means swap from coinA to coinB, `false` means swap from coinB to CoinA.
* **`byAmountIn`**: `true` means fixed the amount of input, `false` means fixed the amount of output.
* **`amount`**: the amount of input (`byAmountIn` = `true`) or output (`byAmountIn` = `false`).

#### Example

```ts
const sendKeypair = buildTestAccount()
// Whether the swap direction is token a to token b
const a2b = true
// fix input token amount
const coinAmount = new BN(120000)
// input token amount is token a
const byAmountIn = true
// slippage value
const slippage = Percentage.fromDecimal(d(5))
// Fetch pool data
const pool = await sdk.Pool.getPool(poolAddress)
// Estimated amountIn amountOut fee
const res: any = await sdk.Swap.preswap({
  pool: pool,
  current_sqrt_price: pool.current_sqrt_price,
  coinTypeA: pool.coinTypeA,
  coinTypeB: pool.coinTypeB,
  decimalsA: 6, // coin a 's decimals
  decimalsB: 8, // coin b 's decimals
  a2b,
  by_amount_in,
  amount,
})

const partner = "0x8e0b7668a79592f70fbfb1ae0aebaf9e2019a7049783b9a4b6fe7c6ae038b528"

const toAmount = byAmountIn ? res.estimatedAmountOut : res.estimatedAmountIn
const amountLimit =  adjustForSlippage(toAmount, slippage, !byAmountIn)

// build swap Payload
const swapPayload = sdk.Swap.createSwapTransactionPayload(
  {
    pool_id: pool.poolAddress,
    coinTypeA: pool.coinTypeA,
    coinTypeB: pool.coinTypeB
    a2b: a2b,
    by_amount_in: by_amount_in,
    amount: res.amount.toString(),
    amount_limit: amountLimit.toString(),
    swap_partner: partner
  },
)

onst transferTxn = await sendTransaction(signer,swapPayload)
console.log('swap: ', transferTxn)
```

## preSwapWithMultiPool

use `sdk.Swap.preSwapWithMultiPool()` method.

#### Function input param

*Please refer to the original function for specific parameter types.*

* **`poolAddresses`**:An array of pool objects ID. All pools must have the same type.
* **`coinTypeA`**: the coin type address about coinA.
* **`coinTypeB`**: the coin type address about coinB.
* **`a2b`**: swap direction, `true` means swap from coinA to coinB, `false` means swap from coinB to CoinA.
* **`byAmountIn`**: `true` means fixed the amount of input, `false` means fixed the amount of output.
* **`amount`**: the amount of input (`byAmountIn` = `true`) or output (`byAmountIn` = `false`).

#### Example

```ts
const a2b = true
const poolAddresses = [
  '0x53d70570db4f4d8ebc20aa1b67dc6f5d061d318d371e5de50ff64525d7dd5bca',
  '0x4038aea2341070550e9c1f723315624c539788d0ca9212dca7eb4b36147c0fcb',
  '0x6fd4915e6d8d3e2ba6d81787046eb948ae36fdfc75dad2e24f0d4aaa2417a416',
]
const pool0 = await buildTestPool(sdk, poolAddresses[0])
const pool1 = await buildTestPool(sdk, poolAddresses[1])
const pool2 = await buildTestPool(sdk, poolAddresses[2])
const byAmountIn = true
const amount = '10000000'

const resWithMultiPool: any = await sdk.Swap.preSwapWithMultiPool({
  poolAddresses: poolAddresses,
  coinTypeA: pool0.coinTypeA,
  coinTypeB: pool0.coinTypeB,
  a2b,
  byAmountIn,
  amount,
})
```
