Skip to main content
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Versionsbanner. Alle Demos zielen auf @raydium-io/raydium-sdk-v2@0.2.42-alpha gegen Solana mainnet-beta ab, verifiziert 2026-04. Program IDs stammen aus reference/program-addresses über das SDK.

Setup

Jedes Demo auf dieser Seite spiegelt eine Datei in raydium-sdk-V2-demo/src/clmm; 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 observation- und tick_array_bitmap_extension-Konten.
  • 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 automatisch, welche Tick-Arrays der Bereich berührt, und bündelt InitTickArray-Anweisungen, falls welche nicht initialisiert sind.

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 zu sammeln, rufen Sie decreaseLiquidity mit liquidity = new BN(0) auf. Die Nebenfolge der Anweisung ist die Abrechnung von tokens_fees_owed_{0,1} und deren Übertragung. Um die Position vollständig zu schließen, nachdem Sie die Liquidität und Gebühren auf Null gesetzt haben, übergeben Sie 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 Program-Source-Branch 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 behalten Sie die deklarierten Konten unverändert und hängen den Pool an:
Sie können poolId bei jedem Close übergeben. CLMM liest es nur, wenn positionNftAccount eingefroren ist, was einen Client-Pfad kompatibel mit alten und neuen Positionen hält.

Sammeln Sie Reward(s)

Quelle: src/clmm/harvestAllRewards.ts
harvestAllRewards durchläuft jede Position in jedem übergebenen Pool, bündelt CollectReward-Anweisungen (und alle UpdateRewardInfos-Anweisungen) und teilt sie bei Bedarf auf mehrere Transaktionen auf.

Swap

Quelle: src/clmm/swap.ts
computeAmountOutFormat durchläuft die Tick-Map offline mit der gleichen Logik wie das On-Chain-Programm und gibt zurück:
  • die erwartete Ausgabemenge,
  • die Mindestausgabemenge nach Slippage,
  • die Liste der Tick-Array-Konten, die der tatsächliche Swap berührt (remainingAccounts).
Übergeben Sie immer die von der Simulation zurückgegebenen remainingAccounts: Wenn Sie zu wenige übergeben, wird der Swap mit TickArrayNotFound mitten im Durchlauf rückgängig gemacht; wenn Sie veraltete übergeben, verschwenden Sie Compute.

Erstellen Sie einen anpassbaren CLMM-Pool

createCustomizablePool ist der neue Einstiegspunkt, der die dynamischen Gebühren- und Single-Sided-Fee-Schalter zum Zeitpunkt der Pool-Erstellung verfügbar macht. Es hat die gleiche Form wie createPool plus drei Ergänzungen:
createPool funktioniert weiterhin für den Standard-Gebühren-, No-Limit-Order-, No-Dynamic-Fee-Pfad. Verwenden Sie createCustomizablePool, wenn Sie einen der drei neuen 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 das 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 von (pool, owner, tick, nonce) ab, erhöht die Pro-(Pool, Eigentümer) 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 das unfilled_ratio_x64 der Order gegen den Kohorten-Tracker, berechnet die gefüllte Ausgabe und überträgt sie an das ATA des Eigentümers. Der Eigentümer kann dies selbst aufrufen; limit_order_admin (ein Off-Chain-Betriebskeeper) kann es auch im Namen des Eigentümers aufrufen — die Ausgabe geht immer noch an den Eigentümer. Um vollständig abgerechnete Orders zu schließen und Miete zurückzugewinnen, verwenden Sie closeLimitOrder (einzeln) oder closeAllLimitOrder (Batch). Um viele auf einmal abzurechnen, packt settleAllLimitOrder so viele SettleLimitOrder-Aufrufe wie möglich in eine v0-Tx.

Listen Sie die geparkten Orders einer Wallet auf (Off-Chain)

Der Endpunkt für aktive Orders gibt sowohl ungefüllte als auch teilweise gefüllte Orders in einer Payload zurück (totalAmount / filledAmount / pendingSettle unterscheiden die Phasen). Für die Closed-Order-Historie 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

Reihenfolge der verbleibenden Konten 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-EndpunkteInvalidTickIndex. Snappen Sie immer über TickUtils.getPriceAndTick.
  • Nicht genug Tick-Arrays in SwapV2 bereitgestelltTickArrayNotFound. Verwenden Sie computeAmountOutFormat, um die vollständige Liste zu erhalten.
  • 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 lesbaren Preis berechnen.
  • Rewards zu eifrig sammeln → jede Sammlung kostet eine Transaktion. Bündeln Sie über harvestAllRewards über viele Positionen.
  • NFT-Konten selbst schließenClosePosition verbrennt das NFT und schließt sein ATA. Es schließt auch eine Token-2022-NFT-Mint; eine klassische SPL-Token-Mint bleibt bei Angebot Null, da 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-gespaced TickInvalidTickIndex. Quantisieren Sie immer über TickUtils.getPriceAndTick.
  • decreaseLimitOrder auf einer vollständig gefüllten Order aufrufenInvalidOrderPhase. Verwenden Sie stattdessen settleLimitOrder dann closeLimitOrder.
  • dynamicFeeConfigId vergessen, während enableDynamicFee: true übergeben wird → der CreateCustomizablePool-Revert ist InvalidDynamicFeeConfigParams. Schalten Sie entweder die dynamische Gebühr aus oder wählen Sie eine Konfiguration aus /main/clmm-dynamic-config.

Wo geht es weiter

Quellen: