DAMM v2 TypeScript SDK
A TypeScript SDK for interacting with Dynamic CP-AMM (DAMM V2) on Meteora
Getting Started
To integrate DAMM v2, this TypeScript SDK provides a set of tools and methods to interact with the Meteora (CP-AMM) DAMM v2 program. It simplifies common operations like creating pools, managing positions, adding/removing liquidity, swapping tokens, and claiming rewards.
Program Repo on Github: https://github.com/MeteoraAg/damm-v2
TypeScript SDK on Github: https://github.com/MeteoraAg/damm-v2-sdk/tree/main
Program ID (mainnet-beta):
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
Program ID (devnet):
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
1. Install dependencies and initialize instance
1.1 Install
pnpm install @meteora-ag/cp-amm-sdk
# or
yarn add @meteora-ag/cp-amm-sdk
1.2 Initialization
import { Connection } from "@solana/web3.js";
import { CpAmm } from "@meteora-ag/cp-amm-sdk";
// Initialize a connection to the Solana network
const connection = new Connection("https://api.mainnet-beta.solana.com");
// Create a new instance of the CpAmm SDK
const cpAmm = new CpAmm(connection);
1.3 Test
pnpm install
pnpm test
1.4 Faucets
2. Core Functions and Use Cases
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; // 0: slot, 1: timestamp
tokenAAmount: BN; // Initial amount of token A to deposit
tokenBAmount: BN; // Initial amount of token B to deposit
minSqrtPrice: BN; // Minimum sqrt price (typically MIN_SQRT_PRICE)
maxSqrtPrice: BN; // Maximum sqrt price (typically MAX_SQRT_PRICE)
tokenADecimal: number; // Decimal places for token A
tokenBDecimal: number; // Decimal places for token B
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 createPoolTx = await cpAmm.createPool({
payer: wallet.publicKey,
creator: wallet.publicKey,
config: configAddress,
positionNft: positionNftMint,
tokenAMint: usdcMint,
tokenBMint: solMint,
activationPoint: new BN(Date.now()),
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,
tokenADecimal: 6,
tokenBDecimal: 9,
tokenAProgram: TOKEN_PROGRAM_ID,
tokenBProgram: TOKEN_PROGRAM_ID
});
const tx = await createPoolTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
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 accountPool creation automatically creates an initial position
To set your Pool and Fee Config, please read the instructions in Setting Pool and Fee Config for DAMM v2
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
minSqrtPrice: BN; // Minimum sqrt price
maxSqrtPrice: BN; // Maximum sqrt price
tokenADecimal: number; // Decimal places for token A
tokenBDecimal: number; // Decimal places 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
tokenAProgram: PublicKey; // Token program for token A
tokenBProgram: PublicKey; // Token program for token B
}
interface PoolFees {
baseFee: {
feeSchedulerMode: number; // 0: Linear, 1: Exponential
cliffFeeNumerator: number;
numberOfPeriod: number;
reductionFactor: number;
periodFrequency: number;
};
partnerFee?: {
partnerAddress: PublicKey;
partnerFeeNumerator: number;
};
dynamicFee?: {
initialized: boolean;
volatilityAccumulator?: number;
binStep?: number;
variableFeeControl?: {
maxFeeNumerator: number;
minFeeNumerator: number;
volatilityThreshold: number;
feeDamper: number;
};
};
}
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
const poolFees = {
baseFee: {
feeSchedulerMode: 0, // 0: Linear, 1: Exponential
cliffFeeNumerator: 1_000_000,
numberOfPeriod: 0,
reductionFactor: 0,
periodFrequency: 0
},
partnerFee: {
partnerAddress: partnerWallet.publicKey,
partnerFeeNumerator: 1000,
},
dynamicFee: {
initialized: false
}
};
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),
minSqrtPrice: MIN_SQRT_PRICE,
maxSqrtPrice: MAX_SQRT_PRICE,
tokenADecimal: 6,
tokenBDecimal: 8,
poolFees,
hasAlphaVault: false,
collectFeeMode: 0, // 0: BothToken, 1: onlyB
activationPoint: new BN(Date.now()),
activationType: 1, // 0: slot, 1: timestamp
tokenAProgram: TOKEN_PROGRAM_ID,
tokenBProgram: TOKEN_PROGRAM_ID
});
const Function = await wallet.sendTransaction(tx, connection);
Notes
Use this function instead of
createPool
when you need custom fee structuresDynamic fees can adjust based on market volatility
Partner fees allow a portion of trading fees to be directed to a specific account
Alpha vault is an advanced feature for protocol-owned liquidity
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 Function = await wallet.sendTransaction(tx, connection);
Notes
The
positionNft
should be a new mint that doesn't already have a positionCreating a position doesn't automatically add liquidity
After creating a position, use
addLiquidity
to provide tokens
getQuote
Calculates the expected output amount for a swap, including fees and slippage protection.
Function
async getQuote(params: GetQuoteParams): Promise<{
swapInAmount: 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
}
Returns
An object containing:
swapInAmount
: The input amountswapOutAmount
: 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 quote = await cpAmm.getQuote({
inAmount: new BN(100_000_000), // 100 USDC
inputTokenMint: usdcMint,
slippage: 0.5, // 0.5% slippage
poolState
});
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 movementsThis function doesn't execute a swap, only provides a quote
Use the
minSwapOutAmount
as theminimumAmountOut
parameter forswap
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 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
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 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
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.
Example
const poolState = await cpAmm.fetchPoolState(poolAddress);
const liquidityDelta = await cpAmm.getLiquidityDelta({
maxAmountTokenA: new BN(1_000_000_000), // 1,000 USDC
maxAmountTokenB: new BN(5_000_000_000), // 5 SOL
sqrtPrice: poolState.sqrtPrice,
sqrtMinPrice: MIN_SQRT_PRICE,
sqrtMaxPrice: MAX_SQRT_PRICE
});
console.log(`Liquidity delta: ${liquidityDelta.toString()}`);
Notes
This function is used before adding liquidity to calculate the appropriate liquidity delta
The function returns the minimum liquidity that can be added based on both token amounts
The result is in Q64 fixed-point notation
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
referralTokenAccount?: PublicKey; // Optional referral account for fees
}
Returns
A transaction builder (TxBuilder
) that can be used to build, sign, and send the transaction.
Example
const poolState = await cpAmm.fetchPoolState(poolAddress);
// Get quote first
const quote = await cpAmm.getQuote({
inAmount: new BN(100_000_000), // 100 USDC
inputTokenMint: poolState.tokenAMint,
slippage: 0.5,
poolState
});
// 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
});
const tx = await swapTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
Get a quote first using
getQuote
to 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
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
positionNftMint: PublicKey; // The position NFT mint
liquidityDeltaQ64: 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
// Calculate liquidity delta first
const liquidityDelta = await cpAmm.getLiquidityDelta({
maxAmountTokenA: new BN(1_000_000_000), // 1,000 USDC
maxAmountTokenB: new BN(5_000_000_000), // 5 SOL
sqrtPrice: poolState.sqrtPrice,
sqrtMinPrice: MIN_SQRT_PRICE,
sqrtMaxPrice: MAX_SQRT_PRICE
});
// Add liquidity
const addLiquidityTx = await cpAmm.addLiquidity({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
positionNftMint: positionNftMint,
liquidityDeltaQ64: liquidityDelta,
maxAmountTokenA: new BN(1_000_000_000),
maxAmountTokenB: new BN(5_000_000_000),
tokenAAmountThreshold: new BN(0),
tokenBAmountThreshold: new BN(0),
tokenAMint: poolState.tokenAMint,
tokenBMint: poolState.tokenBMint,
tokenAVault: poolState.tokenAVault,
tokenBVault: poolState.tokenBVault,
tokenAProgram: TOKEN_PROGRAM_ID,
tokenBProgram: TOKEN_PROGRAM_ID
});
const tx = await addLiquidityTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
Calculate the liquidity delta first using
getLiquidityDelta
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 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
positionNftMint: PublicKey; // The position NFT mint
liquidityDeltaQ64: 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
}
Returns
A transaction builder (TxBuilder
) that can be used to build, sign, and send the transaction.
Example
// Get position state to determine available liquidity
const positionState = await cpAmm.fetchPositionState(positionAddress);
// Remove half of the available liquidity
const liquidityToRemove = positionState.liquidity.div(new BN(2));
const removeLiquidityTx = await cpAmm.removeLiquidity({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
positionNftMint: positionNftMint,
liquidityDeltaQ64: liquidityToRemove,
tokenAAmountThreshold: new BN(0), // Set appropriate thresholds for slippage protection
tokenBAmountThreshold: new BN(0),
tokenAMint: poolState.tokenAMint,
tokenBMint: poolState.tokenBMint,
tokenAVault: poolState.tokenAVault,
tokenBVault: poolState.tokenBVault,
tokenAProgram: TOKEN_PROGRAM_ID,
tokenBProgram: TOKEN_PROGRAM_ID
});
const tx = await removeLiquidityTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
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:
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
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:
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
lockPosition
Locks a position with a vesting schedule for gradual unlocking over time.
Function
async lockPosition(params: LockPositionParams): TxBuilder
Parameters
interface LockPositionParams {
owner: PublicKey; // The owner of the position
pool: PublicKey; // The pool address
payer: PublicKey; // The payer for the transaction
vestingAccount: PublicKey; // The vesting account to create
position: PublicKey; // The position address
positionNftMint: PublicKey; // The position NFT mint
cliffPoint: BN; // The slot or timestamp for the cliff
periodFrequency: BN; // Frequency of unlock periods
cliffUnlockLiquidity: BN; // Liquidity to unlock at cliff
liquidityPerPeriod: BN; // Liquidity to unlock per period
numberOfPeriod: number; // Number of unlock periods
}
Returns
A transaction builder (TxBuilder
) that can be used to build, sign, and send the transaction.
Example
const lockPositionTx = await cpAmm.lockPosition({
owner: wallet.publicKey,
pool: poolAddress,
payer: wallet.publicKey,
vestingAccount: vestingAccountAddress, // Generated keypair
position: positionAddress,
positionNftMint: positionNftMint,
cliffPoint: new BN(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days cliff
periodFrequency: new BN(7 * 24 * 60 * 60), // 7 days per period
cliffUnlockLiquidity: new BN(0), // No liquidity at cliff
liquidityPerPeriod: new BN("1000000000000000"), // Amount in Q64 format
numberOfPeriod: 52 // 52 periods (1 year with weekly unlocks)
});
const tx = await lockPositionTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
The vesting schedule is enforced on-chain
Locked liquidity cannot be removed until it's unlocked according to the schedule
The
vestingAccount
should be a new keypairThe
cliffPoint
andperiodFrequency
are in the same units as the pool's activation type
permanentLockPosition
Permanently locks a portion of a position's liquidity (cannot be unlocked).
Function
async permanentLockPosition(params: PermanentLockParams): TxBuilder
Parameters
interface PermanentLockParams {
owner: PublicKey; // The owner of the position
position: PublicKey; // The position address
positionNftMint: PublicKey; // The position NFT mint
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);
// Lock 20% of the position's liquidity permanently
const liquidityToLock = positionState.liquidity.mul(new BN(20)).div(new BN(100));
const permLockTx = await cpAmm.permanentLockPosition({
owner: wallet.publicKey,
position: positionAddress,
positionNftMint: positionNftMint,
pool: poolAddress,
unlockedLiquidity: liquidityToLock
});
const tx = await permLockTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
Permanently locked liquidity can never be withdrawn
You can only permanently lock liquidity that is currently unlocked
This is useful for governance or long-term incentive mechanisms
refreshVesting
Updates the vesting status of a position to reflect elapsed time and unlock available liquidity.
Function
async refreshVesting(params: RefreshVestingParams): TxBuilder
Parameters
interface RefreshVestingParams {
owner: PublicKey; // The owner of the position
position: PublicKey; // The position address
positionNftMint: PublicKey; // The position NFT mint
pool: PublicKey; // The pool address
vestings: PublicKey[]; // Array of vesting accounts to refresh
}
Returns
A transaction builder (TxBuilder
) that can be used to build, sign, and send the transaction.
Example
const refreshVestingTx = await cpAmm.refreshVesting({
owner: wallet.publicKey,
position: positionAddress,
positionNftMint: positionNftMint,
pool: poolAddress,
vestings: [vestingAccountAddress1, vestingAccountAddress2]
});
const tx = await refreshVestingTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
This function should be called periodically to update the unlocked liquidity amount
It doesn't automatically withdraw the unlocked liquidity
After refreshing, you can use
removeLiquidity
to withdraw the newly unlocked liquidityYou can refresh multiple vesting schedules in a single transaction
claimPositionFee
Claims accumulated swap fees for a liquidity 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
nftPositionMint: PublicKey; // The position NFT mint
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
}
Returns
A transaction builder (TxBuilder
) that can be used to build, sign, and send the transaction.
Example
const claimFeeTx = await cpAmm.claimPositionFee({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
nftPositionMint: positionNftMint,
tokenAVault: poolState.tokenAVault,
tokenBVault: poolState.tokenBVault,
tokenAMint: poolState.tokenAMint,
tokenBMint: poolState.tokenBMint,
tokenAProgram: TOKEN_PROGRAM_ID,
tokenBProgram: TOKEN_PROGRAM_ID
});
const tx = await claimFeeTx.transaction();
const Function = await wallet.sendTransaction(tx, connection);
Notes
Fees are accumulated in both token A and token B
The SDK handles wrapping/unwrapping of SOL automatically
Token accounts are created automatically if they don't exist
Fees can be claimed regardless of whether liquidity is locked
claimPartnerFee
Claims partner fees from a pool (if the pool has partner fees configured).
Function
async claimPartnerFee(params: ClaimPartnerFeeParams): TxBuilder
Parameters
interface ClaimPartnerFeeParams {
partner: PublicKey; // The partner address
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 claimPartnerFeeTx = await cpAmm.claimPartnerFee({
partner: partnerWallet.publicKey,
pool: poolAddress,
maxAmountA: new B
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
positionNftAccount: PublicKey; // The position NFT account
rewardIndex: number; // Index of the reward to claim
poolState: PoolState; // The current pool state
positionState: PositionState; // The current position 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 positionState = await cpAmm.fetchPositionState(positionAddress);
// Claim reward at index 0
const claimRewardTx = await cpAmm.claimReward({
user: wallet.publicKey,
position: positionAddress,
positionNftAccount: positionNftAccount,
rewardIndex: 0,
poolState: poolState,
positionState: positionState
});
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
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 liquidityClosing 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
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
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 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
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 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
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 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()}`);
}
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 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
getMinAmountWithSlippage
Calculates the minimum amount after applying a slippage rate.
Function
function getMinAmountWithSlippage(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 minimum amount after applying slippage as a BN.
Example
const expectedOutput = new BN(1_000_000_000); // 1,000 tokens
const slippageRate = 0.5; // 0.5% slippage allowance
const minAmount = getMinAmountWithSlippage(expectedOutput, slippageRate);
console.log(`Minimum amount with slippage: ${minAmount.toString()}`);
Notes
Used when you need to calculate the lower bound of an amount with slippage tolerance
Formula: amount * (100 - rate) / 100
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 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
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 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
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 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
Fee Calculation Utilities
getUnClaimReward
Calculates unclaimed fees and rewards for a position.
Function
function getUnClaimReward(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 = getUnClaimReward(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()}`);
});
For more technical information, please refer to Github at CP-AMM (DAMM v2) SDK Documentation.
Last updated