Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Configuration
raydium-sdk-V2-demo/src/clmm ; le lien GitHub figure à côté de chaque section. L’initialisation suit le fichier config.ts.template du dépôt de démonstration (source). Pour toute intégration non triviale, nous recommandons de définir disableFeatureCheck: true :
Créer un pool CLMM
Source :src/clmm/createPool.ts
- Trie
mint1etmint2selon l’ordre des octets avant la dérivation. - Calcule
sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64). - Crée les comptes
observationettick_array_bitmap_extension. - Acquitte les frais de création de pool définis par
ammConfig.
Ouvrir une position dans une plage de prix choisie
Source :src/clmm/createPosition.ts
OpenPosition* alloue lui-même un tick array manquant, aux frais du payeur.
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
decreaseLiquidity avec liquidity = new BN(0). Cette instruction règle les montants token_fees_owed_{0,1} et reward_amount_owed, puis les transfère : c’est le seul moyen de collecter l’un ou l’autre.
Pour fermer entièrement la position après avoir ramené la liquidité et les frais à zéro, passez ownerInfo: { closePosition: true } lors du dernier appel à decreaseLiquidity. Le SDK ajoute l’instruction ClosePosition et brûle le NFT.
Pour un client Anchor direct, conservez les comptes déclarés tels quels et ajoutez le pool :
poolId à chaque fermeture. CLMM ne le lit que lorsque positionNftAccount est gelé, ce qui permet à un même chemin client de fonctionner avec les anciennes comme avec les nouvelles positions.
Collecter la ou les récompenses
Source :src/clmm/harvestAllRewards.ts
harvestAllRewards parcourt chaque position de chaque pool transmis, regroupe les appels DecreaseLiquidity à liquidité nulle qui règlent les frais et les récompenses (ainsi que les éventuels UpdateRewardInfos), puis les répartit si nécessaire entre plusieurs transactions.
Swap
Source :src/clmm/swap.ts
Ce code reprend src/clmm/swap.ts, qui effectue la simulation avec swapInternal plutôt qu’avec PoolUtils.computeAmountOutFormat.
amountCalculated) ainsi que la liste exacte des comptes que le swap va utiliser (accounts).
Transmettez toujours les remainingAccounts renvoyés par la simulation : s’il en manque, le swap échoue en cours de parcours avec NotEnoughTickArrayAccount ; s’il y en a de périmés, vous ne faites que consommer du compute inutilement.
PoolUtils.computeAmountOutFormat existe toujours, mais il requiert un ComputeClmmPoolInfo (le
computePoolInfo retourné par getPoolInfoFromRpc, et non un objet pool issu de l’API), ainsi que
deux arguments obligatoires supplémentaires : tickarrayBitmapExtension et blockTimestamp. Il
n’existe pas non plus de méthode raydium.clmm.fetchTickArrays (fetchTickArrays est une
fonction libre ; les helpers au niveau du module sont PoolUtils.fetchMultiplePoolTickArrays et
les tickData / tickArrays retournés par getPoolInfoFromRpc).Créer un pool CLMM personnalisable
createCustomizablePool est le point d’entrée qui expose les options de frais dynamiques et de frais à un seul côté au moment de la création du pool. Il reprend la signature de createPool avec deux paramètres supplémentaires :
createPool continue de fonctionner pour le chemin à frais par défaut, sans frais dynamiques. Utilisez createCustomizablePool dès que vous avez besoin de l’une de ces options. Consultez products/clmm/instructions pour la liste des comptes on-chain.
Ordres limites
Un ordre limite immobilise les fonds de l’utilisateur sur un tick unique, puis est exécuté selon la règle FIFO lorsqu’un swap franchit ce tick. Les montants obtenus sont envoyés vers l’ATA du propriétaire au moment du règlement ; le propriétaire n’a pas besoin d’être en ligne pour que l’ordre soit exécuté.Ouvrir un ordre limite
Il n’existe ni configuration d’ordre limite par pool, ni helpergetClmmLimitOrderConfigs() : les ordres sont identifiés par tick.
LimitOrderState à partir de (owner, nonce PDA, order nonce), incrémente le LimitOrderNonce propre au portefeuille, et insère l’ordre dans la cohorte FIFO correspondant à ce tick.
Augmenter / réduire un ordre ouvert
decreaseLimitOrder ne peut retirer que la partie non exécutée de l’ordre ; la partie exécutée reste bloquée jusqu’au règlement. Les deux instructions échouent avec InvalidOrderPhase si l’ordre a déjà été entièrement exécuté.
Régler un ordre exécuté
settleLimitOrder lit unfilled_ratio_x64 de l’ordre par rapport au suivi de la cohorte, calcule le montant exécuté et le 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 aussi l’appeler pour le compte du propriétaire, le montant restant dans tous les cas destiné au propriétaire.
Pour fermer les ordres entièrement réglés et récupérer le loyer, utilisez closeLimitOrder (unitaire) ou closeAllLimitOrder (par lot). Pour régler plusieurs ordres à la fois, settleAllLimitOrder regroupe autant d’appels SettleLimitOrder que possible dans une transaction v0.
Lister les ordres en attente d’un portefeuille (hors chaîne)
totalAmount / filledAmount / pendingSettle permettent de distinguer les phases). Pour l’historique des ordres clôturés, utilisez /limit-order/history/order/list-by-user?wallet=… (par portefeuille, paginé par nextPageId) ; pour le journal complet des événements d’un ordre donné, utilisez /limit-order/history/event/list-by-pda?pda=….
Squelette de CPI en Rust
SwapV2 :
Pièges courants
- Bornes de tick mal alignées →
TickAndSpacingNotMatch. Alignez toujours les valeurs avecTickUtil.getPriceAndTick(au singulier,TickUtil). - Nombre insuffisant de tick arrays fournis dans
SwapV2→NotEnoughTickArrayAccount. Récupérez la liste depuisswapInternal(...).accounts. - Position pleine largeur sans l’extension de bitmap → le PDA de l’extension doit être accessible en écriture. Le SDK s’en charge automatiquement.
- Confondre
sqrt_price_x64avecprice→ une erreur de facteur 2 est ici particulièrement pénible. En cas de doute, laissez le SDK calculer la valeur à partir d’un prix lisible. - Réclamer les récompenses trop souvent → chaque collecte est un
DecreaseLiquidityà liquidité nulle et coûte une transaction. Regroupez les opérations avecharvestAllRewardssur plusieurs positions, et n’oubliez pas que sonexecutenécessite{ sequentially: true }. - Fermer soi-même les comptes NFT →
ClosePositionbrûle le NFT et ferme son ATA. Il ferme aussi un mint NFT Token-2022 ; un mint SPL Token classique reste en circulation à zéro, car ce programme ne peut pas fermer les mints. Ne fermez pas séparément les comptes pris en charge, sinon l’instruction échouera. - Ouvrir un ordre limite sur un tick non aligné →
TickAndSpacingNotMatch. Quantifiez toujours la valeur avec le helper exportégetOrderTick. - Appeler
decreaseLimitOrdersur un ordre entièrement exécuté →InvalidOrderPhase. Utilisez plutôtsettleLimitOrder, puiscloseLimitOrder. - Chercher un indicateur
enableDynamicFee→ il n’existe pas. OmettredynamicFeeConfigcrée simplement un pool à frais statiques, sans aucune erreur ni avertissement. Si vous souhaitez des frais dynamiques, passez lePublicKeydu compte de configuration, récupéré depuis/main/clmm-dynamic-config.
Où aller ensuite
sdk-api/typescript-sdk: la surface complète du SDK.sdk-api/rest-api: les endpoints de devis et de métadonnées des pools.user-flows/create-clmm-pool: le parcours pas à pas, sans code.integration-guides/aggregator: router le CLMM dans le cadre d’un chemin de swap.

