# 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/features-available/pages/MOBu9fuXlDeLuzeAknMW#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/features-available/pages/lh5w7uEmfJ4eUaLA4NYx#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,
})
```


---

# 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://cetus-1.gitbook.io/cetus-developer-docs/developer/via-sdk/features-available/preswap.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.
