signing について
signingは、Stacks、Bitcoin、Nostrのワークフローで署名と検証を行うコマンドラインスキルです。構造化データ、メッセージ、Taprootダイジェスト、Nostrイベントに対応します。
主な機能
- 01SIP-018データの署名とハッシュ計算
- 02Stacksメッセージの署名と検証
- 03BIP-137およびBIP-322のBitcoin署名
- 04BIP-340 Schnorrダイジェストの署名と検証
- 05Nostrイベントの署名
活用シーン
- 01Stacksメッセージ署名の検証とアドレス復元
- 02アドレス形式に応じたBitcoinメッセージの署名
- 03Taprootマルチシグの調整とダイジェスト署名の検証
- 04ウォレットキーを使ったNostrイベントの署名
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ aibtcdev/ skills --skill signingインストール後、Claude Code で/signingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENT.mdsigning.test.tssigning.ts詳細
署名スキル
Stacks と Bitcoin のエコシステム向けに、暗号学的なメッセージ署名を提供します。4 つの署名規格に対応しています。
- SIP-018 — 構造化された Clarity データの署名です。署名はオフチェーンと、
secp256k1-recover?を介したオンチェーンのスマートコントラクトの両方で検証できます。 - Stacks メッセージ — SIWS 互換のプレーンテキスト署名です。ウォレット認証やアドレスの所有証明に使用します。
- Bitcoin メッセージ — BIP-137 と BIP-322 のハイブリッド方式です。レガシーアドレス(1...)とラップド SegWit アドレス(3...)には BIP-137 を、ネイティブ SegWit アドレス(bc1q)と Taproot アドレス(bc1p)には BIP-322 の「simple」方式を使用します。Electrum、Bitcoin Core、最新のウォレットと互換性があります。
- Schnorr(BIP-340) — 生の 32 バイトダイジェストに対する Taproot ネイティブ署名です。Taproot のスクリプトパスでの使用、マルチシグの調整、OP_CHECKSIGADD の witness 組み立てに使用します。
- Nostr イベント(NIP-06) — デフォルトでは NIP-06 派生鍵(
m/44'/1237'/0'/0/0)を使って Nostr イベントオブジェクトに署名します。または、keySourceを介してウォレットの鍵パスを指定できます。
使用方法
bun run signing/signing.ts <subcommand> [options]
サブコマンド
sip018-sign
SIP-018 規格を使って構造化された Clarity データに署名します。ドメインの紐付け(名前 + バージョン + chain-id)により、アプリ間およびチェーン間のリプレイ攻撃を防ぎます。ロック解除済みのウォレットが必要です。
bun run signing/signing.ts sip018-sign \
--message '{"amount":{"type":"uint","value":100}}' \
--domain-name "My App" \
--domain-version "1.0.0"
オプション:
--message(必須)— JSON 文字列形式の構造化データです。Clarity 型を明示するには、型ヒントを使用します。{"type":"uint","value":100}→uint{"type":"int","value":-50}→int{"type":"principal","value":"SP..."}→principal{"type":"ascii","value":"hello"}→string-ascii{"type":"utf8","value":"hello"}→string-utf8{"type":"buff","value":"0x1234"}→buff{"type":"bool","value":true}→bool{"type":"none"}→none{"type":"some","value":...}→(some ...){"type":"list","value":[...]}→list{"type":"tuple","value":{...}}→tuple- 暗黙の型変換:
string → string-utf8、number → int、boolean → bool、null → none
--domain-name+--domain-version(同時に必須)— CLI 用のフラットなドメインフィールドです。--domain(代替)— MCP 形式の JSON オブジェクトです:{"name":"My App","version":"1.0.0"}(chainIdは任意)
出力:
{
"success": true,
"signature": "abc123...",
"signatureFormat": "RSV (65 bytes hex)",
"signer": "SP...",
"network": "testnet",
"chainId": 2147483648,
"hashes": {
"message": "...",
"domain": "...",
"encoded": "...",
"verification": "...",
"prefix": "0x534950303138"
},
"domain": { "name": "My App", "version": "1.0.0", "chainId": 2147483648 },
"verificationNote": "Use sip018-verify with the 'verification' hash..."
}
sip018-verify
SIP-018 署名を検証し、署名者の Stacks アドレスを復元します。sip018-sign または sip018-hash の verification ハッシュを指定してください。
bun run signing/signing.ts sip018-verify \
--message-hash <verificationHash> \
--signature <rsv65BytesHex> \
[--expected-signer <address>]
オプション:
--message-hash(必須)— SIP-018 の検証ハッシュです(sip018-sign/sip018-hashから取得)。--signature(必須)— RSV 形式の署名(16 進数で 65 バイト)です。--expected-signer(任意)— 照合する署名者のアドレスです。
出力:
{
"success": true,
"recoveredPublicKey": "03...",
"recoveredAddress": "SP...",
"network": "testnet",
"verification": {
"expectedSigner": "SP...",
"isValid": true,
"message": "Signature is valid for the expected signer"
}
}
sip018-hash
署名せずに SIP-018 メッセージのハッシュを計算します。オフチェーンまたはオンチェーンでの検証に必要なハッシュコンポーネントをすべて返します。ロック解除済みのウォレットは必要ありません。
bun run signing/signing.ts sip018-hash \
--message '{"amount":{"type":"uint","value":100}}' \
--domain-name "My App" \
--domain-version "1.0.0" \
[--chain-id <id>]
オプション:
--message(必須)— JSON 文字列形式の構造化データです(sip018-sign と同じ形式)。--domain-name+--domain-version(同時に必須)— CLI 用のフラットなドメインフィールドです。--domain(代替)— MCP 形式の JSON オブジェクトです:{"name":"My App","version":"1.0.0"}(chainIdは任意)--chain-id(任意)— チェーン ID の上書き値です(domain.chainIdより優先されます)。
出力:
{
"success": true,
"hashes": {
"message": "...",
"domain": "...",
"encoded": "...",
"verification": "..."
},
"hashConstruction": {
"prefix": "0x534950303138",
"formula": "verification = sha256(prefix || domainHash || messageHash)"
},
"domain": { "name": "My App", "version": "1.0.0", "chainId": 2147483648 },
"clarityVerification": {
"example": "(secp256k1-recover? (sha256 encoded-data) signature)"
}
}
stacks-sign
Stacks メッセージ署名形式を使ってプレーンテキストのメッセージに署名します。ハッシュ化の前にメッセージへ \x17Stacks Signed Message:\n が付加されます(SIWS 互換)。ロック解除済みのウォレットが必要です。
bun run signing/signing.ts stacks-sign --message "Hello, Stacks!"
オプション:
--message(必須)— 署名するプレーンテキストのメッセージです。
出力:
{
"success": true,
"signature": "abc123...",
"signatureFormat": "RSV (65 bytes hex)",
"signer": "SP...",
"network": "testnet",
"message": {
"original": "Hello, Stacks!",
"prefix": "\u0017Stacks Signed Message:\n",
"prefixHex": "...",
"hash": "..."
},
"verificationNote": "Use stacks-verify with the original message and signature to verify."
}
stacks-verify
Stacks メッセージの署名を検証し、署名者の Stacks アドレスを復元します。SIWS 認証フローと互換性があります。
bun run signing/signing.ts stacks-verify \
--message "Hello, Stacks!" \
--signature <rsv65BytesHex> \
[--expected-signer <address>]
オプション:
--message(必須)— 署名された元のプレーンテキストメッセージです。--signature(必須)— RSV 形式の署名(16 進数で 65 バイト)です。--expected-signer(任意)— 期待する署名者の Stacks アドレスです。
出力:
{
"success": true,
"signatureValid": true,
"recoveredPublicKey": "03...",
"recoveredAddress": "SP...",
"network": "testnet",
"message": {
"original": "Hello, Stacks!",
"prefix": "\u0017Stacks Signed Message:\n",
"hash": "..."
},
"verification": {
"expectedSigner": "SP...",
"signerMatches": true,
"isFullyValid": true,
"message": "Signature is valid and matches expected signer"
}
}
btc-sign
Bitcoin メッセージ署名を使用してプレーンテキストのメッセージに署名します。アドレスの種類に応じて署名形式を自動選択します。レガシー(1...)およびラップド SegWit(3...)アドレスには BIP-137(65 バイトのコンパクト署名)、ネイティブ SegWit(bc1q)および Taproot(bc1p)アドレスには BIP-322「simple」(witness シリアライズ)を使用します。Electrum、Bitcoin Core、最新のウォレットと互換性があります。Bitcoin キーを含むロック解除済みのウォレットが必要です。
bun run signing/signing.ts btc-sign --message "Hello, Bitcoin!"
オプション:
--message(必須)— 署名するプレーンテキストのメッセージ
出力:
{
"success": true,
"signature": "abc123...",
"signatureBase64": "...",
"signatureFormat": "BIP-137 (65 bytes: 1 header + 32 r + 32 s)",
"signer": "bc1q...",
"network": "mainnet",
"addressType": "P2WPKH (native SegWit)",
"message": {
"original": "Hello, Bitcoin!",
"prefix": "\u0018Bitcoin Signed Message:\n",
"prefixHex": "...",
"formattedHex": "...",
"hash": "..."
},
"header": { "value": 39, "recoveryId": 0, "addressType": "P2WPKH (native SegWit)" },
"verificationNote": "Use btc-verify with the original message and signature to verify."
}
btc-verify
Bitcoin メッセージ署名(BIP-137 または BIP-322)を検証し、署名者の Bitcoin アドレスを復元します。形式を自動検出します。レガシー/ラップド SegWit アドレスには BIP-137(65 バイトのコンパクト形式。16 進数 130 文字または base64 88 文字)、ネイティブ SegWit(bc1q)および Taproot(bc1p)アドレスには BIP-322「simple」(witness シリアライズ、base64)を使用します。
bun run signing/signing.ts btc-verify \
--message "Hello, Bitcoin!" \
--signature <hexOrBase64Sig> \
[--expected-signer <btcAddress>]
オプション:
--message(必須)— 署名された元のプレーンテキストのメッセージ--signature(必須)— Bitcoin 署名。レガシー/ラップド SegWit 用の BIP-137(65 バイト。16 進数[130 文字]または base64[88 文字])、または bc1q/bc1p アドレス用の BIP-322「simple」(witness シリアライズ、base64)--expected-signer(任意)— 照合対象として検証する、想定される署名者の Bitcoin アドレス
出力:
{
"success": true,
"signatureValid": true,
"recoveredPublicKey": "03...",
"recoveredAddress": "bc1q...",
"network": "mainnet",
"message": { "original": "Hello, Bitcoin!", "prefix": "...", "hash": "..." },
"header": { "value": 39, "recoveryId": 0, "addressType": "P2WPKH (native SegWit)" },
"verification": {
"expectedSigner": "bc1q...",
"signerMatches": true,
"isFullyValid": true,
"message": "Signature is valid and matches expected signer"
}
}
schnorr-sign-digest
ウォレットの Taproot 秘密鍵を使い、Schnorr(BIP-340)で生の 32 バイトダイジェストに署名します。Taproot のスクリプトパスでの支出、マルチシグの調整、または事前計算されたハッシュ(例:BIP-341 sighash)に対する BIP-340 Schnorr 署名が必要な場合に使用します。ブラインド署名の安全ゲートを備えています。--confirm-blind-sign を指定せずに最初に呼び出すと、確認用にダイジェストが返されます。Taproot キーを含むロック解除済みのウォレットが必要です。
bun run signing/signing.ts schnorr-sign-digest \
--digest <64-char-hex> \
[--aux-rand <64-char-hex>] \
[--confirm-blind-sign]
オプション:
--digest(必須)— 署名する 32 バイトの 16 進数エンコード済みダイジェスト(例:BIP-341 トランザクションの sighash)--aux-rand(任意)— BIP-340 用の 32 バイトの 16 進数補助ランダム値(サイドチャネル耐性を高めます)--confirm-blind-sign(任意)— ダイジェストを確認し、ブラインド署名のリスクを受け入れることを確認するために指定します。このフラグを指定しない場合、確認用のダイジェストと警告が返されます。
出力(--confirm-blind-sign を指定しない場合):
{
"warning": "schnorr-sign-digest signs a raw 32-byte digest...",
"digestToReview": "abc123...",
"instructions": "Review the digest above. If you trust its origin..."
}
出力(--confirm-blind-sign を指定した場合):
{
"success": true,
"signature": "abc123...",
"publicKey": "def456...",
"address": "bc1p...",
"network": "mainnet",
"signatureFormat": "BIP-340 Schnorr (64 bytes)",
"publicKeyFormat": "x-only (32 bytes)",
"note": "For Taproot script-path spending, append sighash type byte..."
}
schnorr-verify-digest
32 バイトのダイジェストに対する BIP-340 Schnorr 署名を検証します。ダイジェスト、署名、x-only 公開鍵を受け取り、署名が有効かどうかを返します。マルチシグの調整で、ほかのエージェントからの Taproot 署名を検証する際に使用します。
bun run signing/signing.ts schnorr-verify-digest \
--digest <64-char-hex> \
--signature <128-char-hex> \
--public-key <64-char-hex>
オプション:
--digest(必須)— 署名された 32 バイトの 16 進数エンコード済みダイジェスト--signature(必須)— 64 バイトの 16 進数エンコード済み BIP-340 Schnorr 署名--public-key(必須)— 署名者の 32 バイトの 16 進数エンコード済み x-only 公開鍵
出力:
{
"success": true,
"isValid": true,
"digest": "abc123...",
"signature": "def456...",
"publicKey": "789abc...",
"message": "Signature is valid for the given digest and public key",
"note": "BIP-340 Schnorr verification. Use for validating signatures in Taproot multisig coordination."
}
nostr-sign-event
ウォレットの Nostr キーを使用して、Nostr イベントオブジェクト(NIP-01 形式)に署名します。デフォルトでは、ウォレットのニーモニックから NIP-06(m/44'/1237'/0'/0/0)を使用してキーを導出し、NIP-06 準拠の Nostr クライアント(Amethyst、Damus、Snort など)に対応する npub を生成します。ウォレットのロックを解除する必要があります。
bun run signing/signing.ts nostr-sign-event \
--event '{"kind":1,"created_at":1700000000,"tags":[],"content":"Hello, Nostr!"}' \
[--key-source nostr|taproot|segwit]
オプション:
--event(必須)— Nostr イベントの JSON オブジェクト(NIP-01 形式)。フィールドid、pubkey、sigは計算されて返されるため、入力に含めないでください。--key-source(任意、デフォルト:"nostr")— 署名に使用するウォレットキーを指定します。"nostr"(デフォルト)— NIP-06 派生キー(m/44'/1237'/0'/0/0)。新しい ID の作成と、すべての NIP-06 Nostr クライアントとの互換性に使用します。"taproot"— BIP-86 Taproot キー(m/86'/0'/0'/0/0)。Taproot キーに既存の Nostr ID がある場合に使用します。"segwit"— BIP-84 ネイティブ SegWit キー(m/84'/0'/0'/0/0)。SegWit キーに既存の Nostr ID がある場合に使用します。
出力:
{
"success": true,
"event": {
"id": "abc123...",
"pubkey": "def456...",
"created_at": 1700000000,
"kind": 1,
"tags": [],
"content": "Hello, Nostr!",
"sig": "789abc..."
},
"npub": "npub1...",
"keySource": "nostr",
"derivationPath": "m/44'/1237'/0'/0/0",
"note": "Key derived via NIP-06. npub matches NIP-06 compliant Nostr clients."
}
キー導出に関する注意: デフォルトの "nostr" ソースは、NIP-06 仕様で定義されている標準の Nostr 導出パスである NIP-06(m/44'/1237'/0'/0/0)を使用します。エージェントはすべての Nostr とのやり取りで、このデフォルトを使用してください。keySource の上書きが必要なのは、既存の Nostr ID が別のキーのパスで以前に作成されている場合のみです。
署名標準のリファレンス
| 標準 | プレフィックス | 用途 | オンチェーンで検証可能か |
|---|---|---|---|
| SIP-018 | SIP018(16 進数) | 構造化された Clarity データ | はい(secp256k1-recover?) |
| Stacks | \x17Stacks Signed Message:\n | 認証、所有権の証明 | いいえ(オフチェーンのみ) |
| BIP-137 / BIP-322 | \x18Bitcoin Signed Message:\n | Bitcoin の認証、所有権の証明(1.../3...には BIP-137、bc1q/bc1pには BIP-322) | いいえ(オフチェーンのみ) |
| BIP-340 | なし(生のダイジェスト) | Taproot マルチシグ、スクリプトパスでの支出 | はい(OP_CHECKSIG/OP_CHECKSIGADD) |
| NIP-06(Nostr) | なし(イベントハッシュ) | Nostr イベントへの署名(NIP-01) | いいえ(Nostr ネットワークのみ) |
注意事項
- SIP-018 署名と Stacks 署名には、ウォレットのロック解除が必要です(
bun run wallet/wallet.ts unlock) - BTC 署名には Bitcoin キーも必要です(管理対象ウォレットには自動的に含まれます)
- Schnorr 署名には Taproot キーが必要です(管理対象ウォレットでは自動的に導出されます)
sip018-hash、両方の*-verifyサブコマンド、およびschnorr-verify-digestでは、ウォレットのロック解除は不要です- すべての ECDSA 署名は secp256k1 曲線を使用し、Schnorr は BIP-340(x-only 公開鍵、64 バイトの署名)を使用します
- SIP-018 のチェーン ID:メインネット = 1、テストネット = 2147483648(0x80000000)