本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
版本說明。 所有 TypeScript 示例針對
@raydium-io/raydium-sdk-v2@0.2.64-alpha;最後執行於 0.2.42-alpha(2026-04),並於 2026-09-09 針對 Solana mainnet-beta 重新檢查了 0.2.64-alpha 原始碼中的呼叫簽名。末尾的 Rust CPI 骨架針對 master 分支上的 raydium-clmm,其中 Anchor 版本為 =0.32.1 — 不是 CPMM 頁面使用的 1.0.2;兩者無法共存於一個 crate 中。程式 ID 來自 reference/program-addresses 透過 SDK。設定
raydium-sdk-V2-demo/src/clmm 中的一個檔案;GitHub 連結位於每個章節旁邊。初始化遵循示例倉庫的 config.ts.template(原始碼)— 對於任何非平凡的整合,建議設定 disableFeatureCheck: true:
建立 CLMM 流動性池
原始碼:src/clmm/createPool.ts
- 在推導前按位元組順序排序
mint1/mint2。 - 計算
sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64)。 - 建立
observation和tick_array_bitmap_extension帳戶。 - 支付由
ammConfig定義的流動性池建立費用。
在選定範圍內開設部位
原始碼:src/clmm/createPosition.ts
OpenPosition* 會自行分配缺失的 tick 陣列,費用由支付者承擔。
增加現有部位的流動性
原始碼:src/clmm/increaseLiquidity.ts
減少流動性(同時收取費用)
原始碼:src/clmm/decreaseLiquidity.ts 和 src/clmm/closePosition.ts
liquidity = new BN(0) 呼叫 decreaseLiquidity。指令的副作用是結算 token_fees_owed_{0,1} 和 reward_amount_owed 並將其轉出 — 這是收取任一者的唯一方式。
若要在清零流動性和費用後完全關閉部位,在最後的 decreaseLiquidity 呼叫上傳遞 ownerInfo: { closePosition: true }。SDK 會附加 ClosePosition 並燒毀 NFT。
對於直接 Anchor 用戶端,保持宣告的帳戶不變並附加流動性池:
poolId。CLMM 只在 positionNftAccount 凍結時讀取它,這使一個用戶端路徑與舊部位和新部位相容。
收取獎勵
原始碼:src/clmm/harvestAllRewards.ts
harvestAllRewards 遍歷傳入的每個流動性池上的每個部位,批次處理結算費用和獎勵的零流動性 DecreaseLiquidity 呼叫(加上任何 UpdateRewardInfos),並在需要時將其分散到多個交易中。
交換
原始碼:src/clmm/swap.ts
amountCalculated)加上交換將涉及的確切帳戶列表(accounts)。
始終傳遞模擬傳回的 remainingAccounts:太少會導致交換在遍歷中途以 NotEnoughTickArrayAccount 回復;過時的只會浪費計算。
PoolUtils.computeAmountOutFormat 仍然存在,但它需要 ComputeClmmPoolInfo(來自 getPoolInfoFromRpc 的 computePoolInfo,不是 API 流動性池物件)加上另外兩個必需的引數 — tickarrayBitmapExtension 和 blockTimestamp — 並且沒有 raydium.clmm.fetchTickArrays 方法(fetchTickArrays 是自由函式;模組級別的輔助程式是 PoolUtils.fetchMultiplePoolTickArrays 和 getPoolInfoFromRpc 傳回的 tickData / tickArrays)。建立可自訂的 CLMM 流動性池
createCustomizablePool 是入口點,在流動性池建立時公開動態費用和單邊費用切換。它採用 createPool 的形狀加上兩個新增項:
createPool 繼續用於預設費用、無動態費用路徑。每當你需要任一旋鈕時,使用 createCustomizablePool。見 products/clmm/instructions 以了解鏈上帳戶列表。
限價單
限價單在單個 tick 處停泊使用者輸入,當交換穿過該 tick 時按 FIFO 方式成交。輸出在結算時推送到所有者的 ATA;所有者不需要在線即可成交。開設限價單
(owner, nonce PDA, order nonce) 推導 LimitOrderState PDA,碰撞每個錢包的 LimitOrderNonce,並將訂單插入該 tick 的 FIFO 隊列。
增加/減少開放訂單
decreaseLimitOrder 只能從訂單的未成交部分移除;成交部分被鎖定直到結算。如果訂單已完全成交,兩個指令都會以 InvalidOrderPhase 回復。
結算已成交的訂單
settleLimitOrder 根據隊列追蹤器讀取訂單的 unfilled_ratio_x64,計算成交輸出,並將其轉移到所有者的 ATA。所有者可以自己呼叫此方法;limit_order_admin(離線操作保管人)也可以代表所有者呼叫它 — 輸出仍然進入所有者。
若要關閉完全結算的訂單以恢復租金,使用 closeLimitOrder(單個)或 closeAllLimitOrder(批次)。若要同時結算許多訂單,settleAllLimitOrder 將盡可能多的 SettleLimitOrder 呼叫打包到 v0 交易中。
列出錢包的停泊訂單(離線)
totalAmount / filledAmount / pendingSettle 區分階段)。對於已關閉訂單的歷史記錄,使用 /limit-order/history/order/list-by-user?wallet=…(按錢包,按 nextPageId 分頁);對於特定訂單的完整事件日誌,使用 /limit-order/history/event/list-by-pda?pda=…。
Rust CPI 骨架
SwapV2 的剩餘帳戶順序:
常見陷阱
- 非間距 tick 端點 →
TickAndSpacingNotMatch。始終透過TickUtil.getPriceAndTick(單數TickUtil)對齊。 - 在
SwapV2中提供的 tick 陣列不足 →NotEnoughTickArrayAccount。取得swapInternal(...).accounts傳回的列表。 - 沒有位圖擴展的全範圍部位 → 擴展 PDA 必須可寫;SDK 會自動處理此問題。
- 將
sqrt_price_x64誤認為price→ 這裡的因子 2 混淆特別痛苦。如有疑問,讓 SDK 從人類可讀的價格計算它。 - 過於急切地收取獎勵 → 每次收取都是零流動性
DecreaseLiquidity,成本為一個交易。透過harvestAllRewards跨許多部位進行批次處理,並記住其execute需要{ sequentially: true }。 - 自己關閉 NFT 帳戶 →
ClosePosition燒毀 NFT 並關閉其 ATA。它也關閉 Token-2022 NFT 鑄幣;經典 SPL Token 鑄幣保持供應量為零,因為該程式無法關閉鑄幣。不要單獨關閉支援的帳戶,否則指令將回復。 - 在非間距 tick 開設限價單 →
TickAndSpacingNotMatch。始終透過匯出的getOrderTick輔助程式進行量化。 - 在完全成交的訂單上呼叫
decreaseLimitOrder→InvalidOrderPhase。改用settleLimitOrder然後closeLimitOrder。 - 期望
enableDynamicFee旗標 → 沒有。省略dynamicFeeConfig只是建立靜態費用流動性池,無聲且無錯誤。如果你想要動態費用,傳遞從/main/clmm-dynamic-config選擇的配置帳戶的PublicKey。
後續步驟
sdk-api/typescript-sdk— 完整 SDK 表面。sdk-api/rest-api— 報價和流動性池元資料端點。user-flows/create-clmm-pool— 非程式碼逐步說明。integration-guides/aggregator— 將 CLMM 作為路徑的一部分進行路由。

