raydium-io / raydium-sdk-V2

Open-source Typescript SDK for Raydium
GNU General Public License v3.0
87 stars 49 forks source link

Token2022 support in CPMM Swap #5

Closed artembruh closed 5 months ago

artembruh commented 5 months ago

Hello! Many thanks for providing such SDK, it solves a lot of tasks out of the box!

I encountered an issue while implementing swap of WSOL and Token2022. Here is a pair address: 8THC7UQN8zPXRL61o75fP4gcwRyB5W3o74yHyqarkqZ9. The error is - while simulating generated transaction I have got an error IncorrectProgramId. Searching through the code, I have found out that CpmmModule.swap method is ignoring token's program id while creating account here and here. Additionally, when checkCreateATAOwner is enabled, the handleTokenAccount will check account's owner only against TOKEN_PROGRAM_ID but not both with TOKEN_2022_PRPOGRAM_ID.

Will appreciate if you can take a look at this, and will provide any additional info if needed.

Here's a reproduce script taken from the sdk-v2-demo repo

import { ApiV3PoolInfoStandardItemCpmm, CurveCalculator } from '@raydium-io/raydium-sdk-v2'
import { initSdk } from '../config'
import BN from 'bn.js'
import { isValidCpmm } from './utils'

export const swap = async () => {
  const raydium = await initSdk()

  // SOL - USDC pool
  // note: api doesn't support get devnet pool info
  const data = await raydium.api.fetchPoolById({ ids: '8THC7UQN8zPXRL61o75fP4gcwRyB5W3o74yHyqarkqZ9' })
  const poolInfo = data[0] as ApiV3PoolInfoStandardItemCpmm
  if (!isValidCpmm(poolInfo.programId)) throw new Error('target pool is not CPMM pool')
  const rpcData = await raydium.cpmm.getRpcPoolInfo(poolInfo.id, true)

  const inputAmount = new BN(10000000)

  // swap pool mintA for mintB
  const swapResult = CurveCalculator.swap(
    inputAmount,
    rpcData.baseReserve,
    rpcData.quoteReserve,
    rpcData.configInfo!.tradeFeeRate
  )

  /**
   * swapResult.sourceAmountSwapped -> input amount
   * swapResult.destinationAmountSwapped -> output amount
   * swapResult.tradeFee -> this swap fee, charge input mint
   */

  const { execute } = await raydium.cpmm.swap({
    poolInfo,
    swapResult,
    baseIn: true,
  })

  await execute({ skipPreflight: false });
}

/** uncomment code below to execute */
swap()
cruzshia commented 5 months ago

nice catch! updated in latest commit and add slippage params in swap method.

artembruh commented 5 months ago

worked great, thanks for the fix!