mcpField
S
signing

signing

github.com/aibtcdev安全11182 次安装1 天前更新
代码仓库

关于 signing

signing 是面向 Stacks、Bitcoin 和 Nostr 工作流的命令行签名技能,提供签名与验证操作。它覆盖结构化数据、消息、Taproot 摘要及 Nostr 事件等不同格式。

主要功能

  1. 01支持 SIP-018 数据签名与哈希
  2. 02签署并验证 Stacks 消息
  3. 03支持 BIP-137、BIP-322 比特币签名
  4. 04支持 BIP-340 Schnorr 摘要签名与验证
  5. 05签署 Nostr 事件

适用场景

  1. 01验证 Stacks 消息签名并恢复地址
  2. 02为 Bitcoin 消息生成适配地址类型的签名
  3. 03协调 Taproot 多签并验证摘要签名
  4. 04使用钱包密钥签署 Nostr 事件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aibtcdev/skills --skill signing

安装后在 Claude Code 中输入/signing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENT.md
signing.test.ts
signing.ts

详细介绍

签名技能

为 Stacks 和 Bitcoin 生态系统提供加密消息签名。支持四种签名标准:

  • SIP-018 — 结构化 Clarity 数据签名。签名既可在链下验证,也可通过 secp256k1-recover? 在链上智能合约中验证。
  • Stacks 消息 — 兼容 SIWS 的纯文本签名。用于钱包身份验证和证明地址所有权。
  • Bitcoin 消息 — BIP-137/BIP-322 混合方案。BIP-137 用于传统地址(1...)和封装式 SegWit 地址(3...);BIP-322「simple」用于原生 SegWit(bc1q)和 Taproot(bc1p)地址。兼容 Electrum、Bitcoin Core 和现代钱包。
  • Schnorr(BIP-340) — 针对原始 32 字节摘要的 Taproot 原生签名。用于 Taproot 脚本路径支出、多重签名协调和 OP_CHECKSIGADD 见证组装。
  • 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 数据。域绑定(名称 + 版本 + 链 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 格式的签名(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 格式的签名(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”(见证序列化)。兼容 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 字节紧凑签名,130 个十六进制字符或 88 个 Base64 字符);原生 SegWit(bc1q)和 Taproot(bc1p)地址使用 BIP-322 “simple”(见证序列化、Base64)。

bun run signing/signing.ts btc-verify \
  --message "Hello, Bitcoin!" \
  --signature <hexOrBase64Sig> \
  [--expected-signer <btcAddress>]

选项:

  • --message(必需)— 已签名的原始纯文本消息
  • --signature(必需)— Bitcoin 签名:传统地址/封装式 SegWit 地址使用 BIP-137(65 字节,以十六进制 [130 个字符] 或 Base64 [88 个字符] 表示),bc1q/bc1p 地址使用 BIP-322 “simple”(见证序列化、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 字节十六进制编码摘要(例如 BIP-341 交易 sighash)
  • --aux-rand(可选)— BIP-340 的 32 字节十六进制辅助随机数(提高侧信道攻击抵抗能力)
  • --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 坐标的公钥,并返回签名是否有效。可用于验证多重签名协调中来自其他 Agent 的 Taproot 签名。

bun run signing/signing.ts schnorr-verify-digest \
  --digest <64-char-hex> \
  --signature <128-char-hex> \
  --public-key <64-char-hex>

选项:

  • --digest(必需)— 已签名的 32 字节十六进制编码摘要
  • --signature(必需)— 64 字节十六进制编码的 BIP-340 Schnorr 签名
  • --public-key(必需)— 签名者的 32 字节十六进制编码、仅含 x 坐标的公钥

输出:

{
  "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)从钱包助记词派生,生成的 npub 与符合 NIP-06 的 Nostr 客户端(例如 Amethyst、Damus、Snort)兼容。需要解锁钱包。

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)。用于创建新身份,并兼容所有符合 NIP-06 的 Nostr 客户端。
    • "taproot" — BIP-86 Taproot 密钥(m/86'/0'/0'/0/0)。如果你已有基于 Taproot 密钥的 Nostr 身份,请使用此选项。
    • "segwit" — BIP-84 原生 SegWit 密钥(m/84'/0'/0'/0/0)。如果你已有基于 SegWit 密钥的 Nostr 身份,请使用此选项。

输出:

{
  "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(m/44'/1237'/0'/0/0),这是 NIP-06 规范定义的标准 Nostr 派生路径。Agent 应在所有 Nostr 交互中使用此默认设置。只有在现有 Nostr 身份此前是通过其他密钥路径创建时,才需要覆盖 keySource。

签名标准参考

标准前缀用例可在链上验证?
SIP-018SIP018(十六进制)结构化 Clarity 数据是(secp256k1-recover?)
Stacks\x17Stacks Signed Message:\n身份验证、所有权证明否(仅限链下)
BIP-137 / BIP-322\x18Bitcoin Signed Message:\nBitcoin 身份验证、所有权证明(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 坐标的公钥、64 字节签名)
  • SIP-018 链 ID:主网 = 1,测试网 = 2147483648(0x80000000)

评论

支持 Markdown