buy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesex402 Buy Skill
x402 付费技能
Enable AI agents to autonomously pay for HTTP resources using the x402 payment protocol.
让AI Agent能够使用x402支付协议自主为HTTP资源付费。
Overview
概述
x402 is an open payment standard that enables programmatic payments over HTTP. When an agent requests a paid resource, the server responds with HTTP 402 (Payment Required) containing payment details. The agent signs a payment authorization and retries the request.
x402是一种开放的支付标准,支持通过HTTP实现程序化支付。当Agent请求付费资源时,服务器会返回包含支付详情的HTTP 402(需要付费)响应。Agent签署支付授权后,重新发起请求。
CRITICAL: Pre-Flight Check (Do This First!)
重要提示:预检检查(务必先执行!)
ALWAYS check the endpoint's x402 version BEFORE writing any payment code.
bash
curl -i "https://example.com/api/paid-endpoint"Look at the 402 response to determine which version and packages to use:
在编写任何支付代码之前,务必检查端点的x402版本。
bash
curl -i "https://example.com/api/paid-endpoint"查看402响应以确定要使用的版本和包:
How to Identify Version
版本识别方法
| Check This | v1 (Legacy) | v2 (Current) |
|---|---|---|
| | |
| Network format | | |
| Requirements location | Body only | |
| Payment header to send | | |
| Response header | | |
Example v1 response:
json
{"x402Version":1,"accepts":[{"network":"base","maxAmountRequired":"2000",...}]}Example v2 response:
PAYMENT-REQUIRED: <base64-encoded>
{"x402Version":2,"accepts":[{"network":"eip155:8453","maxAmountRequired":"2000",...}]}| 检查项 | v1(旧版) | v2(当前版) |
|---|---|---|
| | |
| 网络格式 | | |
| 要求位置 | 仅在响应体中 | |
| 需发送的支付请求头 | | |
| 响应头 | | |
v1响应示例:
json
{"x402Version":1,"accepts":[{"network":"base","maxAmountRequired":"2000",...}]}v2响应示例:
PAYMENT-REQUIRED: <base64-encoded>
{"x402Version":2,"accepts":[{"network":"eip155:8453","maxAmountRequired":"2000",...}]}Quick Start
快速开始
1. Setup Wallet
1. 设置钱包
Non-interactive CLI commands (for AI agents):
bash
undefined非交互式CLI命令(适用于AI Agent):
bash
undefinedEVM wallet (Base, Ethereum, Avalanche) - pipes "1" to select EOA
EVM钱包(Base、Ethereum、Avalanche)- 输入"1"选择EOA
echo "1" | npx add-wallet evm
echo "1" | npx add-wallet evm
Solana wallet
Solana钱包
npx add-wallet sol
npx add-wallet sol
Top up with testnet USDC
充值测试网USDC
npx add-wallet topup testnet
This creates a `.env` file with `WALLET_ADDRESS` and `WALLET_PRIVATE_KEY`.npx add-wallet topup testnet
此命令会创建一个包含`WALLET_ADDRESS`和`WALLET_PRIVATE_KEY`的`.env`文件。2. Install Packages (Based on Version)
2. 安装对应版本的包
For v1 endpoints:
bash
npm install x402-fetch viemFor v2 endpoints:
bash
npm install @x402/fetch @x402/evm viem针对v1端点:
bash
npm install x402-fetch viem针对v2端点:
bash
npm install @x402/fetch @x402/evm viemOptional for Solana: npm install @x402/svm @solana/kit @scure/base
Solana可选依赖:npm install @x402/svm @solana/kit @scure/base
undefinedundefined3. Make Paid Requests
3. 发起付费请求
For v1 Endpoints (Legacy)
针对v1端点(旧版)
typescript
import { wrapFetchWithPayment, createSigner, decodeXPaymentResponse } from "x402-fetch";
const privateKey = process.env.WALLET_PRIVATE_KEY as `0x${string}`;
// Use network string from 402 response: "base", "base-sepolia", "solana", etc.
const signer = await createSigner("base", privateKey);
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
const response = await fetchWithPayment("https://api.example.com/paid", { method: "GET" });
const data = await response.json();
// Check payment receipt
const paymentResponse = response.headers.get("x-payment-response");
if (paymentResponse) {
const receipt = decodeXPaymentResponse(paymentResponse);
console.log("Payment settled:", receipt);
}typescript
import { wrapFetchWithPayment, createSigner, decodeXPaymentResponse } from "x402-fetch";
const privateKey = process.env.WALLET_PRIVATE_KEY as `0x${string}`;
// 使用402响应中的网络字符串:"base", "base-sepolia", "solana"等
const signer = await createSigner("base", privateKey);
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
const response = await fetchWithPayment("https://api.example.com/paid", { method: "GET" });
const data = await response.json();
// 检查支付凭证
const paymentResponse = response.headers.get("x-payment-response");
if (paymentResponse) {
const receipt = decodeXPaymentResponse(paymentResponse);
console.log("Payment settled:", receipt);
}For v2 Endpoints (Current)
针对v2端点(当前版)
typescript
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://api.example.com/paid", { method: "GET" });
// Check payment receipt
const paymentResponse = response.headers.get("PAYMENT-RESPONSE");typescript
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://api.example.com/paid", { method: "GET" });
// 检查支付凭证
const paymentResponse = response.headers.get("PAYMENT-RESPONSE");Package Reference
包参考
| Purpose | v1 (Legacy) | v2 (Current) |
|---|---|---|
| Fetch wrapper | | |
| Axios wrapper | | |
| Core types | | |
| EVM support | Built into x402-fetch | |
| Solana support | Built into x402-fetch | |
| 用途 | v1(旧版) | v2(当前版) |
|---|---|---|
| Fetch包装器 | | |
| Axios包装器 | | |
| 核心类型 | | |
| EVM支持 | 内置在x402-fetch中 | |
| Solana支持 | 内置在x402-fetch中 | |
Network Identifiers
网络标识符
| Network | v1 ID | v2 CAIP-2 ID | Environment |
|---|---|---|---|
| Base Mainnet | | | Production |
| Base Sepolia | | | Testnet |
| Avalanche C-Chain | | | Production |
| Avalanche Fuji | | | Testnet |
| Solana Mainnet | | | Production |
| Solana Devnet | | | Testnet |
| 网络 | v1 ID | v2 CAIP-2 ID | 环境 |
|---|---|---|---|
| Base主网 | | | 生产环境 |
| Base Sepolia测试网 | | | 测试环境 |
| Avalanche C-Chain | | | 生产环境 |
| Avalanche Fuji测试网 | | | 测试环境 |
| Solana主网 | | | 生产环境 |
| Solana Devnet测试网 | | | 测试环境 |
USDC Token Addresses
USDC代币地址
| Network | USDC Address |
|---|---|
| Base Mainnet | |
| Base Sepolia | |
| Avalanche | |
| Solana Mainnet | |
| 网络 | USDC地址 |
|---|---|
| Base主网 | |
| Base Sepolia测试网 | |
| Avalanche | |
| Solana主网 | |
Complete Working Examples
完整可用示例
Example 1: Calling a v1 Endpoint
示例1:调用v1端点
typescript
// call-v1-endpoint.ts
import { wrapFetchWithPayment, createSigner, decodeXPaymentResponse } from "x402-fetch";
const privateKey = "0x..." as `0x${string}`; // Your private key
const walletAddress = "0x..."; // Your wallet address
async function main() {
// Step 1: Check what version the endpoint uses
const checkResponse = await fetch("https://example.com/api/data");
if (checkResponse.status === 402) {
const body = await checkResponse.json();
console.log("x402 Version:", body.x402Version);
console.log("Network:", body.accepts[0].network);
console.log("Price:", body.accepts[0].maxAmountRequired, "atomic units");
}
// Step 2: Create signer with v1 network string
const signer = await createSigner("base", privateKey); // Use network from response
// Step 3: Wrap fetch and make paid request
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
const response = await fetchWithPayment("https://example.com/api/data");
const data = await response.json();
console.log("Response:", data);
// Step 4: Check payment receipt
const receipt = response.headers.get("x-payment-response");
if (receipt) {
console.log("Payment settled:", decodeXPaymentResponse(receipt));
}
}
main().catch(console.error);typescript
// call-v1-endpoint.ts
import { wrapFetchWithPayment, createSigner, decodeXPaymentResponse } from "x402-fetch";
const privateKey = "0x..." as `0x${string}`; // 你的私钥
const walletAddress = "0x..."; // 你的钱包地址
async function main() {
// 步骤1:检查端点使用的版本
const checkResponse = await fetch("https://example.com/api/data");
if (checkResponse.status === 402) {
const body = await checkResponse.json();
console.log("x402 Version:", body.x402Version);
console.log("Network:", body.accepts[0].network);
console.log("Price:", body.accepts[0].maxAmountRequired, "atomic units");
}
// 步骤2:使用v1网络字符串创建签名器
const signer = await createSigner("base", privateKey); // 使用响应中的网络
// 步骤3:包装fetch并发起付费请求
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
const response = await fetchWithPayment("https://example.com/api/data");
const data = await response.json();
console.log("Response:", data);
// 步骤4:检查支付凭证
const receipt = response.headers.get("x-payment-response");
if (receipt) {
console.log("Payment settled:", decodeXPaymentResponse(receipt));
}
}
main().catch(console.error);Example 2: Calling a v2 Endpoint
示例2:调用v2端点
typescript
// call-v2-endpoint.ts
import { wrapFetchWithPayment, x402Client, x402HTTPClient } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const privateKey = "0x..." as `0x${string}`;
async function main() {
// Step 1: Check what version the endpoint uses
const checkResponse = await fetch("https://example.com/api/data");
if (checkResponse.status === 402) {
const hasV2Header = checkResponse.headers.get("PAYMENT-REQUIRED");
console.log("Is v2:", !!hasV2Header);
}
// Step 2: Setup v2 client
const signer = privateKeyToAccount(privateKey);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
// Step 3: Make paid request
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://example.com/api/data");
const data = await response.json();
console.log("Response:", data);
// Step 4: Check payment receipt
const receipt = response.headers.get("PAYMENT-RESPONSE");
if (receipt) {
console.log("Payment settled");
}
}
main().catch(console.error);typescript
// call-v2-endpoint.ts
import { wrapFetchWithPayment, x402Client, x402HTTPClient } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const privateKey = "0x..." as `0x${string}`;
async function main() {
// 步骤1:检查端点使用的版本
const checkResponse = await fetch("https://example.com/api/data");
if (checkResponse.status === 402) {
const hasV2Header = checkResponse.headers.get("PAYMENT-REQUIRED");
console.log("Is v2:", !!hasV2Header);
}
// 步骤2:设置v2客户端
const signer = privateKeyToAccount(privateKey);
const client = new x402Client();
registerExactEvmScheme(client, { signer });
// 步骤3:发起付费请求
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://example.com/api/data");
const data = await response.json();
console.log("Response:", data);
// 步骤4:检查支付凭证
const receipt = response.headers.get("PAYMENT-RESPONSE");
if (receipt) {
console.log("Payment settled");
}
}
main().catch(console.error);Service Discovery (Bazaar)
服务发现(Bazaar)
Find x402-enabled services without knowing URLs in advance.
bash
undefined无需提前知道URL即可找到支持x402的服务。
bash
undefinedQuick discovery via curl
通过curl快速发现
curl -s "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?type=http&limit=50" | jq '.items[] | {url: .resource, price: .accepts[0].maxAmountRequired, version: .x402Version}'
undefinedcurl -s "https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources?type=http&limit=50" | jq '.items[] | {url: .resource, price: .accepts[0].maxAmountRequired, version: .x402Version}'
undefinedProgrammatic Discovery
程序化发现
typescript
import { HTTPFacilitatorClient } from "@x402/core/http";
import { withBazaar } from "@x402/extensions";
const facilitatorClient = new HTTPFacilitatorClient({
url: "https://api.cdp.coinbase.com/platform/v2/x402"
});
const client = withBazaar(facilitatorClient);
const response = await client.extensions.discovery.listResources({ type: "http" });
// Filter by price (under $0.01 = 10000 atomic units)
const affordable = response.items.filter(item =>
Number(item.accepts[0].maxAmountRequired) < 10000
);typescript
import { HTTPFacilitatorClient } from "@x402/core/http";
import { withBazaar } from "@x402/extensions";
const facilitatorClient = new HTTPFacilitatorClient({
url: "https://api.cdp.coinbase.com/platform/v2/x402"
});
const client = withBazaar(facilitatorClient);
const response = await client.extensions.discovery.listResources({ type: "http" });
// 按价格筛选(低于0.01美元 = 10000原子单位)
const affordable = response.items.filter(item =>
Number(item.accepts[0].maxAmountRequired) < 10000
);Payment Amounts
支付金额对照表
| Amount (atomic) | USDC Value |
|---|---|
| $0.001 (0.1 cents) |
| $0.002 |
| $0.01 (1 cent) |
| $0.10 (10 cents) |
| $1.00 |
| 原子单位数量 | USDC价值 |
|---|---|
| $0.001(0.1美分) |
| $0.002 |
| $0.01(1美分) |
| $0.10(10美分) |
| $1.00 |
Extracting Endpoint Requirements (Method, Body, Schema)
提取端点要求(方法、请求体、Schema)
Many x402 endpoints include detailed input/output schemas in their 402 response. This tells you:
- What HTTP method to use (GET, POST, etc.)
- What body format (JSON, form-data)
- Required and optional fields
许多x402端点会在402响应中包含详细的输入/输出Schema,这些信息会告诉你:
- 要使用的HTTP方法(GET、POST等)
- 请求体格式(JSON、form-data)
- 必填和可选字段
Step 1: Get the 402 Response
步骤1:获取402响应
bash
undefinedbash
undefinedTry GET first
先尝试GET方法
curl -i "https://example.com/api/endpoint"
curl -i "https://example.com/api/endpoint"
If you get 405 Method Not Allowed, try POST
如果返回405 Method Not Allowed,尝试POST方法
curl -i -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json"
undefinedcurl -i -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json"
undefinedStep 2: Decode and Inspect the Payment Header
步骤2:解码并检查支付请求头
For v2 endpoints, decode the header:
PAYMENT-REQUIREDbash
undefined对于v2端点,解码请求头:
PAYMENT-REQUIREDbash
undefinedExtract and decode the header (save full header value to a file or variable)
提取并解码请求头(将完整的请求头值保存到文件或变量中)
echo "<base64-payment-required-value>" | base64 -d | jq '.'
undefinedecho "<base64-payment-required-value>" | base64 -d | jq '.'
undefinedStep 3: Find the Input Schema
步骤3:查找输入Schema
Look for in the decoded response:
extensions.bazaar.schema.properties.inputjson
{
"x402Version": 2,
"accepts": [...],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http",
"method": "POST", // <-- HTTP method
"bodyType": "json", // <-- Body format
"body": {}
}
},
"schema": {
"properties": {
"input": {
"properties": {
"body": {
"properties": {
"urls": { "type": "array", "items": { "type": "string" } }, // Required field
"text": { "type": "boolean" } // Optional field
},
"required": ["urls"] // <-- Required fields listed here
}
}
}
}
}
}
}
}在解码后的响应中查找:
extensions.bazaar.schema.properties.inputjson
{
"x402Version": 2,
"accepts": [...],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http",
"method": "POST", // <-- HTTP方法
"bodyType": "json", // <-- 请求体格式
"body": {}
}
},
"schema": {
"properties": {
"input": {
"properties": {
"body": {
"properties": {
"urls": { "type": "array", "items": { "type": "string" } }, // 必填字段
"text": { "type": "boolean" } // 可选字段
},
"required": ["urls"] // <-- 必填字段列表
}
}
}
}
}
}
}
}Step 4: Build Your Request
步骤4:构建请求
Based on the schema above:
typescript
const response = await fetchWithPayment("https://example.com/api/endpoint", {
method: "POST", // From info.input.method
headers: { "Content-Type": "application/json" }, // From info.input.bodyType
body: JSON.stringify({
urls: ["https://example.com"], // Required field
text: true // Optional field
})
});基于上面的Schema:
typescript
const response = await fetchWithPayment("https://example.com/api/endpoint", {
method: "POST", // 来自info.input.method
headers: { "Content-Type": "application/json" }, // 来自info.input.bodyType
body: JSON.stringify({
urls: ["https://example.com"], // 必填字段
text: true // 可选字段
})
});Quick Schema Extraction (One-liner)
快速提取Schema(单行命令)
bash
curl -s -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json" | \
jq -r 'if .accepts then . else empty end' 2>/dev/null || \
echo "Check PAYMENT-REQUIRED header for v2"For v2 with header:
bash
curl -si -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json" | \
grep -i "payment-required:" | cut -d' ' -f2 | base64 -d | \
jq '{method: .extensions.bazaar.info.input.method, bodyType: .extensions.bazaar.info.input.bodyType, required: .extensions.bazaar.schema.properties.input.properties.body.required}'bash
curl -s -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json" | \
jq -r 'if .accepts then . else empty end' 2>/dev/null || \
echo "Check PAYMENT-REQUIRED header for v2"针对带请求头的v2端点:
bash
curl -si -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json" | \
grep -i "payment-required:" | cut -d' ' -f2 | base64 -d | \
jq '{method: .extensions.bazaar.info.input.method, bodyType: .extensions.bazaar.info.input.bodyType, required: .extensions.bazaar.schema.properties.input.properties.body.required}'Common Patterns
常见模式
| If you see... | Then use... |
|---|---|
| |
| |
| |
No | Try GET first, then POST if 405 |
| 如果看到... | 则使用... |
|---|---|
| |
| |
| |
无 | 先尝试GET,若返回405再尝试POST |
Setup Checklist
设置检查清单
- Create wallet - Run (non-interactive)
echo "1" | npx add-wallet evm - Note the address - Check for
.envWALLET_ADDRESS - Fund wallet - Send USDC on Base mainnet (or )
npx add-wallet topup testnet - Check endpoint - to see:
curl -i <url>- x402 version (v1 or v2)
- Price (amount field)
- Network (mainnet or testnet)
- If 405, try
curl -i -X POST <url>
- Extract schema - Decode header to find method, body format, required fields
PAYMENT-REQUIRED - Install correct packages - v1: , v2:
x402-fetch@x402/fetch @x402/evm - Use correct code pattern - v1: , v2:
createSigner()registerExactEvmScheme() - Build request - Use method/body from schema, SDK handles 402 → payment → retry
- 创建钱包 - 运行(非交互式)
echo "1" | npx add-wallet evm - 记录钱包地址 - 在文件中查看
.envWALLET_ADDRESS - 为钱包充值 - 在Base主网发送USDC(或运行充值测试网)
npx add-wallet topup testnet - 检查端点 - 运行查看:
curl -i <url>- x402版本(v1或v2)
- 价格(amount字段)
- 网络(主网或测试网)
- 若返回405,尝试
curl -i -X POST <url>
- 提取Schema - 解码请求头,找到方法、请求体格式和必填字段
PAYMENT-REQUIRED - 安装正确的包 - v1使用,v2使用
x402-fetch@x402/fetch @x402/evm - 使用正确的代码模式 - v1用,v2用
createSigner()registerExactEvmScheme() - 构建请求 - 使用Schema中的方法和请求体,SDK会自动处理402→支付→重试流程
Troubleshooting
故障排除
HTTP 405 Method Not Allowed
HTTP 405 Method Not Allowed
The endpoint requires a different HTTP method. Try POST instead of GET:
bash
curl -i -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json"端点需要使用不同的HTTP方法。尝试用POST替代GET:
bash
curl -i -X POST "https://example.com/api/endpoint" -H "Content-Type: application/json""EIP-712 domain parameters required" Error
"EIP-712 domain parameters required" 错误
You're using v2 packages () on a v1 endpoint. Check the 402 response - if , use instead.
@x402/fetchx402Version: 1x402-fetch你正在将v2包()用于v1端点。检查402响应,如果,请改用。
@x402/fetchx402Version: 1x402-fetch"No scheme registered" Error
"No scheme registered" 错误
The network in the 402 response isn't registered. For v2, make sure you called .
registerExactEvmScheme(client, { signer })402响应中的网络未注册。对于v2,确保你已调用。
registerExactEvmScheme(client, { signer })Payment succeeds but response is empty or error
支付成功但响应为空或报错
You might be missing required body fields. Decode the header and check for required fields.
PAYMENT-REQUIREDextensions.bazaar.schema你可能遗漏了必填的请求体字段。解码请求头,检查中的必填字段。
PAYMENT-REQUIREDextensions.bazaar.schemaPayment not going through
支付无法完成
- Check wallet has sufficient USDC balance on the correct network
- Verify you're using the right network (mainnet vs testnet)
- Check the field in the 402 response matches your setup
network
- 检查钱包在对应网络上是否有足够的USDC余额
- 确认你使用的网络正确(主网vs测试网)
- 检查402响应中的字段是否与你的设置匹配
network
Protocol References
协议参考
For detailed protocol schemas, see:
- references/wallet-setup.md
- references/v1-protocol.md
- references/v2-protocol.md
如需详细的协议Schema,请查看:
- references/wallet-setup.md
- references/v1-protocol.md
- references/v2-protocol.md