跳轉到主要內容
本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
版本說明。 所有範例均以 @raydium-io/raydium-sdk-v2@0.2.42-alpha 為目標,對應 Solana mainnet-beta,驗證日期為 2026-04。Program ID 由 SDK 透過 reference/program-addresses 取得。

環境設定

本頁每個範例都對應 raydium-sdk-V2-demo/src/clmm 中的同名檔案;各節旁均附有 GitHub 連結。初始化設定參考 demo repo 的 config.ts.template原始碼)——對於任何非簡單整合,建議使用 disableFeatureCheck: true

建立 CLMM 池

原始碼:src/clmm/createPool.ts
SDK 的行為如下:
  • 在推導地址前,依位元組順序對 mint1/mint2 排序。
  • 計算 sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64)
  • 建立 observationtick_array_bitmap_extension 帳戶。
  • ammConfig 所定義的費率支付建池費用。

在指定區間開倉

原始碼:src/clmm/createPosition.ts
SDK 會自動計算該區間涉及哪些 tick array,並在有未初始化的情況下一併打包 InitTickArray 指令。

增加現有倉位的流動性

原始碼:src/clmm/increaseLiquidity.ts

減少流動性(同時領取手續費)

原始碼:src/clmm/decreaseLiquidity.tssrc/clmm/closePosition.ts
若只想領取手續費,以 liquidity = new BN(0) 呼叫 decreaseLiquidity。該指令的副作用是結算 tokens_fees_owed_{0,1} 並將其轉出。 若要在清零流動性與手續費後完全關閉倉位,請在最後一次 decreaseLiquidity 呼叫中傳入 closePosition: true。SDK 會附加 ClosePosition 指令並銷毀 NFT。

領取獎勵

原始碼:src/clmm/harvestAllRewards.ts
harvestAllRewards 會遍歷傳入的每個池的每個倉位,批次打包 CollectReward(及任何必要的 UpdateRewardInfos)指令,若數量超出單筆交易上限則自動拆分。

Swap

原始碼:src/clmm/swap.ts
computeAmountOutFormat 使用與鏈上程式相同的邏輯在鏈下遍歷 tick map,並回傳:
  • 預期輸出數量,
  • 扣除滑點後的最低輸出數量,
  • 實際 Swap 將存取的 tick array 帳戶清單(remainingAccounts)。
請務必傳入模擬所回傳的 remainingAccounts:若傳入的帳戶不足,Swap 會在遍歷途中因 TickArrayNotFound 而回滾;若傳入的帳戶已過時,則會浪費運算資源。

建立可自訂的 CLMM 池

createCustomizablePool 是新的建池入口,可在建池時開啟動態手續費與單側手續費開關。其參數結構與 createPool 相同,額外新增三個欄位:
若只需走預設手續費、不需限價單、不需動態手續費,仍可繼續使用 createPool。只要需要以上三個新開關中的任何一個,請改用 createCustomizablePool。鏈上帳戶清單詳見 products/clmm/instructions

限價單

限價單會將用戶輸入停靠在單一 tick,並在 Swap 穿越該 tick 時依 FIFO 順序成交。成交後輸出會在結算時推送至持有人的 ATA;持有人無需在線即可被成交。

開立限價單

SDK 依 (pool, owner, tick, nonce) 推導 LimitOrderState PDA,遞增每個 (pool, owner)LimitOrderNonce,並將訂單插入該 tick 的 FIFO 佇列。

增加/減少未成交訂單數量

decreaseLimitOrder 只能從訂單的未成交部分移除數量;已成交部分在結算前處於鎖定狀態。若訂單已全數成交,兩個指令均會以 InvalidOrderPhase 回滾。

結算已成交訂單

settleLimitOrder 會對照佇列追蹤器讀取訂單的 unfilled_ratio_x64,計算已成交輸出,並將其轉入持有人的 ATA。持有人可自行呼叫此指令;limit_order_admin(鏈下運維 keeper)也可代為呼叫——輸出仍歸屬持有人。 若要在全額結算後關閉訂單以回收租金,可使用 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 的 remaining account 順序:
若 Swap 不需要 extension,可省略;否則它必須是第一個 remaining account。

常見錯誤

  • tick 端點未對齊間距InvalidTickIndex。請務必透過 TickUtils.getPriceAndTick 對齊。
  • SwapV2 傳入的 tick array 不足TickArrayNotFound。請使用 computeAmountOutFormat 取得完整清單。
  • 全區間倉位未附帶 bitmap extension → extension PDA 必須設為可寫入;SDK 會自動處理。
  • 混淆 sqrt_price_x64price → 此處的 2 倍誤差特別難以排查。若有疑慮,讓 SDK 從人類可讀的價格自行計算。
  • 過於頻繁地領取獎勵 → 每次領取需消耗一筆交易。請透過 harvestAllRewards 跨多個倉位批次領取。
  • 在仍有 mint 租金的情況下銷毀 NFTClosePosition 同時會關閉 NFT mint 與 ATA;請勿單獨關閉,否則程式會回滾。
  • 在非對齊 tick 開立限價單InvalidTickIndex。請務必透過 TickUtils.getPriceAndTick 對齊。
  • 對已全數成交的訂單呼叫 decreaseLimitOrderInvalidOrderPhase。請改用 settleLimitOrder 後再呼叫 closeLimitOrder
  • 傳入 enableDynamicFee: true 卻忘記 dynamicFeeConfigIdCreateCustomizablePool 會以 InvalidDynamicFeeConfigParams 回滾。請關閉動態手續費,或從 /main/clmm-dynamic-config 選擇一個設定。

下一步

參考來源: