本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
版本说明。 所有示例均基于
@raydium-io/raydium-sdk-v2@0.2.42-alpha,针对 Solana mainnet-beta 环境,验证时间为 2026 年 4 月。Program ID 通过 SDK 从 reference/program-addresses 获取。初始化配置
raydium-sdk-V2-demo/src/clmm 目录下的文件,每个章节旁附有对应的 GitHub 链接。初始化方式参照 demo 仓库的 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
InitTickArray 指令。
向已有仓位增加流动性
源码:src/clmm/increaseLiquidity.ts
减少流动性(同时领取手续费)
源码:src/clmm/decreaseLiquidity.ts 和 src/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:传入过少会在遍历中途触发 TickArrayNotFound 导致回滚;传入过时的账户则会白白消耗计算资源。
创建可定制化 CLMM 流动池
createCustomizablePool 是新的入口方法,支持在建池时启用动态手续费和单侧手续费等参数。其用法与 createPool 基本一致,额外增加三个字段:
createPool 仍然适用。只要需要上述三个新参数中的任意一个,请改用 createCustomizablePool。链上账户列表详见 products/clmm/instructions。
限价单
限价单将用户的输入锁定在单个 tick,当 swap 穿越该 tick 时按 FIFO 顺序成交。成交后的输出会在结算时推送至持有人的 ATA,持有人无需在线即可被成交。挂出限价单
(pool, owner, tick, nonce) 推导 LimitOrderState PDA,递增对应 (pool, owner) 的 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 的 remaining account 顺序:
常见问题
- tick 端点未对齐到 spacing →
InvalidTickIndex。请始终通过TickUtils.getPriceAndTick进行对齐。 SwapV2提供的 tick array 不足 →TickArrayNotFound。请使用computeAmountOutFormat获取完整列表。- 全区间仓位未提供 bitmap extension → extension PDA 必须设为可写;SDK 会自动处理此情况。
- 将
sqrt_price_x64误用为price→ 此处的 2 倍误差尤为棘手。如有疑虑,请让 SDK 从可读价格自动计算。 - 过于频繁地领取奖励 → 每次领取需消耗一笔交易。建议通过
harvestAllRewards跨多个仓位批量领取。 - 在仍欠 mint 租金时销毁 NFT →
ClosePosition会同时关闭 NFT mint 和 ATA;请勿单独关闭它们,否则程序会回滚。 - 在非对齐 tick 处挂限价单 →
InvalidTickIndex。请始终通过TickUtils.getPriceAndTick进行量化。 - 对已全部成交的订单调用
decreaseLimitOrder→InvalidOrderPhase。请改用settleLimitOrder后再调用closeLimitOrder。 - 传入
enableDynamicFee: true时忘记提供dynamicFeeConfigId→CreateCustomizablePool会以InvalidDynamicFeeConfigParams回滚。请关闭动态手续费,或从/main/clmm-dynamic-config中选择一个配置。
后续阅读
sdk-api/typescript-sdk— 完整 SDK 接口文档。sdk-api/rest-api— 报价和流动池元数据接口。user-flows/create-clmm-pool— 非代码操作指引。integration-guides/aggregator— 在路由中集成 CLMM。

