| name | meteora |
| description | Complete Meteora DeFi SDK suite for building liquidity pools, AMMs, bonding curves, vaults, token launches, and zap operations on Solana. Use when integrating DLMM, DAMM v2, DAMM v1, Dynamic Bonding Curves, Alpha Vaults, Zap, or Stake-for-Fee functionality. |
Meteora Protocol Development Guide
A comprehensive guide for building Solana DeFi applications with Meteora's suite of SDKs - the leading liquidity infrastructure on Solana.
What is Meteora?
Meteora is Solana's premier liquidity layer, powering the infrastructure that connects liquidity providers (LPs), token launchers, and traders. It offers:
- $2B+ Total Value Locked across all protocols
- Multiple AMM Types - DLMM (concentrated), DAMM v2/v1 (constant product)
- Token Launch Infrastructure - Dynamic Bonding Curves, Alpha Vault anti-bot protection
- Yield Optimization - Dynamic Vaults, Stake-for-Fee (M3M3)
- Developer Tools - TypeScript/Go SDKs, CLI tools, Zap for single-token entry
Why Use Meteora?
| Feature | Benefit |
|---|
| Low Pool Creation Cost | 0.022 SOL (vs 0.25+ SOL on competitors) |
| Dynamic Fees | Volatility-adjusted fees maximize LP returns |
| Anti-Snipe Protection | Fee schedulers and Alpha Vault prevent bot exploitation |
| Token-2022 Support | Full Token Extensions compatibility |
| Permissionless | Create pools, farms, and launches without approval |
| Auto-Graduation | Bonding curves auto-migrate to AMM pools |
Overview
Meteora provides a complete DeFi infrastructure stack on Solana:
- DLMM (Dynamic Liquidity Market Maker): Concentrated liquidity with dynamic fees
- DAMM v2 (Dynamic AMM): Next-generation constant product AMM with position NFTs
- DAMM v1 (Legacy AMM): Original constant product AMM with stable/weighted pools
- Dynamic Bonding Curve: Customizable token launch curves with auto-graduation
- Dynamic Vault: Yield-optimized token vaults
- Alpha Vault: Anti-bot protection for token launches
- Stake-for-Fee (M3M3): Staking rewards from trading fees
- Zap SDK: Single-token entry/exit for liquidity positions
- Presale Vault (Beta): Token presale infrastructure
Quick Start
Installation
npm install @meteora-ag/dlmm @coral-xyz/anchor @solana/web3.js
npm install @meteora-ag/cp-amm-sdk @solana/web3.js
npm install @meteora-ag/dynamic-amm @solana/web3.js @coral-xyz/anchor
npm install @meteora-ag/dynamic-bonding-curve-sdk
npm install @meteora-ag/vault-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
npm install @meteora-ag/alpha-vault
npm install @meteora-ag/m3m3 @coral-xyz/anchor @solana/web3.js @solana/spl-token
npm install @meteora-ag/zap-sdk
npm install @meteora-ag/farming
Program Addresses
| Program | Mainnet/Devnet Address |
|---|
| DLMM | LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo |
| DAMM v2 | cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG |
| DAMM v1 | Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB |
| Dynamic Bonding Curve | dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN |
| Dynamic Vault | 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi |
| Stake-for-Fee | FEESngU3neckdwib9X3KWqdL7Mjmqk9XNp3uh5JbP4KP |
| Zap | zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz |
DLMM SDK (Dynamic Liquidity Market Maker)
The DLMM SDK provides programmatic access to Meteora's concentrated liquidity protocol with dynamic fees based on volatility.
Basic Setup
import { Connection, PublicKey, Keypair } from '@solana/web3.js';
import DLMM from '@meteora-ag/dlmm';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const poolAddress = new PublicKey('POOL_ADDRESS');
const dlmm = await DLMM.create(connection, poolAddress);
const dlmmPools = await DLMM.createMultiple(connection, [pool1, pool2, pool3]);
Core Operations
Get Active Bin (Current Price)
const activeBin = await dlmm.getActiveBin();
console.log('Active Bin ID:', activeBin.binId);
console.log('Price:', activeBin.price);
console.log('X Amount:', activeBin.xAmount.toString());
console.log('Y Amount:', activeBin.yAmount.toString());
Price and Bin Conversions
const price = dlmm.getPriceOfBinByBinId(binId);
const binId = dlmm.getBinIdFromPrice(price, true);
const lamportPrice = dlmm.toPricePerLamport(21.23);
const realPrice = dlmm.fromPricePerLamport(lamportPrice);
const bins = await dlmm.getBinsBetweenLowerAndUpperBound(minBinId, maxBinId);
const surroundingBins = await dlmm.getBinsAroundActiveBin(10);
Swap Operations
import { BN } from '@coral-xyz/anchor';
const swapAmount = new BN(1_000_000);
const swapForY = true;
const slippageBps = 100;
const binArrays = await dlmm.getBinArrayForSwap(swapForY);
const swapQuote = dlmm.swapQuote(swapAmount, swapForY, slippageBps, binArrays);
console.log('Amount In:', swapQuote.consumedInAmount.toString());
console.log('Amount Out:', swapQuote.outAmount.toString());
console.log('Min Amount Out:', swapQuote.minOutAmount.toString());
console.log('Price Impact:', swapQuote.priceImpact);
console.log('Fee:', swapQuote.fee.toString());
const swapTx = await dlmm.swap({
inToken: tokenXMint,
outToken: tokenYMint,
inAmount: swapAmount,
minOutAmount: swapQuote.minOutAmount,
lbPair: dlmm.pubkey,
user: wallet.publicKey,
binArraysPubkey: swapQuote.binArraysPubkey,
});
const txHash = await sendAndConfirmTransaction(connection, swapTx, [wallet]);
Liquidity Management
import { StrategyType } from '@meteora-ag/dlmm';
const positions = await dlmm.getPositionsByUserAndLbPair(wallet.publicKey);
const newPositionTx = await dlmm.initializePositionAndAddLiquidityByStrategy({
positionPubKey: newPositionKeypair.publicKey,
user: wallet.publicKey,
totalXAmount: new BN(100_000_000),
totalYAmount: new BN(100_000_000),
strategy: {
maxBinId: activeBin.binId + 10,
minBinId: activeBin.binId - 10,
strategyType: StrategyType.SpotBalanced,
},
});
const addLiquidityTx = await dlmm.addLiquidityByStrategy({
positionPubKey: existingPosition.publicKey,
user: wallet.publicKey,
totalXAmount: new BN(50_000_000),
totalYAmount: new BN(50_000_000),
strategy: {
maxBinId: activeBin.binId + 5,
minBinId: activeBin.binId - 5,
strategyType: StrategyType.SpotBalanced,
},
});
const removeLiquidityTx = await dlmm.removeLiquidity({
position: position.publicKey,
user: wallet.publicKey,
binIds: position.positionData.positionBinData.map(b => b.binId),
bps: new BN(10000),
shouldClaimAndClose: true,
});
Claim Fees and Rewards
const claimableFees = await DLMM.getClaimableSwapFee(connection, position.publicKey);
console.log('Claimable Fee X:', claimableFees.feeX.toString());
console.log('Claimable Fee Y:', claimableFees.feeY.toString());
const claimableRewards = await DLMM.getClaimableLMReward(connection, position.publicKey);
const claimFeeTx = await dlmm.claimSwapFee({
owner: wallet.publicKey,
position: position.publicKey,
});
const claimAllFeesTx = await dlmm.claimAllSwapFee({
owner: wallet.publicKey,
positions: positions.map(p => p.publicKey),
});
const claimRewardTx = await dlmm.claimLMReward({
owner: wallet.publicKey,
position: position.publicKey,
});
const claimAllTx = await dlmm.claimAllRewards({
owner: wallet.publicKey,
positions: positions.map(p => p.publicKey),
});
Position Strategies
import { StrategyType } from '@meteora-ag/dlmm';
StrategyType.SpotOneSide
StrategyType.CurveOneSide
StrategyType.BidAskOneSide
StrategyType.SpotBalanced
StrategyType.CurveBalanced
StrategyType.BidAskBalanced
StrategyType.SpotImBalanced
StrategyType.CurveImBalanced
StrategyType.BidAskImBalanced
DAMM v2 SDK (CP-AMM)
The DAMM v2 SDK provides a comprehensive interface for Meteora's next-generation constant product AMM with significant improvements over V1.
Key DAMM V2 Features (New in 2025)
| Feature | Description |
|---|
| Dynamic Fees | Optional fee scheduler with anti-sniper mechanism |
| Position NFTs | LPs receive transferrable NFT instead of LP token |
| Token2022 Support | Full support for Token Extensions standard |
| Locked Liquidity | Built-in liquidity locking options |
| Permissionless Farms | Create farms without protocol approval |
| Lower Costs | Pool creation costs only 0.022 SOL (vs 0.25 SOL on old DLMM) |
Fee Scheduler (Anti-Snipe)
The fee scheduler starts with high swap fees that taper over time, protecting against sniping:
const createPoolTx = await cpAmm.createCustomPool({
poolFees: {
baseFee: {
cliffFeeNumerator: new BN(10000000),
numberOfPeriod: 10,
reductionFactor: new BN(500000),
periodFrequency: new BN(300),
feeSchedulerMode: 1,
},
},
});
Basic Setup
import { Connection } from '@solana/web3.js';
import { CpAmm } from '@meteora-ag/cp-amm-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const cpAmm = new CpAmm(connection);
Pool Management
Create Pool
const createPoolTx = await cpAmm.createPool({
creator: wallet.publicKey,
configAddress: configPubkey,
tokenAMint,
tokenBMint,
tokenAAmount: new BN(1_000_000_000),
tokenBAmount: new BN(1_000_000_000),
});
const createCustomPoolTx = await cpAmm.createCustomPool({
creator: wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount: new BN(1_000_000_000),
tokenBAmount: new BN(1_000_000_000),
poolFees: {
baseFee: {
cliffFeeNumerator: new BN(2500000),
numberOfPeriod: 0,
reductionFactor: new BN(0),
periodFrequency: new BN(0),
feeSchedulerMode: 0,
},
dynamicFee: null,
protocolFeePercent: 20,
partnerFeePercent: 0,
referralFeePercent: 20,
dynamicFeeConfig: null,
},
hasAlphaVault: false,
activationType: 0,
activationPoint: null,
collectFeeMode: 0,
});
Fetch Pool State
const poolState = await cpAmm.fetchPoolState(poolAddress);
console.log('Token A Vault:', poolState.tokenAVault.toString());
console.log('Token B Vault:', poolState.tokenBVault.toString());
console.log('Sqrt Price:', poolState.sqrtPrice.toString());
console.log('Liquidity:', poolState.liquidity.toString());
const allPools = await cpAmm.getAllPools();
const exists = await cpAmm.isPoolExist(tokenAMint, tokenBMint);
Position Operations
Create and Manage Positions
const createPositionTx = await cpAmm.createPosition({
owner: wallet.publicKey,
pool: poolAddress,
});
const addLiquidityTx = await cpAmm.addLiquidity({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
tokenAAmountIn: new BN(100_000_000),
tokenBAmountIn: new BN(100_000_000),
liquidityMin: new BN(0),
});
const depositQuote = cpAmm.getDepositQuote({
poolState,
tokenAAmount: new BN(100_000_000),
tokenBAmount: new BN(100_000_000),
slippageBps: 100,
});
const removeLiquidityTx = await cpAmm.removeLiquidity({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
liquidityAmount: new BN(50_000_000),
tokenAAmountMin: new BN(0),
tokenBAmountMin: new BN(0),
});
const withdrawQuote = cpAmm.getWithdrawQuote({
poolState,
positionState,
liquidityAmount: new BN(50_000_000),
slippageBps: 100,
});
const mergePositionTx = await cpAmm.mergePosition({
owner: wallet.publicKey,
pool: poolAddress,
sourcePositions: [position1, position2],
destinationPosition: destPosition,
});
const splitPositionTx = await cpAmm.splitPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
percentage: 50,
newPosition: newPositionKeypair.publicKey,
});
Swapping
import { SwapMode } from '@meteora-ag/cp-amm-sdk';
SwapMode.ExactIn
SwapMode.ExactOut
SwapMode.PartialFill
const quote = cpAmm.getQuote({
poolState,
inputTokenMint: tokenAMint,
outputTokenMint: tokenBMint,
amount: new BN(1_000_000),
slippageBps: 100,
swapMode: SwapMode.ExactIn,
});
console.log('Input Amount:', quote.inputAmount.toString());
console.log('Output Amount:', quote.outputAmount.toString());
console.log('Min Output:', quote.minimumOutputAmount.toString());
console.log('Price Impact:', quote.priceImpact);
console.log('Fee:', quote.fee.toString());
const swapTx = await cpAmm.swap({
payer: wallet.publicKey,
pool: poolAddress,
inputTokenMint: tokenAMint,
outputTokenMint: tokenBMint,
amountIn: new BN(1_000_000),
minimumAmountOut: quote.minimumOutputAmount,
referralAccount: null,
});
Fee and Reward Management
const claimFeeTx = await cpAmm.claimPositionFee({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
});
const initRewardTx = await cpAmm.initializeReward({
pool: poolAddress,
rewardMint,
rewardDuration: new BN(86400 * 7),
funder: wallet.publicKey,
});
const fundRewardTx = await cpAmm.fundReward({
pool: poolAddress,
rewardMint,
amount: new BN(1_000_000_000),
funder: wallet.publicKey,
});
const claimRewardTx = await cpAmm.claimReward({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
rewardIndex: 0,
});
Position Locking and Vesting
const lockPositionTx = await cpAmm.lockPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
vestingDuration: new BN(86400 * 30),
cliffDuration: new BN(86400 * 7),
});
const permanentLockTx = await cpAmm.permanentLockPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
liquidityAmount: new BN(50_000_000),
});
const refreshVestingTx = await cpAmm.refreshVesting({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
});
const isLocked = cpAmm.isLockedPosition(positionState);
Helper Functions
const price = cpAmm.getPriceFromSqrtPrice(sqrtPrice, tokenADecimals, tokenBDecimals);
const sqrtPrice = cpAmm.getSqrtPriceFromPrice(price, tokenADecimals, tokenBDecimals);
const feeNumerator = cpAmm.bpsToFeeNumerator(25);
const bps = cpAmm.feeNumeratorToBps(feeNumerator);
const minAmount = cpAmm.getAmountWithSlippage(amount, slippageBps, false);
const maxAmount = cpAmm.getMaxAmountWithSlippage(amount, slippageBps);
const priceImpact = cpAmm.getPriceImpact(amountIn, amountOut, currentPrice);
const liquidityDelta = cpAmm.getLiquidityDelta({
poolState,
tokenAAmount: new BN(100_000_000),
tokenBAmount: new BN(100_000_000),
});
Dynamic Bonding Curve SDK
The Dynamic Bonding Curve SDK enables building customizable token launches with automatic graduation to DAMM.
Basic Setup
import { Connection } from '@solana/web3.js';
import { DynamicBondingCurve } from '@meteora-ag/dynamic-bonding-curve-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const dbc = new DynamicBondingCurve(connection, 'confirmed');
Token Launch Flow
The DBC follows a 5-step progression:
- Partner Configuration: Set up pool parameters
- Pool Creation: Creator launches the bonding curve
- Trading Phase: Users buy/sell on the curve
- Graduation: Auto-migrate to DAMM v1 or v2 when threshold is met
- Post-Graduation: Trade on the graduated AMM
Create Pool with Bonding Curve
const createPoolTx = await dbc.createPool({
creator: wallet.publicKey,
baseMint: baseTokenMint,
quoteMint: quoteTokenMint,
config: configAddress,
baseAmount: new BN(1_000_000_000_000),
quoteAmount: new BN(0),
name: 'My Token',
symbol: 'MTK',
uri: 'https://arweave.net/metadata.json',
});
Trading on Bonding Curve
const buyQuote = await dbc.getBuyQuote({
pool: poolAddress,
quoteAmount: new BN(1_000_000_000),
});
console.log('Tokens to receive:', buyQuote.baseAmount.toString());
console.log('Price per token:', buyQuote.price.toString());
const buyTx = await dbc.buy({
payer: wallet.publicKey,
pool: poolAddress,
quoteAmount: new BN(1_000_000_000),
minBaseAmount: buyQuote.minBaseAmount,
});
const sellQuote = await dbc.getSellQuote({
pool: poolAddress,
baseAmount: new BN(1_000_000),
});
const sellTx = await dbc.sell({
payer: wallet.publicKey,
pool: poolAddress,
baseAmount: new BN(1_000_000),
minQuoteAmount: sellQuote.minQuoteAmount,
});
Pool Graduation
const poolState = await dbc.fetchPoolState(poolAddress);
const isGraduated = poolState.graduated;
const graduationThreshold = poolState.graduationThreshold;
const currentMarketCap = poolState.currentMarketCap;
const migrateTx = await dbc.migrateToDAMMV2({
pool: poolAddress,
payer: wallet.publicKey,
});
const createMetadataTx = await dbc.createMetadata({
pool: poolAddress,
payer: wallet.publicKey,
});
const migrateToDammV1Tx = await dbc.migrateToDAMMV1({
pool: poolAddress,
payer: wallet.publicKey,
});
const lockLpTx = await dbc.lockLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
lockDuration: new BN(86400 * 365),
});
const claimLpTx = await dbc.claimLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
});
Fee Configuration Options
The DBC supports multiple fee tier configurations:
| Tier | Fee (bps) | Use Case |
|---|
| 1 | 25 | Standard launches |
| 2 | 50 | Community tokens |
| 3 | 100 | Meme tokens |
| 4 | 200 | High volatility |
| 5 | 400 | Experimental |
| 6 | 600 | Maximum protection |
Dynamic Vault SDK
The Vault SDK provides yield-optimized token storage with automatic strategy management.
Basic Setup
import { Connection, PublicKey } from '@solana/web3.js';
import { VaultImpl } from '@meteora-ag/vault-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const tokenMint = new PublicKey('TOKEN_MINT_ADDRESS');
const vault = await VaultImpl.create(connection, tokenMint);
const vaultWithAffiliate = await VaultImpl.create(connection, tokenMint, {
affiliateId: new PublicKey('PARTNER_KEY'),
});
Vault Operations
const lpSupply = vault.lpSupply;
const withdrawableAmount = await vault.getWithdrawableAmount();
console.log('Total LP Supply:', lpSupply.toString());
console.log('Locked Amount:', withdrawableAmount.locked.toString());
console.log('Unlocked Amount:', withdrawableAmount.unlocked.toString());
const userLpBalance = await vault.getUserBalance(wallet.publicKey);
const depositTx = await vault.deposit(wallet.publicKey, new BN(1_000_000_000));
await sendAndConfirmTransaction(connection, depositTx, [wallet]);
const withdrawTx = await vault.withdraw(wallet.publicKey, new BN(500_000_000));
await sendAndConfirmTransaction(connection, withdrawTx, [wallet]);
Share Calculations
import { getAmountByShare, getUnmintAmount } from '@meteora-ag/vault-sdk';
const underlyingAmount = getAmountByShare(
userLpBalance,
unlockedAmount,
lpSupply
);
const lpNeeded = getUnmintAmount(
targetWithdrawAmount,
unlockedAmount,
lpSupply
);
Affiliate Integration
const affiliateInfo = await vault.getAffiliateInfo();
console.log('Partner:', affiliateInfo.partner.toString());
console.log('Fee Rate:', affiliateInfo.feeRate);
console.log('Outstanding Fee:', affiliateInfo.outstandingFee.toString());
Alpha Vault SDK
The Alpha Vault SDK provides anti-bot protection for token launches, ensuring fair distribution.
Basic Setup
import { Connection, PublicKey } from '@solana/web3.js';
import { AlphaVault } from '@meteora-ag/alpha-vault';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const vaultAddress = new PublicKey('VAULT_ADDRESS');
const alphaVault = await AlphaVault.create(connection, vaultAddress);
Vault Operations
const vaultState = await alphaVault.getVaultState();
console.log('Total Deposited:', vaultState.totalDeposited.toString());
console.log('Max Deposit:', vaultState.maxDeposit.toString());
console.log('Start Time:', vaultState.startTime.toString());
console.log('End Time:', vaultState.endTime.toString());
const depositTx = await alphaVault.deposit({
payer: wallet.publicKey,
amount: new BN(1_000_000_000),
});
const withdrawTx = await alphaVault.withdraw({
payer: wallet.publicKey,
amount: new BN(500_000_000),
});
const claimTx = await alphaVault.claimTokens({
payer: wallet.publicKey,
});
const allocation = await alphaVault.getUserAllocation(wallet.publicKey);
console.log('Deposit Amount:', allocation.depositAmount.toString());
console.log('Token Allocation:', allocation.tokenAllocation.toString());
console.log('Claimed:', allocation.claimed);
Stake-for-Fee SDK (M3M3)
The M3M3 SDK enables staking tokens to earn fees from trading activity.
Basic Setup
import { Connection, PublicKey } from '@solana/web3.js';
import { StakeForFee } from '@meteora-ag/m3m3';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const poolAddress = new PublicKey('POOL_ADDRESS');
const m3m3 = await StakeForFee.create(connection, poolAddress);
Staking Operations
const userBalance = await m3m3.getUserStakeAndClaimBalance(wallet.publicKey);
console.log('Staked Amount:', userBalance.stakedAmount.toString());
console.log('Claimable Fees:', userBalance.claimableFees.toString());
const stakeTx = await m3m3.stake(new BN(1_000_000_000), wallet.publicKey);
await sendAndConfirmTransaction(connection, stakeTx, [wallet]);
const claimTx = await m3m3.claimFee(wallet.publicKey, null);
await sendAndConfirmTransaction(connection, claimTx, [wallet]);
const unstakeTx = await m3m3.unstake(
new BN(500_000_000),
destinationTokenAccount,
wallet.publicKey
);
const cancelUnstakeTx = await m3m3.cancelUnstake(escrowAddress, wallet.publicKey);
const withdrawTx = await m3m3.withdraw(escrowAddress, wallet.publicKey);
const unstakePeriod = m3m3.getUnstakePeriod();
await m3m3.refreshStates();
DAMM v1 SDK (Legacy Dynamic AMM)
The DAMM v1 SDK is the original constant product AMM, still widely used for stable pools, weighted pools, and LST pools. While DAMM v2 is recommended for new pools, v1 remains fully supported.
Basic Setup
import { Connection, PublicKey, Keypair } from '@solana/web3.js';
import AmmImpl from '@meteora-ag/dynamic-amm';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const pool = await AmmImpl.create(connection, new PublicKey('POOL_ADDRESS'));
const pools = await AmmImpl.createMultiple(connection, [poolAddress1, poolAddress2]);
Pool Creation
const createPoolTx = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress,
{
lockLiquidity: false,
activationPoint: null,
}
);
const memePoolTx = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress,
{
lockLiquidity: true,
}
);
Pool State Queries
const lpSupply = await pool.getLpSupply();
const userBalance = await pool.getUserBalance(wallet.publicKey);
const swapQuote = pool.getSwapQuote(
inputMint,
inputAmount,
slippageBps
);
console.log('Output amount:', swapQuote.outAmount.toString());
console.log('Fee:', swapQuote.fee.toString());
console.log('Price impact:', swapQuote.priceImpact);
const depositQuote = pool.getDepositQuote(
tokenAAmount,
tokenBAmount,
true,
slippageBps
);
console.log('LP tokens to receive:', depositQuote.lpAmount.toString());
const withdrawQuote = pool.getWithdrawQuote(
lpAmount,
slippageBps
);
console.log('Token A out:', withdrawQuote.tokenAAmount.toString());
console.log('Token B out:', withdrawQuote.tokenBAmount.toString());
await pool.updateState();
Liquidity Operations
const depositTx = await pool.deposit(
wallet.publicKey,
tokenAAmount,
tokenBAmount,
lpAmountMin
);
const withdrawTx = await pool.withdraw(
wallet.publicKey,
lpAmount,
tokenAMin,
tokenBMin
);
Swapping
const swapTx = await pool.swap(
wallet.publicKey,
inputMint,
inputAmount,
minOutputAmount
);
Pool Types
| Pool Type | Use Case | Features |
|---|
| Constant Product | General trading pairs | Standard x*y=k AMM |
| Stable | Stablecoin pairs (USDC/USDT) | Lower slippage for pegged assets |
| Weighted | Unbalanced pools (80/20) | Custom token weights |
| LST | Liquid staking tokens | Optimized for staking derivatives |
Zap SDK
The Zap SDK enables single-token entry and exit for liquidity positions, automatically handling swaps through Jupiter or the pool's built-in routing.
Basic Setup
import { Connection, PublicKey } from '@solana/web3.js';
import { Zap } from '@meteora-ag/zap-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const JUPITER_API_URL = 'https://quote-api.jup.ag/v6';
const JUPITER_API_KEY = 'your-api-key';
const zap = new Zap(connection, JUPITER_API_URL, JUPITER_API_KEY);
Zap Into DLMM Position
const zapInDlmmTx = await zap.zapInDlmm({
user: wallet.publicKey,
lbPairAddress: dlmmPoolAddress,
inputMint: SOL_MINT,
inputAmount: new BN(1_000_000_000),
slippageBps: 100,
positionPubkey: positionAddress,
strategyType: 'SpotBalanced',
minBinId: activeBinId - 10,
maxBinId: activeBinId + 10,
});
await sendAndConfirmTransaction(connection, zapInDlmmTx, [wallet]);
Zap Into DAMM v2 Position
const zapInDammV2Tx = await zap.zapInDammV2({
user: wallet.publicKey,
poolAddress: dammV2PoolAddress,
inputMint: USDC_MINT,
inputAmount: new BN(100_000_000),
slippageBps: 100,
positionPubkey: positionAddress,
});
await sendAndConfirmTransaction(connection, zapInDammV2Tx, [wallet]);
Zap Out Operations
const zapOutDlmmTx = await zap.zapOutDlmm({
user: wallet.publicKey,
lbPairAddress: dlmmPoolAddress,
outputMint: SOL_MINT,
positionPubkey: positionAddress,
percentageToZap: 100,
slippageBps: 100,
});
const zapOutDammV2Tx = await zap.zapOutDammV2({
user: wallet.publicKey,
poolAddress: dammV2PoolAddress,
outputMint: USDC_MINT,
positionPubkey: positionAddress,
percentageToZap: 50,
slippageBps: 100,
});
Zap Through Jupiter
const jupiterQuote = await zap.getJupiterQuote({
inputMint: SOL_MINT,
outputMint: USDC_MINT,
amount: new BN(1_000_000_000),
slippageBps: 50,
});
const zapOutJupiterTx = await zap.zapOutThroughJupiter({
user: wallet.publicKey,
inputMint: tokenMint,
outputMint: SOL_MINT,
jupiterSwapResponse: jupiterQuote,
maxSwapAmount: new BN(1_000_000_000),
percentageToZap: 100,
});
Helper Functions
const tokenProgram = await zap.getTokenProgramFromMint(connection, mintAddress);
const swapIx = await zap.getJupiterSwapInstruction(jupiterQuote, wallet.publicKey);
Pool Farms SDK
The Pool Farms SDK enables creating and managing liquidity mining farms on DAMM v1 pools.
Basic Setup
import { Connection, PublicKey } from '@solana/web3.js';
import { FarmImpl } from '@meteora-ag/farming';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const farmAddress = new PublicKey('FARM_ADDRESS');
const farm = await FarmImpl.create(connection, farmAddress);
Farm Operations
const depositTx = await farm.deposit(
wallet.publicKey,
lpAmount
);
const withdrawTx = await farm.withdraw(
wallet.publicKey,
lpAmount
);
const claimTx = await farm.claim(wallet.publicKey);
const pendingRewards = await farm.getPendingRewards(wallet.publicKey);
console.log('Pending rewards:', pendingRewards.toString());
const stakeInfo = await farm.getUserStakeInfo(wallet.publicKey);
console.log('Staked amount:', stakeInfo.amount.toString());
Common Patterns
Pattern 1: Initialize with Wallet
import { Connection, Keypair } from '@solana/web3.js';
import { Wallet, AnchorProvider } from '@coral-xyz/anchor';
import DLMM from '@meteora-ag/dlmm';
const connection = new Connection('https://api.mainnet-beta.solana.com');
const keypair = Keypair.fromSecretKey();
const wallet = new Wallet(keypair);
const provider = new AnchorProvider(connection, wallet, {
commitment: 'confirmed',
});
const dlmm = await DLMM.create(connection, poolAddress);
Pattern 2: Error Handling
try {
const swapTx = await dlmm.swap(swapParams);
const txHash = await sendAndConfirmTransaction(connection, swapTx, [wallet]);
console.log('Success:', txHash);
} catch (error) {
if (error.message.includes('Slippage')) {
console.error('Slippage exceeded - try increasing tolerance');
} else if (error.message.includes('InsufficientFunds')) {
console.error('Not enough balance for this trade');
} else if (error.message.includes('PoolNotFound')) {
console.error('Pool does not exist');
} else {
throw error;
}
}
Pattern 3: Batch Operations
import { Transaction } from '@solana/web3.js';
const transaction = new Transaction();
const claimFeeIx = await dlmm.claimSwapFee({ owner: wallet.publicKey, position: pos1 });
const claimRewardIx = await dlmm.claimLMReward({ owner: wallet.publicKey, position: pos1 });
transaction.add(...claimFeeIx.instructions);
transaction.add(...claimRewardIx.instructions);
const txHash = await sendAndConfirmTransaction(connection, transaction, [wallet]);
Pattern 4: Monitor Pool State
async function monitorPool(dlmm: DLMM, interval: number = 5000) {
setInterval(async () => {
await dlmm.refetchStates();
const activeBin = await dlmm.getActiveBin();
console.log(`Current price: ${activeBin.price}`);
const feeInfo = dlmm.getFeeInfo();
console.log(`Current fee rate: ${feeInfo.baseFeeRate}%`);
}, interval);
}
New Features (2025-2026)
DLMM Limit Orders
DLMM now supports fee-free on-chain limit orders:
const limitOrderTx = await dlmm.placeLimitOrder({
user: wallet.publicKey,
binId: targetBinId,
amount: new BN(1_000_000),
side: "buy",
});
Auto Vaults (Coming Q1 2026)
Auto vaults automatically compound fees and support custom market-making strategies through APIs. These vaults help users earn more with less effort.
Universal Curve (DBC)
The Dynamic Bonding Curve now supports programmable 16-point curves, giving LPs precise control over price trajectories:
const createPoolTx = await dbc.createPoolWithCurve({
creator: wallet.publicKey,
baseMint,
quoteMint,
curvePoints: [
{ price: 0.001, supply: 0 },
{ price: 0.01, supply: 100_000_000 },
{ price: 0.1, supply: 500_000_000 },
],
});
Presale Vault (Beta)
Presale Vault is Meteora's token presale infrastructure, currently in beta. It enables projects to run presales with built-in protection mechanisms.
Note: Presale Vault is in active development. Check the Meteora documentation for the latest information.
GitHub Repositories
TypeScript SDKs
Go SDKs
| Repository | Description |
|---|
| damm-v2-go | DAMM v2 Go implementation |
| dbc-go | Dynamic Bonding Curve Go SDK |
Core Programs (Rust)
Meteora Invent (CLI Tool)
Metsumi is Meteora's CLI tool for launching tokens and executing on-chain actions with minimal configuration.
Installation
git clone https://github.com/MeteoraAg/meteora-invent.git
cd meteora-invent
npm install -g pnpm
pnpm install
Available Commands
DLMM Operations
pnpm dlmm-create-pool
pnpm dlmm-seed-liquidity-lfg
pnpm dlmm-seed-liquidity-single-bin
pnpm dlmm-set-pool-status
DAMM v2 Operations
pnpm damm-v2-create-balanced-pool
pnpm damm-v2-create-one-sided-pool
pnpm damm-v2-add-liquidity
pnpm damm-v2-remove-liquidity
pnpm damm-v2-split-position
pnpm damm-v2-claim-position-fee
Dynamic Bonding Curve Operations
pnpm dbc-create-config
pnpm dbc-create-pool
pnpm dbc-swap
pnpm dbc-migrate-to-damm-v1
pnpm dbc-migrate-to-damm-v2
Vault Operations
pnpm alpha-vault-create
pnpm presale-vault-create
Configuration Files
Configurations are stored in studio/config/:
dlmm_config.jsonc - DLMM pool settings
damm_v1_config.jsonc - DAMM v1 settings
damm_v2_config.jsonc - DAMM v2 settings
dbc_config.jsonc - Bonding curve settings
alpha_vault_config.jsonc - Alpha vault settings
Resources
Skill Structure
meteora/
├── SKILL.md # This file
├── resources/
│ ├── dlmm-api-reference.md # DLMM SDK complete API
│ ├── damm-v2-api-reference.md # DAMM v2 SDK complete API
│ ├── damm-v1-api-reference.md # DAMM v1 SDK complete API
│ ├── zap-api-reference.md # Zap SDK API reference
│ ├── pool-farms-reference.md # Pool Farms SDK reference
│ ├── bonding-curve-reference.md # DBC SDK reference
│ ├── vault-api-reference.md # Vault SDK reference
│ ├── alpha-vault-reference.md # Alpha Vault SDK reference
│ ├── m3m3-api-reference.md # Stake-for-Fee SDK reference
│ ├── github-repos.md # All GitHub repositories
│ └── program-addresses.md # All program addresses
├── examples/
│ ├── dlmm/
│ │ ├── swap.ts # Basic swap example
│ │ ├── add-liquidity.ts # Adding liquidity
│ │ └── claim-fees.ts # Claiming fees/rewards
│ ├── damm-v2/
│ │ ├── create-pool.ts # Pool creation
│ │ ├── swap.ts # Swapping tokens
│ │ └── manage-position.ts # Position management
│ ├── damm-v1/
│ │ └── basic-operations.ts # DAMM v1 pool operations
│ ├── zap/
│ │ └── zap-operations.ts # Zap in/out examples
│ ├── bonding-curve/
│ │ ├── create-token.ts # Launch token on curve
│ │ ├── trade.ts # Buy/sell on curve
│ │ └── graduation.ts # Pool graduation
│ ├── vault/
│ │ └── deposit-withdraw.ts # Vault operations
│ ├── alpha-vault/
│ │ └── participation.ts # Alpha vault participation
│ └── stake-for-fee/
│ └── staking.ts # Staking operations
├── templates/
│ ├── trading-bot.ts # Market making template
│ ├── token-launch.ts # Token launch template
│ └── liquidity-manager.ts # LP management template
└── docs/
├── fee-structures.md # Fee configuration guide
├── migration-guide.md # DBC to DAMM migration
├── strategy-guide.md # Liquidity strategies
└── troubleshooting.md # Common issues