@dexterai/x402 1.9.3 → 1.9.4

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 (37) hide show
  1. package/dist/adapters/index.cjs +14 -5
  2. package/dist/adapters/index.cjs.map +1 -1
  3. package/dist/adapters/index.d.cts +5 -5
  4. package/dist/adapters/index.d.ts +5 -5
  5. package/dist/adapters/index.js +14 -5
  6. package/dist/adapters/index.js.map +1 -1
  7. package/dist/client/index.cjs +60 -24
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +22 -8
  10. package/dist/client/index.d.ts +22 -8
  11. package/dist/client/index.js +59 -24
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/react/index.cjs +63 -30
  14. package/dist/react/index.cjs.map +1 -1
  15. package/dist/react/index.d.cts +10 -5
  16. package/dist/react/index.d.ts +10 -5
  17. package/dist/react/index.js +63 -30
  18. package/dist/react/index.js.map +1 -1
  19. package/dist/server/index.cjs +27 -3
  20. package/dist/server/index.cjs.map +1 -1
  21. package/dist/server/index.d.cts +45 -13
  22. package/dist/server/index.d.ts +45 -13
  23. package/dist/server/index.js +27 -3
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/{solana-CfHuiW2H.d.cts → solana-BcOfK6Eq.d.cts} +2 -2
  26. package/dist/{solana-kZcwbUK9.d.ts → solana-Cxr5byPa.d.ts} +2 -2
  27. package/dist/{sponsored-access-H1EX6zpi.d.ts → sponsored-access-Br6YPA-m.d.cts} +20 -2
  28. package/dist/{sponsored-access-BCB2CxdG.d.cts → sponsored-access-D1_mINs4.d.ts} +20 -2
  29. package/dist/{types-ENcnkof8.d.ts → types-BIHhO2-I.d.ts} +1 -1
  30. package/dist/{types-DmqH9yD8.d.cts → types-CfKflCZO.d.cts} +1 -1
  31. package/dist/{types-BQvaF8lB.d.cts → types-CjLMR7qs.d.cts} +1 -1
  32. package/dist/{types-BQvaF8lB.d.ts → types-CjLMR7qs.d.ts} +1 -1
  33. package/dist/utils/index.cjs +8 -6
  34. package/dist/utils/index.cjs.map +1 -1
  35. package/dist/utils/index.js +8 -6
  36. package/dist/utils/index.js.map +1 -1
  37. package/package.json +1 -1
@@ -136,8 +136,11 @@ var SolanaAdapter = class {
136
136
  const account = await (0, import_spl_token.getAccount)(connection, ata, void 0, programId);
137
137
  const decimals = accept.extra?.decimals ?? 6;
138
138
  return Number(account.amount) / Math.pow(10, decimals);
139
- } catch {
140
- return 0;
139
+ } catch (err) {
140
+ if (err && typeof err === "object" && "name" in err && (err.name === "TokenAccountNotFoundError" || err.name === "TokenInvalidAccountOwnerError")) {
141
+ return 0;
142
+ }
143
+ throw err;
141
144
  }
142
145
  }
143
146
  async buildTransaction(accept, wallet, rpcUrl) {
@@ -365,15 +368,21 @@ var EvmAdapter = class {
365
368
  ]
366
369
  })
367
370
  });
371
+ if (!response.ok) {
372
+ throw new Error(`RPC request failed: ${response.status}`);
373
+ }
368
374
  const result = await response.json();
369
- if (result.error || !result.result) {
375
+ if (result.error) {
376
+ throw new Error(`RPC error: ${JSON.stringify(result.error)}`);
377
+ }
378
+ if (!result.result || result.result === "0x") {
370
379
  return 0;
371
380
  }
372
381
  const balance = BigInt(result.result);
373
382
  const decimals = accept.extra?.decimals ?? 6;
374
383
  return Number(balance) / Math.pow(10, decimals);
375
- } catch {
376
- return 0;
384
+ } catch (err) {
385
+ throw err;
377
386
  }
378
387
  }
379
388
  encodeBalanceOf(address) {
@@ -489,7 +498,8 @@ function createX402Client(config) {
489
498
  maxAmountAtomic,
490
499
  fetch: customFetch = globalThis.fetch,
491
500
  verbose = false,
492
- accessPass: accessPassConfig
501
+ accessPass: accessPassConfig,
502
+ onPaymentRequired
493
503
  } = config;
494
504
  const log = verbose ? console.log.bind(console, "[x402]") : () => {
495
505
  };
@@ -602,13 +612,17 @@ function createX402Client(config) {
602
612
  const paymentAmount = accept.amount ?? accept.maxAmountRequired;
603
613
  if (!paymentAmount) return null;
604
614
  const rpcUrl = getRpcUrl(accept.network, adapter);
605
- const balance = await adapter.getBalance(accept, wallet, rpcUrl);
606
- const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
607
- if (balance < requiredAmount) {
608
- throw new X402Error(
609
- "insufficient_balance",
610
- `Insufficient balance for access pass. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
611
- );
615
+ try {
616
+ const balance = await adapter.getBalance(accept, wallet, rpcUrl);
617
+ const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
618
+ if (balance < requiredAmount) {
619
+ throw new X402Error(
620
+ "insufficient_balance",
621
+ `Insufficient balance for access pass. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
622
+ );
623
+ }
624
+ } catch (err) {
625
+ if (err instanceof X402Error) throw err;
612
626
  }
613
627
  const signedTx = await adapter.buildTransaction(accept, wallet, rpcUrl);
614
628
  let payload;
@@ -621,13 +635,19 @@ function createX402Client(config) {
621
635
  let resolvedResource = requirements.resource;
622
636
  if (typeof requirements.resource === "string") {
623
637
  try {
624
- resolvedResource = new URL(requirements.resource, originalUrl).toString();
638
+ const resolved = new URL(requirements.resource, originalUrl);
639
+ if (["http:", "https:"].includes(resolved.protocol)) {
640
+ resolvedResource = resolved.toString();
641
+ }
625
642
  } catch {
626
643
  }
627
644
  } else if (requirements.resource && typeof requirements.resource === "object" && "url" in requirements.resource) {
628
645
  const rObj = requirements.resource;
629
646
  try {
630
- resolvedResource = { ...rObj, url: new URL(rObj.url, originalUrl).toString() };
647
+ const resolved = new URL(rObj.url, originalUrl);
648
+ if (["http:", "https:"].includes(resolved.protocol)) {
649
+ resolvedResource = { ...rObj, url: resolved.toString() };
650
+ }
631
651
  } catch {
632
652
  }
633
653
  }
@@ -755,16 +775,27 @@ function createX402Client(config) {
755
775
  }
756
776
  const rpcUrl = getRpcUrl(accept.network, adapter);
757
777
  log("Checking balance...");
758
- const balance = await adapter.getBalance(accept, wallet, rpcUrl);
759
- const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
760
- if (balance < requiredAmount) {
761
- const network = adapter.name === "EVM" ? "Base" : "Solana";
762
- throw new X402Error(
763
- "insufficient_balance",
764
- `Insufficient USDC balance on ${network}. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
765
- );
778
+ try {
779
+ const balance = await adapter.getBalance(accept, wallet, rpcUrl);
780
+ const requiredAmount = Number(paymentAmount) / Math.pow(10, decimals);
781
+ if (balance < requiredAmount) {
782
+ const network = adapter.name === "EVM" ? "Base" : "Solana";
783
+ throw new X402Error(
784
+ "insufficient_balance",
785
+ `Insufficient USDC balance on ${network}. Have $${balance.toFixed(4)}, need $${requiredAmount.toFixed(4)}`
786
+ );
787
+ }
788
+ log(`Balance OK: $${balance.toFixed(4)} >= $${requiredAmount.toFixed(4)}`);
789
+ } catch (err) {
790
+ if (err instanceof X402Error) throw err;
791
+ log("Balance check failed (RPC error), proceeding with transaction attempt");
792
+ }
793
+ if (onPaymentRequired) {
794
+ const approved = await onPaymentRequired(accept);
795
+ if (!approved) {
796
+ throw new X402Error("payment_rejected", "Payment rejected by onPaymentRequired callback");
797
+ }
766
798
  }
767
- log(`Balance OK: $${balance.toFixed(4)} >= $${requiredAmount.toFixed(4)}`);
768
799
  log("Building transaction...");
769
800
  const signedTx = await adapter.buildTransaction(accept, wallet, rpcUrl);
770
801
  log("Transaction signed");
@@ -849,13 +880,15 @@ function createX402Client(config) {
849
880
  }
850
881
 
851
882
  // src/utils.ts
883
+ function isSolanaNetwork(network) {
884
+ return network.startsWith("solana:") || network === "solana";
885
+ }
886
+ function isEvmNetwork(network) {
887
+ return network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network);
888
+ }
852
889
  function getChainFamily(network) {
853
- if (network.startsWith("solana:") || network === "solana") {
854
- return "solana";
855
- }
856
- if (network.startsWith("eip155:") || ["base", "ethereum", "arbitrum"].includes(network)) {
857
- return "evm";
858
- }
890
+ if (isSolanaNetwork(network)) return "solana";
891
+ if (isEvmNetwork(network)) return "evm";
859
892
  return "unknown";
860
893
  }
861
894
  function getChainName(network) {