NUT-26:付款请求的Bech32m编码

cashubtc 发布于 2026-03-16 阅读 105

本文介绍NUT-26规范,定义了一种基于Bech32m编码和TLV序列化的付款请求编码格式,相比NUT-18的CBOR+base64格式,QR码兼容性更好且体积可缩减30-60%。详细说明了编码格式、TLV结构(包括顶层标签、单位编码、传输子TLV、NUT-10子TLV等)、示例以及与BIP-321的集成,支持多种支付方式统一QR码。

可选 依赖于:NUT-18


编码请求格式

支付请求使用 TLV 编码序列化,然后使用 Bech32m 编码:

"creqb" + "1" + bech32m(TLV(PaymentRequest))

人类可读部分(HRP)为 "creqb",版本分隔符为 "1"。数据载荷按照下文描述进行 TLV 编码,然后使用 Bech32m(非标准 Bech32)编码。

[!注意] 实现应该输出大写的 Bech32m 字符串,以获得最佳的二维码兼容性。大写字母数字字符使用 QR 码的“字母数字模式”,该模式比混合大小写所需的“字节模式”更节省空间。解码器必须同时接受大写和小写输入。

在解析 creq 参数时,实现应该支持两种格式:

  1. 如果参数以 creqA 开头(不区分大小写),则按 NUT-18 CBOR+base64 格式解析
  2. 如果参数是有效的 Bech32m 且 HRP 为 creqb,则按 NUT-26 格式解析
  3. 否则,返回错误

TLV 结构

支付请求被编码为一系列 TLV 字段。每个 TLV 条目包含:

  • 类型(1 字节):字段标识符
  • 长度(2 字节,大端序):值的字节长度
  • (可变长度):字段数据

顶层 TLV 标签

标签 字段 类型 描述
0x01 id 字符串 支付标识符(对应 JSON 中的 i
0x02 amount u64 以基本单位表示的金额(对应 JSON 中的 a
0x03 unit u8/字符串 货币单位(对应 JSON 中的 u
0x04 single_use u8 一次性使用标志:0=否,1=是(对应 JSON 中的 s
0x05 mint 字符串 Mint URL(可重复,对应 JSON 中的 m
0x06 description 字符串 人类可读描述(对应 JSON 中的 d
0x07 transport 子 TLV 传输配置(可重复,对应 JSON 中的 t
0x08 nut10 子 TLV NUT-10 花费条件(对应 JSON 中的 nut10

所有字段都是可选的。未知标签必须被忽略,以保持向前兼容性。

单位编码(标签 0x03)

单位字段使用紧凑编码:

  • 值 0x00:表示 sat(比特币聪)
  • 字符串值:任何其他单位编码为 UTF-8 字符串(例如 "msat""usd""eur"

传输子 TLV(标签 0x07)

传输配置编码为嵌套的 TLV 结构。每个传输具有以下子标签:

子标签 字段 类型 描述
0x01 kind u8 传输类型:0=nostr,1=http_post
0x02 target 字节流 传输目标(解释取决于 kind)
0x03 tag_tuple 子-子 TLV 通用标签元组(可重复)

传输类型映射

kind 字段(子标签 0x01)标识传输方法。定义以下传输类型:

Kind 值 传输类型 描述 目标格式
0x00 nostr 基于 Nostr 的传输,使用 NIP-04 DM 32 字节 X-only 公钥(原始字节)
0x01 http_post HTTP POST 到指定 URL UTF-8 编码的 URL 字符串

[!注意] 如果未指定传输(标签 0x07 不存在),则默认支付为带内传输,与 NUT-18 语义一致。

JSON 表示:

在 NUT-18 JSON 格式中,传输使用 type 字段表示:

{
  "t": [
    { "type": "nostr", "target": "npub1...", "tags": [["n", "17"]] },
    { "type": "post", "target": "https://callback.example.com/pay" }
  ]
}

编码为 TLV 时,type 字符串转换为对应的数字 kind 值。

传输目标编码(子标签 0x02)

目标字段根据传输 kind 进行解释:

  • kind=0(nostr):32 字节 X-only 公钥(原始字节,非 bech32 编码)
  • kind=1(http_post):UTF-8 编码的 URL 字符串

Nostr 传输细节

对于 Nostr 传输(kind=0),目标字段包含原始的 32 字节 X-only 公钥(非 bech32 编码)。NIP 和中继 URL 使用通用标签元组(子标签 0x03)编码,与 NUT-18 的 tags 数组一致。

编码(JSON 转 TLV):

  1. 使用 NIP-19 从 JSON 目标字段中解析 nprofilenpub
  2. 将原始 32 字节 X-only 公钥存储到目标(子标签 0x02)中
  3. 将来自 nprofile 的中继 URL 作为键为 "r" 的标签元组存储
  4. 将来自 tags 数组的 NIP 作为键为 "n" 的标签元组存储

解码(TLV 转 JSON):

  • 如果没有 "r" 标签元组:将公钥编码为 npub
  • 如果有 "r" 标签元组:使用 NIP-19 格式编码为 nprofile

标签元组编码(子标签 0x03)

通用标签元组编码为:

  1. 键长度(1 字节)
  2. 键字符串(UTF-8)
  3. 对于每个值:
    • 值长度(1 字节)
    • 值字符串(UTF-8)

这允许编码任意键值对以实现可扩展性。

NUT-10 子 TLV(标签 0x08)

NUT-10 花费条件编码为嵌套的 TLV 结构:

子标签 字段 类型 描述
0x01 kind u8 秘密种类(0=P2PK,1=HTLC 等)
0x02 data 字节流 特定种类的数据(UTF-8 编码)
0x03 tag_tuple 子-子 TLV 标签元组(可重复,使用与传输标签相同的编码)

NUT-10 种类枚举

为 NUT-10 花费条件定义了以下 kind 值:

Kind 值 名称 描述
0x00 P2PK 公钥支付 - 需要指定公钥的签名
0x01 HTLC 哈希时间锁定合约 - 需要哈希的原像

其他 kind 值可能在未来的 NUT 规范中定义。在重新编码时应该保留未知 kind 值,但在验证时可以忽略。

示例

这是一个以 JSON 表示的支付请求示例:

{
  "i": "demo123",
  "a": 1000,
  "u": "sat",
  "s": true,
  "m": ["https://mint.example.com"],
  "d": "Coffee payment"
}

该支付请求编码为 NUT-26 格式后如下:

CREQB1QYQQWER9D4HNZV3NQGQQSQQQQQQQQQQRAQPSQQGQQSQQZQG9QQVXSAR5WPEN5TE0D45KUAPWV4UXZMTSD3JJUCM0D5RQQRJRDANXVET9YPCXZ7TDV4H8GXHR3TQ

BIP-321 集成

NUT-26 支付请求可以通过 creq 查询参数包含在 BIP-321 比特币 URI 中。这允许创建支持多种支付方式的统一二维码。

完整的 Bech32m 编码字符串(包括 creqb1 前缀)用作参数值。

[!注意] 实现应该使用大写以优化二维码兼容性。解码器必须同时接受大写和小写输入。

统一二维码

通过将闪电网络支付数据和 Cashu 支付请求同时包含在单个 BIP-321 URI 中,一个二维码可以作为多种支付方式的入口点。支持某一支付方式的钱包可以使用该方式,而其他钱包可以回退到支持的方法。

示例

仅 Cashu

仅包含一个 Cashu 支付请求的比特币 URI:

bitcoin:?creq=CREQB1QYQQWER9D4HNZV3NQGQQSQQQQQQQQQQRAQPSQQGQQSQQZQG9QQVXSAR5WPEN5TE0D45KUAPWV4UXZMTSD3JJUCM0D5RQQRJRDANXVET9YPCXZ7TDV4H8GXHR3TQ

BOLT11 + Cashu

同时支持闪电网络(BOLT11)和 Cashu 的统一二维码:

bitcoin:?lightning=lnbc210n1p56amv8sp5v5gvxh0swyje66pcxtqtqh3qmzxd74fkxhjmzgzw7nff9fuhcdgqpp566zkpvgxn832cg06ghlk48tqntffkp6nsemw8g836pjfw4tdhdmsdqgde6hgv3kxqyjw5qcqpjrzjqwryaup9lh50kkranzgcdnn2fgvx390wgj5jd07rwr3vxeje0glc7rf05uqqg8gqqqqqqqlgqqqqrucqjq9qxpqysgqrdvjgsemgtxs3wa38xf8qs3awqf5ksw0d3mpm07t9yl7xkasyzgz8rw5qlas6r4ers68u7nmgvqsgar4t9lr47fwlaue302nrasdekgqnvfjmp&creq=CREQB1QYQQWER9D4HNZV3NQGQQSQQQQQQQQQQRAQPSQQGQQSQQZQG9QQVXSAR5WPEN5TE0D45KUAPWV4UXZMTSD3JJUCM0D5RQQRJRDANXVET9YPCXZ7TDV4H8GXHR3TQ

BOLT12 + Cashu

同时支持闪电网络报价(BOLT12)和 Cashu 的统一二维码:

bitcoin:?lno=lno1pgzkcctzv4kpvggzu2th0tw73fx2ygyd7gyuul490zkhkmz75ncz6q9nkyp9m78932tq&creq=CREQB1QYQQWER9D4HNZV3NQGQQSQQQQQQQQQQRAQPSQQGQQSQQZQG9QQVXSAR5WPEN5TE0D45KUAPWV4UXZMTSD3JJUCM0D5RQQRJRDANXVET9YPCXZ7TDV4H8GXHR3TQ
  • 原文链接: github.com/cashubtc/nuts...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论