dflow について
DFlowは、Solanaの現物市場と予測市場向けの取引プロトコルおよび統合ガイドです。ルート指定型またはインテント型のスワップ、トランザクション生成、予測市場データの照会に対応するAPIを提供します。
主な機能
- 01現物・予測市場の取引API
- 02命令型・宣言型のスワップフロー
- 03見積もりとトランザクション生成
- 04非同期注文の状態確認
- 05予測市場のイベント・市場データ
- 06WebSocketによる価格・板情報更新
活用シーン
- 01Solanaトークンスワップアプリの構築
- 02署名前にスワップルートを選択
- 03実行時にルートを最適化するスワップの送信
- 04予測市場イベントや価格の照会
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sendaifun/ skills --skill dflowインストール後、Claude Code で/dflowを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
docs/advanced-patterns.mdtroubleshooting.mdexamples/declarative-swaps/intent-swap.tsexamples/imperative-swaps/basic-swap.tsexamples/prediction-markets/query-markets.tstrade-outcomes.tswebsocket-client.tsexamples/trade-api/unified-trade.tsresources/api-reference.mderror-codes.mdgithub-sdks.mdprediction-market-api.mdtoken-mints.mdtemplates/prediction-market-client.tsswap-client.ts詳細
DFlow - 完全な統合ガイド
DFlow を統合するための決定版ガイドです。DFlow は、トレーダーが Solana 上で現物市場と予測市場をまたいでネイティブに価値を交換できるようにする取引プロトコルです。
DFlow とは?
DFlow は、以下を提供する包括的な取引インフラストラクチャです。
- 取引アプリケーションとウォレット - インテリジェントなルーティングと 99.9% のトークンカバレッジを備えたトークンスワップ
- 取引所とアグリゲーター - DEX と Prop AMM 全体で、毎月数十億規模のルーティング済み取引量にアクセス
- 金融機関とマーケットメーカー - CLP と非同期取引を備えたプログラム可能な実行レイヤー
- 予測市場プラットフォーム - ディスカバリー、価格設定、ルーティング、決済のインフラストラクチャ
主な機能
| 機能 | 説明 |
|---|---|
| トークンカバレッジ | ミリ秒単位の検出で 99.9% |
| インフラストラクチャ | グローバルに分散され、高スループット向けに最適化 |
| 実行 | 最良価格での実行を実現する JIT ルーティングを備えた高度なアルゴリズム |
| 市場 | 現物取引と予測市場取引の両方に対応 |
| MEV 保護 | Jito バンドルによる強化されたサンドイッチ攻撃対策 |
API の概要
DFlow には、主に 2 つの API カテゴリがあります。
1. スワップ API(取引)
ベース URL: https://quote-api.dflow.net
取引を実行するための API です。
- 命令型スワップ - 署名時にルート選択を完全に制御
- 宣言型スワップ - ルート最適化を後回しにするインテントベースのスワップ
- 取引 API - 現物市場と予測市場の取引に対応する統合インターフェース
- 注文 API - 見積もりとトランザクションを生成
2. 予測市場メタデータ API
ベース URL: https://api.prod.dflow.net
予測市場データを照会するための API です。
- イベント API - 予測イベントと予測結果を照会
- 市場 API - 市場の詳細、オーダーブック、結果ミントを取得
- 取引 API - 過去の取引データ
- ライブデータ API - リアルタイムのマイルストーンと更新情報
- WebSocket - 価格とオーダーブックの更新をストリーミング
認証
ほとんどのエンドポイントでは、x-api-key ヘッダーによる API キー認証が必要です。認証情報を取得するには、[email protected] までお問い合わせください。
クイックスタート
命令型スワップ(3 ステップ)
import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
const API_BASE = "https://quote-api.dflow.net";
const API_KEY = process.env.DFLOW_API_KEY; // Optional but recommended
// Token addresses
const SOL = "So11111111111111111111111111111111111111112";
const USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
async function imperativeSwap(keypair: Keypair, connection: Connection) {
// Step 1: Get Quote
const quoteParams = new URLSearchParams({
inputMint: SOL,
outputMint: USDC,
amount: "1000000000", // 1 SOL
slippageBps: "50", // 0.5%
});
const quote = await fetch(`${API_BASE}/quote?${quoteParams}`, {
headers: API_KEY ? { "x-api-key": API_KEY } : {},
}).then(r => r.json());
// Step 2: Get Swap Transaction
const swapResponse = await fetch(`${API_BASE}/swap`, {
method: "POST",
headers: {
"content-type": "application/json",
...(API_KEY && { "x-api-key": API_KEY }),
},
body: JSON.stringify({
userPublicKey: keypair.publicKey.toBase58(),
quoteResponse: quote,
dynamicComputeUnitLimit: true,
prioritizationFeeLamports: 150000,
}),
}).then(r => r.json());
// Step 3: Sign and Send
const tx = VersionedTransaction.deserialize(
Buffer.from(swapResponse.swapTransaction, "base64")
);
tx.sign([keypair]);
const signature = await connection.sendTransaction(tx);
await connection.confirmTransaction(signature);
return signature;
}
取引 API(統合版 - 推奨)
取引 API は、同期実行と非同期実行の両方を処理する単一のエンドポイントを提供します。
async function tradeTokens(keypair: Keypair, connection: Connection) {
// Step 1: Get Order (quote + transaction in one call)
const orderParams = new URLSearchParams({
inputMint: SOL,
outputMint: USDC,
amount: "1000000000",
slippageBps: "50",
userPublicKey: keypair.publicKey.toBase58(),
});
const order = await fetch(`${API_BASE}/order?${orderParams}`, {
headers: API_KEY ? { "x-api-key": API_KEY } : {},
}).then(r => r.json());
// Step 2: Sign and Send
const tx = VersionedTransaction.deserialize(
Buffer.from(order.transaction, "base64")
);
tx.sign([keypair]);
const signature = await connection.sendTransaction(tx);
// Step 3: Monitor (based on execution mode)
if (order.executionMode === "async") {
// Poll order status for async trades
let status = "pending";
while (status !== "closed" && status !== "failed") {
await new Promise(r => setTimeout(r, 2000));
const statusRes = await fetch(
`${API_BASE}/order-status?signature=${signature}`,
{ headers: API_KEY ? { "x-api-key": API_KEY } : {} }
).then(r => r.json());
status = statusRes.status;
}
} else {
// Sync trades complete atomically
await connection.confirmTransaction(signature);
}
return signature;
}
API リファレンス
注文 API エンドポイント
GET /order
現物取引または予測市場取引の見積もりを返し、オプションでトランザクションも返します。
| パラメーター | 必須 | 説明 |
|---|---|---|
inputMint | はい | Base58 形式の入力トークンミント |
outputMint | はい | Base58 形式の出力トークンミント |
amount | はい | スケーリング済み整数で指定する数量(1 SOL = 1000000000) |
userPublicKey | いいえ | 署名可能なトランザクションを受け取る場合に指定 |
slippageBps | いいえ | ベーシスポイントで指定する最大スリッページ、または "auto" |
platformFeeBps | いいえ | ベーシスポイントで指定するプラットフォーム手数料 |
prioritizationFeeLamports | いいえ | "auto"、"medium"、"high"、"veryHigh"、または Lamport 単位の数量 |
レスポンス:
{
"outAmount": "150000000",
"minOutAmount": "149250000",
"priceImpactPct": "0.05",
"executionMode": "sync",
"transaction": "base64...",
"computeUnitLimit": 200000,
"lastValidBlockHeight": 123456789,
"routePlan": [...]
}
GET /order-status
非同期注文のステータスを確認します。
| パラメーター | 必須 | 説明 |
|---|---|---|
signature | はい | Base58 形式のトランザクション署名 |
lastValidBlockHeight | いいえ | 有効期限の確認に使用するブロック高 |
ステータス値:
pending- 注文を送信済みで、処理待ちですopen- 注文を開始済みで、約定待ちですpendingClose- 約定済みで、クローズトランザクションが保留中ですclosed- 注文が正常に完了しましたexpired- トランザクションが反映される前に期限切れになりましたfailed- 注文の実行に失敗しました
命令型スワップのエンドポイント
GET /quote
インペラティブスワップの見積もりを取得します。
| パラメーター | 必須 | 説明 |
|---|---|---|
inputMint | はい | Base58 形式の入力ミント |
outputMint | はい | Base58 形式の出力ミント |
amount | はい | 入力量(スケーリング済み整数) |
slippageBps | いいえ | スリッページ許容値、または「auto」 |
dexes | いいえ | 対象に含める DEX(カンマ区切り) |
excludeDexes | いいえ | 対象から除外する DEX(カンマ区切り) |
onlyDirectRoutes | いいえ | 単一レッグのルートのみ |
maxRouteLength | いいえ | ルートの最大レッグ数 |
forJitoBundle | いいえ | Jito バンドルに対応するルート |
platformFeeBps | いいえ | プラットフォーム手数料(ベーシスポイント) |
POST /swap
見積もりからスワップトランザクションを生成します。
リクエスト本文:
{
"userPublicKey": "Base58...",
"quoteResponse": { /* from /quote */ },
"dynamicComputeUnitLimit": true,
"prioritizationFeeLamports": 150000,
"wrapAndUnwrapSol": true
}
レスポンス:
{
"swapTransaction": "base64...",
"computeUnitLimit": 200000,
"lastValidBlockHeight": 123456789,
"prioritizationFeeLamports": 150000
}
POST /swap-instructions
トランザクション全体の代わりに個別のインストラクションを返します(カスタムトランザクションの構築用)。
宣言型スワップエンドポイント
宣言型スワップでは、ルートの最適化を遅延させるインテントベースの実行を使用します。
GET /intent
宣言型スワップのインテント見積もりを取得します。
| パラメーター | 必須 | 説明 |
|---|---|---|
inputMint | はい | Base58 形式の入力ミント |
outputMint | はい | Base58 形式の出力ミント |
amount | はい | 入力量(スケーリング済み整数) |
slippageBps | いいえ | スリッページ許容値 |
userPublicKey | はい | ユーザーのウォレットアドレス |
POST /submit-intent
署名済みインテントトランザクションを実行のために送信します。
リクエスト本文:
{
"signedTransaction": "base64...",
"intentResponse": { /* from /intent */ }
}
トークン API エンドポイント
GET /tokens
サポートされているトークンミントの一覧を返します。
GET /tokens-with-decimals
適切な数量スケーリングに必要な小数桁情報を含むトークンを返します。
ベニュー API エンドポイント
GET /venues
サポートされている DEX ベニュー(Raydium、Orca、Phoenix、Lifinity など)の一覧を返します。
スワップモードの比較
| 機能 | インペラティブ | 宣言型 |
|---|---|---|
| ルート制御 | 署名時に完全に制御 | 実行時に最適化 |
| レイテンシー | 高い(API 呼び出しが 2 回) | 低い(計算を遅延) |
| スリッページ | 見積もり時に固定 | 実行時に最小化 |
| サンドイッチ攻撃対策 | 標準 | 強化 |
| ユースケース | ルート要件を厳密に指定 | 最良の執行を優先 |
インペラティブを使用する場合
- 署名前に正確なルートを確認する必要がある
- オーダーブックや特定の DEX ルーティングを構築する
- 複雑な複数ステップのトランザクション
- 決定論的な実行パスが必要
宣言型を使用する場合
- 最良の執行を優先する
- スリッページを低く抑える必要がある
- シンプルなトークンスワップ
- MEV 対策が重要
実行モード
同期(アトミック)
- 単一トランザクションで実行
- 全成功または全失敗の決済
- 標準的な確認フロー
connection.confirmTransaction()を使用
非同期(複数トランザクション)
- Jito バンドルを使用
- Open → Fill → Close のトランザクションフロー
- 完了まで
/order-statusをポーリング - 複雑なルートや予測市場に適しています
// Async order monitoring
async function monitorAsyncOrder(signature: string) {
const statuses = ["pending", "open", "pendingClose"];
let currentStatus = "pending";
while (statuses.includes(currentStatus)) {
await new Promise(r => setTimeout(r, 2000));
const res = await fetch(
`${API_BASE}/order-status?signature=${signature}`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
currentStatus = res.status;
if (currentStatus === "closed") {
return { success: true, fills: res.fills };
}
if (currentStatus === "failed" || currentStatus === "expired") {
return { success: false, status: currentStatus };
}
}
}
予測市場
DFlow は、予測市場の結果トークンを取引するためのインフラストラクチャを提供します。
市場の構造
Series (Collection)
└── Event (Occurrence)
└── Market (Outcome Trade)
市場のライフサイクル
- 初期化済み - 市場が作成されました
- アクティブ - 取引が有効です
- 非アクティブ - 取引が一時停止されています
- 終了 - これ以上取引できません
- 結果確定 - 結果が判明しました
- 最終確定 - 払い戻しが利用可能です
予測市場の取引
// Use the Trade API with prediction market token mints
const order = await fetch(`${API_BASE}/order?${new URLSearchParams({
inputMint: USDC,
outputMint: OUTCOME_TOKEN_MINT, // Prediction market token
amount: "10000000", // 10 USDC
slippageBps: "100",
userPublicKey: keypair.publicKey.toBase58(),
predictionMarketSlippageBps: "200", // Separate slippage for PM
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());
一般的なトークンミント
| トークン | ミントアドレス |
|---|---|
| SOL(ラップ済み) | So11111111111111111111111111111111111111112 |
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| BONK | DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 |
| JUP | JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN |
| WIF | EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm |
優先手数料
トランザクションの優先度を設定します。
// Option 1: Auto (recommended)
prioritizationFeeLamports: "auto"
// Option 2: Priority level
prioritizationFeeLamports: {
priorityLevel: "high" // "medium", "high", "veryHigh"
}
// Option 3: Exact amount
prioritizationFeeLamports: 150000
// Option 4: Max with auto-adjust
prioritizationFeeLamports: {
autoMultiplier: 2,
maxLamports: 500000
}
エラー処理
async function safeSwap(params: SwapParams) {
try {
const quote = await getQuote(params);
if (!quote.routePlan?.length) {
throw new Error("No route found");
}
const swap = await getSwapTransaction(quote, params.userPublicKey);
const tx = deserializeTransaction(swap.swapTransaction);
tx.sign([params.keypair]);
const signature = await connection.sendTransaction(tx, {
skipPreflight: false,
maxRetries: 3,
});
return { success: true, signature };
} catch (error) {
if (error.message.includes("insufficient")) {
return { success: false, error: "Insufficient balance" };
}
if (error.message.includes("slippage")) {
return { success: false, error: "Slippage exceeded" };
}
return { success: false, error: error.message };
}
}
プラットフォーム手数料
スワップでプラットフォーム手数料を徴収します。
const quote = await fetch(`${API_BASE}/quote?${new URLSearchParams({
inputMint: SOL,
outputMint: USDC,
amount: "1000000000",
platformFeeBps: "50", // 0.5% fee
platformFeeMode: "outputMint", // Collect in output token
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());
// In swap request, specify fee account
const swap = await fetch(`${API_BASE}/swap`, {
method: "POST",
headers: { "content-type": "application/json", "x-api-key": API_KEY },
body: JSON.stringify({
userPublicKey: user.toBase58(),
quoteResponse: quote,
feeAccount: platformFeeAccount.toBase58(), // Your fee recipient
}),
}).then(r => r.json());
Jito との統合
MEV 対策とバンドル送信に使用します。
// Request Jito-compatible routes
const quote = await fetch(`${API_BASE}/quote?${new URLSearchParams({
inputMint: SOL,
outputMint: USDC,
amount: "1000000000",
forJitoBundle: "true",
})}`, { headers: { "x-api-key": API_KEY } }).then(r => r.json());
// Include Jito sandwich mitigation
const swap = await fetch(`${API_BASE}/swap`, {
method: "POST",
body: JSON.stringify({
userPublicKey: user.toBase58(),
quoteResponse: quote,
includeJitoSandwichMitigationAccount: true,
}),
}).then(r => r.json());
DFlow Swap Orchestrator
DFlow Swap Orchestrator コントラクトは、宣言型のスワップ実行を管理します。
Program ID: DF1ow3DqMj3HvTj8i8J9yM2hE9hCrLLXpdbaKZu4ZPnz
Prediction Market Metadata API
Prediction Market Metadata API は、予測市場情報に包括的にアクセスできます。
ベース URL: https://api.prod.dflow.net
市場構造
Series (Collection)
└── Event (Occurrence)
└── Market (Outcome Trade)
├── Yes Token (outcome mint)
└── No Token (outcome mint)
イベント API
GET /api/v1/event/{ticker}
ティッカーを指定して、ネストされた市場を任意で含む単一のイベントを返します。
const METADATA_API = "https://api.prod.dflow.net";
// Get event details
const event = await fetch(`${METADATA_API}/api/v1/event/TRUMP-2024`, {
headers: { "x-api-key": API_KEY }
}).then(r => r.json());
// Response includes: ticker, title, status, markets, close_time, etc.
GET /api/v1/events
すべてのイベントをページネーション付きで返します。
const events = await fetch(`${METADATA_API}/api/v1/events?limit=50&offset=0`, {
headers: { "x-api-key": API_KEY }
}).then(r => r.json());
GET /api/v1/event/{ticker}/forecast
過去の予測パーセンタイルデータを返します。
GET /api/v1/event/{ticker}/candlesticks
Kalshi のローソク足データを返します。
市場 API
GET /api/v1/market/{ticker}
ティッカーを指定して、単一の市場を返します。
const market = await fetch(`${METADATA_API}/api/v1/market/TRUMP-2024-WIN`, {
headers: { "x-api-key": API_KEY }
}).then(r => r.json());
// Response: ticker, yes_mint, no_mint, status, last_price, volume, etc.
GET /api/v1/market/by-mint/{mint_address}
任意のミント(台帳またはアウトカムのミント)から市場を検索します。
const market = await fetch(
`${METADATA_API}/api/v1/market/by-mint/${outcomeMint}`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
POST /api/v1/markets/batch
複数の市場をまとめて取得します(最大 100 件)。
const markets = await fetch(`${METADATA_API}/api/v1/markets/batch`, {
method: "POST",
headers: { "content-type": "application/json", "x-api-key": API_KEY },
body: JSON.stringify({
tickers: ["MARKET-1", "MARKET-2"],
mints: ["mint1...", "mint2..."]
})
}).then(r => r.json());
GET /api/v1/outcome_mints
サポート対象のすべての市場から、すべての yes_mint および no_mint の公開鍵を返します。
// Get all outcome mints, optionally filter by close time
const mints = await fetch(
`${METADATA_API}/api/v1/outcome_mints?min_close_timestamp=${Date.now()}`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
POST /api/v1/filter_outcome_mints
アドレスがアウトカムのミントかどうかを確認します(最大 200 件)。
const filtered = await fetch(`${METADATA_API}/api/v1/filter_outcome_mints`, {
method: "POST",
headers: { "content-type": "application/json", "x-api-key": API_KEY },
body: JSON.stringify({ addresses: ["mint1...", "mint2..."] })
}).then(r => r.json());
オーダーブック API
GET /api/v1/orderbook/{ticker}
市場のティッカーを指定してオーダーブックを取得します。
const orderbook = await fetch(
`${METADATA_API}/api/v1/orderbook/TRUMP-2024-WIN`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
// Response: bids: [{price, quantity}], asks: [{price, quantity}]
GET /api/v1/orderbook/by-mint/{mint_address}
ミントアドレスで検索してオーダーブックを取得します。
取引 API
GET /api/v1/trades
フィルタリングに対応した、ページネーション付きの取引履歴を返します。
const trades = await fetch(
`${METADATA_API}/api/v1/trades?ticker=TRUMP-2024-WIN&limit=100`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
GET /api/v1/trades/by-mint/{mint_address}
ミントアドレスで検索して取引を取得します。
ライブデータ API
GET /api/v1/milestones/{ticker}
Kalshi のリアルタイムのマイルストーンデータを返します。
const milestones = await fetch(
`${METADATA_API}/api/v1/milestones/TRUMP-2024`,
{ headers: { "x-api-key": API_KEY } }
).then(r => r.json());
シリーズとカテゴリ
GET /api/v1/series
定期的に発生するイベントのシリーズテンプレートを返します。
GET /api/v1/categories
フィルタリング用のカテゴリタグを返します。
WebSocket ストリーミング
リアルタイム更新を受信するには接続します。
const ws = new WebSocket("wss://api.prod.dflow.net/ws");
ws.onopen = () => {
// Subscribe to market updates
ws.send(JSON.stringify({
action: "subscribe",
channel: "market",
ticker: "TRUMP-2024-WIN"
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
// Handle: price_update, orderbook_update, trade, etc.
console.log("Update:", data);
};
市場のライフサイクル
| ステータス | 説明 |
|---|---|
initialized | 市場が作成されました |
active | 取引が有効です |
inactive | 取引が一時停止されています |
closed | 取引が終了しました |
determined | アウトカムが判明しました |
finalized | ペイアウトを利用できます |
GitHub ツールと SDK
DFlow は GitHub で複数のオープンソースツールを提供しています。
solana-agent-kit
リポジトリ: DFlowProtocol/solana-agent-kit
AI エージェントが Solana プロトコルに接続できるツールキットです。
// Use with AI agents for automated trading
import { SolanaAgentKit } from "@dflow/solana-agent-kit";
const agent = new SolanaAgentKit({
rpcUrl: process.env.RPC_URL,
privateKey: process.env.PRIVATE_KEY,
});
// Agent can execute DFlow swaps, query markets, etc.
clearpools
リポジトリ: DFlowProtocol/clearpools
フローのセグメンテーションに対応した Orca Whirlpools です。
// Extends Orca protocol with DFlow routing
import { ClearPools } from "@dflow/clearpools";
const pools = new ClearPools(connection);
await pools.initializePool(/* params */);
dflow-amm-interface
リポジトリ: DFlowProtocol/dflow-amm-interface
DFlow の AMM 実装用の Rust トレイト定義です。DFlow のルーティングと統合するカスタム AMM の構築に使用します。
スキルの構成
dflow/
├── SKILL.md # This file - complete integration guide
├── resources/
│ ├── api-reference.md # Swap API reference
│ ├── prediction-market-api.md # Prediction Market Metadata API reference
│ ├── github-sdks.md # GitHub tools & SDKs documentation
│ ├── token-mints.md # Common token addresses
│ └── error-codes.md # Error handling guide
├── examples/
│ ├── imperative-swaps/ # Imperative swap examples
│ ├── declarative-swaps/ # Declarative swap examples
│ ├── trade-api/ # Unified Trade API examples
│ └── prediction-markets/ # Prediction market examples
│ ├── query-markets.ts # Query events, markets, orderbook
│ ├── trade-outcomes.ts # Trade outcome tokens
│ └── websocket-client.ts # Real-time data streaming
├── templates/
│ ├── swap-client.ts # Swap client starter
│ └── prediction-market-client.ts # Prediction market client starter
└── docs/
├── advanced-patterns.md # Complex integrations
└── troubleshooting.md # Common issues
ガイドライン
- ほとんどの場合は Trade API を使用する - 統合エンドポイントが同期と非同期の両方を処理します
- 非同期注文は必ず処理する -
executionModeを確認してステータスをポーリングします - 適切なスリッページを設定する - 手軽さを重視する場合は「auto」、制御する場合はカスタム値を指定します
- 優先手数料を含める - 安定した実行に不可欠です
- エラーを適切に処理する - ネットワークの問題、スリッページ、残高不足に対応します
- レート制限を監視する - 本番環境では API キーを使用します
- まず devnet でテストする - DFlow は Solana devnet に対応しています