Skip to content

Latest commit

 

History

History
3705 lines (2804 loc) · 99.2 KB

File metadata and controls

3705 lines (2804 loc) · 99.2 KB

Dynamic DAMM-V2 SDK: Function Documentation

Table of Contents


Core Functions

createPool

Creates a new standard pool according to a predefined configuration.

Function

async createPool(params: CreatePoolParams): TxBuilder

Parameters

interface CreatePoolParams {
  payer: PublicKey; // The wallet paying for the transaction
  creator: PublicKey; // The creator of the pool
  config: PublicKey; // The configuration account for the pool
  positionNft: PublicKey; // The mint for the initial position NFT
  tokenAMint: PublicKey; // The mint address for token A
  tokenBMint: PublicKey; // The mint address for token B
  activationPoint: BN | null; // The slot or timestamp for activation
  tokenAAmount: BN; // Initial amount of token A to deposit
  tokenBAmount: BN; // Initial amount of token B to deposit
  initSqrtPrice: BN; // Initial sqrt price in Q64 format
  liquidityDelta: BN; // Initial liquidity delta in Q64 format
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  isLockLiquidity?: boolean; // true if you wanna permanent lock position after pool created.
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

// First, prepare the pool creation parameters
const configState = await cpAmm.getConfigState(configAccount);
const initPrice = 10; // 1 base token = 10 quote token
const {actualInputAmount, consumedInputAmount, outputAmount, liquidityDelta} = cpAmm.getDepositQuote({
  inAmount: new BN(5_000_000_000), // 5 tokenA (base token) with 9 decimals
  isTokenA: true;
  minSqrtPrice: configState.sqrtMinPrice,
  maxSqrtPrice: configState.sqrtMinPrice,
  sqrtPrice: getSqrtPriceFromPrice(initPrice, tokenADecimal, tokenBDecimal),
  inputTokenInfo, // provide if input token is token2022
  outputTokenInfo // provide if output token is token2022
})

const createPoolTx = await cpAmm.createPool({
  payer: wallet.publicKey,
  creator: wallet.publicKey,
  config: configAddress,
  positionNft: positionNftMint,
  tokenAMint,
  tokenBMint,
  activationPoint: null,
  tokenAAmount: consumedInputAmount,
  tokenBAmount: outputAmount,
  initSqrtPrice: getSqrtPriceFromPrice(initPrice, tokenADecimal, tokenBDecimal);,
  liquidityDelta: liquidityDelta,
  tokenAProgram,
  tokenBProgram
});

Notes

  • Both token amounts must be greater than zero
  • If using native SOL, it will be automatically wrapped to wSOL
  • The config parameter should be a valid configuration account
  • Pool creation automatically creates an initial position
  • Use preparePoolCreationParams to calculate proper initSqrtPrice and liquidityDelta

createCustomPool

Creates a customizable pool with specific fee parameters, reward settings, and activation conditions.

Function

async createCustomPool(params: InitializeCustomizeablePoolParams): Promise<{
  tx: Transaction;
  pool: PublicKey;
  position: PublicKey;
}>

Parameters

interface InitializeCustomizeablePoolParams {
  payer: PublicKey; // The wallet paying for the transaction
  creator: PublicKey; // The creator of the pool
  positionNft: PublicKey; // The mint for the initial position NFT
  tokenAMint: PublicKey; // The mint address for token A
  tokenBMint: PublicKey; // The mint address for token B
  tokenAAmount: BN; // Initial amount of token A to deposit
  tokenBAmount: BN; // Initial amount of token B to deposit
  sqrtMinPrice: BN; // Minimum sqrt price
  sqrtMaxPrice: BN; // Maximum sqrt price
  initSqrtPrice: BN; // Initial sqrt price in Q64 format
  liquidityDelta: BN; // Initial liquidity in Q64 format
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  poolFees: PoolFees; // Fee configuration
  hasAlphaVault: boolean; // Whether the pool has an alpha vault
  collectFeeMode: number; // How fees are collected (0: normal, 1: alpha)
  activationPoint: BN; // The slot or timestamp for activation
  activationType: number; // 0: slot, 1: timestamp
  isLockLiquidity?: boolean; // true if you wanna permanent lock position after pool created.
}

interface PoolFees {
  baseFee: BaseFee; // Base fee configuration (see below for different modes)
  padding: number[];
  dynamicFee?: {
    // Optional dynamic fee configuration
    binStep: number;
    binStepU128: BN;
    filterPeriod: number;
    decayPeriod: number;
    reductionFactor: number;
    variableFeeControl: number;
    maxVolatilityAccumulator: number;
  };
}

// Base Fee Mode Types:
// 0 = Fee Time Scheduler Linear
// 1 = Fee Time Scheduler Exponential
// 2 = Rate Limiter
// 3 = Fee Market Cap Scheduler Linear
// 4 = Fee Market Cap Scheduler Exponential

// For Fee Time Scheduler (baseFeeMode 0 or 1):
interface FeeTimeSchedulerBaseFee {
  cliffFeeNumerator: BN; // Starting fee numerator (e.g., 500000000 = 50%)
  baseFeeMode: number; // 0 = Linear, 1 = Exponential
  numberOfPeriod: number; // Number of fee reduction periods
  periodFrequency: BN; // Time between periods (slots or seconds)
  reductionFactor: BN; // Fee reduction per period
}

// For Rate Limiter (baseFeeMode 2):
interface RateLimiterBaseFee {
  cliffFeeNumerator: BN; // Base fee numerator (e.g., 10000000 = 1%)
  baseFeeMode: number; // 2 = Rate Limiter
  feeIncrementBps: number; // Fee increment in basis points per reference amount
  maxLimiterDuration: number; // Maximum duration for rate limiter
  maxFeeBps: number; // Maximum fee cap in basis points
  referenceAmount: BN; // Reference amount for fee calculation
}

// For Fee Market Cap Scheduler (baseFeeMode 3 or 4):
interface FeeMarketCapSchedulerBaseFee {
  cliffFeeNumerator: BN; // Starting fee numerator (e.g., 500000000 = 50%)
  baseFeeMode: number; // 3 = Linear, 4 = Exponential
  numberOfPeriod: number; // Number of fee reduction periods
  sqrtPriceStepBps: number; // Sqrt price step in bps to advance one period
  schedulerExpirationDuration: number; // Duration after which scheduler expires
  reductionFactor: BN; // Fee reduction per period
}

Returns

An object containing:

  • tx: The transaction to sign and send
  • pool: The public key of the created pool
  • position: The public key of the initial position

Example

// First, prepare the pool creation parameters
const { initSqrtPrice, liquidityDelta } = cpAmm.preparePoolCreationParams({
  tokenAAmount: new BN(5_000_000_000),
  tokenBAmount: new BN(20_000_000),
  minSqrtPrice: MIN_SQRT_PRICE,
  maxSqrtPrice: MAX_SQRT_PRICE,
});

const baseFeeParams = getBaseFeeParams(
  {
    baseFeeMode: BaseFeeMode.FeeTimeSchedulerExponential,
    feeTimeSchedulerParam: {
      startingFeeBps: 5000,
      endingFeeBps: 25,
      numberOfPeriod: 50,
      totalDuration: 300,
    },
  },
  9,
  ActivationType.Timestamp
);
const dynamicFeeParams = getDynamicFeeParams(25); // max dynamic fee is 20% of 0.25%
const poolFees: PoolFeesParams = {
  baseFee: baseFeeParams,
  padding: [],
  dynamicFee: dynamicFeeParams,
};

const { tx, pool, position } = await cpAmm.createCustomPool({
  payer: wallet.publicKey,
  creator: wallet.publicKey,
  positionNft: positionNftMint,
  tokenAMint: usdcMint,
  tokenBMint: btcMint,
  tokenAAmount: new BN(5_000_000_000),
  tokenBAmount: new BN(20_000_000),
  sqrtMinPrice: MIN_SQRT_PRICE,
  sqrtMaxPrice: MAX_SQRT_PRICE,
  initSqrtPrice: initSqrtPrice,
  liquidityDelta: liquidityDelta,
  poolFees,
  hasAlphaVault: false,
  collectFeeMode: 0, // 0: BothToken, 1: onlyB
  activationPoint: new BN(Date.now()),
  activationType: 1, // 0: slot, 1: timestamp
  tokenAProgram,
  tokenBProgram,
});

Notes

  • Use this function instead of createPool when you need custom fee structures
  • Use preparePoolCreationParams to calculate proper initSqrtPrice and liquidityDelta

createCustomPoolWithDynamicConfig

Creates a customizable pool with dynamic configuration, allowing for specific fee parameters with specified pool creator authority

Function

async createCustomPoolWithDynamicConfig(params: InitializeCustomizeablePoolWithDynamicConfigParams): Promise<{
  tx: Transaction;
  pool: PublicKey;
  position: PublicKey;
}>

Parameters

interface InitializeCustomizeablePoolWithDynamicConfigParams {
  payer: PublicKey; // The wallet paying for the transaction
  creator: PublicKey; // The creator of the pool
  positionNft: PublicKey; // The mint for the initial position NFT
  tokenAMint: PublicKey; // The mint address for token A
  tokenBMint: PublicKey; // The mint address for token B
  tokenAAmount: BN; // Initial amount of token A to deposit
  tokenBAmount: BN; // Initial amount of token B to deposit
  sqrtMinPrice: BN; // Minimum sqrt price
  sqrtMaxPrice: BN; // Maximum sqrt price
  initSqrtPrice: BN; // Initial sqrt price in Q64 format
  liquidityDelta: BN; // Initial liquidity in Q64 format
  poolFees: PoolFeesParams; // Fee configuration
  hasAlphaVault: boolean; // Whether the pool has an alpha vault
  collectFeeMode: number; // How fees are collected (0: normal, 1: alpha)
  activationPoint: BN | null; // The slot or timestamp for activation (null for immediate)
  activationType: number; // 0: slot, 1: timestamp
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  config: PublicKey; // dynamic config account
  poolCreatorAuthority: PublicKey; // Authority allowed to create pools with this config
  isLockLiquidity?: boolean; // true if you wanna permanent lock position after pool created.
}

Returns

An object containing:

  • tx: The transaction to sign and send
  • pool: The public key of the created pool
  • position: The public key of the initial position

Example

// First, prepare the pool creation parameters
const tokenAAmount = new BN(5_000_000_000);
const tokenBAmount = new BN(20_000_000);
const sqrtPrice = getSqrtPriceFromPrice("172", tokenADecimal, tokenBDecimal);
const sqrtMinPrice = getSqrtPriceFromPrice("4", tokenADecimal, tokenBDecimal);
const sqrtMaxPrice = getSqrtPriceFromPrice("400", tokenADecimal, tokenBDecimal);
const { initSqrtPrice, liquidityDelta } = cpAmm.getLiquidityDelta({
  maxAmountTokenA: tokenAAmount,
  maxAmountTokenB: tokenBAmount,
  sqrtMaxPrice,
  sqrtMinPrice,
  sqrtPrice,
});

const baseFeeParams = getBaseFeeParams(
  {
    baseFeeMode: BaseFeeMode.FeeTimeSchedulerExponential,
    feeTimeSchedulerParam: {
      startingFeeBps: 5000,
      endingFeeBps: 25,
      numberOfPeriod: 50,
      totalDuration: 300,
    },
  },
  9,
  ActivationType.Timestamp
);
const dynamicFeeParams = getDynamicFeeParams(25); // max dynamic fee is 20% of 0.25%
const poolFees: PoolFeesParams = {
  baseFee: baseFeeParams,
  padding: [],
  dynamicFee: dynamicFeeParams,
};

const { tx, pool, position } = await cpAmm.createCustomPoolWithDynamicConfig({
  payer
  creator,
  config: dynamicConfigAddress,
  poolCreatorAuthority: poolCreatorAuth.publicKey,
  positionNft: positionNftMint,
  tokenAMint: usdcMint,
  tokenBMint: btcMint,
  tokenAAmount,
  tokenBAmount,
  sqrtMinPrice,
  sqrtMaxPrice,
  initSqrtPrice,
  liquidityDelta,
  poolFees,
  hasAlphaVault: false,
  collectFeeMode: 0, // 0: Both tokens, 1: Only token B
  activationPoint: null,
  activationType: 1, // 0: slot, 1: timestamp
  tokenAProgram: TOKEN_PROGRAM_ID,
  tokenBProgram: TOKEN_PROGRAM_ID,
});

createPosition

Creates a new position in an existing pool.

Function

async createPosition(params: CreatePositionParams): TxBuilder

Parameters

interface CreatePositionParams {
  owner: PublicKey; // The owner of the position
  payer: PublicKey; // The wallet paying for the transaction
  pool: PublicKey; // The pool to create a position in
  positionNft: PublicKey; // The mint for the position NFT
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const createPositionTx = await cpAmm.createPosition({
  owner: wallet.publicKey,
  payer: wallet.publicKey,
  pool: poolAddress,
  positionNft: positionNftMint,
});

const tx = await createPositionTx.transaction();
const result = await wallet.sendTransaction(tx, connection);

Notes

  • The positionNft should be a new mint that doesn't already have a position
  • Creating a position doesn't automatically add liquidity
  • After creating a position, use addLiquidity to provide tokens

getLiquidityDelta

Calculates the liquidity delta based on the provided token amounts and price ranges.

Function

async getLiquidityDelta(params: LiquidityDeltaParams): Promise<BN>

Parameters

interface LiquidityDeltaParams {
  maxAmountTokenA: BN; // Maximum amount of token A to use
  maxAmountTokenB: BN; // Maximum amount of token B to use
  sqrtMaxPrice: BN; // Maximum sqrt price for the range
  sqrtMinPrice: BN; // Minimum sqrt price for the range
  sqrtPrice: BN; // Current sqrt price
}

Returns

A BN representing the liquidity delta in Q64 format.

getQuote

Calculates the expected output amount for a swap, including fees and slippage protection.

Function

async getQuote(params: GetQuoteParams): Promise<{
  swapInAmount: BN;
  consumedInAmount: BN;
  swapOutAmount: BN;
  minSwapOutAmount: BN;
  totalFee: BN;
  priceImpact: number;
}>

Parameters

interface GetQuoteParams {
  inAmount: BN; // The amount of input token to swap
  inputTokenMint: PublicKey; // The mint of the input token
  slippage: number; // Slippage tolerance in percentage (e.g., 0.5 for 0.5%)
  poolState: PoolState; // The state of the pool
  currentTime: number; // Current timestamp (for time-based fees)
  currentSlot: number; // Current slot (for slot-based fees)
  inputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  outputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  tokenADecimal: number; // The decimal of the input token
  tokenBDecimal: number; // The decimal of the output token
  hasReferral?: boolean; // Whether the swap has a referral token account
}

Returns

An object containing:

  • swapInAmount: The original input amount
  • consumedInAmount: The actual input amount used (after transfer fees)
  • swapOutAmount: The expected output amount
  • minSwapOutAmount: The minimum output amount accounting for slippage
  • totalFee: The total fee to be paid
  • priceImpact: The price impact of the swap as a percentage

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const currentSlot = await connection.getSlot();
const blockTime = await connection.getBlockTime(currentSlot);
const quote = await cpAmm.getQuote({
  inAmount: new BN(100_000_000), // 100 USDC
  inputTokenMint: usdcMint,
  slippage: 0.5, // 0.5% slippage
  poolState,
  currentTime: blockTime,
  currentSlot,
  inputTokenInfo: {
    mint: usdcMint,
    currentEpoch: currentEpoch,
  },
  outputTokenInfo: {
    mint: btcMint,
    currentEpoch: currentEpoch,
  },
  tokenADecimal: 6,
  tokenBDecimal: 9,
  hasReferral: false,
});

console.log(`Expected output: ${quote.swapOutAmount.toString()}`);
console.log(`Minimum output: ${quote.minSwapOutAmount.toString()}`);
console.log(`Fee: ${quote.totalFee.toString()}`);
console.log(`Price impact: ${quote.priceImpact.toFixed(2)}%`);

Notes

  • Always check the price impact before executing a swap
  • The slippage parameter protects users from price movements
  • Use the minSwapOutAmount as the minimumAmountOut parameter for swap
  • For Token2022 tokens with transfer fees, provide the token info parameters

getQuote2

Calculates the expected output amount or input amount for a swap depending on the swap mode. There are 3 swap modes: ExactIn, ExactOut, PartialFill.

Function

async getQuote2(params: GetQuote2Params): Promise<{
  includedFeeInputAmount: BN;
  excludedFeeInputAmount: BN;
  amountLeft: BN;
  outputAmount: BN;
  nextSqrtPrice: BN;
  tradingFee: BN;
  protocolFee: BN;
  partnerFee: BN; // Deprecating soon
  referralFee: BN;
  priceImpact: Decimal;
  minimumAmountOut?: BN;
  maximumAmountIn?: BN;
}>

Parameters

interface GetQuote2Params {
  inputTokenMint: PublicKey; // The mint of the input token
  slippage: number; // Slippage tolerance in percentage (e.g., 0.5 for 0.5%)
  currentPoint: BN; // Current point depending on the activation type
  poolState: PoolState; // The state of the pool
  inputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  outputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  tokenADecimal: number; // The decimal of the input token
  tokenBDecimal: number; // The decimal of the output token
  hasReferral: boolean; // Whether the swap has a referral token account
  swapMode: SwapMode; // The swap mode
  amountIn?: BN; // The amount of input token to swap (for ExactIn and PartialFill modes)
  amountOut?: BN; // The amount of output token to swap (for ExactOut mode)
}

Returns

An object containing:

  • includedFeeInputAmount: The input amount including all applicable fees
  • excludedFeeInputAmount: The input amount excluding fees
  • amountLeft: The remaining amount after the swap (if any)
  • outputAmount: The expected output amount
  • nextSqrtPrice: The next sqrt price after the swap
  • tradingFee: The trading fee charged for the swap
  • protocolFee: The protocol fee charged for the swap
  • partnerFee: The partner fee charged for the swap (Deprecating soon)
  • referralFee: The referral fee charged for the swap
  • priceImpact: The price impact of the swap
  • minimumAmountOut (optional): The minimum output amount guaranteed (for ExactIn and PartialFill modes)
  • maximumAmountIn (optional): The maximum input amount allowed (for ExactOut mode)

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const currentPoint = await getCurrentPoint(
  connection,
  poolState.activationType
);
const quote = await cpAmm.getQuote2({
  inputTokenMint: poolState.tokenBMint,
  slippage: 0.5,
  currentPoint,
  poolState,
  tokenADecimal: 6,
  tokenBDecimal: 9,
  hasReferral: false,
  swapMode: SwapMode.PartialFill,
  amountIn: new BN(1_000_000_000),
});

Notes

  • Always check the price impact before executing a swap
  • The slippage parameter protects users from price movements
  • For Token2022 tokens with transfer fees, provide the token info parameters

getDepositQuote

Calculates the deposit quote for adding liquidity to a pool based on a single token input.

Function

async getDepositQuote(params: GetDepositQuoteParams): Promise<DepositQuote>

Parameters

interface GetDepositQuoteParams {
  inAmount: BN; // The amount of input token
  isTokenA: boolean; // Whether the input token is token A
  minSqrtPrice: BN; // Minimum sqrt price
  maxSqrtPrice: BN; // Maximum sqrt price
  sqrtPrice: BN; // Current sqrt price
  inputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  outputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
}

Returns

An object containing:

  • actualInputAmount: The actual input amount (after transfer fees)
  • consumedInputAmount: The full input amount including transfer fees
  • liquidityDelta: The amount of liquidity that will be added
  • outputAmount: The calculated amount of the other token to be paired

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);

const depositQuote = await cpAmm.getDepositQuote({
  inAmount: new BN(1_000_000_000), // 1,000 USDC
  isTokenA: true, // USDC is token A
  minSqrtPrice: poolState.sqrtMinPrice,
  maxSqrtPrice: poolState.sqrtMaxPrice,
  sqrtPrice: poolState.sqrtPrice,
});

console.log(`Liquidity delta: ${depositQuote.liquidityDelta.toString()}`);
console.log(`Required token B: ${depositQuote.outputAmount.toString()}`);

Notes

  • Use this to calculate how much of token B is needed when adding token A (or vice versa)
  • Particularly useful for single-sided liquidity provision
  • The function handles Token2022 transfer fees if token info is provided

getWithdrawQuote

Calculates the withdrawal quote for removing liquidity from a pool.

Function

async getWithdrawQuote(params: GetWithdrawQuoteParams): Promise<WithdrawQuote>

Parameters

interface GetWithdrawQuoteParams {
  liquidityDelta: BN; // The amount of liquidity to withdraw
  sqrtPrice: BN; // Current sqrt price
  maxSqrtPrice: BN; // Maximum sqrt price
  minSqrtPrice: BN; // Minimum sqrt price
  inputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
  outputTokenInfo?: {
    mint: Mint;
    currentEpoch: number;
  }; // Token info for Token2022 transfer fee calculations
}

Returns

An object containing:

  • liquidityDelta: The amount of liquidity being removed
  • outAmountA: The calculated amount of token A to receive
  • outAmountB: The calculated amount of token B to receive

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

// Calculate quote for removing half the liquidity
const liquidityToRemove = positionState.liquidity.div(new BN(2));

const withdrawQuote = await cpAmm.getWithdrawQuote({
  liquidityDelta: liquidityToRemove,
  sqrtPrice: poolState.sqrtPrice,
  minSqrtPrice: poolState.sqrtMinPrice,
  maxSqrtPrice: poolState.sqrtMaxPrice,
});

console.log(`Expected token A: ${withdrawQuote.outAmountA.toString()}`);
console.log(`Expected token B: ${withdrawQuote.outAmountB.toString()}`);

Notes

  • Use this to estimate the tokens you'll receive when removing liquidity
  • The function handles Token2022 transfer fees if token info is provided
  • The calculation accounts for the current price relative to the position's price range

swap

Executes a token swap in the pool.

Function

async swap(params: SwapParams): TxBuilder

Parameters

interface SwapParams {
  payer: PublicKey; // The wallet paying for the transaction
  pool: PublicKey; // Address of the pool to swap in
  inputTokenMint: PublicKey; // Mint of the input token
  outputTokenMint: PublicKey; // Mint of the output token
  amountIn: BN; // Amount of input token to swap
  minimumAmountOut: BN; // Minimum amount of output token (slippage protection)
  tokenAVault: PublicKey; // Pool's token A vault
  tokenBVault: PublicKey; // Pool's token B vault
  tokenAMint: PublicKey; // Pool's token A mint
  tokenBMint: PublicKey; // Pool's token B mint
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  receiver?: PublicKey; // Optional receiver of the input and output tokens
  referralTokenAccount?: PublicKey; // Optional referral account for fees
  poolState?: PoolState; // Optional pool state to pass in to atomically fetch the pool state
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const currentSlot = await connection.getSlot();
const blockTime = await connection.getBlockTime(currentSlot);
// Get quote first
const quote = await cpAmm.getQuote({
  inAmount: new BN(100_000_000), // 100 USDC
  inputTokenMint: poolState.tokenAMint,
  slippage: 0.5,
  poolState,
  currentTime: blockTime,
  currentSlot,
});

// Execute swap
const swapTx = await cpAmm.swap({
  payer: wallet.publicKey,
  pool: poolAddress,
  inputTokenMint: poolState.tokenAMint,
  outputTokenMint: poolState.tokenBMint,
  amountIn: new BN(100_000_000),
  minimumAmountOut: quote.minSwapOutAmount,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAProgram: TOKEN_PROGRAM_ID,
  tokenBProgram: TOKEN_PROGRAM_ID,
});

Notes

  • Get a quote first using getQuote to determine the minimumAmountOut
  • The SDK handles wrapping/unwrapping of SOL automatically
  • Token accounts are created automatically if they don't exist
  • The transaction will fail if the output amount would be less than minimumAmountOut
  • Optional referral tokenAccount will receive a portion of fees if the pool is configured for referrals

swap2

Executes a token swap in the pool depending on the swap mode. There are 3 swap modes: ExactIn, ExactOut, PartialFill.

Function

async swap2(params: Swap2Params): TxBuilder

Parameters

interface SwapParams {
  payer: PublicKey; // The wallet paying for the transaction
  pool: PublicKey; // Address of the pool to swap in
  inputTokenMint: PublicKey; // Mint of the input token
  outputTokenMint: PublicKey; // Mint of the output token
  tokenAVault: PublicKey; // Pool's token A vault
  tokenBVault: PublicKey; // Pool's token B vault
  tokenAMint: PublicKey; // Pool's token A mint
  tokenBMint: PublicKey; // Pool's token B mint
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  receiver?: PublicKey; // Optional receiver of the input and output tokens
  referralTokenAccount?: PublicKey; // Optional referral account for fees
  poolState?: PoolState; // Optional pool state to pass in to atomically fetch the pool state
  swapMode: SwapMode; // The swap mode
  amountIn?: BN; // The amount of input token to swap (for ExactIn and PartialFill modes)
  amountOut?: BN; // The amount of output token to swap (for ExactOut mode)
  minimumAmountOut?: BN; // Minimum amount of output token (slippage protection) for ExactIn and PartialFill modes
  maximumAmountIn?: BN; // Maximum amount of input token (slippage protection) for ExactOut mode
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const currentPoint = await getCurrentPoint(
  connection,
  poolState.activationType
);
// Get quote first
const quote = await cpAmm.getQuote2({
  inputTokenMint: poolState.tokenBMint,
  slippage: 0.5,
  currentPoint,
  poolState,
  tokenADecimal: 6,
  tokenBDecimal: 9,
  hasReferral: false,
  swapMode: SwapMode.PartialFill,
  amountIn: new BN(1_000_000_000),
});

// Execute swap
const swap2Tx = await cpAmm.swap2({
  payer: wallet.publicKey,
  pool: poolAddress,
  inputTokenMint: poolState.tokenAMint,
  outputTokenMint: poolState.tokenBMint,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAProgram: TOKEN_PROGRAM_ID,
  tokenBProgram: TOKEN_PROGRAM_ID,
  referralTokenAccount: null,
  swapMode: SwapMode.PartialFill,
  amountIn: new BN(1_000_000_000),
  minimumAmountOut: quote.minimumAmountOut,
});

Notes

  • Get a quote first using getQuote2 to determine the minimumAmountOut or maximumAmountIn depending on the swap mode
  • The SDK handles wrapping/unwrapping of SOL automatically
  • Token accounts are created automatically if they don't exist
  • The transaction will fail if the output amount would be less than minimumAmountOut or the input amount would be greater than maximumAmountIn depending on the swap mode
  • Optional referral tokenAccount will receive a portion of fees if the pool is configured for referrals

addLiquidity

Adds liquidity to an existing position.

Function

async addLiquidity(params: AddLiquidityParams): TxBuilder

Parameters

interface AddLiquidityParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The ata account of position nft
  liquidityDelta: BN; // The amount of liquidity to add in Q64 format
  maxAmountTokenA: BN; // Maximum amount of token A to use
  maxAmountTokenB: BN; // Maximum amount of token B to use
  tokenAAmountThreshold: BN; // Minimum acceptable token A amount (slippage protection)
  tokenBAmountThreshold: BN; // Minimum acceptable token B amount (slippage protection)
  tokenAMint: PublicKey; // The mint of token A
  tokenBMint: PublicKey; // The mint of token B
  tokenAVault: PublicKey; // The pool's token A vault
  tokenBVault: PublicKey; // The pool's token B vault
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

// Get deposit quote
const depositQuote = await cpAmm.getDepositQuote({
  inAmount: new BN(1_000_000_000), // 1,000 USDC
  isTokenA: true,
  minSqrtPrice: poolState.sqrtMinPrice,
  maxSqrtPrice: poolState.sqrtMaxPrice,
  sqrtPrice: poolState.sqrtPrice,
});

// Add liquidity
const addLiquidityTx = await cpAmm.addLiquidity({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  liquidityDelta: depositQuote.liquidityDelta,
  maxAmountTokenA: new BN(1_000_000_000),
  maxAmountTokenB: depositQuote.outputAmount,
  tokenAAmountThreshold: maxAmountTokenA,
  tokenBAmountThreshold: maxAmountTokenB,
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAProgram,
  tokenBProgram,
});

Notes

  • Calculate the liquidity delta first using getDepositQuote
  • The SDK handles wrapping/unwrapping of SOL automatically
  • Token accounts are created automatically if they don't exist
  • Set appropriate thresholds to protect against slippage

removeLiquidity

Removes a specific amount of liquidity from an existing position.

Function

async removeLiquidity(params: RemoveLiquidityParams): TxBuilder

Parameters

interface RemoveLiquidityParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftAccount?: PublicKey; // The position NFT account
  liquidityDelta: BN; // The amount of liquidity to remove in Q64 format
  tokenAAmountThreshold: BN; // Minimum acceptable token A amount (slippage protection)
  tokenBAmountThreshold: BN; // Minimum acceptable token B amount (slippage protection)
  tokenAMint: PublicKey; // The mint of token A
  tokenBMint: PublicKey; // The mint of token B
  tokenAVault: PublicKey; // The pool's token A vault
  tokenBVault: PublicKey; // The pool's token B vault
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  vestings?: Array<{ account: PublicKey }>; // Optional vesting accounts to refresh
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

// Get withdraw quote for half of the liquidity
const liquidityToRemove = positionState.unlockedLiquidity.div(new BN(2));
const withdrawQuote = await cpAmm.getWithdrawQuote({
  liquidityDelta: liquidityToRemove,
  sqrtPrice: poolState.sqrtPrice,
  minSqrtPrice: poolState.sqrtMinPrice,
  maxSqrtPrice: poolState.sqrtMaxPrice,
});

const removeLiquidityTx = await cpAmm.removeLiquidity({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  liquidityDelta: liquidityToRemove,
  tokenAAmountThreshold: new BN(0),
  tokenBAmountThreshold: new BN(0),
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAProgram,
  tokenBProgram,
});

Notes

  • You can only remove unlocked liquidity
  • The SDK handles wrapping/unwrapping of SOL automatically
  • Token accounts are created automatically if they don't exist
  • Set appropriate thresholds to protect against slippage
  • Removing all liquidity doesn't close the position

removeAllLiquidity

Removes all available liquidity from a position.

Function

async removeAllLiquidity(params: RemoveAllLiquidityParams): TxBuilder

Parameters

interface RemoveAllLiquidityParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The ata account of position nft
  tokenAAmountThreshold: BN; // Minimum acceptable token A amount (slippage protection)
  tokenBAmountThreshold: BN; // Minimum acceptable token B amount (slippage protection)
  tokenAMint: PublicKey; // The mint of token A
  tokenBMint: PublicKey; // The mint of token B
  tokenAVault: PublicKey; // The pool's token A vault
  tokenBVault: PublicKey; // The pool's token B vault
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  vestings?: Array<{ account: PublicKey }>; // Optional vesting accounts to refresh if position has vesting lock
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

const removeAllLiquidityTx = await cpAmm.removeAllLiquidity({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  tokenAAmountThreshold: new BN(0),
  tokenBAmountThreshold: new BN(0),
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAProgram,
  tokenBProgram,
});

Notes

  • This removes all unlocked liquidity in one transaction
  • The position remains open after removing all liquidity
  • You can't remove locked liquidity (use refreshVesting first if needed)
  • The SDK handles wrapping/unwrapping of SOL automatically

removeAllLiquidityAndClosePosition

Removes all liquidity from a position and closes it in a single transaction.

Function

async removeAllLiquidityAndClosePosition(params: RemoveAllLiquidityAndClosePositionParams): TxBuilder

Parameters

interface RemoveAllLiquidityAndClosePositionParams {
  owner: PublicKey; // The owner of the position
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  positionState: PositionState; // The current position state
  poolState: PoolState; // The current pool state
  tokenAAmountThreshold: BN; // Minimum acceptable token A amount (slippage protection)
  tokenBAmountThreshold: BN; // Minimum acceptable token B amount (slippage protection)
  currentPoint: BN; // Current timestamp or slot number for vesting calculations
  vestings?: Array<{ account: PublicKey; vestingState: VestingState }>; // Optional vesting accounts
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

// Check if position is locked
if (cpAmm.isLockedPosition(positionState)) {
  console.error("Cannot close a locked position");
  return;
}

// Build transaction to remove all liquidity and close position
const tx = await cpAmm.removeAllLiquidityAndClosePosition({
  owner: wallet.publicKey,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  positionState: positionState,
  poolState: poolState,
  tokenAAmountThreshold: new BN(0),
  tokenBAmountThreshold: new BN(0),
});

Notes

  • This combines multiple operations in a single transaction:
    1. Claims any accumulated fees
    2. Removes all liquidity
    3. Closes the position and returns the rent
  • The position must be completely unlocked
  • The function will throw an error if the position has any locked liquidity
  • This is more gas-efficient than doing these operations separately
  • If there are vesting schedules, they must be refreshed before closing the position

mergePosition

Merges liquidity from one position into another in a single transaction.

Function

async mergePosition(params: MergePositionParams): TxBuilder

Parameters

interface MergePositionParams {
  owner: PublicKey; // The owner of both positions
  positionA: PublicKey; // Target position to merge into
  positionB: PublicKey; // Source position to merge from
  positionBState: PositionState; // State of the source position
  poolState: PoolState; // State of the pool
  positionANftAccount: PublicKey; // ata account of target position NFT
  positionBNftAccount: PublicKey; // ata account of source position NFT
  tokenAAmountAddLiquidityThreshold: BN; // Minimum token A amount for add liquidity
  tokenBAmountAddLiquidityThreshold: BN; // Minimum token B amount for add liquidity
  tokenAAmountRemoveLiquidityThreshold: BN; // Minimum token A amount for remove liquidity
  tokenBAmountRemoveLiquidityThreshold: BN; // Minimum token B amount for remove liquidity
  currentPoint: BN; // Current timestamp or slot number for vesting calculations
  positionBVestings?: Array<{ account: PublicKey; vestingState: VestingState }>; // Optional vesting accounts for position B
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionAState = await cpAmm.fetchPositionState(positionAAddress); // Target position
const positionBState = await cpAmm.fetchPositionState(positionBAddress); // Source position to merge from

// Check if position is locked
if (cpAmm.isLockedPosition(positionBState)) {
  console.error("Cannot merge a locked position");
  return;
}

// Build transaction to merge positions
const tx = await cpAmm.mergePosition({
  owner: wallet.publicKey,
  positionA: positionAAddress,
  positionB: positionBAddress,
  positionBState: positionBState,
  poolState: poolState,
  positionANftAccount: positionANftAccount,
  positionBNftAccount: positionBNftAccount,
  tokenAAmountAddLiquidityThreshold: new BN(U64_MAX),
  tokenBAmountAddLiquidityThreshold: new BN(u64_MAX),
  tokenAAmountRemoveLiquidityThreshold: new BN(0),
  tokenBAmountRemoveLiquidityThreshold: new BN(0),
});

Notes

  • This function combines multiple operations:
    1. Claims any accumulated fees from the source position
    2. Removes all liquidity from the source position
    3. Adds the liquidity to the target position
    4. Closes the source position
  • Both positions must be owned by the same wallet
  • The source position must be completely unlocked
  • This is more gas-efficient than performing these operations separately
  • Set appropriate thresholds to protect against slippage for both add and remove operations

lockPosition

Builds a transaction to lock a position with vesting schedule.

Function

async lockPosition(params: LockPositionParams): TxBuilder

Parameters

interface LockPositionParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  payer: PublicKey; // The wallet paying for the transaction
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  cliffPoint: BN | null; // The cliff point (slot or timestamp)
  periodFrequency: BN; // How often liquidity unlocks
  cliffUnlockLiquidity: BN; // Amount to unlock at cliff
  liquidityPerPeriod: BN; // Amount to unlock per period
  numberOfPeriod: number; // Number of vesting periods
  vestingAccount?: PublicKey; // The vesting account to create (required for when innerPosition is not provided or false)
  innerPosition?: boolean; // Whether the position is an inner position (required to be true for when vestingAccount is not provided)
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

With vesting account:

const vestingAccount = Keypair.generate();

const lockPositionTx = await cpAmm.lockPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  payer: wallet.publicKey,
  vestingAccount: vestingAccount.publicKey,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  cliffPoint: new BN(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days cliff
  periodFrequency: new BN(24 * 60 * 60 * 1000), // 1 day periods
  cliffUnlockLiquidity: new BN(0), // No initial unlock
  liquidityPerPeriod: positionState.unlockedLiquidity.div(new BN(30)), // Unlock over 30 days
  numberOfPeriod: 30, // 30 periods
});

Without vesting account:

const lockPositionTx = await cpAmm.lockPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  payer: wallet.publicKey,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  cliffPoint: new BN(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days cliff
  periodFrequency: new BN(24 * 60 * 60 * 1000), // 1 day periods
  cliffUnlockLiquidity: new BN(0), // No initial unlock
  liquidityPerPeriod: positionState.unlockedLiquidity.div(new BN(30)), // Unlock over 30 days
  numberOfPeriod: 30, // 30 periods
  innerPosition: true,
});

Notes

  • Locking positions is useful for creating various incentive mechanisms
  • The vesting schedule controls how quickly liquidity unlocks over time
  • Locked liquidity cannot be withdrawn until it becomes unlocked
  • The vesting account is a new account that must be created
  • The function only locks currently unlocked liquidity

permanentLockPosition

Permanently locks a portion of liquidity in a position.

Function

async permanentLockPosition(params: PermanentLockParams): TxBuilder

Parameters

interface PermanentLockParams {
  owner: PublicKey; // The owner of the position
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  pool: PublicKey; // The pool address
  unlockedLiquidity: BN; // Amount of liquidity to permanently lock
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const positionState = await cpAmm.fetchPositionState(positionAddress);

// Permanently lock half of the unlocked liquidity
const liquidityToLock = positionState.unlockedLiquidity.div(new BN(2));

const lockTx = await cpAmm.permanentLockPosition({
  owner: wallet.publicKey,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  pool: poolAddress,
  unlockedLiquidity: liquidityToLock,
});

Notes

  • Permanently locked liquidity can never be withdrawn
  • This is useful for deep liquidity protocols or governance mechanisms
  • Once liquidity is permanently locked, this action cannot be reversed
  • The owner can still collect fees from permanently locked liquidity

refreshVesting

Refreshes vesting status of a position to unlock available liquidity.

Function

async refreshVesting(params: RefreshVestingParams): TxBuilder

Parameters

interface RefreshVestingParams {
  owner: PublicKey; // The owner of the position
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  pool: PublicKey; // The pool address
  vestingAccounts: PublicKey[]; // Array of vesting accounts to refresh
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

// Get all vesting accounts for the position
const vestings = await cpAmm.getAllVestingsByPosition(positionAddress);

const refreshVestingTx = await cpAmm.refreshVesting({
  owner: wallet.publicKey,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  pool: poolAddress,
  vestingAccounts: vestings.map((v) => v.publicKey),
});

Notes

  • Call this function to update the vesting state and unlock available liquidity
  • Should be called periodically to ensure liquidity is properly unlocked
  • If all liquidity is unlocked, the vesting account remains but is no longer used
  • Must be called before removing liquidity if position has vesting accounts

claimPositionFee

Claims accumulated fees for a position.

Function

async claimPositionFee(params: ClaimPositionFeeParams): TxBuilder

Parameters

interface ClaimPositionFeeParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  tokenAVault: PublicKey; // The pool's token A vault
  tokenBVault: PublicKey; // The pool's token B vault
  tokenAMint: PublicKey; // The mint of token A
  tokenBMint: PublicKey; // The mint of token B
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  receiver?: Pubkey; // the wallet that will receive the fees (optional)
  tempWSolAccount?: Pubkey; // the temporary wallet that will receive the fees (optional)
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);

const claimFeeTx = await cpAmm.claimPositionFee({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  positionNftAccount: positionNftAccount,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAProgram,
  tokenBProgram,
});

Notes

  • Fees are collected when trades occur in the pool
  • Only the position owner can claim fees
  • Fees are earned on both token A and token B based on the amount of liquidity provided
  • Fees accumulate over time and should be claimed periodically
  • The SDK handles wrapping/unwrapping of SOL automatically

claimPositionFee2

Claims accumulated fees for a position.

Function

async claimPositionFee2(params: ClaimPositionFeeParams2): TxBuilder

Parameters

interface ClaimPositionFeeParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftAccount: PublicKey; // The position NFT account
  tokenAVault: PublicKey; // The pool's token A vault
  tokenBVault: PublicKey; // The pool's token B vault
  tokenAMint: PublicKey; // The mint of token A
  tokenBMint: PublicKey; // The mint of token B
  tokenAProgram: PublicKey; // Token program for token A
  tokenBProgram: PublicKey; // Token program for token B
  receiver: Pubkey; //  The wallet that will receive the fees
  feePayer?: PublicKey; // Specific fee payer for transaction. Default fee payer is position's owner
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);

const claimFeeTx = await cpAmm.claimPositionFee2({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  receiver: receiverAddress,
  positionNftAccount: positionNftAccount,
  tokenAVault: poolState.tokenAVault,
  tokenBVault: poolState.tokenBVault,
  tokenAMint: poolState.tokenAMint,
  tokenBMint: poolState.tokenBMint,
  tokenAProgram,
  tokenBProgram,
});

Notes

  • Fees are collected when trades occur in the pool
  • Only the position owner can claim fees
  • Fees will claim to receiver address
  • Fees are earned on both token A and token B based on the amount of liquidity provided
  • The SDK handles wrapping/unwrapping of SOL automatically

claimPartnerFee

Claims partner fee rewards. (Deprecating soon)

Function

async claimPartnerFee(params: ClaimPartnerFeeParams): TxBuilder

Parameters

interface ClaimPartnerFeeParams {
  partner: PublicKey; // Partner address to receive fees
  pool: PublicKey; // The pool address
  maxAmountA: BN; // Maximum amount of token A to claim
  maxAmountB: BN; // Maximum amount of token B to claim
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);

const claimPartnerFeeTx = await cpAmm.claimPartnerFee({
  partner: partnerWallet.publicKey,
  pool: poolAddress,
  maxAmountA: new BN(1_000_000_000), // 1,000 USDC
  maxAmountB: new BN(5_000_000_000), // 5 SOL
});

Notes

  • Partner fees are a portion of trading fees directed to a specific account
  • Only the configured partner address can claim these fees
  • Partner fees must be enabled in the pool configuration
  • The SDK handles wrapping/unwrapping of SOL automatically
  • Token accounts are created automatically if they don't exist

initializeReward

Initializes a reward for a pool.

Function

async initializeReward(params: InitializeRewardParams): TxBuilder

Parameters

interface InitializeRewardParams {
  rewardIndex: number; // 0: for creators or admins, 1: for admins only
  rewardDuration: BN; // Duration of the reward
  pool: PublicKey; // The pool address
  rewardMint: PublicKey; // The reward mint address
  funder: PublicKey; // The
  payer: PublicKey; // The payer address
  creator: PublicKey; // The creator address
  rewardMintProgram: PublicKey; // The reward mint program address
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const initializeRewardTx = await cpAmm.initializeReward({
  rewardIndex: 0,
  rewardDuration: new BN(1000000000),
  pool: poolAddress,
  rewardMint: rewardMintAddress,
  funder: wallet.publicKey,
  payer: wallet.publicKey,
  creator: wallet.publicKey,
  rewardMintProgram: rewardMintProgramAddress,
});

Notes

  • Only the pool creator can initialize a reward
  • The funder is the account that will fund the reward
  • The payer is the account that will pay for the initialize reward transaction
  • The creator is the account that is the creator of the pool
  • The reward mint program is the program that will mint the reward
  • Pool creators can only initialize rewards for rewardIndex = 0. rewardIndex = 1 is a permissioned reward initialization for admins only.

initializeAndFundReward

Initializes and funds a reward for a pool.

Function

async initializeAndFundReward(params: InitializeAndFundReward): TxBuilder

Parameters

interface InitializeAndFundRewardParams {
  rewardIndex: number; // 0: for creators or admins, 1: for admins only
  rewardDuration: BN; // Duration of the reward
  pool: PublicKey; // The pool address
  creator: PublicKey; // The creator address
  payer: PublicKey; // The payer address
  rewardMint: PublicKey; // The reward mint address
  carryForward: boolean; // Whether to carry forward the reward
  amount: BN; // The amount to fund
  rewardMintProgram: PublicKey; // The reward mint program address
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const initializeAndFundRewardTx = await cpAmm.initializeAndFundReward({
  rewardIndex: 0,
  rewardDuration: new BN(1000000000),
  pool: poolAddress,
  creator: wallet.publicKey,
  payer: wallet.publicKey,
  rewardMint: rewardMintAddress,
  carryForward: true,
  amount: new BN(1000000000),
  rewardMintProgram: rewardMintProgramAddress,
});

Notes

  • Only the pool creator can initialize a reward
  • The creator in this case is also the funder of the reward
  • The payer is the account that will pay for the initialize reward transaction
  • The reward mint program is the program that will mint the reward
  • Pool creators can only initialize rewards for rewardIndex = 0. rewardIndex = 1 is a permissioned reward initialization for admins only.
  • The carryForward parameter specifies whether to carry forward the reward

updateRewardDuration

Updates the duration of a reward.

Function

async updateRewardDuration(params: UpdateRewardDurationParams): TxBuilder

Parameters

interface UpdateRewardDurationParams {
  pool: PublicKey; // The pool address
  signer: PublicKey; // The signer of the transaction
  rewardIndex: number; // Index of the reward to update
  newDuration: BN; // New duration of the reward
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const updateRewardDurationTx = await cpAmm.updateRewardDuration({
  pool: poolAddress,
  signer: wallet.publicKey,
  rewardIndex: 0,
  newDuration: new BN(1000000000),
});

Notes

  • Only the pool creator or admin can update the duration of a reward
  • The new duration must be greater than the current duration
  • The signer must be the pool creator or admin depending on the rewardIndex

updateRewardFunder

Updates the funder of a reward.

Function

async updateRewardFunder(params: UpdateRewardFunderParams): TxBuilder

Parameters

interface UpdateRewardFunderParams {
  pool: PublicKey; // The pool address
  signer: PublicKey; // The signer of the transaction
  rewardIndex: number; // Index of the reward to update
  newFunder: PublicKey; // The new funder of the reward
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const updateRewardFunderTx = await cpAmm.updateRewardFunder({
  pool: poolAddress,
  signer: wallet.publicKey,
  rewardIndex: 0,
  newFunder: newFunderAddress,
});

Notes

  • Only the pool creator can update the funder of a reward
  • The new funder must be a valid public key
  • The signer must be the pool creator or admin depending on the rewardIndex

fundReward

Funds a reward for a pool.

Function

async fundReward(params: FundRewardParams): TxBuilder

Parameters

interface FundRewardParams {
  funder: PublicKey; // The funder address
  rewardIndex: number; // Index of the reward to fund
  pool: PublicKey; // The pool address
  carryForward: boolean; // Whether to carry forward the reward
  amount: BN; // The amount to fund
  rewardMint: PublicKey; // The reward token mint address
  rewardVault: PublicKey; // The reward vault address
  rewardMintProgram: PublicKey; // The reward mint's program id
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const fundRewardTx = await cpAmm.fundReward({
  funder: wallet.publicKey,
  rewardIndex: 0,
  pool: poolAddress,
  carryForward: true,
  amount: new BN(1000000000),
  rewardMint: rewardMintAddress,
  rewardVault: rewardVaultAddress,
  rewardMintProgram: rewardMintProgramAddress,
});

Notes

  • Only the pool creator can fund rewards
  • The rewardIndex parameter specifies which reward token to fund
  • The carryForward parameter specifies whether to carry forward the reward
  • The amount parameter specifies the amount to fund

claimReward

Claims reward tokens from a position.

Function

async claimReward(params: ClaimRewardParams): TxBuilder

Parameters

interface ClaimRewardParams {
  user: PublicKey; // The user claiming rewards
  position: PublicKey; // The position address
  poolState: PoolState; // The current pool state
  positionState: PositionState; // The current position state
  positionNftAccount: PublicKey; // The position NFT account
  rewardIndex: number; // Index of the reward to claim
  isSkipReward: boolean; // Whether to skip reward transfer
  feePayer?: PublicKey; // Specific fee payer for transaction. Default fee payer is user
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

// Claim reward at index 0
const claimRewardTx = await cpAmm.claimReward({
  user: wallet.publicKey,
  position: positionAddress,
  poolState: poolState,
  positionState: positionState,
  positionNftAccount: positionNftAccount,
  rewardIndex: 0,
  isSkipReward: false,
  feePayer: wallet.publicKey,
});

Notes

  • Pools can have multiple reward tokens configured
  • The rewardIndex parameter specifies which reward token to claim
  • Rewards accrue based on the amount of liquidity provided and duration
  • Only the position owner can claim rewards
  • The SDK handles wrapping/unwrapping of SOL automatically

withdrawIneligibleReward

Withdraws ineligible reward tokens from a pool.

Function

async withdrawIneligibleReward(params: WithdrawIneligibleRewardParams): TxBuilder

Parameters

interface WithdrawIneligibleRewardParams {
  rewardIndex: number; // Index of the reward to withdraw
  pool: PublicKey; // The pool address
  funder: PublicKey; // The funder address to withdraw to
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const withdrawIneligibleRewardTx = await cpAmm.withdrawIneligibleReward({
  rewardIndex: 0,
  pool: poolAddress,
  funder: wallet.publicKey,
});

Notes

  • Only the pool creator can withdraw ineligible rewards
  • The rewardIndex parameter specifies which reward token to withdraw
  • The funder parameter specifies the address to withdraw to

closePosition

Closes a position with no liquidity.

Function

async closePosition(params: ClosePositionParams): TxBuilder

Parameters

interface ClosePositionParams {
  owner: PublicKey; // The owner of the position
  pool: PublicKey; // The pool address
  position: PublicKey; // The position address
  positionNftMint: PublicKey; // The position NFT mint
  positionNftAccount: PublicKey; // The position NFT account
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const positionState = await cpAmm.fetchPositionState(positionAddress);

// Check if position has no liquidity
if (
  !positionState.unlockedLiquidity.isZero() ||
  !positionState.vestedLiquidity.isZero() ||
  !positionState.permanentLockedLiquidity.isZero()
) {
  console.error("Position still has liquidity");
  return;
}

const closePositionTx = await cpAmm.closePosition({
  owner: wallet.publicKey,
  pool: positionState.pool,
  position: positionAddress,
  positionNftMint: positionState.nftMint,
  positionNftAccount: positionNftAccount,
});

Notes

  • Position must have zero liquidity before closing
  • Use removeAllLiquidity first if the position still has liquidity
  • Closing a position returns the rent to the owner
  • This function only closes the position account, not the NFT
  • For a full cleanup, use removeAllLiquidityAndClosePosition instead

splitPosition

Splits a position into two positions.

Function

async splitPosition(params: SplitPositionParams): TxBuilder

Parameters

interface SplitPositionParams {
  firstPositionOwner: PublicKey; // The owner of the first position
  secondPositionOwner: PublicKey; // The owner of the second position
  pool: PublicKey; // The pool address
  firstPosition: PublicKey; // The first position address
  firstPositionNftAccount: PublicKey; // The first position NFT account
  secondPosition: PublicKey; // The second position address
  secondPositionNftAccount: PublicKey; // The second position NFT account
  unlockedLiquidityPercentage: number; // The percentage of unlocked liquidity to split
  permanentLockedLiquidityPercentage: number; // The percentage of permanent locked liquidity to split
  feeAPercentage: number; // The percentage of fee A to split
  feeBPercentage: number; // The percentage of fee B to split
  reward0Percentage: number; // The percentage of reward 0 to split
  reward1Percentage: number; // The percentage of reward 1 to split
  innerVestingLiquidityPercentage: number; // The percentage of inner vesting liquidity to split
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const firstPosition = await client.getUserPositionByPool(
  poolAddress,
  firstUser.publicKey
);

const secondPositionKP = Keypair.generate();

const createSecondPositionTx = await client.createPosition({
  owner: secondUser.publicKey,
  payer: secondUser.publicKey,
  pool: poolAddress,
  positionNft: secondPositionKP.publicKey,
});

const createSignature = await sendAndConfirmTransaction(
  connection,
  createSecondPositionTx,
  [secondUser, secondPositionKP],
  {
    commitment: "confirmed",
    skipPreflight: true,
  }
);
console.log("Second position created:", createSignature);

const secondPosition = await client.getUserPositionByPool(
  poolAddress,
  secondUser.publicKey
);

const splitPositionTx = await client.splitPosition({
  firstPositionOwner: firstUser.publicKey,
  secondPositionOwner: secondUser.publicKey,
  pool: poolAddress,
  firstPosition: firstPosition[0].position,
  firstPositionNftAccount: firstPosition[0].positionNftAccount,
  secondPosition: secondPosition[0].position,
  secondPositionNftAccount: secondPosition[0].positionNftAccount,
  unlockedLiquidityPercentage: 50,
  permanentLockedLiquidityPercentage: 0,
  feeAPercentage: 50,
  feeBPercentage: 50,
  reward0Percentage: 50,
  reward1Percentage: 50,
  innerVestingLiquidityPercentage: 50,
});

Notes

  • The first position must already exist for that pool
  • The second position can be a new empty position for that same pool

splitPosition2

Splits a position into two positions via numerator.

Function

async splitPosition2(params: SplitPosition2Params): TxBuilder

Parameters

interface SplitPosition2Params {
  firstPositionOwner: PublicKey; // The owner of the first position
  secondPositionOwner: PublicKey; // The owner of the second position
  pool: PublicKey; // The pool address
  firstPosition: PublicKey; // The first position address
  firstPositionNftAccount: PublicKey; // The first position NFT account
  secondPosition: PublicKey; // The second position address
  secondPositionNftAccount: PublicKey; // The second position NFT account
  numerator: number; // The numerator to split the position by, which is a percentage of the position
}

Returns

A transaction builder (TxBuilder) that can be used to build, sign, and send the transaction.

Example

const firstPosition = await client.getUserPositionByPool(
  poolAddress,
  firstUser.publicKey
);

const secondPositionKP = Keypair.generate();

const createSecondPositionTx = await client.createPosition({
  owner: secondUser.publicKey,
  payer: secondUser.publicKey,
  pool: poolAddress,
  positionNft: secondPositionKP.publicKey,
});

const createSignature = await sendAndConfirmTransaction(
  connection,
  createSecondPositionTx,
  [secondUser, secondPositionKP],
  {
    commitment: "confirmed",
    skipPreflight: true,
  }
);
console.log("Second position created:", createSignature);

const secondPosition = await client.getUserPositionByPool(
  poolAddress,
  secondUser.publicKey
);

const splitPosition2Tx = await client.splitPosition2({
  firstPositionOwner: firstUser.publicKey,
  secondPositionOwner: secondUser.publicKey,
  pool: poolAddress,
  firstPosition: firstPosition[0].position,
  firstPositionNftAccount: firstPosition[0].positionNftAccount,
  secondPosition: secondPosition[0].position,
  secondPositionNftAccount: secondPosition[0].positionNftAccount,
  numerator: SPLIT_POSITION_DENOMINATOR / 2,
});

Notes

  • The first position must already exist for that pool
  • The second position can be a new empty position for that same pool

State Functions

fetchConfigState

Fetches the Config state of the program.

Function

async fetchConfigState(config: PublicKey): Promise<ConfigState>

Parameters

  • config: Public key of the config account.

Returns

Parsed ConfigState.

Example

const configState = await cpAmm.fetchConfigState(configAddress);
console.log(configState);

Notes

  • Throws an error if the config account does not exist

fetchPoolState

Fetches the Pool state.

Function

async fetchPoolState(pool: PublicKey): Promise<PoolState>

Parameters

  • pool: Public key of the pool.

Returns

Parsed PoolState.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
console.log(`Current Price: ${poolState.sqrtPrice.toString()}`);
console.log(`Liquidity: ${poolState.liquidity.toString()}`);

Notes

  • Throws an error if the pool account does not exist
  • Contains all essential information about the pool including prices, liquidity, and fees

fetchPoolStatesByTokenAMint

Fetches all Pool states by tokenAMint.

Function

async fetchPoolStatesByTokenAMint(tokenAMint: PublicKey): Promise<Array<{ publicKey: PublicKey; account: PoolState }>>

Parameters

  • tokenAMint: Public key of the tokenA mint.

Returns

Array of matched pool accounts and their state.

Example

const poolStates = await cpAmm.fetchPoolStatesByTokenAMint(tokenAMint);
console.log(`Found ${poolStates.length} pools`);
poolStates.forEach((pool, i) => {
  console.log(`Pool ${i}: ${pool.publicKey.toString()}`);
  console.log(`- Pool State: ${JSON.stringify(pool.account)}`);
});

Notes

  • Returns an empty array if no pools are found for the given tokenAMint
  • Contains all essential information about the pool including pool address, prices, liquidity, and fees

fetchPositionState

Fetches the Position state.

Function

async fetchPositionState(position: PublicKey): Promise<PositionState>

Parameters

  • position: Public key of the position.

Returns

Parsed PositionState.

Example

const positionState = await cpAmm.fetchPositionState(positionAddress);
console.log(
  `Unlocked Liquidity: ${positionState.unlockedLiquidity.toString()}`
);
console.log(`Vested Liquidity: ${positionState.vestedLiquidity.toString()}`);
console.log(
  `Permanent Locked Liquidity: ${positionState.permanentLockedLiquidity.toString()}`
);

Notes

  • Throws an error if the position account does not exist
  • Contains information about liquidity amounts, fee collection, and rewards

getAllConfigs

Retrieves all config accounts.

Function

async getAllConfigs(): Promise<Array<{ publicKey: PublicKey; account: ConfigState }>>

Returns

Array of config public keys and their states.

Example

const configs = await cpAmm.getAllConfigs();
console.log(`Found ${configs.length} configs`);
configs.forEach((config, i) => {
  console.log(`Config ${i}: ${config.publicKey.toString()}`);
});

getAllPools

Retrieves all pool accounts.

Function

async getAllPools(): Promise<Array<{ publicKey: PublicKey; account: PoolState }>>

Returns

Array of pool public keys and their states.

Example

const pools = await cpAmm.getAllPools();
console.log(`Found ${pools.length} pools`);
pools.forEach((pool, i) => {
  console.log(`Pool ${i}: ${pool.publicKey.toString()}`);
  console.log(`- Token A: ${pool.account.tokenAMint.toString()}`);
  console.log(`- Token B: ${pool.account.tokenBMint.toString()}`);
});

getAllPositions

Retrieves all position accounts.

Function

async getAllPositions(): Promise<Array<{ publicKey: PublicKey; account: PositionState }>>

Returns

Array of position public keys and their states.

Example

const positions = await cpAmm.getAllPositions();
console.log(`Found ${positions.length} positions`);

getAllPositionsByPool

Gets all positions for a specific pool.

Function

async getAllPositionsByPool(pool: PublicKey): Promise<Array<{ publicKey: PublicKey; account: PositionState }>>

Parameters

  • pool: Public key of the pool.

Returns

List of positions for the pool.

Example

const poolPositions = await cpAmm.getAllPositionsByPool(poolAddress);
console.log(`Pool has ${poolPositions.length} positions`);

getUserPositionByPool

Gets all positions of a user for a specific pool.

Function

async getUserPositionByPool(pool: PublicKey, user: PublicKey): Promise<Array<{ positionNftAccount: PublicKey; position: PublicKey; positionState: PositionState }>>

Parameters

  • pool: Public key of the pool.
  • user: Public key of the user.

Returns

List of user positions for the pool.

Example

const userPoolPositions = await cpAmm.getUserPositionByPool(
  poolAddress,
  wallet.publicKey
);
console.log(`User has ${userPoolPositions.length} positions in this pool`);

getPositionsByUser

Gets all positions of a user across all pools.

Function

async getPositionsByUser(user: PublicKey): Promise<Array<{ positionNftAccount: PublicKey; position: PublicKey; positionState: PositionState }>>

Parameters

  • user: Public key of the user.

Returns

Array of user positions already sorted by liquidity.

Example

const userPositions = await cpAmm.getPositionsByUser(wallet.publicKey);
console.log(`User has ${userPositions.length} total positions`);

Notes

  • Positions are sorted by total liquidity in descending order
  • Returns position NFT accounts, position addresses, and full position states

getAllVestingsByPosition

Retrieves all vesting accounts associated with a position.

Function

async getAllVestingsByPosition(position: PublicKey): Promise<Array<{ publicKey: PublicKey; account: VestingState }>>

Parameters

  • position: Public key of the position.

Returns

Array of vesting account public keys and their states.

Example

const vestings = await cpAmm.getAllVestingsByPosition(positionAddress);
console.log(`Position has ${vestings.length} vesting accounts`);

isLockedPosition

Checks if a position has any locked liquidity.

Function

isLockedPosition(position: PositionState): boolean

Parameters

  • position: The position state.

Returns

Boolean indicating whether the position has locked liquidity.

Example

const positionState = await cpAmm.fetchPositionState(positionAddress);
if (cpAmm.isLockedPosition(positionState)) {
  console.log("Position has locked liquidity");
} else {
  console.log("Position has no locked liquidity");
}

isPoolExist

Checks if a pool exists.

Function

async isPoolExist(pool: PublicKey): Promise<boolean>

Parameters

  • pool: Public key of the pool.

Returns

Boolean indicating whether the pool exists.

Example

const exists = await cpAmm.isPoolExist(poolAddress);
if (exists) {
  console.log("Pool exists");
} else {
  console.log("Pool does not exist");
}

Helper Functions

preparePoolCreationParams

Prepares parameters required for pool creation, including initial sqrt price and liquidity.

Function

preparePoolCreationParams(params: PreparePoolCreationParams): PreparedPoolCreation

Parameters

interface PreparePoolCreationParams {
  tokenAAmount: BN; // Initial amount of token A to deposit
  tokenBAmount: BN; // Initial amount of token B to deposit
  minSqrtPrice: BN; // Minimum sqrt price
  maxSqrtPrice: BN; // Maximum sqrt price
  tokenAInfo?: any; // Token info for Token2022 transfer fee calculations
  tokenBInfo?: any; // Token info for Token2022 transfer fee calculations
}

Returns

An object containing:

  • initSqrtPrice: The initial sqrt price in Q64 format
  • liquidityDelta: The initial liquidity in Q64 format

Example

const { initSqrtPrice, liquidityDelta } = cpAmm.preparePoolCreationParams({
  tokenAAmount: new BN(1_000_000_000), // 1,000 USDC with 6 decimals
  tokenBAmount: new BN(5_000_000_000), // 5 SOL with 9 decimals
  minSqrtPrice: MIN_SQRT_PRICE,
  maxSqrtPrice: MAX_SQRT_PRICE,
});

console.log(`Initial sqrt price: ${initSqrtPrice.toString()}`);
console.log(`Initial liquidity: ${liquidityDelta.toString()}`);

Notes

  • This function calculates the correct initial price and liquidity based on the token amounts
  • Both token amounts must be greater than zero
  • The function handles Token2022 transfer fees if token info is provided

isVestingComplete

Checks if a vesting schedule is ready for full release.

Function

function isVestingComplete(
  vestingData: VestingState,
  currentPoint: BN
): boolean;

Parameters

  • vestingData: The vesting account state data
  • currentPoint: Current timestamp or slot number

Returns

Boolean indicating whether the vesting schedule is complete and all liquidity can be released.

Example

const vestings = await cpAmm.getAllVestingsByPosition(positionAddress);
if (vestings.length > 0) {
  const isComplete = isVestingComplete(vestings[0].account, new BN(Date.now()));
  if (isComplete) {
    console.log("Vesting schedule is complete, all liquidity can be released");
  } else {
    console.log("Vesting schedule is still active");
  }
}

Notes

  • This function checks if the current point (timestamp or slot) has passed the end of the vesting schedule
  • The end point is calculated as: cliffPoint + (periodFrequency * numberOfPeriods)
  • Returns true if currentPoint >= endPoint, false otherwise
  • Useful to determine if a position can be fully unlocked

getTotalLockedLiquidity

Gets the total amount of liquidity in the vesting schedule.

Function

function getTotalLockedLiquidity(vestingData: VestingState): BN;

Parameters

  • vestingData: The vesting account state data

Returns

The total locked liquidity amount as a BN.

Example

const vestings = await cpAmm.getAllVestingsByPosition(positionAddress);
if (vestings.length > 0) {
  const totalLocked = getTotalLockedLiquidity(vestings[0].account);
  console.log(`Total locked liquidity: ${totalLocked.toString()}`);
}

Notes

  • Calculates the sum of cliff unlock liquidity and periodic unlock liquidity
  • Formula: cliffUnlockLiquidity + (liquidityPerPeriod * numberOfPeriod)
  • This is the total amount of liquidity that was initially locked in the vesting schedule
  • Does not account for already released liquidity

getAvailableVestingLiquidity

Calculates the available liquidity to withdraw based on vesting schedule.

Function

function getAvailableVestingLiquidity(
  vestingData: VestingState,
  currentPoint: BN
): BN;

Parameters

  • vestingData: The vesting account state data
  • currentPoint: Current timestamp or slot number

Returns

The amount of liquidity available to withdraw as a BN.

Example

const vestings = await cpAmm.getAllVestingsByPosition(positionAddress);
if (vestings.length > 0) {
  const availableLiquidity = getAvailableVestingLiquidity(
    vestings[0].account,
    new BN(Date.now())
  );
  console.log(
    `Available liquidity to withdraw: ${availableLiquidity.toString()}`
  );
}

getMaxAmountWithSlippage

Calculates the maximum amount after applying a slippage rate.

Function

function getMaxAmountWithSlippage(amount: BN, rate: number): BN;

Parameters

  • amount: The base amount as a BN
  • rate: The slippage rate as a percentage (e.g., 0.5 for 0.5%)

Returns

The maximum amount after applying slippage as a BN.

Example

const tokenAmount = new BN(1_000_000_000); // 1,000 tokens
const slippageRate = 0.5; // 0.5% slippage allowance
const maxAmount = getMaxAmountWithSlippage(tokenAmount, slippageRate);
console.log(`Maximum amount with slippage: ${maxAmount.toString()}`);

Notes

  • Used when you need to calculate the upper bound of an amount with slippage tolerance
  • Formula: amount * (100 + rate) / 100
  • Common use case: Setting a maximum deposit amount when adding liquidity
  • Slippage rate is expressed as a percentage and supports up to 2 decimal places

getAmountWithSlippage

Calculates the minimum amount after applying a slippage rate.

Function

function getAmountWithSlippage(
  amount: BN,
  slippageBps: number,
  swapMode: SwapMode
): BN;

Parameters

  • amount: The base amount as a BN
  • slippageBps: The slippage rate in basis points (e.g., 100 bps for 1%)
  • swapMode: The swap mode (ExactIn, PartialFill, ExactOut)

Returns

The minimum amount after applying slippage as a BN (for ExactIn/PartialFill) or maximum amount in (for ExactOut).

Example

const expectedOutput = new BN(1_000_000_000); // 1,000 tokens
const slippageBps = 50; // 0.5% slippage allowance
const amountWithSlippage = getAmountWithSlippage(
  expectedOutput,
  slippageBps,
  SwapMode.ExactIn
);
console.log(`Amount with slippage: ${amountWithSlippage.toString()}`);

Notes

  • Used when you need to calculate the lower bound of an amount with slippage tolerance
  • Formula: amount * (100 - slippageBps) / 100 (for ExactIn/PartialFill) or amount * (100 + slippageBps) / 100 (for ExactOut)
  • Common use case: Setting a minimum output amount when swapping tokens
  • Slippage rate is expressed as a percentage and supports up to 2 decimal places

getPriceImpact

Calculates the price impact as a percentage.

Function

function getPriceImpact(actualAmount: BN, idealAmount: BN): number;

Parameters

  • actualAmount: The actual amount after slippage in token units
  • idealAmount: The theoretical amount without slippage in token units

Returns

The price impact as a percentage (e.g., 1.5 means 1.5%).

Example

const idealAmount = new BN(1_000_000_000); // 1,000 tokens (theoretical)
const actualAmount = new BN(990_000_000); // 990 tokens (actual)
const impact = getPriceImpact(actualAmount, idealAmount);
console.log(`Price impact: ${impact.toFixed(2)}%`);

Notes

  • Used to express how much a transaction will affect the price
  • Formula: ((idealAmount - actualAmount) / idealAmount) * 100
  • Higher price impact indicates a greater effect on the market price
  • Common use case: Showing users the effect of their swap on the pool

Price Conversion Utilities

getPriceFromSqrtPrice

Converts a sqrt price in Q64 format to a human-readable price.

Function

function getPriceFromSqrtPrice(
  sqrtPrice: BN,
  tokenADecimal: number,
  tokenBDecimal: number
): string;

Parameters

  • sqrtPrice: The sqrt price in Q64 format
  • tokenADecimal: The number of decimals for token A
  • tokenBDecimal: The number of decimals for token B

Returns

The price as a string in human-readable format.

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const price = getPriceFromSqrtPrice(
  poolState.sqrtPrice,
  6, // USDC has 6 decimals
  9 // SOL has 9 decimals
);
console.log(`Current price: ${price} USDC per SOL`);

Notes

  • Converts the internal sqrt price representation to a human-readable price
  • Formula: (sqrtPrice >> 64)^2 * 10^(tokenADecimal - tokenBDecimal)
  • The result represents the price of token B in terms of token A
  • Useful for displaying current pool prices to users

getSqrtPriceFromPrice

Converts a human-readable price to a sqrt price in Q64 format.

Function

function getSqrtPriceFromPrice(
  price: string,
  tokenADecimal: number,
  tokenBDecimal: number
): BN;

Parameters

  • price: The price as a string in human-readable format
  • tokenADecimal: The number of decimals for token A
  • tokenBDecimal: The number of decimals for token B

Returns

The sqrt price as a BN in Q64 format.

Example

const price = "0.05"; // 0.05 USDC per SOL
const sqrtPrice = getSqrtPriceFromPrice(
  price,
  6, // USDC has 6 decimals
  9 // SOL has 9 decimals
);
console.log(`Sqrt price in Q64 format: ${sqrtPrice.toString()}`);

Notes

  • Converts a human-readable price to the internal sqrt price representation
  • Formula: sqrt(price / 10^(tokenADecimal - tokenBDecimal)) << 64
  • Useful when creating pools with a specific initial price
  • Can be used to define price boundaries for concentrated liquidity positions

Fee Calculation Utilities

getUnClaimLpFee

Calculates unclaimed fees and rewards for a position.

Function

function getUnClaimLpFee(
  poolState: PoolState,
  positionState: PositionState
): {
  feeTokenA: BN;
  feeTokenB: BN;
  rewards: BN[];
};

Parameters

  • poolState: The current state of the pool
  • positionState: The current state of the position

Returns

An object containing:

  • feeTokenA: Unclaimed fees in token A
  • feeTokenB: Unclaimed fees in token B
  • rewards: Array of unclaimed reward amounts for each reward token

Example

const poolState = await cpAmm.fetchPoolState(poolAddress);
const positionState = await cpAmm.fetchPositionState(positionAddress);

const unclaimed = getUnClaimLpFee(poolState, positionState);
console.log(`Unclaimed token A fees: ${unclaimed.feeTokenA.toString()}`);
console.log(`Unclaimed token B fees: ${unclaimed.feeTokenB.toString()}`);
unclaimed.rewards.forEach((reward, i) => {
  console.log(`Unclaimed reward ${i}: ${reward.toString()}`);
});

getBaseFeeNumerator

Calculates the current base fee numerator based on the configured fee scheduler mode and elapsed periods.

Function

function getBaseFeeNumerator(
  cliffFeeNumerator: BN,
  numberOfPeriod: number,
  periodFrequency: BN,
  reductionFactor: BN,
  baseFeeMode: BaseFeeMode,
  currentPoint: BN,
  activationPoint: BN
): BN;

Parameters

  • baseFeeMode: The fee reduction mode (Fee Scheduler Linear or Exponential)
  • cliffFeeNumerator: The initial maximum fee numerator (starting point)
  • period: The number of elapsed periods since fee reduction began
  • reductionFactor: The rate of fee reduction per period

Mathematical Formula

Linear Mode:

fee = cliffFeeNumerator - (period × reductionFactor)

Exponential Mode:

fee = cliffFeeNumerator × (1 - reductionFactor/BASIS_POINT_MAX)^period

Returns

  • BN: The calculated base fee numerator for the current period

getDynamicFeeNumerator

Calculates a dynamic fee component based on market volatility

Function

function getDynamicFeeNumerator(
  volatilityAccumulator: BN,
  binStep: BN,
  variableFeeControl: BN
): BN;

Parameters

  • volatilityAccumulator: Accumulated measure of market volatility over time
  • binStep: The price bin step size used in the liquidity distribution system
  • variableFeeControl: Control parameter that determines how much volatility affects fees

Mathematical Formula

squareVfaBin = (volatilityAccumulator × binStep)²
vFee = variableFeeControl × squareVfaBin
dynamicFee = (vFee + 99,999,999,999) ÷ 100,000,000,000

Returns

  • BN: The calculated dynamic fee numerator
  • Returns 0 if variableFeeControl is zero (dynamic fees disabled)

bpsToFeeNumerator

Converts basis points to fee numerator format.

Mathematical Formula

feeNumerator = (bps × FEE_DENOMINATOR) ÷ BASIS_POINT_MAX

feeNumeratorToBps

Converts fee numerator back to basis points.

Mathematical Formula

bps = (feeNumerator × BASIS_POINT_MAX) ÷ FEE_DENOMINATOR

getBaseFeeParams

Get and prepares the base fee parameters of the pool.

Function

getBaseFeeParams(
  baseFeeParams: {
    baseFeeMode: BaseFeeMode;
    rateLimiterParam?: {
      baseFeeBps: number;
      feeIncrementBps: number;
      referenceAmount: number;
      maxLimiterDuration: number;
      maxFeeBps: number;
    };
    feeTimeSchedulerParam?: {
      startingFeeBps: number;
      endingFeeBps: number;
      numberOfPeriod: number;
      totalDuration: number;
    };
    feeMarketCapSchedulerParam?: {
      startingFeeBps: number;
      endingFeeBps: number;
      numberOfPeriod: number;
      sqrtPriceStepBps: number;
      schedulerExpirationDuration: number;
    };
  },
  tokenBDecimal: number,
  activationType: ActivationType): BaseFee

Parameters

connection: Connection, // rpc connection
baseFeeParams: {
  baseFeeMode: BaseFeeMode; // base fee mode
  rateLimiterParam?: { // if you choose BaseFeeMode.RateLimiter mode
    baseFeeBps: number; // base fee in basis points
    feeIncrementBps: number; // fee increment in basis points
    referenceAmount: number; // reference amount (in terms of quote token)
    maxLimiterDuration: number; // max limiter duration in seconds
    maxFeeBps: number; // max fee in basis points
  };
  feeTimeSchedulerParam?: { // if you choose BaseFeeMode.FeeTimeSchedulerLinear or BaseFeeMode.FeeTimeSchedulerExponential mode
    startingFeeBps: number; // starting fee in basis points
    endingFeeBps: number; // ending fee in basis points
    numberOfPeriod: number; // number of periods
    totalDuration: number; // total duration in seconds
  };
  feeMarketCapSchedulerParam?: { // if you choose BaseFeeMode.FeeMarketCapSchedulerLinear or BaseFeeMode.FeeMarketCapSchedulerExponential mode
    startingFeeBps: number; // starting fee in basis points
    endingFeeBps: number; // ending fee in basis points
    numberOfPeriod: number; // number of periods
    sqrtPriceStepBps: number; // sqrt price step in basis points
    schedulerExpirationDuration: number; // scheduler expiration duration in seconds
  };
},
tokenBDecimal: number, // token B decimal
activationType: ActivationType // activation type

Returns

The base fee parameters in encoded Borsh format. (data: number[])

Example

const baseFee = getBaseFeeParams(
  {
    baseFeeMode: BaseFeeMode.FeeMarketCapSchedulerLinear,
    feeMarketCapSchedulerParam: {
      startingFeeBps: 5000,
      endingFeeBps: 100,
      numberOfPeriod: 180,
      sqrtPriceStepBps: 200,
      schedulerExpirationDuration: 2592000,
    },
  },
  6,
  ActivationType.Timestamp
);

Notes

  • Returns the base fee parameters in encoded Borsh format. (data: number[])

getDynamicFeeParams

Calculates the parameters needed for dynamic fee. This function will always return dynamic fee parameters that are configured to be 20% of the feeBps that you input in.

Key Features

  • Configures volatility-based fee parameters
  • Sets maximum price change thresholds
  • Calculates variable fee control parameters

Fee Codec Functions

These functions are used to encode and decode base fee parameters. There are two serialization formats:

  • Borsh format (30 bytes): Used in EvtInitializePool events
  • PodAligned format (32 bytes): Used in poolState account data

encodeFeeTimeSchedulerParams

Encodes Fee Time Scheduler parameters into Borsh format for pool creation.

Function

encodeFeeTimeSchedulerParams(
  cliffFeeNumerator: BN,
  numberOfPeriod: number,
  periodFrequency: BN,
  reductionFactor: BN,
  baseFeeMode: BaseFeeMode
): Buffer

Parameters

  • cliffFeeNumerator: Starting fee numerator (e.g., 500000000 = 50%)
  • numberOfPeriod: Number of fee reduction periods
  • periodFrequency: Time between periods (slots or seconds)
  • reductionFactor: Fee reduction per period
  • baseFeeMode: BaseFeeMode.FeeTimeSchedulerLinear (0) or BaseFeeMode.FeeTimeSchedulerExponential (1)

Returns

A Buffer containing the Borsh-encoded fee parameters.

Example

const encoded = encodeFeeTimeSchedulerParams(
  new BN(500000000), // 50% starting fee
  100, // 100 periods
  new BN(6), // 6 seconds between periods
  new BN(4900000), // reduction factor
  BaseFeeMode.FeeTimeSchedulerLinear
);

encodeFeeMarketCapSchedulerParams

Encodes Fee Market Cap Scheduler parameters into Borsh format for pool creation.

Function

encodeFeeMarketCapSchedulerParams(
  cliffFeeNumerator: BN,
  numberOfPeriod: number,
  sqrtPriceStepBps: number,
  schedulerExpirationDuration: number,
  reductionFactor: BN,
  baseFeeMode: BaseFeeMode
): Buffer

Parameters

  • cliffFeeNumerator: Starting fee numerator (e.g., 500000000 = 50%)
  • numberOfPeriod: Number of fee reduction periods
  • sqrtPriceStepBps: Sqrt price step in basis points to advance one period
  • schedulerExpirationDuration: Duration after which scheduler expires (slots or seconds)
  • reductionFactor: Fee reduction per period
  • baseFeeMode: BaseFeeMode.FeeMarketCapSchedulerLinear (3) or BaseFeeMode.FeeMarketCapSchedulerExponential (4)

Returns

A Buffer containing the Borsh-encoded fee parameters.

Example

const encoded = encodeFeeMarketCapSchedulerParams(
  new BN(500000000), // 50% starting fee
  100, // 100 periods
  100, // 1% sqrt price step
  86400, // 24 hours expiration
  new BN(4950000), // reduction factor
  BaseFeeMode.FeeMarketCapSchedulerLinear
);

encodeFeeRateLimiterParams

Encodes Rate Limiter parameters into Borsh format for pool creation.

Function

encodeFeeRateLimiterParams(
  cliffFeeNumerator: BN,
  feeIncrementBps: number,
  maxLimiterDuration: number,
  maxFeeBps: number,
  referenceAmount: BN
): Buffer

Parameters

  • cliffFeeNumerator: Base fee numerator (e.g., 10000000 = 1%)
  • feeIncrementBps: Fee increment in basis points per reference amount
  • maxLimiterDuration: Maximum duration for rate limiter (slots or seconds)
  • maxFeeBps: Maximum fee cap in basis points
  • referenceAmount: Reference amount for fee calculation (in lamports)

Returns

A Buffer containing the Borsh-encoded fee parameters.

Example

const encoded = encodeFeeRateLimiterParams(
  new BN(10000000), // 1% base fee
  10, // 0.1% fee increment per reference amount
  10, // 10 slots/seconds max duration
  5000, // 50% max fee cap
  new BN(1000000000) // 1 SOL reference amount
);

decodeFeeTimeSchedulerParams

Decodes Borsh-encoded Fee Time Scheduler parameters (from EvtInitializePool events).

Function

decodeFeeTimeSchedulerParams(data: Buffer): BorshFeeTimeScheduler

Parameters

  • data: A Buffer containing Borsh-encoded fee data (30 bytes)

Returns

interface BorshFeeTimeScheduler {
  cliffFeeNumerator: BN;
  numberOfPeriod: number;
  periodFrequency: BN;
  reductionFactor: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from EvtInitializePool event
const decoded = decodeFeeTimeSchedulerParams(eventData.baseFee.data);
console.log(`Starting Fee: ${decoded.cliffFeeNumerator.toString()}`);
console.log(`Number of Periods: ${decoded.numberOfPeriod}`);

decodeFeeMarketCapSchedulerParams

Decodes Borsh-encoded Fee Market Cap Scheduler parameters (from EvtInitializePool events).

Function

decodeFeeMarketCapSchedulerParams(data: Buffer): BorshFeeMarketCapScheduler

Parameters

  • data: A Buffer containing Borsh-encoded fee data (30 bytes)

Returns

interface BorshFeeMarketCapScheduler {
  cliffFeeNumerator: BN;
  numberOfPeriod: number;
  sqrtPriceStepBps: number;
  schedulerExpirationDuration: number;
  reductionFactor: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from EvtInitializePool event
const decoded = decodeFeeMarketCapSchedulerParams(eventData.baseFee.data);
console.log(`Starting Fee: ${decoded.cliffFeeNumerator.toString()}`);
console.log(`Sqrt Price Step: ${decoded.sqrtPriceStepBps} bps`);

decodeFeeRateLimiterParams

Decodes Borsh-encoded Rate Limiter parameters (from EvtInitializePool events).

Function

decodeFeeRateLimiterParams(data: Buffer): BorshFeeRateLimiter

Parameters

  • data: A Buffer containing Borsh-encoded fee data (30 bytes)

Returns

interface BorshFeeRateLimiter {
  cliffFeeNumerator: BN;
  feeIncrementBps: number;
  maxLimiterDuration: number;
  maxFeeBps: number;
  referenceAmount: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from EvtInitializePool event
const decoded = decodeFeeRateLimiterParams(eventData.baseFee.data);
console.log(`Base Fee: ${decoded.cliffFeeNumerator.toString()}`);
console.log(`Max Fee: ${decoded.maxFeeBps} bps`);

decodePodAlignedFeeTimeScheduler

Decodes PodAligned Fee Time Scheduler parameters (from poolState account data).

Function

decodePodAlignedFeeTimeScheduler(data: Buffer): PodAlignedFeeTimeScheduler

Parameters

  • data: A Buffer containing PodAligned fee data (32 bytes)

Returns

interface PodAlignedFeeTimeScheduler {
  cliffFeeNumerator: BN;
  numberOfPeriod: number;
  periodFrequency: BN;
  reductionFactor: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from poolState account
const poolState = await program.account.pool.fetch(poolAddress);
const decoded = decodePodAlignedFeeTimeScheduler(
  Buffer.from(poolState.poolFees.baseFee.data)
);
console.log(`Current Fee Config: ${decoded.cliffFeeNumerator.toString()}`);

decodePodAlignedFeeMarketCapScheduler

Decodes PodAligned Fee Market Cap Scheduler parameters (from poolState account data).

Function

decodePodAlignedFeeMarketCapScheduler(data: Buffer): PodAlignedFeeMarketCapScheduler

Parameters

  • data: A Buffer containing PodAligned fee data (32 bytes)

Returns

interface PodAlignedFeeMarketCapScheduler {
  cliffFeeNumerator: BN;
  numberOfPeriod: number;
  sqrtPriceStepBps: number;
  schedulerExpirationDuration: number;
  reductionFactor: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from poolState account
const poolState = await program.account.pool.fetch(poolAddress);
const decoded = decodePodAlignedFeeMarketCapScheduler(
  Buffer.from(poolState.poolFees.baseFee.data)
);
console.log(`Expiration Duration: ${decoded.schedulerExpirationDuration}`);

decodePodAlignedFeeRateLimiter

Decodes PodAligned Rate Limiter parameters (from poolState account data).

Function

decodePodAlignedFeeRateLimiter(data: Buffer): PodAlignedFeeRateLimiter

Parameters

  • data: A Buffer containing PodAligned fee data (32 bytes)

Returns

interface PodAlignedFeeRateLimiter {
  cliffFeeNumerator: BN;
  feeIncrementBps: number;
  maxLimiterDuration: number;
  maxFeeBps: number;
  referenceAmount: BN;
  baseFeeMode: number;
  padding: number[];
}

Example

// Decode from poolState account
const poolState = await program.account.pool.fetch(poolAddress);
const decoded = decodePodAlignedFeeRateLimiter(
  Buffer.from(poolState.poolFees.baseFee.data)
);
console.log(`Reference Amount: ${decoded.referenceAmount.toString()}`);

Decoding BaseFee Summary

When decoding baseFee.data, choose the decoder based on data source and baseFeeMode:

Data Source Format Size baseFeeMode 0-1 baseFeeMode 2 baseFeeMode 3-4
EvtInitializePool event Borsh 30 bytes decodeFeeTimeSchedulerParams decodeFeeRateLimiterParams decodeFeeMarketCapSchedulerParams
poolState account PodAligned 32 bytes decodePodAlignedFeeTimeScheduler decodePodAlignedFeeRateLimiter decodePodAlignedFeeMarketCapScheduler