@meteora-ag/dynamic-amm-sdk v1.3.8
Meteora Dynamic AMM SDK
Getting started
NPM: https://www.npmjs.com/package/@meteora-ag/dynamic-amm-sdk
SDK: https://github.com/MeteoraAg/dynamic-amm-sdk
Discord: https://discord.com/channels/841152225564950528/864859354335412224
Installation
# NPM
npm i @meteora-ag/dynamic-amm-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
# YARN
yarn add @meteora-ag/dynamic-amm-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
# Or, use any package manager of your choice.Pool Types
The Dynamic AMM SDK supports three types of pools:
Constant Product Pool (Volatile Pool)
Memecoin Pool (M3M3 Pool)
Stable Pool
Usage Examples
Initialize AmmImpl instance
import AmmImpl, { MAINNET_POOL } from '@meteora-ag/dynamic-amm-sdk';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
// Connection, Wallet, and AnchorProvider to interact with the network
const mainnetConnection = new Connection('https://api.mainnet-beta.solana.com');
const mockWallet = new Wallet(new Keypair());
const provider = new AnchorProvider(mainnetConnection, mockWallet, {
commitment: 'confirmed',
});
// Alternatively, to use Solana Wallet Adapter
// Create single instance
const constantProductPool = await AmmImpl.create(mainnetConnection, MAINNET_POOL.USDC_SOL);
const stablePool = await AmmImpl.create(mainnetConnection, MAINNET_POOL.USDT_USDC);
// Or with any other pool address, refer to the pool creation section below
const pool = await AmmImpl.create(mainnetConnection, new PublicKey('...'));
// If you need to create multiple, can consider using `createMultiple`
const pools = [MAINNET_POOL.USDC_SOL, MAINNET_POOL.USDT_USDC];
const [constantProductPool, stablePool] = await AmmImpl.createMultiple(mainnetConnection, pools);Creating New Pools
Note: If the Dynamic AMM Pool is being launched with an Alpha Vault, SOL or USDC must be used as the quote token.
1. Create Constant Product Pool
import AmmImpl, { PROGRAM_ID } from '@meteora-ag/dynamic-amm-sdk';
import { derivePoolAddressWithConfig } from '@meteora-ag/dynamic-amm-sdk/dist/cjs/src/amm/utils';
import { BN } from 'bn.js';
// 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);
// Get pool address
const programId = new PublicKey(PROGRAM_ID);
const poolPubkey = derivePoolAddressWithConfig(tokenAMint, tokenBMint, config, programId);
// Create pool
const transactions = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
provider.connection,
mockWallet.publicKey, // payer
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
config,
);
// Or if you need to set the activation point earlier than the default derived from the config
const startTime = '...';
const transactions = await AmmImpl.createPermissionlessConstantProductPoolWithConfig2(
provider.connection,
mockWallet.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(mockWallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}2. Create Stable Pool
import AmmImpl, { derivePoolAddress } from '@meteora-ag/dynamic-amm-sdk';
import { BN } from 'bn.js';
// 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,
mockWallet.publicKey, // payer
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
true, // stable,
feeBps,
);
for (const transaction of transactions) {
transaction.sign(mockWallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}3. Create Memecoin Pool
import AmmImpl, { PROGRAM_ID } from '@meteora-ag/dynamic-amm-sdk';
import { derivePoolAddressWithConfig } from '@meteora-ag/dynamic-amm-sdk/dist/cjs/src/amm/utils';
import { BN } from 'bn.js';
import { roundToNearestMinutes } from 'date-fns';
// 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);
// Get pool address
const poolAddress = derivePoolAddressWithConfig(memecoinMint, tokenBMint, feeConfig.publicKey, programId);
// Create pool
const programId = new PublicKey(PROGRAM_ID);
const isNow = true;
const CONFIG_KEY = new PublicKey('..');
const feeConfigurations = await AmmImpl.getFeeConfigurations(provider.connection, {
programId,
});
const feeConfig = feeConfigurations.find(({ publicKey }) => publicKey.equals(CONFIG_KEY));
const transactions = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
provider.connection,
mockWallet.publicKey, // payer
memecoinMint,
tokenBMint,
memecoinAmount,
tokenBAmount,
feeConfig.publicKey,
{ isMinted: true },
);
// with M3M3 vault
const feeDurationInDays = 7;
const numOfStakers = 1000;
const feeClaimStartTime = roundToNearestMinutes(new Date(), {
nearestTo: 30,
});
const cooldownDurationInHours = 6;
const transactions = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
provider.connection,
mockWallet.publicKey, // payer
memecoinMint,
tokenBMint,
memecoinAmount,
tokenBAmount,
feeConfig.publicKey,
{ isMinted: true },
{
feeVault: {
secondsToFullUnlock: feeDurationInDays ? new BN(feeDurationInDays * 86400) : new BN(0),
topListLength: numOfStakers || 0,
startFeeDistributeTimestamp: feeClaimStartTime ? new BN(feeClaimStartTime.getTime() / 1000) : null,
unstakeLockDuration: cooldownDurationInHours ? new BN(cooldownDurationInHours * 3600) : new BN(0),
},
// other options
},
);
for (const transaction of transactions) {
transaction.sign(mockWallet.payer);
const txHash = await provider.connection.sendRawTransaction(transaction.serialize());
await provider.connection.confirmTransaction(txHash, 'finalized');
console.log('transaction %s', txHash);
}Note: For Alpha Vault integration, please refer to Create Dynamic Pool With Permissionless Alpha Vault.
Common Operations
Get Lp Supply
// To refetch the pool's latest supply
// Alternatively, use `AmmImpl.poolState.lpSupply`
const lpSupply = await pool.getLpSupply();Check Pool Balance
// Get the user's ATA LP balance
const userLpBalance = await pool.getUserBalance(mockWallet.publicKey);Update Pool State (It's recommended to update the deposit before perform any quotation)
await pool.updateState();Constant Product Pool Operations
Deposit
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 } = constantProductPool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
);
const depositTx = await constantProductPool.deposit(
mockWallet.publicKey,
tokenAInAmount,
tokenBInAmount,
poolTokenAmountOut,
); // Web3 Transaction Object
const depositResult = await provider.sendAndConfirm(depositTx); // Transaction hashWithdraw
const slippage = 0.1; // Max to 2 decimal place
const outTokenAmountLamport = new BN(0.1 * 10 ** constantProductPool.decimals);
const { poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount } = constantProductPool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
); // use lp balance for full withdrawal
const withdrawTx = await constantProductPool.withdraw(
mockWallet.publicKey,
poolTokenAmountIn,
tokenAOutAmount,
tokenBOutAmount,
); // Web3 Transaction Object
const withdrawResult = await provider.sendAndConfirm(withdrawTx); // Transaction hashSwap
const slippage = 0.1; // Max to 2 decimal place
const inAmountLamport = new BN(0.1 * 10 ** constantProductPool.tokenB.decimals);
const { minSwapOutAmount } = constantProductPool.getSwapQuote(
new PublicKey(constantProductPool.tokenB.address),
inAmountLamport,
slippage,
);
const swapTx = await constantProductPool.swap(
mockWallet.publicKey,
new PublicKey(constantProductPool.tokenB.address),
inAmountLamport,
minSwapOutAmount,
);
const swapResult = await provider.sendAndConfirm(swapTx);Stable Pool Operations
Balanced Deposit
const slippage = 0.1; // Max to 2 decimal place
const balance = true;
const inAmountALamport = new BN(0.1 * 10 ** stablePool.tokenA.decimals);
const { poolTokenAmountOut, tokenAInAmount, tokenBInAmount } = stablePool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
);
const depositTx = await stablePool.deposit(mockWallet.publicKey, tokenAInAmount, tokenBInAmount, poolTokenAmountOut); // Web3 Transaction Object
const depositResult = await provider.sendAndConfirm(depositTx); // Transaction hashDouble Side Imbalance Deposit
const slippage = 0.1; // Max to 2 decimal place
const balance = false;
const inAmountALamport = new BN(0.1 * 10 ** stablePool.tokenA.decimals);
const inAmountBLamport = new BN(0.1 * 10 ** stablePool.tokenB.decimals);
const { poolTokenAmountOut, tokenAInAmount, tokenBInAmount } = stablePool.getDepositQuote(
inAmountALamport,
inAmountBLamport,
balance,
slippage,
); // Web3 Transaction Object
const depositTx = await stablePool.deposit(mockWallet.publicKey, tokenAInAmount, tokenBInAmount, poolTokenAmountOut);
const depositResult = await provider.sendAndConfirm(depositTx); // Transaction hashSingle Side Imbalance Deposit
const slippage = 0.1; // Max to 2 decimal place
const balance = false;
const inAmountALamport = new BN(0.1 * 10 ** stablePool.tokenA.decimals);
const { poolTokenAmountOut, tokenAInAmount, tokenBInAmount } = stablePool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
); // Web3 Transaction Object
const depositTx = await stablePool.deposit(mockWallet.publicKey, tokenAInAmount, tokenBInAmount, poolTokenAmountOut);
const depositResult = await provider.sendAndConfirm(depositTx); // Transaction hashBalanced Withdraw
const slippage = 0.1; // Max to 2 decimal place
const outTokenAmountLamport = new BN(0.1 * 10 ** stablePool.decimals);
const { poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount } = stablePool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
); // use lp balance for full withdrawal
const withdrawTx = await stablePool.withdraw(mockWallet.publicKey, poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount); // Web3 Transaction Object
const withdrawResult = await provider.sendAndConfirm(withdrawTx);Imbalanced Withdraw
const slippage = 0.1; // Max to 2 decimal place
const outTokenAmountLamport = new BN(0.1 * 10 ** stablePool.decimals);
const { poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount } = stablePool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
new PublicKey(stablePool.tokenA.address), // Pass in token A/B mint to perform imbalanced withdraw
);
const withdrawTx = await stablePool.withdraw(mockWallet.publicKey, poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount); // Web3 Transaction Object
const withdrawResult = await provider.sendAndConfirm(withdrawTx);Swap
const slippage = 0.1; // Max to 2 decimal place
const inAmountLamport = new BN(0.1 * 10 ** stablePool.tokenB.decimals);
const { minSwapOutAmount } = stablePool.getSwapQuote(
new PublicKey(stablePool.tokenB.address),
inAmountLamport,
slippage,
);
const swapTx = await stablePool.swap(
mockWallet.publicKey,
new PublicKey(stablePool.tokenB.address),
inAmountLamport,
minSwapOutAmount,
);
const swapResult = await provider.sendAndConfirm(swapTx);Memecoin Pool Operations
Deposit
const balance = true;
const slippage = 0.1; // Max to 2 decimal place
const inAmountALamport = new BN(1 * 10 ** memecoinPool.tokenA.decimals);
// Get deposit quote for constant product
const { poolTokenAmountOut, tokenAInAmount, tokenBInAmount } = memecoinPool.getDepositQuote(
inAmountALamport,
new BN(0),
balance,
slippage,
);
const depositTx = await memecoinPool.deposit(mockWallet.publicKey, tokenAInAmount, tokenBInAmount, poolTokenAmountOut); // Web3 Transaction Object
const depositResult = await provider.sendAndConfirm(depositTx); // Transaction hashWithdraw
const slippage = 0.1; // Max to 2 decimal place
const outTokenAmountLamport = new BN(0.1 * 10 ** memecoinPool.decimals);
const { poolTokenAmountIn, tokenAOutAmount, tokenBOutAmount } = memecoinPool.getWithdrawQuote(
outTokenAmountLamport,
slippage,
); // use lp balance for full withdrawal
const withdrawTx = await memecoinPool.withdraw(
mockWallet.publicKey,
poolTokenAmountIn,
tokenAOutAmount,
tokenBOutAmount,
); // Web3 Transaction Object
const withdrawResult = await provider.sendAndConfirm(withdrawTx); // Transaction hashSwap
const slippage = 0.1; // Max to 2 decimal place
const inAmountLamport = new BN(0.1 * 10 ** memecoinPool.tokenB.decimals);
const { minSwapOutAmount } = memecoinPool.getSwapQuote(
new PublicKey(memecoinPool.tokenB.address),
inAmountLamport,
slippage,
);
const swapTx = await memecoinPool.swap(
mockWallet.publicKey,
new PublicKey(memecoinPool.tokenB.address),
inAmountLamport,
minSwapOutAmount,
);
const swapResult = await provider.sendAndConfirm(swapTx);9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago