@cetusprotocol/cetus-clmm-aptos-sdk
TypeScript icon, indicating that this package has built-in type declarations

1.3.3 • Public • Published

cetus-sdk

  • The typescript SDK for cetus-clmm.
  • A more structured code example for this guide can be found here

Install

  • Our published package can be found here NPM.
yarn add @cetusprotocol/cetus-clmm-aptos-sdk

Usage

1.SDK configuration parameters

  • The contract address available for reference config.ts.
export const netConfig = {
  devnet: {
    // ...
  },
  testnet: {
    fullRpcUrl: 'https://fullnode.testnet.aptoslabs.com',
    fraphQLUrl: "https://indexer-testnet.staging.gcp.aptosdev.com/v1/graphql",
    launchpad:{
      cetusLaunchpad: '0xf85d392e74a995f2b67b966abde0af90df74ca1c5f35c144452c8815034180a4',
      crowdCoin: '0x7c9710312258aa802fdc801ca13934c2f4bef9ca6d28acdbeffdedf878229723'
    },
    simulationAccount: {
      pubkey: accountConfig.default.publicKeyHex,
      address: accountConfig.default.address,
    },
    modules: {
      TokenDeployer: '0xce854db9e3d7ae088359dbc54e2d425370c86a010b7656a272019abd9abf5b5a',
      LiquidswapDeployer: '0xa7f01413d33ba919441888637ca1607ca0ddcbfa3c0a9ddea64743aaa560e498',
      ClmmIntegrate: '0xd58630ae0012aa3c6fa61d2a9038bb79382e022ff159bfe4ad78d9d5c72cb08d',
      FetcherDeployer: '0x1a20cf35d14815220efcd3b11f7bc3624914b1af475959a2d679e1c3d70cfe52',
      IntegerMate: '0xa7f01413d33ba919441888637ca1607ca0ddcbfa3c0a9ddea64743aaa560e498',
    },
  },
  mainnet: {
    // ...
  }
}

2. Init SDK

export const sdkEnv =  netConfig.mainnet
const defaultNetworkOptions: SdkOptions = {
  rpcUrl: sdkEnv.fullRpcUrl,
  fraphQLUrl:sdkEnv.fraphQLUrl,
  networkOptions: {
    nativeToken: '0x1::aptos_coin::AptosCoin',
    launchpad: sdkEnv.launchpad,
    simulationAccount: sdkEnv.simulationAccount,
    modules: sdkEnv.modules,
  },
}
const sdk = new SDK(defaultNetworkOptions)

3. fetch the token list and pool list

  • The token list and pool list is fetched from config-extended contains the token metadata.
  • code example for this guide can be found token.test.ts
const networkOptions = sdk.sdkOptions.networkOptions
const simulationAccount = networkOptions.simulationAccount
const ownerAddress = networkOptions.TokenDeployer

// Fetch  all tokens
const tokenList =  await sdk.Token.getAllRegisteredTokenList(simulationAccount)

// Fetch  all tokens for specify ownerAddress
const tokenList =  await sdk.Token.getOwnerTokenList(simulationAccount,ownerAddress)

// Fetch  all pools
const poolList =  await sdk.Token.getAllRegisteredPoolList(simulationAccount)

// Fetch  all pools for specify ownerAddress
const poolList =  await sdk.Token.getOwnerPoolList(simulationAccount,ownerAddress)

//Fetch  all pools (contains the token metadata)
const poolList =  await sdk.Token.getWarpPoolList(simulationAccount)

// Fetch  all pools for specify ownerAddress (contains the token metadata)
const poolList =  await sdk.Token.getOwnerPoolList(simulationAccount,ownerAddress)

4. fetch the clmm pool and position

  • the clmm pool not contains the token metadata.
  • all liquidity and swap operations are based on clmm pool.
  • code example for this guide can be found pool.test.ts
4.1 fetch the clmm pool and position
//Fetch all clmm pools
const assignPools = [''] // query assign pool , if is empty else query all pool
const offset = 0  // optional paging cursor
const limit = 10  // maximum number of items per page
const pools = await sdk.Resources.getPools(assignPools, offset, limit)

//Fetch clmm pool by poolAddress
const pool = await sdk.Resources.getPool(poolAddress)

//Fetch clmm position list of accountAddress for assign pools
const pool = sdk.Resources.getPositionList(accountAddress, pools)

//Fetch clmm position by positionName
sdk.Resources.getPosition(pool.poolAddress, 'Cetus LP | Pool3-20')
4.2 create clmm pool and add liquidity
const account = buildTestAccount()
// initialize sqrt_price
const initialize_sqrt_price = TickMath.priceToSqrtPriceX64(d(1.2),6,6).toString()
const tick_spacing = 18
const current_tick_index = TickMath.sqrtPriceX64ToTickIndex(new BN(initialize_sqrt_price))
// build tick range
const lowerTick = TickMath.getPrevInitializableTickIndex(new BN(current_tick_index).toNumber()
    , new BN(tick_spacing).toNumber())
const upperTick = TickMath.getNextInitializableTickIndex(new BN(current_tick_index).toNumber()
    , new BN(tick_spacing).toNumber())
const lowerSqrtPrice = TickMath.tickIndexToSqrtPriceX64(lowerTick)
const upperSqrtPrice = TickMath.tickIndexToSqrtPriceX64(upperTick)
// optional : If liquidity is 0, only pool is created
const liquidity = new BN(100000)
// Estimate token a and token b by liquidity
const coinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(liquidity, new BN(initialize_sqrt_price), lowerSqrtPrice, upperSqrtPrice, true)
// Estimate slippageTolerance
const slippageTolerance = new Percentage(new BN(5), new BN(100))
const { tokenMaxA, tokenMaxB } = adjustForCoinSlippage(coinAmounts, slippageTolerance, true)
// build creatPoolPayload Payload
const creatPoolPayload = sdk.Pool.creatPoolTransactionPayload({
    coinTypeA: `0x3cfe7b9f6106808a8178ebd2d5ae6656cd0ccec15d33e63fd857c180bde8da75::coin:CetusUSDT`,
    coinTypeB: `0x3cfe7b9f6106808a8178ebd2d5ae6656cd0ccec15d33e63fd857c180bde8da75::coin::CetusUSDC`,
    tick_spacing: 12,
    initialize_sqrt_price: new BN(initialize_sqrt_price),
    uri: '',
    delta_liquidity: liquidity,
    max_amount_a: tokenMaxA,
    max_amount_b: tokenMaxB,
    tick_lower: lowerTick,
    tick_upper: upperTick
  },true) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account1, creatPoolPayload)
console.log('creatPool', respose)

5. Liquidity

code example for this guide can be found position.test.ts

5.1 open position and addLiquidity
const account = buildTestAccount()
//  Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
//  build lowerTick and  upperTick
const lowerTick = TickMath.getPrevInitializableTickIndex(new BN(pool.current_tick_index).toNumber()
      ,new BN(pool.tickSpacing).toNumber())
const upperTick = TickMath.getNextInitializableTickIndex(new BN(pool.current_tick_index).toNumber()
      ,new BN(pool.tickSpacing).toNumber())
// fix input token amount
const coinAmount = new BN(120000)
// input token amount is token a
const fix_amount_a = true
// slippage value
const slippage = 0.05
const curSqrtPrice = new BN(pool.current_sqrt_price)
// Estimate liquidity and token amount from one amounts
const liquidityInput = ClmmPoolUtil.estLiquidityAndcoinAmountFromOneAmounts(
        lowerTick,
        upperTick,
        coinAmount,
        fix_amount_a,
        true,
        slippage,
        curSqrtPrice
      )
// Estimate  token a and token b amount
const amount_a = fix_amount_a ? coinAmount.toNumber()  : liquidityInput.tokenMaxA.toNumber()
const amount_b = fix_amount_a ? liquidityInput.tokenMaxB.toNumber()  : coinAmount.toNumber()

// build open position and addLiquidity Payload
const addLiquidityPayload = sdk.Position.createAddLiquidityTransactionPayload(
      {
          amount_a,
          amount_b,
          fix_amount_a,
          pool: pool.poolAddress,
          coinTypeA: pool.coinTypeA,
          coinTypeB: pool.coinTypeB,
          tick_lower: lowerTick,
          tick_upper: upperTick,
          is_open: true,// control whether or not to create a new position or add liquidity on existed position.
          index: 0,// index: position index. if `is_open` is true, index is no use.
      },
        true
      ) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, addLiquidityPayload)
5.2 addLiquidity
const account = buildTestAccount()
//  Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
//  Fetch position data
const position = await sdk.Resources.getPositionInfo(pool, position_name)
//  build position lowerTick and upperTick
const lowerTick = Number(position.tick_lower_index)
const upperTick = Number(position.tick_upper_index)
// fix input token amount
const coinAmount = new BN(120000)
// input token amount is token a
const fix_amount_a = true
// slippage value
const slippage = 0.05
const curSqrtPrice = new BN(pool.current_sqrt_price)
// Estimate liquidity and token amount from one amounts
const liquidityInput = ClmmPoolUtil.estLiquidityAndcoinAmountFromOneAmounts(
        lowerTick,
        upperTick,
        coinAmount,
        fix_amount_a,
        true,
        slippage,
        curSqrtPrice
      )
// Estimate  token a and token b amount
const amount_a = fix_amount_a ? coinAmount.toNumber()  : liquidityInput.tokenMaxA.toNumber()
const amount_b = fix_amount_a ? liquidityInput.tokenMaxB.toNumber()  : coinAmount.toNumber()

// build addLiquidity Payload
const addLiquidityPayload = sdk.Position.createAddLiquidityTransactionPayload(
      {
          amount_a,
          amount_b,
          fix_amount_a,
          pool: pool.poolAddress,
          coinTypeA: pool.coinTypeA,
          coinTypeB: pool.coinTypeB,
          tick_lower: lowerTick,
          tick_upper: upperTick,
          is_open: false,// control whether or not to create a new position or add liquidity on existed position.
          index: position.index,// index: position index. if `is_open` is true, index is no use.
      },
        true
      ) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, addLiquidityPayload)
5.3 removeLiquidity
  • if want to remove liquidity and collect rewarder, The cointype of the reward must be passed in when build Payload, else only remove liquidity
const account = buildTestAccount()
// Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
// Fetch position data
const position = await sdk.Resources.getPositionInfo(pool, positionName)
// build tick data
const lowerSqrtPrice = TickMath.tickIndexToSqrtPriceX64(Number(position.tick_lower_index))
const upperSqrtPrice = TickMath.tickIndexToSqrtPriceX64(Number(position.tick_upper_index))
const ticksHandle = pool.ticks_handle
const tickLower = await sdk.Resources.getTickDataByIndex(ticksHandle, position.tick_lower_index)
const tickUpper = await sdk.Resources.getTickDataByIndex(ticksHandle, position.tick_upper_index)
// input liquidity amount for remove
const liquidity = new BN(10000)
// slippage value
const slippageTolerance = new Percentage(new BN(5), new BN(100))
const curSqrtPrice = new BN(pool.current_sqrt_price)
// Get token amount fron liquidity.
const coinAmounts = ClmmPoolUtil.getCoinAmountFromLiquidity(liquidity, curSqrtPrice, lowerSqrtPrice, upperSqrtPrice, false)
// adjust  token a and token b amount for slippage
const { tokenMaxA, tokenMaxB } = adjustForCoinSlippage(coinAmounts, slippageTolerance, false)
// Fetch all rewards data for position (If only remove liquidity ,  This step is optional)
const rewards: any[] = await sdk.Rewarder.posRewardersAmount(poolAddress, positionName, tickLower, tickUpper)
const rewardsNum = rewards.length
// build removeLiquidity Payload
const removeLiquidityPayload = (await sdk.Position.removeLiquidityTransactionPayload(
        {
          pool: pool.poolAddress,
          coinTypeA: pool.coinTypeA,
          coinTypeB: pool.coinTypeB,
          delta_liquidity: liquidity,
          min_amount_a: tokenMaxA.toNumber(),
          min_amount_b: tokenMaxB.toNumber(),
          pos_index: position.index,
          is_close: false,
          // If only remove liquidity , coinTypeC coinTypeD coinTypeE rewards_num use default value
          coinTypeC: rewardsNum > 0 ? rewards[0].coin_address : "",
          coinTypeD: rewardsNum > 1 ? rewards[1].coin_address : "",
          coinTypeE: rewardsNum > 2 ? rewards[2].coin_address : "",
          rewards_num: rewardsNum
        },
        true
      )) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, removeLiquidityPayload)
5.4 close position

only empty position can be closed

const account = buildTestAccount()
// Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
// Fetch position data
const position = await sdk.Resources.getPositionInfo(pool, positionName)

// build closePosition Payload
const removeLiquidityPayload = (await sdk.Position.closePositionTransactionPayload(
        {
          pool_address: pool.poolAddress,
          coinTypeA: pool.coinTypeA,
          coinTypeB: pool.coinTypeB,
          pos_index: position.index,
        },
        true
      )) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, removeLiquidityPayload)
5.5 collect fee
const account = buildTestAccount()
// Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
// Fetch position data
const position = await sdk.Resources.getPositionInfo(pool, positionName)

// build collect fee Payload
const removeLiquidityPayload = (await sdk.Position.collectFeeTransactionPayload(
        {
          pool_address: pool.poolAddress,
          coinTypeA: pool.coinTypeA,
          coinTypeB: pool.coinTypeB,
          pos_index: position.index,
        },
        true
      )) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, removeLiquidityPayload)

6. swap

const account = buildTestAccount()
//  Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
//  build tick
const ticks = await getTicks(poolAddress)
const tickdatas = getTickDataFromUrlData(ticks)
// 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 fix_amount_a = true
// slippage value
const slippage = 0.05
const curSqrtPrice = new BN(pool.current_sqrt_price)
// Estimated amountIn amountOut fee
const res = await sdk.Swap.calculateRates({
      decimalsA: 6,
      decimalsB: 6,
      a2b,
      byAmountIn,
      amount,
      swapTicks: tickdatas,
      currentPool,
    })
const toAmount = res.estimatedAmountOut
const amountLimit = toAmount.sub(toAmount.mul(new BN(slippage)))

// build swap Payload
const swapPayload = sdk.Swap.createSwapTransactionPayload(
      {
        pool_addr: pool,
        coinTypeA,
        coinTypeB,
        a_to_b: true,
        by_amount_in: true,
        amount: res.amount.toString(),
        amount_limit: amountLimit.toString(),
        partner: '',
      },
      true
    ) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, addLiquidityPayload)

7. collect rewarder

const account = buildTestAccount()
// Fetch pool data
const pool = await sdk.Resources.getPool(poolAddress)
// Fetch position data
const position = await sdk.Resources.getPositionInfo(pool, positionName)
// build tickLower  and tickUpper
const ticksHandle = pool.ticks_handle
const tickLower = await sdk.Resources.getTickDataByIndex(ticksHandle, Number(position.tick_lower_index))
const tickUpper = await sdk.Resources.getTickDataByIndex(ticksHandle, Number(position.tick_upper_index))
// Fetch all rewarder for position
const rewards: any[] = await sdk.Rewarder.posRewardersAmount(poolAddress, positionName, tickLower, tickUpper)
const rewardsNum = rewards.length

// build collect rewarder Payload
const collectPoolRewarderParams: CollectPoolRewarderParams = {
      coinTypeA: rewardsNum > 0 ? rewards[0].coin_address : "",
      coinTypeB: rewardsNum > 1 ? rewards[1].coin_address : "",
      coinTypeC: rewardsNum > 2 ? rewards[2].coin_address : "",
      coinTypeD: rewardsNum > 3 ? rewards[3].coin_address : "",
      coinTypeE: rewardsNum > 4 ? rewards[4].coin_address : "",
      pool_address: poolAddress,
      pos_index: position.index,
      rewarder_nums: rewardsNum
    }
const collectPoolRewarderTransactionPayload = (await sdk.Rewarder.collectPoolRewarderTransactionPayload(collectPoolRewarderParams)) as TxnBuilderTypes.TransactionPayloadEntryFunction
const respose = await sendPayloadTx(sdk.client, account, addLiquidityPayload)

8. other helper function

// Fetch tick by index from table
const ticksHandle = pool.ticks_handle
const tickLower = await sdk.Resources.getTickDataByIndex(ticksHandle, Number(position.tick_lower_index))
// Fetch all tick data for pool
const res = await sdk.Fetcher.fetchTicks({
          pool: '0xd2330a4f32f14ae3bcfe00c847ce495d444fdda5579a097a42ddef24b45c3460',
          coinTypeA: '0x3cfe7b9f6106808a8178ebd2d5ae6656cd0ccec15d33e63fd857c180bde8da75::coin::CetusUSDT',
          coinTypeB: '0x3cfe7b9f6106808a8178ebd2d5ae6656cd0ccec15d33e63fd857c180bde8da75::coin::CetusUSDC',
        })

Package Sidebar

Install

npm i @cetusprotocol/cetus-clmm-aptos-sdk

Weekly Downloads

3

Version

1.3.3

License

Apache-2.0

Unpacked Size

4.11 MB

Total Files

14

Last publish

Collaborators

  • cetusprotocol