关于 nano-pay
nano-pay 是面向 AI Agent 的自托管 Nano(XNO)钱包、x402 支付客户端和商户服务端,适用于需要进行 API 微支付的开发者。它在本地签名,并提供价格上限、支付记录和链上确认机制。
主要功能
- 01本地托管 Nano 钱包与签名
- 02处理 x402 支付握手
- 03设置单笔支付价格上限
- 04记录并重试待处理支付
- 05提供 x402 商户验证与结算
适用场景
- 01用 Nano 支付按次收费的 API
- 02检查端点报价后再决定付款
- 03运行可收取 Nano 付款的 API 服务
MCP 相关
提供 MCP 工具 `x402_pay`,供客户端执行 x402 支付,并应用价格上限。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
nano-pay · Feeless402
面向 AI Agent 构建的自托管 Nano(XNO)钱包、x402 支付客户端和商家服务。客户端负责支付;nano-pay serve 负责收款——提供付费端点、链上验证与结算(无需中介服务)、入门水龙头,以及用于指导访问 Agent 如何开始使用的 railHint x402 扩展(参见 SPEC-railhint.md)。网站:site/index.html + site/llms.txt。
关于对外宣传的说明: Feeless402 不会在其他项目中发起议题、拉取请求或提案。其他地方发布的、推介“Nano 支付通道”并提及 Feeless402 的帖子,来自与我们无关的账号,并非我们所为。如果此类内容出现在你的代码仓库中,可以直接关闭。疑问:请在此处发起议题。
一句话说明价值: 同样的 5 美元,可以购买 5,000 次 API 调用,通过 x402 使用 USDC-on-Base 按次支付(商家将价格下限设为 0.001 USDC);也可以购买数十万次调用,按 Nano 的真实计量价格支付(在 nano-gpt.com 实测为每次调用 0.0000096 美元,并已在链上确认)。充值一次,尽情进行微支付。
安装
pip install feeless402 # needs Python 3.10+; pulls nanopy + requests
# (from a checkout: pip install -e .)
nano-pay init # creates ~/.nano-pay/wallet.json (chmod 600)
Agent 工作流
nano-pay topup 5 # quote: $5 USDC-BASE → ~12.3 XNO (NanSwap)
nano-pay topup 5 --execute # create order (set NANSWAP_API_KEY)
# → send USDC to the returned deposit address; XNO arrives in 30-60s
nano-pay receive # pocket incoming XNO
nano-pay quote https://nano-gpt.com/api/v1/chat/completions \
--json '{"model":"gpt-5-nano","messages":[{"role":"user","content":"hi"}]}'
nano-pay pay https://nano-gpt.com/api/v1/chat/completions \
--json '{"model":"gpt-5-nano","messages":[{"role":"user","content":"hi"}]}'
pay 会处理完整的 x402 握手:请求 → 解析 402 报价(支持 x402nano/PAYMENT-REQUIRED v2 方言和 NanoGPT/accepts v1 方言)→ 检查价格上限 → 在本地签署一笔发送状态块 → 使用 PAYMENT-SIGNATURE 和 X-PAYMENT 标头重试。服务端通过其中介服务结算该状态块;只有服务端接受后才会广播。若商家的回复丢失或状态码不是 2xx,客户端会在报告任何结果前,先向账本查询已签署的状态块哈希:回执中的 settled 为 true、false 或 "indeterminate",绝不猜测。已上链的状态块绝不会再次支付——重新提交同一笔即可。现在客户端会自动重新提交:每笔支付都会在发送前记录到钱包旁的日志文件(pending-payments.json);重试时——无论是同一次调用中还是崩溃后——都会重新发送同一已签署的状态块,并附带 X-PAYMENT-PROOF 标头(付款方对状态块哈希、方法和路径的签名)。服务端会在 24 小时内接受经过证明的重新提交,因此观察者重放公开状态块也无法耗尽付款方的重试次数。(v0.2.9;由 giskard09 私下报告,并通过独立测试工具重新验证了修复——参见安全公告 GHSA-cx37-j5vc-c967。v0.2.10 根据此次重新验证增加了两项后续修复:未知区块年龄的状态块绝不会被视为处于有效时间窗口内;只有来自已配置代理的转发 IP 标头才会被信任。)
v0.2.12 修复了客户端可能重复支付的剩余问题。无法访问的账本绝不会被当作“未支付”;拒绝也会像其他结果一样获得相同的确认等待时间;无法写入或读取的支付记录会阻止支付,而不是被遗忘;并且支付记录会与请求的正文和查询参数关联,因此同价的两个不同操作不会共用同一记录。此外:如果没有节点响应,回执检查器会抛出 Unreachable,而不是 NotFound;空白的 F402_* 设置表示“使用默认值”(空白的充值设置仍会保持关闭)。由 pyfile-toolkit(#10–#14)和 enricoaboujaoude-droid(#15–#18)报告;修复均根据他们的报告和测试独立完成。
v0.2.13 让 pay 命令如实报告结果。其 paid 字段现在表示账本的判定(true、false 或 "indeterminate"),而不再表示“已签署状态块”;只有调用已成功提供服务且支付已在账本上确认时,pay 才会以状态码 0 退出。其他情况均以状态码 1 退出,并在 stderr 中打印状态块哈希。非零退出状态并不意味着没有发生支付: 再次支付前,请先检查该状态块。有效的 402 报价仍会使 quote 以状态码 0 退出。由 vjohannesb(#19)报告;修复根据该报告独立完成。
设计说明
- **自我保管:**种子不会离开
~/.nano-pay/wallet.json(0600)。 - 无需节点:通过公共 RPC 故障转移(rpc.nano.to、somenano、
rainstorm.city、nanoslo);所有签名和 PoW 均在本地完成(nanopy
C 扩展)。优先尝试 RPC
work_generate,本地 PoW 作为后备方案(约 25 秒)。CLI 会在 打印当前区块的结果后,为你的下一个区块预缓存工作量,因此稳定状态下的付款 可即时完成。库调用由用户选择是否启用:send()、receive_all()和request_with_payment()接受prework=,默认值为关闭,因为 预缓存区块会持续数分钟,绝不能放在请求路径上。 - **安全措施:**每笔付款设有价格上限(
--max-xno,默认值为 0.05);quote命令可查看任意端点的价格,无需付款; 余额始终从网络重新同步,绝不信任本地记录。 - 无需托管即可充值:
topup通过 NanSwap 的 API 直接报价并创建兑换(支持 1,400 多种输入资产,最低约 $0.02)。此工具绝不持有或转移资金。
分叉风险说明(x402 付款)
x402 付款会签署一个由服务器广播的区块。如果服务器在收到区块后发生错误,该区块仍可能延迟结算。钱包会在每次操作前从网络重新同步其前沿,因此延迟结算会自动纳入;与此同时签署的竞争区块只会导致两个区块中的一个无效(资金绝无风险,但不要从同一个钱包同时发起多笔付款)。
状态
Beta 版(v0.2.13)。已在主网上使用真实资金验证:向 NanoGPT 发起实时付费调用(每次 $0.0000096,已在链上确认)、完整商户流程(验证 → 结算 → 确认,无需协调器)、受 PoW 限制的水龙头领取,以及完整的陌生 Agent 生命周期(新建钱包 → PoW 领取 → 付费 API 调用 → 确认),全程不到 3 分钟。71 项测试套件可离线覆盖付款流程(两项水龙头测试需要可选的 mcp extra)。尚未经审计——仅在其中存放运营资金。
收录目录
- gold-402 — 精选 x402
目录;
/premium参考端点收录在 APIs 下, 这个 Python 客户端收录在 SDKs 下。 - Official MCP registry —
com.feeless402/nano-pay。 - agent-tools.cloud — x402、MCP 和 A2A 条目。
安全须知(持有真实资金前请阅读)
- 自主托管:种子仅存放在
~/.nano-pay/*.json中(0600)。 任何工具或日志路径都不会打印它。请离线备份。 - 仅用于周转资金:这是测试版钱包软件。只放入几美元, 不要存放你的积蓄。
- 支出上限:
pay会拒绝超过--max-xno(默认值为 0.05)的报价。 MCPx402_pay会强制执行相同的上限参数。 - railHint 仅供参考:来自远程服务的提示是不可信的
输入。此客户端绝不会执行远程引导字符串;它只会
处理通过自身检查的结构化报价,并且
accepts始终绑定,而不会绑定提示。 - 商家分叉保护:服务会缓存已接受的前沿,并拒绝 前沿重复的区块;结算前会根据实时账本验证付款方余额/前沿/签名。
- 使用代理时:商家只信任来自
F402_TRUSTED_PROXIES(默认值为127.0.0.1,::1)的X-Real-IP/X-Forwarded-For;其他所有对端都通过其套接字地址识别。 如果你的反向代理运行在其他主机上,请将其地址添加到该变量中,并让它 覆盖这两个标头(proxy_set_header X-Real-IP $remote_addr;)。 - 运行一个工作进程:分叉保护(
_seen_previous)和重放 限制(_replays)均为进程内存状态。在uvicorn --workers N模式下,每个工作进程都有自己的副本,因此两个工作进程可能接受 同一个付款方前沿,而其中一个区块会在分叉竞争中落败。 除非将这些保护机制迁移到共享存储,否则请使用单个进程提供服务(通过在前面加锁来扩展, 而不是增加工作进程)。账本轮询预算是整个流程共用的 单一值(verify.CONFIRM_WAIT_S),因此商家结算循环和 x402 客户端查看链的 时间相同;如果某个工作进程比该时限更早放弃,就会对实际上已到账的付款报告“状态不确定”。 - 未经审计。MIT 许可 — 不提供任何担保。
致谢
Feeless402 因为有人花时间阅读代码、发现问题 并指出问题而变得更好。感谢:
- giskard09:私下报告了丢失回复后重试可能导致重复付款, 随后使用独立测试框架再次验证了修复结果(安全公告 GHSA-cx37-j5vc-c967;v0.2.9 和 v0.2.10)。
- pyfile-toolkit:修复了失效的 railHint 规范链接、精确的 XNO/raw 转换和水龙头的每次申领金额(#5–#7);统一了整个付款流程的账本等待时间(#9, v0.2.11);并报告了 v0.2.12 中修复的无法访问账本、收据检查器和空白 设置问题(#10–#14)。
- enricoaboujaoude-droid: 报告了 v0.2.12 中修复的付款日志和请求绑定问题 (#15–#18)。
- vjohannesb:报告了
pay会对已拒绝和未确认的付款宣布结算完成(#19,v0.2.13)。 - dhyabi2:贡献了独立的
结算收据验证器
nano_pay.receipt(#4)。 - Circadian-agent:发现 railHint 规范字段指向了已停用的部署(#2)。
发现问题了吗?请提交 issue;如果问题可能导致用户损失资金, 请通过 GitHub 的安全公告私下报告。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。