@wazabiai/x402 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Wazabi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,356 @@
1
+ # @wazabiai/x402
2
+
3
+ <div align="center">
4
+
5
+ **Production-ready SDK for the x402 v2 Payment Protocol on BNB Smart Chain**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@wazabiai/x402)](https://www.npmjs.com/package/@wazabiai/x402)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue)](https://www.typescriptlang.org/)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ ## Overview
16
+
17
+ The x402 protocol standardizes crypto payments over HTTP, enabling seamless pay-per-use APIs and premium content access on the blockchain.
18
+
19
+ **Protocol Flow:**
20
+ 1. **402 Payment Required** — Server responds with payment details in headers
21
+ 2. **EIP-712 Signing** — Client signs typed data payload
22
+ 3. **Retry with Signature** — Client retries with `X-PAYMENT-SIGNATURE` header
23
+ 4. **Verification** — Server verifies signature and processes request
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install @wazabiai/x402
29
+ # or
30
+ pnpm add @wazabiai/x402
31
+ # or
32
+ yarn add @wazabiai/x402
33
+ ```
34
+
35
+ **Peer Dependencies:**
36
+ ```bash
37
+ npm install viem express
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ### Client Usage
43
+
44
+ ```typescript
45
+ import { X402Client } from '@wazabiai/x402/client';
46
+
47
+ // Create client with private key (for server-to-server)
48
+ const client = new X402Client({
49
+ privateKey: process.env.PRIVATE_KEY,
50
+ });
51
+
52
+ // Make requests - 402 responses are handled automatically
53
+ const response = await client.fetch('https://api.example.com/premium-data');
54
+ console.log(response.data);
55
+ ```
56
+
57
+ ### Server Usage
58
+
59
+ ```typescript
60
+ import express from 'express';
61
+ import { x402Middleware } from '@wazabiai/x402/server';
62
+ import { BSC_USDT, parseTokenAmount } from '@wazabiai/x402/chains';
63
+
64
+ const app = express();
65
+
66
+ // Protect routes with payment requirement
67
+ app.use('/api/paid', x402Middleware({
68
+ recipientAddress: '0xYourWalletAddress',
69
+ amount: parseTokenAmount('0.10', BSC_USDT.address).toString(), // $0.10 USDT
70
+ tokenAddress: BSC_USDT.address,
71
+ description: 'Access to premium API',
72
+ }));
73
+
74
+ app.get('/api/paid/data', (req, res) => {
75
+ // Payment verified ✓
76
+ res.json({ premium: 'content' });
77
+ });
78
+
79
+ app.listen(3000);
80
+ ```
81
+
82
+ ## API Reference
83
+
84
+ ### Client
85
+
86
+ #### `X402Client`
87
+
88
+ ```typescript
89
+ import { X402Client } from '@wazabiai/x402/client';
90
+
91
+ const client = new X402Client({
92
+ // Private key for signing (hex, with or without 0x)
93
+ privateKey?: string;
94
+
95
+ // Custom RPC URL (defaults to BSC public RPC)
96
+ rpcUrl?: string;
97
+
98
+ // Supported networks (defaults to ['eip155:56'])
99
+ supportedNetworks?: string[];
100
+
101
+ // Payment deadline in seconds (default: 300)
102
+ defaultDeadline?: number;
103
+
104
+ // Auto-retry on 402 (default: true)
105
+ autoRetry?: boolean;
106
+
107
+ // Maximum retry attempts (default: 1)
108
+ maxRetries?: number;
109
+
110
+ // Callbacks
111
+ onPaymentRequired?: (requirement: PaymentRequirement) => void;
112
+ onPaymentSigned?: (payment: SignedPayment) => void;
113
+ });
114
+ ```
115
+
116
+ **Methods:**
117
+
118
+ ```typescript
119
+ // Generic fetch with automatic 402 handling
120
+ await client.fetch(url, options);
121
+
122
+ // HTTP verb shortcuts
123
+ await client.get(url, options);
124
+ await client.post(url, data, options);
125
+ await client.put(url, data, options);
126
+ await client.delete(url, options);
127
+
128
+ // Manual signing
129
+ const signedPayment = await client.signPayment(requirement);
130
+ ```
131
+
132
+ ### Server
133
+
134
+ #### `x402Middleware`
135
+
136
+ ```typescript
137
+ import { x402Middleware } from '@wazabiai/x402/server';
138
+
139
+ const middleware = x402Middleware({
140
+ // Required: Payment recipient address
141
+ recipientAddress: '0x...',
142
+
143
+ // Required: Amount in smallest token unit (wei)
144
+ amount: '1000000000000000000',
145
+
146
+ // Token address (default: BSC-USDT)
147
+ tokenAddress?: '0x...',
148
+
149
+ // External facilitator URL for verification
150
+ facilitatorUrl?: string;
151
+
152
+ // Payment description
153
+ description?: string;
154
+
155
+ // Network ID (default: 'eip155:56')
156
+ networkId?: string;
157
+
158
+ // Deadline duration in seconds (default: 300)
159
+ deadlineDuration?: number;
160
+
161
+ // Custom verification logic
162
+ verifyPayment?: (payment, req) => Promise<boolean>;
163
+
164
+ // Routes to exclude from payment
165
+ excludeRoutes?: string[];
166
+ });
167
+ ```
168
+
169
+ #### Utility Functions
170
+
171
+ ```typescript
172
+ import {
173
+ createPaymentRequirement,
174
+ verifyPayment,
175
+ parsePaymentFromRequest
176
+ } from '@wazabiai/x402/server';
177
+
178
+ // Create a payment requirement manually
179
+ const requirement = createPaymentRequirement({
180
+ recipientAddress: '0x...',
181
+ amount: '1000000000000000000',
182
+ resource: '/api/resource',
183
+ });
184
+
185
+ // Verify a signed payment
186
+ const result = await verifyPayment(
187
+ signedPayment,
188
+ recipientAddress,
189
+ 'eip155:56'
190
+ );
191
+
192
+ // Parse payment from Express request
193
+ const payment = parsePaymentFromRequest(req);
194
+ ```
195
+
196
+ ### Types
197
+
198
+ ```typescript
199
+ import type {
200
+ PaymentRequirement,
201
+ PaymentPayload,
202
+ SignedPayment,
203
+ NetworkConfig,
204
+ TokenConfig,
205
+ } from '@wazabiai/x402/types';
206
+ ```
207
+
208
+ ### Chain Configuration
209
+
210
+ ```typescript
211
+ import {
212
+ BSC_CHAIN_ID, // 56
213
+ BSC_CAIP_ID, // 'eip155:56'
214
+ BSC_USDT, // TokenConfig
215
+ BSC_USDC, // TokenConfig
216
+ BSC_TOKENS, // All tokens
217
+ formatTokenAmount, // Convert wei to readable
218
+ parseTokenAmount, // Convert readable to wei
219
+ } from '@wazabiai/x402/chains';
220
+ ```
221
+
222
+ ## Supported Tokens (BSC)
223
+
224
+ | Token | Address | Decimals |
225
+ |-------|---------|----------|
226
+ | USDT | `0x55d398326f99059fF775485246999027B3197955` | 18 |
227
+ | USDC | `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d` | 18 |
228
+ | BUSD | `0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56` | 18 |
229
+ | WBNB | `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c` | 18 |
230
+
231
+ ## Protocol Details
232
+
233
+ ### HTTP Headers
234
+
235
+ | Header | Direction | Description |
236
+ |--------|-----------|-------------|
237
+ | `X-PAYMENT-REQUIRED` | Response | JSON payment requirement |
238
+ | `X-PAYMENT-SIGNATURE` | Request | EIP-712 signature |
239
+ | `X-PAYMENT-PAYLOAD` | Request | JSON payment payload |
240
+
241
+ ### EIP-712 Structure
242
+
243
+ **Domain:**
244
+ ```typescript
245
+ {
246
+ name: 'x402',
247
+ version: '2.0.0',
248
+ chainId: 56 // BSC
249
+ }
250
+ ```
251
+
252
+ **Payment Type:**
253
+ ```typescript
254
+ {
255
+ Payment: [
256
+ { name: 'amount', type: 'uint256' },
257
+ { name: 'token', type: 'address' },
258
+ { name: 'chainId', type: 'uint256' },
259
+ { name: 'payTo', type: 'address' },
260
+ { name: 'payer', type: 'address' },
261
+ { name: 'deadline', type: 'uint256' },
262
+ { name: 'nonce', type: 'string' },
263
+ { name: 'resource', type: 'string' },
264
+ ]
265
+ }
266
+ ```
267
+
268
+ ## Error Handling
269
+
270
+ ```typescript
271
+ import {
272
+ PaymentRequiredError,
273
+ PaymentVerificationError,
274
+ UnsupportedNetworkError,
275
+ PaymentExpiredError,
276
+ } from '@wazabiai/x402/client';
277
+
278
+ try {
279
+ await client.fetch(url);
280
+ } catch (error) {
281
+ if (error instanceof PaymentRequiredError) {
282
+ console.log('Payment needed:', error.requirement);
283
+ }
284
+ if (error instanceof UnsupportedNetworkError) {
285
+ console.log('Unsupported network:', error.details);
286
+ }
287
+ }
288
+ ```
289
+
290
+ ## Examples
291
+
292
+ ### Pay-per-API-Call
293
+
294
+ ```typescript
295
+ // Server
296
+ app.use('/api/ai', x402Middleware({
297
+ recipientAddress: TREASURY,
298
+ amount: parseTokenAmount('0.001', BSC_USDT.address).toString(),
299
+ description: 'AI API call',
300
+ }));
301
+
302
+ app.post('/api/ai/generate', async (req, res) => {
303
+ const { x402 } = req as X402Request;
304
+ console.log(`Payment from: ${x402?.signer}`);
305
+
306
+ const result = await generateAIResponse(req.body);
307
+ res.json(result);
308
+ });
309
+ ```
310
+
311
+ ### Tiered Pricing
312
+
313
+ ```typescript
314
+ const PRICES = {
315
+ basic: '100000000000000000', // 0.1 USDT
316
+ premium: '1000000000000000000', // 1 USDT
317
+ };
318
+
319
+ app.use('/api/basic', x402Middleware({
320
+ recipientAddress: TREASURY,
321
+ amount: PRICES.basic,
322
+ }));
323
+
324
+ app.use('/api/premium', x402Middleware({
325
+ recipientAddress: TREASURY,
326
+ amount: PRICES.premium,
327
+ }));
328
+ ```
329
+
330
+ ### With Facilitator
331
+
332
+ ```typescript
333
+ // Offload verification to external service
334
+ app.use('/api/paid', x402Middleware({
335
+ recipientAddress: TREASURY,
336
+ amount: PRICE,
337
+ facilitatorUrl: 'https://facilitator.example.com',
338
+ }));
339
+ ```
340
+
341
+ ## Environment Variables
342
+
343
+ ```bash
344
+ # Client
345
+ X402_PRIVATE_KEY=0x... # Used by createX402ClientFromEnv()
346
+ ```
347
+
348
+ ## License
349
+
350
+ MIT © Wazabi
351
+
352
+ ---
353
+
354
+ <div align="center">
355
+ <sub>Built with ❤️ for the decentralized web</sub>
356
+ </div>
@@ -0,0 +1,98 @@
1
+ import { TokenConfig, NetworkConfig } from './types/index.cjs';
2
+
3
+ /**
4
+ * BNB Smart Chain (BSC) Mainnet Chain ID
5
+ */
6
+ declare const BSC_CHAIN_ID: 56;
7
+ /**
8
+ * BNB Smart Chain CAIP-2 Identifier
9
+ */
10
+ declare const BSC_CAIP_ID: "eip155:56";
11
+ /**
12
+ * BNB Smart Chain public RPC endpoints
13
+ * Using multiple for fallback support
14
+ */
15
+ declare const BSC_RPC_URLS: readonly ["https://bsc-dataseed.binance.org", "https://bsc-dataseed1.binance.org", "https://bsc-dataseed2.binance.org", "https://bsc-dataseed3.binance.org", "https://bsc-dataseed4.binance.org", "https://bsc-dataseed1.defibit.io", "https://bsc-dataseed1.ninicoin.io"];
16
+ /**
17
+ * Default BSC RPC URL
18
+ */
19
+ declare const BSC_DEFAULT_RPC: "https://bsc-dataseed.binance.org";
20
+ /**
21
+ * BscScan block explorer URL
22
+ */
23
+ declare const BSC_BLOCK_EXPLORER: "https://bscscan.com";
24
+ /**
25
+ * BSC-USDT (Tether USD) Token Configuration
26
+ * @see https://bscscan.com/token/0x55d398326f99059fF775485246999027B3197955
27
+ */
28
+ declare const BSC_USDT: TokenConfig;
29
+ /**
30
+ * BSC-USDC (USD Coin) Token Configuration
31
+ * @see https://bscscan.com/token/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d
32
+ */
33
+ declare const BSC_USDC: TokenConfig;
34
+ /**
35
+ * BSC-BUSD (Binance USD) Token Configuration
36
+ * @see https://bscscan.com/token/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56
37
+ */
38
+ declare const BSC_BUSD: TokenConfig;
39
+ /**
40
+ * Wrapped BNB (WBNB) Token Configuration
41
+ * @see https://bscscan.com/token/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
42
+ */
43
+ declare const BSC_WBNB: TokenConfig;
44
+ /**
45
+ * Default token for payments (BSC-USDT)
46
+ */
47
+ declare const BSC_DEFAULT_TOKEN: TokenConfig;
48
+ /**
49
+ * All supported tokens on BSC
50
+ */
51
+ declare const BSC_TOKENS: {
52
+ readonly USDT: TokenConfig;
53
+ readonly USDC: TokenConfig;
54
+ readonly BUSD: TokenConfig;
55
+ readonly WBNB: TokenConfig;
56
+ };
57
+ /**
58
+ * Token address to config mapping for quick lookup
59
+ */
60
+ declare const BSC_TOKEN_BY_ADDRESS: Record<string, TokenConfig>;
61
+ /**
62
+ * Complete BNB Smart Chain network configuration
63
+ */
64
+ declare const BSC_NETWORK_CONFIG: NetworkConfig;
65
+ /**
66
+ * Get token configuration by address
67
+ */
68
+ declare function getTokenByAddress(address: string): TokenConfig | undefined;
69
+ /**
70
+ * Get token configuration by symbol
71
+ */
72
+ declare function getTokenBySymbol(symbol: string): TokenConfig | undefined;
73
+ /**
74
+ * Check if a token address is supported on BSC
75
+ */
76
+ declare function isTokenSupported(address: string): boolean;
77
+ /**
78
+ * Format token amount from wei to human-readable string
79
+ */
80
+ declare function formatTokenAmount(amount: bigint | string, tokenAddress: string): string;
81
+ /**
82
+ * Parse human-readable amount to wei
83
+ */
84
+ declare function parseTokenAmount(amount: string, tokenAddress: string): bigint;
85
+ /**
86
+ * Get BscScan URL for a transaction
87
+ */
88
+ declare function getTxUrl(txHash: string): string;
89
+ /**
90
+ * Get BscScan URL for an address
91
+ */
92
+ declare function getAddressUrl(address: string): string;
93
+ /**
94
+ * Get BscScan URL for a token
95
+ */
96
+ declare function getTokenUrl(tokenAddress: string): string;
97
+
98
+ export { BSC_CHAIN_ID as B, BSC_CAIP_ID as a, BSC_RPC_URLS as b, BSC_DEFAULT_RPC as c, BSC_BLOCK_EXPLORER as d, BSC_USDT as e, BSC_USDC as f, BSC_BUSD as g, BSC_WBNB as h, BSC_DEFAULT_TOKEN as i, BSC_TOKENS as j, BSC_TOKEN_BY_ADDRESS as k, BSC_NETWORK_CONFIG as l, getTokenByAddress as m, getTokenBySymbol as n, isTokenSupported as o, formatTokenAmount as p, parseTokenAmount as q, getTxUrl as r, getAddressUrl as s, getTokenUrl as t };
@@ -0,0 +1,98 @@
1
+ import { TokenConfig, NetworkConfig } from './types/index.js';
2
+
3
+ /**
4
+ * BNB Smart Chain (BSC) Mainnet Chain ID
5
+ */
6
+ declare const BSC_CHAIN_ID: 56;
7
+ /**
8
+ * BNB Smart Chain CAIP-2 Identifier
9
+ */
10
+ declare const BSC_CAIP_ID: "eip155:56";
11
+ /**
12
+ * BNB Smart Chain public RPC endpoints
13
+ * Using multiple for fallback support
14
+ */
15
+ declare const BSC_RPC_URLS: readonly ["https://bsc-dataseed.binance.org", "https://bsc-dataseed1.binance.org", "https://bsc-dataseed2.binance.org", "https://bsc-dataseed3.binance.org", "https://bsc-dataseed4.binance.org", "https://bsc-dataseed1.defibit.io", "https://bsc-dataseed1.ninicoin.io"];
16
+ /**
17
+ * Default BSC RPC URL
18
+ */
19
+ declare const BSC_DEFAULT_RPC: "https://bsc-dataseed.binance.org";
20
+ /**
21
+ * BscScan block explorer URL
22
+ */
23
+ declare const BSC_BLOCK_EXPLORER: "https://bscscan.com";
24
+ /**
25
+ * BSC-USDT (Tether USD) Token Configuration
26
+ * @see https://bscscan.com/token/0x55d398326f99059fF775485246999027B3197955
27
+ */
28
+ declare const BSC_USDT: TokenConfig;
29
+ /**
30
+ * BSC-USDC (USD Coin) Token Configuration
31
+ * @see https://bscscan.com/token/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d
32
+ */
33
+ declare const BSC_USDC: TokenConfig;
34
+ /**
35
+ * BSC-BUSD (Binance USD) Token Configuration
36
+ * @see https://bscscan.com/token/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56
37
+ */
38
+ declare const BSC_BUSD: TokenConfig;
39
+ /**
40
+ * Wrapped BNB (WBNB) Token Configuration
41
+ * @see https://bscscan.com/token/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
42
+ */
43
+ declare const BSC_WBNB: TokenConfig;
44
+ /**
45
+ * Default token for payments (BSC-USDT)
46
+ */
47
+ declare const BSC_DEFAULT_TOKEN: TokenConfig;
48
+ /**
49
+ * All supported tokens on BSC
50
+ */
51
+ declare const BSC_TOKENS: {
52
+ readonly USDT: TokenConfig;
53
+ readonly USDC: TokenConfig;
54
+ readonly BUSD: TokenConfig;
55
+ readonly WBNB: TokenConfig;
56
+ };
57
+ /**
58
+ * Token address to config mapping for quick lookup
59
+ */
60
+ declare const BSC_TOKEN_BY_ADDRESS: Record<string, TokenConfig>;
61
+ /**
62
+ * Complete BNB Smart Chain network configuration
63
+ */
64
+ declare const BSC_NETWORK_CONFIG: NetworkConfig;
65
+ /**
66
+ * Get token configuration by address
67
+ */
68
+ declare function getTokenByAddress(address: string): TokenConfig | undefined;
69
+ /**
70
+ * Get token configuration by symbol
71
+ */
72
+ declare function getTokenBySymbol(symbol: string): TokenConfig | undefined;
73
+ /**
74
+ * Check if a token address is supported on BSC
75
+ */
76
+ declare function isTokenSupported(address: string): boolean;
77
+ /**
78
+ * Format token amount from wei to human-readable string
79
+ */
80
+ declare function formatTokenAmount(amount: bigint | string, tokenAddress: string): string;
81
+ /**
82
+ * Parse human-readable amount to wei
83
+ */
84
+ declare function parseTokenAmount(amount: string, tokenAddress: string): bigint;
85
+ /**
86
+ * Get BscScan URL for a transaction
87
+ */
88
+ declare function getTxUrl(txHash: string): string;
89
+ /**
90
+ * Get BscScan URL for an address
91
+ */
92
+ declare function getAddressUrl(address: string): string;
93
+ /**
94
+ * Get BscScan URL for a token
95
+ */
96
+ declare function getTokenUrl(tokenAddress: string): string;
97
+
98
+ export { BSC_CHAIN_ID as B, BSC_CAIP_ID as a, BSC_RPC_URLS as b, BSC_DEFAULT_RPC as c, BSC_BLOCK_EXPLORER as d, BSC_USDT as e, BSC_USDC as f, BSC_BUSD as g, BSC_WBNB as h, BSC_DEFAULT_TOKEN as i, BSC_TOKENS as j, BSC_TOKEN_BY_ADDRESS as k, BSC_NETWORK_CONFIG as l, getTokenByAddress as m, getTokenBySymbol as n, isTokenSupported as o, formatTokenAmount as p, parseTokenAmount as q, getTxUrl as r, getAddressUrl as s, getTokenUrl as t };