uvd-x402-sdk 2.4.0 → 2.5.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.
Files changed (45) hide show
  1. package/dist/adapters/index.d.mts +7 -1
  2. package/dist/adapters/index.d.ts +7 -1
  3. package/dist/adapters/index.js +28 -3
  4. package/dist/adapters/index.js.map +1 -1
  5. package/dist/adapters/index.mjs +28 -3
  6. package/dist/adapters/index.mjs.map +1 -1
  7. package/dist/index.js +21 -12
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +21 -12
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/providers/evm/index.d.mts +7 -2
  12. package/dist/providers/evm/index.d.ts +7 -2
  13. package/dist/providers/evm/index.js +42 -13
  14. package/dist/providers/evm/index.js.map +1 -1
  15. package/dist/providers/evm/index.mjs +42 -13
  16. package/dist/providers/evm/index.mjs.map +1 -1
  17. package/dist/providers/near/index.d.mts +6 -2
  18. package/dist/providers/near/index.d.ts +6 -2
  19. package/dist/providers/near/index.js +562 -5
  20. package/dist/providers/near/index.js.map +1 -1
  21. package/dist/providers/near/index.mjs +562 -5
  22. package/dist/providers/near/index.mjs.map +1 -1
  23. package/dist/providers/solana/index.d.mts +6 -4
  24. package/dist/providers/solana/index.d.ts +6 -4
  25. package/dist/providers/solana/index.js +33 -7
  26. package/dist/providers/solana/index.js.map +1 -1
  27. package/dist/providers/solana/index.mjs +33 -7
  28. package/dist/providers/solana/index.mjs.map +1 -1
  29. package/dist/providers/stellar/index.d.mts +6 -2
  30. package/dist/providers/stellar/index.d.ts +6 -2
  31. package/dist/providers/stellar/index.js +568 -11
  32. package/dist/providers/stellar/index.js.map +1 -1
  33. package/dist/providers/stellar/index.mjs +568 -11
  34. package/dist/providers/stellar/index.mjs.map +1 -1
  35. package/dist/react/index.js +37 -12
  36. package/dist/react/index.js.map +1 -1
  37. package/dist/react/index.mjs +37 -12
  38. package/dist/react/index.mjs.map +1 -1
  39. package/package.json +1 -1
  40. package/src/adapters/wagmi.ts +17 -5
  41. package/src/client/X402Client.ts +29 -16
  42. package/src/providers/evm/index.ts +37 -16
  43. package/src/providers/near/index.ts +25 -8
  44. package/src/providers/solana/index.ts +29 -10
  45. package/src/providers/stellar/index.ts +31 -14
@@ -31,9 +31,9 @@
31
31
  */
32
32
 
33
33
  import { getChainByName } from '../chains';
34
- import { createX402V1Header, encodeX402Header, validateRecipient } from '../utils';
34
+ import { createX402V1Header, createX402V2Header, encodeX402Header, validateRecipient } from '../utils';
35
35
  import { X402Error } from '../types';
36
- import type { PaymentResult } from '../types';
36
+ import type { PaymentResult, X402Version } from '../types';
37
37
 
38
38
  /**
39
39
  * Viem WalletClient interface (minimal type to avoid viem dependency)
@@ -67,6 +67,12 @@ export interface WagmiPaymentOptions {
67
67
  chainName?: string;
68
68
  /** Validity window in seconds (default: 300 = 5 minutes) */
69
69
  validitySeconds?: number;
70
+ /**
71
+ * x402 protocol version (default: 1)
72
+ * - 1: Classic format with network as string (e.g., "base")
73
+ * - 2: CAIP-2 format (e.g., "eip155:8453")
74
+ */
75
+ x402Version?: X402Version;
70
76
  }
71
77
 
72
78
  /**
@@ -134,6 +140,7 @@ export async function createPaymentFromWalletClient(
134
140
  amount,
135
141
  chainName = 'base',
136
142
  validitySeconds = 300,
143
+ x402Version = 1,
137
144
  } = options;
138
145
 
139
146
  // Validate recipient address - prevents empty/invalid addresses
@@ -211,9 +218,9 @@ export async function createPaymentFromWalletClient(
211
218
  );
212
219
  }
213
220
 
214
- // Create x402 header with correct format
221
+ // Build the payload data
215
222
  // IMPORTANT: validAfter, validBefore, and value must be STRINGS
216
- const header = createX402V1Header(chainName, {
223
+ const payloadData = {
217
224
  signature,
218
225
  authorization: {
219
226
  from,
@@ -223,7 +230,12 @@ export async function createPaymentFromWalletClient(
223
230
  validBefore: validBefore.toString(),
224
231
  nonce,
225
232
  },
226
- });
233
+ };
234
+
235
+ // Create x402 header with correct version format
236
+ const header = x402Version === 2
237
+ ? createX402V2Header(chainName, payloadData)
238
+ : createX402V1Header(chainName, payloadData);
227
239
 
228
240
  return encodeX402Header(header);
229
241
  }
@@ -25,7 +25,7 @@ import {
25
25
  getChainById,
26
26
  getEnabledChains,
27
27
  } from '../chains';
28
- import { validateRecipient } from '../utils';
28
+ import { validateRecipient, chainToCAIP2 } from '../utils';
29
29
 
30
30
  /**
31
31
  * X402Client - Main SDK client for x402 payments
@@ -581,24 +581,37 @@ export class X402Client {
581
581
  // Reconstruct full signature from v, r, s
582
582
  const fullSignature = payload.r + payload.s.slice(2) + payload.v.toString(16).padStart(2, '0');
583
583
 
584
- // Format in x402 standard format
585
- const x402Payload = {
586
- x402Version: 1,
587
- scheme: 'exact',
588
- network: chain.name,
589
- payload: {
590
- signature: fullSignature,
591
- authorization: {
592
- from: payload.from,
593
- to: payload.to,
594
- value: payload.value,
595
- validAfter: payload.validAfter.toString(),
596
- validBefore: payload.validBefore.toString(),
597
- nonce: payload.nonce,
598
- },
584
+ // Determine version to use (default to v1 for backward compatibility)
585
+ const version = this.config.x402Version === 2 ? 2 : 1;
586
+
587
+ // Build the payload data
588
+ const payloadData = {
589
+ signature: fullSignature,
590
+ authorization: {
591
+ from: payload.from,
592
+ to: payload.to,
593
+ value: payload.value,
594
+ validAfter: payload.validAfter.toString(),
595
+ validBefore: payload.validBefore.toString(),
596
+ nonce: payload.nonce,
599
597
  },
600
598
  };
601
599
 
600
+ // Format in x402 standard format (v1 or v2)
601
+ const x402Payload = version === 2
602
+ ? {
603
+ x402Version: 2 as const,
604
+ scheme: 'exact' as const,
605
+ network: chainToCAIP2(chain.name), // CAIP-2 format for v2
606
+ payload: payloadData,
607
+ }
608
+ : {
609
+ x402Version: 1 as const,
610
+ scheme: 'exact' as const,
611
+ network: chain.name, // Plain chain name for v1
612
+ payload: payloadData,
613
+ };
614
+
602
615
  // Base64 encode
603
616
  const jsonString = JSON.stringify(x402Payload);
604
617
  return btoa(jsonString);
@@ -32,7 +32,8 @@ import type {
32
32
  } from '../../types';
33
33
  import { X402Error } from '../../types';
34
34
  import { getChainByName, getChainById, getTokenConfig } from '../../chains';
35
- import { validateRecipient } from '../../utils';
35
+ import { validateRecipient, chainToCAIP2 } from '../../utils';
36
+ import type { X402Version } from '../../types';
36
37
 
37
38
  /**
38
39
  * Ethereum provider interface
@@ -370,30 +371,50 @@ export class EVMProvider implements WalletAdapter {
370
371
 
371
372
  /**
372
373
  * Encode EVM payment as X-PAYMENT header
374
+ *
375
+ * @param paymentPayload - JSON-encoded payment payload from signPayment()
376
+ * @param chainConfig - Chain configuration
377
+ * @param version - x402 protocol version (1 or 2, defaults to 1)
378
+ * @returns Base64-encoded X-PAYMENT header value
373
379
  */
374
- encodePaymentHeader(paymentPayload: string, chainConfig: ChainConfig): string {
380
+ encodePaymentHeader(
381
+ paymentPayload: string,
382
+ chainConfig: ChainConfig,
383
+ version: X402Version = 1
384
+ ): string {
375
385
  const payload = JSON.parse(paymentPayload) as EVMPaymentPayload;
376
386
 
377
387
  // Reconstruct full signature
378
388
  const fullSignature = payload.r + payload.s.slice(2) + payload.v.toString(16).padStart(2, '0');
379
389
 
380
- const x402Payload = {
381
- x402Version: 1,
382
- scheme: 'exact',
383
- network: chainConfig.name,
384
- payload: {
385
- signature: fullSignature,
386
- authorization: {
387
- from: payload.from,
388
- to: payload.to,
389
- value: payload.value,
390
- validAfter: payload.validAfter.toString(),
391
- validBefore: payload.validBefore.toString(),
392
- nonce: payload.nonce,
393
- },
390
+ // Build the payload data
391
+ const payloadData = {
392
+ signature: fullSignature,
393
+ authorization: {
394
+ from: payload.from,
395
+ to: payload.to,
396
+ value: payload.value,
397
+ validAfter: payload.validAfter.toString(),
398
+ validBefore: payload.validBefore.toString(),
399
+ nonce: payload.nonce,
394
400
  },
395
401
  };
396
402
 
403
+ // Format in x402 standard format (v1 or v2)
404
+ const x402Payload = version === 2
405
+ ? {
406
+ x402Version: 2 as const,
407
+ scheme: 'exact' as const,
408
+ network: chainToCAIP2(chainConfig.name), // CAIP-2 format for v2
409
+ payload: payloadData,
410
+ }
411
+ : {
412
+ x402Version: 1 as const,
413
+ scheme: 'exact' as const,
414
+ network: chainConfig.name, // Plain chain name for v1
415
+ payload: payloadData,
416
+ };
417
+
397
418
  return btoa(JSON.stringify(x402Payload));
398
419
  }
399
420
 
@@ -32,8 +32,10 @@ import type {
32
32
  PaymentInfo,
33
33
  NEARPaymentPayload,
34
34
  WalletAdapter,
35
+ X402Version,
35
36
  } from '../../types';
36
37
  import { X402Error } from '../../types';
38
+ import { chainToCAIP2 } from '../../utils';
37
39
 
38
40
  // NEAR configuration
39
41
  const NEAR_CONFIG = {
@@ -473,19 +475,34 @@ export class NEARProvider implements WalletAdapter {
473
475
 
474
476
  /**
475
477
  * Encode NEAR payment as X-PAYMENT header
478
+ *
479
+ * @param paymentPayload - JSON-encoded payment payload from signPayment()
480
+ * @param version - x402 protocol version (1 or 2, defaults to 1)
481
+ * @returns Base64-encoded X-PAYMENT header value
476
482
  */
477
- encodePaymentHeader(paymentPayload: string): string {
483
+ encodePaymentHeader(paymentPayload: string, version: X402Version = 1): string {
478
484
  const payload = JSON.parse(paymentPayload) as NEARPaymentPayload;
479
485
 
480
- const x402Payload = {
481
- x402Version: 1,
482
- scheme: 'exact',
483
- network: 'near',
484
- payload: {
485
- signedDelegateAction: payload.signedDelegateAction,
486
- },
486
+ // Build the payload data
487
+ const payloadData = {
488
+ signedDelegateAction: payload.signedDelegateAction,
487
489
  };
488
490
 
491
+ // Format in x402 standard format (v1 or v2)
492
+ const x402Payload = version === 2
493
+ ? {
494
+ x402Version: 2 as const,
495
+ scheme: 'exact' as const,
496
+ network: chainToCAIP2('near'), // CAIP-2 format for v2
497
+ payload: payloadData,
498
+ }
499
+ : {
500
+ x402Version: 1 as const,
501
+ scheme: 'exact' as const,
502
+ network: 'near', // Plain chain name for v1
503
+ payload: payloadData,
504
+ };
505
+
489
506
  return btoa(JSON.stringify(x402Payload));
490
507
  }
491
508
 
@@ -43,9 +43,11 @@ import type {
43
43
  PaymentInfo,
44
44
  SolanaPaymentPayload,
45
45
  WalletAdapter,
46
+ X402Version,
46
47
  } from '../../types';
47
48
  import { X402Error } from '../../types';
48
49
  import { getChainByName } from '../../chains';
50
+ import { chainToCAIP2 } from '../../utils';
49
51
 
50
52
  /**
51
53
  * Browser-compatible base64 encoding for Uint8Array
@@ -395,24 +397,41 @@ export class SVMProvider implements WalletAdapter {
395
397
  /**
396
398
  * Encode SVM payment as X-PAYMENT header
397
399
  *
398
- * @param paymentPayload - The payment payload JSON string
399
- * @param chainConfig - Optional chain config (defaults to 'solana' if not provided)
400
+ * @param paymentPayload - JSON-encoded payment payload from signPayment()
401
+ * @param chainConfig - Chain configuration (optional, defaults to 'solana')
402
+ * @param version - x402 protocol version (1 or 2, defaults to 1)
403
+ * @returns Base64-encoded X-PAYMENT header value
400
404
  */
401
- encodePaymentHeader(paymentPayload: string, chainConfig?: ChainConfig): string {
405
+ encodePaymentHeader(
406
+ paymentPayload: string,
407
+ chainConfig?: ChainConfig,
408
+ version: X402Version = 1
409
+ ): string {
402
410
  const payload = JSON.parse(paymentPayload) as SolanaPaymentPayload;
403
411
 
404
412
  // Use chain name from config, or default to 'solana' for backward compatibility
405
413
  const networkName = chainConfig?.name || 'solana';
406
414
 
407
- const x402Payload = {
408
- x402Version: 1,
409
- scheme: 'exact',
410
- network: networkName,
411
- payload: {
412
- transaction: payload.transaction,
413
- },
415
+ // Build the payload data
416
+ const payloadData = {
417
+ transaction: payload.transaction,
414
418
  };
415
419
 
420
+ // Format in x402 standard format (v1 or v2)
421
+ const x402Payload = version === 2
422
+ ? {
423
+ x402Version: 2 as const,
424
+ scheme: 'exact' as const,
425
+ network: chainToCAIP2(networkName), // CAIP-2 format for v2
426
+ payload: payloadData,
427
+ }
428
+ : {
429
+ x402Version: 1 as const,
430
+ scheme: 'exact' as const,
431
+ network: networkName, // Plain chain name for v1
432
+ payload: payloadData,
433
+ };
434
+
416
435
  return btoa(JSON.stringify(x402Payload));
417
436
  }
418
437
 
@@ -25,8 +25,10 @@ import type {
25
25
  PaymentInfo,
26
26
  StellarPaymentPayload,
27
27
  WalletAdapter,
28
+ X402Version,
28
29
  } from '../../types';
29
30
  import { X402Error } from '../../types';
31
+ import { chainToCAIP2 } from '../../utils';
30
32
 
31
33
  /**
32
34
  * Browser-compatible text to Uint8Array encoding
@@ -343,25 +345,40 @@ export class StellarProvider implements WalletAdapter {
343
345
 
344
346
  /**
345
347
  * Encode Stellar payment as X-PAYMENT header
348
+ *
349
+ * @param paymentPayload - JSON-encoded payment payload from signPayment()
350
+ * @param version - x402 protocol version (1 or 2, defaults to 1)
351
+ * @returns Base64-encoded X-PAYMENT header value
346
352
  */
347
- encodePaymentHeader(paymentPayload: string): string {
353
+ encodePaymentHeader(paymentPayload: string, version: X402Version = 1): string {
348
354
  const payload = JSON.parse(paymentPayload) as StellarPaymentPayload;
349
355
 
350
- const x402Payload = {
351
- x402Version: 1,
352
- scheme: 'exact',
353
- network: 'stellar',
354
- payload: {
355
- from: payload.from,
356
- to: payload.to,
357
- amount: payload.amount,
358
- tokenContract: payload.tokenContract,
359
- authorizationEntryXdr: payload.authorizationEntryXdr,
360
- nonce: payload.nonce,
361
- signatureExpirationLedger: payload.signatureExpirationLedger,
362
- },
356
+ // Build the payload data
357
+ const payloadData = {
358
+ from: payload.from,
359
+ to: payload.to,
360
+ amount: payload.amount,
361
+ tokenContract: payload.tokenContract,
362
+ authorizationEntryXdr: payload.authorizationEntryXdr,
363
+ nonce: payload.nonce,
364
+ signatureExpirationLedger: payload.signatureExpirationLedger,
363
365
  };
364
366
 
367
+ // Format in x402 standard format (v1 or v2)
368
+ const x402Payload = version === 2
369
+ ? {
370
+ x402Version: 2 as const,
371
+ scheme: 'exact' as const,
372
+ network: chainToCAIP2('stellar'), // CAIP-2 format for v2
373
+ payload: payloadData,
374
+ }
375
+ : {
376
+ x402Version: 1 as const,
377
+ scheme: 'exact' as const,
378
+ network: 'stellar', // Plain chain name for v1
379
+ payload: payloadData,
380
+ };
381
+
365
382
  return btoa(JSON.stringify(x402Payload));
366
383
  }
367
384