Skip to main content
このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
バージョン情報: 掲載されているすべてのデモは @raydium-io/raydium-sdk-v2@0.2.42-alpha を対象とし、Solana mainnet-beta で動作確認済みです(2026年4月)。プログラム ID は SDK 経由で reference/program-addresses から取得しています。

セットアップ

このページの各デモは raydium-sdk-V2-demo/src/clmm 内のファイルに対応しています。各セクションには GitHub リンクを記載しています。初期設定はデモリポジトリの config.ts.templateソース)に準拠しており、本格的なインテグレーションには disableFeatureCheck: true を推奨します。

CLMMプールを作成する

ソース:src/clmm/createPool.ts
SDK の動作:
  • mint1/mint2 をバイト順でソートしてから導出します。
  • sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64) を計算します。
  • observation アカウントと tick_array_bitmap_extension アカウントを作成します。
  • ammConfig で定義されたプール作成手数料を支払います。

指定した価格範囲でポジションを開設する

ソース:src/clmm/createPosition.ts
SDK は、指定した範囲が接触するティック配列を自動的に特定し、未初期化のものがあれば 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)命令をまとめ、必要に応じて複数のトランザクションに分割して送信します。

スワップ

ソース:src/clmm/swap.ts
computeAmountOutFormat はオンチェーンプログラムと同じロジックでオフチェーンのティックマップを走査し、以下を返します。
  • 期待される出力量
  • スリッページ適用後の最小出力量
  • 実際のスワップが参照するティック配列アカウントのリスト(remainingAccounts
remainingAccounts は必ずシミュレーションの戻り値を使用してください。不足している場合はスワップが途中で TickArrayNotFound エラーで失敗し、古いものを渡した場合はコンピュートを無駄に消費します。

カスタマイズ可能な CLMM プールを作成する

createCustomizablePool は、プール作成時にダイナミックフィーと片側フィーのトグルを設定できる新しいエントリーポイントです。createPool と同じ引数に加えて、以下の3つが追加されています。
デフォルト手数料・リミットオーダーなし・ダイナミックフィーなしの場合は引き続き createPool が利用できます。上記3つの新しい設定が必要な場合は createCustomizablePool を使用してください。オンチェーンのアカウント一覧は products/clmm/instructions を参照してください。

リミットオーダー

リミットオーダーはユーザーの入力を単一のティックに置き、スワップがそのティックを通過した際に FIFO 順で約定します。出力はセトルメント時にオーナーの ATA に送信されるため、オーナーはオンラインである必要はありません。

リミットオーダーを開設する

SDK は (pool, owner, tick, nonce) から LimitOrderState PDA を導出し、(pool, owner) ごとの LimitOrderNonce をインクリメントして、そのティックの FIFO コホートにオーダーを挿入します。

オープン中のオーダーの量を増減する

decreaseLimitOrder はオーダーの未約定部分からのみ削除できます。約定済み部分はセトルメントまでロックされます。オーダーが既に全量約定している場合、両方の命令は InvalidOrderPhase で失敗します。

約定済みオーダーをセトルする

settleLimitOrder はコホートトラッカーに対してオーダーの unfilled_ratio_x64 を参照し、約定した出力量を計算してオーナーの ATA に転送します。オーナー自身が呼び出すことも、オフチェーンの運用キーパーである limit_order_admin がオーナーに代わって呼び出すこともできます。いずれの場合も出力はオーナーに届きます。 完全にセトルされたオーダーをクローズしてレントを回収するには、closeLimitOrder(単一)または closeAllLimitOrder(バッチ)を使用してください。多数のオーダーを一括でセトルするには、settleAllLimitOrder が v0 トランザクションに収まる数の SettleLimitOrder 呼び出しをまとめて実行します。

ウォレットの未決済オーダーを一覧表示する(オフチェーン)

アクティブオーダーエンドポイントは、未約定と部分約定のオーダーを1つのペイロードで返します(totalAmount / filledAmount / pendingSettle でフェーズを区別します)。クローズ済みオーダーの履歴は /limit-order/history/order/list-by-user?wallet=…(ウォレット別、nextPageId でページネーション)、特定オーダーの全イベントログは /limit-order/history/event/list-by-pda?pda=… を利用してください。

Rust CPI スケルトン

SwapV2 の残余アカウントの順序:
スワップでエクステンションが不要な場合は省略してください。必要な場合は最初の残余アカウントに配置します。

よくある落とし穴

  • ティック間隔に合っていないティック端点InvalidTickIndex。必ず TickUtils.getPriceAndTick でスナップしてください。
  • SwapV2 に渡すティック配列が不足しているTickArrayNotFoundcomputeAmountOutFormat で完全なリストを取得してください。
  • ビットマップエクステンションなしのフルレンジポジション → エクステンション PDA は書き込み可能である必要がありますが、SDK が自動的に処理します。
  • sqrt_price_x64price と混同する → ここでの2倍の混乱は特に深刻です。不明な場合は SDK に人間が読める価格から計算させてください。
  • リワードを過剰に頻繁に回収する → 1回の回収ごとに1トランザクションのコストがかかります。harvestAllRewards で多数のポジションをまとめて処理してください。
  • ミントへのレントが残っている状態で NFT をバーンするClosePosition は NFT ミントと ATA も一緒にクローズします。それらを個別にクローズするとプログラムが失敗します。
  • 間隔に合っていないティックでリミットオーダーを開設するInvalidTickIndex。必ず TickUtils.getPriceAndTick で量子化してください。
  • 全量約定済みのオーダーで decreaseLimitOrder を呼び出すInvalidOrderPhase。代わりに settleLimitOrder を呼び出してから closeLimitOrder を使用してください。
  • enableDynamicFee: true を渡しながら dynamicFeeConfigId を忘れるCreateCustomizablePoolInvalidDynamicFeeConfigParams で失敗します。ダイナミックフィーを無効にするか、/main/clmm-dynamic-config からコンフィグを選択してください。

次のステップ

参考資料: