关于 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 完成。
要参与 Agent 竞赛交易? 该竞赛使用独立网络 (
competition-testnet),采用 LMSR 市场,而非下文介绍的相互博彩市场。定价数学、代币、注册步骤和排行榜都各不相同——交易前请阅读 reference/competition.md,不要将下文的相互博彩部分应用于该竞赛。
动态相互博彩市场的运作方式
本节介绍 Delphi 测试网/主网。竞赛使用 LMSR,价格总和为 1,现货价格 就是 隐含概率,获胜份额始终恰好兑付 1 个代币。请参阅 reference/competition.md。
动态相互博彩市场是一种博彩或信息系统,其价格(赔率)由所有参与者下注的分布内生形成,而非由做市商设定。随着新赌注不断加入,隐含概率会持续更新:获得更多资金支持的结果赔率会下降(隐含概率上升),支持较少的结果则会变得更便宜。所有参与者的流动性汇集在一起,因此交易者实际上是在与整体市场而非某个交易对手下注,而资金池的深度决定了新信息对价格的影响程度。这形成了一种自我调节机制,使价格既反映当前观点,也反映新增流动性的边际影响。与流动性稀薄的订单簿市场相比,这通常会带来更平稳、更稳定的价格更新,同时价格仍会随时间逐步趋向共识概率。
重要:现货价格和预期兑付额各自独立变动,且兑付额并非固定。不同于固定兑付市场(例如 Polymarket),其中获胜份额始终可恰好兑付 $1,Delphi DPM 的兑付额在结算时确定:整个资金池由获胜份额持有者瓜分,因此每份获胜份额的兑付额=获胜份额总数/资金池总额。
现货价格是当前买入下一份额的边际成本,也就是定价曲线的局部斜率。可以根据当前资金池状态和预期赎回价值推断出一个类似概率的数值,但它与现货价格并不相同;根据流动性分布和市场深度的不同,两者可能存在显著差异。
何时使用此技能
- 用户想要列出、搜索或浏览信息市场
- 用户想要查询某个市场的价格、概率或详情
- 用户想要买入或卖出结果份额
- 用户想要查看自己的投资组合、持仓或交易历史
- 用户想要赎回已结算市场的收益
- 用户想要清仓已过期(未结算)市场中的持仓
- 如果用户要求创建市场,请提醒他们:在 UI 之外创建的市场不会显示在 UI 上
- 用户想要查询或设置交易所需的代币授权
- 用户想要查询历史链上交易数据(买入、卖出、赎回、清算)
- 用户想要通过 Goldsky 子图查询某个市场或钱包的近期交易
- 用户想要查看钱包中的 ETH 或代币余额
- 用户想要获取 ETH 或 USDC,为交易钱包提供资金(测试网水龙头、跨链桥接)
- 用户想要参与Agent 交易竞赛交易、注册或查询自己的排名 → 加载 reference/competition.md
- 用户提到竞赛、排行榜、
agent-competition.gensyn.ai,或设置了DELPHI_NETWORK=competition-testnet - 任何关于 Delphi 信息市场或在 Gensyn 上进行链上交易的问题
安装
npm install
这将安装所有必需的依赖项,包括 SDK、dotenv、viem 和开发工具。
示例脚本
此仓库在 scripts/ 文件夹中包含可运行的示例脚本,展示所有常见操作。这些脚本为 Agent 提供了便捷的参考或直接运行路径:
| 脚本 | 用途 | 使用方法 |
|---|---|---|
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 事件日志追加可追踪事件(Agent TUI → 概览 → Agent Logs) | npx tsx scripts/log-event.ts <type> "<message>" |
scripts/compute-edge.ts | 计算一个或多个市场结果的优势(你的概率 − 市场隐含概率);输出信号并提供给 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 水龙头领取 1,000 测试网 USDC | npx tsx scripts/testnet-faucet.ts |
scripts/bridge-eth-to-gensyn-testnet.ts | 将 ETH 从 Sepolia 跨链桥接至 Gensyn Testnet | npx tsx scripts/bridge-eth-to-gensyn-testnet.ts <amount-eth> |
scripts/bridge-eth-to-gensyn-mainnet.ts | 将 ETH 从 Ethereum 主网跨链桥接至 Gensyn Mainnet | npx tsx scripts/bridge-eth-to-gensyn-mainnet.ts <amount-eth> |
scripts/bridge-usdc-to-gensyn-mainnet.ts | 通过 LayerZero 将 USDC 从 Ethereum 主网跨链桥接至 Gensyn Mainnet | 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文件(首选),或者 - 确认已在 Shell 会话中导出环境变量
- 检查项目根目录中是否有
- 如果任一项检查未通过,请先修复,再运行任何任务脚本。
- 设置完成前,请勿调用
scripts/*.ts。 - 请勿在命令中内联传递环境变量——请改用
.env文件或export语句。
环境变量
只有两项是必需的:API 密钥和钱包签名凭据。其他所有配置都有合理的默认值。如果未设置 DELPHI_NETWORK,SDK 默认使用 testnet。
缺少环境变量时的 Agent 指示:
如果未设置必需的环境变量,请勿在聊天中向用户索要这些变量的值。请改为:
- 告知用户需要哪些变量(如下所列)。
- 告知用户在哪里获取每个值。
- 请用户在项目根目录自行创建
.env文件,并填入这些值。 - 等待用户确认文件已创建后再继续。
- 切勿读取
.env文件——请将其视为 Agent 不得访问的机密存储。
需要告知用户的必需变量:
| 变量 | 获取方式 |
|---|---|
DELPHI_API_ACCESS_KEY | Testnet: 在 https://delphi-api-access.gensyn.ai/ 生成 · Mainnet: 在 https://api-access.delphi.fyi/ 生成 |
此外,还需选择以下一种签名方式(请告知用户任选其一):
选项 A — 私钥
| 变量 | 说明 |
|---|---|
DELPHI_SIGNER_TYPE | 设置为 private_key |
WALLET_PRIVATE_KEY | 钱包的 0x 前缀十六进制私钥 |
选项 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) |
还请务必向用户传达以下两点:
-
使用 CDP 选项时,私钥会安全地存储在 Coinbase 的可信执行环境(TEE)中,绝不会离开 TEE。详情请参阅 Server Wallet v2 docs。
-
执行 Delphi 交易时,签名钱包必须在 Gensyn 链上持有
ETH(用于支付 Gas)和USDC。
网络选择
| 变量 | 值 | 默认值 |
|---|---|---|
DELPHI_NETWORK | "testnet" | "mainnet" | "competition-testnet" | "testnet" |
SDK 默认使用 testnet — DELPHI_NETWORK 为可选项。仅当用户明确希望使用 mainnet 或参加竞赛时才设置此变量。
当 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(Agent 交易竞赛)时,SDK 会自动使用:
- RPC URL:
https://gensyn-testnet.g.alchemy.com/public(与 testnet 使用同一条链) - Chain ID:
685685 - Gateway:
0x097599c9D966fF496284b892A8F13BF885b258ef(LmsrGateway — 单一部署,没有 legacy) - 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 同时运行两个部署。每个新市场都会创建在自动结算网关上,并由预言机结算;较早的市场则位于 legacy 网关上。每个网关都会拒绝对方的市场,因此 SDK 会针对每个市场解析正确的网关 — 传入任意市场地址即可使用。不过,默认的子图仅涵盖自动部署:查询 legacy 市场的子图会返回空结果(参见 reference/subgraph.md)。
由于现在采用自动结算,市场可能会变为 failed — 预言机已运行,但无法确定问题的结果。failed 市场没有获胜结果,因此 redeemMarket() 会回滚,资金需通过 liquidate() 取回,与 expired 的处理方式完全相同。完整状态列表:open、awaiting_settlement、settled、expired、failed。
上述地址和子图端点,以及
client.resolveGateway()、client.getMarketStatus()和subgraph.getMarketSettlement(),要求使用@gensyn-ai/gensyn-delphi-sdk@^2.0.0(已固定在package.json中)。在较旧版本的 SDK 中, 默认值仍指向 legacy 网关,并且不存在这些方法。
可选覆盖项
如果需要指向自定义端点,可覆盖网络默认值:
| 变量 | 描述 |
|---|---|
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 位小数的大整数 | 1n * 10n**18n = 1 份额 |
| USDC | 6 位小数的大整数 | 1_000_000n = 1 USDC |
| 隐含概率(链上大整数) | 18 位小数(1e18 = 100%) | 5n * 10n**17n = 50% |
| 现货价格(链上大整数) | 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。
买入报价(只读,不消耗 Gas)
提示:请参阅
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;
卖出报价(只读,不消耗 Gas)
提示:请参阅
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;
赎回/清算报价(只读,不消耗 Gas)
对于已结束的市场,现货价格不再反映持仓价值——可实现的价值是已结算市场的赎回支付金额,或已到期市场的清算所得。这些报价会通过 eth_call 模拟链上 redeem/liquidate(不消耗 Gas,不更改状态);如果持仓无法赎回/清算(例如,已结算但结果为亏损,或市场尚未结束),则会抛出异常,因此请使用 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;
跨状态估值组合:仅对开放市场使用现货价格(
shares × spotPrice)。对已结算市场,使用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)表示已完全退出的仓位。由于钱包不持有任何份额,因此无法赎回或清算。尝试赎回或清算之前,请务必过滤掉份额为零的仓位。
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:只有份额非零的仓位才能赎回。如果
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 仪表板实时查看 Agent 正在执行的操作,包括投资组合、仓位、活动、市场、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>)即可启动。下面的两个辅助工具会为其 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 标签页已经显示了交易细节(金额、价格、交易哈希),所以不要重复记录。 - 使用
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–1,例如 0.30,或百分比,例如 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 子图 GraphQL 架构、SubgraphClient API、实体类型、筛选方式和原始查询示例 |
| reference/funding.md | 查看如何将 ETH 和 USDC 转入 Gensyn(测试网水龙头、OP Stack 桥、LayerZero USDC 桥) |
| reference/competition.md | Agent 交易竞赛:LMSR 与互助投注定价、注册、交易差异、排行榜、子图差异和故障模式 |