Skip to main content
X402 是一个由 Coinbase 提出的“按 HTTP 402 计费”的链上支付协议:服务端在没有 token 的请求上返回 402 Payment Required,附带 accepts: [...] 字段列出可接受的链 / 资产 / 价格;客户端在本地签好一笔授权(EVM 上是 Permit2 / EIP-712,Solana 上是 SPL token transfer 授权),把 base64 后的 envelope 放进 PAYMENT-SIGNATURE 头重发。服务端验证后真正去链上结算,再返回业务结果。
Ace Data Cloud 的 X402 客户端直接调用目标 API,并以该请求实时返回的 402 Payment Required 和 accepts 作为价格与签名依据。Facilitator 的支付能力可在 /.well-known/x402 核验。
@acedatacloud/sdk 和 acedatacloud 都暴露了一个 paymentHandler 钩子:当 SDK 自己发出的请求收到 402 时,调用你注入的 handler 拿到 PAYMENT-SIGNATURE 头,再重发原请求。把 @acedatacloud/x402-client / acedatacloud-x402 配合 SDK,整个流程对业务代码完全透明——你只用 client.openai.chat.completions.create(...) ,看起来和 token 模式一模一样,但底层是按调用付费、不需要事先充值。 本文:
  • 真实串了一遍 TS 端的「无 token + X402 handler 注入」链路(T12 验证)
  • 列了 EVM / Solana 两套签名链路的差异
  • 给出 viem 私钥模式、浏览器钱包模式、Python EVMAccountSigner 模式三种适配
  • 把 preferScheme / prefer_scheme 这个容易踩坑的字段说清楚

一、协议总览(必看)

一次成功的 X402 调用涉及 3 个 HTTP RTT:
X402 envelope 是一段 JSON,被 base64 之后塞在 PAYMENT-SIGNATURE 头。结构(节选):
envelope 顶层是 x402Version: 2,并用 accepted 对象声明本次选择的 scheme 和 network(CAIP-2 标识)。 preferScheme / prefer_scheme 用来在服务端同时提供多种 scheme 时选偏好。如果服务端只暴露 exact,这个字段会被忽略;如果设了 upto 但服务端没暴露,会回退到第一个匹配项。

二、TypeScript:浏览器钱包 + 服务端 viem 两套用法

安装

实测的版本号:

createX402PaymentHandler 完整签名

返回值是一个 (ctx) => Promise&lt;{ headers: Record<string, string> }>,正好对得上 SDK 的 paymentHandler 钩子签名。

用法 1:浏览器(MetaMask / WalletConnect)

第一次调用浏览器会弹两次签名提示:第一次是 Permit2 对 USDC 的一次性 approve(金额是 MaxUint256,写进链);第二次是 X402 envelope 的 EIP-712 签名(不上链,只是给 facilitator 验证)。后续调用只需要第二次签名,体验上是“点一次签名 → 拿结果”。

用法 2:Node 服务端 + viem 私钥(适合后端 / CLI)

@acedatacloud/x402-client 在 TS 端只接受 EIP-1193 provider——它不直接管私钥。在 Node / CLI 场景,标准做法是用 viem 把私钥包成 WalletClient,再走 @ethereumjs/util 或 viem 内部的 EIP-1193 适配。
如果觉得 viem 的 EIP-1193 适配不够稳,也可以走更底层的 signEVMUptoPayment ,自己把 accepts → signed envelope → PAYMENT-SIGNATURE header 这条路串起来,跳过 SDK 钩子;不过推荐还是首选 createX402PaymentHandler,省得自己维护协议升级。

用法 3:Solana

Solana 链上目前只暴露 exact scheme,所以 preferScheme 在 Solana 上不起作用。

三、Python:私钥模式

Python 的 acedatacloud-x402 走的是直接拿私钥签名的路(没有 EIP-1193 抽象),更适合服务端 / 任务执行器。

安装

实测版本号:

EVM(Base / Skale)

Solana

一次性 approve(仅 EVM 首次)

EVM Base 上 X402 走 Permit2,需要钱包对 USDC 给 Permit2 合约做一次 MaxUint256 的 approve。acedatacloud-x402 内置了 approve_permit2:
这个交易只需要发一次,之后所有 X402 EVM 支付都用这个授权。Solana 不需要。

四、真实运行验证

测试目标:TS SDK 不传 token,注入 X402 handler,能正常构造并发起请求(不消耗真链上 USDC 的轻量验证)。
输出:
结果说明:
  • 没有传 apiToken,SDK 构造不报错,证明 X402 模式确实是 token 的合法替代品。
  • createX402PaymentHandler 返回的是函数(钩子),SDK 拿到后只在收到 402 时才会调。
  • 实际链上付费走通的端到端测试,因为涉及真实 USDC 扣款,没放进本教程;可以参考 X402 集成指南 里的 e2e 示例。
Python 端 create_x402_payment_handler 也做了相同的验证 —— 函数返回值是 callable,注入 payment_handler=... 时 AceDataCloud(...) 构造不报错。两边语义对齐。

五、和「Bearer token 模式」的对比

两种模式可以共存——同一个进程里,给不同 client 实例配不同认证方式即可。

六、常见陷阱

  1. chat 类必须 preferScheme=upto:用 exact 会让 facilitator 按 maxAmountRequired(不是实际用量)扣 USDC。
  2. Node 端别传裸私钥给 createX402PaymentHandler:TS 包不接受 { privateKey },必须包成 EIP-1193 provider(推荐 viem WalletClient)。
  3. 首次调用是双签名:第一次签 Permit2 approve(上链、有 gas),第二次签 X402 envelope(不上链)。后续调用只剩第二次。
  4. Solana 没有 Permit2 概念:直接签 SPL token transfer 授权,不需要 approve;但目前 Solana 链上只支持 exact。
  5. 业务报错和支付错误区分:402 → handler 失败抛 X402SignError(具体类型按链不同);后续重发后业务接口的报错(401 / 422 / 5xx)仍然按普通 SDK 异常分类。
  6. viem 适配最稳的写法:evmProvider: walletClient as any 会失去类型检查但兼容性最好;如果想保留类型,用 viem 的 .transport.request 单独包一层 { request } 对象传进去。

了解更多