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私鑰模式、瀏覽器錢包模式、PythonEVMAccountSigner模式三種適配 - 把
preferScheme/prefer_scheme這個容易踩坑的欄位說清楚
一、協議總覽(必看)
一次成功的 X402 調用涉及 3 個 HTTP RTT:PAYMENT-SIGNATURE 標頭。結構(節選):
x402Version: 2,並用 accepted 對象聲明本次選擇的 scheme 和 network(CAIP-2 標識)。
preferScheme / prefer_scheme 用來在服務端同時提供多種 scheme 時選偏好。如果服務端只暴露 exact,這個欄位會被忽略;如果設了 upto 但服務端沒暴露,會回退到第一個匹配項。
二、TypeScript:瀏覽器錢包 + 服務端 viem 兩套用法
安裝
createX402PaymentHandler 完整簽名
(ctx) => Promise<{ headers: Record<string, string> }>,正好對得上 SDK 的 paymentHandler 鉤子簽名。
用法 1:瀏覽器(MetaMask / WalletConnect)
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
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:
四、真實運行驗證
測試目標: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 模式」的對比
六、常見陷阱
- chat 類必須
preferScheme=upto:用exact會讓 facilitator 按maxAmountRequired(不是實際用量)扣 USDC。 - Node 端別傳裸私鑰給
createX402PaymentHandler:TS 包不接受{ privateKey },必須包成 EIP-1193 provider(推薦 viemWalletClient)。 - 首次調用是雙簽名:第一次簽 Permit2 approve(上鏈、有 gas),第二次簽 X402 envelope(不上鏈)。後續調用只剩第二次。
- Solana 沒有 Permit2 概念:直接簽 SPL token transfer 授權,不需要 approve;但目前 Solana 鏈上只支持
exact。 - 業務報錯和支付錯誤區分:402 → handler 失敗拋
X402SignError(具體類型按鏈不同);後續重發後業務接口的報錯(401 / 422 / 5xx)仍然按普通 SDK 異常分類。 viem適配最穩的寫法:evmProvider: walletClient as any會失去類型檢查但兼容性最好;如果想保留類型,用 viem 的.transport.request單獨包一層{ request }對象傳進去。

