meteora

Par elophanto · elophanto

Suite SDK DeFi Meteora complète pour créer des pools de liquidité, des AMM, des courbes de bonding, des vaults, des lancements de tokens et des opérations zap sur Solana. À utiliser lors de l'intégration des fonctionnalités DLMM, DAMM v2, DAMM v1, Dynamic Bonding Curves, Alpha Vaults, Zap ou Stake-for-Fee.

npx skills add https://github.com/elophanto/elophanto --skill meteora

Guide de développement du protocole Meteora

Guide complet pour construire des applications Solana DeFi avec la suite de SDKs de Meteora - l'infrastructure de liquidité leader sur Solana.

Qu'est-ce que Meteora ?

Meteora est la couche de liquidité première de Solana, alimentant l'infrastructure qui connecte les fournisseurs de liquidité (LPs), les lanceurs de tokens et les traders. Elle offre :

  • 2 milliards de dollars+ de valeur totale verrouillée sur tous les protocoles
  • Plusieurs types d'AMM - DLMM (concentré), DAMM v2/v1 (produit constant)
  • Infrastructure de lancement de tokens - Courbes de liaison dynamiques, protection anti-bot Alpha Vault
  • Optimisation des rendements - Vaults dynamiques, Stake-for-Fee (M3M3)
  • Outils pour développeurs - SDKs TypeScript/Go, outils CLI, Zap pour entrée mono-token

Pourquoi utiliser Meteora ?

Fonctionnalité Avantage
Coût bas de création de pool 0,022 SOL (vs 0,25+ SOL chez les concurrents)
Frais dynamiques Frais ajustés à la volatilité maximisent les rendements des LPs
Protection anti-snipe Planificateurs de frais et Alpha Vault préviennent l'exploitation par bots
Support Token-2022 Compatibilité complète avec Token Extensions
Permissionless Créez des pools, farms et lancements sans approbation
Auto-graduation Les courbes de liaison migrent automatiquement vers les pools AMM

Aperçu

Meteora fournit une pile d'infrastructure DeFi complète sur Solana :

  • DLMM (Dynamic Liquidity Market Maker) : Liquidité concentrée avec frais dynamiques
  • DAMM v2 (Dynamic AMM) : AMM produit constant nouvelle génération avec NFTs de position
  • DAMM v1 (Legacy AMM) : AMM produit constant original avec pools stables/pondérés
  • Courbe de liaison dynamique : Courbes de lancement de tokens personnalisables avec auto-graduation
  • Dynamic Vault : Vaults de tokens optimisés pour le rendement
  • Alpha Vault : Protection anti-bot pour lancements de tokens
  • Stake-for-Fee (M3M3) : Récompenses de staking à partir des frais de trading
  • Zap SDK : Entrée/sortie mono-token pour positions de liquidité
  • Presale Vault (Bêta) : Infrastructure de présale de tokens

Démarrage rapide

Installation

# SDK DLMM - Liquidité concentrée
npm install @meteora-ag/dlmm @coral-xyz/anchor @solana/web3.js

# SDK DAMM v2 - AMM produit constant nouvelle génération
npm install @meteora-ag/cp-amm-sdk @solana/web3.js

# SDK DAMM v1 - AMM hérité (pools stables, pools pondérés)
npm install @meteora-ag/dynamic-amm @solana/web3.js @coral-xyz/anchor

# SDK Courbe de liaison dynamique - Lancements de tokens
npm install @meteora-ag/dynamic-bonding-curve-sdk

# SDK Vault - Optimisation des rendements
npm install @meteora-ag/vault-sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token

# SDK Alpha Vault - Protection anti-bot
npm install @meteora-ag/alpha-vault

# SDK Stake-for-Fee (M3M3) - Staking de frais
npm install @meteora-ag/m3m3 @coral-xyz/anchor @solana/web3.js @solana/spl-token

# Zap SDK - Entrée/sortie mono-token (nécessite une clé API Jupiter)
npm install @meteora-ag/zap-sdk

# SDK Pool Farms - Création et staking de farms
npm install @meteora-ag/farming

Adresses des programmes

Programme Adresse Mainnet/Devnet
DLMM LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
DAMM v2 cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
DAMM v1 Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
Courbe de liaison dynamique dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
Dynamic Vault 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi
Stake-for-Fee FEESngU3neckdwib9X3KWqdL7Mjmqk9XNp3uh5JbP4KP
Zap zapvX9M3uf5pvy4wRPAbQgdQsM1xmuiFnkfHKPvwMiz

SDK DLMM (Dynamic Liquidity Market Maker)

Le SDK DLMM fournit un accès programmatique au protocole de liquidité concentrée de Meteora avec frais dynamiques basés sur la volatilité.

Configuration de base

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');

// Créer une instance DLMM pour un pool existant
const dlmm = await DLMM.create(connection, poolAddress);

// Créer plusieurs pools
const dlmmPools = await DLMM.createMultiple(connection, [pool1, pool2, pool3]);

Opérations essentielles

Obtenir le Bin actif (prix actuel)

const activeBin = await dlmm.getActiveBin();
console.log('ID du Bin actif :', activeBin.binId);
console.log('Prix :', activeBin.price);
console.log('Montant X :', activeBin.xAmount.toString());
console.log('Montant Y :', activeBin.yAmount.toString());

Conversions de prix et de bin

// Obtenir le prix à partir de l'ID du bin
const price = dlmm.getPriceOfBinByBinId(binId);

// Obtenir l'ID du bin à partir du prix
const binId = dlmm.getBinIdFromPrice(price, true); // true = arrondir vers le bas

// Convertir vers/depuis la représentation en lamports
const lamportPrice = dlmm.toPricePerLamport(21.23);
const realPrice = dlmm.fromPricePerLamport(lamportPrice);

// Obtenir les bins dans une plage
const bins = await dlmm.getBinsBetweenLowerAndUpperBound(minBinId, maxBinId);

// Obtenir les bins autour du bin actif
const surroundingBins = await dlmm.getBinsAroundActiveBin(10); // 10 bins de chaque côté

Opérations de swap

import { BN } from '@coral-xyz/anchor';

// Obtenir un devis de swap
const swapAmount = new BN(1_000_000); // 1 USDC (6 décimales)
const swapForY = true; // Échanger X pour Y
const slippageBps = 100; // 1% de glissement

const binArrays = await dlmm.getBinArrayForSwap(swapForY);
const swapQuote = dlmm.swapQuote(swapAmount, swapForY, slippageBps, binArrays);

console.log('Montant entrant :', swapQuote.consumedInAmount.toString());
console.log('Montant sortant :', swapQuote.outAmount.toString());
console.log('Montant sortant min :', swapQuote.minOutAmount.toString());
console.log('Impact de prix :', swapQuote.priceImpact);
console.log('Frais :', swapQuote.fee.toString());

// Exécuter le 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]);

Gestion de la liquidité

import { StrategyType } from '@meteora-ag/dlmm';

// Obtenir les positions de l'utilisateur
const positions = await dlmm.getPositionsByUserAndLbPair(wallet.publicKey);

// Initialiser une position et ajouter de la liquidité avec stratégie
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,
  },
});

// Ajouter de la liquidité à une position existante
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,
  },
});

// Retirer de la liquidité
const removeLiquidityTx = await dlmm.removeLiquidity({
  position: position.publicKey,
  user: wallet.publicKey,
  binIds: position.positionData.positionBinData.map(b => b.binId),
  bps: new BN(10000), // 100% (points de base)
  shouldClaimAndClose: true,
});

Réclamer les frais et récompenses

// Obtenir les frais de swap réclamables
const claimableFees = await DLMM.getClaimableSwapFee(connection, position.publicKey);
console.log('Frais réclamables X :', claimableFees.feeX.toString());
console.log('Frais réclamables Y :', claimableFees.feeY.toString());

// Obtenir les récompenses LM réclamables
const claimableRewards = await DLMM.getClaimableLMReward(connection, position.publicKey);

// Réclamer les frais de swap
const claimFeeTx = await dlmm.claimSwapFee({
  owner: wallet.publicKey,
  position: position.publicKey,
});

// Réclamer tous les frais de plusieurs positions
const claimAllFeesTx = await dlmm.claimAllSwapFee({
  owner: wallet.publicKey,
  positions: positions.map(p => p.publicKey),
});

// Réclamer les récompenses LM
const claimRewardTx = await dlmm.claimLMReward({
  owner: wallet.publicKey,
  position: position.publicKey,
});

// Réclamer toutes les récompenses
const claimAllTx = await dlmm.claimAllRewards({
  owner: wallet.publicKey,
  positions: positions.map(p => p.publicKey),
});

Stratégies de position

import { StrategyType } from '@meteora-ag/dlmm';

// Stratégies disponibles
StrategyType.SpotOneSide      // Liquidité unilatérale au prix actuel
StrategyType.CurveOneSide     // Distribution courbe d'un côté
StrategyType.BidAskOneSide    // Distribution achat/vente d'un côté
StrategyType.SpotBalanced     // Équilibré autour du prix actuel
StrategyType.CurveBalanced    // Distribution courbe autour du prix actuel
StrategyType.BidAskBalanced   // Distribution achat/vente autour du prix actuel
StrategyType.SpotImBalanced   // Distribution spot déséquilibrée
StrategyType.CurveImBalanced  // Distribution courbe déséquilibrée
StrategyType.BidAskImBalanced // Distribution achat/vente déséquilibrée

SDK DAMM v2 (CP-AMM)

Le SDK DAMM v2 fournit une interface complète pour l'AMM produit constant nouvelle génération de Meteora avec des améliorations significatives par rapport à la V1.

Fonctionnalités clés de DAMM V2 (Nouveau en 2025)

Fonctionnalité Description
Frais dynamiques Planificateur de frais optionnel avec mécanisme anti-sniper
NFTs de position Les LPs reçoivent un NFT transférable au lieu d'un token LP
Support Token2022 Support complet de la norme Token Extensions
Liquidité verrouillée Options de verrouillage de liquidité intégrées
Farms permissionless Créer des farms sans approbation du protocole
Coûts plus bas Création de pools à seulement 0,022 SOL (vs 0,25 SOL sur l'ancien DLMM)

Planificateur de frais (Anti-snipe)

Le planificateur de frais commence avec des frais de swap élevés qui diminuent au fil du temps, protégeant contre le snipping :

// Créer un pool avec planificateur de frais
const createPoolTx = await cpAmm.createCustomPool({
  // ... autres paramètres
  poolFees: {
    baseFee: {
      cliffFeeNumerator: new BN(10000000), // Frais initiaux de 1%
      numberOfPeriod: 10,
      reductionFactor: new BN(500000),     // Réduire de 0,05% chaque période
      periodFrequency: new BN(300),        // Tous les 5 minutes
      feeSchedulerMode: 1,                 // Réduction linéaire
    },
    // ...
  },
});

Configuration de base

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);

Gestion des pools

Créer un pool

// Créer un pool standard à partir d'une 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),
});

// Créer un pool personnalisé avec paramètres spécifiques
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 = immédiat
  collectFeeMode: 0,
});

Récupérer l'état du pool

// Récupérer un pool unique
const poolState = await cpAmm.fetchPoolState(poolAddress);
console.log('Vault Token A :', poolState.tokenAVault.toString());
console.log('Vault Token B :', poolState.tokenBVault.toString());
console.log('Prix racine carrée :', poolState.sqrtPrice.toString());
console.log('Liquidité :', poolState.liquidity.toString());

// Récupérer tous les pools
const allPools = await cpAmm.getAllPools();

// Vérifier si un pool existe
const exists = await cpAmm.isPoolExist(tokenAMint, tokenBMint);

Opérations de position

Créer et gérer des positions

// Créer une position
const createPositionTx = await cpAmm.createPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
});

// Ajouter de la liquidité
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),
});

// Obtenir un devis de dépôt
const depositQuote = cpAmm.getDepositQuote({
  poolState,
  tokenAAmount: new BN(100_000_000),
  tokenBAmount: new BN(100_000_000),
  slippageBps: 100,
});

// Retirer de la liquidité
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),
});

// Obtenir un devis de retrait
const withdrawQuote = cpAmm.getWithdrawQuote({
  poolState,
  positionState,
  liquidityAmount: new BN(50_000_000),
  slippageBps: 100,
});

// Fusionner des positions
const mergePositionTx = await cpAmm.mergePosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  sourcePositions: [position1, position2],
  destinationPosition: destPosition,
});

// Diviser une position
const splitPositionTx = await cpAmm.splitPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  percentage: 50, // Diviser 50%
  newPosition: newPositionKeypair.publicKey,
});

Swapping

import { SwapMode } from '@meteora-ag/cp-amm-sdk';

// Modes de swap disponibles
SwapMode.ExactIn     // Spécifier le montant exact en entrée
SwapMode.ExactOut    // Spécifier le montant exact en sortie
SwapMode.PartialFill // Autoriser les remplissages partiels

// Obtenir un devis de swap
const quote = cpAmm.getQuote({
  poolState,
  inputTokenMint: tokenAMint,
  outputTokenMint: tokenBMint,
  amount: new BN(1_000_000),
  slippageBps: 100,
  swapMode: SwapMode.ExactIn,
});

console.log('Montant en entrée :', quote.inputAmount.toString());
console.log('Montant en sortie :', quote.outputAmount.toString());
console.log('Sortie minimale :', quote.minimumOutputAmount.toString());
console.log('Impact de prix :', quote.priceImpact);
console.log('Frais :', quote.fee.toString());

// Exécuter le 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,
});

Gestion des frais et récompenses

// Réclamer les frais de position
const claimFeeTx = await cpAmm.claimPositionFee({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
});

// Initialiser une récompense (créateur de pool uniquement)
const initRewardTx = await cpAmm.initializeReward({
  pool: poolAddress,
  rewardMint,
  rewardDuration: new BN(86400 * 7), // 7 jours
  funder: wallet.publicKey,
});

// Financer une récompense
const fundRewardTx = await cpAmm.fundReward({
  pool: poolAddress,
  rewardMint,
  amount: new BN(1_000_000_000),
  funder: wallet.publicKey,
});

// Réclamer les récompenses
const claimRewardTx = await cpAmm.claimReward({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  rewardIndex: 0,
});

Verrouillage de position et vesting

// Verrouiller une position avec calendrier de vesting
const lockPositionTx = await cpAmm.lockPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  vestingDuration: new BN(86400 * 30), // 30 jours
  cliffDuration: new BN(86400 * 7),    // Falaise de 7 jours
});

// Verrouillage permanent (irréversible)
const permanentLockTx = await cpAmm.permanentLockPosition({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
  liquidityAmount: new BN(50_000_000), // Montant à verrouiller de manière permanente
});

// Actualiser le vesting (déverrouiller les tokens disponibles)
const refreshVestingTx = await cpAmm.refreshVesting({
  owner: wallet.publicKey,
  pool: poolAddress,
  position: positionAddress,
});

// Vérifier si une position est verrouillée
const isLocked = cpAmm.isLockedPosition(positionState);

Fonctions d'assistance

// Conversions de prix
const price = cpAmm.getPriceFromSqrtPrice(sqrtPrice, tokenADecimals, tokenBDecimals);
const sqrtPrice = cpAmm.getSqrtPriceFromPrice(price, tokenADecimals, tokenBDecimals);

// Conversions de frais
const feeNumerator = cpAmm.bpsToFeeNumerator(25); // 0,25% = 25 bps
const bps = cpAmm.feeNumeratorToBps(feeNumerator);

// Calculs de glissement
const minAmount = cpAmm.getAmountWithSlippage(amount, slippageBps, false);
const maxAmount = cpAmm.getMaxAmountWithSlippage(amount, slippageBps);

// Obtenir l'impact de prix
const priceImpact = cpAmm.getPriceImpact(amountIn, amountOut, currentPrice);

// Obtenir le delta de liquidité
const liquidityDelta = cpAmm.getLiquidityDelta({
  poolState,
  tokenAAmount: new BN(100_000_000),
  tokenBAmount: new BN(100_000_000),
});

SDK Courbe de liaison dynamique

Le SDK Courbe de liaison dynamique permet de construire des lancements de tokens personnalisés avec graduation automatique vers DAMM.

Configuration de base

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');

Flux de lancement de token

La DBC suit une progression en 5 étapes :

  1. Configuration du partenaire : Configurer les paramètres du pool
  2. Création du pool : Le créateur lance la courbe de liaison
  3. Phase de trading : Les utilisateurs achètent/vendent sur la courbe
  4. Graduation : Migration automatique vers DAMM v1 ou v2 quand le seuil est atteint
  5. Post-graduation : Trader sur l'AMM gradué

Créer un pool avec courbe de liaison

// Créer un nouveau pool avec courbe de liaison
const createPoolTx = await dbc.createPool({
  creator: wallet.publicKey,
  baseMint: baseTokenMint,
  quoteMint: quoteTokenMint, // Généralement SOL ou USDC
  config: configAddress,
  baseAmount: new BN(1_000_000_000_000), // Offre totale
  quoteAmount: new BN(0), // Devis initial (généralement 0)
  name: 'My Token',
  symbol: 'MTK',
  uri: 'https://arweave.net/metadata.json',
});

Trading sur la courbe de liaison

// Obtenir un devis d'achat de tokens
const buyQuote = await dbc.getBuyQuote({
  pool: poolAddress,
  quoteAmount: new BN(1_000_000_000), // 1 SOL
});

console.log('Tokens à recevoir :', buyQuote.baseAmount.toString());
console.log('Prix par token :', buyQuote.price.toString());

// Exécuter l'achat
const buyTx = await dbc.buy({
  payer: wallet.publicKey,
  pool: poolAddress,
  quoteAmount: new BN(1_000_000_000),
  minBaseAmount: buyQuote.minBaseAmount,
});

// Obtenir un devis de vente de tokens
const sellQuote = await dbc.getSellQuote({
  pool: poolAddress,
  baseAmount: new BN(1_000_000), // Tokens à vendre
});

// Exécuter la vente
const sellTx = await dbc.sell({
  payer: wallet.publicKey,
  pool: poolAddress,
  baseAmount: new BN(1_000_000),
  minQuoteAmount: sellQuote.minQuoteAmount,
});

Graduation du pool

// Vérifier le statut de graduation
const poolState = await dbc.fetchPoolState(poolAddress);
const isGraduated = poolState.graduated;
const graduationThreshold = poolState.graduationThreshold;
const currentMarketCap = poolState.currentMarketCap;

// Migration manuelle vers DAMM v2 (si la graduation automatique n'a pas déclenché)
const migrateTx = await dbc.migrateToDAMMV2({
  pool: poolAddress,
  payer: wallet.publicKey,
});

// Pour la migration DAMM v1 (plus d'étapes requises)
// 1. Créer les métadonnées
const createMetadataTx = await dbc.createMetadata({
  pool: poolAddress,
  payer: wallet.publicKey,
});

// 2. Exécuter la migration
const migrateToDammV1Tx = await dbc.migrateToDAMMV1({
  pool: poolAddress,
  payer: wallet.publicKey,
});

// 3. Verrouiller les tokens LP (optionnel)
const lockLpTx = await dbc.lockLpTokens({
  pool: poolAddress,
  payer: wallet.publicKey,
  lockDuration: new BN(86400 * 365), // 1 an
});

// 4. Réclamer les tokens LP après l'expiration du verrou
const claimLpTx = await dbc.claimLpTokens({
  pool: poolAddress,
  payer: wallet.publicKey,
});

Options de configuration des frais

La DBC supporte plusieurs configurations de paliers de frais :

Palier Frais (bps) Cas d'usage
1 25 Lancements standard
2 50 Tokens communautaires
3 100 Tokens meme
4 200 Haute volatilité
5 400 Expérimental
6 600 Protection maximale

SDK Dynamic Vault

Le SDK Vault fournit un stockage de tokens optimisé pour le rendement avec gestion automatique de stratégie.

Configuration de base

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');

// Créer une instance de vault
const vault = await VaultImpl.create(connection, tokenMint);

// Avec ID d'affilié (pour intégrations partenaires)
const vaultWithAffiliate = await VaultImpl.create(connection, tokenMint, {
  affiliateId: new PublicKey('PARTNER_KEY'),
});

Opérations de vault

// Obtenir les informations du vault
const lpSupply = vault.lpSupply; // Ou utiliser vault.getVaultSupply() pour rafraîchir
const withdrawableAmount = await vault.getWithdrawableAmount();

console.log('Offre totale LP :', lpSupply.toString());
console.log('Montant verrouillé :', withdrawableAmount.locked.toString());
console.log('Montant déverrouillé :', withdrawableAmount.unlocked.toString());

// Obtenir le solde de l'utilisateur
const userLpBalance = await vault.getUserBalance(wallet.publicKey);

// Déposer des tokens
const depositTx = await vault.deposit(wallet.publicKey, new BN(1_000_000_000));
await sendAndConfirmTransaction(connection, depositTx, [wallet]);

// Retirer des tokens
const withdrawTx = await vault.withdraw(wallet.publicKey, new BN(500_000_000));
await sendAndConfirmTransaction(connection, withdrawTx, [wallet]);

Calculs de parts

import { getAmountByShare, getUnmintAmount } from '@meteora-ag/vault-sdk';

// Convertir les tokens LP en montant sous-jacent
const underlyingAmount = getAmountByShare(
  userLpBalance,      // Tokens LP de l'utilisateur
  unlockedAmount,     // Solde déverrouillé du vault
  lpSupply            // Offre totale LP
);

// Calculer les tokens LP nécessaires pour un retrait spécifique
const lpNeeded = getUnmintAmount(
  targetWithdrawAmount, // Montant à retirer
  unlockedAmount,       // Solde déverrouillé du vault
  lpSupply              // Offre totale LP
);

Intégration d'affilié

// Obtenir les infos d'affilié
const affiliateInfo = await vault.getAffiliateInfo();
console.log('Partenaire :', affiliateInfo.partner.toString());
console.log('Taux de frais :', affiliateInfo.feeRate);
console.log('Frais en attente :', affiliateInfo.outstandingFee.toString());

SDK Alpha Vault

Le SDK Alpha Vault fournit une protection anti-bot pour les lancements de tokens, assurant une distribution équitable.

Configuration de base

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);

Opérations de vault

// Obtenir l'état du vault
const vaultState = await alphaVault.getVaultState();
console.log('Total déposé :', vaultState.totalDeposited.toString());
console.log('Dépôt maximum :', vaultState.maxDeposit.toString());
console.log('Heure de début :', vaultState.startTime.toString());
console.log('Heure de fin :', vaultState.endTime.toString());

// Déposer dans le vault (pendant la fenêtre de dépôt)
const depositTx = await alphaVault.deposit({
  payer: wallet.publicKey,
  amount: new BN(1_000_000_000), // 1 SOL
});

// Retirer du vault (si autorisé)
const withdrawTx = await alphaVault.withdraw({
  payer: wallet.publicKey,
  amount: new BN(500_000_000),
});

// Réclamer les tokens (après le lancement)
const claimTx = await alphaVault.claimTokens({
  payer: wallet.publicKey,
});

// Obtenir l'allocation de l'utilisateur
const allocation = await alphaVault.getUserAllocation(wallet.publicKey);
console.log('Montant déposé :', allocation.depositAmount.toString());
console.log('Allocation de token :', allocation.tokenAllocation.toString());
console.log('Réclamé :', allocation.claimed);

SDK Stake-for-Fee (M3M3)

Le SDK M3M3 permet de staquer des tokens pour gagner des frais de l'activité de trading.

Configuration de base

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);

Opérations de staking

// Obtenir le stake de l'utilisateur et le solde réclamable
const userBalance = await m3m3.getUserStakeAndClaimBalance(wallet.publicKey);
console.log('Montant staké :', userBalance.stakedAmount.toString());
console.log('Frais réclamables :', userBalance.claimableFees.toString());

// Staquer des tokens
const stakeTx = await m3m3.stake(new BN(1_000_000_000), wallet.publicKey);
await sendAndConfirmTransaction(connection, stakeTx, [wallet]);

// Réclamer les frais accumulés
const claimTx = await m3m3.claimFee(wallet.publicKey, null); // null = réclamer tout
await sendAndConfirmTransaction(connection, claimTx, [wallet]);

// Initier un unstake (commence la période de verrouillage)
const unstakeTx = await m3m3.unstake(
  new BN(500_000_000),
  destinationTokenAccount,
  wallet.publicKey
);

// Annuler un unstake en attente
const cancelUnstakeTx = await m3m3.cancelUnstake(escrowAddress, wallet.publicKey);

// Compléter le retrait (après la période de verrouillage)
const withdrawTx = await m3m3.withdraw(escrowAddress, wallet.publicKey);

// Obtenir la période d'unstake
const unstakePeriod = m3m3.getUnstakePeriod(); // Durée en secondes

// Rafraîchir les états
await m3m3.refreshStates();

SDK DAMM v1 (Legacy Dynamic AMM)

Le SDK DAMM v1 est l'AMM produit constant original, toujours largement utilisé pour les pools stables, les pools pondérés et les pools LST. Bien que DAMM v2 soit recommandé pour les nouveaux pools, v1 reste entièrement supporté.

Configuration de base

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');

// Créer une instance de pool
const pool = await AmmImpl.create(connection, new PublicKey('POOL_ADDRESS'));

// Ou créer plusieurs pools
const pools = await AmmImpl.createMultiple(connection, [poolAddress1, poolAddress2]);

Création de pool

// Créer un pool produit constant permissionless
const createPoolTx = await AmmImpl.createPermissionlessConstantProductPoolWithConfig(
  connection,
  wallet.publicKey,
  tokenAMint,
  tokenBMint,
  tokenAAmount,
  tokenBAmount,
  configAddress, // Configuration des frais
  {
    lockLiquidity: false, // Verrouiller la liquidité initiale
    activationPoint: null, // Activation retardée optionnelle
  }
);

// Créer un pool memecoin (optimisé pour lancements de tokens)
const memePoolTx = await AmmImpl.createPermissionlessConstantProductMemecoinPoolWithConfig(
  connection,
  wallet.publicKey,
  tokenAMint,
  tokenBMint,
  tokenAAmount,
  tokenBAmount,
  configAddress,
  {
    lockLiquidity: true, // Verrouiller la liquidité pour la confiance
  }
);

Requêtes d'état de pool

// Obtenir l'offre de token LP
const lpSupply = await pool.getLpSupply();

// Obtenir le solde du token LP de l'utilisateur
const userBalance = await pool.getUserBalance(wallet.publicKey);

// Obtenir un devis de swap
const swapQuote = pool.getSwapQuote(
  inputMint,
  inputAmount,
  slippageBps // 100 = 1%
);
console.log('Montant en sortie :', swapQuote.outAmount.toString());
console.log('Frais :', swapQuote.fee.toString());
console.log('Impact de prix :', swapQuote.priceImpact);

// Obtenir un devis de dépôt
const depositQuote = pool.getDepositQuote(
  tokenAAmount,
  tokenBAmount,
  true, // dépôt équilibré
  slippageBps
);
console.log('Tokens LP à recevoir :', depositQuote.lpAmount.toString());

// Obtenir un devis de retrait
const withdrawQuote = pool.getWithdrawQuote(
  lpAmount,
  slippageBps
);
console.log('Token A en sortie :', withdrawQuote.tokenAAmount.toString());
console.log('Token B en sortie :', withdrawQuote.tokenBAmount.toString());

// Rafraîchir l'état du pool
await pool.updateState();

Opérations de liquidité

// Déposer de la liquidité
const depositTx = await pool.deposit(
  wallet.publicKey,
  tokenAAmount,
  tokenBAmount,
  lpAmountMin // Tokens LP minimum à recevoir
);

// Retirer de la liquidité
const withdrawTx = await pool.withdraw(
  wallet.publicKey,
  lpAmount,
  tokenAMin, // Token A minimum à recevoir
  tokenBMin  // Token B minimum à recevoir
);

Swapping

// Exécuter un swap
const swapTx = await pool.swap(
  wallet.publicKey,
  inputMint,
  inputAmount,
  minOutputAmount
);

Types de pools

Type de pool Cas d'usage Fonctionnalités
Produit constant Paires de trading générales AMM x*y=k standard
Stable Paires stablecoins (USDC/USDT) Glissement inférieur pour actifs rattachés
Pondéré Pools déséquilibrés (80/20) Poids de token personnalisés
LST Tokens de staking liquide Optimisé pour dérivés de staking

SDK Zap

Le SDK Zap permet une entrée et une sortie mono-token pour les positions de liquidité, gérant automatiquement les swaps via Jupiter ou le routage intégré du pool.

Configuration de base

import { Connection, PublicKey } from '@solana/web3.js';
import { Zap } from '@meteora-ag/zap-sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com');

// La clé API Jupiter est requise (obtenir depuis 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 dans une position DLMM

// Zap mono-token dans une position de liquidité concentrée DLMM
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, // Position existante ou nouvelle
  strategyType: 'SpotBalanced', // Stratégie de distribution
  minBinId: activeBinId - 10,
  maxBinId: activeBinId + 10,
});

await sendAndConfirmTransaction(connection, zapInDlmmTx, [wallet]);

Zap dans une position DAMM v2

// Zap mono-token dans un pool DAMM v2
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]);

Opérations de sortie Zap

// Zap sortie de DLMM vers mono-token
const zapOutDlmmTx = await zap.zapOutDlmm({
  user: wallet.publicKey,
  lbPairAddress: dlmmPoolAddress,
  outputMint: SOL_MINT, // Recevoir tout en SOL
  positionPubkey: positionAddress,
  percentageToZap: 100, // 100% de la position
  slippageBps: 100,
});

// Zap sortie de DAMM v2 vers mono-token
const zapOutDammV2Tx = await zap.zapOutDammV2({
  user: wallet.publicKey,
  poolAddress: dammV2PoolAddress,
  outputMint: USDC_MINT,
  positionPubkey: positionAddress,
  percentageToZap: 50, // 50% de la position
  slippageBps: 100,
});

Zap via Jupiter

// Obtenir un devis Jupiter pour routage optimal
const jupiterQuote = await zap.getJupiterQuote({
  inputMint: SOL_MINT,
  outputMint: USDC_MINT,
  amount: new BN(1_000_000_000),
  slippageBps: 50,
});

// Zap sortie via agrégateur Jupiter
const zapOutJupiterTx = await zap.zapOutThroughJupiter({
  user: wallet.publicKey,
  inputMint: tokenMint,
  outputMint: SOL_MINT,
  jupiterSwapResponse: jupiterQuote,
  maxSwapAmount: new BN(1_000_000_000),
  percentageToZap: 100,
});

Fonctions d'assistance

// Obtenir le programme de token à partir du mint
const tokenProgram = await zap.getTokenProgramFromMint(connection, mintAddress);

// Obtenir l'instruction de swap Jupiter
const swapIx = await zap.getJupiterSwapInstruction(jupiterQuote, wallet.publicKey);

SDK Pool Farms

Le SDK Pool Farms permet de créer et gérer des farms d'exploitation de liquidité sur les pools DAMM v1.

Configuration de base

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);

Opérations de farm

// Déposer des tokens LP dans la farm
const depositTx = await farm.deposit(
  wallet.publicKey,
  lpAmount
);

// Retirer des tokens LP de la farm
const withdrawTx = await farm.withdraw(
  wallet.publicKey,
  lpAmount
);

// Réclamer les récompenses de farming
const claimTx = await farm.claim(wallet.publicKey);

// Obtenir les récompenses en attente
const pendingRewards = await farm.getPendingRewards(wallet.publicKey);
console.log('Récompenses en attente :', pendingRewards.toString());

// Obtenir les infos de stake de l'utilisateur
const stakeInfo = await farm.getUserStakeInfo(wallet.publicKey);
console.log('Montant staké :', stakeInfo.amount.toString());

Motifs courants

Motif 1 : Initialiser avec 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(/* votre clé secrète */);
const wallet = new Wallet(keypair);

const provider = new AnchorProvider(connection, wallet, {
  commitment: 'confirmed',
});

// Utilisez maintenant provider.wallet.publicKey pour les transactions
const dlmm = await DLMM.create(connection, poolAddress);

Motif 2 : Gestion des erreurs

try {
  const swapTx = await dlmm.swap(swapParams);
  const txHash = await sendAndConfirmTransaction(connection, swapTx, [wallet]);
  console.log('Succès :', txHash);
} catch (error) {
  if (error.message.includes('Slippage')) {
    console.error('Glissement dépassé - essayez d\'augmenter la tolérance');
  } else if (error.message.includes('InsufficientFunds')) {
    console.error('Solde insuffisant pour ce trade');
  } else if (error.message.includes('PoolNotFound')) {
    console.error('Le pool n\'existe pas');
  } else {
    throw error;
  }
}

Motif 3 : Opérations par lot

import { Transaction } from '@solana/web3.js';

// Combiner plusieurs instructions dans une 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]);

Motif 4 : Surveiller l'état du pool

// Rafraîchir périodiquement l'état du pool
async function monitorPool(dlmm: DLMM, interval: number = 5000) {
  setInterval(async () => {
    await dlmm.refetchStates();
    const activeBin = await dlmm.getActiveBin();
    console.log(`Prix actuel : ${activeBin.price}`);

    const feeInfo = dlmm.getFeeInfo();
    console.log(`Taux de frais actuel : ${feeInfo.baseFeeRate}%`);
  }, interval);
}

Nouvelles fonctionnalités (2025-2026)

Ordres limites DLMM

DLMM supporte désormais les ordres limites sans frais sur chaîne :

// Placer un ordre limite sur DLMM
const limitOrderTx = await dlmm.placeLimitOrder({
  user: wallet.publicKey,
  binId: targetBinId,
  amount: new BN(1_000_000),
  side: "buy", // ou "sell"
});

Auto Vaults (Arrivée Q1 2026)

Les auto vaults composent automatiquement les frais et supportent des stratégies de market-making personnalisées via des APIs. Ces vaults aident les utilisateurs à gagner plus avec moins d'effort.

Courbe universelle (DBC)

La courbe de liaison dynamique supporte maintenant les courbes programmables à 16 points, donnant aux LPs un contrôle précis sur les trajectoires de prix :

// Créer un pool avec courbe personnalisée
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 },
    // ... jusqu'à 16 points
  ],
});

Presale Vault (Bêta)

Presale Vault est l'infrastructure de présale de tokens de Meteora, actuellement en bêta. Elle permet aux projets de lancer des présales avec des mécanismes de protection intégrés.

Note : Presale Vault est en développement actif. Consultez la documentation Meteora pour les dernières informations.


Dépôts GitHub

SDKs TypeScript

Dépôt Description Stars
dlmm-sdk SDK liquidité concentrée DLMM 280+
damm-v2-sdk SDK AMM produit constant DAMM v2 44+
damm-v1-sdk SDK legacy DAMM v1 126+
dynamic-bonding-curve-sdk Courbes de liaison pour lancement de tokens 35+
zap-sdk Entrée/sortie mono-token 2+
vault-sdk SDK vault dynamique -
alpha-vault-sdk Protection anti-bot pour lancement -
m3m3 SDK stake-for-fee -

SDKs Go

Dépôt Description
damm-v2-go Implémentation DAMM v2 en Go
dbc-go SDK Courbe de liaison dynamique en Go

Programmes essentiels (Rust)

Dépôt Description Stars
damm-v2 Programme DAMM v2 98+
dynamic-bonding-curve Programme DBC 86+
zap-program Programme on-chain Zap -

Meteora Invent (Outil CLI)

Metsumi est l'outil CLI de Meteora pour lancer des tokens et exécuter des actions on-chain avec une configuration minimale.

Installation

# Prérequis : 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

Commandes disponibles

Opérations DLMM

# Créer un pool permissionless
pnpm dlmm-create-pool

# Amorcer la liquidité
pnpm dlmm-seed-liquidity-lfg
pnpm dlmm-seed-liquidity-single-bin

# Contrôler le trading de pool
pnpm dlmm-set-pool-status

Opérations DAMM v2

# Créer des pools
pnpm damm-v2-create-balanced-pool
pnpm damm-v2-create-one-sided-pool

# Gérer la liquidité
pnpm damm-v2-add-liquidity
pnpm damm-v2-remove-liquidity
pnpm damm-v2-split-position

# Réclamer les frais
pnpm damm-v2-claim-position-fee

Opérations Courbe de liaison dynamique

# Créer une courbe de liaison
pnpm dbc-create-config
pnpm dbc-create-pool

# Trader sur la courbe
pnpm dbc-swap

# Graduer vers AMM
pnpm dbc-migrate-to-damm-v1
pnpm dbc-migrate-to-damm-v2

Opérations Vault

# Alpha Vault pour lancements anti-bot
pnpm alpha-vault-create

# Presale Vault (bêta)
pnpm presale-vault-create

Fichiers de configuration

Les configurations sont stockées dans studio/config/ :

  • dlmm_config.jsonc - Paramètres de pool DLMM
  • damm_v1_config.jsonc - Paramètres DAMM v1
  • damm_v2_config.jsonc - Paramètres DAMM v2
  • dbc_config.jsonc - Paramètres de courbe de liaison
  • alpha_vault_config.jsonc - Paramètres de vault alpha

Ressources


Structure de skill

meteora/
├── SKILL.md                          # Ce fichier
├── resources/
│   ├── dlmm-api-reference.md         # Référence API SDK DLMM complète
│   ├── damm-v2-api-reference.md      # Référence API SDK DAMM v2 complète
│   ├── damm-v1-api-reference.md      # Référence API SDK DAMM v1 complète
│   ├── zap-api-reference.md          # Référence API SDK Zap
│   ├── pool-farms-reference.md       # Référence SDK Pool Farms
│   ├── bonding-curve-reference.md    # Référence SDK DBC
│   ├── vault-api-reference.md        # Référence API SDK Vault
│   ├── alpha-vault-reference.md      # Référence SDK Alpha Vault
│   ├── m3m3-api-reference.md         # Référence API SDK Stake-for-Fee
│   ├── github-repos.md               # Tous les dépôts GitHub
│   └── program-addresses.md          # Toutes les adresses de programmes
├── examples/
│   ├── dlmm/
│   │   ├── swap.ts                   # Exemple de swap basique
│   │   ├── add-liquidity.ts          # Ajouter de la liquidité
│   │   └── claim-fees.ts             # Réclamer les frais/récompenses
│   ├── damm-v2/
│   │   ├── create-pool.ts            # Création de pool
│   │   ├── swap.ts                   # Échanger des tokens
│   │   └── manage-position.ts        # Gestion de position
│   ├── damm-v1/
│   │   └── basic-operations.ts       # Opérations de pool DAMM v1
│   ├── zap/
│   │   └── zap-operations.ts         # Exemples d'opérations Zap
│   ├── bonding-curve/
│   │   ├── create-token.ts           # Lancer un token sur courbe
│   │   ├── trade.ts                  # Acheter/vendre sur courbe
│   │   └── graduation.ts             # Graduation de pool
│   ├── vault/
│   │   └── deposit-withdraw.ts       # Opérations de vault
│   ├── alpha-vault/
│   │   └── participation.ts          # Participation Alpha vault
│   └── stake-for-fee/
│       └── staking.ts                # Opérations de staking
├── templates/
│   ├── trading-bot.ts                # Modèle de market making
│   ├── token-launch.ts               # Modèle de lancement de token
│   └── liquidity-manager.ts          # Modèle de gestion de LP
└── docs/
    ├── fee-structures.md             # Guide de configuration des frais
    ├── migration-guide.md            # Guide migration DBC vers DAMM
    ├── strategy-guide.md             # Guide des stratégies de liquidité
    └── troubleshooting.md            # Problèmes courants

Vérifier

  • Un appel RPC/SDK réel a été émis (mainnet, devnet ou validateur local) et le payload de réponse est capturé dans la transcription, pas juste paraphrasé
  • Chaque transaction a été simulée (simulateTransaction ou équivalent) avant tout étape de signature/envoi ; les logs de simulation sont joints
  • Pour toute transaction signée/envoyée, la signature résultante est enregistrée et confirmée sur chaîne (statut retourné par getSignatureStatuses ou URL d'explorateur)
  • Glissement, frais de priorité et limites d'unités de calcul ont été définis explicitement avec des valeurs numériques concrètes, pas laissés aux défauts de bibliothèque
  • Les adresses de compte, les mints et les IDs de programme utilisés correspondent aux adresses meteora-defi documentées pour le cluster ciblé (pas de mélange mainnet/devnet)
  • Le chemin d'erreur a été exercé au moins une fois (solde insuffisant, oracle obsolète, blockhash expiré, etc.) et la gestion des erreurs de l'agent a produit un message lisible .

Skills similaires