用途
basket-settle 用于为 PolyBaskets 篮子发起并完成结算。它适用于智能体已具备 settler 角色、需要通过 vara-wallet 提交结算提案,或在提案后挑战窗口已过、需要最终确认结算的场景。
主要能力
- 发起结算提案(ProposeSettlement):需要 settler 角色。
- 最终结算(FinalizeSettlement):不需要 settler 角色,但仅在挑战截止时间(challenge_deadline)之后可用。
- 检查篮子状态、结算状态、挑战截止时间与最终结果。
- 核对 Polymarket 上各条目是否已结算。
使用方式
环境准备
仅限主网(MAINNET ONLY)。执行任何操作前先运行:
vara-wallet config set network mainnet
资料明确提示:绝不要切换到测试网,因为那里没有合约。
相关变量:
BASKET_MARKET="0xea8373e8b4441ef6e95325c1044d23ebf615b43fdef60a48623836a15ca7a25a"
_PB="${POLYBASKETS_SKILLS_DIR:-skills}"
IDL="$_PB/idl/polymarket-mirror.idl"
验证 settler 角色
只有合约配置中 settler_role 指定的地址才能调用 ProposeSettlement。
# 查看谁拥有 settler 角色
vara-wallet call $BASKET_MARKET BasketMarket/GetConfig --args '[]' --idl $IDL | jq -r '.result.settler_role'
# 查看智能体的十六进制 actor id
MY_ADDR=$(vara-wallet balance --account agent | jq -r .address)
echo "$MY_ADDR"
如果地址与 settler_role 不匹配,则不能发起新结算;但仍可在 challenge_deadline 之后对已提案的结算执行最终结算。
结算流程
- 检查篮子处于 Active 状态。
- 确认所有条目已在 Polymarket 上结算。
- 调用 ProposeSettlement,启动配置的挑战窗口。
- 等待 challenge_deadline 过去。
- 调用 FinalizeSettlement,篮子变为 Settled,用户可领取。
步骤 1:检查篮子状态
vara-wallet call $BASKET_MARKET BasketMarket/GetBasket \
--args '[<basket_id>]' --idl $IDL | jq '.result.ok.status'
状态必须为 "Active"。
步骤 2:检查 Polymarket 结算情况
对篮子中的每个条目,检查对应市场是否已在 Polymarket 上结算:
curl -s "https://gamma-api.polymarket.com/markets?slug=<poly_slug>" | jq '.[0] | {closed, outcomePrices}'
所有条目必须已结算(closed: true),且最终价格接近 0 或 1。
步骤 3:发起结算提案
构建 item_resolutions 数组,每个篮子条目对应一个 ItemResolution:
{
"item_index": 0,
"resolved": "YES",
"poly_slug": "will-btc-hit-100k",
"poly_condition_id": "0xabc123...",
"poly_price_yes": 9900,
"poly_price_no": 100
}
规则:
- 每个篮子条目恰好提供一个 resolution。
- item_index 从 0 开始,必须唯一,且在篮子条目范围内。
- poly_slug 必须与篮子条目的 slug 完全一致。
- poly_price_yes + poly_price_no 应以 bps 反映 Polymarket 最终价格。
- resolved 为最终结果:"YES" 或 "NO"。
- poly_condition_id 可选。
示例:为一个包含 2 个条目的篮子发起结算提案:
vara-wallet --account agent call $BASKET_MARKET BasketMarket/ProposeSettlement --voucher $VOUCHER_ID \
--args '[
0,
[
{
"item_index": 0,
"resolved": "YES",
"poly_slug": "will-btc-hit-100k",
"poly_condition_id": null,
"poly_price_yes": 9900,
"poly_price_no": 100
},
{
"item_index": 1,
"resolved": "NO",
"poly_slug": "will-eth-hit-5k",
"poly_condition_id": null,
"poly_price_yes": 200,
"poly_price_no": 9800
}
],
"Resolved via Polymarket API"
]' \
--idl $IDL
提案后,篮子进入 SettlementPending 状态,配置的挑战窗口开始计时。
步骤 4:等待挑战窗口
# 查看挑战截止时间
vara-wallet call $BASKET_MARKET BasketMarket/GetSettlement \
--args '[<basket_id>]' --idl $IDL | jq '.result.ok | {status, challenge_deadline, proposed_at}'
challenge_deadline 是区块时间戳。存活窗口在 BasketMarket/GetConfig.liveness_ms 中配置;不要硬编码时长。等待当前区块时间戳超过 challenge_deadline。
步骤 5:最终结算
vara-wallet --account agent call $BASKET_MARKET BasketMarket/FinalizeSettlement --voucher $VOUCHER_ID \
--args '[<basket_id>]' --idl $IDL
最终结算后:
- 篮子状态变为 Settled。
- 设置 finalized_at。
- 用户可通过 ../basket-claim/SKILL.md 领取收益。
验证
vara-wallet call $BASKET_MARKET BasketMarket/GetSettlement \
--args '[<basket_id>]' --idl $IDL | jq '.result.ok | {status, payout_per_share, finalized_at}'
常见错误
| 错误 | 原因 | 修复 |
|---|---|---|
| Unauthorized | 发起 ProposeSettlement 时不是 settler 角色 | 检查配置中的 settler_role 地址 |
| BasketNotActive | 篮子已处于结算中 | 检查状态 |
| SettlementAlreadyExists | 已提案过 | 等待并最终结算 |
| InvalidResolutionCount | resolution 数量错误 | 每个条目提供一个 |
| ResolutionSlugMismatch | slug 与篮子条目不匹配 | 使用篮子中的精确 slug |
| DuplicateResolutionIndex | 同一 item_index 出现两次 | 使索引唯一 |
| ResolutionIndexOutOfBounds | 索引 >= 条目数量 | 使用 0 到 items.length-1 |
| ChallengeDeadlineNotPassed | 过早最终结算 | 等待挑战窗口 |
| SettlementNotProposed | 不存在提案 | 先发起提案 |
适用场景
- 智能体拥有 settler 角色,需要为 PolyBaskets 篮子提交结算提案。
- 结算提案已提交且挑战窗口已过,需要完成最终结算。
- 需要核对篮子状态、Polymarket 结算情况或结算结果。
限制
- 仅限主网,资料明确禁止切换到测试网。
- ProposeSettlement 需要 settler 角色。
- FinalizeSettlement 必须在 challenge_deadline 之后执行。
- 挑战窗口时长由 BasketMarket/GetConfig.liveness_ms 配置,不应硬编码。
- 资料未提供收费、价格、平台支持范围等信息。