メインコンテンツへスキップ

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

このページは AI による自動翻訳です。すべての内容は英語版を正とします。英語版を表示 →
アグリゲーターの役割は、複数のプール全体でユーザーに最適な価格を提供し、単一の入力を複数のプール ルート間で分割し、原子的に実行することです。このページでは、検出、見積もり、トランザクション作成といった Raydium 固有の処理について説明します。

検出

プール インベントリ

各プロダクトの稼働中 Raydium プール全体のリストが必要です。3 つのオプションがあります:
  1. REST API(最もシンプル):GET https://api-v3.raydium.io/pools/info/list?poolType=all&pageSize=1000&page=1 は 1000 件ずつプールを返します。すべて取得するまでページネーションします。1~5 分間キャッシュしてください。
  2. オンチェーン スキャン:CPMM、CLMM、AMM v4 プログラム ID に対して getProgramAccounts を実行し、ステート アカウント ディスクリミネーターでフィルタします。約 10 秒の RPC 時間で、ほぼすべての稼働中プールを取得できます。API がダウンしているか、レート制限されている場合に便利です。
  3. ハイブリッド:API をプライマリ ソースとして使用し、1 日 1 回のオンチェーン スキャンをサニティ チェックとして実行します。チーム側では API の包括性を維持することを公約していますが、直接 CPI を通じて作成されたプール(フロントエンドなし)は時々遅れることがあります。

ミント ペア ルックアップ

特定の (mintA, mintB) ペアについては、GET /pools/info/mint?mint1=...&mint2=...&poolType=all&sort=liquidity を使用します。あらゆるフィー ティアとプロダクト タイプのすべてのプールを返します。トラフィックの多いミントでは、ペアあたり最大約 10 件の結果が一般的です。TVL でソートして上位数件をルーティングに使用してください。

見積もり

見積もり計算はプロダクトごとに異なります。再実装しないよう SDK の純粋な計算関数を使用してください:
// CPMM
const cpmmQuote = raydium.cpmm.computeAmountOut({
  poolInfo: cpmmPool,
  amountIn,
  mintIn,
  mintOut,
  slippage: 0,        // compute exact expected; layer slippage at route level
});

// CLMM — crosses ticks; deterministic but more expensive.
// `computeAmountOutFormat` is the canonical helper exposed via `PoolUtils` in
// raydium-sdk-v2: the `*Format` suffix signals that it returns the output
// pre-shaped for transaction building (including `remainingAccounts` for tick arrays).
const { output: clmmOut, remainingAccounts } = PoolUtils.computeAmountOutFormat({
  poolInfo:  clmmPool,
  poolState: clmmPoolState,
  tickArrayCache,
  amountIn,
  tokenIn:   mintIn,
  slippage:  0,
});

// AMM v4
const ammV4Quote = raydium.liquidity.computeAmountOut({
  poolInfo: ammV4Pool,
  amountIn,
  mintIn: mintIn,
  mintOut: mintOut,
  slippage: 0,
});
3 つすべてで返されるもの:{ amountOut, fee, priceImpact, minAmountOut }。アグリゲーター比較では、amountOut(スリッページ前)を使用してください。

キャッシュの鮮度

プール ステートはすぐに古くなります。推奨される鮮度目標は以下の通りです:
プール タイプ再取得頻度理由
<$100k TVL の CPMM<10sすべてのトレードでリザーブが変動します。
>$10M TVL の CPMM30~60 秒リザーブが支配的で、小規模トレードはノイズです。
CLMM<30sティック境界;単一の大型トレードでリクイディティが再設定できます。
AMM v4<30sOpenBook 側の動きがボールトに反映されません。
インタラクティブ レイテンシーで見積もりを取得するアグリゲーターの場合は、関連する各プール ステートで WebSocket アカウント更新(accountSubscribe)にサブスクライブしてください。これにより、ポーリング モデルからプッシュ モデルに切り替わります。

Token-2022 調整

ルート内のいずれかのミント に Token-2022 トランスファー フィーがある場合、見積もり計算は algorithms/token-2022-transfer-fees に従って入力と出力を調整する必要があります。SDK は poolInfo.mintA.extensions.transferFeeConfig が入力されている場合これを処理します。見積もりを信頼する前に、.extensions フィールドを確認してください。

ルーティング

シングル プール ルート

ほとんどのルートはシングル プールです。amountOut が最も高いプールを選択してください。複数のプールが接近している場合は、フィー ティア(低いほど良い)で同点を解消し、次に TVL(大きいほど安全)で解消します。

スプリット ルーティング

単一プールの価格影響が >5% の大型トレードの場合、プール間で分割してください。シンプルな貪欲アルゴリズム:
remaining = amountIn
routes    = []
while remaining > 0:
    best_pool, best_size = argmax over pools of:
        marginal_out_per_in(pool, current_size_toward_pool + epsilon)
    size = min(remaining, best_pool.max_size_at_target_impact)
    routes.append((best_pool, size))
    remaining -= size
これにより、集約影響を最小化するルーティング ベクトル [(pool_A, 0.6), (pool_B, 0.3), (pool_C, 0.1)] が生成されます。適切な凸最適化ソリューション(例:プール間で限界価格を均等化)は、実際には貪欲結果の約 1% 以内です。

マルチホップ ルート

直接 USDC-SOL プールが良い見積もりを提供しない場合(稀)、2 つの別のプール経由で USDC → RAY → SOL を実行することは一般的です。ホップごとにスリッページ上限を適用します。各ホップは独自の minAmountOut を適用します。algorithms/slippage-and-price-impact を参照してください。 同じプール上のマルチホップ(例:SOL-USDC 上の 2 つの CLMM ホップ)は、シングル ホップと比べて常に最適ではありません。そのようなルートを生成しないでください。

トランザクション作成

シングル ホップ、シングル プール

SDK の raydium.trade.swap を直接使用してください:
const { execute } = await raydium.trade.swap({
  poolKeys:        poolInfo,
  amountIn,
  amountOut:       quote.minAmountOut,
  fixedSide:       "in",
  inputMint:       mintIn,
  txVersion:       TxVersion.V0,
  computeBudgetConfig: {
    units:         250_000,
    microLamports: priorityFee,
  },
});

スプリットおよびマルチホップ

ATA とインストラクションを手動で構成してください。パターン:
[1] ComputeBudget set_compute_unit_limit
[2] ComputeBudget set_compute_unit_price
[3] createATA (if needed, once per mint the user doesn't hold)
[4..N] SwapInstruction for each (pool, size) in routes
[N+1] CloseAccount (if you wrap/unwrap SOL)
すべてを 1 つのトランザクション内に含めて原子性を保証します。V0 上の 3 プール スプリットでアドレス ルックアップ テーブルを使用する場合、通常は約 1100 バイトに収まります。4 つ以上のプールの場合、トランザクション サイズの上限により、マルチ tx またはハブ ミント での統合が必要になります。

原子性

アグリゲーターは原子性を保証する必要があります。つまり、完全なルートが着地するか、まったく着地しないかのどちらかです。Raydium のスワップ インストラクションは ExceededSlippage で復帰するため、1 つのホップが失敗するマルチプール ルートはトランザクション全体を復帰させます。無料です。 唯一の例外:ルートが Raydium + サードパーティ DEX を通過する場合、その DEX もスリッページ復帰モデルがあることを確認してください。一部のプログラムはスリッページ上限を無視します(稀)。

ピットフォール

1. 古い見積もり

ユーザーが「125.43 RAY を受け取ります」と表示されてからトランザクションが着地するまでの間に、リザーブがシフトする可能性があります。提出直前にプール ステートを再取得し、再見積もりします。新しい見積もりが 1% 以上悪い場合は、一時停止してユーザーに再確認してください。

2. プール ブラックリスト

一部の Raydium プールは、トランスファー フィーが 99% に設定されているか、転送不可能なエクステンションを持つスキャム トークンです。REST API はこれらにタグを付けます(tags フィールドを参照)。scam または honeypot タグが付いているプールをスキップしてください。Raydium のタグの上で独自のセーフティ チェックを実行することが適切です。

3. CLMM のオブザベーション ステート要件

CLMM SwapV2observation_state アカウントを取得します。SDK はこれを入力します。手動で構築されたインストラクションは忘れていることが多く、プログラムが AccountNotFound で復帰します。常に含めてください。

4. アドレス ルックアップ テーブル

Raydium は、最も使用されるアカウント(メイン ミント、プログラム ID、AmmConfigs)のパブリック ルックアップ テーブルを管理しています。アグリゲーターはこれらを使用する必要があります。トランザクションあたり約 100 バイト節約でき、より大きなルートが V0 に収まるようになります。LUT アドレスの取得:
const raydiumLUTs = await raydium.getRaydiumLutAddresses();

5. 混雑への対応

高スループット期間では、トランザクションはメモリプール内で複数ブロック留まる可能性があります。TX 有効期限時の積極的な再試行(復帰時ではなく;復帰は確定的)を推奨します。SDK の sendAndConfirm オプションは基本的な再試行を行い、本番アグリゲーターはその上に独自のロジック(Jito バンドル、マルチ RPC ブロードキャスト)を重ねます。

チェックリスト

本番稼働前に以下を確認してください:
  • プール検出は CPMM + CLMM + AMM v4 を包括的にカバーしています。
  • 見積もりは、テスト トレード数件で Raydium 独自の UI 見積もりと 1 ベーシス ポイント以内で一致します。
  • スプリット ルーティングは、任意の単一プール上での取引 >5% 影響でキックインします。
  • プライオリティ フィーは最近のプール プログラム フィーに対してサイズ設定されています(integration-guides/priority-fee-tuning を参照)。
  • Token-2022 トランスファー フィーが計算され、ユーザーに表示されます。
  • スリッページを超過した場合、トランザクションはきれいに復帰します。
  • 再試行ロジックは tx 有効期限(再試行)と復帰(再試行しない)を区別します。

ポインター

ソース: