---
name: blockking-agent
description: Use this skill when a user asks an AI agent to participate in BLOCKKING, run BLOCKKING Agent wallet mining, compete for Seats, pay mint fee only after winning, or monitor BLOCKKING Agent progress.
---

# BLOCKKING Agent Skill

你是用户自己的 BLOCKKING 参与智能体。用户会给你一个小额 EVM 钱包和 BLOCKKING 链接。你的任务是独立完成链上流程，不要等待用户在网页点启动按钮。

## 核心规则

- 默认读取 `https://blockking.co/agent.json` 和 `https://blockking.co/api/agent-config`。
- 只使用用户提供的小额 Agent 钱包。
- 这个钱包同时负责激活、创建 Agent、请求 Ticket、提交竞争、赢后 mint、收取 KING。
- 网页 `https://blockking.co/` 只是人类进度查看器，不是执行入口。
- 默认复用这个钱包最近的 Agent；只有用户明确要求新 Agent 才新建。
- 没赢 Seat 时绝不支付 mint fee。
- 赢 Seat 后，mint fee 必须从 `MintController.primarySeatMintFee(seatId)` 读取，金额必须完全一致。
- 不要索要用户主钱包助记词，不要要求用户把资金托管给项目方。
- 合约里的 `AgentRunnerRegistry` / `registerRunner` 是旧命名，实际含义是激活这个小额 Agent 钱包，不代表还有第二个执行者角色。

## 快速路径

如果你能运行 Node.js，优先使用公开 CLI：

```bash
mkdir -p blockking-agent/abi
cd blockking-agent
npm init -y
npm install ethers
curl -fsSLO https://blockking.co/cli/blockking-agent-cli.cjs
for name in AgentRunnerRegistry AgentRegistry AgentGateway QuestTicket QuestVerifier SeatRace MintController CrownRoll KING; do
  curl -fsSLo abi/$name.json https://blockking.co/abi/$name.json
done
BLOCKKING_AGENT_PRIVATE_KEY=<agent_wallet_private_key> node blockking-agent-cli.cjs run-once
```

持续参与：

```bash
BLOCKKING_AGENT_PRIVATE_KEY=<agent_wallet_private_key> node blockking-agent-cli.cjs loop
```

发现已有 Agent：

```bash
BLOCKKING_AGENT_PRIVATE_KEY=<agent_wallet_private_key> node blockking-agent-cli.cjs discover
```

## 手动实现路径

如果不能运行 CLI，就按下面的合约流程实现。

1. GET `https://blockking.co/api/agent-config`。
2. 使用返回的 `rpcUrl`、`chainId`、`contracts`。
3. 用用户给的小额 Agent 钱包作为 signer。
4. 调用 `AgentRunnerRegistry.isActiveRunner(agentWallet)`；如果为 false，调用 `registerRunner("Player Agent Wallet", "agent://<agentWallet>")`。
5. 查询 `AgentRegistry.AgentRegistered(owner=agentWallet)`，按 block/log index 找最新 `agentId`。
6. 如果没有 `agentId`，生成 `memoryHash`，调用 `AgentGateway.createAgent(agentWallet, memoryHash)`。
7. 调用 `QuestTicket.activeTicketOf(agentId)`；如果没有有效 Ticket 或已过期，调用 `requestTicket(agentId)`。
8. 调用 `QuestTicket.getTicket(ticketId)`。
9. 构造 proof：

```text
memoryHash = AgentRegistry.getAgent(agentId).memoryHash
targetWindowStart = ticket.validFrom
targetWindowEnd = ticket.validFrom + 5
salt = keccak256(agentWallet + ":" + ticketId + ":blockking-agent-wallet")
strategyHash = 0x0000000000000000000000000000000000000000000000000000000000000000
useSwapTouch = false
useLPTouch = false
```

10. 如果 `ticket.questType == 2`，在 `validFrom` 前调用 `QuestVerifier.predictionSaltHash(...)`，再调用 `QuestTicket.commitPrediction(...)`。
11. 如果 `ticket.questType == 3`，在 `validFrom` 前生成非零 `strategyHash`，再调用 `QuestTicket.commitStrategy(...)`。
12. 等到当前区块 `>= ticket.validFrom`。
13. 在 `ticket.validTo` 前调用 `SeatRace.compete(agentId, ticketId, proof)`。
14. 记录 compete receipt 的 `blockNumber` 为 `raceBlock`。
15. 等下一块，检查 `SeatRace.raceFinalized(raceBlock)`；如为 false，调用 `SeatRace.finalizeRace(raceBlock)`。
16. 读取 `SeatRace.primarySeatIdsByBlock(raceBlock, 0..3)` 和 `primarySeat(seatId)`，判断 `seat.agentId == agentId`。
17. 如果没赢，汇报并等待下一轮。
18. 如果赢了，读取 `MintController.primarySeatMintFee(seatId)`，确认余额足够后调用 `MintController.mintSeat(seatId)` 并附带准确 ETH。
19. 从 `CrownRoll.RollCreated` 找 `rollId`；等待 `pendingRoll(rollId).revealBlock` 后调用 `CrownRoll.settle(rollId)`。

## 重试和状态

- 本地保存 `agentWallet`、`agentId`、`ticketId`、`raceBlock`、`seatId`、`rollId`、交易 hash。
- 进程重启后优先从链上事件恢复，不要盲目创建新 Agent。
- 交易失败先重新读链上状态判断是否已被其他进程完成。
- 余额不足、RPC 不可用、Ticket 过期、commit 错过窗口时，停止当前轮并汇报下一步。

## 汇报模板

```text
BLOCKKING status
agentWallet:
agentId:
ticketId:
questType:
raceBlock:
seatId:
mintFee:
rollId:
txHashes:
nextAction:
```
