Create Pool Functions
createPermissionlessConstantProductPoolWithConfig
Creates a new permissionless constant product pool with a predefined configuration.
Function
async createPermissionlessConstantProductPoolWithConfig(
connection: Connection,
payer: PublicKey,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
config: PublicKey,
opt?: {
cluster?: Cluster;
programId?: string;
lockLiquidity?: boolean;
swapLiquidity?: {
inAmount: BN;
minAmountOut: BN;
};
skipAAta?: boolean;
skipBAta?: boolean;
}
): Promise<Transaction>
Parameters
connection: Connection // Solana connection instance
payer: PublicKey // Wallet paying for the transaction
tokenAMint: PublicKey // Mint address for token A
tokenBMint: PublicKey // Mint address for token B
tokenAAmount: BN // Initial amount of token A to deposit
tokenBAmount: BN // Initial amount of token B to deposit
config: PublicKey // The configuration account for the pool
opt?: { // Optional parameters
cluster?: Cluster; // The Solana cluster (mainnet, devnet, etc.)
programId?: string; // Custom program ID if different from default
lockLiquidity?: boolean; // Whether to permanently lock the initial liquidity
swapLiquidity?: { // Optional swap parameters for initial liquidity
inAmount: BN; // Amount to swap in
minAmountOut: BN; // Minimum amount to receive from swap
};
skipAAta?: boolean; // Skip creating associated token account for token A
skipBAta?: boolean; // Skip creating associated token account for token B
}
Returns
An array of transactions that can be signed and sent to the network.
Example
// Token A/B address of the pool.
const tokenAMint = new PublicKey('...');
const tokenBMint = new PublicKey('...');
// Configuration address for the pool. It will decide the fees of the pool.
const config = new PublicKey('...');
// Amount of token A and B to be deposited to the pool.
const tokenAAmount = new BN(100_000);
const tokenBAmount = new BN(500_000);
const transactions = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
provider.connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
config,
);
for (const transaction of transactions) {
transaction.sign(wallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
Notes
- Both token amounts must be greater than zero
- If using native SOL, it will be automatically wrapped to wSOL
- The
config
parameter should be a valid configuration account
createPermissionlessConstantProductPoolWithConfig2
Creates a new permissionless constant product pool with a predefined configuration. This function is similar to createPermissionlessConstantProductPoolWithConfig
but only if you need to set the activation point earlier than the default derived from the config.
Function
async createPermissionlessConstantProductPoolWithConfig2(
connection: Connection,
payer: PublicKey,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
config: PublicKey,
opt?: {
cluster?: Cluster;
programId?: string;
lockLiquidity?: boolean;
swapLiquidity?: {
// always swap B to A
inAmount: BN;
minAmountOut: BN;
};
stakeLiquidity?: {
ratio?: Decimal;
param: Omit<InitializeVaultParams, 'padding'>;
};
activationPoint?: BN;
}
): Promise<Transaction>
Parameters
connection: Connection // Solana connection instance
payer: PublicKey // Wallet paying for the transaction
tokenAMint: PublicKey // Mint address for token A
tokenBMint: PublicKey // Mint address for token B
tokenAAmount: BN // Initial amount of token A to deposit
tokenBAmount: BN // Initial amount of token B to deposit
config: PublicKey // The configuration account for the pool
opt?: { // Optional parameters
cluster?: Cluster; // The Solana cluster (mainnet, devnet, etc.)
programId?: string; // Custom program ID if different from default
lockLiquidity?: boolean; // Whether to permanently lock the initial liquidity
swapLiquidity?: { // Optional swap parameters for initial liquidity
inAmount: BN; // Amount to swap in
minAmountOut: BN; // Minimum amount to receive from swap
};
stakeLiquidity?: { // Optional stake parameters for initial liquidity
ratio?: Decimal; // Stake ratio
param: Omit<InitializeVaultParams, 'padding'>; // Stake parameters
};
activationPoint?: BN; // Activation point for the pool
}
Returns
An array of transactions that can be signed and sent to the network.
Example
// Token A/B address of the pool.
const tokenAMint = new PublicKey('...');
const tokenBMint = new PublicKey('...');
// Configuration address for the pool. It will decide the fees of the pool.
const config = new PublicKey('...');
// Amount of token A and B to be deposited to the pool.
const tokenAAmount = new BN(100_000);
const tokenBAmount = new BN(500_000);
const startTime = 'now' // const startTime = new Date('2024-12-20T15:30:00Z').toISOString();
const transactions = await AmmImpl.createPermissionlessConstantProductPoolWithConfig2(
provider.connection,
wallet.publicKey, // payer
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
config,
{
activationPoint: startTime !== 'now' ? new BN(Math.floor(new UTCDate(startTime).getTime() / 1000)) : undefined,
},
);
for (const transaction of transactions) {
transaction.sign(wallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
Notes
- Both token amounts must be greater than zero
- If using native SOL, it will be automatically wrapped to wSOL
- The
config
parameter should be a valid configuration account
- The
activationPoint
parameter is the timestamp in seconds since the Unix epoch. If you want to set it to the current time, you can use 'now'
.
createPermissionlessPool
Creates a new permissionless constant product pool.
Function
async createPermissionlessPool(
connection: Connection,
payer: PublicKey,
mintA: PublicKey,
mintB: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
isStable: boolean,
tradeFeeBps: BN,
opt?: {
programId?: string;
skipAta?: boolean;
}
): Promise<Transaction>
Parameters
connection: Connection // The Solana connection instance
payer: PublicKey // The wallet paying for the transaction
mintA: PublicKey // The mint address for token A
mintB: 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
isStable: boolean // Whether the pool is stable
tradeFeeBps: BN // Trade fee in basis points
opt?: { // Optional parameters
programId?: string; // Custom program ID if different from default
skipAta?: boolean; // Skip creating associated token account for token A
}
Returns
A transaction that can be signed and sent to the network.
Example
// Token A/B address of the pool.
const tokenAMint = new PublicKey('...');
const tokenBMint = new PublicKey('...');
const tokenADecimal = 6;
const tokenBDecimal = 6;
const feeBps = new BN(1); // 0.01%
// Get pool address
const poolPubkey = derivePoolAddress(
provider.connection,
tokenAMint,
tokenBMint,
tokenADecimal,
tokenBDecimal,
true, // stable
feeBps,
);
// Create pool
const transactions = await AmmImpl.createPermissionlessPool(
provider.connection,
wallet.publicKey, // payer
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
true, // stable,
feeBps,
);
for (const transaction of transactions) {
transaction.sign(wallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
Notes
- Both token amounts must be greater than zero
- If using native SOL, it will be automatically wrapped to wSOL
- The
tradeFeeBps
parameter is the trade fee in basis points.
- The
isStable
parameter is whether the pool is stable.
- The
skipAta
parameter is whether to skip creating associated token account for token A.
createPermissionlessConstantProductMemecoinPoolWithConfig
Creates a new permissionless constant product memecoin pool with a predefined configuration.
Function
async createPermissionlessConstantProductMemecoinPoolWithConfig(
connection: Connection,
payer: PublicKey,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
config: PublicKey,
memecoinInfo: {
isMinted?: boolean;
keypair?: Keypair;
payer?: PublicKey;
assetData?: DataV2;
mintAuthority?: PublicKey;
freezeAuthority?: PublicKey | null;
decimals?: number;
mintAmount?: BN;
},
opt?: {
cluster?: Cluster;
programId?: string;
lockLiquidity?: boolean;
swapLiquidity?: {
inAmount: BN;
minAmountOut: BN;
};
stakeLiquidity?: {
ratio?: Decimal;
};
skipAAta?: boolean;
skipBAta?: boolean;
feeVault?: {
secondsToFullUnlock: BN;
topListLength: number;
startFeeDistributeTimestamp: BN | null;
unstakeLockDuration: BN;
};
}
): Promise<Transaction>
Parameters
connection: Connection // Solana connection instance
payer: PublicKey // Wallet paying for the transaction
tokenAMint: PublicKey // Mint address for token A
tokenBMint: PublicKey // Mint address for token B
tokenAAmount: BN // Initial amount of token A to deposit
tokenBAmount: BN // Initial amount of token B to deposit
config: PublicKey // The configuration account for the pool
memecoinInfo: {
isMinted?: boolean; // Whether the memecoin is minted
keypair?: Keypair; // Keypair for the memecoin
payer?: PublicKey; // Payer for the memecoin
assetData?: DataV2; // Asset data for the memecoin
mintAuthority?: PublicKey; // Mint authority for the memecoin
freezeAuthority?: PublicKey | null; // Freeze authority for the memecoin
decimals?: number; // Decimals for the memecoin
mintAmount?: BN; // Mint amount
}
opt?: { // Optional parameters
cluster?: Cluster; // The Solana cluster (mainnet, devnet, etc.)
programId?: string; // Custom program ID if different from default
lockLiquidity?: boolean; // Whether to permanently lock the initial liquidity
swapLiquidity?: { // Optional swap parameters for initial liquidity
inAmount: BN; // Amount to swap in
minAmountOut: BN; // Minimum amount to receive from swap
};
stakeLiquidity?: { // Optional stake parameters for initial liquidity
ratio?: Decimal; // Stake ratio
};
skipAAta?: boolean; // Skip creating associated token account for token A
skipBAta?: boolean; // Skip creating associated token account for token B
feeVault?: {
secondsToFullUnlock: BN; // Seconds to full unlock
topListLength: number; // Top list length
startFeeDistributeTimestamp: BN | null; // Start fee distribute timestamp
unstakeLockDuration: BN; // Unstake lock duration
};
}
Returns
An array of transactions that can be signed and sent to the network.
Example
// Token A/B address of the pool.
const memecoinMint = new PublicKey('...');
const tokenBMint = new PublicKey('...');
const memecoinAmount = new BN(100_000);
const tokenBAmount = new BN(500_000);
// Create pool
const programId = new PublicKey(PROGRAM_ID);
const CONFIG_KEY = new PublicKey('...');
const feeConfigurations = await AmmImpl.getFeeConfigurations(provider.connection, {
programId,
});
const feeConfig = feeConfigurations.find(({ publicKey }) => publicKey.equals(CONFIG_KEY));
// Create pool
const transactions = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
provider.connection,
wallet.publicKey, // payer
memecoinMint,
tokenBMint,
memecoinAmount,
tokenBAmount,
feeConfig.publicKey,
{ isMinted: true },
);
for (const transaction of transactions) {
transaction.sign(wallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}
Notes
- Both token amounts must be greater than zero
- If using native SOL, it will be automatically wrapped to wSOL
- The
memecoinInfo
parameter is the information for the memecoin.
- The
feeVault
parameter is the information for the fee vault.
State Functions
getLpSupply
Get the total supply of the pool.
Function
async getLpSupply(): Promise<BN>
Returns
The total supply of the pool.
Example
const lpSupply = await pool.getLpSupply();
Notes
- The
pool
parameter is the instance of the pool.
getUserBalance
Get the balance of a user in the pool.
Function
async getUserBalance(owner: PublicKey): Promise<BN>
Parameters
owner: PublicKey // The owner of the pool
Returns
The balance of the user in the pool.
Example
const userLpBalance = await pool.getUserBalance(wallet.publicKey);
Notes
- The
pool
parameter is the instance of the pool.
- The
owner
parameter is the address of the user.
getSwapQuote
Get the swap quote for a given amount of token.
Function
getSwapQuote(
inTokenMint: PublicKey,
inAmountLamport: BN,
slippage: number,
swapInitiator?: PublicKey
): Promise<{
swapInAmount: BN;
swapOutAmount: BN;
minSwapOutAmount: BN;
fee: BN;
priceImpact: Decimal;
}>
Parameters
inTokenMint: PublicKey, // Mint address for the input token
inAmountLamport: BN, // Amount of input token to swap
slippage: number, // Slippage tolerance
swapInitiator?: PublicKey // Optional swap initiator
Returns
The swap quote containing the following parameters:
{
swapInAmount: BN;
swapOutAmount: BN;
minSwapOutAmount: BN;
fee: BN;
priceImpact: Decimal;
}
Example
const slippage = 0.1; // Max to 2 decimal place
const inAmountLamport = new BN(0.1 * 10 ** pool.tokenB.decimals);
const { swapInAmount, swapOutAmount, minSwapOutAmount, fee, priceImpact } = await pool.getSwapQuote(
new PublicKey(pool.tokenB.address),
inAmountLamport,
slippage, // 0.01
);
Notes
- The
inTokenMint
parameter is the mint address of the input token.
- The
inAmountLamport
parameter is the amount of input token to swap.
- The
slippage
parameter is the slippage tolerance.
- The
swapInitiator
parameter is the address of the swap initiator.
getDepositQuote
Get the deposit quote for a given amount of token.
Function
getDepositQuote(
tokenAInAmount: BN,
tokenBInAmount: BN,
balance: boolean,
slippage: number
): Promise<DepositQuote>
Parameters
tokenAInAmount: BN, // Amount of token A to deposit
tokenBInAmount: BN, // Amount of token B to deposit
balance: boolean, // Whether to use the balance of the user
slippage: number // Slippage tolerance
Returns
The deposit quote containing the following parameters:
{
poolTokenAmountOut: BN;
minPoolTokenAmountOut: BN;
tokenAInAmount: BN;
tokenBInAmount: BN;
}
Example
const balance = true;
const slippage = 0.1; // Max to 2 decimal place
const inAmountALamport = new BN(1 * 10 ** pool.tokenAMint.decimals);
const { poolTokenAmountOut, minPoolTokenAmountOut, tokenAInAmount, tokenBInAmount } = pool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
);
Notes
- The
tokenAInAmount
parameter is the amount of token A to deposit.
- The
tokenBInAmount
parameter is the amount of token B to deposit.
- The
balance
parameter is whether to use the balance of the user.
- The
slippage
parameter is the slippage tolerance.
getWithdrawQuote
Get the withdraw quote for a given amount of pool token.
Function
getWithdrawQuote(
withdrawTokenAmount: BN,
slippage: number,
tokenMint?: PublicKey
): Promise<WithdrawQuote>
Parameters
withdrawTokenAmount: BN, // Amount of pool token to withdraw
slippage: number, // Slippage tolerance
tokenMint?: PublicKey // Optional mint address for the token
Returns
The withdraw quote containing the following parameters:
{
poolTokenAmountIn: BN;
minTokenAOutAmount: BN;
minTokenBOutAmount: BN;
tokenAOutAmount: BN;
tokenBOutAmount: BN;
}
Example
const slippage = 0.1; // Max to 2 decimal place
const outTokenAmountLamport = new BN(0.1 * 10 ** pool.decimals);
const { poolTokenAmountIn, minTokenAOutAmount, minTokenBOutAmount, tokenAOutAmount, tokenBOutAmount } = pool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
);
Notes
- The
withdrawTokenAmount
parameter is the amount of pool token to withdraw.
- The
slippage
parameter is the slippage tolerance.
updateState
Update the state of the pool.
Function
Returns
No return value.
Example
await pool.updateState();
Notes
- The
pool
parameter is the instance of the pool.
Pool Functions
deposit
Deposit tokens into the pool.
Function
async deposit(
owner: PublicKey,
tokenAInAmount: BN,
tokenBInAmount: BN,
poolTokenAmount: BN,
): Promise<Transaction>
Parameters
owner: PublicKey, // The owner of the pool
tokenAInAmount: BN, // Amount of token A to deposit
tokenBInAmount: BN, // Amount of token B to deposit
poolTokenAmount: BN, // Amount of pool token to deposit
Returns
The transaction that can be signed and sent to the network.
Example
const balance = true;
const slippage = 0.1; // Max to 2 decimal place
const inAmountALamport = new BN(1 * 10 ** constantProductPool.tokenAMint.decimals);
// Get deposit quote
const { poolTokenAmountOut, tokenAInAmount, tokenBInAmount } = pool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
);
const depositTx = await pool.deposit(
wallet.publicKey,
tokenAInAmount,
tokenBInAmount,
poolTokenAmountOut,
);
const depositResult = await provider.sendAndConfirm(depositTx);
Notes
- The
owner
parameter is the address of the owner.
- The
tokenAInAmount
parameter is the amount of token A to deposit.
- The
tokenBInAmount
parameter is the amount of token B to deposit.
- The
poolTokenAmount
parameter is the amount of pool token to deposit.
withdraw
Withdraw tokens from the pool.
Function
async withdraw(
owner: PublicKey,
lpTokenAmount: BN,
tokenAOutAmount: BN,
tokenBOutAmount: BN,
): Promise<Transaction>
Parameters
owner: PublicKey, // The owner of the pool
lpTokenAmount: BN, // Amount of pool token to withdraw
tokenAOutAmount: BN, // Amount of token A to withdraw
tokenBOutAmount: BN, // Amount of token B to withdraw
Returns
The transaction that can be signed and sent to the network.
Example
const slippage = 0.1;
const outTokenAmountLamport = new BN(0.1 * 10 ** pool.decimals);
const { poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount } = pool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
);
const withdrawTx = await pool.withdraw(
wallet.publicKey,
poolTokenAmountIn,
tokenAOutAmount,
tokenBOutAmount,
);
const withdrawResult = await provider.sendAndConfirm(withdrawTx);
Notes
- The
owner
parameter is the address of the owner.
- The
lpTokenAmount
parameter is the amount of pool token to withdraw.
- The
tokenAOutAmount
parameter is the amount of token A to withdraw.
- The
tokenBOutAmount
parameter is the amount of token B to withdraw.
swap
Swap tokens in the pool.
Function
async swap(
owner: PublicKey,
inTokenMint: PublicKey,
inAmountLamport: BN,
outAmountLamport: BN,
referralOwner?: PublicKey,
): Promise<Transaction>
Parameters
owner: PublicKey, // The owner of the pool
inTokenMint: PublicKey, // Mint address for the input token
inAmountLamport: BN, // Amount of input token to swap
outAmountLamport: BN, // Amount of output token to receive
referralOwner?: PublicKey // Optional referral owner
Returns
The transaction that can be signed and sent to the network.
Example
const slippage = 0.1;
const inAmountLamport = new BN(0.1 * 10 ** pool.tokenB.decimals);
const { minSwapOutAmount } = pool.getSwapQuote(
new PublicKey(pool.tokenB.address),
inAmountLamport,
slippage,
);
const swapTx = await pool.swap(
mockWallet.publicKey,
new PublicKey(pool.tokenB.address),
inAmountLamport,
minSwapOutAmount,
);
const swapResult = await provider.sendAndConfirm(swapTx);
Notes
- The
owner
parameter is the address of the owner.
- The
inTokenMint
parameter is the mint address of the input token.
- The
inAmountLamport
parameter is the amount of input token to swap.
- The
outAmountLamport
parameter is the amount of output token to receive.
- The
referralOwner
parameter is the address of the referral owner.