Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Einrichtung
raydium-sdk-V2-demo/src/clmm; der GitHub-Link steht neben jedem Abschnitt. Die Initialisierung folgt der Vorlage config.ts.template des Demo-Repositorys (Quelle). disableFeatureCheck: true wird für jede nicht triviale Integration empfohlen:
Einen CLMM-Pool erstellen
Quelle:src/clmm/createPool.ts
- Sortiert
mint1/mint2vor der Ableitung nach Byte-Reihenfolge. - Berechnet
sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64). - Legt die Konten
observationundtick_array_bitmap_extensionan. - Bezahlt die Gebühr für die Poolerstellung, die durch
ammConfigfestgelegt ist.
Eine Position in einer gewählten Preisspanne eröffnen
Quelle:src/clmm/createPosition.ts
OpenPosition* legt ein fehlendes Tick-Array selbst an, auf Kosten des Zahlers.
Liquidität auf einer bestehenden Position erhöhen
Quelle:src/clmm/increaseLiquidity.ts
Liquidität verringern (und gleichzeitig Gebühren einsammeln)
Quelle:src/clmm/decreaseLiquidity.ts und src/clmm/closePosition.ts
decreaseLiquidity mit liquidity = new BN(0) auf. Die Nebenwirkung der Instruktion besteht darin, token_fees_owed_{0,1} und reward_amount_owed abzurechnen und auszuzahlen. Das ist der einzige Weg, beides einzusammeln.
Um die Position vollständig zu schließen, nachdem Liquidität und Gebühren auf null gesetzt wurden, übergeben Sie ownerInfo: { closePosition: true } beim letzten decreaseLiquidity-Aufruf. Das SDK hängt ClosePosition an und verbrennt den NFT.
Für einen direkten Anchor-Client lassen Sie die deklarierten Konten unverändert und hängen den Pool an:
poolId bei jedem Schließen übergeben. CLMM liest sie nur, wenn positionNftAccount eingefroren ist. So bleibt ein Client-Pfad mit alten und neuen Positionen kompatibel.
Belohnung(en) einsammeln
Quelle:src/clmm/harvestAllRewards.ts
harvestAllRewards durchläuft jede Position in jedem übergebenen Pool. Dabei bündelt es die DecreaseLiquidity-Aufrufe mit null Liquidität, die Gebühren und Belohnungen abrechnen (zusammen mit etwaigen UpdateRewardInfos), und verteilt sie bei Bedarf auf mehrere Transaktionen.
Swap
Quelle:src/clmm/swap.ts
Dieses Beispiel entspricht src/clmm/swap.ts. Dort wird die Simulation mit swapInternal durchgeführt und nicht mit PoolUtils.computeAmountOutFormat.
amountCalculated) sowie die genaue Kontoliste, die der Swap berühren wird (accounts).
Übergeben Sie immer die remainingAccounts, die die Simulation zurückgibt. Sind es zu wenige, bricht der Swap mitten in der Durchquerung mit NotEnoughTickArrayAccount ab. Veraltete Konten verbrauchen lediglich unnötiges Compute-Budget.
PoolUtils.computeAmountOutFormat gibt es weiterhin. Es benötigt jedoch eine ComputeClmmPoolInfo (das computePoolInfo aus getPoolInfoFromRpc, kein API-Pool-Objekt) sowie zwei weitere Pflichtargumente, tickarrayBitmapExtension und blockTimestamp. Außerdem existiert keine Methode raydium.clmm.fetchTickArrays. fetchTickArrays ist eine freie Funktion. Die modulweiten Hilfsfunktionen sind PoolUtils.fetchMultiplePoolTickArrays sowie die tickData und tickArrays, die getPoolInfoFromRpc zurückgibt.Einen anpassbaren CLMM-Pool erstellen
createCustomizablePool ist der Einstiegspunkt, der beim Erstellen des Pools die Schalter für dynamische Gebühren und einseitige Gebühren bereitstellt. Er übernimmt die Struktur von createPool und ergänzt zwei Parameter:
createPool funktioniert weiterhin für den Pfad mit Standardgebühren ohne dynamische Gebühren. Verwenden Sie createCustomizablePool, sobald Sie eine der beiden Optionen benötigen. Die On-Chain-Kontoliste finden Sie unter products/clmm/instructions.
Limit-Orders
Eine Limit-Order hinterlegt die Eingabe des Nutzers bei genau einem Tick. Sie wird im FIFO-Verfahren ausgeführt, sobald ein Swap diesen Tick durchquert. Die Ausgaben werden beim Settlement an die ATA des Inhabers gesendet. Der Inhaber muss zum Zeitpunkt der Ausführung nicht online sein.Limit-Order eröffnen
Es gibt weder ein Konfigurationskonto pro Pool für Limit-Orders noch einen HelfergetClmmLimitOrderConfigs(). Orders werden über ihren Tick identifiziert.
LimitOrderState aus (owner, nonce PDA, order nonce) ab, erhöht die LimitOrderNonce pro Wallet und fügt die Order am jeweiligen Tick in die FIFO-Kohorte ein.
Offene Order erhöhen oder verringern
decreaseLimitOrder kann nur aus dem nicht ausgeführten Teil der Order entnehmen. Der ausgeführte Teil bleibt bis zum Settlement gesperrt. Beide Instruktionen brechen mit InvalidOrderPhase ab, wenn die Order bereits vollständig ausgeführt wurde.
Ausgeführte Order abrechnen
settleLimitOrder liest das unfilled_ratio_x64 der Order gegen den Kohorten-Tracker aus, berechnet den ausgeführten Ertrag und überweist ihn an die ATA des Inhabers. Der Inhaber kann dies selbst aufrufen. Auch limit_order_admin (ein Off-Chain-Operations-Keeper) kann es im Namen des Inhabers tun. Die Ausgabe geht dabei trotzdem an den Inhaber.
Um vollständig abgerechnete Orders zu schließen und die Rent zurückzuholen, verwenden Sie closeLimitOrder (einzeln) oder closeAllLimitOrder (im Stapel). Um viele Orders auf einmal abzurechnen, packt settleAllLimitOrder so viele SettleLimitOrder-Aufrufe in eine v0-Transaktion, wie hineinpassen.
Offene Orders einer Wallet abrufen (Off-Chain)
totalAmount, filledAmount und pendingSettle unterscheiden die Phasen. Für die Historie geschlossener Orders verwenden Sie /limit-order/history/order/list-by-user?wallet=… (pro Wallet, paginiert über nextPageId). Für das vollständige Ereignisprotokoll einer bestimmten Order verwenden Sie /limit-order/history/event/list-by-pda?pda=….
Rust-CPI-Grundgerüst
SwapV2:
Häufige Fallstricke
- Ungenaue Tick-Endpunkte →
TickAndSpacingNotMatch. Rasten Sie Ticks immer überTickUtil.getPriceAndTickein (SingularTickUtil). - Zu wenige Tick-Arrays in
SwapV2übergeben →NotEnoughTickArrayAccount. Übernehmen Sie die Liste ausswapInternal(...).accounts. - Full-Range-Position ohne Bitmap-Erweiterung → Die PDA der Erweiterung muss beschreibbar sein. Das SDK übernimmt dies automatisch.
- Verwechslung von
sqrt_price_x64mitprice→ Ein Faktor-2-Fehler ist hier besonders unangenehm. Im Zweifel lassen Sie das SDK den Wert aus einem lesbaren Preis berechnen. - Rewards zu früh einsammeln → Jedes Einsammeln ist ein
DecreaseLiquidityohne Liquidität und kostet eine Transaktion. Bündeln Sie Einsammlungen überharvestAllRewardsfür mehrere Positionen. Denken Sie dabei daran, dass dessenexecute{ sequentially: true }benötigt. - NFT-Konten selbst schließen →
ClosePositionverbrennt den NFT und schließt dessen ATA. Bei einem Token-2022-NFT-Mint wird auch dieser geschlossen. Ein klassischer SPL-Token-Mint bleibt dagegen mit Supply null bestehen, da dieses Programm Mints nicht schließen kann. Schließen Sie unterstützte Konten nicht separat, sonst bricht die Instruktion mit einem Revert ab. - Limit-Order auf einem nicht abgestimmten Tick eröffnen →
TickAndSpacingNotMatch. Quantisieren Sie Ticks immer über den exportierten HelfergetOrderTick. decreaseLimitOrderbei einer vollständig gefüllten Order aufrufen →InvalidOrderPhase. Verwenden Sie stattdessensettleLimitOrderund anschließendcloseLimitOrder.- Ein Flag
enableDynamicFeeerwarten → Es gibt kein solches Flag. Wenn SiedynamicFeeConfigweglassen, entsteht einfach ein Pool mit statischer Gebühr, und zwar ohne Fehlermeldung. Wenn Sie dynamische Gebühren möchten, übergeben Sie denPublicKeydes Konfigurationskontos, den Sie unter/main/clmm-dynamic-configauswählen.
Wie es weitergeht
sdk-api/typescript-sdk– vollständige SDK-Oberfläche.sdk-api/rest-api– Endpunkte für Quotes und Pool-Metadaten.user-flows/create-clmm-pool– Anleitung ohne Code.integration-guides/aggregator– CLMM als Teil eines Routings einbinden.

