@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.
@@ -0,0 +1,408 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * x402 Protocol Version
5
+ */
6
+ declare const X402_VERSION: "2.0.0";
7
+ /**
8
+ * EIP-712 Domain name for x402 protocol
9
+ */
10
+ declare const X402_DOMAIN_NAME: "x402";
11
+ /**
12
+ * HTTP Header names used in x402 protocol
13
+ */
14
+ declare const X402_HEADERS: {
15
+ readonly PAYMENT_REQUIRED: "x-payment-required";
16
+ readonly PAYMENT_SIGNATURE: "x-payment-signature";
17
+ readonly PAYMENT_PAYLOAD: "x-payment-payload";
18
+ };
19
+ /**
20
+ * Supported token symbol types
21
+ */
22
+ type TokenSymbol = 'USDT' | 'USDC' | 'BNB' | 'BUSD';
23
+ /**
24
+ * Token configuration for a specific blockchain
25
+ */
26
+ interface TokenConfig {
27
+ /** Token contract address (0x...) */
28
+ address: `0x${string}`;
29
+ /** Token symbol */
30
+ symbol: TokenSymbol;
31
+ /** Token decimals (typically 18 for most tokens) */
32
+ decimals: number;
33
+ /** Human-readable token name */
34
+ name: string;
35
+ }
36
+ /**
37
+ * Network configuration for a specific blockchain
38
+ */
39
+ interface NetworkConfig {
40
+ /** CAIP-2 chain identifier (e.g., 'eip155:56' for BSC) */
41
+ caipId: string;
42
+ /** Numeric chain ID */
43
+ chainId: number;
44
+ /** Human-readable network name */
45
+ name: string;
46
+ /** Default RPC URL */
47
+ rpcUrl: string;
48
+ /** Native currency symbol */
49
+ nativeCurrency: {
50
+ name: string;
51
+ symbol: string;
52
+ decimals: number;
53
+ };
54
+ /** Block explorer URL */
55
+ blockExplorer: string;
56
+ /** Supported tokens on this network */
57
+ tokens: Record<string, TokenConfig>;
58
+ }
59
+ /**
60
+ * Zod schema for PaymentRequirement validation
61
+ */
62
+ declare const PaymentRequirementSchema: z.ZodObject<{
63
+ /** Payment amount in smallest token unit (wei/satoshi) as string */
64
+ amount: z.ZodString;
65
+ /** Token contract address */
66
+ token: z.ZodString;
67
+ /** CAIP-2 network identifier */
68
+ network_id: z.ZodString;
69
+ /** Recipient address for payment */
70
+ pay_to: z.ZodString;
71
+ /** Optional: Payment description */
72
+ description: z.ZodOptional<z.ZodString>;
73
+ /** Optional: Resource identifier being accessed */
74
+ resource: z.ZodOptional<z.ZodString>;
75
+ /** Optional: Expiration timestamp (Unix epoch seconds) */
76
+ expires_at: z.ZodOptional<z.ZodNumber>;
77
+ /** Optional: Unique nonce to prevent replay attacks */
78
+ nonce: z.ZodOptional<z.ZodString>;
79
+ /** Protocol version */
80
+ version: z.ZodOptional<z.ZodString>;
81
+ }, "strip", z.ZodTypeAny, {
82
+ amount: string;
83
+ token: string;
84
+ network_id: string;
85
+ pay_to: string;
86
+ description?: string | undefined;
87
+ resource?: string | undefined;
88
+ expires_at?: number | undefined;
89
+ nonce?: string | undefined;
90
+ version?: string | undefined;
91
+ }, {
92
+ amount: string;
93
+ token: string;
94
+ network_id: string;
95
+ pay_to: string;
96
+ description?: string | undefined;
97
+ resource?: string | undefined;
98
+ expires_at?: number | undefined;
99
+ nonce?: string | undefined;
100
+ version?: string | undefined;
101
+ }>;
102
+ /**
103
+ * Payment requirement structure returned in 402 response header
104
+ */
105
+ type PaymentRequirement = z.infer<typeof PaymentRequirementSchema>;
106
+ /**
107
+ * EIP-712 Domain structure for x402 protocol
108
+ */
109
+ interface X402Domain {
110
+ name: typeof X402_DOMAIN_NAME;
111
+ version: string;
112
+ chainId: number;
113
+ verifyingContract?: `0x${string}`;
114
+ }
115
+ /**
116
+ * Zod schema for PaymentPayload validation
117
+ */
118
+ declare const PaymentPayloadSchema: z.ZodObject<{
119
+ /** Payment amount in smallest token unit */
120
+ amount: z.ZodString;
121
+ /** Token contract address */
122
+ token: z.ZodString;
123
+ /** Chain ID (numeric) */
124
+ chainId: z.ZodNumber;
125
+ /** Recipient address */
126
+ payTo: z.ZodString;
127
+ /** Payer address (signer) */
128
+ payer: z.ZodString;
129
+ /** Unix timestamp when payment expires */
130
+ deadline: z.ZodNumber;
131
+ /** Unique nonce to prevent replay attacks */
132
+ nonce: z.ZodString;
133
+ /** Optional: Resource being accessed */
134
+ resource: z.ZodOptional<z.ZodString>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ amount: string;
137
+ token: string;
138
+ nonce: string;
139
+ chainId: number;
140
+ payTo: string;
141
+ payer: string;
142
+ deadline: number;
143
+ resource?: string | undefined;
144
+ }, {
145
+ amount: string;
146
+ token: string;
147
+ nonce: string;
148
+ chainId: number;
149
+ payTo: string;
150
+ payer: string;
151
+ deadline: number;
152
+ resource?: string | undefined;
153
+ }>;
154
+ /**
155
+ * EIP-712 typed data payload for signing
156
+ */
157
+ type PaymentPayload = z.infer<typeof PaymentPayloadSchema>;
158
+ /**
159
+ * EIP-712 type definitions for Payment message
160
+ */
161
+ declare const PAYMENT_TYPES: {
162
+ readonly Payment: readonly [{
163
+ readonly name: "amount";
164
+ readonly type: "uint256";
165
+ }, {
166
+ readonly name: "token";
167
+ readonly type: "address";
168
+ }, {
169
+ readonly name: "chainId";
170
+ readonly type: "uint256";
171
+ }, {
172
+ readonly name: "payTo";
173
+ readonly type: "address";
174
+ }, {
175
+ readonly name: "payer";
176
+ readonly type: "address";
177
+ }, {
178
+ readonly name: "deadline";
179
+ readonly type: "uint256";
180
+ }, {
181
+ readonly name: "nonce";
182
+ readonly type: "string";
183
+ }, {
184
+ readonly name: "resource";
185
+ readonly type: "string";
186
+ }];
187
+ };
188
+ /**
189
+ * Complete signed payment ready to be sent as header
190
+ */
191
+ interface SignedPayment {
192
+ /** The payment payload that was signed */
193
+ payload: PaymentPayload;
194
+ /** EIP-712 signature (0x prefixed) */
195
+ signature: `0x${string}`;
196
+ /** Address of the signer */
197
+ signer: `0x${string}`;
198
+ }
199
+ /**
200
+ * Zod schema for SignedPayment validation
201
+ */
202
+ declare const SignedPaymentSchema: z.ZodObject<{
203
+ payload: z.ZodObject<{
204
+ /** Payment amount in smallest token unit */
205
+ amount: z.ZodString;
206
+ /** Token contract address */
207
+ token: z.ZodString;
208
+ /** Chain ID (numeric) */
209
+ chainId: z.ZodNumber;
210
+ /** Recipient address */
211
+ payTo: z.ZodString;
212
+ /** Payer address (signer) */
213
+ payer: z.ZodString;
214
+ /** Unix timestamp when payment expires */
215
+ deadline: z.ZodNumber;
216
+ /** Unique nonce to prevent replay attacks */
217
+ nonce: z.ZodString;
218
+ /** Optional: Resource being accessed */
219
+ resource: z.ZodOptional<z.ZodString>;
220
+ }, "strip", z.ZodTypeAny, {
221
+ amount: string;
222
+ token: string;
223
+ nonce: string;
224
+ chainId: number;
225
+ payTo: string;
226
+ payer: string;
227
+ deadline: number;
228
+ resource?: string | undefined;
229
+ }, {
230
+ amount: string;
231
+ token: string;
232
+ nonce: string;
233
+ chainId: number;
234
+ payTo: string;
235
+ payer: string;
236
+ deadline: number;
237
+ resource?: string | undefined;
238
+ }>;
239
+ signature: z.ZodString;
240
+ signer: z.ZodString;
241
+ }, "strip", z.ZodTypeAny, {
242
+ payload: {
243
+ amount: string;
244
+ token: string;
245
+ nonce: string;
246
+ chainId: number;
247
+ payTo: string;
248
+ payer: string;
249
+ deadline: number;
250
+ resource?: string | undefined;
251
+ };
252
+ signature: string;
253
+ signer: string;
254
+ }, {
255
+ payload: {
256
+ amount: string;
257
+ token: string;
258
+ nonce: string;
259
+ chainId: number;
260
+ payTo: string;
261
+ payer: string;
262
+ deadline: number;
263
+ resource?: string | undefined;
264
+ };
265
+ signature: string;
266
+ signer: string;
267
+ }>;
268
+ /**
269
+ * Configuration options for X402Client
270
+ */
271
+ interface X402ClientConfig {
272
+ /** Private key for signing (hex string with or without 0x prefix) */
273
+ privateKey?: string;
274
+ /** Custom RPC URL to use instead of default */
275
+ rpcUrl?: string;
276
+ /** Supported network IDs (defaults to ['eip155:56']) */
277
+ supportedNetworks?: string[];
278
+ /** Default deadline duration in seconds (default: 300 = 5 minutes) */
279
+ defaultDeadline?: number;
280
+ /** Auto-retry on 402 response (default: true) */
281
+ autoRetry?: boolean;
282
+ /** Maximum retries for payment (default: 1) */
283
+ maxRetries?: number;
284
+ /** Custom axios instance configuration */
285
+ axiosConfig?: Record<string, unknown>;
286
+ /** Callback when payment is required */
287
+ onPaymentRequired?: (requirement: PaymentRequirement) => void | Promise<void>;
288
+ /** Callback when payment is signed */
289
+ onPaymentSigned?: (payment: SignedPayment) => void | Promise<void>;
290
+ }
291
+ /**
292
+ * Payment verification result
293
+ */
294
+ interface PaymentVerificationResult {
295
+ /** Whether the payment signature is valid */
296
+ valid: boolean;
297
+ /** Recovered signer address if valid */
298
+ signer?: `0x${string}`;
299
+ /** Error message if invalid */
300
+ error?: string;
301
+ /** The verified payment payload */
302
+ payload?: PaymentPayload;
303
+ }
304
+ /**
305
+ * Facilitator verification request
306
+ */
307
+ interface FacilitatorVerifyRequest {
308
+ signature: string;
309
+ payload: PaymentPayload;
310
+ networkId: string;
311
+ }
312
+ /**
313
+ * Facilitator verification response
314
+ */
315
+ interface FacilitatorVerifyResponse {
316
+ valid: boolean;
317
+ signer?: string;
318
+ error?: string;
319
+ balanceSufficient?: boolean;
320
+ allowanceSufficient?: boolean;
321
+ }
322
+ /**
323
+ * Configuration options for x402 server middleware
324
+ */
325
+ interface X402MiddlewareConfig {
326
+ /** Recipient address for payments */
327
+ recipientAddress: `0x${string}`;
328
+ /** Payment amount in smallest token unit */
329
+ amount: string;
330
+ /** Token contract address (defaults to BSC-USDT) */
331
+ tokenAddress?: `0x${string}`;
332
+ /** Optional facilitator URL for offloading verification */
333
+ facilitatorUrl?: string;
334
+ /** Custom payment description */
335
+ description?: string;
336
+ /** Network ID (defaults to 'eip155:56') */
337
+ networkId?: string;
338
+ /** Deadline duration in seconds (default: 300) */
339
+ deadlineDuration?: number;
340
+ /** Custom nonce generator */
341
+ nonceGenerator?: () => string;
342
+ /** Callback to verify payment against custom logic (e.g., database) */
343
+ verifyPayment?: (payment: SignedPayment, req: unknown) => Promise<boolean>;
344
+ /** Routes to exclude from payment requirement */
345
+ excludeRoutes?: string[];
346
+ /** Custom error handler */
347
+ onError?: (error: Error, req: unknown, res: unknown) => void;
348
+ }
349
+ /**
350
+ * Base error class for x402 protocol errors
351
+ */
352
+ declare class X402Error extends Error {
353
+ code: string;
354
+ details?: Record<string, unknown> | undefined;
355
+ constructor(message: string, code: string, details?: Record<string, unknown> | undefined);
356
+ }
357
+ /**
358
+ * Error thrown when payment is required but not provided
359
+ */
360
+ declare class PaymentRequiredError extends X402Error {
361
+ requirement: PaymentRequirement;
362
+ constructor(requirement: PaymentRequirement, message?: string);
363
+ }
364
+ /**
365
+ * Error thrown when payment signature verification fails
366
+ */
367
+ declare class PaymentVerificationError extends X402Error {
368
+ details?: Record<string, unknown> | undefined;
369
+ constructor(message: string, details?: Record<string, unknown> | undefined);
370
+ }
371
+ /**
372
+ * Error thrown when network is not supported
373
+ */
374
+ declare class UnsupportedNetworkError extends X402Error {
375
+ constructor(networkId: string, supportedNetworks: string[]);
376
+ }
377
+ /**
378
+ * Error thrown when payment has expired
379
+ */
380
+ declare class PaymentExpiredError extends X402Error {
381
+ constructor(deadline: number);
382
+ }
383
+ /**
384
+ * Hex string type (0x prefixed)
385
+ */
386
+ type HexString = `0x${string}`;
387
+ /**
388
+ * Address type (0x prefixed, 40 hex chars)
389
+ */
390
+ type Address = `0x${string}`;
391
+ /**
392
+ * Extract chain ID from CAIP-2 identifier
393
+ */
394
+ declare function extractChainId(caipId: string): number;
395
+ /**
396
+ * Create CAIP-2 identifier from chain ID
397
+ */
398
+ declare function createCaipId(chainId: number): string;
399
+ /**
400
+ * Generate a random nonce
401
+ */
402
+ declare function generateNonce(): string;
403
+ /**
404
+ * Calculate deadline from duration
405
+ */
406
+ declare function calculateDeadline(durationSeconds?: number): number;
407
+
408
+ export { type Address, type FacilitatorVerifyRequest, type FacilitatorVerifyResponse, type HexString, type NetworkConfig, PAYMENT_TYPES, PaymentExpiredError, type PaymentPayload, PaymentPayloadSchema, PaymentRequiredError, type PaymentRequirement, PaymentRequirementSchema, PaymentVerificationError, type PaymentVerificationResult, type SignedPayment, SignedPaymentSchema, type TokenConfig, type TokenSymbol, UnsupportedNetworkError, type X402ClientConfig, type X402Domain, X402Error, type X402MiddlewareConfig, X402_DOMAIN_NAME, X402_HEADERS, X402_VERSION, calculateDeadline, createCaipId, extractChainId, generateNonce };
@@ -0,0 +1,141 @@
1
+ import { z } from 'zod';
2
+
3
+ /* @wazabiai/x402 - x402 v2 Payment Protocol SDK */
4
+
5
+ var X402_VERSION = "2.0.0";
6
+ var X402_DOMAIN_NAME = "x402";
7
+ var X402_HEADERS = {
8
+ PAYMENT_REQUIRED: "x-payment-required",
9
+ PAYMENT_SIGNATURE: "x-payment-signature",
10
+ PAYMENT_PAYLOAD: "x-payment-payload"
11
+ };
12
+ var PaymentRequirementSchema = z.object({
13
+ /** Payment amount in smallest token unit (wei/satoshi) as string */
14
+ amount: z.string().regex(/^\d+$/, "Amount must be a numeric string"),
15
+ /** Token contract address */
16
+ token: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid token address"),
17
+ /** CAIP-2 network identifier */
18
+ network_id: z.string().regex(/^eip155:\d+$/, "Invalid CAIP-2 network ID"),
19
+ /** Recipient address for payment */
20
+ pay_to: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid recipient address"),
21
+ /** Optional: Payment description */
22
+ description: z.string().optional(),
23
+ /** Optional: Resource identifier being accessed */
24
+ resource: z.string().optional(),
25
+ /** Optional: Expiration timestamp (Unix epoch seconds) */
26
+ expires_at: z.number().int().positive().optional(),
27
+ /** Optional: Unique nonce to prevent replay attacks */
28
+ nonce: z.string().optional(),
29
+ /** Protocol version */
30
+ version: z.string().optional()
31
+ });
32
+ var PaymentPayloadSchema = z.object({
33
+ /** Payment amount in smallest token unit */
34
+ amount: z.string().regex(/^\d+$/, "Amount must be a numeric string"),
35
+ /** Token contract address */
36
+ token: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid token address"),
37
+ /** Chain ID (numeric) */
38
+ chainId: z.number().int().positive(),
39
+ /** Recipient address */
40
+ payTo: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid recipient address"),
41
+ /** Payer address (signer) */
42
+ payer: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid payer address"),
43
+ /** Unix timestamp when payment expires */
44
+ deadline: z.number().int().positive(),
45
+ /** Unique nonce to prevent replay attacks */
46
+ nonce: z.string(),
47
+ /** Optional: Resource being accessed */
48
+ resource: z.string().optional()
49
+ });
50
+ var PAYMENT_TYPES = {
51
+ Payment: [
52
+ { name: "amount", type: "uint256" },
53
+ { name: "token", type: "address" },
54
+ { name: "chainId", type: "uint256" },
55
+ { name: "payTo", type: "address" },
56
+ { name: "payer", type: "address" },
57
+ { name: "deadline", type: "uint256" },
58
+ { name: "nonce", type: "string" },
59
+ { name: "resource", type: "string" }
60
+ ]
61
+ };
62
+ var SignedPaymentSchema = z.object({
63
+ payload: PaymentPayloadSchema,
64
+ signature: z.string().regex(/^0x[a-fA-F0-9]+$/, "Invalid signature format"),
65
+ signer: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid signer address")
66
+ });
67
+ var X402Error = class _X402Error extends Error {
68
+ constructor(message, code, details) {
69
+ super(message);
70
+ this.code = code;
71
+ this.details = details;
72
+ this.name = "X402Error";
73
+ Object.setPrototypeOf(this, _X402Error.prototype);
74
+ }
75
+ };
76
+ var PaymentRequiredError = class _PaymentRequiredError extends X402Error {
77
+ constructor(requirement, message = "Payment required") {
78
+ super(message, "PAYMENT_REQUIRED", { requirement });
79
+ this.requirement = requirement;
80
+ this.name = "PaymentRequiredError";
81
+ Object.setPrototypeOf(this, _PaymentRequiredError.prototype);
82
+ }
83
+ };
84
+ var PaymentVerificationError = class _PaymentVerificationError extends X402Error {
85
+ constructor(message, details) {
86
+ super(message, "PAYMENT_VERIFICATION_FAILED", details);
87
+ this.details = details;
88
+ this.name = "PaymentVerificationError";
89
+ Object.setPrototypeOf(this, _PaymentVerificationError.prototype);
90
+ }
91
+ };
92
+ var UnsupportedNetworkError = class _UnsupportedNetworkError extends X402Error {
93
+ constructor(networkId, supportedNetworks) {
94
+ super(
95
+ `Network ${networkId} is not supported. Supported networks: ${supportedNetworks.join(", ")}`,
96
+ "UNSUPPORTED_NETWORK",
97
+ { networkId, supportedNetworks }
98
+ );
99
+ this.name = "UnsupportedNetworkError";
100
+ Object.setPrototypeOf(this, _UnsupportedNetworkError.prototype);
101
+ }
102
+ };
103
+ var PaymentExpiredError = class _PaymentExpiredError extends X402Error {
104
+ constructor(deadline) {
105
+ super(
106
+ `Payment has expired. Deadline: ${new Date(deadline * 1e3).toISOString()}`,
107
+ "PAYMENT_EXPIRED",
108
+ { deadline }
109
+ );
110
+ this.name = "PaymentExpiredError";
111
+ Object.setPrototypeOf(this, _PaymentExpiredError.prototype);
112
+ }
113
+ };
114
+ function extractChainId(caipId) {
115
+ const match = caipId.match(/^eip155:(\d+)$/);
116
+ if (!match?.[1]) {
117
+ throw new X402Error(`Invalid CAIP-2 identifier: ${caipId}`, "INVALID_CAIP_ID");
118
+ }
119
+ return parseInt(match[1], 10);
120
+ }
121
+ function createCaipId(chainId) {
122
+ return `eip155:${chainId}`;
123
+ }
124
+ function generateNonce() {
125
+ const bytes = new Uint8Array(16);
126
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
127
+ crypto.getRandomValues(bytes);
128
+ } else {
129
+ for (let i = 0; i < bytes.length; i++) {
130
+ bytes[i] = Math.floor(Math.random() * 256);
131
+ }
132
+ }
133
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
134
+ }
135
+ function calculateDeadline(durationSeconds = 300) {
136
+ return Math.floor(Date.now() / 1e3) + durationSeconds;
137
+ }
138
+
139
+ export { PAYMENT_TYPES, PaymentExpiredError, PaymentPayloadSchema, PaymentRequiredError, PaymentRequirementSchema, PaymentVerificationError, SignedPaymentSchema, UnsupportedNetworkError, X402Error, X402_DOMAIN_NAME, X402_HEADERS, X402_VERSION, calculateDeadline, createCaipId, extractChainId, generateNonce };
140
+ //# sourceMappingURL=index.js.map
141
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;AASO,IAAM,YAAA,GAAe;AAKrB,IAAM,gBAAA,GAAmB;AAKzB,IAAM,YAAA,GAAe;AAAA,EAC1B,gBAAA,EAAkB,oBAAA;AAAA,EAClB,iBAAA,EAAmB,qBAAA;AAAA,EACnB,eAAA,EAAiB;AACnB;AAwDO,IAAM,wBAAA,GAA2B,EAAE,MAAA,CAAO;AAAA;AAAA,EAE/C,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,SAAS,iCAAiC,CAAA;AAAA;AAAA,EAEnE,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,uBAAuB,CAAA;AAAA;AAAA,EAEtE,YAAY,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,gBAAgB,2BAA2B,CAAA;AAAA;AAAA,EAExE,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,2BAA2B,CAAA;AAAA;AAAA,EAE3E,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAEjC,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE9B,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA;AAAA,EAEjD,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAE3B,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACtB,CAAC;AAwBM,IAAM,oBAAA,GAAuB,EAAE,MAAA,CAAO;AAAA;AAAA,EAE3C,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,SAAS,iCAAiC,CAAA;AAAA;AAAA,EAEnE,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,uBAAuB,CAAA;AAAA;AAAA,EAEtE,SAAS,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA;AAAA,EAEnC,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,2BAA2B,CAAA;AAAA;AAAA,EAE1E,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,uBAAuB,CAAA;AAAA;AAAA,EAEtE,UAAU,CAAA,CAAE,MAAA,EAAO,CAAE,GAAA,GAAM,QAAA,EAAS;AAAA;AAAA,EAEpC,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA;AAAA,EAEhB,QAAA,EAAU,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACvB,CAAC;AAUM,IAAM,aAAA,GAAgB;AAAA,EAC3B,OAAA,EAAS;AAAA,IACP,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,SAAA,EAAU;AAAA,IAClC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,IACjC,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAA,EAAU;AAAA,IACnC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,IACjC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,SAAA,EAAU;AAAA,IACjC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,SAAA,EAAU;AAAA,IACpC,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,QAAA,EAAS;AAAA,IAChC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,QAAA;AAAS;AAEvC;AAqBO,IAAM,mBAAA,GAAsB,EAAE,MAAA,CAAO;AAAA,EAC1C,OAAA,EAAS,oBAAA;AAAA,EACT,WAAW,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,oBAAoB,0BAA0B,CAAA;AAAA,EAC1E,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,uBAAuB,wBAAwB;AAC1E,CAAC;AAuGM,IAAM,SAAA,GAAN,MAAM,UAAA,SAAkB,KAAA,CAAM;AAAA,EACnC,WAAA,CACE,OAAA,EACO,IAAA,EACA,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,UAAA,CAAU,SAAS,CAAA;AAAA,EACjD;AACF;AAKO,IAAM,oBAAA,GAAN,MAAM,qBAAA,SAA6B,SAAA,CAAU;AAAA,EAClD,WAAA,CACS,WAAA,EACP,OAAA,GAAU,kBAAA,EACV;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,EAAE,WAAA,EAAa,CAAA;AAH3C,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAIP,IAAA,IAAA,CAAK,IAAA,GAAO,sBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,qBAAA,CAAqB,SAAS,CAAA;AAAA,EAC5D;AACF;AAKO,IAAM,wBAAA,GAAN,MAAM,yBAAA,SAAiC,SAAA,CAAU;AAAA,EACtD,WAAA,CACE,SACO,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAA,EAAS,+BAA+B,OAAO,CAAA;AAF9C,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,0BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,yBAAA,CAAyB,SAAS,CAAA;AAAA,EAChE;AACF;AAKO,IAAM,uBAAA,GAAN,MAAM,wBAAA,SAAgC,SAAA,CAAU;AAAA,EACrD,WAAA,CACE,WACA,iBAAA,EACA;AACA,IAAA,KAAA;AAAA,MACE,WAAW,SAAS,CAAA,uCAAA,EAA0C,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,MAC1F,qBAAA;AAAA,MACA,EAAE,WAAW,iBAAA;AAAkB,KACjC;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,wBAAA,CAAwB,SAAS,CAAA;AAAA,EAC/D;AACF;AAKO,IAAM,mBAAA,GAAN,MAAM,oBAAA,SAA4B,SAAA,CAAU;AAAA,EACjD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA;AAAA,MACE,kCAAkC,IAAI,IAAA,CAAK,WAAW,GAAI,CAAA,CAAE,aAAa,CAAA,CAAA;AAAA,MACzE,iBAAA;AAAA,MACA,EAAE,QAAA;AAAS,KACb;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,oBAAA,CAAoB,SAAS,CAAA;AAAA,EAC3D;AACF;AAmBO,SAAS,eAAe,MAAA,EAAwB;AACrD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,gBAAgB,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAA,GAAQ,CAAC,CAAA,EAAG;AACf,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,2BAAA,EAA8B,MAAM,IAAI,iBAAiB,CAAA;AAAA,EAC/E;AACA,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,EAAG,EAAE,CAAA;AAC9B;AAKO,SAAS,aAAa,OAAA,EAAyB;AACpD,EAAA,OAAO,UAAU,OAAO,CAAA,CAAA;AAC1B;AAKO,SAAS,aAAA,GAAwB;AACtC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,eAAA,EAAiB;AAC3D,IAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAAA,EAC9B,CAAA,MAAO;AAEL,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,KAAW,GAAG,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,OAAO,MAAM,IAAA,CAAK,KAAK,CAAA,CACpB,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAC1C,KAAK,EAAE,CAAA;AACZ;AAKO,SAAS,iBAAA,CAAkB,kBAA0B,GAAA,EAAa;AACvE,EAAA,OAAO,KAAK,KAAA,CAAM,IAAA,CAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI,eAAA;AACzC","file":"index.js","sourcesContent":["import { z } from 'zod';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * x402 Protocol Version\n */\nexport const X402_VERSION = '2.0.0' as const;\n\n/**\n * EIP-712 Domain name for x402 protocol\n */\nexport const X402_DOMAIN_NAME = 'x402' as const;\n\n/**\n * HTTP Header names used in x402 protocol\n */\nexport const X402_HEADERS = {\n PAYMENT_REQUIRED: 'x-payment-required',\n PAYMENT_SIGNATURE: 'x-payment-signature',\n PAYMENT_PAYLOAD: 'x-payment-payload',\n} as const;\n\n// ============================================================================\n// Network Configuration Types\n// ============================================================================\n\n/**\n * Supported token symbol types\n */\nexport type TokenSymbol = 'USDT' | 'USDC' | 'BNB' | 'BUSD';\n\n/**\n * Token configuration for a specific blockchain\n */\nexport interface TokenConfig {\n /** Token contract address (0x...) */\n address: `0x${string}`;\n /** Token symbol */\n symbol: TokenSymbol;\n /** Token decimals (typically 18 for most tokens) */\n decimals: number;\n /** Human-readable token name */\n name: string;\n}\n\n/**\n * Network configuration for a specific blockchain\n */\nexport interface NetworkConfig {\n /** CAIP-2 chain identifier (e.g., 'eip155:56' for BSC) */\n caipId: string;\n /** Numeric chain ID */\n chainId: number;\n /** Human-readable network name */\n name: string;\n /** Default RPC URL */\n rpcUrl: string;\n /** Native currency symbol */\n nativeCurrency: {\n name: string;\n symbol: string;\n decimals: number;\n };\n /** Block explorer URL */\n blockExplorer: string;\n /** Supported tokens on this network */\n tokens: Record<string, TokenConfig>;\n}\n\n// ============================================================================\n// Payment Requirement Types\n// ============================================================================\n\n/**\n * Zod schema for PaymentRequirement validation\n */\nexport const PaymentRequirementSchema = z.object({\n /** Payment amount in smallest token unit (wei/satoshi) as string */\n amount: z.string().regex(/^\\d+$/, 'Amount must be a numeric string'),\n /** Token contract address */\n token: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid token address'),\n /** CAIP-2 network identifier */\n network_id: z.string().regex(/^eip155:\\d+$/, 'Invalid CAIP-2 network ID'),\n /** Recipient address for payment */\n pay_to: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid recipient address'),\n /** Optional: Payment description */\n description: z.string().optional(),\n /** Optional: Resource identifier being accessed */\n resource: z.string().optional(),\n /** Optional: Expiration timestamp (Unix epoch seconds) */\n expires_at: z.number().int().positive().optional(),\n /** Optional: Unique nonce to prevent replay attacks */\n nonce: z.string().optional(),\n /** Protocol version */\n version: z.string().optional(),\n});\n\n/**\n * Payment requirement structure returned in 402 response header\n */\nexport type PaymentRequirement = z.infer<typeof PaymentRequirementSchema>;\n\n// ============================================================================\n// EIP-712 Payment Payload Types\n// ============================================================================\n\n/**\n * EIP-712 Domain structure for x402 protocol\n */\nexport interface X402Domain {\n name: typeof X402_DOMAIN_NAME;\n version: string;\n chainId: number;\n verifyingContract?: `0x${string}`;\n}\n\n/**\n * Zod schema for PaymentPayload validation\n */\nexport const PaymentPayloadSchema = z.object({\n /** Payment amount in smallest token unit */\n amount: z.string().regex(/^\\d+$/, 'Amount must be a numeric string'),\n /** Token contract address */\n token: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid token address'),\n /** Chain ID (numeric) */\n chainId: z.number().int().positive(),\n /** Recipient address */\n payTo: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid recipient address'),\n /** Payer address (signer) */\n payer: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid payer address'),\n /** Unix timestamp when payment expires */\n deadline: z.number().int().positive(),\n /** Unique nonce to prevent replay attacks */\n nonce: z.string(),\n /** Optional: Resource being accessed */\n resource: z.string().optional(),\n});\n\n/**\n * EIP-712 typed data payload for signing\n */\nexport type PaymentPayload = z.infer<typeof PaymentPayloadSchema>;\n\n/**\n * EIP-712 type definitions for Payment message\n */\nexport const PAYMENT_TYPES = {\n Payment: [\n { name: 'amount', type: 'uint256' },\n { name: 'token', type: 'address' },\n { name: 'chainId', type: 'uint256' },\n { name: 'payTo', type: 'address' },\n { name: 'payer', type: 'address' },\n { name: 'deadline', type: 'uint256' },\n { name: 'nonce', type: 'string' },\n { name: 'resource', type: 'string' },\n ],\n} as const;\n\n// ============================================================================\n// Signed Payment Types\n// ============================================================================\n\n/**\n * Complete signed payment ready to be sent as header\n */\nexport interface SignedPayment {\n /** The payment payload that was signed */\n payload: PaymentPayload;\n /** EIP-712 signature (0x prefixed) */\n signature: `0x${string}`;\n /** Address of the signer */\n signer: `0x${string}`;\n}\n\n/**\n * Zod schema for SignedPayment validation\n */\nexport const SignedPaymentSchema = z.object({\n payload: PaymentPayloadSchema,\n signature: z.string().regex(/^0x[a-fA-F0-9]+$/, 'Invalid signature format'),\n signer: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid signer address'),\n});\n\n// ============================================================================\n// Client Configuration Types\n// ============================================================================\n\n/**\n * Configuration options for X402Client\n */\nexport interface X402ClientConfig {\n /** Private key for signing (hex string with or without 0x prefix) */\n privateKey?: string;\n /** Custom RPC URL to use instead of default */\n rpcUrl?: string;\n /** Supported network IDs (defaults to ['eip155:56']) */\n supportedNetworks?: string[];\n /** Default deadline duration in seconds (default: 300 = 5 minutes) */\n defaultDeadline?: number;\n /** Auto-retry on 402 response (default: true) */\n autoRetry?: boolean;\n /** Maximum retries for payment (default: 1) */\n maxRetries?: number;\n /** Custom axios instance configuration */\n axiosConfig?: Record<string, unknown>;\n /** Callback when payment is required */\n onPaymentRequired?: (requirement: PaymentRequirement) => void | Promise<void>;\n /** Callback when payment is signed */\n onPaymentSigned?: (payment: SignedPayment) => void | Promise<void>;\n}\n\n// ============================================================================\n// Server/Middleware Configuration Types\n// ============================================================================\n\n/**\n * Payment verification result\n */\nexport interface PaymentVerificationResult {\n /** Whether the payment signature is valid */\n valid: boolean;\n /** Recovered signer address if valid */\n signer?: `0x${string}`;\n /** Error message if invalid */\n error?: string;\n /** The verified payment payload */\n payload?: PaymentPayload;\n}\n\n/**\n * Facilitator verification request\n */\nexport interface FacilitatorVerifyRequest {\n signature: string;\n payload: PaymentPayload;\n networkId: string;\n}\n\n/**\n * Facilitator verification response\n */\nexport interface FacilitatorVerifyResponse {\n valid: boolean;\n signer?: string;\n error?: string;\n balanceSufficient?: boolean;\n allowanceSufficient?: boolean;\n}\n\n/**\n * Configuration options for x402 server middleware\n */\nexport interface X402MiddlewareConfig {\n /** Recipient address for payments */\n recipientAddress: `0x${string}`;\n /** Payment amount in smallest token unit */\n amount: string;\n /** Token contract address (defaults to BSC-USDT) */\n tokenAddress?: `0x${string}`;\n /** Optional facilitator URL for offloading verification */\n facilitatorUrl?: string;\n /** Custom payment description */\n description?: string;\n /** Network ID (defaults to 'eip155:56') */\n networkId?: string;\n /** Deadline duration in seconds (default: 300) */\n deadlineDuration?: number;\n /** Custom nonce generator */\n nonceGenerator?: () => string;\n /** Callback to verify payment against custom logic (e.g., database) */\n verifyPayment?: (payment: SignedPayment, req: unknown) => Promise<boolean>;\n /** Routes to exclude from payment requirement */\n excludeRoutes?: string[];\n /** Custom error handler */\n onError?: (error: Error, req: unknown, res: unknown) => void;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * Base error class for x402 protocol errors\n */\nexport class X402Error extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: Record<string, unknown>\n ) {\n super(message);\n this.name = 'X402Error';\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n\n/**\n * Error thrown when payment is required but not provided\n */\nexport class PaymentRequiredError extends X402Error {\n constructor(\n public requirement: PaymentRequirement,\n message = 'Payment required'\n ) {\n super(message, 'PAYMENT_REQUIRED', { requirement });\n this.name = 'PaymentRequiredError';\n Object.setPrototypeOf(this, PaymentRequiredError.prototype);\n }\n}\n\n/**\n * Error thrown when payment signature verification fails\n */\nexport class PaymentVerificationError extends X402Error {\n constructor(\n message: string,\n public details?: Record<string, unknown>\n ) {\n super(message, 'PAYMENT_VERIFICATION_FAILED', details);\n this.name = 'PaymentVerificationError';\n Object.setPrototypeOf(this, PaymentVerificationError.prototype);\n }\n}\n\n/**\n * Error thrown when network is not supported\n */\nexport class UnsupportedNetworkError extends X402Error {\n constructor(\n networkId: string,\n supportedNetworks: string[]\n ) {\n super(\n `Network ${networkId} is not supported. Supported networks: ${supportedNetworks.join(', ')}`,\n 'UNSUPPORTED_NETWORK',\n { networkId, supportedNetworks }\n );\n this.name = 'UnsupportedNetworkError';\n Object.setPrototypeOf(this, UnsupportedNetworkError.prototype);\n }\n}\n\n/**\n * Error thrown when payment has expired\n */\nexport class PaymentExpiredError extends X402Error {\n constructor(deadline: number) {\n super(\n `Payment has expired. Deadline: ${new Date(deadline * 1000).toISOString()}`,\n 'PAYMENT_EXPIRED',\n { deadline }\n );\n this.name = 'PaymentExpiredError';\n Object.setPrototypeOf(this, PaymentExpiredError.prototype);\n }\n}\n\n// ============================================================================\n// Utility Types\n// ============================================================================\n\n/**\n * Hex string type (0x prefixed)\n */\nexport type HexString = `0x${string}`;\n\n/**\n * Address type (0x prefixed, 40 hex chars)\n */\nexport type Address = `0x${string}`;\n\n/**\n * Extract chain ID from CAIP-2 identifier\n */\nexport function extractChainId(caipId: string): number {\n const match = caipId.match(/^eip155:(\\d+)$/);\n if (!match?.[1]) {\n throw new X402Error(`Invalid CAIP-2 identifier: ${caipId}`, 'INVALID_CAIP_ID');\n }\n return parseInt(match[1], 10);\n}\n\n/**\n * Create CAIP-2 identifier from chain ID\n */\nexport function createCaipId(chainId: number): string {\n return `eip155:${chainId}`;\n}\n\n/**\n * Generate a random nonce\n */\nexport function generateNonce(): string {\n const bytes = new Uint8Array(16);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n } else {\n // Fallback for Node.js without Web Crypto\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Calculate deadline from duration\n */\nexport function calculateDeadline(durationSeconds: number = 300): number {\n return Math.floor(Date.now() / 1000) + durationSeconds;\n}\n"]}