npx skills add https://github.com/sendaifun/skills --skill meteora使用 Meteora 的 SDK 套件构建 Solana DeFi 应用程序的综合指南 - Solana 上领先的流动性基础设施。
Meteora 是 Solana 首屈一指的流动性层,为连接流动性提供者、代币发行方和交易者的基础设施提供动力。它提供:
| 功能 | 优势 |
|---|---|
| 低池创建成本 | 0.022 SOL(竞争对手需 0.25+ SOL) |
| 动态费用 | 波动率调整的费用最大化 LP 回报 |
| 反狙击保护 | 费用调度器和 Alpha Vault 防止机器人利用 |
| Token-2022 支持 | 完全兼容 Token 扩展标准 |
| 无需许可 | 无需批准即可创建池、农场和启动 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 自动毕业 | 绑定曲线自动迁移到 AMM 池 |
Meteora 在 Solana 上提供完整的 DeFi 基础设施栈:
# DLMM SDK - 集中流动性
npm install @meteora-ag/dlmm @coral-xyz/anchor @solana/web3.js
# DAMM v2 SDK - 下一代恒定乘积 AMM
npm install @meteora-ag/cp-amm-sdk @solana/web3.js
# DAMM v1 SDK - 旧版 AMM(稳定池、加权池)
npm install @meteora-ag/dynamic-amm @solana/web3.js @coral-xyz/anchor
# 动态绑定曲线 SDK - 代币发行
npm install @meteora-ag/dynamic-bonding-curve-sdk
# 金库 SDK - 收益优化
npm install @meteora-ag/vault-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
# Alpha Vault SDK - 反机器人保护
npm install @meteora-ag/alpha-vault
# 质押赚取费用 SDK - 费用质押
npm install @meteora-ag/m3m3 @coral-xyz/anchor @solana/web3.js @solana/spl-token
# Zap SDK - 单币种存入/取出(需要 Jupiter API 密钥)
npm install @meteora-ag/zap-sdk
# 池农场 SDK - 农场创建和质押
npm install @meteora-ag/farming
| 程序 | 主网/开发网地址 |
|---|---|
| DLMM | LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo |
| DAMM v2 | cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG |
| DAMM v1 | Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB |
| 动态绑定曲线 | dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN |
| 动态金库 | 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi |
| 质押赚取费用 | FEESngU3neckdwib9X3KWqdL7Mjmqk9XNp3uh5JbP4KP |
| Zap | zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz |
DLMM SDK 提供对 Meteora 集中流动性协议的编程访问,该协议具有基于波动性的动态费用。
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');
// 为现有池创建 DLMM 实例
const dlmm = await DLMM.create(connection, poolAddress);
// 创建多个池
const dlmmPools = await DLMM.createMultiple(connection, [pool1, pool2, pool3]);
const activeBin = await dlmm.getActiveBin();
console.log('活跃仓位 ID:', activeBin.binId);
console.log('价格:', activeBin.price);
console.log('X 数量:', activeBin.xAmount.toString());
console.log('Y 数量:', activeBin.yAmount.toString());
// 根据仓位 ID 获取价格
const price = dlmm.getPriceOfBinByBinId(binId);
// 根据价格获取仓位 ID
const binId = dlmm.getBinIdFromPrice(price, true); // true = 向下取整
// 转换到/从 lamport 表示法
const lamportPrice = dlmm.toPricePerLamport(21.23);
const realPrice = dlmm.fromPricePerLamport(lamportPrice);
// 获取范围内的仓位
const bins = await dlmm.getBinsBetweenLowerAndUpperBound(minBinId, maxBinId);
// 获取活跃仓位周围的仓位
const surroundingBins = await dlmm.getBinsAroundActiveBin(10); // 每边 10 个仓位
import { BN } from '@coral-xyz/anchor';
// 获取交换报价
const swapAmount = new BN(1_000_000); // 1 USDC(6 位小数)
const swapForY = true; // 用 X 交换 Y
const slippageBps = 100; // 1% 滑点
const binArrays = await dlmm.getBinArrayForSwap(swapForY);
const swapQuote = dlmm.swapQuote(swapAmount, swapForY, slippageBps, binArrays);
console.log('输入数量:', swapQuote.consumedInAmount.toString());
console.log('输出数量:', swapQuote.outAmount.toString());
console.log('最小输出数量:', swapQuote.minOutAmount.toString());
console.log('价格影响:', swapQuote.priceImpact);
console.log('费用:', 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]);
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), // 100 个代币
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), // 100%(基点)
shouldClaimAndClose: true,
});
// 获取可申领费用
const claimableFees = await DLMM.getClaimableSwapFee(connection, position.publicKey);
console.log('可申领费用 X:', claimableFees.feeX.toString());
console.log('可申领费用 Y:', claimableFees.feeY.toString());
// 获取可申领的 LM 奖励
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),
});
// 申领 LM 奖励
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),
});
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 为 Meteora 的下一代恒定乘积 AMM 提供了全面的接口,相比 V1 有显著改进。
| 功能 | 描述 |
|---|---|
| 动态费用 | 可选费用调度器,具有反狙击机制 |
| 仓位 NFT | LP 接收可转让的 NFT 而非 LP 代币 |
| Token2022 支持 | 完全支持 Token 扩展标准 |
| 锁定流动性 | 内置流动性锁定选项 |
| 无需许可农场 | 无需协议批准即可创建农场 |
| 更低成本 | 池创建成本仅需 0.022 SOL(旧版 DLMM 需 0.25 SOL) |
费用调度器以高交换费用开始,并随时间逐渐降低,防止狙击:
// 创建带费用调度器的池
const createPoolTx = await cpAmm.createCustomPool({
// ... 其他参数
poolFees: {
baseFee: {
cliffFeeNumerator: new BN(10000000), // 1% 初始费用
numberOfPeriod: 10,
reductionFactor: new BN(500000), // 每期减少 0.05%
periodFrequency: new BN(300), // 每 5 分钟
feeSchedulerMode: 1, // 线性减少
},
// ...
},
});
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);
// 根据配置创建标准池
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), // 0.25%
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, // 0 = 区块,1 = 时间戳
activationPoint: null, // null = 立即
collectFeeMode: 0,
});
// 获取单个池
const poolState = await cpAmm.fetchPoolState(poolAddress);
console.log('代币 A 金库:', poolState.tokenAVault.toString());
console.log('代币 B 金库:', poolState.tokenBVault.toString());
console.log('平方根价格:', poolState.sqrtPrice.toString());
console.log('流动性:', poolState.liquidity.toString());
// 获取所有池
const allPools = await cpAmm.getAllPools();
// 检查池是否存在
const exists = await cpAmm.isPoolExist(tokenAMint, tokenBMint);
// 创建仓位
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, // 拆分 50%
newPosition: newPositionKeypair.publicKey,
});
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('输入数量:', quote.inputAmount.toString());
console.log('输出数量:', quote.outputAmount.toString());
console.log('最小输出:', quote.minimumOutputAmount.toString());
console.log('价格影响:', quote.priceImpact);
console.log('费用:', 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,
});
// 申领仓位费用
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), // 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,
});
// 使用归属计划锁定仓位
const lockPositionTx = await cpAmm.lockPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
vestingDuration: new BN(86400 * 30), // 30 天
cliffDuration: new BN(86400 * 7), // 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);
// 价格转换
const price = cpAmm.getPriceFromSqrtPrice(sqrtPrice, tokenADecimals, tokenBDecimals);
const sqrtPrice = cpAmm.getSqrtPriceFromPrice(price, tokenADecimals, tokenBDecimals);
// 费用转换
const feeNumerator = cpAmm.bpsToFeeNumerator(25); // 0.25% = 25 bps
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),
});
动态绑定曲线 SDK 支持构建可自定义的代币发行,并自动毕业到 DAMM。
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');
DBC 遵循 5 步流程:
// 创建新的绑定曲线池
const createPoolTx = await dbc.createPool({
creator: wallet.publicKey,
baseMint: baseTokenMint,
quoteMint: quoteTokenMint, // 通常是 SOL 或 USDC
config: configAddress,
baseAmount: new BN(1_000_000_000_000), // 总供应量
quoteAmount: new BN(0), // 初始报价(通常为 0)
name: 'My Token',
symbol: 'MTK',
uri: 'https://arweave.net/metadata.json',
});
// 获取购买代币的报价
const buyQuote = await dbc.getBuyQuote({
pool: poolAddress,
quoteAmount: new BN(1_000_000_000), // 1 SOL
});
console.log('将收到的代币:', buyQuote.baseAmount.toString());
console.log('每个代币的价格:', 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,
});
// 检查毕业状态
const poolState = await dbc.fetchPoolState(poolAddress);
const isGraduated = poolState.graduated;
const graduationThreshold = poolState.graduationThreshold;
const currentMarketCap = poolState.currentMarketCap;
// 手动迁移到 DAMM v2(如果未触发自动毕业)
const migrateTx = await dbc.migrateToDAMMV2({
pool: poolAddress,
payer: wallet.publicKey,
});
// 对于 DAMM v1 迁移(需要更多步骤)
// 1. 创建元数据
const createMetadataTx = await dbc.createMetadata({
pool: poolAddress,
payer: wallet.publicKey,
});
// 2. 执行迁移
const migrateToDammV1Tx = await dbc.migrateToDAMMV1({
pool: poolAddress,
payer: wallet.publicKey,
});
// 3. 锁定 LP 代币(可选)
const lockLpTx = await dbc.lockLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
lockDuration: new BN(86400 * 365), // 1 年
});
// 4. 锁定到期后申领 LP 代币
const claimLpTx = await dbc.claimLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
});
DBC 支持多种费用层级配置:
| 层级 | 费用 | 使用场景 |
|---|---|---|
| 1 | 25 | 标准发行 |
| 2 | 50 | 社区代币 |
| 3 | 100 | Meme 代币 |
| 4 | 200 | 高波动性 |
| 5 | 400 | 实验性 |
| 6 | 600 | 最大保护 |
金库 SDK 提供收益优化的代币存储,并具有自动策略管理功能。
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);
// 使用联盟 ID(用于合作伙伴集成)
const vaultWithAffiliate = await VaultImpl.create(connection, tokenMint, {
affiliateId: new PublicKey('PARTNER_KEY'),
});
// 获取金库信息
const lpSupply = vault.lpSupply; // 或使用 vault.getVaultSupply() 刷新
const withdrawableAmount = await vault.getWithdrawableAmount();
console.log('总 LP 供应量:', lpSupply.toString());
console.log('锁定数量:', withdrawableAmount.locked.toString());
console.log('解锁数量:', 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]);
import { getAmountByShare, getUnmintAmount } from '@meteora-ag/vault-sdk';
// 将 LP 代币转换为底层资产数量
const underlyingAmount = getAmountByShare(
userLpBalance, // 用户的 LP 代币
unlockedAmount, // 金库的解锁余额
lpSupply // 总 LP 供应量
);
// 计算特定取款所需的 LP 代币
const lpNeeded = getUnmintAmount(
targetWithdrawAmount, // 要取出的数量
unlockedAmount, // 金库的解锁余额
lpSupply // 总 LP 供应量
);
// 获取联盟信息
const affiliateInfo = await vault.getAffiliateInfo();
console.log('合作伙伴:', affiliateInfo.partner.toString());
console.log('费用率:', affiliateInfo.feeRate);
console.log('未结费用:', affiliateInfo.outstandingFee.toString());
Alpha Vault SDK 为代币发行提供反机器人保护,确保公平分配。
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);
// 获取金库状态
const vaultState = await alphaVault.getVaultState();
console.log('总存入:', vaultState.totalDeposited.toString());
console.log('最大存入:', vaultState.maxDeposit.toString());
console.log('开始时间:', vaultState.startTime.toString());
console.log('结束时间:', vaultState.endTime.toString());
// 存入金库(在存入窗口期间)
const depositTx = await alphaVault.deposit({
payer: wallet.publicKey,
amount: new BN(1_000_000_000), // 1 SOL
});
// 从金库取出(如果允许)
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('存入数量:', allocation.depositAmount.toString());
console.log('代币分配额:', allocation.tokenAllocation.toString());
console.log('已申领:', allocation.claimed);
M3M3 SDK 支持质押代币以赚取交易活动产生的费用。
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);
// 获取用户质押和可申领余额
const userBalance = await m3m3.getUserStakeAndClaimBalance(wallet.publicKey);
console.log('质押数量:', userBalance.stakedAmount.toString());
console.log('可申领费用:', 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); // 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 是原始的恒定乘积 AMM,仍广泛用于稳定池、加权池和 LST 池。虽然建议新池使用 DAMM v2,但 v1 仍得到完全支持。
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]);
// 创建无需许可的恒定乘积池
const createPoolTx = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress, // 费用配置
{
lockLiquidity: false, // 锁定初始流动性
activationPoint: null, // 可选的延迟激活
}
);
// 创建 Memecoin 池(为代币发行优化)
const memePoolTx = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress,
{
lockLiquidity: true, // 锁定流动性以建立信任
}
);
// 获取 LP 代币供应量
const lpSupply = await pool.getLpSupply();
// 获取用户的 LP 代币余额
const userBalance = await pool.getUserBalance(wallet.publicKey);
// 获取交换报价
const swapQuote = pool.getSwapQuote(
inputMint,
inputAmount,
slippageBps // 100 = 1%
);
console.log('输出数量:', swapQuote.outAmount.toString());
console.log('费用:', swapQuote.fee.toString());
console.log('价格影响:', swapQuote.priceImpact);
// 获取存款报价
const depositQuote = pool.getDepositQuote(
tokenAAmount,
tokenBAmount,
true, // 平衡存款
slippageBps
);
console.log('将收到的 LP 代币:', depositQuote.lpAmount.toString());
// 获取取款报价
const withdrawQuote = pool.getWithdrawQuote(
lpAmount,
slippageBps
);
console.log('代币 A 输出:', withdrawQuote.tokenAAmount.toString());
console.log('代币 B 输出:', withdrawQuote.tokenBAmount.toString());
// 刷新池状态
await pool.updateState();
// 存入流动性
const depositTx = await pool.deposit(
wallet.publicKey,
tokenAAmount,
tokenBAmount,
lpAmountMin // 收到的最小 LP 代币数量
);
// 取出流动性
const withdrawTx = await pool.withdraw(
wallet.publicKey,
lpAmount,
tokenAMin, // 收到的最小代币 A 数量
tokenBMin // 收到的最小代币 B 数量
);
// 执行交换
const swapTx = await pool.swap(
wallet.publicKey,
inputMint,
inputAmount,
minOutputAmount
);
| 池类型 | 使用场景 | 特性 |
|---|---|---|
| 恒定乘积 | 通用交易对 | 标准 x*y=k AMM |
| 稳定 | 稳定币对 | 对挂钩资产滑点更低 |
| 加权 | 不平衡池 | 自定义代币权重 |
| LST | 流动性质押代币 | 为质押衍生品优化 |
Zap SDK 支持流动性仓位的单币种存入和取出,通过 Jupiter 或池的内置路由自动处理交换。
A comprehensive guide for building Solana DeFi applications with Meteora's suite of SDKs - the leading liquidity infrastructure on Solana.
Meteora is Solana's premier liquidity layer, powering the infrastructure that connects liquidity providers (LPs), token launchers, and traders. It offers:
| 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 |
Meteora provides a complete DeFi infrastructure stack on Solana:
# DLMM SDK - Concentrated liquidity
npm install @meteora-ag/dlmm @coral-xyz/anchor @solana/web3.js
# DAMM v2 SDK - Next-gen constant product AMM
npm install @meteora-ag/cp-amm-sdk @solana/web3.js
# DAMM v1 SDK - Legacy AMM (stable pools, weighted pools)
npm install @meteora-ag/dynamic-amm @solana/web3.js @coral-xyz/anchor
# Dynamic Bonding Curve SDK - Token launches
npm install @meteora-ag/dynamic-bonding-curve-sdk
# Vault SDK - Yield optimization
npm install @meteora-ag/vault-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
# Alpha Vault SDK - Anti-bot protection
npm install @meteora-ag/alpha-vault
# Stake-for-Fee (M3M3) SDK - Fee staking
npm install @meteora-ag/m3m3 @coral-xyz/anchor @solana/web3.js @solana/spl-token
# Zap SDK - Single-token entry/exit (requires Jupiter API key)
npm install @meteora-ag/zap-sdk
# Pool Farms SDK - Farm creation and staking
npm install @meteora-ag/farming
| Program | Mainnet/Devnet Address |
|---|---|
| DLMM | LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo |
| DAMM v2 | cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG |
| DAMM v1 | Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB |
| Dynamic Bonding Curve | dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN |
| Dynamic Vault | 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi |
| Stake-for-Fee |
The DLMM SDK provides programmatic access to Meteora's concentrated liquidity protocol with dynamic fees based on volatility.
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');
// Create DLMM instance for existing pool
const dlmm = await DLMM.create(connection, poolAddress);
// Create multiple pools
const dlmmPools = await DLMM.createMultiple(connection, [pool1, pool2, pool3]);
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());
// Get price from bin ID
const price = dlmm.getPriceOfBinByBinId(binId);
// Get bin ID from price
const binId = dlmm.getBinIdFromPrice(price, true); // true = round down
// Convert to/from lamport representation
const lamportPrice = dlmm.toPricePerLamport(21.23);
const realPrice = dlmm.fromPricePerLamport(lamportPrice);
// Get bins in a range
const bins = await dlmm.getBinsBetweenLowerAndUpperBound(minBinId, maxBinId);
// Get bins around active bin
const surroundingBins = await dlmm.getBinsAroundActiveBin(10); // 10 bins each side
import { BN } from '@coral-xyz/anchor';
// Get swap quote
const swapAmount = new BN(1_000_000); // 1 USDC (6 decimals)
const swapForY = true; // Swap X for Y
const slippageBps = 100; // 1% slippage
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());
// Execute swap
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]);
import { StrategyType } from '@meteora-ag/dlmm';
// Get user positions
const positions = await dlmm.getPositionsByUserAndLbPair(wallet.publicKey);
// Initialize position and add liquidity with strategy
const newPositionTx = await dlmm.initializePositionAndAddLiquidityByStrategy({
positionPubKey: newPositionKeypair.publicKey,
user: wallet.publicKey,
totalXAmount: new BN(100_000_000), // 100 tokens
totalYAmount: new BN(100_000_000),
strategy: {
maxBinId: activeBin.binId + 10,
minBinId: activeBin.binId - 10,
strategyType: StrategyType.SpotBalanced,
},
});
// Add liquidity to existing position
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,
},
});
// Remove liquidity
const removeLiquidityTx = await dlmm.removeLiquidity({
position: position.publicKey,
user: wallet.publicKey,
binIds: position.positionData.positionBinData.map(b => b.binId),
bps: new BN(10000), // 100% (basis points)
shouldClaimAndClose: true,
});
// Get claimable fees
const claimableFees = await DLMM.getClaimableSwapFee(connection, position.publicKey);
console.log('Claimable Fee X:', claimableFees.feeX.toString());
console.log('Claimable Fee Y:', claimableFees.feeY.toString());
// Get claimable LM rewards
const claimableRewards = await DLMM.getClaimableLMReward(connection, position.publicKey);
// Claim swap fees
const claimFeeTx = await dlmm.claimSwapFee({
owner: wallet.publicKey,
position: position.publicKey,
});
// Claim all fees from multiple positions
const claimAllFeesTx = await dlmm.claimAllSwapFee({
owner: wallet.publicKey,
positions: positions.map(p => p.publicKey),
});
// Claim LM rewards
const claimRewardTx = await dlmm.claimLMReward({
owner: wallet.publicKey,
position: position.publicKey,
});
// Claim all rewards
const claimAllTx = await dlmm.claimAllRewards({
owner: wallet.publicKey,
positions: positions.map(p => p.publicKey),
});
import { StrategyType } from '@meteora-ag/dlmm';
// Available strategies
StrategyType.SpotOneSide // Single-sided liquidity at current price
StrategyType.CurveOneSide // Curve distribution on one side
StrategyType.BidAskOneSide // Bid/ask distribution on one side
StrategyType.SpotBalanced // Balanced around current price
StrategyType.CurveBalanced // Curve distribution around current price
StrategyType.BidAskBalanced // Bid/ask distribution around current price
StrategyType.SpotImBalanced // Imbalanced spot distribution
StrategyType.CurveImBalanced // Imbalanced curve distribution
StrategyType.BidAskImBalanced // Imbalanced bid/ask distribution
The DAMM v2 SDK provides a comprehensive interface for Meteora's next-generation constant product AMM with significant improvements over V1.
| 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) |
The fee scheduler starts with high swap fees that taper over time, protecting against sniping:
// Create pool with fee scheduler
const createPoolTx = await cpAmm.createCustomPool({
// ... other params
poolFees: {
baseFee: {
cliffFeeNumerator: new BN(10000000), // 1% initial fee
numberOfPeriod: 10,
reductionFactor: new BN(500000), // Reduce by 0.05% each period
periodFrequency: new BN(300), // Every 5 minutes
feeSchedulerMode: 1, // Linear reduction
},
// ...
},
});
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);
// Create standard pool from config
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),
});
// Create custom pool with specific parameters
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), // 0.25%
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, // 0 = slot, 1 = timestamp
activationPoint: null, // null = immediate
collectFeeMode: 0,
});
// Fetch single pool
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());
// Fetch all pools
const allPools = await cpAmm.getAllPools();
// Check if pool exists
const exists = await cpAmm.isPoolExist(tokenAMint, tokenBMint);
// Create position
const createPositionTx = await cpAmm.createPosition({
owner: wallet.publicKey,
pool: poolAddress,
});
// Add liquidity
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),
});
// Get deposit quote
const depositQuote = cpAmm.getDepositQuote({
poolState,
tokenAAmount: new BN(100_000_000),
tokenBAmount: new BN(100_000_000),
slippageBps: 100,
});
// Remove liquidity
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),
});
// Get withdraw quote
const withdrawQuote = cpAmm.getWithdrawQuote({
poolState,
positionState,
liquidityAmount: new BN(50_000_000),
slippageBps: 100,
});
// Merge positions
const mergePositionTx = await cpAmm.mergePosition({
owner: wallet.publicKey,
pool: poolAddress,
sourcePositions: [position1, position2],
destinationPosition: destPosition,
});
// Split position
const splitPositionTx = await cpAmm.splitPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
percentage: 50, // Split 50%
newPosition: newPositionKeypair.publicKey,
});
import { SwapMode } from '@meteora-ag/cp-amm-sdk';
// Available swap modes
SwapMode.ExactIn // Specify exact input amount
SwapMode.ExactOut // Specify exact output amount
SwapMode.PartialFill // Allow partial fills
// Get swap quote
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());
// Execute swap
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,
});
// Claim position fees
const claimFeeTx = await cpAmm.claimPositionFee({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
});
// Initialize reward (pool creator only)
const initRewardTx = await cpAmm.initializeReward({
pool: poolAddress,
rewardMint,
rewardDuration: new BN(86400 * 7), // 7 days
funder: wallet.publicKey,
});
// Fund reward
const fundRewardTx = await cpAmm.fundReward({
pool: poolAddress,
rewardMint,
amount: new BN(1_000_000_000),
funder: wallet.publicKey,
});
// Claim rewards
const claimRewardTx = await cpAmm.claimReward({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
rewardIndex: 0,
});
// Lock position with vesting schedule
const lockPositionTx = await cpAmm.lockPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
vestingDuration: new BN(86400 * 30), // 30 days
cliffDuration: new BN(86400 * 7), // 7 day cliff
});
// Permanent lock (irreversible)
const permanentLockTx = await cpAmm.permanentLockPosition({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
liquidityAmount: new BN(50_000_000), // Amount to permanently lock
});
// Refresh vesting (unlock available tokens)
const refreshVestingTx = await cpAmm.refreshVesting({
owner: wallet.publicKey,
pool: poolAddress,
position: positionAddress,
});
// Check if position is locked
const isLocked = cpAmm.isLockedPosition(positionState);
// Price conversions
const price = cpAmm.getPriceFromSqrtPrice(sqrtPrice, tokenADecimals, tokenBDecimals);
const sqrtPrice = cpAmm.getSqrtPriceFromPrice(price, tokenADecimals, tokenBDecimals);
// Fee conversions
const feeNumerator = cpAmm.bpsToFeeNumerator(25); // 0.25% = 25 bps
const bps = cpAmm.feeNumeratorToBps(feeNumerator);
// Slippage calculations
const minAmount = cpAmm.getAmountWithSlippage(amount, slippageBps, false);
const maxAmount = cpAmm.getMaxAmountWithSlippage(amount, slippageBps);
// Get price impact
const priceImpact = cpAmm.getPriceImpact(amountIn, amountOut, currentPrice);
// Get liquidity delta
const liquidityDelta = cpAmm.getLiquidityDelta({
poolState,
tokenAAmount: new BN(100_000_000),
tokenBAmount: new BN(100_000_000),
});
The Dynamic Bonding Curve SDK enables building customizable token launches with automatic graduation to DAMM.
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');
The DBC follows a 5-step progression:
// Create a new bonding curve pool
const createPoolTx = await dbc.createPool({
creator: wallet.publicKey,
baseMint: baseTokenMint,
quoteMint: quoteTokenMint, // Usually SOL or USDC
config: configAddress,
baseAmount: new BN(1_000_000_000_000), // Total supply
quoteAmount: new BN(0), // Initial quote (usually 0)
name: 'My Token',
symbol: 'MTK',
uri: 'https://arweave.net/metadata.json',
});
// Get quote for buying tokens
const buyQuote = await dbc.getBuyQuote({
pool: poolAddress,
quoteAmount: new BN(1_000_000_000), // 1 SOL
});
console.log('Tokens to receive:', buyQuote.baseAmount.toString());
console.log('Price per token:', buyQuote.price.toString());
// Execute buy
const buyTx = await dbc.buy({
payer: wallet.publicKey,
pool: poolAddress,
quoteAmount: new BN(1_000_000_000),
minBaseAmount: buyQuote.minBaseAmount,
});
// Get quote for selling tokens
const sellQuote = await dbc.getSellQuote({
pool: poolAddress,
baseAmount: new BN(1_000_000), // Tokens to sell
});
// Execute sell
const sellTx = await dbc.sell({
payer: wallet.publicKey,
pool: poolAddress,
baseAmount: new BN(1_000_000),
minQuoteAmount: sellQuote.minQuoteAmount,
});
// Check graduation status
const poolState = await dbc.fetchPoolState(poolAddress);
const isGraduated = poolState.graduated;
const graduationThreshold = poolState.graduationThreshold;
const currentMarketCap = poolState.currentMarketCap;
// Manual migration to DAMM v2 (if auto-graduation not triggered)
const migrateTx = await dbc.migrateToDAMMV2({
pool: poolAddress,
payer: wallet.publicKey,
});
// For DAMM v1 migration (more steps required)
// 1. Create metadata
const createMetadataTx = await dbc.createMetadata({
pool: poolAddress,
payer: wallet.publicKey,
});
// 2. Execute migration
const migrateToDammV1Tx = await dbc.migrateToDAMMV1({
pool: poolAddress,
payer: wallet.publicKey,
});
// 3. Lock LP tokens (optional)
const lockLpTx = await dbc.lockLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
lockDuration: new BN(86400 * 365), // 1 year
});
// 4. Claim LP tokens after lock expires
const claimLpTx = await dbc.claimLpTokens({
pool: poolAddress,
payer: wallet.publicKey,
});
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 |
The Vault SDK provides yield-optimized token storage with automatic strategy management.
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');
// Create vault instance
const vault = await VaultImpl.create(connection, tokenMint);
// With affiliate ID (for partner integrations)
const vaultWithAffiliate = await VaultImpl.create(connection, tokenMint, {
affiliateId: new PublicKey('PARTNER_KEY'),
});
// Get vault information
const lpSupply = vault.lpSupply; // Or use vault.getVaultSupply() to refresh
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());
// Get user balance
const userLpBalance = await vault.getUserBalance(wallet.publicKey);
// Deposit tokens
const depositTx = await vault.deposit(wallet.publicKey, new BN(1_000_000_000));
await sendAndConfirmTransaction(connection, depositTx, [wallet]);
// Withdraw tokens
const withdrawTx = await vault.withdraw(wallet.publicKey, new BN(500_000_000));
await sendAndConfirmTransaction(connection, withdrawTx, [wallet]);
import { getAmountByShare, getUnmintAmount } from '@meteora-ag/vault-sdk';
// Convert LP tokens to underlying amount
const underlyingAmount = getAmountByShare(
userLpBalance, // User's LP tokens
unlockedAmount, // Vault's unlocked balance
lpSupply // Total LP supply
);
// Calculate LP tokens needed for specific withdrawal
const lpNeeded = getUnmintAmount(
targetWithdrawAmount, // Amount to withdraw
unlockedAmount, // Vault's unlocked balance
lpSupply // Total LP supply
);
// Get affiliate info
const affiliateInfo = await vault.getAffiliateInfo();
console.log('Partner:', affiliateInfo.partner.toString());
console.log('Fee Rate:', affiliateInfo.feeRate);
console.log('Outstanding Fee:', affiliateInfo.outstandingFee.toString());
The Alpha Vault SDK provides anti-bot protection for token launches, ensuring fair distribution.
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);
// Get vault state
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());
// Deposit to vault (during deposit window)
const depositTx = await alphaVault.deposit({
payer: wallet.publicKey,
amount: new BN(1_000_000_000), // 1 SOL
});
// Withdraw from vault (if allowed)
const withdrawTx = await alphaVault.withdraw({
payer: wallet.publicKey,
amount: new BN(500_000_000),
});
// Claim tokens (after launch)
const claimTx = await alphaVault.claimTokens({
payer: wallet.publicKey,
});
// Get user allocation
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);
The M3M3 SDK enables staking tokens to earn fees from trading activity.
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);
// Get user stake and claimable balance
const userBalance = await m3m3.getUserStakeAndClaimBalance(wallet.publicKey);
console.log('Staked Amount:', userBalance.stakedAmount.toString());
console.log('Claimable Fees:', userBalance.claimableFees.toString());
// Stake tokens
const stakeTx = await m3m3.stake(new BN(1_000_000_000), wallet.publicKey);
await sendAndConfirmTransaction(connection, stakeTx, [wallet]);
// Claim accumulated fees
const claimTx = await m3m3.claimFee(wallet.publicKey, null); // null = claim all
await sendAndConfirmTransaction(connection, claimTx, [wallet]);
// Initiate unstake (starts lock period)
const unstakeTx = await m3m3.unstake(
new BN(500_000_000),
destinationTokenAccount,
wallet.publicKey
);
// Cancel pending unstake
const cancelUnstakeTx = await m3m3.cancelUnstake(escrowAddress, wallet.publicKey);
// Complete withdrawal (after lock period)
const withdrawTx = await m3m3.withdraw(escrowAddress, wallet.publicKey);
// Get unstake period
const unstakePeriod = m3m3.getUnstakePeriod(); // Duration in seconds
// Refresh states
await m3m3.refreshStates();
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.
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');
// Create pool instance
const pool = await AmmImpl.create(connection, new PublicKey('POOL_ADDRESS'));
// Or create multiple pools
const pools = await AmmImpl.createMultiple(connection, [poolAddress1, poolAddress2]);
// Create permissionless constant product pool
const createPoolTx = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress, // Fee configuration
{
lockLiquidity: false, // Lock initial liquidity
activationPoint: null, // Optional delayed activation
}
);
// Create memecoin pool (optimized for token launches)
const memePoolTx = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
connection,
wallet.publicKey,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
configAddress,
{
lockLiquidity: true, // Lock liquidity for trust
}
);
// Get LP token supply
const lpSupply = await pool.getLpSupply();
// Get user's LP token balance
const userBalance = await pool.getUserBalance(wallet.publicKey);
// Get swap quote
const swapQuote = pool.getSwapQuote(
inputMint,
inputAmount,
slippageBps // 100 = 1%
);
console.log('Output amount:', swapQuote.outAmount.toString());
console.log('Fee:', swapQuote.fee.toString());
console.log('Price impact:', swapQuote.priceImpact);
// Get deposit quote
const depositQuote = pool.getDepositQuote(
tokenAAmount,
tokenBAmount,
true, // balanced deposit
slippageBps
);
console.log('LP tokens to receive:', depositQuote.lpAmount.toString());
// Get withdraw quote
const withdrawQuote = pool.getWithdrawQuote(
lpAmount,
slippageBps
);
console.log('Token A out:', withdrawQuote.tokenAAmount.toString());
console.log('Token B out:', withdrawQuote.tokenBAmount.toString());
// Refresh pool state
await pool.updateState();
// Deposit liquidity
const depositTx = await pool.deposit(
wallet.publicKey,
tokenAAmount,
tokenBAmount,
lpAmountMin // Minimum LP tokens to receive
);
// Withdraw liquidity
const withdrawTx = await pool.withdraw(
wallet.publicKey,
lpAmount,
tokenAMin, // Minimum token A to receive
tokenBMin // Minimum token B to receive
);
// Execute swap
const swapTx = await pool.swap(
wallet.publicKey,
inputMint,
inputAmount,
minOutputAmount
);
| 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 |
The Zap SDK enables single-token entry and exit for liquidity positions, automatically handling swaps through Jupiter or the pool's built-in routing.
import { Connection, PublicKey } from '@solana/web3.js';
import { Zap } from '@meteora-ag/zap-sdk';
const connection = new Connection('https://api.mainnet-beta.solana.com');
// Jupiter API key is required (get from Jupiter Portal)
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 single token into DLMM concentrated liquidity position
const zapInDlmmTx = await zap.zapInDlmm({
user: wallet.publicKey,
lbPairAddress: dlmmPoolAddress,
inputMint: SOL_MINT,
inputAmount: new BN(1_000_000_000), // 1 SOL
slippageBps: 100, // 1%
positionPubkey: positionAddress, // Existing or new position
strategyType: 'SpotBalanced', // Distribution strategy
minBinId: activeBinId - 10,
maxBinId: activeBinId + 10,
});
await sendAndConfirmTransaction(connection, zapInDlmmTx, [wallet]);
// Zap single token into DAMM v2 pool
const zapInDammV2Tx = await zap.zapInDammV2({
user: wallet.publicKey,
poolAddress: dammV2PoolAddress,
inputMint: USDC_MINT,
inputAmount: new BN(100_000_000), // 100 USDC
slippageBps: 100,
positionPubkey: positionAddress,
});
await sendAndConfirmTransaction(connection, zapInDammV2Tx, [wallet]);
// Zap out from DLMM to single token
const zapOutDlmmTx = await zap.zapOutDlmm({
user: wallet.publicKey,
lbPairAddress: dlmmPoolAddress,
outputMint: SOL_MINT, // Receive everything as SOL
positionPubkey: positionAddress,
percentageToZap: 100, // 100% of position
slippageBps: 100,
});
// Zap out from DAMM v2 to single token
const zapOutDammV2Tx = await zap.zapOutDammV2({
user: wallet.publicKey,
poolAddress: dammV2PoolAddress,
outputMint: USDC_MINT,
positionPubkey: positionAddress,
percentageToZap: 50, // 50% of position
slippageBps: 100,
});
// Get Jupiter quote for optimal routing
const jupiterQuote = await zap.getJupiterQuote({
inputMint: SOL_MINT,
outputMint: USDC_MINT,
amount: new BN(1_000_000_000),
slippageBps: 50,
});
// Zap out through Jupiter aggregator
const zapOutJupiterTx = await zap.zapOutThroughJupiter({
user: wallet.publicKey,
inputMint: tokenMint,
outputMint: SOL_MINT,
jupiterSwapResponse: jupiterQuote,
maxSwapAmount: new BN(1_000_000_000),
percentageToZap: 100,
});
// Get token program from mint
const tokenProgram = await zap.getTokenProgramFromMint(connection, mintAddress);
// Get Jupiter swap instruction
const swapIx = await zap.getJupiterSwapInstruction(jupiterQuote, wallet.publicKey);
The Pool Farms SDK enables creating and managing liquidity mining farms on DAMM v1 pools.
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);
// Deposit LP tokens to farm
const depositTx = await farm.deposit(
wallet.publicKey,
lpAmount
);
// Withdraw LP tokens from farm
const withdrawTx = await farm.withdraw(
wallet.publicKey,
lpAmount
);
// Claim farming rewards
const claimTx = await farm.claim(wallet.publicKey);
// Get pending rewards
const pendingRewards = await farm.getPendingRewards(wallet.publicKey);
console.log('Pending rewards:', pendingRewards.toString());
// Get user stake info
const stakeInfo = await farm.getUserStakeInfo(wallet.publicKey);
console.log('Staked amount:', stakeInfo.amount.toString());
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(/* your secret key */);
const wallet = new Wallet(keypair);
const provider = new AnchorProvider(connection, wallet, {
commitment: 'confirmed',
});
// Now use provider.wallet.publicKey for transactions
const dlmm = await DLMM.create(connection, poolAddress);
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;
}
}
import { Transaction } from '@solana/web3.js';
// Combine multiple instructions in one transaction
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]);
// Periodically refresh 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);
}
DLMM now supports fee-free on-chain limit orders:
// Place limit order on DLMM
const limitOrderTx = await dlmm.placeLimitOrder({
user: wallet.publicKey,
binId: targetBinId,
amount: new BN(1_000_000),
side: "buy", // or "sell"
});
Auto vaults automatically compound fees and support custom market-making strategies through APIs. These vaults help users earn more with less effort.
The Dynamic Bonding Curve now supports programmable 16-point curves, giving LPs precise control over price trajectories:
// Create pool with custom curve
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 },
// ... up to 16 points
],
});
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.
| Repository | Description | Stars |
|---|---|---|
| dlmm-sdk | DLMM concentrated liquidity SDK | 280+ |
| damm-v2-sdk | DAMM v2 constant product AMM SDK | 44+ |
| damm-v1-sdk | Legacy DAMM v1 SDK | 126+ |
| dynamic-bonding-curve-sdk | Token launch bonding curves | 35+ |
| zap-sdk | Single-token entry/exit | 2+ |
| vault-sdk | Dynamic vault SDK | - |
| alpha-vault-sdk |
| Repository | Description |
|---|---|
| damm-v2-go | DAMM v2 Go implementation |
| dbc-go | Dynamic Bonding Curve Go SDK |
| Repository | Description | Stars |
|---|---|---|
| damm-v2 | DAMM v2 program | 98+ |
| dynamic-bonding-curve | DBC program | 86+ |
| zap-program | Zap on-chain program | - |
Metsumi is Meteora's CLI tool for launching tokens and executing on-chain actions with minimal configuration.
# Prerequisites: Node.js ≥ 18.0.0, pnpm ≥ 10.0.0
git clone https://github.com/MeteoraAg/meteora-invent.git
cd meteora-invent
npm install -g pnpm
pnpm install
# Create permissionless pool
pnpm dlmm-create-pool
# Seed liquidity
pnpm dlmm-seed-liquidity-lfg
pnpm dlmm-seed-liquidity-single-bin
# Control pool trading
pnpm dlmm-set-pool-status
# Create pools
pnpm damm-v2-create-balanced-pool
pnpm damm-v2-create-one-sided-pool
# Manage liquidity
pnpm damm-v2-add-liquidity
pnpm damm-v2-remove-liquidity
pnpm damm-v2-split-position
# Claim fees
pnpm damm-v2-claim-position-fee
# Create bonding curve
pnpm dbc-create-config
pnpm dbc-create-pool
# Trade on curve
pnpm dbc-swap
# Graduate to AMM
pnpm dbc-migrate-to-damm-v1
pnpm dbc-migrate-to-damm-v2
# Alpha Vault for anti-bot launches
pnpm alpha-vault-create
# Presale Vault (beta)
pnpm presale-vault-create
Configurations are stored in studio/config/:
dlmm_config.jsonc - DLMM pool settingsdamm_v1_config.jsonc - DAMM v1 settingsdamm_v2_config.jsonc - DAMM v2 settingsdbc_config.jsonc - Bonding curve settingsalpha_vault_config.jsonc - Alpha vault settingsmeteora/
├── 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
Weekly Installs
90
Repository
GitHub Stars
68
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykFail
Installed on
opencode76
gemini-cli76
codex75
github-copilot72
cursor72
amp68
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
120,000 周安装
靶标研究工具:9条路径全面收集药物靶点情报,支持基因符号、UniProt ID识别
178 周安装
skybridge:为大型语言模型(LLM)构建交互式AI应用的工具与框架
179 周安装
MongoDB Atlas配置检查器 - 验证连接字符串、环境变量和数据库设置
78 周安装
Hummingbot 交易机器人 AI 技能:自动化加密货币交易与 DeFi 策略管理
183 周安装
网站克隆技能:多智能体工作流实现像素级网站克隆,支持React + Tailwind CSS
180 周安装
Supermemory:AI智能体记忆基础设施 - 长期/短期记忆、RAG语义搜索与知识图谱
179 周安装
FEESngU3neckdwib9X3KWqdL7Mjmqk9XNp3uh5JbP4KP| Zap | zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz |
| Anti-bot launch protection |
| - |
| m3m3 | Stake-for-fee SDK | - |