このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
セットアップ
このページのすべてのデモは、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 が精算され、外部に送金されます。どちらかを回収する方法は、これonly です。
流動性とフィーをゼロにした後にポジションを完全にクローズするには、最後の decreaseLiquidity 呼び出しで ownerInfo: { closePosition: true } を渡します。SDK は ClosePosition を追加し、NFT をバーンします。
Anchor クライアントを直接使う場合は、宣言済みのアカウントはそのままにして、プールを追加します:
poolId を渡しても構いません。CLMM が読み取るのは positionNftAccount が凍結されている場合のみです。そのため、1 つのクライアントの処理で古いポジションと新しいポジションの両方に対応できます。
リワードを回収する
ソース:src/clmm/harvestAllRewards.ts
harvestAllRewards は、渡されたすべてのプールのすべてのポジションを走査し、フィーとリワードを精算する残高ゼロの DecreaseLiquidity 呼び出し(および必要に応じて UpdateRewardInfos)をまとめます。必要な場合は、それらを複数のトランザクションに分割します。
スワップ
ソース:src/clmm/swap.ts
このサンプルは src/clmm/swap.ts を再現したものです。PoolUtils.computeAmountOutFormat ではなく swapInternal を使ってシミュレーションを行います。
amountCalculated)と、スワップが触れる正確なアカウント一覧(accounts)を返します。
シミュレーションが返した remainingAccounts は必ず渡してください。数が足りないとスワップは走査の途中で NotEnoughTickArrayAccount によりリバートします。古いアカウントを渡した場合はリバートはしませんが、計算リソースを無駄に消費します。
PoolUtils.computeAmountOutFormat も引き続き存在しますが、ComputeClmmPoolInfo(API のプールオブジェクトではなく、getPoolInfoFromRpc が返す computePoolInfo)と、さらに 2 つの必須引数(tickarrayBitmapExtension と blockTimestamp)が必要です。また、raydium.clmm.fetchTickArrays メソッドは存在しません。fetchTickArrays はフリー関数で、モジュールレベルのヘルパーは PoolUtils.fetchMultiplePoolTickArrays と、getPoolInfoFromRpc が返す tickData / tickArrays です。カスタマイズ可能な CLMM プールの作成
createCustomizablePool は、プール作成時に動的手数料と片側手数料のトグルを指定できるエントリーポイントです。引数は createPool と同じ形に、2 つの項目を追加したものになります。
createPool を利用できます。どちらかの設定が必要な場合は createCustomizablePool を使用してください。オンチェーンのアカウント一覧は products/clmm/instructions を参照してください。
指値注文
指値注文は、ユーザーの入力資産を単一のティックに預けておき、スワップがそのティックを横切ったときに先入れ先出し(FIFO)で約定させる仕組みです。出力はセトルの時点で所有者の ATA に送られるため、約定のために所有者がオンラインである必要はありません。指値注文の作成
プールごとの指値注文設定アカウントやgetClmmLimitOrderConfigs() ヘルパーは存在しません。注文はティックをキーとして管理されます。
(owner, nonce PDA, order nonce) から LimitOrderState PDA を導出し、ウォレットごとの LimitOrderNonce を更新して、注文をそのティックの FIFO コホートに挿入します。
未約定の注文を増額・減額する
decreaseLimitOrder で減額できるのは、注文の未約定部分のみです。約定済みの部分は、セトルされるまでロックされます。注文がすでに全量約定している場合、どちらの命令も InvalidOrderPhase によりリバートします。
約定済み注文の決済
settleLimitOrder は、注文の unfilled_ratio_x64 をコホートのトラッカーと照合して約定済みの出力を計算し、所有者の ATA に送金します。所有者は自分で呼び出せます。オフチェーンの運用キーパーである limit_order_admin も、所有者の代わりに呼び出せます。その場合も出力は所有者に送られます。
完全に決済された注文のレントを回収するには、closeLimitOrder(単一)または closeAllLimitOrder(一括)を使用します。複数の注文をまとめて決済する場合は、settleAllLimitOrder が v0 トランザクションに収まる範囲で SettleLimitOrder の呼び出しをまとめます。
ウォレットの未約定注文の一覧取得(オフチェーン)
totalAmount / filledAmount / pendingSettle で状態を区別できます。クローズ済み注文の履歴は /limit-order/history/order/list-by-user?wallet=…(ウォレットごと、nextPageId によるページング)で取得し、特定の注文のイベントログ全体は /limit-order/history/event/list-by-pda?pda=… で取得します。
Rust CPI のスケルトン
SwapV2 の残りアカウントの順序は次のとおりです。
よくある落とし穴
- ティック範囲の端点が間隔に合っていない →
TickAndSpacingNotMatch。必ずTickUtil.getPriceAndTickを使ってスナップしてください(TickUtilは単数形)。 SwapV2に供給するティック配列が不足している →NotEnoughTickArrayAccount。一覧はswapInternal(...).accountsから取得してください。- ビットマップ拡張なしでフルレンジのポジションを作成している → 拡張の PDA は書き込み可能である必要があります。SDK がこれを自動的に処理します。
sqrt_price_x64をpriceと取り違えている → ここでの 2 倍の誤差は特に厄介です。迷ったら、人が読める価格から SDK に計算させてください。- 報酬の回収が頻繁すぎる → 回収のたびにゼロ流動性の
DecreaseLiquidityが実行され、トランザクションが 1 件ずつ発生します。複数のポジションをまとめて処理するにはharvestAllRewardsを使い、そのexecuteには{ sequentially: true }が必要な点に注意してください。 - NFT アカウントを自分でクローズしている →
ClosePositionは NFT をバーンし、その ATA もクローズします。Token-2022 の NFT ミントもクローズされます。一方、従来の SPL Token ミントは、そのプログラムではミントをクローズできないため、供給量ゼロのまま残ります。対応しているアカウントを個別にクローズしないでください。そうすると命令がリバートします。 - ティック間隔に合っていない位置で指値注文を開いている →
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 を組み込む方法。

