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

updateState()

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.