Skip to main content
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Versionsbanner. Alle TypeScript-Demos zielen auf @raydium-io/raydium-sdk-v2@0.2.64-alpha ab; sie wurden zuletzt gegen 0.2.42-alpha (2026-04) ausgeführt und ihre Aufrufsignaturen wurden am 2026-09-09 gegen die 0.2.64-alpha-Quelle auf Solana mainnet-beta überprüft. Das Rust-CPI-Skelett am Ende zielt auf raydium-clmm im Branch chore/upgrade-anchor, Anchor 1.0.2, denselben Pin wie die CPMM-Seite, sodass beide in einer Crate leben können. master pinnt immer noch 0.32.1. Programm-IDs stammen aus reference/program-addresses über das SDK.

Setup

Jede Demo auf dieser Seite spiegelt eine Datei in raydium-sdk-V2-demo/src/clmm wider; der GitHub-Link befindet sich neben jedem Abschnitt. Das Bootstrap folgt der config.ts.template des Demo-Repos (Quelle) — disableFeatureCheck: true ist die empfohlene Einstellung für jede nicht-triviale Integration:

Erstellen Sie einen CLMM-Pool

Quelle: src/clmm/createPool.ts
Das SDK:
  • Sortiert mint1/mint2 nach Byte-Reihenfolge vor der Ableitung.
  • Berechnet sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Erstellt die Konten observation und tick_array_bitmap_extension.
  • Zahlt die von ammConfig definierte Pool-Erstellungsgebühr.

Öffnen Sie eine Position in einem gewählten Bereich

Quelle: src/clmm/createPosition.ts
Das SDK berechnet, welche Tick-Arrays der Bereich berührt, und übergibt sie als Konten. Es muss keine Init-Anweisung bündeln — es gibt keine Init-Tick-Array-Anweisung; OpenPosition* weist selbst ein fehlendes Tick-Array zu, auf Kosten des Zahlers.

Erhöhen Sie die Liquidität einer bestehenden Position

Quelle: src/clmm/increaseLiquidity.ts

Verringern Sie die Liquidität (und sammeln Sie gleichzeitig Gebühren)

Quelle: src/clmm/decreaseLiquidity.ts und src/clmm/closePosition.ts
Um nur Gebühren und Rewards zu sammeln, rufen Sie decreaseLiquidity mit liquidity = new BN(0) auf. Die Nebenwirkung der Anweisung ist die Abrechnung von token_fees_owed_{0,1} und reward_amount_owed und deren Übertragung — dies ist die einzige Möglichkeit, eine davon zu sammeln. Um die Position nach dem Nullstellen der Liquidität und Gebühren vollständig zu schließen, übergeben Sie ownerInfo: { closePosition: true } beim letzten decreaseLiquidity-Aufruf. Das SDK hängt ClosePosition an und verbrennt das NFT.
Positionen mit eingeschränktem Emittenten erfordern einen kompatiblen Close-Builder. Diese Positionen haben ein eingefrorenes NFT-Token-Konto. ClosePosition muss die Pool-ID der Position als erstes verbleibendes Konto anhängen, damit CLMM das Konto auftauen kann, bevor es das NFT verbrennt. Der Programmquellbranch enthält keine SDK-Änderung. Bestätigen Sie, dass Ihre SDK-Version den eingefrorenen Close-Pfad explizit unterstützt, bevor Sie die Erstellung von Positionen mit eingeschränktem Emittenten aktivieren.
Für einen direkten Anchor-Client halten Sie die deklarierten Konten unverändert und hängen Sie den Pool an:
Sie können poolId bei jedem Close übergeben. CLMM liest es nur, wenn positionNftAccount eingefroren ist, was einen Client-Pfad mit alten und neuen Positionen kompatibel hält.

Sammeln Sie Reward(s)

Quelle: src/clmm/harvestAllRewards.ts
harvestAllRewards durchläuft jede Position in jedem übergebenen Pool, bündelt die Zero-Liquidity-DecreaseLiquidity-Aufrufe, die Gebühren und Rewards abrechnen (plus alle UpdateRewardInfos), und teilt sie bei Bedarf auf Transaktionen auf.

Swap

Quelle: src/clmm/swap.ts
Die Simulation durchläuft die Tick-Map offline mit derselben Logik wie das On-Chain-Programm und gibt die Ausgabemenge (amountCalculated) plus die genaue Kontoliste zurück, die der Swap berührt (accounts). Übergeben Sie immer die remainingAccounts, die die Simulation zurückgibt: zu wenige und der Swap wird mit NotEnoughTickArrayAccount mitten im Durchlauf rückgängig gemacht; veraltete verschwenden nur Compute.
PoolUtils.computeAmountOutFormat existiert immer noch, benötigt aber eine ComputeClmmPoolInfo (die computePoolInfo aus getPoolInfoFromRpc, nicht ein API-Pool-Objekt) plus zwei weitere erforderliche Argumente — tickarrayBitmapExtension und blockTimestamp — und es gibt keine raydium.clmm.fetchTickArrays-Methode (fetchTickArrays ist eine freie Funktion; die Modul-Level- Helfer sind PoolUtils.fetchMultiplePoolTickArrays und die tickData / tickArrays von getPoolInfoFromRpc).

Erstellen Sie einen anpassbaren CLMM-Pool

createCustomizablePool ist der Einstiegspunkt, der die dynamischen Gebühren und Single-Sided-Fee-Umschalter zum Zeitpunkt der Pool-Erstellung verfügbar macht. Es nimmt die Form von createPool plus zwei Ergänzungen:
Es gibt kein enableDynamicFee-Flag und keinen dynamicFeeConfigId-Parameter, und keinen startTime. Das Übergeben von dynamicFeeConfig ist das, was dynamische Gebühren aktiviert — lassen Sie es weg und Sie erhalten einen statischen Gebühren-Pool, ohne Fehler. Beachten Sie auch, dass die SDK-Enum-Member TokenOnlyA / TokenOnlyB sind, während die On-Chain-Rust-Enum sie als Token0Only / Token1Only schreibt; die numerischen Werte stimmen überein (FromInput = 0).
createPool funktioniert weiterhin für den Standard-Gebühren-, kein-dynamisches-Gebühren-Pfad. Verwenden Sie createCustomizablePool, wann immer Sie einen der beiden Schalter benötigen. Siehe products/clmm/instructions für die On-Chain-Kontoliste.

Limit Orders

Eine Limit Order parkt Benutzereingaben bei einem einzelnen Tick und wird FIFO gefüllt, wenn ein Swap diesen Tick kreuzt. Ausgaben werden zum Zeitpunkt der Abrechnung an die ATA des Eigentümers gepusht; der Eigentümer muss nicht online sein, um gefüllt zu werden.

Öffnen Sie eine Limit Order

Das SDK leitet die LimitOrderState-PDA aus (owner, nonce PDA, order nonce) ab, erhöht die Pro-Wallet-LimitOrderNonce und fügt die Order in die FIFO-Kohorte bei diesem Tick ein.

Erhöhen / verringern Sie eine offene Order

decreaseLimitOrder kann nur vom ungefüllten Teil der Order entfernen; der gefüllte Teil ist bis zur Abrechnung gesperrt. Beide Anweisungen werden mit InvalidOrderPhase rückgängig gemacht, wenn die Order bereits vollständig gefüllt wurde.

Begleichen Sie eine gefüllte Order

settleLimitOrder liest die unfilled_ratio_x64 der Order gegen den Kohorten-Tracker, berechnet die gefüllte Ausgabe und überträgt sie an die ATA des Eigentümers. Der Eigentümer kann dies selbst aufrufen; limit_order_admin (ein Off-Chain-Betriebswächter) kann es auch im Namen des Eigentümers aufrufen — die Ausgabe geht immer noch an den Eigentümer. Zum Schließen vollständig abgerechneter Orders zur Rückgewinnung von Miete verwenden Sie closeLimitOrder (einzeln) oder closeAllLimitOrder (Batch). Zum Abrechnen vieler auf einmal packt settleAllLimitOrder so viele SettleLimitOrder-Aufrufe, wie in eine v0-Tx passen.

Auflisten der geparkten Orders eines Wallets (Off-Chain)

Der Endpunkt für aktive Orders gibt sowohl ungefüllte als auch teilweise gefüllte Orders in einer Nutzlast zurück (totalAmount / filledAmount / pendingSettle unterscheiden die Phasen). Für die Verlaufshistorie geschlossener Orders verwenden Sie /limit-order/history/order/list-by-user?wallet=… (pro Wallet, paginiert nach nextPageId); für das vollständige Ereignisprotokoll einer bestimmten Order verwenden Sie /limit-order/history/event/list-by-pda?pda=….

Rust-CPI-Skelett

Verbleibende Kontenreihenfolge für SwapV2:
Wenn der Swap die Erweiterung nie benötigt, lassen Sie sie weg; andernfalls ist sie das erste verbleibende Konto.

Häufige Fallstricke

  • Off-Spacing-Tick-Endpunkte → TickAndSpacingNotMatch. Immer über TickUtil.getPriceAndTick ausrichten (Singular TickUtil).
  • Nicht genug Tick-Arrays in SwapV2 bereitgestellt → NotEnoughTickArrayAccount. Nehmen Sie die Liste aus swapInternal(...).accounts.
  • Full-Range-Position ohne Bitmap-Erweiterung → die Erweiterungs-PDA muss beschreibbar sein; das SDK handhabt dies automatisch.
  • sqrt_price_x64 mit price verwechseln → eine Faktor-2-Verwirrung hier ist besonders schmerzhaft. Im Zweifelsfall lassen Sie das SDK es aus einem menschenlesbaren Preis berechnen.
  • Rewards zu eifrig sammeln → jede Sammlung ist ein Zero-Liquidity-DecreaseLiquidity und kostet eine Transaktion. Batch über harvestAllRewards über viele Positionen, und denken Sie daran, dass sein execute { sequentially: true } benötigt.
  • NFT-Konten selbst schließen → ClosePosition verbrennt das NFT und schließt sein ATA. Es schließt auch ein Token-2022-NFT-Mint; ein klassisches SPL-Token-Mint bleibt bei Angebot Null, weil dieses Programm Mints nicht schließen kann. Schließen Sie unterstützte Konten nicht separat, oder die Anweisung wird rückgängig gemacht.
  • Öffnen einer Limit Order bei einem nicht-spaced Tick → TickAndSpacingNotMatch. Immer über den exportierten getOrderTick-Helfer quantisieren.
  • Aufrufen von decreaseLimitOrder bei einer vollständig gefüllten Order → InvalidOrderPhase. Verwenden Sie stattdessen settleLimitOrder dann closeLimitOrder.
  • Erwarten eines enableDynamicFee-Flags → es gibt keines. Das Weglassen von dynamicFeeConfig erstellt einfach einen statischen Gebühren-Pool, stillschweigend und ohne Fehler. Wenn Sie dynamische Gebühren wollten, übergeben Sie die PublicKey des Config-Kontos, ausgewählt aus /main/clmm-dynamic-config.

Wo es weitergeht

Quellen: