nonce-manager について
複数のスキルやプロセス間でStacksトランザクションのnonceを調整するコマンドラインツールです。ファイルロックで状態を管理し、古い値をHiroから再同期するとともに、ブロードキャスト済みと拒否された取引を区別します。
主な機能
- 01nonceのアトミックな取得
- 02確認・失敗後の解放
- 03Hiroによる古い状態の再同期
- 04ファイルロックによる並行アクセス
- 05ブロードキャスト済みと拒否の区別
- 06CLIとTypeScriptライブラリからの利用
活用シーン
- 01並行トランザクションでのnonce衝突防止
- 02古いnonceエラーからの復旧
- 03取引結果に応じたnonce状態の管理
- 04複数スキル間での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 Manager
Stacks トランザクション用のバックアップ送信者 nonce トラッカーです。x402 の状態管理には、paymentId による標準の支払いステータスポーリングを主に使用してください。新しい送信者 nonce が実際に必要な場合は、このツールをローカルでの nonce 調整と復旧に使用してください。
問題
各スキルが個別に Hiro API から nonce を取得します。タスクが立て続けに実行されると(mempool がクリアされる前に)、同じ nonce を取得してしまい、SENDER_NONCE_STALE または SENDER_NONCE_DUPLICATE エラーが発生します。
解決策
ファイルロックで保護された単一の nonce 状態を ~/.aibtc/nonce-state.json に保存します。スキルは acquire を呼び出して次の nonce を取得し(アトミックにインクリメントされます)、トランザクションが確定または失敗した後に release を呼び出します。状態が古い場合(5 分超)、Hiro から自動的に再同期します。
サブコマンド
acquire
Stacks アドレスの次の nonce を取得します。保存値をアトミックにインクリメントします。状態がない場合、または古い場合(5 分超)は Hiro と自動同期します。
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— tx は mempool に到達していません(署名エラー、リレーの 409 nonce 拒否)。nonce は消費されていないため、安全にロールバックして再利用できます。--broadcast(--failedのデフォルト)— tx は mempool に到達しています。tx がオンチェーンで失敗しても、nonce は消費されています。ロールバックしないでください。
--failed --rejected の場合にのみロールバックが実行されます。デフォルトの --failed はブロードキャスト済みとみなします(より安全です)。
出力:
{ "address": "SP...", "nonce": 42, "action": "confirmed" }
sync
Hiro API から nonce 状態を強制的に再同期します。手動で介入した後や mempool のクリア後に使用します。
bun run nonce-manager/nonce-manager.ts sync --address SP...
出力:
{ "nonce": 42, "address": "SP...", "mempoolPending": 3, "lastExecuted": 41, "detectedMissing": [] }
status
追跡中のアドレスを 1 つ、またはすべて指定して、現在の 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 戦略
- 送信前に acquire — 常にマネージャーから nonce を取得し、Hiro から直接取得しないでください
- 確定または失敗後に release — 次の呼び出し元のために状態を正確に保ちます
- 古い状態を自動同期 — 最後の同期から 5 分を超えている場合、返却前に Hiro から再取得します
- アトミック性を確保するファイルロック — mkdir ベースのロックにより、並行読み取りで同じ nonce が返されるのを防ぎます
- ブロードキャスト済みと拒否済みを区別 — ロールバックできるのは拒否済みの nonce のみです
x402 エラーコードとの連携
まず、標準の支払いステータスと terminalReason を使用してください。ローカルでの nonce の記録管理が引き続き必要な場合は、次のように結果を release アクションに対応付けます。
| リレーの応答 | Release アクション |
|---|---|
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 + リレー/スポンサー/内部理由 | 送信者の再構築を促す指示として扱わず、ツールのポリシーに従って回数を制限して再試行するか、停止します |
replaced / not_found | 古い paymentId のポーリングを停止します。上位のアクションで引き続き支払いが必要な場合に限り、新しい支払いフローを開始します |