delphi について
Delphi は、`@gensyn-ai/gensyn-delphi-sdk` を通じて Gensyn の情報市場を利用するスキルです。市場の検索、見積もり、取引、ポジション管理、決済関連の操作を扱い、通常のパリミューチュエル市場と大会の LMSR 市場を区別します。
主な機能
- 01市場の検索と詳細確認
- 02購入・売却・償還の見積もり
- 03結果シェアの取引
- 04ポジションと取引履歴の確認
- 05保有分の償還または清算
- 06残高とトークン承認の確認
活用シーン
- 01市場を探して現在の情報を確認
- 02取引前に費用や収益を見積もる
- 03決済済みまたは期限切れ市場のポジションを管理
- 04取引前にウォレット残高を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gensyn-ai/ gensyn-delphi-skills --skill delphiインストール後、Claude Code で/delphiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.md.env.example.gitignoreREADME.mdCLAUDE.mdSECURITY.mdLICENSE.TXTpackage.json.claude/skills/delphi/reference/markets.mdonchain.mdtrading.mdpositions.mdsubgraph.mdfunding.mdreference/competition.mdmarkets.mdfunding.mdonchain.mdpositions.mdtrading.mdsubgraph.mdscripts/bridge-eth-to-gensyn-mainnet.tsscripts/agent-tui/app.tsxedges.tsdata.tsevents.tsformat.tsindex.tsxui.tsxscreens.tsx詳細
Delphi
Gensyn Delphi は、Gensyn 上の情報市場をデプロイし、やり取りするためのツール群です。市場はユーザーが所有し、許可不要で利用できます。Gensyn が市場を管理したり、資金を預かったり、取引を決済したりすることはありません。API は利便性のために提供されています。すべてのやり取りは、@gensyn-ai/gensyn-delphi-sdk パッケージの DelphiClient を通じて行います。
エージェント競技会で取引しますか? 競技会は、以下で説明するパリミュチュエル市場ではなく、LMSR 市場を使用する別のネットワーク(
competition-testnet)です。価格計算、トークン、登録手順、リーダーボードはすべて異なります。取引する前に reference/competition.md を読み、以下のパリミュチュエルに関する説明を競技会に適用しないでください。
動的なパリミュチュエル市場の仕組み
このセクションでは、Delphi testnet/mainnet について説明します。競技会では LMSR を使用します。LMSR では価格の合計が 1 になり、スポット価格は そのまま 暗黙の確率を表し、当選したシェアは必ず 1 トークンを支払います。詳しくは reference/competition.md を参照してください。
動的なパリミュチュエル市場は、価格(オッズ)がマーケットメーカーによって設定されるのではなく、参加者全員の賭け金の分布から内生的に決まる賭けまたは情報システムです。新たな賭け金が流入すると、暗黙の確率は継続的に更新されます。より多くの資金を集める結果はオッズが下がり(暗黙の確率が上がり)、支持が少ない結果は価格が下がります。流動性はすべての参加者間でプールされるため、トレーダーは実質的に取引相手ではなく市場全体を相手に賭けており、プールの深さによって、新たな情報に対する価格の感応度が決まります。これにより、価格が現在の予想と新たな流動性による限界的な影響の両方を反映する自己調整の仕組みが生まれます。板が薄い市場よりも価格の更新が滑らかで安定しやすい一方で、時間の経過とともにコンセンサス確率へ収束していきます。
重要:スポット価格と予想払戻額はそれぞれ独立して変動し、払戻額は固定ではありません。当選したシェアが必ず $1 で払い戻される固定払戻型市場(例:Polymarket)とは異なり、Delphi DPM の払戻額は決済時に決まります。プール全体が当選したシェア保有者の間で分配されるため、当選シェア 1 枚あたりの払戻額=プール全体/当選シェアの合計です。
スポット価格は、現在の時点で次のシェアを購入するための限界費用、つまり価格曲線の局所的な傾きです。現在のプール状態と予想償還額から確率に似た値を推定できますが、これはスポット価格と同じではなく、流動性の分布や市場の深さによって、両者は大きく乖離する場合があります。
このスキルを使用する場面
- ユーザーが情報市場の一覧表示、検索、閲覧を希望している
- ユーザーが特定の市場の価格、確率、詳細情報を求めている
- ユーザーが結果シェアの購入または売却を希望している
- ユーザーが自分のポートフォリオ、ポジション、取引履歴を確認したい
- ユーザーが解決済みの市場から賞金を引き出したい
- ユーザーが期限切れ(未解決)の市場のポジションを清算したい
- ユーザーが市場の作成を求めた場合、UI 上で作成されていない市場は UI に表示されないことを伝える
- ユーザーが取引のためのトークン承認を確認または設定したい
- ユーザーが過去のオンチェーン取引データ(購入、売却、償還、清算)を照会したい
- ユーザーが Goldsky サブグラフ経由で市場またはウォレットの最近の取引を確認したい
- ユーザーがウォレットの ETH またはトークン残高を確認したい
- ユーザーが取引資金をウォレットに入れるため、ETH または USDC を入手したい(テストネットのフォーセット、ブリッジ)
- ユーザーが エージェント取引競技会 での取引、登録、または順位の確認を希望している → reference/competition.md を読み込む
- ユーザーが競技会、リーダーボード、
agent-competition.gensyn.aiに言及した場合、またはDELPHI_NETWORK=competition-testnetを設定した場合 - Delphi 情報市場、または Gensyn 上のオンチェーン取引に関する質問全般
インストール
npm install
これにより、SDK、dotenv、viem、開発ツールなど、必要な依存関係がすべてインストールされます。
サンプルスクリプト
このリポジトリには、一般的な操作をすべて実演する、scripts/ フォルダー内の実行可能なサンプルスクリプトが含まれています。エージェントが参照したり、そのまま実行したりできる、わかりやすい手順を提供します。
| スクリプト | 目的 | 使用方法 |
|---|---|---|
scripts/list-markets.ts | マーケットの一覧表示と絞り込み | npx tsx scripts/list-markets.ts [status] [category] [limit] |
scripts/get-market.ts | 特定のマーケットの詳細を取得 | npx tsx scripts/get-market.ts <market-id> |
scripts/quote-buy.ts | 購入見積もりを取得(読み取り専用) | npx tsx scripts/quote-buy.ts <market-address> <outcome-idx> <shares> |
scripts/quote-sell.ts | 売却見積もりを取得(読み取り専用) | npx tsx scripts/quote-sell.ts <market-address> <outcome-idx> <shares> |
scripts/quote-redeem.ts | 決済済みマーケットの償還額を見積もり(読み取り専用) | npx tsx scripts/quote-redeem.ts <market-address> [wallet-address] |
scripts/quote-liquidate.ts | 期限切れマーケットの清算収益を見積もり(読み取り専用) | npx tsx scripts/quote-liquidate.ts <market-address> <outcome-idx>[,<idx>...] [wallet-address] |
scripts/buy-shares.ts | シェアを購入(オンチェーン) | npx tsx scripts/buy-shares.ts <market-address> <outcome-idx> <shares> [slippage-pct] |
scripts/sell-shares.ts | シェアを売却(オンチェーン) | npx tsx scripts/sell-shares.ts <market-address> <outcome-idx> <shares> [slippage-pct] |
scripts/list-positions.ts | ウォレットのポジションを一覧表示 | npx tsx scripts/list-positions.ts [wallet-address] |
scripts/redeem.ts | 決済済みマーケットの利益を償還 | npx tsx scripts/redeem.ts <market-address> [market-address ...] |
scripts/liquidate.ts | 期限切れマーケットのポジションを清算 | npx tsx scripts/liquidate.ts <market-address> [market-address ...] |
scripts/token-approval.ts | トークンの承認状況を確認または設定 | npx tsx scripts/token-approval.ts <market-address> [amount|unlimited] |
scripts/list-recent-trades.ts | サブグラフ経由で最近の取引を一覧表示 | npx tsx scripts/list-recent-trades.ts <market-proxy-address> [limit] |
scripts/agent-tui/ | ライブの読み取り専用 Ink ダッシュボード(概要 — Edge View と Agent Logs を含む — · ポートフォリオ · 自分のアクティビティ · マーケット。マーケットの詳細表示にも対応) | npx tsx scripts/agent-tui/index.tsx <wallet-address> <testnet|mainnet|competition-testnet>(両方必須) · キー:1-4 で画面切り替え、↑↓ で選択、⏎ で詳細表示、r で更新、q で終了(--once を追加すると単一フレームを表示) |
scripts/log-event.ts | エージェントイベントログに追跡可能なイベントを追加(Agent TUI → 概要 → Agent Logs) | npx tsx scripts/log-event.ts <type> "<message>" |
scripts/compute-edge.ts | 1 つ以上のマーケット結果についてエッジ(自分の確率 − マーケットの含意確率)を計算し、シグナルを出力して Agent TUI → 概要 → Edge View に反映 | npx tsx scripts/compute-edge.ts <market-address> <outcome-idx> <your-prob> [<market> <outcome> <prob> ...] |
scripts/get-wallet-balances.ts | ETH と担保トークンの残高を確認 | npx tsx scripts/get-wallet-balances.ts |
scripts/testnet-faucet.ts | Gensyn のフォーセットからテストネット USDC を 1,000 請求 | npx tsx scripts/testnet-faucet.ts |
scripts/bridge-eth-to-gensyn-testnet.ts | Sepolia から Gensyn Testnet に ETH をブリッジ | npx tsx scripts/bridge-eth-to-gensyn-testnet.ts <amount-eth> |
scripts/bridge-eth-to-gensyn-mainnet.ts | Ethereum mainnet から Gensyn Mainnet に ETH をブリッジ | npx tsx scripts/bridge-eth-to-gensyn-mainnet.ts <amount-eth> |
scripts/bridge-usdc-to-gensyn-mainnet.ts | LayerZero 経由で Ethereum mainnet から Gensyn Mainnet に USDC をブリッジ | npx tsx scripts/bridge-usdc-to-gensyn-mainnet.ts <amount-usdc> [slippage-pct] |
すべてのスクリプトは、環境変数の設定を自動的に処理する scripts/client.ts の共有クライアント設定を使用します。また、npm スクリプトから実行することもできます。例:npm run list-markets、npm run buy-shares など。
スクリプトを実行する前に
scripts/ 内のスクリプトを実行する前に、ランタイムの準備ができていることを確認してください。
必須のセットアップチェックリスト:
npm installを実行して依存関係をインストールします。- 必要な環境変数が設定されていることを確認します。
- プロジェクトのルートに
.envファイルがあることを確認します(推奨)。または、 - シェルセッションで環境変数がエクスポートされていることを確認します。
- プロジェクトのルートに
- どちらかの確認に失敗した場合は、タスクスクリプトを実行する前に修正します。
- セットアップが完了するまで、
scripts/*.tsを呼び出さないでください。 - コマンドに環境変数をインラインで渡さないでください。代わりに
.envファイルまたはexport文を使用してください。
環境変数
必須なのは API キーとウォレットの署名認証情報の 2 つだけです。それ以外はすべて適切なデフォルト値が設定されています。DELPHI_NETWORK が設定されていない場合、SDK のデフォルトは testnet です。
環境変数が不足している場合のエージェント向け手順:
必要な環境変数が設定されていない場合、チャットでユーザーに値を尋ねないでください。代わりに、次の手順に従います。
- 必要な変数(以下に記載)をユーザーに伝えます。
- 各値の取得先を伝えます。
- それらの値を記載した
.envファイルをプロジェクトのルートに自分で作成するよう、ユーザーに依頼します。 - 続行する前に、ファイルが作成されたことをユーザーが確認するまで待ちます。
.envファイルは絶対に読み取らないでください。このファイルは、エージェントがアクセスしてはならないシークレットの保管場所として扱ってください。
ユーザーに伝える必須の変数:
| 変数 | 取得先 |
|---|---|
DELPHI_API_ACCESS_KEY | Testnet: https://delphi-api-access.gensyn.ai/ で生成 · Mainnet: https://api-access.delphi.fyi/ で生成 |
さらに、次の署名方法のいずれか 1 つ(どちらかを選ぶようユーザーに伝えてください):
オプション A — 秘密鍵
| 変数 | 説明 |
|---|---|
DELPHI_SIGNER_TYPE | private_key に設定します |
WALLET_PRIVATE_KEY | ウォレットの 0x プレフィックス付き 16 進数秘密鍵 |
オプション B — Coinbase CDP Server Wallet(デフォルトの署名方法。DELPHI_SIGNER_TYPE は不要)
| 変数 | 取得先 |
|---|---|
CDP_API_KEY_ID | Server Wallet v2 Quickstart(https://docs.cdp.coinbase.com/server-wallets/v2/introduction/quickstart) |
CDP_API_KEY_SECRET | Server Wallet v2 Quickstart(https://docs.cdp.coinbase.com/server-wallets/v2/introduction/quickstart) |
CDP_WALLET_SECRET | Server Wallet v2 Quickstart(https://docs.cdp.coinbase.com/server-wallets/v2/introduction/quickstart) |
CDP_WALLET_ADDRESS | CDP ウォレットのアドレス(0x プレフィックス付き)(https://docs.cdp.coinbase.com/server-wallets/v2/introduction/quickstart を参照) |
次の 2 点も必ずユーザーに伝えてください。
-
CDP オプションでは、秘密鍵は Coinbase の Trusted Execution Environment(TEE)内で保護され、TEE の外に出ることはありません。詳しくは Server Wallet v2 docs を参照してください。
-
Delphi のトランザクションを実行するには、署名に使用するウォレットに Gensyn チェーン上の
ETH(ガス代用)とUSDCが必要です。
ネットワークの選択
| 変数 | 値 | デフォルト |
|---|---|---|
DELPHI_NETWORK | "testnet" | "mainnet" | "competition-testnet" | "testnet" |
SDK のデフォルトは testnet です。DELPHI_NETWORK は省略できます。ユーザーが mainnet または competition を明示的に希望する場合にのみ設定してください。
DELPHI_NETWORK=testnet(デフォルト)の場合、SDK は次を自動的に使用します。
- RPC URL:
https://gensyn-testnet.g.alchemy.com/public - Chain ID:
685685 - Gateway:
0x22ea355D7218Dc86b4c83732cBbd01f7Ff2332b3(自動決済) - Factory:
0x97d2b3F0614C8189343A38094629FCE2910b727A - Legacy gateway:
0x7b8FDBD187B0Be5e30e48B1995df574A62667147(自動決済導入前の市場) - Token:
0x0724D6079b986F8e44bDafB8a09B60C0bd6A45a1 - API URL:
https://delphi-api.gensyn.ai/ - Subgraph URL:
https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-testnet-autoset/1.0.0/gn
DELPHI_NETWORK=mainnet の場合、SDK は次を自動的に使用します。
- RPC URL:
https://gensyn-mainnet.g.alchemy.com/public - Chain ID:
685689 - Gateway:
0x982a67aE92D8de361957249fB2BB4a62BCc6A8d5(自動決済) - Factory:
0x9C73417f79a1361c6aF9Bd828343badEE1b84936 - Legacy gateway:
0x4e4e85c52E0F414cc67eE88d0C649Ec81698d700(自動決済導入前の市場) - Token:
0x5b32c997211621d55a89Cc5abAF1cC21F3A6ddF5 - API URL:
https://api.delphi.fyi/ - Subgraph URL:
https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-mainnet-autoset/1.0.0/gn
DELPHI_NETWORK=competition-testnet(エージェント取引コンペティション)の場合、SDK は次を自動的に使用します。
- RPC URL:
https://gensyn-testnet.g.alchemy.com/public(testnet と同じチェーン) - Chain ID:
685685 - Gateway:
0x097599c9D966fF496284b892A8F13BF885b258ef(LmsrGateway — 単一のデプロイメントで、レガシー版はありません) - Factory:
0xEa9D0a78d0209916e88e363B8FDa3e23206Ff49b - Token:
0x8A2d75753362Eb5D5669a2c22cbf394b26a0571F(TST、小数点以下 6 桁 — USDC ではありません) - API URL:
https://delphi-api.gensyn.ai/(testnet と共有のデプロイメント。クライアントはX-Delphi-Mode: competitionを自動的に送信します) - Subgraph URL:
https://api.goldsky.com/api/public/project_cmnoqdag1obop01z3efnu8ssq/subgraphs/delphi-agent-competition/1.0.0/gn - リーダーボード:
https://agent-competition.gensyn.ai
コンペティションは単にアドレスが異なるだけではありません。 LMSR 価格設定を使用し(勝ちシェアは正確に 1 トークンを支払い、価格の合計は 1 になります)、testnet API キーが必要です。また、順位に掲載されるには、DoraHacks を通じてウォレットを登録する必要があります。 取引を始める前に reference/competition.md をお読みください。
Delphi は 2 つのデプロイメントを並行して稼働させています。新しい市場はすべて自動決済ゲートウェイ上に作成され、オラクルによって決済されます。古い市場はレガシーゲートウェイ上にあります。各ゲートウェイはもう一方の市場を拒否するため、SDK は市場ごとに適切なゲートウェイを解決します。任意の市場アドレスを渡せば機能します。ただし、デフォルトの subgraph が対象とするのは自動決済デプロイメントのみです。そのため、レガシー市場の subgraph クエリは空の結果を返します(reference/subgraph.md を参照)。
決済が自動化されたことで、市場が failed になる場合があります。オラクルは実行されたものの、質問を解決できなかった状態です。failed の市場には勝ちとなる結果がないため、redeemMarket() はリバートし、資金は expired の場合と同じく liquidate() で回収します。ステータス一覧:open、awaiting_settlement、settled、expired、failed。
上記のアドレスと subgraph エンドポイントに加え、
client.resolveGateway()、client.getMarketStatus()、subgraph.getMarketSettlement()を利用するには、@gensyn-ai/gensyn-delphi-sdk@^2.0.0(package.jsonに固定)が必要です。古い SDK ではデフォルトが引き続きレガシーゲートウェイを指し、これらのメソッドは存在しません。
オプションのオーバーライド
カスタムエンドポイントを指定する必要がある場合は、これらの設定でネットワークのデフォルト値を上書きできます。
| 変数 | 説明 |
|---|---|
GENSYN_RPC_URL | カスタム RPC エンドポイント |
GENSYN_CHAIN_ID | カスタムチェーン ID |
DELPHI_GATEWAY_CONTRACT | カスタムゲートウェイアドレス。すべての呼び出しをこのゲートウェイに固定し、市場ごとのルーティングを無効にします — このゲートウェイが所有していない市場への呼び出しはリバートします |
DELPHI_LEGACY_GATEWAY_CONTRACT | カスタムのレガシーゲートウェイアドレス |
DELPHI_FACTORY_CONTRACT | カスタムの自動決済ファクトリー(市場のルーティングに使用) |
DELPHI_LEGACY_FACTORY_CONTRACT | カスタムのレガシーファクトリー(市場のルーティングに使用) |
DELPHI_API_BASE_URL | カスタム API ベース URL |
DELPHI_SUBGRAPH_URL | カスタム Goldsky サブグラフエンドポイント |
DELPHI_TOKEN_ADDRESS | ERC-20 担保トークンアドレスをオーバーライドします |
DELPHI_SIGNER_TYPE | "private_key" または "cdp_server_wallet"(デフォルト) |
DELPHI_COMPETITION_ID | list-markets.ts、get-market.ts、Agent TUI で市場の読み取り対象を絞り込む競技会 UUID(競技会ネットワークのみ。その他では無視されます)。未設定の場合はアクティブな競技会が使われます |
クライアントのセットアップ
import {
DelphiClient,
SubgraphClient,
createPrivateKeySigner,
createCdpSigner,
} from "@gensyn-ai/gensyn-delphi-sdk";
// All config is read from environment variables automatically.
const client = new DelphiClient();
単位
| 種類 | 生の表現 | 人間向けの換算 |
|---|---|---|
| シェア | 18 桁の小数部を持つ bigint | 1n * 10n**18n = 1 シェア |
| USDC | 6 桁の小数部を持つ bigint | 1_000_000n = 1 USDC |
| 含意確率(オンチェーン bigint) | 18 桁の小数部(1e18 = 100%) | 5n * 10n**17n = 50% |
| スポット価格(オンチェーン bigint) | 6 桁の小数部(1e6 = 1.0 USDC/シェア) | 600_000n = 0.60 USDC/シェア |
market.spotPrices[i] | 通常の number 浮動小数点数 | 0.6 = 0.60 USDC/シェア — すでに人間向けの値です |
market.spotImpliedProbabilities[i] | 通常の number 浮動小数点数(0~1) | 0.6 = 60% — すでに人間向けの値です |
// Human → raw bigint (inputs to SDK)
const sharesToBigint = (n: number) => BigInt(Math.round(n * 1e18));
const usdcToBigint = (n: number) => BigInt(Math.round(n * 1e6));
// Raw bigint → display string
const toUsdc = (n: bigint) => `${(Number(n) / 1e6).toFixed(6)} USDC`;
const toShares = (n: bigint) => `${(Number(n) / 1e18).toFixed(4)} shares`;
const toProb = (n: bigint) => `${(Number(n) / 1e18 * 100).toFixed(2)}%`;
const toSpotPrice = (n: bigint) => `${(Number(n) / 1e6).toFixed(4)} USDC/share`;
基本パターン
ヒント:動作する完全な例については、
scripts/list-markets.tsを参照してください。
市場を一覧表示する
const { markets } = await client.listMarkets({
status: "open", // "open" | "awaiting_settlement" | "settled" | "expired"
category: "crypto", // crypto, culture, economics, miscellaneous, politics, sports
limit: 20,
skip: 0,
orderBy: "liquidity", // "liquidity" (default) | "created" | "settles_at" (soonest first)
verifiable: true, // optional: filter to markets with verifiable settlement
pricesAndImpliedProbabilities: true, // optional: fetch spot prices and implied probabilities
});
for (const market of markets ?? []) {
const meta = market.metadata; // typed as MarketMetadata | null — no cast needed
console.log(market.id, meta?.question);
// market.id = market address — use this as marketAddress in all SDK calls
// market.appMarketId = UUID identifying the market in the Delphi app
// market.marketUrl = direct link to the market on the Delphi app
// market.implementation = underlying logic contract (NOT used for SDK calls)
// market.category = market category string (e.g. "crypto")
// market.verifiable = true if market uses verifiable settlement
// market.tradingFee = 18-decimal bigint string (e.g. "20000000000000000" = 2%); null if no fee
// convert: Number(market.tradingFee) / 1e18 * 100 → fee percentage
// market.winningOutcomeIdx = set after settlement, otherwise null
// market.resolvesAt = ISO timestamp for when market resolves, or null
// market.settlesAt = ISO timestamp for scheduled settlement, or null
// market.proof = settlement proof string, or null
// market.error = resolution error message if settlement failed, or null
// market.fetchResponseStatus = metadata fetch status string (e.g. "success"), or null
// market.metadataUriContentHash = hex hash of the fetched metadata content (e.g. "0x9434...")
// market.dataSources = data source identifiers, or null
// market.spotPrices = spot price per outcome as human-readable float (only if pricesAndImpliedProbabilities: true)
// market.spotImpliedProbabilities = implied probability per outcome as 0–1 float (only if pricesAndImpliedProbabilities: true)
}
単一の市場を取得する
ヒント:動作する完全な例については、
scripts/get-market.tsを参照してください。
const market = await client.getMarket({ id: "<market-id>", pricesAndImpliedProbabilities: true });
const meta = market.metadata; // typed as MarketMetadata | null — no cast needed
// market.id = use as marketAddress for all SDK calls (quoteBuy, buyShares, etc.)
// market.appMarketId = UUID identifying the market in the Delphi app
// market.marketUrl = direct link to the market on the Delphi app
// market.implementation = the logic contract address — NOT the marketAddress for SDK calls
// market.spotPrices = spot price per outcome as human-readable float (e.g. [0.6, 0.4])
// market.spotImpliedProbabilities = implied probability per outcome as 0–1 float (e.g. [0.6, 0.4])
ライブ価格
ライブ価格を取得する最も簡単な方法は、listMarkets または getMarket で pricesAndImpliedProbabilities: true を指定することです。SDK は multicall で価格を取得し、市場オブジェクトに人間向けの浮動小数点数として返します。
// market.spotPrices[i] — spot price as float (e.g. 0.6 = 0.60 USDC/share)
// market.spotImpliedProbabilities[i] — implied probability as 0–1 float (e.g. 0.6 = 60%)
if (market.spotPrices && market.spotImpliedProbabilities) {
for (let i = 0; i < (meta?.outcomes?.length ?? 0); i++) {
console.log(`[${i}] price: ${market.spotPrices[i].toFixed(4)} USDC/share | prob: ${(market.spotImpliedProbabilities[i] * 100).toFixed(2)}%`);
}
}
カスタムのオンチェーン読み取り(上級者向け)には、viem 経由で Gateway ABI を直接使用してください。reference/onchain.md を参照してください。
購入見積もり(読み取り専用、ガス代不要)
ヒント:動作する完全な例については、
scripts/quote-buy.tsを参照してください。
const { tokensIn } = await client.quoteBuy({
marketAddress: "0x..." as `0x${string}`,
outcomeIdx: 0,
sharesOut: BigInt(Math.round(10 * 1e18)), // 10 shares
});
// tokensIn = USDC cost in 6-decimal bigint
const costUsdc = Number(tokensIn) / 1e6;
売却見積もり(読み取り専用、ガス代不要)
ヒント:動作する完全な例については、
scripts/quote-sell.tsを参照してください。
const { tokensOut } = await client.quoteSell({
marketAddress: "0x..." as `0x${string}`,
outcomeIdx: 0,
sharesIn: BigInt(Math.round(5 * 1e18)), // 5 shares
});
const payoutUsdc = Number(tokensOut) / 1e6;
償還/清算見積もり(読み取り専用、ガス代不要)
終了済み市場では、スポット価格はポジションの価値を反映しなくなります。実現可能な価値は、決済済み市場では償還払い戻し額、期限切れ市場では清算収益です。これらの見積もりは eth_call を使ってオンチェーンの redeem/liquidate をシミュレートします(ガス代不要、状態変更なし)。ポジションが償還または清算できない場合(例:決済済み市場で負けた結果、またはまだ終了していない市場)は例外をスローするため、try/catch で囲んでください。
ヒント:動作する完全な例については、
scripts/quote-redeem.tsとscripts/quote-liquidate.tsを参照してください。
// Settled market: payout for the caller's winning shares. account defaults to
// the configured signer; pass it to quote for any wallet.
const { sharesIn, tokensOut } = await client.quoteRedeem({
marketAddress: "0x..." as `0x${string}`,
account: "0x..." as `0x${string}`, // optional
});
const payoutUsdc = Number(tokensOut) / 1e6; // 0 / throws for a losing outcome
// Expired market: proceeds from liquidating the given outcomes.
const { sharesIn: burned, totalTokensOut } = await client.quoteLiquidate({
marketAddress: "0x..." as `0x${string}`,
outcomeIndices: [0, 1],
account: "0x..." as `0x${string}`, // optional
});
const proceedsUsdc = Number(totalTokensOut) / 1e6;
ステータスをまたいでポートフォリオを評価する場合:スポット価格(
シェア × スポット価格)を使うのはオープン市場のみです。決済済み市場ではquoteRedeemで勝ちの結果を評価し(負けの結果は 0 の価値です)、期限切れ市場ではquoteLiquidateを使います。Agent TUI の Portfolio タブはこの方法で評価し、ポジションごとにステータスバッジを表示します。
シェアを購入する(オンチェーン、自動承認あり)
ヒント:動作する完全な例については、
scripts/buy-shares.tsを参照してください。
const marketAddress = "0x..." as `0x${string}`;
const outcomeIdx = 0;
const sharesOut = BigInt(Math.round(10 * 1e18)); // 10 shares
// 1. Quote, and cap the spend with 2% slippage
const { tokensIn } = await client.quoteBuy({ marketAddress, outcomeIdx, sharesOut });
const maxTokensIn = tokensIn * 102n / 100n;
// 2. Ensure USDC approval (idempotent — only sends tx if needed).
// Approve maxTokensIn, not tokensIn: the buy can spend up to the cap, so an
// allowance sized to the quote reverts if the price moves within slippage.
await client.ensureTokenApproval({ marketAddress, minimumAmount: maxTokensIn });
// 3. Buy
const { transactionHash } = await client.buyShares({
marketAddress,
outcomeIdx,
sharesOut,
maxTokensIn,
});
シェアを売却する(オンチェーン)
ヒント:動作する完全な例については、
scripts/sell-shares.tsを参照してください。
const sharesIn = BigInt(Math.round(5 * 1e18));
// 1. Quote
const { tokensOut } = await client.quoteSell({ marketAddress, outcomeIdx, sharesIn });
// 2. Sell with 2% slippage
const minTokensOut = tokensOut * 98n / 100n;
const { transactionHash } = await client.sellShares({
marketAddress,
outcomeIdx,
sharesIn,
minTokensOut,
});
ポジションの一覧表示
Tip:完全に動作する例については、
scripts/list-positions.tsを参照してください。
Important:
sharesが0のポジション(つまり、BigInt(p.shares) === 0n)は、完全に解消済みのステークを表します。ウォレットがシェアを保有していないため、これらは償還も清算もできません。償還または清算を行う前に、必ずシェアが0のポジションを除外してください。
const { positions } = await client.listPositions({
wallet: "0x...",
redeemedOrLiquidated: false, // only active positions
limit: 50,
});
for (const p of positions ?? []) {
const shares = Number(BigInt(p.shares)) / 1e18;
if (shares === 0) continue; // no stake — skip
console.log(`Market ${p.marketProxy} | Outcome ${p.outcomeIdx} | ${shares} shares`);
}
決済済みポジションの償還
Tip:完全に動作する例については、
scripts/redeem.tsを参照してください。
Important:償還できるのは、シェアが0以外のポジションのみです。
listPositionsがshares === "0"のポジションを返した場合、そのウォレットはその市場にステークを保有しておらず、redeemMarketを呼び出すと失敗するか、何も返されません。償還する前に、必ずシェアが0より大きいことを確認してください。
// Single market
const { transactionHash, sharesIn, tokensOut } = await client.redeemMarket({
marketAddress: "0x..." as `0x${string}`,
});
// Batch
const { results, totalTokensOut } = await client.redeemPositions({
marketAddresses: ["0x...", "0x..."],
});
for (const r of results) {
if (r.success) console.log(`Redeemed ${Number(r.tokensOut!) / 1e6} USDC from ${r.marketAddress}`);
else console.error(`Failed ${r.marketAddress}: ${r.error}`);
}
期限切れポジションの清算
Tip:完全に動作する例については、
scripts/liquidate.tsを参照してください。
清算は、決済されないまま期限切れになった市場のポジションを対象とします。勝者が決まった決済済み市場を対象とする償還とは異なり、清算では解決されずに期限切れとなった市場からトークンを回収します。
// Liquidate a single market — pass all outcome indices you hold
const { transactionHash, sharesIn, totalTokensOut } = await client.liquidate({
marketAddress: "0x..." as `0x${string}`,
outcomeIndices: [0, 1], // all outcome indices with positions
});
// sharesIn: bigint[] — shares burned per outcome index
// totalTokensOut: bigint — total USDC recovered across all outcomes
// Derive outcome indices from listPositions:
const { positions } = await client.listPositions({ wallet, redeemedOrLiquidated: false });
const outcomeIndices = positions!
.filter(p => p.marketProxy === marketAddress && BigInt(p.shares) > 0n)
.map(p => Number(p.outcomeIdx));
トークンの承認
Tip:完全に動作する例については、
scripts/token-approval.tsを参照してください。
// Check current allowance
const { ownerAddress, allowance } = await client.getTokenAllowance({ marketAddress });
// Approve unlimited
await client.approveToken({ marketAddress });
// Approve specific amount (50 USDC)
await client.approveToken({ marketAddress, amount: 50_000_000n });
// Idempotent: only approves if current allowance is below minimum
// Response always includes current allowance, plus transactionHash if a tx was sent
const { approvalNeeded, allowance, transactionHash } = await client.ensureTokenApproval({
marketAddress,
minimumAmount: requiredTokens,
approveAmount: 100_000_000n, // optional: amount to approve if needed (defaults to max uint256)
});
ウォレット残高の確認
Tip:完全に動作する例については、
scripts/get-wallet-balances.tsを参照してください。
// ETH (native gas token)
const ethBalance = await client.getEthBalance();
console.log(`ETH: ${(Number(ethBalance) / 1e18).toFixed(6)}`);
// ERC-20 collateral token (defaults to SDK-configured token address)
const tokenAddress = client.getTokenAddress(); // inspect the configured token address
const { balance, decimals } = await client.getErc20BalanceWithDecimals();
const formatted = (Number(balance) / 10 ** decimals).toFixed(decimals > 6 ? 6 : decimals);
console.log(`Token (${tokenAddress}): ${formatted}`);
// Or fetch raw balance only (6-decimal for USDC)
const raw = await client.getErc20Balance(); // uses default token; pass address to override
サブグラフ経由で最近の取引を照会
Tip:完全に動作する例については、
scripts/list-recent-trades.tsを参照してください。
SDK のSubgraphClientは、Goldsky サブグラフによってインデックス化されたオンチェーンイベントデータを照会します。client.getSubgraph()からアクセスできます。
const subgraph = client.getSubgraph();
// Convenience method: get buys and sells for a market
const { buys, sells } = await subgraph.getMarketTrades(
"0x..." as string, // market proxy address
{ first: 20 }
);
for (const buy of buys) {
const cost = Number(BigInt(buy.tokensIn ?? "0")) / 1e6;
const shares = Number(BigInt(buy.sharesOut ?? "0")) / 1e18;
const time = new Date(Number(buy.timestamp_) * 1000).toLocaleString();
console.log(`BUY ${time} | ${cost.toFixed(4)} USDC → ${shares.toFixed(4)} shares`);
}
// Arbitrary GraphQL: recent buys across all markets
// SubgraphBuy, SubgraphSell, SubgraphMeta are all exported from the SDK for typing:
// import type { SubgraphBuy, SubgraphSell, SubgraphMeta } from "@gensyn-ai/gensyn-delphi-sdk";
const data = await subgraph.query<{ gatewayBuys: SubgraphBuy[] }>(`{
gatewayBuys(first: 5, orderBy: timestamp_, orderDirection: desc) {
id buyer marketProxy tokensIn sharesOut timestamp_
}
}`);
// Check subgraph indexing status (block number, deployment, error flag)
const meta = await subgraph.getMeta();
console.log(`Block: ${meta.block.number}, indexing errors: ${meta.hasIndexingErrors}`);
利用可能なエンティティ:gatewayBuys、gatewaySells、gatewayRedemptions、gatewayLiquidations、gatewayMarketSettleds、gatewayMarketFaileds、marketResolutionRequesteds。すべて、フィルタリング(where)、並べ替え(orderBy + orderDirection)、ページネーション(first + skip)に対応しています。自動決済サブグラフにはgatewayWinnerSubmittedsが存在しない点に注意してください。これを照会すると GraphQL エラーが発生します。同じペイロードを持つgatewayMarketSettledsを使用してください。
TUI
ユーザーは読み取り専用の Agent TUI ダッシュボードを使って、エージェントの動作をリアルタイムで可視化できます。ダッシュボードには、ポートフォリオ、ポジション、アクティビティ、市場、Edge View、推論ストリームを表示する Agent Logs が含まれます。起動するには、npx tsx scripts/agent-tui/index.tsx <wallet-address> <testnet|mainnet|competition-testnet>(またはnpm run agent-tui -- <wallet-address> <testnet|mainnet|competition-testnet>)を実行します。以下の2つのヘルパーが、Agent Logs パネルと Edge View パネルにデータを提供します。
推論の記録(Agent Logs)
log-event は、Agent TUI の Agent Logs パネルに情報を記録します。実際に判断を下したタイミングで使用してください。行動する理由(THINK)を記録してから、取った行動を記録します。イベントの種類は次のとおりです。
| 種類 | 用途 |
|---|---|
THINK | 推論 — 観察した内容、市場が割安に見える理由、どのような優位性を見いだしたか、なぜその方向と取引サイズなのか。最も重要な項目です。 |
BUY | 実行した買い。 |
SELL | 実行した売り。 |
LIQUIDATE | 期限切れの市場のポジションを清算すること。 |
REDEEM | 決済済みの市場から賞金を受け取ること。 |
SKIP | 検討したうえで、意図的に見送った市場(およびその理由)。 |
npx tsx scripts/log-event.ts THINK "<the reasoning — why this trade>"
npx tsx scripts/log-event.ts BUY "<the action you took>"
THINKが最も重要です。推論を記録してください。Agent Logs パネルは、その内容を表示するためのものです。- アクションの種類(
BUY/SELL/LIQUIDATE/REDEEM)には、その推論に続いて行ったことを簡潔に記録します。短くまとめてください。My Activity タブには取引の詳細(金額、価格、tx ハッシュ)がすでに表示されるため、同じ内容を繰り返す必要はありません。 SKIPを使って、評価したものの見送った市場を記録してください。これにより、取引したものだけでなく、検討したものもログに表示されます。
注文の内容だけを記述するのは避けてください。"Buy 10 YES on Wild Pandas, 2% slippage" は Activity にすでに表示されています。代わりに、その理由を記録してください。
良い例:
npx tsx scripts/log-event.ts THINK "BTC $99,999 by Jun 31: ~12 days left and price is still ~\$25k away — that move is unlikely, yet the market prices NO at only 71%. Taking NO; small testnet size to validate."
npx tsx scripts/log-event.ts BUY "10 NO on BTC $99,999"
日常的な読み取りのたびではなく、実際に判断を下したタイミングで THINK→アクションのペアを記録してください。<type> では大文字・小文字が区別されず、大文字に正規化されます。イベントは $DELPHI_AGENT_LOG(デフォルトは ~/.delphi/agent-events.jsonl)に追加されます。ファイルは自動的に作成されます。
取引前のエッジ計算(Edge View)
エッジは取引判断の中心となるシグナルです。市場を自律的に買うか売るか決める前に、必ず計算してください。 エッジとは、ある結果に対する独自の確率推定と、市場のリアルタイムのインプライド確率との差です。
edge = your probability − market's implied probability
エッジが正の場合、その結果は自身の見立てに対して割安であり、買いの候補になります。エッジが負の場合は割高であり、売りまたは回避の対象になります。差の絶対値が大きいほど、シグナルは強くなります。
scripts/compute-edge.ts は市場のリアルタイムのインプライド確率を取得し、自身の推定値との差であるエッジを計算してシグナルを出力し、結果を保存します。保存された結果は、エッジの大きさ順に Agent TUI の Edge View(Overview 画面)に表示されます。
# Single market outcome: your probability is 0.30 (or pass 30 for percent)
npx tsx scripts/compute-edge.ts 0x1234…abcd 1 0.30
# Several at once — repeat the (market, outcome, prob) triple
npx tsx scripts/compute-edge.ts 0x1234…abcd 1 0.30 0x5678…ef01 0 0.62
<your-prob> はその結果に対する推定値です(0.30 のような 0~1 の値、または 30 のようなパーセント値)。<market-address> は listMarkets/getMarket で取得できる市場 ID、<outcome-idx> は結果のインデックスです。同じ(市場、結果)の組み合わせで再実行すると、以前の値は新しい値で置き換えられます(最新の値が有効になります)。
市場を自律的に買うか売るか判断する際の必須フロー:
- その結果に対する独自の確率推定を行います。
compute-edge.tsを実行し、市場のリアルタイムのインプライド確率と比較します。- 算出されたエッジを判断に活用します。エッジが十分に正の場合は買い、十分に負の場合は売り、差が大きいものを優先して取引します。エッジが小さい場合、または符号が逆の場合は
SKIPにします。 - その後、エッジに触れながら推論を
log-event THINKで記録し、実行したアクションをlog-event BUY/SELLで記録します。
エッジは $DELPHI_AGENT_EDGES(デフォルトは ~/.delphi/agent-edges.jsonl)に保存されます。ファイルは自動的に作成されます。Edge View は更新のたびに、保存された確率を現在の市場価格と再度照合します。そのため、市場が変動しても表示されるエッジは最新の状態に保たれます。
エラー処理
| エラー | 原因 | 修正方法 |
|---|---|---|
TokensInExceedsMax | 価格が maxTokensIn を上回りました | 再見積もりし、スリッページを大きくします |
TokensOutBelowMin | 価格が minTokensOut を下回りました | 再見積もりし、スリッページを大きくします |
MarketNotOpen | 市場が終了しているか、決済済みです | まず market.status を確認します |
SharesInExceedSupply | 保有数を超えるシェアを売却しようとしています | 売却前にポジションを確認します |
Requires apiKey | DELPHI_API_ACCESS_KEY がありません | 環境変数を設定します |
Requires rpcUrl | GENSYN_RPC_URL がありません | 環境変数を設定するか、ネットワークのデフォルト値を適用します |
Requires privateKey | WALLET_PRIVATE_KEY がありません | 環境変数を設定するか、CDP 署名者に切り替えます |
CDP signing requires ... | CDP 環境変数がありません | すべての CDP_ 変数を設定します |
リファレンスファイル(必要に応じて読み込み)
| ファイル | 読み込むタイミング |
|---|---|
| reference/markets.md | listMarkets/getMarket の全パラメーター、Market 型のスキーマ、メタデータの構造 |
| reference/trading.md | 取引の仕組み、スリッページの計算式、パリミュチュエル価格の解説 |
| reference/positions.md | Position/Trade 型のスキーマ、一括償還のパターン、ポートフォリオの推定 |
| reference/onchain.md | Gateway ABI 関数の全一覧、viem による直接読み取りのパターン、署名設定 |
| reference/subgraph.md | Goldsky subgraph の GraphQL スキーマ、SubgraphClient API、エンティティ型、フィルタリング、生クエリの例 |
| reference/funding.md | Gensyn への ETH と USDC の入金方法(テストネットのフォーセット、OP Stack ブリッジ、LayerZero USDC ブリッジ) |
| reference/competition.md | エージェント取引コンペティション:LMSR とパリミュチュエル価格の比較、登録、取引上の違い、リーダーボード、subgraph の違い、障害モード |