-
- createPool
- createCustomPool
- createCustomPoolWithDynamicConfig
- createPosition
- getLiquidityDelta
- getQuote
- getQuote2
- getDepositQuote
- getWithdrawQuote
- swap
- addLiquidity
- removeLiquidity
- removeAllLiquidity
- removeAllLiquidityAndClosePosition
- mergePosition
- lockPosition
- permanentLockPosition
- refreshVesting
- claimPositionFee
- claimPositionFee2
- claimPartnerFee
- initializeReward
- initializeAndFundReward
- updateRewardDuration
- updateRewardFunder
- fundReward
- claimReward
- withdrawIneligibleReward
- closePosition
- splitPosition
- splitPosition2
-
- preparePoolCreationParams
- isVestingComplete
- getTotalLockedLiquidity
- getAvailableVestingLiquidity
- getMaxAmountWithSlippage
- getAmountWithSlippage
- getPriceImpact
- getPriceFromSqrtPrice
- getSqrtPriceFromPrice
- getUnClaimLpFee
- getBaseFeeNumerator
- getDynamicFeeNumerator
- bpsToFeeNumerator
- feeNumeratorToBps
- getBaseFeeParams
- getDynamicFeeParams
- encodeFeeTimeSchedulerParams
- encodeFeeMarketCapSchedulerParams
- encodeFeeRateLimiterParams
- decodeFeeTimeSchedulerParams
- decodeFeeMarketCapSchedulerParams
- decodeFeeRateLimiterParams
- decodePodAlignedFeeTimeScheduler
- decodePodAlignedFeeMarketCapScheduler
- decodePodAlignedFeeRateLimiter
Creates a new standard pool according to a predefined configuration.
Function
async createPool(params: CreatePoolParams): TxBuilderParameters
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
configparameter should be a valid configuration account - Pool creation automatically creates an initial position
- Use
preparePoolCreationParamsto calculate properinitSqrtPriceandliquidityDelta
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 sendpool: The public key of the created poolposition: 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
createPoolwhen you need custom fee structures - Use
preparePoolCreationParamsto calculate properinitSqrtPriceandliquidityDelta
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 sendpool: The public key of the created poolposition: 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,
});Creates a new position in an existing pool.
Function
async createPosition(params: CreatePositionParams): TxBuilderParameters
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
positionNftshould be a new mint that doesn't already have a position - Creating a position doesn't automatically add liquidity
- After creating a position, use
addLiquidityto provide tokens
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.
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 amountconsumedInAmount: The actual input amount used (after transfer fees)swapOutAmount: The expected output amountminSwapOutAmount: The minimum output amount accounting for slippagetotalFee: The total fee to be paidpriceImpact: 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
slippageparameter protects users from price movements - Use the
minSwapOutAmountas theminimumAmountOutparameter forswap - For Token2022 tokens with transfer fees, provide the token info parameters
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 feesexcludedFeeInputAmount: The input amount excluding feesamountLeft: The remaining amount after the swap (if any)outputAmount: The expected output amountnextSqrtPrice: The next sqrt price after the swaptradingFee: The trading fee charged for the swapprotocolFee: The protocol fee charged for the swappartnerFee: The partner fee charged for the swap (Deprecating soon)referralFee: The referral fee charged for the swappriceImpact: The price impact of the swapminimumAmountOut(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
slippageparameter protects users from price movements - For Token2022 tokens with transfer fees, provide the token info parameters
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 feesliquidityDelta: The amount of liquidity that will be addedoutputAmount: 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
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 removedoutAmountA: The calculated amount of token A to receiveoutAmountB: 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
Executes a token swap in the pool.
Function
async swap(params: SwapParams): TxBuilderParameters
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
getQuoteto determine theminimumAmountOut - 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
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): TxBuilderParameters
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
getQuote2to determine theminimumAmountOutormaximumAmountIndepending 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
minimumAmountOutor the input amount would be greater thanmaximumAmountIndepending on the swap mode - Optional referral tokenAccount will receive a portion of fees if the pool is configured for referrals
Adds liquidity to an existing position.
Function
async addLiquidity(params: AddLiquidityParams): TxBuilderParameters
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
Removes a specific amount of liquidity from an existing position.
Function
async removeLiquidity(params: RemoveLiquidityParams): TxBuilderParameters
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
Removes all available liquidity from a position.
Function
async removeAllLiquidity(params: RemoveAllLiquidityParams): TxBuilderParameters
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
refreshVestingfirst if needed) - The SDK handles wrapping/unwrapping of SOL automatically
Removes all liquidity from a position and closes it in a single transaction.
Function
async removeAllLiquidityAndClosePosition(params: RemoveAllLiquidityAndClosePositionParams): TxBuilderParameters
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:
- Claims any accumulated fees
- Removes all liquidity
- 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
Merges liquidity from one position into another in a single transaction.
Function
async mergePosition(params: MergePositionParams): TxBuilderParameters
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:
- Claims any accumulated fees from the source position
- Removes all liquidity from the source position
- Adds the liquidity to the target position
- 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
Builds a transaction to lock a position with vesting schedule.
Function
async lockPosition(params: LockPositionParams): TxBuilderParameters
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
Permanently locks a portion of liquidity in a position.
Function
async permanentLockPosition(params: PermanentLockParams): TxBuilderParameters
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
Refreshes vesting status of a position to unlock available liquidity.
Function
async refreshVesting(params: RefreshVestingParams): TxBuilderParameters
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
Claims accumulated fees for a position.
Function
async claimPositionFee(params: ClaimPositionFeeParams): TxBuilderParameters
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
Claims accumulated fees for a position.
Function
async claimPositionFee2(params: ClaimPositionFeeParams2): TxBuilderParameters
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
Claims partner fee rewards. (Deprecating soon)
Function
async claimPartnerFee(params: ClaimPartnerFeeParams): TxBuilderParameters
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
Initializes a reward for a pool.
Function
async initializeReward(params: InitializeRewardParams): TxBuilderParameters
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.
Initializes and funds a reward for a pool.
Function
async initializeAndFundReward(params: InitializeAndFundReward): TxBuilderParameters
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
Updates the duration of a reward.
Function
async updateRewardDuration(params: UpdateRewardDurationParams): TxBuilderParameters
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
Updates the funder of a reward.
Function
async updateRewardFunder(params: UpdateRewardFunderParams): TxBuilderParameters
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
Funds a reward for a pool.
Function
async fundReward(params: FundRewardParams): TxBuilderParameters
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
Claims reward tokens from a position.
Function
async claimReward(params: ClaimRewardParams): TxBuilderParameters
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
Withdraws ineligible reward tokens from a pool.
Function
async withdrawIneligibleReward(params: WithdrawIneligibleRewardParams): TxBuilderParameters
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
Closes a position with no liquidity.
Function
async closePosition(params: ClosePositionParams): TxBuilderParameters
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
removeAllLiquidityfirst 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
removeAllLiquidityAndClosePositioninstead
Splits a position into two positions.
Function
async splitPosition(params: SplitPositionParams): TxBuilderParameters
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
Splits a position into two positions via numerator.
Function
async splitPosition2(params: SplitPosition2Params): TxBuilderParameters
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
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
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
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
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
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()}`);
});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()}`);
});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`);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`);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`);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
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`);Checks if a position has any locked liquidity.
Function
isLockedPosition(position: PositionState): booleanParameters
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");
}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");
}Prepares parameters required for pool creation, including initial sqrt price and liquidity.
Function
preparePoolCreationParams(params: PreparePoolCreationParams): PreparedPoolCreationParameters
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 formatliquidityDelta: 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
Checks if a vesting schedule is ready for full release.
Function
function isVestingComplete(
vestingData: VestingState,
currentPoint: BN
): boolean;Parameters
vestingData: The vesting account state datacurrentPoint: 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
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
Calculates the available liquidity to withdraw based on vesting schedule.
Function
function getAvailableVestingLiquidity(
vestingData: VestingState,
currentPoint: BN
): BN;Parameters
vestingData: The vesting account state datacurrentPoint: 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()}`
);
}Calculates the maximum amount after applying a slippage rate.
Function
function getMaxAmountWithSlippage(amount: BN, rate: number): BN;Parameters
amount: The base amount as a BNrate: 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
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 BNslippageBps: 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
Calculates the price impact as a percentage.
Function
function getPriceImpact(actualAmount: BN, idealAmount: BN): number;Parameters
actualAmount: The actual amount after slippage in token unitsidealAmount: 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
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 formattokenADecimal: The number of decimals for token AtokenBDecimal: 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
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 formattokenADecimal: The number of decimals for token AtokenBDecimal: 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
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 poolpositionState: The current state of the position
Returns
An object containing:
feeTokenA: Unclaimed fees in token AfeeTokenB: Unclaimed fees in token Brewards: 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()}`);
});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 beganreductionFactor: 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
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 timebinStep: The price bin step size used in the liquidity distribution systemvariableFeeControl: 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
0ifvariableFeeControlis zero (dynamic fees disabled)
Converts basis points to fee numerator format.
Mathematical Formula
feeNumerator = (bps × FEE_DENOMINATOR) ÷ BASIS_POINT_MAX
Converts fee numerator back to basis points.
Mathematical Formula
bps = (feeNumerator × BASIS_POINT_MAX) ÷ FEE_DENOMINATOR
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): BaseFeeParameters
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 typeReturns
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[])
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
These functions are used to encode and decode base fee parameters. There are two serialization formats:
- Borsh format (30 bytes): Used in
EvtInitializePoolevents - PodAligned format (32 bytes): Used in
poolStateaccount data
Encodes Fee Time Scheduler parameters into Borsh format for pool creation.
Function
encodeFeeTimeSchedulerParams(
cliffFeeNumerator: BN,
numberOfPeriod: number,
periodFrequency: BN,
reductionFactor: BN,
baseFeeMode: BaseFeeMode
): BufferParameters
cliffFeeNumerator: Starting fee numerator (e.g., 500000000 = 50%)numberOfPeriod: Number of fee reduction periodsperiodFrequency: Time between periods (slots or seconds)reductionFactor: Fee reduction per periodbaseFeeMode:BaseFeeMode.FeeTimeSchedulerLinear(0) orBaseFeeMode.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
);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
): BufferParameters
cliffFeeNumerator: Starting fee numerator (e.g., 500000000 = 50%)numberOfPeriod: Number of fee reduction periodssqrtPriceStepBps: Sqrt price step in basis points to advance one periodschedulerExpirationDuration: Duration after which scheduler expires (slots or seconds)reductionFactor: Fee reduction per periodbaseFeeMode:BaseFeeMode.FeeMarketCapSchedulerLinear(3) orBaseFeeMode.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
);Encodes Rate Limiter parameters into Borsh format for pool creation.
Function
encodeFeeRateLimiterParams(
cliffFeeNumerator: BN,
feeIncrementBps: number,
maxLimiterDuration: number,
maxFeeBps: number,
referenceAmount: BN
): BufferParameters
cliffFeeNumerator: Base fee numerator (e.g., 10000000 = 1%)feeIncrementBps: Fee increment in basis points per reference amountmaxLimiterDuration: Maximum duration for rate limiter (slots or seconds)maxFeeBps: Maximum fee cap in basis pointsreferenceAmount: 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
);Decodes Borsh-encoded Fee Time Scheduler parameters (from EvtInitializePool events).
Function
decodeFeeTimeSchedulerParams(data: Buffer): BorshFeeTimeSchedulerParameters
data: ABuffercontaining 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}`);Decodes Borsh-encoded Fee Market Cap Scheduler parameters (from EvtInitializePool events).
Function
decodeFeeMarketCapSchedulerParams(data: Buffer): BorshFeeMarketCapSchedulerParameters
data: ABuffercontaining 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`);Decodes Borsh-encoded Rate Limiter parameters (from EvtInitializePool events).
Function
decodeFeeRateLimiterParams(data: Buffer): BorshFeeRateLimiterParameters
data: ABuffercontaining 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`);Decodes PodAligned Fee Time Scheduler parameters (from poolState account data).
Function
decodePodAlignedFeeTimeScheduler(data: Buffer): PodAlignedFeeTimeSchedulerParameters
data: ABuffercontaining 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()}`);Decodes PodAligned Fee Market Cap Scheduler parameters (from poolState account data).
Function
decodePodAlignedFeeMarketCapScheduler(data: Buffer): PodAlignedFeeMarketCapSchedulerParameters
data: ABuffercontaining 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}`);Decodes PodAligned Rate Limiter parameters (from poolState account data).
Function
decodePodAlignedFeeRateLimiter(data: Buffer): PodAlignedFeeRateLimiterParameters
data: ABuffercontaining 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()}`);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 |