@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/README.md +467 -130
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +121 -131
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +123 -139
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +39 -9
- package/dist/react/index.d.ts +39 -9
- package/dist/react/index.js +818 -248
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +836 -257
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/styles.css +1 -1
- package/package.json +9 -2
package/dist/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ var PROD_BACK_URL;
|
|
|
8
8
|
var init_common = __esm({
|
|
9
9
|
"src/types/common.ts"() {
|
|
10
10
|
"use strict";
|
|
11
|
-
PROD_BACK_URL = "https://v402pay.onvoyage.ai/api/pay";
|
|
11
|
+
PROD_BACK_URL = true ? "https://v402pay.onvoyage.ai/api/pay" : "https://v402pay.onvoyage.ai/api/pay";
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -183,16 +183,10 @@ var init_wallet = __esm({
|
|
|
183
183
|
init_types();
|
|
184
184
|
|
|
185
185
|
// src/services/svm/payment-header.ts
|
|
186
|
-
import {
|
|
187
|
-
ComputeBudgetProgram,
|
|
188
|
-
Connection,
|
|
189
|
-
PublicKey,
|
|
190
|
-
TransactionMessage,
|
|
191
|
-
VersionedTransaction
|
|
192
|
-
} from "@solana/web3.js";
|
|
186
|
+
import { ComputeBudgetProgram, Connection, PublicKey, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
|
|
193
187
|
import {
|
|
194
188
|
createTransferCheckedInstruction,
|
|
195
|
-
|
|
189
|
+
getAssociatedTokenAddressSync,
|
|
196
190
|
getMint,
|
|
197
191
|
TOKEN_2022_PROGRAM_ID,
|
|
198
192
|
TOKEN_PROGRAM_ID
|
|
@@ -201,6 +195,40 @@ import {
|
|
|
201
195
|
// src/utils/index.ts
|
|
202
196
|
init_wallet();
|
|
203
197
|
|
|
198
|
+
// src/utils/wallet-discovery.ts
|
|
199
|
+
var evmWallets = /* @__PURE__ */ new Map();
|
|
200
|
+
var evmDiscoveryListeners = /* @__PURE__ */ new Set();
|
|
201
|
+
var evmDiscoveryInitialized = false;
|
|
202
|
+
var currentConnectedWallet = null;
|
|
203
|
+
function initEVMWalletDiscovery() {
|
|
204
|
+
if (typeof window === "undefined" || evmDiscoveryInitialized) return;
|
|
205
|
+
evmDiscoveryInitialized = true;
|
|
206
|
+
window.addEventListener("eip6963:announceProvider", ((event) => {
|
|
207
|
+
const { info, provider } = event.detail;
|
|
208
|
+
evmWallets.set(info.uuid, { info, provider });
|
|
209
|
+
evmDiscoveryListeners.forEach((listener) => listener());
|
|
210
|
+
}));
|
|
211
|
+
window.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
212
|
+
}
|
|
213
|
+
function getWalletProviderForPayment(networkType) {
|
|
214
|
+
if (currentConnectedWallet && currentConnectedWallet.networkType === networkType) {
|
|
215
|
+
return currentConnectedWallet.provider;
|
|
216
|
+
}
|
|
217
|
+
if (typeof window === "undefined") return null;
|
|
218
|
+
switch (networkType) {
|
|
219
|
+
case "evm" /* EVM */:
|
|
220
|
+
return window.ethereum;
|
|
221
|
+
case "solana" /* SOLANA */:
|
|
222
|
+
case "svm" /* SVM */:
|
|
223
|
+
return window.phantom?.solana || window.solana;
|
|
224
|
+
default:
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (typeof window !== "undefined") {
|
|
229
|
+
initEVMWalletDiscovery();
|
|
230
|
+
}
|
|
231
|
+
|
|
204
232
|
// src/services/evm/payment-header.ts
|
|
205
233
|
import { ethers } from "ethers";
|
|
206
234
|
async function createEvmPaymentHeader(params) {
|
|
@@ -316,6 +344,15 @@ function getChainIdFromNetwork(network) {
|
|
|
316
344
|
|
|
317
345
|
// src/services/evm/payment-handler.ts
|
|
318
346
|
init_types();
|
|
347
|
+
var NETWORK_NAMES = {
|
|
348
|
+
1: "Ethereum Mainnet",
|
|
349
|
+
11155111: "Sepolia Testnet",
|
|
350
|
+
8453: "Base Mainnet",
|
|
351
|
+
84532: "Base Sepolia Testnet",
|
|
352
|
+
137: "Polygon Mainnet",
|
|
353
|
+
42161: "Arbitrum One",
|
|
354
|
+
10: "Optimism Mainnet"
|
|
355
|
+
};
|
|
319
356
|
async function handleEvmPayment(endpoint, config, requestInit) {
|
|
320
357
|
const { wallet, network, maxPaymentAmount } = config;
|
|
321
358
|
const initialResponse = await fetch(endpoint, {
|
|
@@ -326,25 +363,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
|
|
|
326
363
|
return initialResponse;
|
|
327
364
|
}
|
|
328
365
|
const rawResponse = await initialResponse.json();
|
|
329
|
-
|
|
330
|
-
"X-PAYMENT header is required",
|
|
331
|
-
"missing X-PAYMENT header",
|
|
332
|
-
"payment_required"
|
|
333
|
-
];
|
|
334
|
-
if (rawResponse.error && !IGNORED_ERRORS.includes(rawResponse.error)) {
|
|
366
|
+
if (rawResponse.error && !IGNORED_402_ERRORS.includes(rawResponse.error)) {
|
|
335
367
|
console.error(`\u274C Payment verification failed: ${rawResponse.error}`);
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
"invalid_signature": "Invalid payment signature",
|
|
339
|
-
"expired": "Payment authorization has expired",
|
|
340
|
-
"already_used": "This payment has already been used",
|
|
341
|
-
"network_mismatch": "Payment network does not match",
|
|
342
|
-
"invalid_payment": "Invalid payment data",
|
|
343
|
-
"verification_failed": "Payment verification failed"
|
|
344
|
-
};
|
|
345
|
-
const errorMessage = ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
|
|
346
|
-
const error = new Error(errorMessage);
|
|
347
|
-
throw wrapPaymentError(error);
|
|
368
|
+
const errorMessage = PAYMENT_ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
|
|
369
|
+
throw wrapPaymentError(new Error(errorMessage));
|
|
348
370
|
}
|
|
349
371
|
const x402Version = rawResponse.x402Version;
|
|
350
372
|
const parsedPaymentRequirements = rawResponse.accepts || [];
|
|
@@ -376,19 +398,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
|
|
|
376
398
|
console.warn("\u26A0\uFE0F Failed to get current chainId:", error);
|
|
377
399
|
}
|
|
378
400
|
}
|
|
379
|
-
const networkNames = {
|
|
380
|
-
1: "Ethereum Mainnet",
|
|
381
|
-
11155111: "Sepolia Testnet",
|
|
382
|
-
8453: "Base Mainnet",
|
|
383
|
-
84532: "Base Sepolia Testnet",
|
|
384
|
-
137: "Polygon Mainnet",
|
|
385
|
-
42161: "Arbitrum One",
|
|
386
|
-
10: "Optimism Mainnet"
|
|
387
|
-
};
|
|
388
401
|
if (currentChainId && currentChainId !== targetChainId) {
|
|
389
402
|
if (!wallet.switchChain) {
|
|
390
|
-
const currentNetworkName =
|
|
391
|
-
const targetNetworkName =
|
|
403
|
+
const currentNetworkName = NETWORK_NAMES[currentChainId] || `Chain ${currentChainId}`;
|
|
404
|
+
const targetNetworkName = NETWORK_NAMES[targetChainId] || selectedRequirements.network;
|
|
392
405
|
const error = new Error(
|
|
393
406
|
`Network mismatch: Your wallet is connected to ${currentNetworkName}, but payment requires ${targetNetworkName}. Please switch to ${targetNetworkName} manually in your wallet.`
|
|
394
407
|
);
|
|
@@ -400,7 +413,7 @@ async function handleEvmPayment(endpoint, config, requestInit) {
|
|
|
400
413
|
console.log(`\u2705 Successfully switched to chain ${targetChainId}`);
|
|
401
414
|
} catch (error) {
|
|
402
415
|
console.error("\u274C Failed to switch chain:", error);
|
|
403
|
-
const targetNetworkName =
|
|
416
|
+
const targetNetworkName = NETWORK_NAMES[targetChainId] || selectedRequirements.network;
|
|
404
417
|
const wrappedError = wrapPaymentError(error);
|
|
405
418
|
let finalError;
|
|
406
419
|
if (wrappedError.code === "USER_REJECTED" /* USER_REJECTED */) {
|
|
@@ -454,25 +467,10 @@ async function handleEvmPayment(endpoint, config, requestInit) {
|
|
|
454
467
|
if (retryResponse.status === 402) {
|
|
455
468
|
try {
|
|
456
469
|
const retryData = await retryResponse.json();
|
|
457
|
-
|
|
458
|
-
"X-PAYMENT header is required",
|
|
459
|
-
"missing X-PAYMENT header",
|
|
460
|
-
"payment_required"
|
|
461
|
-
];
|
|
462
|
-
if (retryData.error && !IGNORED_ERRORS2.includes(retryData.error)) {
|
|
470
|
+
if (retryData.error && !IGNORED_402_ERRORS.includes(retryData.error)) {
|
|
463
471
|
console.error(`\u274C Payment verification failed: ${retryData.error}`);
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
"invalid_signature": "Invalid payment signature",
|
|
467
|
-
"expired": "Payment authorization has expired",
|
|
468
|
-
"already_used": "This payment has already been used",
|
|
469
|
-
"network_mismatch": "Payment network does not match",
|
|
470
|
-
"invalid_payment": "Invalid payment data",
|
|
471
|
-
"verification_failed": "Payment verification failed"
|
|
472
|
-
};
|
|
473
|
-
const errorMessage = ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
|
|
474
|
-
const error = new Error(errorMessage);
|
|
475
|
-
throw wrapPaymentError(error);
|
|
472
|
+
const errorMessage = PAYMENT_ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
|
|
473
|
+
throw wrapPaymentError(new Error(errorMessage));
|
|
476
474
|
}
|
|
477
475
|
} catch (error) {
|
|
478
476
|
if (error instanceof PaymentOperationError) {
|
|
@@ -503,9 +501,9 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
|
|
|
503
501
|
}
|
|
504
502
|
} : {};
|
|
505
503
|
if (networkType === "solana" /* SOLANA */ || networkType === "svm" /* SVM */) {
|
|
506
|
-
const solana =
|
|
504
|
+
const solana = getWalletProviderForPayment(networkType);
|
|
507
505
|
if (!solana) {
|
|
508
|
-
throw new Error("\u8BF7\
|
|
506
|
+
throw new Error("\u8BF7\u5148\u8FDE\u63A5 Solana \u94B1\u5305");
|
|
509
507
|
}
|
|
510
508
|
if (!solana.isConnected) {
|
|
511
509
|
await solana.connect();
|
|
@@ -516,10 +514,11 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
|
|
|
516
514
|
// Will use backend's network configuration
|
|
517
515
|
}, requestInit);
|
|
518
516
|
} else if (networkType === "evm" /* EVM */) {
|
|
519
|
-
|
|
520
|
-
|
|
517
|
+
const ethereum = getWalletProviderForPayment(networkType);
|
|
518
|
+
if (!ethereum) {
|
|
519
|
+
throw new Error("\u8BF7\u5148\u8FDE\u63A5 EVM \u94B1\u5305");
|
|
521
520
|
}
|
|
522
|
-
const provider = new ethers2.BrowserProvider(
|
|
521
|
+
const provider = new ethers2.BrowserProvider(ethereum);
|
|
523
522
|
const signer = await provider.getSigner();
|
|
524
523
|
const wallet = {
|
|
525
524
|
address: await signer.getAddress(),
|
|
@@ -533,7 +532,7 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, ad
|
|
|
533
532
|
},
|
|
534
533
|
// Switch to a different chain
|
|
535
534
|
switchChain: async (chainId) => {
|
|
536
|
-
await
|
|
535
|
+
await ethereum.request({
|
|
537
536
|
method: "wallet_switchEthereumChain",
|
|
538
537
|
params: [{ chainId }]
|
|
539
538
|
});
|
|
@@ -620,6 +619,21 @@ function is402Response(response) {
|
|
|
620
619
|
}
|
|
621
620
|
|
|
622
621
|
// src/utils/payment-error-handler.ts
|
|
622
|
+
var IGNORED_402_ERRORS = [
|
|
623
|
+
"X-PAYMENT header is required",
|
|
624
|
+
"missing X-PAYMENT header",
|
|
625
|
+
"payment_required"
|
|
626
|
+
];
|
|
627
|
+
var PAYMENT_ERROR_MESSAGES = {
|
|
628
|
+
"insufficient_funds": "Insufficient balance to complete this payment",
|
|
629
|
+
"invalid_signature": "Invalid payment signature",
|
|
630
|
+
"expired": "Payment authorization has expired",
|
|
631
|
+
"already_used": "This payment has already been used",
|
|
632
|
+
"network_mismatch": "Payment network does not match",
|
|
633
|
+
"invalid_payment": "Invalid payment data",
|
|
634
|
+
"verification_failed": "Payment verification failed",
|
|
635
|
+
"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."
|
|
636
|
+
};
|
|
623
637
|
function parsePaymentError(error) {
|
|
624
638
|
if (!error) {
|
|
625
639
|
return {
|
|
@@ -754,7 +768,7 @@ function wrapPaymentError(error) {
|
|
|
754
768
|
// src/services/svm/payment-header.ts
|
|
755
769
|
async function createSvmPaymentHeader(params) {
|
|
756
770
|
const { wallet, paymentRequirements, x402Version, rpcUrl } = params;
|
|
757
|
-
const connection = new Connection(rpcUrl
|
|
771
|
+
const connection = new Connection(rpcUrl);
|
|
758
772
|
const feePayer = paymentRequirements?.extra?.feePayer;
|
|
759
773
|
if (typeof feePayer !== "string" || !feePayer) {
|
|
760
774
|
throw new Error("Missing facilitator feePayer in payment requirements (extra.feePayer).");
|
|
@@ -768,83 +782,85 @@ async function createSvmPaymentHeader(params) {
|
|
|
768
782
|
if (!paymentRequirements?.payTo) {
|
|
769
783
|
throw new Error("Missing payTo in payment requirements");
|
|
770
784
|
}
|
|
771
|
-
const
|
|
772
|
-
const instructions = [];
|
|
773
|
-
instructions.push(
|
|
774
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
775
|
-
units: 7e3
|
|
776
|
-
// Sufficient for SPL token transfer
|
|
777
|
-
})
|
|
778
|
-
);
|
|
779
|
-
instructions.push(
|
|
780
|
-
ComputeBudgetProgram.setComputeUnitPrice({
|
|
781
|
-
microLamports: 1
|
|
782
|
-
// Minimal price
|
|
783
|
-
})
|
|
784
|
-
);
|
|
785
|
+
const destinationPubkey = new PublicKey(paymentRequirements.payTo);
|
|
785
786
|
if (!paymentRequirements.asset) {
|
|
786
787
|
throw new Error("Missing token mint for SPL transfer");
|
|
787
788
|
}
|
|
788
789
|
const mintPubkey = new PublicKey(paymentRequirements.asset);
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
790
|
+
const mintAccountInfo = await connection.getAccountInfo(mintPubkey);
|
|
791
|
+
if (!mintAccountInfo) {
|
|
792
|
+
throw new Error(`Mint account ${mintPubkey.toBase58()} not found`);
|
|
793
|
+
}
|
|
794
|
+
const tokenProgramId = mintAccountInfo.owner.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;
|
|
795
|
+
const mint = await getMint(connection, mintPubkey, void 0, tokenProgramId);
|
|
796
|
+
const sourceAta = getAssociatedTokenAddressSync(
|
|
793
797
|
mintPubkey,
|
|
794
798
|
userPubkey,
|
|
795
799
|
false,
|
|
796
|
-
|
|
800
|
+
tokenProgramId
|
|
797
801
|
);
|
|
798
|
-
const destinationAta =
|
|
802
|
+
const destinationAta = getAssociatedTokenAddressSync(
|
|
799
803
|
mintPubkey,
|
|
800
|
-
|
|
804
|
+
destinationPubkey,
|
|
801
805
|
false,
|
|
802
|
-
|
|
806
|
+
tokenProgramId
|
|
803
807
|
);
|
|
804
|
-
const sourceAtaInfo = await connection.getAccountInfo(sourceAta
|
|
808
|
+
const sourceAtaInfo = await connection.getAccountInfo(sourceAta);
|
|
805
809
|
if (!sourceAtaInfo) {
|
|
806
810
|
throw new Error(
|
|
807
811
|
`User does not have an Associated Token Account for ${paymentRequirements.asset}. Please create one first or ensure you have the required token.`
|
|
808
812
|
);
|
|
809
813
|
}
|
|
810
|
-
const destAtaInfo = await connection.getAccountInfo(destinationAta
|
|
814
|
+
const destAtaInfo = await connection.getAccountInfo(destinationAta);
|
|
811
815
|
if (!destAtaInfo) {
|
|
812
816
|
throw new Error(
|
|
813
817
|
`Destination does not have an Associated Token Account for ${paymentRequirements.asset}. The receiver must create their token account before receiving payments.`
|
|
814
818
|
);
|
|
815
819
|
}
|
|
816
|
-
const
|
|
817
|
-
|
|
820
|
+
const instructions = [
|
|
821
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
822
|
+
units: 7e3
|
|
823
|
+
// Sufficient for SPL token transfer
|
|
824
|
+
}),
|
|
825
|
+
ComputeBudgetProgram.setComputeUnitPrice({
|
|
826
|
+
microLamports: 1
|
|
827
|
+
// Minimal price
|
|
828
|
+
}),
|
|
818
829
|
createTransferCheckedInstruction(
|
|
819
830
|
sourceAta,
|
|
820
831
|
mintPubkey,
|
|
821
832
|
destinationAta,
|
|
822
833
|
userPubkey,
|
|
823
|
-
|
|
834
|
+
BigInt(paymentRequirements.maxAmountRequired),
|
|
824
835
|
mint.decimals,
|
|
825
836
|
[],
|
|
826
|
-
|
|
837
|
+
tokenProgramId
|
|
827
838
|
)
|
|
828
|
-
|
|
829
|
-
const { blockhash } = await connection.getLatestBlockhash(
|
|
830
|
-
const
|
|
839
|
+
];
|
|
840
|
+
const { blockhash } = await connection.getLatestBlockhash();
|
|
841
|
+
const messageV0 = new TransactionMessage({
|
|
831
842
|
payerKey: feePayerPubkey,
|
|
832
843
|
recentBlockhash: blockhash,
|
|
833
844
|
instructions
|
|
834
845
|
}).compileToV0Message();
|
|
835
|
-
const transaction = new VersionedTransaction(
|
|
846
|
+
const transaction = new VersionedTransaction(messageV0);
|
|
836
847
|
if (typeof wallet?.signTransaction !== "function") {
|
|
837
848
|
throw new Error("Connected wallet does not support signTransaction");
|
|
838
849
|
}
|
|
839
|
-
let
|
|
850
|
+
let signedTransaction;
|
|
840
851
|
try {
|
|
841
|
-
|
|
852
|
+
signedTransaction = await wallet.signTransaction(transaction);
|
|
842
853
|
console.log("\u2705 Transaction signed successfully");
|
|
843
854
|
} catch (error) {
|
|
844
855
|
console.error("\u274C Failed to sign transaction:", error);
|
|
845
856
|
throw wrapPaymentError(error);
|
|
846
857
|
}
|
|
847
|
-
const
|
|
858
|
+
const serializedBytes = signedTransaction.serialize();
|
|
859
|
+
let binary = "";
|
|
860
|
+
for (let i = 0; i < serializedBytes.length; i++) {
|
|
861
|
+
binary += String.fromCharCode(serializedBytes[i]);
|
|
862
|
+
}
|
|
863
|
+
const serializedTransaction = btoa(binary);
|
|
848
864
|
const paymentPayload = {
|
|
849
865
|
x402Version,
|
|
850
866
|
scheme: paymentRequirements.scheme,
|
|
@@ -853,7 +869,7 @@ async function createSvmPaymentHeader(params) {
|
|
|
853
869
|
transaction: serializedTransaction
|
|
854
870
|
}
|
|
855
871
|
};
|
|
856
|
-
const paymentHeader =
|
|
872
|
+
const paymentHeader = btoa(JSON.stringify(paymentPayload));
|
|
857
873
|
return paymentHeader;
|
|
858
874
|
}
|
|
859
875
|
function getDefaultSolanaRpcUrl(network) {
|
|
@@ -869,7 +885,7 @@ function getDefaultSolanaRpcUrl(network) {
|
|
|
869
885
|
// src/services/svm/payment-handler.ts
|
|
870
886
|
init_types();
|
|
871
887
|
async function handleSvmPayment(endpoint, config, requestInit) {
|
|
872
|
-
const { wallet,
|
|
888
|
+
const { wallet, rpcUrl, maxPaymentAmount } = config;
|
|
873
889
|
const initialResponse = await fetch(endpoint, {
|
|
874
890
|
...requestInit,
|
|
875
891
|
method: requestInit?.method || "POST"
|
|
@@ -878,26 +894,10 @@ async function handleSvmPayment(endpoint, config, requestInit) {
|
|
|
878
894
|
return initialResponse;
|
|
879
895
|
}
|
|
880
896
|
const rawResponse = await initialResponse.json();
|
|
881
|
-
|
|
882
|
-
"X-PAYMENT header is required",
|
|
883
|
-
"missing X-PAYMENT header",
|
|
884
|
-
"payment_required"
|
|
885
|
-
];
|
|
886
|
-
if (rawResponse.error && !IGNORED_ERRORS.includes(rawResponse.error)) {
|
|
897
|
+
if (rawResponse.error && !IGNORED_402_ERRORS.includes(rawResponse.error)) {
|
|
887
898
|
console.error(`\u274C Payment verification failed: ${rawResponse.error}`);
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
"invalid_signature": "Invalid payment signature",
|
|
891
|
-
"expired": "Payment authorization has expired",
|
|
892
|
-
"already_used": "This payment has already been used",
|
|
893
|
-
"network_mismatch": "Payment network does not match",
|
|
894
|
-
"invalid_payment": "Invalid payment data",
|
|
895
|
-
"verification_failed": "Payment verification failed",
|
|
896
|
-
"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."
|
|
897
|
-
};
|
|
898
|
-
const errorMessage = ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
|
|
899
|
-
const error = new Error(errorMessage);
|
|
900
|
-
throw wrapPaymentError(error);
|
|
899
|
+
const errorMessage = PAYMENT_ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
|
|
900
|
+
throw wrapPaymentError(new Error(errorMessage));
|
|
901
901
|
}
|
|
902
902
|
const x402Version = rawResponse.x402Version;
|
|
903
903
|
const parsedPaymentRequirements = rawResponse.accepts || [];
|
|
@@ -947,26 +947,10 @@ async function handleSvmPayment(endpoint, config, requestInit) {
|
|
|
947
947
|
if (retryResponse.status === 402) {
|
|
948
948
|
try {
|
|
949
949
|
const retryData = await retryResponse.json();
|
|
950
|
-
|
|
951
|
-
"X-PAYMENT header is required",
|
|
952
|
-
"missing X-PAYMENT header",
|
|
953
|
-
"payment_required"
|
|
954
|
-
];
|
|
955
|
-
if (retryData.error && !IGNORED_ERRORS2.includes(retryData.error)) {
|
|
950
|
+
if (retryData.error && !IGNORED_402_ERRORS.includes(retryData.error)) {
|
|
956
951
|
console.error(`\u274C Payment verification failed: ${retryData.error}`);
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
"invalid_signature": "Invalid payment signature",
|
|
960
|
-
"expired": "Payment authorization has expired",
|
|
961
|
-
"already_used": "This payment has already been used",
|
|
962
|
-
"network_mismatch": "Payment network does not match",
|
|
963
|
-
"invalid_payment": "Invalid payment data",
|
|
964
|
-
"verification_failed": "Payment verification failed",
|
|
965
|
-
"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."
|
|
966
|
-
};
|
|
967
|
-
const errorMessage = ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
|
|
968
|
-
const error = new Error(errorMessage);
|
|
969
|
-
throw wrapPaymentError(error);
|
|
952
|
+
const errorMessage = PAYMENT_ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
|
|
953
|
+
throw wrapPaymentError(new Error(errorMessage));
|
|
970
954
|
}
|
|
971
955
|
} catch (error) {
|
|
972
956
|
if (error instanceof PaymentOperationError) {
|