@wtflabs/x402-server 0.0.1-beta.10 → 0.0.1-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,61 +1,140 @@
1
1
  # @wtflabs/x402-server
2
2
 
3
- Server SDK for the x402 Payment Protocol. Handles payment verification and settlement with automatic token detection.
3
+ 完整的服务端 SDK,用于 x402 支付协议。提供支付验证、结算和自动 Token 检测功能。
4
4
 
5
- ## Features
5
+ ## ✨ 特性
6
6
 
7
- **Simple API** - Just 2 required parameters to get started
8
- **Automatic Token Detection** - Built on `@wtflabs/x402-detector`
9
- **Payment Processing** - Verify and settle payments via `@wtflabs/x402-facilitator`
10
- **Dynamic Requirements** - Create payment requirements on-the-fly
11
- ✅ **Performance Optimized** - Built-in caching, non-blocking initialization
12
- **Framework Middlewares** - Ready-to-use Express and Hono middlewares
13
- ✅ **Zod Validation** - Runtime type safety for all data
14
- **Decoupled Design** - Facilitator and Server are independent
7
+ - 🚀 **简洁 API** - 仅需 2 个必填参数即可开始
8
+ - 🔍 **自动 Token 检测** - 基于 `@wtflabs/x402-detector` 自动识别支付类型
9
+ - 💰 **支付处理** - 通过 `@wtflabs/x402-facilitator` 验证和结算支付
10
+ - **动态需求** - 实时创建支付要求
11
+ - 🎯 **性能优化** - 内置缓存、非阻塞初始化
12
+ - 🔌 **框架中间件** - Express Hono 中间件开箱即用
13
+ - ✅ **Zod 验证** - 运行时类型安全
14
+ - 🔒 **100% 类型安全** - `any` 类型,完整 TypeScript 支持
15
+ - 🎨 **解耦设计** - Facilitator 和 Server 独立运行
15
16
 
16
- ## Installation
17
+ ## 📦 安装
17
18
 
18
19
  ```bash
19
- npm install @wtflabs/x402-server viem
20
+ npm install @wtflabs/x402-server @wtflabs/x402-facilitator viem
20
21
  ```
21
22
 
22
- ## Quick Start
23
+ **可选依赖**(根据框架选择):
24
+ ```bash
25
+ # 使用 Express
26
+ npm install express
27
+
28
+ # 使用 Hono
29
+ npm install hono
30
+ ```
31
+
32
+ ## 🚀 快速开始
33
+
34
+ ### 方式 1:使用中间件(推荐)
23
35
 
24
- ### Option 1: Using Middleware (Easiest)
36
+ #### Express 中间件
25
37
 
26
38
  ```typescript
27
39
  import express from "express";
28
40
  import { createExpressMiddleware, X402Server } from "@wtflabs/x402-server";
29
41
  import { Facilitator } from "@wtflabs/x402-facilitator";
42
+ import { createPublicClient, http } from "viem";
43
+ import { bscTestnet } from "viem/chains";
30
44
 
31
45
  const app = express();
32
46
 
33
- // 1. Create facilitator
47
+ // 1. 创建 viem client
48
+ const client = createPublicClient({
49
+ chain: bscTestnet,
50
+ transport: http(),
51
+ });
52
+
53
+ // 2. 创建 facilitator
34
54
  const facilitator = new Facilitator({
35
55
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
56
+ waitUntil: "confirmed",
36
57
  });
37
58
 
38
- // 2. Create server
59
+ // 3. 创建 server
39
60
  const server = new X402Server({
40
- client: createPublicClient({ chain: bscTestnet, transport: http() }),
61
+ client,
41
62
  facilitator,
42
63
  });
43
64
 
44
- // 3. Create middleware
65
+ // 4. 创建中间件
45
66
  const paymentMiddleware = createExpressMiddleware({
46
67
  server,
47
68
  getToken: () => "0x25d066c4C68C8A6332DfDB4230263608305Ca991", // USDC
48
- getAmount: () => "1000",
69
+ getAmount: () => "1000000", // 1 USDC (6 decimals)
49
70
  });
50
71
 
51
- // 4. Use middleware
52
- app.post("/api/resource", paymentMiddleware, (req, res) => {
72
+ // 5. 使用中间件
73
+ app.post("/api/premium", paymentMiddleware, (req, res) => {
53
74
  const { payer, txHash } = req.x402!;
54
- res.json({ data: "resource", payer, txHash });
75
+ res.json({
76
+ success: true,
77
+ data: "Premium content",
78
+ payer,
79
+ txHash,
80
+ });
81
+ });
82
+
83
+ app.listen(3000, () => {
84
+ console.log("Server running on http://localhost:3000");
85
+ });
86
+ ```
87
+
88
+ #### Hono 中间件
89
+
90
+ ```typescript
91
+ import { Hono } from "hono";
92
+ import { createHonoMiddleware, X402Server } from "@wtflabs/x402-server";
93
+ import { Facilitator } from "@wtflabs/x402-facilitator";
94
+ import { createPublicClient, http } from "viem";
95
+ import { bscTestnet } from "viem/chains";
96
+
97
+ const app = new Hono();
98
+
99
+ // 1. 创建 viem client
100
+ const client = createPublicClient({
101
+ chain: bscTestnet,
102
+ transport: http(),
103
+ });
104
+
105
+ // 2. 创建 facilitator
106
+ const facilitator = new Facilitator({
107
+ recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
108
+ });
109
+
110
+ // 3. 创建 server
111
+ const server = new X402Server({
112
+ client,
113
+ facilitator,
55
114
  });
115
+
116
+ // 4. 创建中间件
117
+ const paymentMiddleware = createHonoMiddleware({
118
+ server,
119
+ getToken: () => "0x25d066c4C68C8A6332DfDB4230263608305Ca991",
120
+ getAmount: () => "1000000",
121
+ });
122
+
123
+ // 5. 使用中间件
124
+ app.post("/api/premium", paymentMiddleware, (c) => {
125
+ const x402 = c.get("x402") as { payer: string; txHash: string };
126
+ return c.json({
127
+ success: true,
128
+ data: "Premium content",
129
+ payer: x402.payer,
130
+ txHash: x402.txHash,
131
+ });
132
+ });
133
+
134
+ export default app;
56
135
  ```
57
136
 
58
- ### Option 2: Manual Processing
137
+ ### 方式 2:手动处理
59
138
 
60
139
  ```typescript
61
140
  import { X402Server } from "@wtflabs/x402-server";
@@ -63,37 +142,42 @@ import { Facilitator } from "@wtflabs/x402-facilitator";
63
142
  import { createPublicClient, http } from "viem";
64
143
  import { bscTestnet } from "viem/chains";
65
144
 
66
- // 1. Create facilitator
145
+ // 1. 创建 viem client
146
+ const client = createPublicClient({
147
+ chain: bscTestnet,
148
+ transport: http(),
149
+ });
150
+
151
+ // 2. 创建 facilitator
67
152
  const facilitator = new Facilitator({
68
153
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
69
154
  waitUntil: "confirmed",
70
155
  });
71
156
 
72
- // 2. Create server instance
157
+ // 3. 创建 server
73
158
  const server = new X402Server({
74
- client: createPublicClient({
75
- chain: bscTestnet,
76
- transport: http(),
77
- }),
159
+ client,
78
160
  facilitator,
161
+ network: "bsc-testnet", // 可选
79
162
  });
80
163
 
81
- // 3. Optional: Pre-warm cache (non-blocking)
164
+ // 4. 可选:预热缓存(非阻塞)
82
165
  server.initialize([
83
166
  "0x25d066c4C68C8A6332DfDB4230263608305Ca991", // USDC
84
167
  ]);
85
168
 
86
- // 4. Handle payment in your route
169
+ // 5. 在路由中处理支付
87
170
  app.post("/api/resource", async (req, res) => {
88
- // Create payment requirements
171
+ // 创建支付要求
89
172
  const requirements = await server.createRequirements({
90
173
  asset: "0x25d066c4C68C8A6332DfDB4230263608305Ca991",
91
- maxAmountRequired: "1000", // wei
174
+ maxAmountRequired: "1000000",
175
+ description: "Premium API access",
92
176
  });
93
177
 
94
- // Process payment (parse → verify → settle)
178
+ // 处理支付(parse → verify → settle
95
179
  const result = await server.process(
96
- req.headers["x-payment"],
180
+ req.headers["x-payment"] as string,
97
181
  requirements
98
182
  );
99
183
 
@@ -101,108 +185,131 @@ app.post("/api/resource", async (req, res) => {
101
185
  return res.status(402).json(result.response);
102
186
  }
103
187
 
104
- // Payment successful!
188
+ // 支付成功
105
189
  res.json({
106
190
  message: "Access granted",
107
191
  payer: result.data.payer,
108
192
  txHash: result.data.txHash,
109
- data: "your protected resource",
193
+ data: "Your protected resource",
110
194
  });
111
195
  });
112
196
  ```
113
197
 
114
- ## API Reference
198
+ ## 📚 API 参考
115
199
 
116
- ### Constructor
200
+ ### X402Server 构造函数
117
201
 
118
202
  ```typescript
119
203
  const server = new X402Server(config: X402ServerConfig)
120
204
  ```
121
205
 
122
- **Required:**
123
- - `client: PublicClient` - Viem PublicClient instance
124
- - `facilitator: Facilitator` - Facilitator instance (handles payment processing)
206
+ #### 参数
207
+
208
+ **必填:**
209
+ - `client: PublicClient` - Viem PublicClient 实例
210
+ - `facilitator: Facilitator` - Facilitator 实例(处理支付)
211
+
212
+ **可选:**
213
+ - `network?: string` - 网络名称(默认从 client 自动检测)
125
214
 
126
- **Optional:**
127
- - `network?: string` - Network name (auto-detected from client if not provided)
215
+ #### 示例
128
216
 
129
- **Example:**
130
217
  ```typescript
131
218
  import { Facilitator } from "@wtflabs/x402-facilitator";
132
219
  import { createPublicClient, http } from "viem";
133
220
  import { bscTestnet } from "viem/chains";
134
221
 
135
- // 1. Create viem client
136
222
  const client = createPublicClient({
137
223
  chain: bscTestnet,
138
224
  transport: http(),
139
225
  });
140
226
 
141
- // 2. Create facilitator first
142
227
  const facilitator = new Facilitator({
143
228
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
144
- waitUntil: "confirmed", // optional: "confirmed" | "finalized"
229
+ waitUntil: "confirmed",
145
230
  });
146
231
 
147
- // 3. Create server with client and facilitator
148
232
  const server = new X402Server({
149
233
  client,
150
234
  facilitator,
151
- network: "bsc-testnet", // optional
235
+ network: "bsc-testnet", // 可选
152
236
  });
153
237
  ```
154
238
 
155
- ### Methods
239
+ ### 核心方法
156
240
 
157
241
  #### `initialize(tokens: string[]): Promise<InitResult>`
158
242
 
159
- Pre-warm the token detection cache. Non-blocking, can run in background.
243
+ 预热 Token 检测缓存。非阻塞,可以在后台运行。
160
244
 
161
245
  ```typescript
162
- // Wait for initialization
246
+ // 等待初始化完成
163
247
  await server.initialize([tokenAddress]);
164
248
 
165
- // Or run in background
249
+ // 或在后台运行
166
250
  server.initialize([tokenAddress]).then(result => {
167
- if (result.success) console.log("✅ Cache ready");
251
+ if (result.success) {
252
+ console.log("✅ Cache ready");
253
+ }
168
254
  });
169
255
  ```
170
256
 
171
257
  #### `createRequirements(config): Promise<PaymentRequirements>`
172
258
 
173
- Create payment requirements. Supports dynamic amounts and auto-detection.
259
+ 创建支付要求。支持动态金额和自动检测。
174
260
 
175
- ```typescript
176
- const requirements = await server.createRequirements({
177
- // Required
178
- asset: "0x...", // Token contract address
179
- maxAmountRequired: "1000", // Amount in wei (as string)
261
+ **参数:**
180
262
 
181
- // Optional - network and scheme
182
- network?: "bsc-testnet", // Network name (overrides server config)
183
- scheme?: "exact", // Payment scheme (currently only "exact")
184
- outputSchema?: {}, // Output schema (for validation)
185
-
186
- // Optional - payment type
187
- paymentType?: "permit" | "eip3009" | "permit2" | "auto",
263
+ ```typescript
264
+ interface CreateRequirementsConfig {
265
+ // 必填
266
+ asset: string; // Token 合约地址
267
+ maxAmountRequired: string; // 金额(wei,字符串格式)
268
+
269
+ // 可选 - 网络和方案
270
+ network?: string; // 网络名称(覆盖全局配置)
271
+ scheme?: "exact"; // 支付方案(目前仅支持 "exact")
272
+ outputSchema?: Record<string, unknown>;
273
+
274
+ // 可选 - 支付类型
275
+ paymentType?: "permit" | "eip3009" | "permit2" | "auto";
276
+
277
+ // 可选 - 资源描述
278
+ resource?: string; // 资源 URL
279
+ description?: string; // 描述
280
+ mimeType?: string; // MIME 类型
281
+ maxTimeoutSeconds?: number; // 超时时间(秒)
282
+
283
+ // 可选 - 额外元数据
284
+ extra?: Record<string, unknown>;
285
+
286
+ // 可选 - 性能控制
287
+ autoDetect?: boolean; // false = 快速模式(需手动指定 paymentType)
288
+ }
289
+ ```
188
290
 
189
- // Optional - resource description
190
- resource?: "https://api.example.com/data",
191
- description?: "Premium API access",
192
- mimeType?: "application/json",
193
- maxTimeoutSeconds?: 300,
291
+ **示例:**
194
292
 
195
- // Optional - extra metadata
196
- extra?: {}, // Additional metadata
293
+ ```typescript
294
+ // 自动检测(默认)
295
+ const requirements = await server.createRequirements({
296
+ asset: "0x25d066c4C68C8A6332DfDB4230263608305Ca991",
297
+ maxAmountRequired: "1000000",
298
+ description: "Premium access",
299
+ });
197
300
 
198
- // Optional - performance
199
- autoDetect?: true, // Set to false for fast mode (requires manual paymentType)
301
+ // 快速模式(跳过检测)
302
+ const requirements = await server.createRequirements({
303
+ asset: "0x25d066c4C68C8A6332DfDB4230263608305Ca991",
304
+ maxAmountRequired: "1000000",
305
+ paymentType: "permit",
306
+ autoDetect: false, // <1ms
200
307
  });
201
308
  ```
202
309
 
203
310
  #### `process(paymentHeader, requirements): Promise<ProcessResult>`
204
311
 
205
- Complete payment processing (parse verifysettle).
312
+ 完整的支付处理流程(解析验证结算)。
206
313
 
207
314
  ```typescript
208
315
  const result = await server.process(
@@ -215,20 +322,22 @@ if (result.success) {
215
322
  console.log("TxHash:", result.data.txHash);
216
323
  } else {
217
324
  console.log("Error:", result.response.error);
218
- // Return 402 with result.response
325
+ // 返回 402 状态码和 result.response
219
326
  }
220
327
  ```
221
328
 
222
- #### Advanced: Step-by-Step Processing
329
+ #### 分步处理(高级用法)
330
+
331
+ 如需更细粒度的控制,可以分步处理:
223
332
 
224
333
  ```typescript
225
- // 1. Parse payment header
334
+ // 1. 解析支付头
226
335
  const parsed = server.parse(paymentHeader, requirements);
227
336
  if (!parsed.success) {
228
337
  return res.status(402).json(parsed.response402);
229
338
  }
230
339
 
231
- // 2. Verify payment
340
+ // 2. 验证支付
232
341
  const verified = await server.verify(parsed.data);
233
342
  if (!verified.success) {
234
343
  return res.status(402).json(
@@ -237,7 +346,7 @@ if (!verified.success) {
237
346
  }
238
347
  console.log("Payer:", verified.payer);
239
348
 
240
- // 3. Settle payment (optional - you can skip this for verify-only mode)
349
+ // 3. 结算支付(可选 - 仅验证模式可跳过)
241
350
  const settled = await server.settle(parsed.data);
242
351
  if (!settled.success) {
243
352
  return res.status(402).json(
@@ -247,53 +356,59 @@ if (!settled.success) {
247
356
  console.log("TxHash:", settled.txHash);
248
357
  ```
249
358
 
250
- ### Utility Methods
359
+ ### 工具方法
251
360
 
252
361
  ```typescript
253
- // Generate 402 response
362
+ // 生成 402 响应
254
363
  const response402 = server.get402Response(requirements, error?);
255
364
 
256
- // Clear token cache
257
- await server.clearCache(tokenAddress?); // specific or all
365
+ // 清除 Token 缓存
366
+ await server.clearCache(tokenAddress?); // 指定地址或清除全部
258
367
 
259
- // Get cache stats
368
+ // 获取缓存统计
260
369
  const stats = server.getCacheStats();
261
370
  console.log(stats.size, stats.keys);
262
371
 
263
- // Get underlying instances (for advanced usage)
372
+ // 获取底层实例(高级用法)
264
373
  const facilitator = server.getFacilitator();
265
374
  const detector = server.getDetector();
266
375
  const client = server.getClient();
267
376
  ```
268
377
 
269
- ## Usage Examples
378
+ ## 💡 使用示例
270
379
 
271
- ### Example 1: Fixed Amount
380
+ ### 示例 1: 固定金额
272
381
 
273
382
  ```typescript
383
+ import express from "express";
274
384
  import { X402Server } from "@wtflabs/x402-server";
275
385
  import { Facilitator } from "@wtflabs/x402-facilitator";
276
386
 
277
- // 1. Create facilitator
387
+ const app = express();
388
+
389
+ // 创建 facilitator
278
390
  const facilitator = new Facilitator({
279
391
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
280
392
  });
281
393
 
282
- // 2. Create server
394
+ // 创建 server
283
395
  const server = new X402Server({ client, facilitator });
284
396
 
285
- // 3. Pre-warm cache (optional)
397
+ // 预热缓存(可选)
286
398
  await server.initialize(["0xUSDC"]);
287
399
 
288
- // 4. Fixed requirements
400
+ // 固定要求
289
401
  const requirements = await server.createRequirements({
290
402
  asset: "0xUSDC",
291
- maxAmountRequired: "1000",
403
+ maxAmountRequired: "1000000",
292
404
  description: "Access to premium API",
293
405
  });
294
406
 
295
407
  app.post("/premium-api", async (req, res) => {
296
- const result = await server.process(req.headers["x-payment"], requirements);
408
+ const result = await server.process(
409
+ req.headers["x-payment"] as string,
410
+ requirements
411
+ );
297
412
 
298
413
  if (!result.success) {
299
414
  return res.status(402).json(result.response);
@@ -303,57 +418,60 @@ app.post("/premium-api", async (req, res) => {
303
418
  });
304
419
  ```
305
420
 
306
- ### Example 2: Dynamic Pricing
421
+ ### 示例 2: 动态定价
307
422
 
308
423
  ```typescript
309
424
  app.post("/api/compute", async (req, res) => {
310
425
  const { complexity } = req.body;
311
426
 
312
- // Calculate price based on complexity
427
+ // 根据复杂度计算价格
313
428
  const price = calculatePrice(complexity);
314
429
 
315
- // Dynamic requirements
430
+ // 动态创建要求
316
431
  const requirements = await server.createRequirements({
317
432
  asset: "0xUSDC",
318
433
  maxAmountRequired: price,
319
- description: `Compute task (${complexity})`,
434
+ description: `Compute task (complexity: ${complexity})`,
320
435
  });
321
436
 
322
- const result = await server.process(req.headers["x-payment"], requirements);
437
+ const result = await server.process(
438
+ req.headers["x-payment"] as string,
439
+ requirements
440
+ );
323
441
 
324
442
  if (!result.success) {
325
443
  return res.status(402).json(result.response);
326
444
  }
327
445
 
328
- // Execute computation
446
+ // 执行计算
329
447
  const computeResult = await performComputation(complexity);
330
448
  res.json({ result: computeResult, paid: price });
331
449
  });
332
450
  ```
333
451
 
334
- ### Example 3: Multiple Tokens
452
+ ### 示例 3: Token 支持
335
453
 
336
454
  ```typescript
337
- import { X402Server } from "@wtflabs/x402-server";
338
- import { Facilitator } from "@wtflabs/x402-facilitator";
339
-
340
- // 1. Create facilitator
341
- const facilitator = new Facilitator({
342
- recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
343
- });
344
-
345
- // 2. Create server
346
455
  const server = new X402Server({ client, facilitator });
347
456
 
348
- // 3. Pre-warm multiple tokens
457
+ // 预热多个 Token
349
458
  await server.initialize(["0xUSDC", "0xDAI", "0xUSDT"]);
350
459
 
351
460
  app.get("/premium-api", async (req, res) => {
352
- // Return multiple payment options
461
+ // 返回多个支付选项
353
462
  const accepts = await Promise.all([
354
- server.createRequirements({ asset: "0xUSDC", maxAmountRequired: "1000" }),
355
- server.createRequirements({ asset: "0xDAI", maxAmountRequired: "1000" }),
356
- server.createRequirements({ asset: "0xUSDT", maxAmountRequired: "1000" }),
463
+ server.createRequirements({
464
+ asset: "0xUSDC",
465
+ maxAmountRequired: "1000000"
466
+ }),
467
+ server.createRequirements({
468
+ asset: "0xDAI",
469
+ maxAmountRequired: "1000000000000000000"
470
+ }),
471
+ server.createRequirements({
472
+ asset: "0xUSDT",
473
+ maxAmountRequired: "1000000"
474
+ }),
357
475
  ]);
358
476
 
359
477
  res.status(402).json({
@@ -363,39 +481,51 @@ app.get("/premium-api", async (req, res) => {
363
481
  });
364
482
 
365
483
  app.post("/premium-api", async (req, res) => {
366
- // User pays with their chosen token
367
- const parsed = server.parse(req.headers["x-payment"], accepts[0]);
484
+ // 用户使用选定的 Token 支付
485
+ const parsed = server.parse(
486
+ req.headers["x-payment"] as string,
487
+ accepts[0]
488
+ );
489
+
368
490
  if (!parsed.success) {
369
491
  return res.status(402).json(parsed.response402);
370
492
  }
371
493
 
372
- // Detect which token was used
494
+ // 检测使用的 Token
373
495
  const tokenUsed = parsed.data.payload.payload.authorization.token;
374
496
 
375
- // Create matching requirements
497
+ // 创建匹配的要求
376
498
  const requirements = await server.createRequirements({
377
499
  asset: tokenUsed,
378
- maxAmountRequired: "1000",
500
+ maxAmountRequired: "1000000",
379
501
  });
380
502
 
381
- const result = await server.process(req.headers["x-payment"], requirements);
382
- // ...
503
+ const result = await server.process(
504
+ req.headers["x-payment"] as string,
505
+ requirements
506
+ );
507
+
508
+ if (!result.success) {
509
+ return res.status(402).json(result.response);
510
+ }
511
+
512
+ res.json({ data: "premium content" });
383
513
  });
384
514
  ```
385
515
 
386
- ### Example 4: Fast Mode (Skip Detection)
516
+ ### 示例 4: 快速模式(跳过检测)
387
517
 
388
518
  ```typescript
389
- // For maximum performance, skip auto-detection
519
+ // 为获得最大性能,跳过自动检测
390
520
  const requirements = await server.createRequirements({
391
521
  asset: "0xUSDC",
392
- maxAmountRequired: "1000",
393
- paymentType: "permit", // Manually specify
394
- autoDetect: false, // Skip detection (<1ms)
522
+ maxAmountRequired: "1000000",
523
+ paymentType: "permit", // 手动指定
524
+ autoDetect: false, // 跳过检测 (<1ms)
395
525
  });
396
526
  ```
397
527
 
398
- ## Framework Integration
528
+ ## 🔌 框架集成
399
529
 
400
530
  ### Express
401
531
 
@@ -408,27 +538,27 @@ import { bscTestnet } from "viem/chains";
408
538
 
409
539
  const app = express();
410
540
 
411
- // Create client
412
541
  const client = createPublicClient({
413
542
  chain: bscTestnet,
414
543
  transport: http(),
415
544
  });
416
545
 
417
- // Create facilitator
418
546
  const facilitator = new Facilitator({
419
547
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
420
548
  });
421
549
 
422
- // Create server
423
550
  const server = new X402Server({ client, facilitator });
424
551
 
425
552
  app.post("/api/resource", async (req, res) => {
426
553
  const requirements = await server.createRequirements({
427
554
  asset: "0xUSDC",
428
- maxAmountRequired: "1000",
555
+ maxAmountRequired: "1000000",
429
556
  });
430
557
 
431
- const result = await server.process(req.headers["x-payment"], requirements);
558
+ const result = await server.process(
559
+ req.headers["x-payment"] as string,
560
+ requirements
561
+ );
432
562
 
433
563
  if (!result.success) {
434
564
  return res.status(402).json(result.response);
@@ -449,27 +579,27 @@ import { bscTestnet } from "viem/chains";
449
579
 
450
580
  const app = new Hono();
451
581
 
452
- // Create client
453
582
  const client = createPublicClient({
454
583
  chain: bscTestnet,
455
584
  transport: http(),
456
585
  });
457
586
 
458
- // Create facilitator
459
587
  const facilitator = new Facilitator({
460
588
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
461
589
  });
462
590
 
463
- // Create server
464
591
  const server = new X402Server({ client, facilitator });
465
592
 
466
593
  app.post("/api/resource", async (c) => {
467
594
  const requirements = await server.createRequirements({
468
595
  asset: "0xUSDC",
469
- maxAmountRequired: "1000",
596
+ maxAmountRequired: "1000000",
470
597
  });
471
598
 
472
- const result = await server.process(c.req.header("x-payment"), requirements);
599
+ const result = await server.process(
600
+ c.req.header("x-payment"),
601
+ requirements
602
+ );
473
603
 
474
604
  if (!result.success) {
475
605
  return c.json(result.response, 402);
@@ -479,7 +609,7 @@ app.post("/api/resource", async (c) => {
479
609
  });
480
610
  ```
481
611
 
482
- ### Next.js API Route
612
+ ### Next.js App Router
483
613
 
484
614
  ```typescript
485
615
  import { X402Server } from "@wtflabs/x402-server";
@@ -488,24 +618,21 @@ import { NextRequest } from "next/server";
488
618
  import { createPublicClient, http } from "viem";
489
619
  import { bscTestnet } from "viem/chains";
490
620
 
491
- // Create client
492
621
  const client = createPublicClient({
493
622
  chain: bscTestnet,
494
623
  transport: http(),
495
624
  });
496
625
 
497
- // Create facilitator
498
626
  const facilitator = new Facilitator({
499
627
  recipientAddress: "0x5D06b8145D908DDb7ca116664Fcf113ddaA4d6F3",
500
628
  });
501
629
 
502
- // Create server
503
630
  const server = new X402Server({ client, facilitator });
504
631
 
505
632
  export async function POST(req: NextRequest) {
506
633
  const requirements = await server.createRequirements({
507
634
  asset: "0xUSDC",
508
- maxAmountRequired: "1000",
635
+ maxAmountRequired: "1000000",
509
636
  });
510
637
 
511
638
  const result = await server.process(
@@ -521,110 +648,452 @@ export async function POST(req: NextRequest) {
521
648
  }
522
649
  ```
523
650
 
524
- ## Performance
651
+ ## 🎯 中间件详细文档
525
652
 
526
- | Operation | First Call | Cached Call |
527
- |-----------|-----------|-------------|
528
- | `createRequirements(autoDetect: true)` | 2-5s | <1ms |
529
- | `createRequirements(autoDetect: false)` | <1ms | <1ms |
530
- | `process()` | 2-5s + network | <1ms + network |
653
+ ### Express 中间件
531
654
 
532
- **Tips:**
533
- - Use `initialize()` on startup to pre-warm cache
534
- - Set `autoDetect: false` for maximum speed (requires manual `paymentType`)
535
- - Cache persists for the lifetime of the server instance
655
+ #### 基础用法
536
656
 
537
- ## Error Handling
657
+ ```typescript
658
+ import { createExpressMiddleware } from "@wtflabs/x402-server";
659
+
660
+ const middleware = createExpressMiddleware({
661
+ server,
662
+ getToken: (req) => req.body.token || "0xUSDC",
663
+ getAmount: (req) => calculatePrice(req.body),
664
+ });
665
+
666
+ app.post("/api", middleware, (req, res) => {
667
+ const { payer, txHash } = req.x402!;
668
+ res.json({ data: "resource", payer, txHash });
669
+ });
670
+ ```
671
+
672
+ #### 高级配置
538
673
 
539
674
  ```typescript
540
- const result = await server.process(paymentHeader, requirements);
675
+ const middleware = createExpressMiddleware({
676
+ server,
677
+
678
+ // 获取 token 地址
679
+ getToken: (req) => req.query.token as string || "0xUSDC",
680
+
681
+ // 获取金额
682
+ getAmount: (req) => {
683
+ const { complexity } = req.body;
684
+ return calculateDynamicPrice(complexity);
685
+ },
686
+
687
+ // 可选:额外配置
688
+ getConfig: (req) => ({
689
+ description: `API call for user ${req.user?.id}`,
690
+ resource: req.url,
691
+ }),
692
+
693
+ // 可选:自定义错误处理
694
+ onError: (error, req, res) => {
695
+ console.error("Payment error:", error);
696
+ res.status(500).json({ error: error.message });
697
+ },
698
+
699
+ // 可选:自定义 402 响应
700
+ on402: (req, res, response402) => {
701
+ console.log("Payment required for:", req.url);
702
+ res.status(402).json(response402);
703
+ },
704
+
705
+ // 可选:支付成功回调
706
+ onPaymentSuccess: async (req, payer, txHash) => {
707
+ await logPayment(payer, txHash);
708
+ console.log(`Payment received from ${payer}`);
709
+ },
710
+ });
711
+ ```
541
712
 
542
- if (!result.success) {
543
- // 402 response with error details
544
- console.log(result.response.error);
545
- return res.status(402).json(result.response);
713
+ #### 类型定义
714
+
715
+ ```typescript
716
+ import type {
717
+ ExpressRequest,
718
+ ExpressResponse,
719
+ ExpressNextFunction,
720
+ ExpressMiddleware
721
+ } from "@wtflabs/x402-server";
722
+
723
+ // ExpressRequest 接口
724
+ interface ExpressRequest {
725
+ headers: Record<string, string | string[] | undefined>;
726
+ body?: unknown;
727
+ params?: Record<string, string>;
728
+ query?: Record<string, string | string[] | undefined>;
729
+ x402?: {
730
+ payer: string;
731
+ txHash: string;
732
+ };
733
+ }
734
+
735
+ // ExpressResponse 接口
736
+ interface ExpressResponse {
737
+ status(code: number): this;
738
+ json(body: unknown): this;
546
739
  }
547
740
 
548
- // Success!
549
- console.log(result.data.payer);
550
- console.log(result.data.txHash);
741
+ // 中间件类型
742
+ type ExpressMiddleware = (
743
+ req: ExpressRequest,
744
+ res: ExpressResponse,
745
+ next: ExpressNextFunction
746
+ ) => void | Promise<void>;
551
747
  ```
552
748
 
553
- ## TypeScript Support
749
+ ### Hono 中间件
554
750
 
555
- Full TypeScript support with comprehensive type definitions:
751
+ #### 基础用法
752
+
753
+ ```typescript
754
+ import { createHonoMiddleware } from "@wtflabs/x402-server";
755
+
756
+ const middleware = createHonoMiddleware({
757
+ server,
758
+ getToken: (c) => c.req.query("token") || "0xUSDC",
759
+ getAmount: async (c) => {
760
+ const body = await c.req.json();
761
+ return calculatePrice(body.complexity);
762
+ },
763
+ });
764
+
765
+ app.post("/api", middleware, (c) => {
766
+ const x402 = c.get("x402") as { payer: string; txHash: string };
767
+ return c.json({ data: "resource", payer: x402.payer });
768
+ });
769
+ ```
770
+
771
+ #### 高级配置
772
+
773
+ ```typescript
774
+ const middleware = createHonoMiddleware({
775
+ server,
776
+
777
+ // 获取 token 地址
778
+ getToken: (c) => c.req.query("token") || "0xUSDC",
779
+
780
+ // 获取金额
781
+ getAmount: async (c) => {
782
+ const body = await c.req.json<{ complexity: number }>();
783
+ return calculateDynamicPrice(body.complexity);
784
+ },
785
+
786
+ // 可选:额外配置
787
+ getConfig: async (c) => {
788
+ const body = await c.req.json();
789
+ return {
790
+ description: `API call with complexity ${body.complexity}`,
791
+ };
792
+ },
793
+
794
+ // 可选:自定义错误处理
795
+ onError: (error, c) => {
796
+ console.error("Payment error:", error);
797
+ return c.json({ error: error.message }, 500);
798
+ },
799
+
800
+ // 可选:自定义 402 响应
801
+ on402: (c, response402) => {
802
+ console.log("Payment required");
803
+ return c.json(response402, 402);
804
+ },
805
+
806
+ // 可选:支付成功回调
807
+ onPaymentSuccess: async (c, payer, txHash) => {
808
+ await logPayment(payer, txHash);
809
+ console.log(`Payment received from ${payer}`);
810
+ },
811
+ });
812
+ ```
813
+
814
+ #### 类型定义
815
+
816
+ ```typescript
817
+ import type {
818
+ HonoContext,
819
+ HonoRequest,
820
+ HonoNext,
821
+ HonoMiddlewareHandler
822
+ } from "@wtflabs/x402-server";
823
+
824
+ // HonoRequest 接口
825
+ interface HonoRequest {
826
+ header(name: string): string | undefined;
827
+ json<T = unknown>(): Promise<T>;
828
+ query(name: string): string | undefined;
829
+ }
830
+
831
+ // HonoContext 接口
832
+ interface HonoContext {
833
+ req: HonoRequest;
834
+ json(body: unknown, status?: number): Response;
835
+ set(key: string, value: unknown): void;
836
+ get(key: string): unknown;
837
+ }
838
+
839
+ // 中间件类型
840
+ type HonoMiddlewareHandler = (
841
+ c: HonoContext,
842
+ next: HonoNext
843
+ ) => Promise<Response | void>;
844
+ ```
845
+
846
+ ## 🎨 TypeScript 类型
847
+
848
+ ### 完整类型导出
556
849
 
557
850
  ```typescript
558
851
  import type {
852
+ // 配置
559
853
  X402ServerConfig,
560
854
  CreateRequirementsConfig,
855
+
856
+ // 数据结构
561
857
  PaymentRequirements,
562
- ProcessResult,
858
+ PaymentPayload,
859
+ Response402,
860
+ ParsedPayment,
861
+
862
+ // 结果类型
563
863
  InitResult,
864
+ ProcessResult,
865
+ ParseResult,
866
+ VerifyResult,
867
+ SettleResult,
868
+
869
+ // 中间件类型
870
+ ExpressRequest,
871
+ ExpressResponse,
872
+ ExpressNextFunction,
873
+ ExpressMiddleware,
874
+ ExpressMiddlewareOptions,
875
+
876
+ HonoContext,
877
+ HonoRequest,
878
+ HonoNext,
879
+ HonoMiddlewareHandler,
880
+ HonoMiddlewareOptions,
881
+
882
+ // Facilitator 类型
883
+ WaitUntil,
564
884
  } from "@wtflabs/x402-server";
565
885
  ```
566
886
 
567
- ## Middlewares
887
+ ### Zod Schema 导出
568
888
 
569
- ### Express Middleware
889
+ 所有类型都有对应的 Zod schema,用于运行时验证:
570
890
 
571
891
  ```typescript
572
- import { createExpressMiddleware } from "@wtflabs/x402-server";
892
+ import {
893
+ CreateRequirementsConfigSchema,
894
+ PaymentRequirementsSchema,
895
+ PaymentPayloadSchema,
896
+ Response402Schema,
897
+ InitResultSchema,
898
+ ProcessResultSchema,
899
+ ParseResultSchema,
900
+ VerifyResultSchema,
901
+ SettleResultSchema,
902
+ ParsedPaymentSchema,
903
+ } from "@wtflabs/x402-server";
573
904
 
574
- const middleware = createExpressMiddleware({
575
- server,
576
- getToken: (req) => req.body.token,
577
- getAmount: (req) => calculatePrice(req.body),
578
- onPaymentSuccess: async (req, payer, txHash) => {
579
- console.log(`Payment from ${payer}: ${txHash}`);
580
- },
581
- });
905
+ // 使用 schema 验证
906
+ const validated = CreateRequirementsConfigSchema.parse(config);
907
+ ```
582
908
 
583
- app.post("/api", middleware, (req, res) => {
584
- const { payer, txHash } = req.x402!;
585
- res.json({ data: "resource", payer, txHash });
909
+ ## 性能优化
910
+
911
+ ### 性能指标
912
+
913
+ | 操作 | 首次调用 | 缓存调用 |
914
+ |------|---------|---------|
915
+ | `createRequirements(autoDetect: true)` | 2-5s | <1ms |
916
+ | `createRequirements(autoDetect: false)` | <1ms | <1ms |
917
+ | `process()` | 2-5s + 网络 | <1ms + 网络 |
918
+
919
+ ### 优化技巧
920
+
921
+ #### 1. 预热缓存
922
+
923
+ ```typescript
924
+ // 服务启动时预热
925
+ await server.initialize([
926
+ "0xUSDC",
927
+ "0xDAI",
928
+ "0xUSDT",
929
+ ]);
930
+ ```
931
+
932
+ #### 2. 快速模式
933
+
934
+ ```typescript
935
+ // 跳过自动检测以获得最大性能
936
+ const requirements = await server.createRequirements({
937
+ asset: "0xUSDC",
938
+ maxAmountRequired: "1000000",
939
+ paymentType: "permit",
940
+ autoDetect: false, // <1ms
586
941
  });
587
942
  ```
588
943
 
589
- ### Hono Middleware
944
+ #### 3. 复用 Requirements
590
945
 
591
946
  ```typescript
592
- import { createHonoMiddleware } from "@wtflabs/x402-server";
947
+ // 对于固定金额的 API,可以复用 requirements
948
+ const cachedRequirements = await server.createRequirements({
949
+ asset: "0xUSDC",
950
+ maxAmountRequired: "1000000",
951
+ });
593
952
 
594
- const middleware = createHonoMiddleware({
595
- server,
596
- getToken: async (c) => (await c.req.json()).token,
597
- getAmount: async (c) => calculatePrice(await c.req.json()),
598
- onPaymentSuccess: async (c, payer, txHash) => {
599
- console.log(`Payment from ${payer}: ${txHash}`);
600
- },
953
+ // 在多个请求中复用
954
+ app.post("/api", async (req, res) => {
955
+ const result = await server.process(
956
+ req.headers["x-payment"] as string,
957
+ cachedRequirements
958
+ );
959
+ // ...
601
960
  });
961
+ ```
602
962
 
603
- app.post("/api", middleware, (c) => {
604
- const x402 = c.get("x402")!;
605
- return c.json({ data: "resource", payer: x402.payer });
963
+ #### 4. 后台初始化
964
+
965
+ ```typescript
966
+ // 不阻塞服务启动
967
+ server.initialize([tokenAddress]).then(result => {
968
+ if (result.success) {
969
+ console.log("✅ Cache warmed up");
970
+ }
606
971
  });
972
+
973
+ // 立即开始服务
974
+ app.listen(3000);
975
+ ```
976
+
977
+ ## ❌ 错误处理
978
+
979
+ ### ProcessResult 类型
980
+
981
+ ```typescript
982
+ type ProcessResult =
983
+ | {
984
+ success: true;
985
+ status: 200;
986
+ data: {
987
+ payer: string;
988
+ txHash: string;
989
+ };
990
+ }
991
+ | {
992
+ success: false;
993
+ status: 402;
994
+ response: Response402;
995
+ };
607
996
  ```
608
997
 
609
- **See [MIDDLEWARES.md](./MIDDLEWARES.md) for detailed guide.**
998
+ ### 错误处理示例
610
999
 
611
- ## Documentation
1000
+ ```typescript
1001
+ const result = await server.process(paymentHeader, requirements);
1002
+
1003
+ if (!result.success) {
1004
+ // 402 响应,包含错误详情
1005
+ console.log("Error:", result.response.error);
1006
+ console.log("Accepts:", result.response.accepts);
1007
+ return res.status(402).json(result.response);
1008
+ }
1009
+
1010
+ // 成功
1011
+ console.log("Payer:", result.data.payer);
1012
+ console.log("TxHash:", result.data.txHash);
1013
+ ```
612
1014
 
613
- - **[README.md](./README.md)** - This file
614
- - **[QUICK-START.md](./QUICK-START.md)** - 5-minute quick start guide
615
- - **[USAGE.md](./USAGE.md)** - Detailed usage documentation
616
- - **[MIDDLEWARES.md](./MIDDLEWARES.md)** - Express and Hono middleware guide
617
- - **[ZOD-VALIDATION.md](./ZOD-VALIDATION.md)** - Zod validation explained
618
- - **[ARCHITECTURE.md](./ARCHITECTURE.md)** - Architecture and design
619
- - **[examples/](./examples/)** - Complete examples
1015
+ ### 常见错误
620
1016
 
621
- ## License
1017
+ | 错误 | 原因 | 解决方案 |
1018
+ |------|------|---------|
1019
+ | `missing_payment_header` | 未提供 X-Payment header | 客户端需要发送支付头 |
1020
+ | `invalid_payment_header` | 支付头格式错误 | 检查 Base64 编码和 JSON 格式 |
1021
+ | `Verification failed` | 签名验证失败 | 检查签名和参数匹配 |
1022
+ | `Settlement failed` | 链上交易失败 | 检查余额、授权和网络状态 |
1023
+
1024
+ ### Try-Catch 处理
1025
+
1026
+ ```typescript
1027
+ try {
1028
+ const result = await server.process(paymentHeader, requirements);
1029
+
1030
+ if (!result.success) {
1031
+ return res.status(402).json(result.response);
1032
+ }
1033
+
1034
+ res.json({ data: "success" });
1035
+ } catch (error) {
1036
+ console.error("Unexpected error:", error);
1037
+ res.status(500).json({
1038
+ error: "Internal server error",
1039
+ message: error instanceof Error ? error.message : "Unknown error"
1040
+ });
1041
+ }
1042
+ ```
1043
+
1044
+ ## 🔍 调试
1045
+
1046
+ ### 启用日志
1047
+
1048
+ ```typescript
1049
+ // Facilitator 支持自定义 logger
1050
+ const facilitator = new Facilitator({
1051
+ recipientAddress: "0x...",
1052
+ logger: console, // 或自定义 logger
1053
+ });
1054
+ ```
1055
+
1056
+ ### 缓存统计
1057
+
1058
+ ```typescript
1059
+ const stats = server.getCacheStats();
1060
+ console.log("Cache size:", stats.size);
1061
+ console.log("Cached tokens:", stats.keys);
1062
+ ```
1063
+
1064
+ ### 清除缓存
1065
+
1066
+ ```typescript
1067
+ // 清除特定 token
1068
+ await server.clearCache("0xUSDC");
1069
+
1070
+ // 清除所有缓存
1071
+ await server.clearCache();
1072
+ ```
1073
+
1074
+ ## 📖 相关资源
1075
+
1076
+ ### 相关包
1077
+
1078
+ - [`@wtflabs/x402`](../x402) - 核心协议类型和工具
1079
+ - [`@wtflabs/x402-detector`](../x402-detector) - Token 检测库
1080
+ - [`@wtflabs/x402-facilitator`](../x402-facilitator) - 支付处理库
1081
+ - [`@wtflabs/x402-fetch`](../x402-fetch) - 客户端 SDK
1082
+
1083
+ ### 文档
1084
+
1085
+ - [x402 协议规范](../../specs/x402-specification.md)
1086
+ - [Exact Scheme 文档](../../specs/schemes/exact/)
1087
+ - [HTTP Transport](../../specs/transports/http.md)
1088
+
1089
+ ## 📄 许可证
622
1090
 
623
1091
  Apache-2.0
624
1092
 
625
- ## Related Packages
1093
+ ## 🤝 贡献
1094
+
1095
+ 欢迎提交 Issue 和 Pull Request!
1096
+
1097
+ ---
626
1098
 
627
- - `@wtflabs/x402-detector` - Token detection (used internally)
628
- - `@wtflabs/x402-facilitator` - Payment processing (used internally)
629
- - `@wtflabs/x402-fetch` - Client SDK
630
- - `@wtflabs/x402` - Core protocol types
1099
+ **Made with ❤️ by WTFLabs**