Swapping

Execute token swaps in CPMM pools. The SDK supports both base-input (fixed input amount) and base-output (fixed output amount) swaps.


Base-input swap (exact input)

Specify the exact amount of tokens to sell. The SDK calculates how many tokens you receive.

import {
  ApiV3PoolInfoStandardItemCpmm,
  CpmmKeys,
  CpmmParsedRpcData,
  CurveCalculator,
  FeeOn,
  TxVersion,
} from '@raydium-io/raydium-sdk-v2'
import { NATIVE_MINT } from '@solana/spl-token'
import BN from 'bn.js'
import { initSdk } from '../config'

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

  const poolId = '7JuwJuNU88gurFnyWeiyGKbFmExMWcmRZntn9imEzdny'
  const inputAmount = new BN(100)
  const inputMint = NATIVE_MINT.toBase58()

  let poolInfo: ApiV3PoolInfoStandardItemCpmm
  let poolKeys: CpmmKeys | undefined
  let rpcData: CpmmParsedRpcData

  if (raydium.cluster === 'mainnet') {
    const data = await raydium.api.fetchPoolById({ ids: poolId })
    poolInfo = data[0] as ApiV3PoolInfoStandardItemCpmm
    rpcData = await raydium.cpmm.getRpcPoolInfo(poolInfo.id, true)
  } else {
    const data = await raydium.cpmm.getPoolInfoFromRpc(poolId)
    poolInfo = data.poolInfo
    poolKeys = data.poolKeys
    rpcData = data.rpcData
  }

  if (inputMint !== poolInfo.mintA.address && inputMint !== poolInfo.mintB.address)
    throw new Error('input mint does not match pool')

  const baseIn = inputMint === poolInfo.mintA.address

  // Compute the swap off-chain
  const swapResult = CurveCalculator.swapBaseInput(
    inputAmount,
    baseIn ? rpcData.baseReserve : rpcData.quoteReserve,
    baseIn ? rpcData.quoteReserve : rpcData.baseReserve,
    rpcData.configInfo!.tradeFeeRate,
    rpcData.configInfo!.creatorFeeRate,
    rpcData.configInfo!.protocolFeeRate,
    rpcData.configInfo!.fundFeeRate,
    rpcData.feeOn === FeeOn.BothToken || rpcData.feeOn === FeeOn.OnlyTokenB
  )

  /**
   * swapResult.inputAmount   -> actual input after fees
   * swapResult.outputAmount  -> tokens received
   * swapResult.tradeFee      -> fee charged on input mint
   */

  const { execute } = await raydium.cpmm.swap({
    poolInfo,
    poolKeys,
    inputAmount,
    swapResult,
    slippage: 0.001, // 0.1% — range: 1 (100%) to 0.0001 (0.01%)
    baseIn,
    txVersion: TxVersion.V0,
    // optional: set up priority fee here
    // computeBudgetConfig: {
    //   units: 600000,
    //   microLamports: 4659150,
    // },
  })

  const { txId } = await execute({ sendAndConfirm: true })
  console.log(`swapped: ${poolInfo.mintA.symbol} to ${poolInfo.mintB.symbol}:`, {
    txId: `https://explorer.solana.com/tx/${txId}`,
  })
}

swap()

Base-output swap (exact output)

Specify the exact amount of tokens to receive. The SDK calculates how many tokens you need to sell.


Swap parameters

Parameter
Type
Description

poolInfo

object

Pool info from API or RPC.

poolKeys

object

Pool keys. Required for devnet.

inputAmount

BN

Amount of input tokens (base-input). Ignored when fixedOut: true.

fixedOut

boolean

Set true for base-output swaps. Default false.

swapResult

object

Pre-computed swap result from CurveCalculator.swapBaseInput() or CurveCalculator.swapBaseOutput().

slippage

number

Slippage tolerance as a decimal. 0.001 = 0.1%. Range: 1 (100%) to 0.0001 (0.01%).

baseIn

boolean

true if swapping mintA → mintB, false for mintB → mintA.

txVersion

TxVersion

Transaction version.

CurveCalculator

The CurveCalculator computes swap amounts off-chain before submitting the transaction.

Method
Description

swapBaseInput()

Given exact input amount, compute output and fees.

swapBaseOutput()

Given desired output amount, compute required input.

Both methods take the same fee parameters from the pool's configInfo:

Parameter
Description

tradeFeeRate

Fee taken from swap input, in units of 1e-6.

creatorFeeRate

Additional fee sent to the pool creator.

protocolFeeRate

Share of trade fee sent to Raydium protocol.

fundFeeRate

Share of trade fee sent to Raydium treasury.

circle-info

Always fetch fresh RPC data (getRpcPoolInfo) before computing swaps to get the latest reserves and avoid stale quotes.

Last updated

Was this helpful?