关于 nonce-manager
用于在多个 Skill 和进程间协调 Stacks 交易的命令行 Nonce 管理器。它通过文件锁维护状态、从 Hiro 重新同步过期值,并区分已广播交易与被拒交易。
主要功能
- 01原子获取 Nonce
- 02按确认或失败释放
- 03从 Hiro 重新同步过期状态
- 04通过文件锁支持并发访问
- 05区分已广播与被拒交易
- 06支持 CLI 和 TypeScript 库调用
适用场景
- 01防止并发交易发生 Nonce 冲突
- 02从过期 Nonce 错误中恢复
- 03依据交易结果跟踪 Nonce 状态
- 04在多个 Skill 间共享 Nonce 协调
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aibtcdev/ skills --skill nonce-manager安装后在 Claude Code 中输入/nonce-manager确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AGENT.mdnonce-manager.tsnonce-store.ts详细介绍
Nonce 管理器
用于 Stacks 交易的备用发送方 nonce 跟踪器。请优先通过 paymentId 轮询规范的支付状态,以此作为 x402 状态机;仅当确实需要新的发送方 nonce 时,才使用此工具进行本地 nonce 协调和恢复。
问题
每个技能都会独立从 Hiro API 获取 nonce。当任务接连触发(而内存池尚未清空)时,它们会拿到相同的 nonce,并因 SENDER_NONCE_STALE 或 SENDER_NONCE_DUPLICATE 错误而冲突。
解决方案
在 ~/.aibtc/nonce-state.json 中使用单个受文件锁保护的 nonce 状态。技能调用 acquire 获取下一个 nonce(原子递增),并在交易确认或失败后调用 release。如果状态已过期(超过 5 分钟),则自动从 Hiro 重新同步。
子命令
acquire
获取 Stacks 地址的下一个 nonce。原子递增存储的值。如果状态缺失或已过期(超过 5 分钟),则自动同步。
bun run nonce-manager/nonce-manager.ts acquire --address SP...
输出:
{ "nonce": 42, "address": "SP...", "source": "local" }
release
在确认交易结果后,将 nonce 标记为已确认或失败。
bun run nonce-manager/nonce-manager.ts release --address SP... --nonce 42
bun run nonce-manager/nonce-manager.ts release --address SP... --nonce 42 --failed
bun run nonce-manager/nonce-manager.ts release --address SP... --nonce 42 --failed --rejected
失败类型(关键区别):
--rejected— 交易从未进入内存池(签名错误、relay 以 409 拒绝 nonce)。nonce 未被消耗,可以安全回滚并重用。--broadcast(指定--failed时的默认值)— 交易已进入内存池。即使交易在链上失败,nonce 也已被消耗。请勿回滚。
只有 --failed --rejected 会触发回滚。默认的 --failed 表示交易已广播(更安全)。
输出:
{ "address": "SP...", "nonce": 42, "action": "confirmed" }
sync
强制从 Hiro API 重新同步 nonce 状态。手动干预或内存池清空后使用。
bun run nonce-manager/nonce-manager.ts sync --address SP...
输出:
{ "nonce": 42, "address": "SP...", "mempoolPending": 3, "lastExecuted": 41, "detectedMissing": [] }
status
显示一个或所有已跟踪地址的当前 nonce 状态。
bun run nonce-manager/nonce-manager.ts status
bun run nonce-manager/nonce-manager.ts status --address SP...
库导入
在同一进程中运行的技能可以直接导入:
import { acquireNonce, releaseNonce, syncNonce } from "../nonce-manager/nonce-store.js";
const { nonce } = await acquireNonce("SP...");
// ... send transaction ...
await releaseNonce("SP...", nonce, true); // true = success
Nonce 策略
- 发送前获取 — 始终从管理器获取 nonce,绝不直接从 Hiro 获取
- 确认/失败后释放 — 确保状态对下一个调用方准确无误
- 过期时自动同步 — 如果距离上次同步已超过 5 分钟,则在返回前重新从 Hiro 获取
- 使用文件锁确保原子性 — 基于 mkdir 的锁可防止并发读取返回相同的 nonce
- 区分已广播与已拒绝 — 只有被拒绝的 nonce 可以回滚
与 x402 错误代码集成
优先使用规范的支付状态和 terminalReason。仍需进行本地 nonce 记账时,可按如下方式将结果映射到释放操作:
| Relay 响应 | 释放操作 |
|---|---|
confirmed | release --address ... --nonce N(成功) |
queued / broadcasting / mempool | 继续轮询同一个 paymentId;不要重新构建;将 nonce 继续跟踪为处理中 |
failed + sender_nonce_duplicate | release --address ... --nonce N --failed --rejected + 重新同步并重新构建 |
409 SENDER_NONCE_STALE | release --address ... --nonce N --failed --rejected + 重新同步 |
409 SENDER_NONCE_GAP | release --address ... --nonce N --failed --rejected + 重新同步 |
failed + relay/赞助方/内部原因 | 不要将其视为发送方重新构建的指引;按照工具策略进行有限重试或停止 |
replaced / not_found | 停止轮询旧的 paymentId;仅当更高层操作仍需支付时,才启动新的支付流程 |