Skip to main content
Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Bannière de version. Toutes les démos ciblent @raydium-io/raydium-sdk-v2@0.2.42-alpha sur Solana mainnet-beta, vérifiées en avril 2026. Les identifiants de programme proviennent de reference/program-addresses via le SDK.

Configuration

Chaque démo de cette page correspond à un fichier dans raydium-sdk-V2-demo/src/clmm ; le lien GitHub est indiqué à côté de chaque section. L’initialisation suit le config.ts.template du dépôt de démo (source) — disableFeatureCheck: true est le réglage recommandé pour toute intégration non triviale :

Créer un pool CLMM

Source : src/clmm/createPool.ts
Le SDK :
  • Trie mint1/mint2 par ordre d’octets avant la dérivation.
  • Calcule sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Crée les comptes observation et tick_array_bitmap_extension.
  • Règle les frais de création du pool définis par ammConfig.

Ouvrir une position dans une plage choisie

Source : src/clmm/createPosition.ts
Le SDK calcule automatiquement les tick arrays touchés par la plage et regroupe les instructions InitTickArray pour ceux qui ne sont pas encore initialisés.

Augmenter la liquidité d’une position existante

Source : src/clmm/increaseLiquidity.ts

Réduire la liquidité (et collecter les frais en même temps)

Source : src/clmm/decreaseLiquidity.ts et src/clmm/closePosition.ts
Pour collecter uniquement les frais, appelez decreaseLiquidity avec liquidity = new BN(0). L’effet de bord de l’instruction est de solder tokens_fees_owed_{0,1} et de les transférer. Pour fermer entièrement la position après avoir vidé la liquidité et les frais, passez closePosition: true lors du dernier appel à decreaseLiquidity. Le SDK ajoute ClosePosition et brûle le NFT.

Collecter les récompenses

Source : src/clmm/harvestAllRewards.ts
harvestAllRewards parcourt chaque position de chaque pool fourni, regroupe les instructions CollectReward (et les éventuels UpdateRewardInfos) et les répartit sur plusieurs transactions si nécessaire.

Swap

Source : src/clmm/swap.ts
computeAmountOutFormat parcourt la carte des ticks hors chaîne en utilisant la même logique que le programme on-chain et retourne :
  • le montant de sortie attendu,
  • le montant de sortie minimum après slippage,
  • la liste des comptes tick-array que le swap effectif utilisera (remainingAccounts).
Transmettez toujours les remainingAccounts retournés par la simulation : si vous en fournissez trop peu, le swap échoue en cours de parcours avec TickArrayNotFound ; si vous en fournissez des obsolètes, vous gaspillez du compute.

Créer un pool CLMM personnalisable

createCustomizablePool est le nouveau point d’entrée qui expose les options de frais dynamiques et de frais unilatéraux au moment de la création du pool. Il accepte la même structure que createPool, plus trois paramètres supplémentaires :
createPool continue de fonctionner pour le chemin par défaut (frais fixes, sans limit order, sans frais dynamiques). Utilisez createCustomizablePool dès que vous avez besoin de l’un des trois nouveaux paramètres. Consultez products/clmm/instructions pour la liste des comptes on-chain.

Limit orders

Un limit order place l’entrée utilisateur sur un tick unique et est exécuté en mode FIFO lorsqu’un swap franchit ce tick. Les sorties sont poussées vers l’ATA du propriétaire au moment du règlement ; le propriétaire n’a pas besoin d’être en ligne pour être exécuté.

Ouvrir un limit order

Le SDK dérive le PDA LimitOrderState à partir de (pool, owner, tick, nonce), incrémente le LimitOrderNonce par (pool, owner) et insère l’ordre dans la file FIFO à ce tick.

Augmenter / réduire un order ouvert

decreaseLimitOrder ne peut retirer que la portion non exécutée de l’order ; la portion exécutée est verrouillée jusqu’au règlement. Les deux instructions échouent avec InvalidOrderPhase si l’order a déjà été intégralement rempli.

Régler un order exécuté

settleLimitOrder compare le unfilled_ratio_x64 de l’order avec le suivi de la cohorte, calcule la sortie exécutée et la transfère vers l’ATA du propriétaire. Le propriétaire peut appeler cette instruction lui-même ; limit_order_admin (un keeper opérationnel hors chaîne) peut également l’appeler au nom du propriétaire — la sortie revient toujours au propriétaire. Pour fermer les orders entièrement réglés et récupérer le loyer, utilisez closeLimitOrder (unitaire) ou closeAllLimitOrder (en lot). Pour régler plusieurs orders à la fois, settleAllLimitOrder regroupe autant d’appels SettleLimitOrder que possible dans une transaction v0.

Lister les orders en attente d’un portefeuille (hors chaîne)

L’endpoint des orders actifs retourne en une seule réponse les orders non exécutés et partiellement exécutés (totalAmount / filledAmount / pendingSettle distinguent les phases). Pour l’historique des orders fermés, utilisez /limit-order/history/order/list-by-user?wallet=… (par portefeuille, paginé via nextPageId) ; pour le journal complet des événements d’un order spécifique, utilisez /limit-order/history/event/list-by-pda?pda=….

Squelette CPI en Rust

Ordre des remaining accounts pour SwapV2 :
Si le swap n’a pas besoin de l’extension, omettez-la ; sinon elle est le premier remaining account.

Erreurs fréquentes

  • Tick endpoints hors espacementInvalidTickIndex. Utilisez toujours TickUtils.getPriceAndTick pour l’alignement.
  • Nombre insuffisant de tick arrays fournis dans SwapV2TickArrayNotFound. Utilisez computeAmountOutFormat pour obtenir la liste complète.
  • Position pleine plage sans l’extension bitmap → le PDA d’extension doit être accessible en écriture ; le SDK gère cela automatiquement.
  • Confondre sqrt_price_x64 avec price → l’erreur d’un facteur 2 est particulièrement douloureuse ici. En cas de doute, laissez le SDK calculer depuis un prix lisible par l’humain.
  • Collecter les récompenses trop fréquemment → chaque collecte coûte une transaction. Regroupez via harvestAllRewards sur plusieurs positions.
  • Brûler le NFT alors que le loyer est encore dû au mintClosePosition ferme également le mint NFT et l’ATA ; ne les fermez pas séparément, le programme rejetterait la transaction.
  • Ouvrir un limit order sur un tick non alignéInvalidTickIndex. Quantifiez toujours via TickUtils.getPriceAndTick.
  • Appeler decreaseLimitOrder sur un order entièrement exécutéInvalidOrderPhase. Utilisez settleLimitOrder puis closeLimitOrder à la place.
  • Oublier dynamicFeeConfigId en passant enableDynamicFee: true → le rejet de CreateCustomizablePool est InvalidDynamicFeeConfigParams. Désactivez les frais dynamiques, ou choisissez une configuration depuis /main/clmm-dynamic-config.

Pour aller plus loin

Sources :