@voyage_ai/v402-web-ts 0.2.0 → 0.3.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/dist/index.d.mts CHANGED
@@ -1,23 +1,21 @@
1
1
  import { PaymentRequirements } from 'x402/types';
2
2
  export { PaymentRequirements, SPLTokenAmount, SettleResponse, VerifyResponse, x402Response } from 'x402/types';
3
- import { VersionedTransaction } from '@solana/web3.js';
4
3
  import { z } from 'zod';
5
4
 
6
5
  /**
7
6
  * Common types for x402 SDK
8
7
  * Framework-agnostic types that work across different wallet implementations
9
8
  */
10
-
11
9
  /**
12
10
  * Generic wallet adapter interface - works with any wallet provider
13
- * Compatible with Anza wallet-adapter, Privy, and custom implementations
11
+ * Compatible with Anza wallet-adapter, Privy, @solana/kit, and custom implementations
14
12
  */
15
13
  interface WalletAdapter {
16
14
  publicKey?: {
17
15
  toString(): string;
18
16
  };
19
17
  address?: string;
20
- signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>;
18
+ signTransaction: <T>(tx: T) => Promise<T>;
21
19
  }
22
20
  /**
23
21
  * EVM wallet adapter interface
@@ -235,6 +233,8 @@ declare function getChainId(network: string): number;
235
233
  *
236
234
  * Low-level API: Creates X-PAYMENT header for Solana transactions
237
235
  * Use this when you want to build the payment header yourself and handle fetch separately
236
+ *
237
+ * Uses @solana/web3.js and @solana/spl-token packages
238
238
  */
239
239
 
240
240
  /**
package/dist/index.d.ts CHANGED
@@ -1,23 +1,21 @@
1
1
  import { PaymentRequirements } from 'x402/types';
2
2
  export { PaymentRequirements, SPLTokenAmount, SettleResponse, VerifyResponse, x402Response } from 'x402/types';
3
- import { VersionedTransaction } from '@solana/web3.js';
4
3
  import { z } from 'zod';
5
4
 
6
5
  /**
7
6
  * Common types for x402 SDK
8
7
  * Framework-agnostic types that work across different wallet implementations
9
8
  */
10
-
11
9
  /**
12
10
  * Generic wallet adapter interface - works with any wallet provider
13
- * Compatible with Anza wallet-adapter, Privy, and custom implementations
11
+ * Compatible with Anza wallet-adapter, Privy, @solana/kit, and custom implementations
14
12
  */
15
13
  interface WalletAdapter {
16
14
  publicKey?: {
17
15
  toString(): string;
18
16
  };
19
17
  address?: string;
20
- signTransaction: (tx: VersionedTransaction) => Promise<VersionedTransaction>;
18
+ signTransaction: <T>(tx: T) => Promise<T>;
21
19
  }
22
20
  /**
23
21
  * EVM wallet adapter interface
@@ -235,6 +233,8 @@ declare function getChainId(network: string): number;
235
233
  *
236
234
  * Low-level API: Creates X-PAYMENT header for Solana transactions
237
235
  * Use this when you want to build the payment header yourself and handle fetch separately
236
+ *
237
+ * Uses @solana/web3.js and @solana/spl-token packages
238
238
  */
239
239
 
240
240
  /**
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ var PROD_BACK_URL;
25
25
  var init_common = __esm({
26
26
  "src/types/common.ts"() {
27
27
  "use strict";
28
- PROD_BACK_URL = "https://v402pay.onvoyage.ai/api/pay";
28
+ PROD_BACK_URL = true ? "https://v402pay.onvoyage.ai/api/pay" : "https://v402pay.onvoyage.ai/api/pay";
29
29
  }
30
30
  });
31
31
 
@@ -231,6 +231,40 @@ var import_spl_token = require("@solana/spl-token");
231
231
  // src/utils/index.ts
232
232
  init_wallet();
233
233
 
234
+ // src/utils/wallet-discovery.ts
235
+ var evmWallets = /* @__PURE__ */ new Map();
236
+ var evmDiscoveryListeners = /* @__PURE__ */ new Set();
237
+ var evmDiscoveryInitialized = false;
238
+ var currentConnectedWallet = null;
239
+ function initEVMWalletDiscovery() {
240
+ if (typeof window === "undefined" || evmDiscoveryInitialized) return;
241
+ evmDiscoveryInitialized = true;
242
+ window.addEventListener("eip6963:announceProvider", ((event) => {
243
+ const { info, provider } = event.detail;
244
+ evmWallets.set(info.uuid, { info, provider });
245
+ evmDiscoveryListeners.forEach((listener) => listener());
246
+ }));
247
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
248
+ }
249
+ function getWalletProviderForPayment(networkType) {
250
+ if (currentConnectedWallet && currentConnectedWallet.networkType === networkType) {
251
+ return currentConnectedWallet.provider;
252
+ }
253
+ if (typeof window === "undefined") return null;
254
+ switch (networkType) {
255
+ case "evm" /* EVM */:
256
+ return window.ethereum;
257
+ case "solana" /* SOLANA */:
258
+ case "svm" /* SVM */:
259
+ return window.phantom?.solana || window.solana;
260
+ default:
261
+ return null;
262
+ }
263
+ }
264
+ if (typeof window !== "undefined") {
265
+ initEVMWalletDiscovery();
266
+ }
267
+
234
268
  // src/services/evm/payment-header.ts
235
269
  var import_ethers = require("ethers");
236
270
  async function createEvmPaymentHeader(params) {
@@ -346,6 +380,15 @@ function getChainIdFromNetwork(network) {
346
380
 
347
381
  // src/services/evm/payment-handler.ts
348
382
  init_types();
383
+ var NETWORK_NAMES = {
384
+ 1: "Ethereum Mainnet",
385
+ 11155111: "Sepolia Testnet",
386
+ 8453: "Base Mainnet",
387
+ 84532: "Base Sepolia Testnet",
388
+ 137: "Polygon Mainnet",
389
+ 42161: "Arbitrum One",
390
+ 10: "Optimism Mainnet"
391
+ };
349
392
  async function handleEvmPayment(endpoint, config, requestInit) {
350
393
  const { wallet, network, maxPaymentAmount } = config;
351
394
  const initialResponse = await fetch(endpoint, {
@@ -356,25 +399,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
356
399
  return initialResponse;
357
400
  }
358
401
  const rawResponse = await initialResponse.json();
359
- const IGNORED_ERRORS = [
360
- "X-PAYMENT header is required",
361
- "missing X-PAYMENT header",
362
- "payment_required"
363
- ];
364
- if (rawResponse.error && !IGNORED_ERRORS.includes(rawResponse.error)) {
402
+ if (rawResponse.error && !IGNORED_402_ERRORS.includes(rawResponse.error)) {
365
403
  console.error(`\u274C Payment verification failed: ${rawResponse.error}`);
366
- const ERROR_MESSAGES = {
367
- "insufficient_funds": "Insufficient balance to complete this payment",
368
- "invalid_signature": "Invalid payment signature",
369
- "expired": "Payment authorization has expired",
370
- "already_used": "This payment has already been used",
371
- "network_mismatch": "Payment network does not match",
372
- "invalid_payment": "Invalid payment data",
373
- "verification_failed": "Payment verification failed"
374
- };
375
- const errorMessage = ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
376
- const error = new Error(errorMessage);
377
- throw wrapPaymentError(error);
404
+ const errorMessage = PAYMENT_ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
405
+ throw wrapPaymentError(new Error(errorMessage));
378
406
  }
379
407
  const x402Version = rawResponse.x402Version;
380
408
  const parsedPaymentRequirements = rawResponse.accepts || [];
@@ -406,19 +434,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
406
434
  console.warn("\u26A0\uFE0F Failed to get current chainId:", error);
407
435
  }
408
436
  }
409
- const networkNames = {
410
- 1: "Ethereum Mainnet",
411
- 11155111: "Sepolia Testnet",
412
- 8453: "Base Mainnet",
413
- 84532: "Base Sepolia Testnet",
414
- 137: "Polygon Mainnet",
415
- 42161: "Arbitrum One",
416
- 10: "Optimism Mainnet"
417
- };
418
437
  if (currentChainId && currentChainId !== targetChainId) {
419
438
  if (!wallet.switchChain) {
420
- const currentNetworkName = networkNames[currentChainId] || `Chain ${currentChainId}`;
421
- const targetNetworkName = networkNames[targetChainId] || selectedRequirements.network;
439
+ const currentNetworkName = NETWORK_NAMES[currentChainId] || `Chain ${currentChainId}`;
440
+ const targetNetworkName = NETWORK_NAMES[targetChainId] || selectedRequirements.network;
422
441
  const error = new Error(
423
442
  `Network mismatch: Your wallet is connected to ${currentNetworkName}, but payment requires ${targetNetworkName}. Please switch to ${targetNetworkName} manually in your wallet.`
424
443
  );
@@ -430,7 +449,7 @@ async function handleEvmPayment(endpoint, config, requestInit) {
430
449
  console.log(`\u2705 Successfully switched to chain ${targetChainId}`);
431
450
  } catch (error) {
432
451
  console.error("\u274C Failed to switch chain:", error);
433
- const targetNetworkName = networkNames[targetChainId] || selectedRequirements.network;
452
+ const targetNetworkName = NETWORK_NAMES[targetChainId] || selectedRequirements.network;
434
453
  const wrappedError = wrapPaymentError(error);
435
454
  let finalError;
436
455
  if (wrappedError.code === "USER_REJECTED" /* USER_REJECTED */) {
@@ -484,25 +503,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
484
503
  if (retryResponse.status === 402) {
485
504
  try {
486
505
  const retryData = await retryResponse.json();
487
- const IGNORED_ERRORS2 = [
488
- "X-PAYMENT header is required",
489
- "missing X-PAYMENT header",
490
- "payment_required"
491
- ];
492
- if (retryData.error && !IGNORED_ERRORS2.includes(retryData.error)) {
506
+ if (retryData.error && !IGNORED_402_ERRORS.includes(retryData.error)) {
493
507
  console.error(`\u274C Payment verification failed: ${retryData.error}`);
494
- const ERROR_MESSAGES = {
495
- "insufficient_funds": "Insufficient balance to complete this payment",
496
- "invalid_signature": "Invalid payment signature",
497
- "expired": "Payment authorization has expired",
498
- "already_used": "This payment has already been used",
499
- "network_mismatch": "Payment network does not match",
500
- "invalid_payment": "Invalid payment data",
501
- "verification_failed": "Payment verification failed"
502
- };
503
- const errorMessage = ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
504
- const error = new Error(errorMessage);
505
- throw wrapPaymentError(error);
508
+ const errorMessage = PAYMENT_ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
509
+ throw wrapPaymentError(new Error(errorMessage));
506
510
  }
507
511
  } catch (error) {
508
512
  if (error instanceof PaymentOperationError) {
@@ -533,9 +537,9 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
533
537
  }
534
538
  } : {};
535
539
  if (networkType === "solana" /* SOLANA */ || networkType === "svm" /* SVM */) {
536
- const solana = window.solana;
540
+ const solana = getWalletProviderForPayment(networkType);
537
541
  if (!solana) {
538
- throw new Error("\u8BF7\u5B89\u88C5 Phantom \u94B1\u5305");
542
+ throw new Error("\u8BF7\u5148\u8FDE\u63A5 Solana \u94B1\u5305");
539
543
  }
540
544
  if (!solana.isConnected) {
541
545
  await solana.connect();
@@ -546,10 +550,11 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
546
550
  // Will use backend's network configuration
547
551
  }, requestInit);
548
552
  } else if (networkType === "evm" /* EVM */) {
549
- if (!window.ethereum) {
550
- throw new Error("\u8BF7\u5B89\u88C5 MetaMask \u94B1\u5305");
553
+ const ethereum = getWalletProviderForPayment(networkType);
554
+ if (!ethereum) {
555
+ throw new Error("\u8BF7\u5148\u8FDE\u63A5 EVM \u94B1\u5305");
551
556
  }
552
- const provider = new import_ethers2.ethers.BrowserProvider(window.ethereum);
557
+ const provider = new import_ethers2.ethers.BrowserProvider(ethereum);
553
558
  const signer = await provider.getSigner();
554
559
  const wallet = {
555
560
  address: await signer.getAddress(),
@@ -563,7 +568,7 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
563
568
  },
564
569
  // Switch to a different chain
565
570
  switchChain: async (chainId) => {
566
- await window.ethereum.request({
571
+ await ethereum.request({
567
572
  method: "wallet_switchEthereumChain",
568
573
  params: [{ chainId }]
569
574
  });
@@ -650,6 +655,21 @@ function is402Response(response) {
650
655
  }
651
656
 
652
657
  // src/utils/payment-error-handler.ts
658
+ var IGNORED_402_ERRORS = [
659
+ "X-PAYMENT header is required",
660
+ "missing X-PAYMENT header",
661
+ "payment_required"
662
+ ];
663
+ var PAYMENT_ERROR_MESSAGES = {
664
+ "insufficient_funds": "Insufficient balance to complete this payment",
665
+ "invalid_signature": "Invalid payment signature",
666
+ "expired": "Payment authorization has expired",
667
+ "already_used": "This payment has already been used",
668
+ "network_mismatch": "Payment network does not match",
669
+ "invalid_payment": "Invalid payment data",
670
+ "verification_failed": "Payment verification failed",
671
+ "invalid_exact_svm_payload_transaction_simulation_failed": "Transaction simulation failed due to insufficient balance. Please check your wallet balance carefully and ensure you have enough funds to cover the payment and transaction fees."
672
+ };
653
673
  function parsePaymentError(error) {
654
674
  if (!error) {
655
675
  return {
@@ -784,7 +804,7 @@ function wrapPaymentError(error) {
784
804
  // src/services/svm/payment-header.ts
785
805
  async function createSvmPaymentHeader(params) {
786
806
  const { wallet, paymentRequirements, x402Version, rpcUrl } = params;
787
- const connection = new import_web3.Connection(rpcUrl, "confirmed");
807
+ const connection = new import_web3.Connection(rpcUrl);
788
808
  const feePayer = paymentRequirements?.extra?.feePayer;
789
809
  if (typeof feePayer !== "string" || !feePayer) {
790
810
  throw new Error("Missing facilitator feePayer in payment requirements (extra.feePayer).");
@@ -798,83 +818,85 @@ async function createSvmPaymentHeader(params) {
798
818
  if (!paymentRequirements?.payTo) {
799
819
  throw new Error("Missing payTo in payment requirements");
800
820
  }
801
- const destination = new import_web3.PublicKey(paymentRequirements.payTo);
802
- const instructions = [];
803
- instructions.push(
804
- import_web3.ComputeBudgetProgram.setComputeUnitLimit({
805
- units: 7e3
806
- // Sufficient for SPL token transfer
807
- })
808
- );
809
- instructions.push(
810
- import_web3.ComputeBudgetProgram.setComputeUnitPrice({
811
- microLamports: 1
812
- // Minimal price
813
- })
814
- );
821
+ const destinationPubkey = new import_web3.PublicKey(paymentRequirements.payTo);
815
822
  if (!paymentRequirements.asset) {
816
823
  throw new Error("Missing token mint for SPL transfer");
817
824
  }
818
825
  const mintPubkey = new import_web3.PublicKey(paymentRequirements.asset);
819
- const mintInfo = await connection.getAccountInfo(mintPubkey, "confirmed");
820
- const programId = mintInfo?.owner?.toBase58() === import_spl_token.TOKEN_2022_PROGRAM_ID.toBase58() ? import_spl_token.TOKEN_2022_PROGRAM_ID : import_spl_token.TOKEN_PROGRAM_ID;
821
- const mint = await (0, import_spl_token.getMint)(connection, mintPubkey, void 0, programId);
822
- const sourceAta = await (0, import_spl_token.getAssociatedTokenAddress)(
826
+ const mintAccountInfo = await connection.getAccountInfo(mintPubkey);
827
+ if (!mintAccountInfo) {
828
+ throw new Error(`Mint account ${mintPubkey.toBase58()} not found`);
829
+ }
830
+ const tokenProgramId = mintAccountInfo.owner.equals(import_spl_token.TOKEN_2022_PROGRAM_ID) ? import_spl_token.TOKEN_2022_PROGRAM_ID : import_spl_token.TOKEN_PROGRAM_ID;
831
+ const mint = await (0, import_spl_token.getMint)(connection, mintPubkey, void 0, tokenProgramId);
832
+ const sourceAta = (0, import_spl_token.getAssociatedTokenAddressSync)(
823
833
  mintPubkey,
824
834
  userPubkey,
825
835
  false,
826
- programId
836
+ tokenProgramId
827
837
  );
828
- const destinationAta = await (0, import_spl_token.getAssociatedTokenAddress)(
838
+ const destinationAta = (0, import_spl_token.getAssociatedTokenAddressSync)(
829
839
  mintPubkey,
830
- destination,
840
+ destinationPubkey,
831
841
  false,
832
- programId
842
+ tokenProgramId
833
843
  );
834
- const sourceAtaInfo = await connection.getAccountInfo(sourceAta, "confirmed");
844
+ const sourceAtaInfo = await connection.getAccountInfo(sourceAta);
835
845
  if (!sourceAtaInfo) {
836
846
  throw new Error(
837
847
  `User does not have an Associated Token Account for ${paymentRequirements.asset}. Please create one first or ensure you have the required token.`
838
848
  );
839
849
  }
840
- const destAtaInfo = await connection.getAccountInfo(destinationAta, "confirmed");
850
+ const destAtaInfo = await connection.getAccountInfo(destinationAta);
841
851
  if (!destAtaInfo) {
842
852
  throw new Error(
843
853
  `Destination does not have an Associated Token Account for ${paymentRequirements.asset}. The receiver must create their token account before receiving payments.`
844
854
  );
845
855
  }
846
- const amount = BigInt(paymentRequirements.maxAmountRequired);
847
- instructions.push(
856
+ const instructions = [
857
+ import_web3.ComputeBudgetProgram.setComputeUnitLimit({
858
+ units: 7e3
859
+ // Sufficient for SPL token transfer
860
+ }),
861
+ import_web3.ComputeBudgetProgram.setComputeUnitPrice({
862
+ microLamports: 1
863
+ // Minimal price
864
+ }),
848
865
  (0, import_spl_token.createTransferCheckedInstruction)(
849
866
  sourceAta,
850
867
  mintPubkey,
851
868
  destinationAta,
852
869
  userPubkey,
853
- amount,
870
+ BigInt(paymentRequirements.maxAmountRequired),
854
871
  mint.decimals,
855
872
  [],
856
- programId
873
+ tokenProgramId
857
874
  )
858
- );
859
- const { blockhash } = await connection.getLatestBlockhash("confirmed");
860
- const message = new import_web3.TransactionMessage({
875
+ ];
876
+ const { blockhash } = await connection.getLatestBlockhash();
877
+ const messageV0 = new import_web3.TransactionMessage({
861
878
  payerKey: feePayerPubkey,
862
879
  recentBlockhash: blockhash,
863
880
  instructions
864
881
  }).compileToV0Message();
865
- const transaction = new import_web3.VersionedTransaction(message);
882
+ const transaction = new import_web3.VersionedTransaction(messageV0);
866
883
  if (typeof wallet?.signTransaction !== "function") {
867
884
  throw new Error("Connected wallet does not support signTransaction");
868
885
  }
869
- let userSignedTx;
886
+ let signedTransaction;
870
887
  try {
871
- userSignedTx = await wallet.signTransaction(transaction);
888
+ signedTransaction = await wallet.signTransaction(transaction);
872
889
  console.log("\u2705 Transaction signed successfully");
873
890
  } catch (error) {
874
891
  console.error("\u274C Failed to sign transaction:", error);
875
892
  throw wrapPaymentError(error);
876
893
  }
877
- const serializedTransaction = Buffer.from(userSignedTx.serialize()).toString("base64");
894
+ const serializedBytes = signedTransaction.serialize();
895
+ let binary = "";
896
+ for (let i = 0; i < serializedBytes.length; i++) {
897
+ binary += String.fromCharCode(serializedBytes[i]);
898
+ }
899
+ const serializedTransaction = btoa(binary);
878
900
  const paymentPayload = {
879
901
  x402Version,
880
902
  scheme: paymentRequirements.scheme,
@@ -883,7 +905,7 @@ async function createSvmPaymentHeader(params) {
883
905
  transaction: serializedTransaction
884
906
  }
885
907
  };
886
- const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
908
+ const paymentHeader = btoa(JSON.stringify(paymentPayload));
887
909
  return paymentHeader;
888
910
  }
889
911
  function getDefaultSolanaRpcUrl(network) {
@@ -899,7 +921,7 @@ function getDefaultSolanaRpcUrl(network) {
899
921
  // src/services/svm/payment-handler.ts
900
922
  init_types();
901
923
  async function handleSvmPayment(endpoint, config, requestInit) {
902
- const { wallet, network, rpcUrl, maxPaymentAmount } = config;
924
+ const { wallet, rpcUrl, maxPaymentAmount } = config;
903
925
  const initialResponse = await fetch(endpoint, {
904
926
  ...requestInit,
905
927
  method: requestInit?.method || "POST"
@@ -908,26 +930,10 @@ async function handleSvmPayment(endpoint, config, requestInit) {
908
930
  return initialResponse;
909
931
  }
910
932
  const rawResponse = await initialResponse.json();
911
- const IGNORED_ERRORS = [
912
- "X-PAYMENT header is required",
913
- "missing X-PAYMENT header",
914
- "payment_required"
915
- ];
916
- if (rawResponse.error && !IGNORED_ERRORS.includes(rawResponse.error)) {
933
+ if (rawResponse.error && !IGNORED_402_ERRORS.includes(rawResponse.error)) {
917
934
  console.error(`\u274C Payment verification failed: ${rawResponse.error}`);
918
- const ERROR_MESSAGES = {
919
- "insufficient_funds": "Insufficient balance to complete this payment",
920
- "invalid_signature": "Invalid payment signature",
921
- "expired": "Payment authorization has expired",
922
- "already_used": "This payment has already been used",
923
- "network_mismatch": "Payment network does not match",
924
- "invalid_payment": "Invalid payment data",
925
- "verification_failed": "Payment verification failed",
926
- "invalid_exact_svm_payload_transaction_simulation_failed": "Transaction simulation failed due to insufficient balance. Please check your wallet balance carefully and ensure you have enough funds to cover the payment and transaction fees."
927
- };
928
- const errorMessage = ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
929
- const error = new Error(errorMessage);
930
- throw wrapPaymentError(error);
935
+ const errorMessage = PAYMENT_ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
936
+ throw wrapPaymentError(new Error(errorMessage));
931
937
  }
932
938
  const x402Version = rawResponse.x402Version;
933
939
  const parsedPaymentRequirements = rawResponse.accepts || [];
@@ -977,26 +983,10 @@ async function handleSvmPayment(endpoint, config, requestInit) {
977
983
  if (retryResponse.status === 402) {
978
984
  try {
979
985
  const retryData = await retryResponse.json();
980
- const IGNORED_ERRORS2 = [
981
- "X-PAYMENT header is required",
982
- "missing X-PAYMENT header",
983
- "payment_required"
984
- ];
985
- if (retryData.error && !IGNORED_ERRORS2.includes(retryData.error)) {
986
+ if (retryData.error && !IGNORED_402_ERRORS.includes(retryData.error)) {
986
987
  console.error(`\u274C Payment verification failed: ${retryData.error}`);
987
- const ERROR_MESSAGES = {
988
- "insufficient_funds": "Insufficient balance to complete this payment",
989
- "invalid_signature": "Invalid payment signature",
990
- "expired": "Payment authorization has expired",
991
- "already_used": "This payment has already been used",
992
- "network_mismatch": "Payment network does not match",
993
- "invalid_payment": "Invalid payment data",
994
- "verification_failed": "Payment verification failed",
995
- "invalid_exact_svm_payload_transaction_simulation_failed": "Transaction simulation failed due to insufficient balance. Please check your wallet balance carefully and ensure you have enough funds to cover the payment and transaction fees."
996
- };
997
- const errorMessage = ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
998
- const error = new Error(errorMessage);
999
- throw wrapPaymentError(error);
988
+ const errorMessage = PAYMENT_ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
989
+ throw wrapPaymentError(new Error(errorMessage));
1000
990
  }
1001
991
  } catch (error) {
1002
992
  if (error instanceof PaymentOperationError) {