@voyage_ai/v402-web-ts 0.1.1 → 0.1.3

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.
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,64 +30,75 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
30
- // src/react/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- PaymentButton: () => PaymentButton,
34
- WalletConnect: () => WalletConnect,
35
- usePayment: () => usePayment,
36
- usePaymentInfo: () => usePaymentInfo,
37
- useWallet: () => useWallet
38
- });
39
- module.exports = __toCommonJS(index_exports);
40
-
41
- // src/react/hooks/useWalletStore.ts
42
- var import_react = require("react");
43
-
44
- // src/types/index.ts
45
- var import_types3 = require("x402/types");
46
-
47
33
  // src/types/common.ts
48
- var PROD_BACK_URL = "https://v402.onvoyage.ai/api/pay";
34
+ var PROD_BACK_URL, DEV_BACK_URL;
35
+ var init_common = __esm({
36
+ "src/types/common.ts"() {
37
+ "use strict";
38
+ PROD_BACK_URL = "https://v402.onvoyage.ai/api/pay";
39
+ DEV_BACK_URL = "http://localhost:3000/api/pay";
40
+ }
41
+ });
49
42
 
50
43
  // src/types/svm.ts
51
- var import_zod = require("zod");
52
- var import_types = require("x402/types");
53
- var SolanaNetworkSchema = import_zod.z.enum([
54
- "solana-devnet",
55
- "solana",
56
- "solana-mainnet"
57
- // Alias for mainnet
58
- ]);
59
- var SolanaPaymentPayloadSchema = import_zod.z.object({
60
- x402Version: import_zod.z.literal(1),
61
- scheme: import_zod.z.literal("exact"),
62
- network: SolanaNetworkSchema,
63
- payload: import_types.ExactSvmPayloadSchema
44
+ var import_zod, import_types, SolanaNetworkSchema, SolanaPaymentPayloadSchema;
45
+ var init_svm = __esm({
46
+ "src/types/svm.ts"() {
47
+ "use strict";
48
+ import_zod = require("zod");
49
+ import_types = require("x402/types");
50
+ SolanaNetworkSchema = import_zod.z.enum([
51
+ "solana-devnet",
52
+ "solana",
53
+ "solana-mainnet"
54
+ // Alias for mainnet
55
+ ]);
56
+ SolanaPaymentPayloadSchema = import_zod.z.object({
57
+ x402Version: import_zod.z.literal(1),
58
+ scheme: import_zod.z.literal("exact"),
59
+ network: SolanaNetworkSchema,
60
+ payload: import_types.ExactSvmPayloadSchema
61
+ });
62
+ }
64
63
  });
65
64
 
66
65
  // src/types/evm.ts
67
- var import_zod2 = require("zod");
68
- var import_types2 = require("x402/types");
69
- var EvmNetworkSchema = import_zod2.z.enum([
70
- "ethereum",
71
- "sepolia",
72
- "base",
73
- "base-sepolia",
74
- "polygon",
75
- "arbitrum",
76
- "optimism"
77
- ]);
78
- var EvmPaymentPayloadSchema = import_zod2.z.object({
79
- x402Version: import_zod2.z.literal(1),
80
- scheme: import_zod2.z.literal("exact"),
81
- network: EvmNetworkSchema,
82
- payload: import_types2.ExactEvmPayloadSchema
66
+ var import_zod2, import_types2, EvmNetworkSchema, EvmPaymentPayloadSchema;
67
+ var init_evm = __esm({
68
+ "src/types/evm.ts"() {
69
+ "use strict";
70
+ import_zod2 = require("zod");
71
+ import_types2 = require("x402/types");
72
+ EvmNetworkSchema = import_zod2.z.enum([
73
+ "ethereum",
74
+ "sepolia",
75
+ "base",
76
+ "base-sepolia",
77
+ "polygon",
78
+ "arbitrum",
79
+ "optimism"
80
+ ]);
81
+ EvmPaymentPayloadSchema = import_zod2.z.object({
82
+ x402Version: import_zod2.z.literal(1),
83
+ scheme: import_zod2.z.literal("exact"),
84
+ network: EvmNetworkSchema,
85
+ payload: import_types2.ExactEvmPayloadSchema
86
+ });
87
+ }
88
+ });
89
+
90
+ // src/types/index.ts
91
+ var import_types3;
92
+ var init_types = __esm({
93
+ "src/types/index.ts"() {
94
+ "use strict";
95
+ import_types3 = require("x402/types");
96
+ init_svm();
97
+ init_evm();
98
+ }
83
99
  });
84
100
 
85
101
  // src/utils/wallet.ts
86
- var WALLET_DISCONNECTED_KEY = "wallet_manually_disconnected";
87
- var CONNECTED_NETWORK_TYPE_KEY = "connected_network_type";
88
102
  function isWalletInstalled(networkType) {
89
103
  if (typeof window === "undefined") {
90
104
  return false;
@@ -105,22 +119,50 @@ function formatAddress(address) {
105
119
  }
106
120
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
107
121
  }
108
- function markWalletDisconnected() {
122
+ function getDisconnectedNetworks() {
123
+ if (typeof window === "undefined") {
124
+ return {};
125
+ }
126
+ try {
127
+ const cached = localStorage.getItem(WALLET_DISCONNECTED_NETWORKS_KEY);
128
+ return cached ? JSON.parse(cached) : {};
129
+ } catch (error) {
130
+ return {};
131
+ }
132
+ }
133
+ function markWalletDisconnected(networkType) {
109
134
  if (typeof window !== "undefined") {
110
- localStorage.setItem(WALLET_DISCONNECTED_KEY, "true");
111
- localStorage.removeItem(CONNECTED_NETWORK_TYPE_KEY);
135
+ if (networkType) {
136
+ const disconnected = getDisconnectedNetworks();
137
+ disconnected[networkType] = true;
138
+ localStorage.setItem(WALLET_DISCONNECTED_NETWORKS_KEY, JSON.stringify(disconnected));
139
+ } else {
140
+ localStorage.setItem(WALLET_DISCONNECTED_KEY, "true");
141
+ localStorage.removeItem(CONNECTED_NETWORK_TYPE_KEY);
142
+ }
112
143
  }
113
144
  }
114
- function clearWalletDisconnection() {
145
+ function clearWalletDisconnection(networkType) {
115
146
  if (typeof window !== "undefined") {
116
- localStorage.removeItem(WALLET_DISCONNECTED_KEY);
147
+ if (networkType) {
148
+ const disconnected = getDisconnectedNetworks();
149
+ delete disconnected[networkType];
150
+ localStorage.setItem(WALLET_DISCONNECTED_NETWORKS_KEY, JSON.stringify(disconnected));
151
+ } else {
152
+ localStorage.removeItem(WALLET_DISCONNECTED_KEY);
153
+ }
117
154
  }
118
155
  }
119
- function isWalletManuallyDisconnected() {
156
+ function isWalletManuallyDisconnected(networkType) {
120
157
  if (typeof window === "undefined") {
121
158
  return false;
122
159
  }
123
- return localStorage.getItem(WALLET_DISCONNECTED_KEY) === "true";
160
+ if (networkType) {
161
+ const disconnected = getDisconnectedNetworks();
162
+ return disconnected[networkType] === true;
163
+ } else {
164
+ return localStorage.getItem(WALLET_DISCONNECTED_KEY) === "true";
165
+ }
124
166
  }
125
167
  function saveConnectedNetworkType(networkType) {
126
168
  if (typeof window !== "undefined") {
@@ -145,8 +187,70 @@ function getWalletInstallUrl(networkType) {
145
187
  return "#";
146
188
  }
147
189
  }
190
+ function getAllWalletAddresses() {
191
+ if (typeof window === "undefined") {
192
+ return {};
193
+ }
194
+ try {
195
+ const cached = localStorage.getItem(WALLET_ADDRESSES_KEY);
196
+ return cached ? JSON.parse(cached) : {};
197
+ } catch (error) {
198
+ console.error("Failed to parse wallet addresses cache:", error);
199
+ return {};
200
+ }
201
+ }
202
+ function saveWalletAddress(networkType, address) {
203
+ if (typeof window === "undefined") {
204
+ return;
205
+ }
206
+ const addresses = getAllWalletAddresses();
207
+ addresses[networkType] = address;
208
+ localStorage.setItem(WALLET_ADDRESSES_KEY, JSON.stringify(addresses));
209
+ }
210
+ function getCachedWalletAddress(networkType) {
211
+ const addresses = getAllWalletAddresses();
212
+ return addresses[networkType] || null;
213
+ }
214
+ function removeWalletAddress(networkType) {
215
+ if (typeof window === "undefined") {
216
+ return;
217
+ }
218
+ const addresses = getAllWalletAddresses();
219
+ delete addresses[networkType];
220
+ localStorage.setItem(WALLET_ADDRESSES_KEY, JSON.stringify(addresses));
221
+ }
222
+ var WALLET_DISCONNECTED_KEY, WALLET_DISCONNECTED_NETWORKS_KEY, CONNECTED_NETWORK_TYPE_KEY, WALLET_ADDRESSES_KEY;
223
+ var init_wallet = __esm({
224
+ "src/utils/wallet.ts"() {
225
+ "use strict";
226
+ WALLET_DISCONNECTED_KEY = "wallet_manually_disconnected";
227
+ WALLET_DISCONNECTED_NETWORKS_KEY = "wallet_disconnected_networks";
228
+ CONNECTED_NETWORK_TYPE_KEY = "connected_network_type";
229
+ WALLET_ADDRESSES_KEY = "wallet_addresses_cache";
230
+ }
231
+ });
232
+
233
+ // src/react/index.ts
234
+ var index_exports = {};
235
+ __export(index_exports, {
236
+ V402Checkout: () => V402Checkout,
237
+ WalletConnect: () => WalletConnect,
238
+ usePageNetwork: () => usePageNetwork,
239
+ usePayment: () => usePayment,
240
+ usePaymentInfo: () => usePaymentInfo,
241
+ useWallet: () => useWallet
242
+ });
243
+ module.exports = __toCommonJS(index_exports);
244
+ var import_styles = require("./styles.css");
245
+
246
+ // src/react/hooks/useWalletStore.ts
247
+ var import_react = require("react");
248
+
249
+ // src/utils/index.ts
250
+ init_wallet();
148
251
 
149
252
  // src/utils/wallet-connect.ts
253
+ init_wallet();
150
254
  async function connectWallet(networkType) {
151
255
  if (typeof window === "undefined") {
152
256
  throw new Error("\u8BF7\u5728\u6D4F\u89C8\u5668\u73AF\u5883\u4E2D\u4F7F\u7528");
@@ -181,13 +285,11 @@ async function connectWallet(networkType) {
181
285
  default:
182
286
  throw new Error("\u4E0D\u652F\u6301\u7684\u7F51\u7EDC\u7C7B\u578B");
183
287
  }
184
- clearWalletDisconnection();
288
+ clearWalletDisconnection(networkType);
185
289
  saveConnectedNetworkType(networkType);
290
+ saveWalletAddress(networkType, address);
186
291
  return address;
187
292
  }
188
- function disconnectWallet() {
189
- markWalletDisconnected();
190
- }
191
293
  async function getCurrentWallet(networkType) {
192
294
  if (typeof window === "undefined") {
193
295
  return null;
@@ -196,28 +298,36 @@ async function getCurrentWallet(networkType) {
196
298
  if (!type) {
197
299
  return null;
198
300
  }
301
+ const cachedAddress = getCachedWalletAddress(type);
199
302
  try {
303
+ let currentAddress = null;
200
304
  switch (type) {
201
305
  case "evm" /* EVM */: {
202
- if (!window.ethereum) return null;
306
+ if (!window.ethereum) return cachedAddress;
203
307
  const accounts = await window.ethereum.request({
204
308
  method: "eth_accounts",
205
309
  params: []
206
310
  });
207
- return accounts && accounts.length > 0 ? accounts[0] : null;
311
+ currentAddress = accounts && accounts.length > 0 ? accounts[0] : null;
312
+ break;
208
313
  }
209
314
  case "solana" /* SOLANA */:
210
315
  case "svm" /* SVM */: {
211
316
  const solana = window.solana;
212
- if (!solana || !solana.isConnected) return null;
213
- return solana.publicKey?.toString() || null;
317
+ if (!solana || !solana.isConnected) return cachedAddress;
318
+ currentAddress = solana.publicKey?.toString() || null;
319
+ break;
214
320
  }
215
321
  default:
216
- return null;
322
+ return cachedAddress;
217
323
  }
324
+ if (currentAddress && currentAddress !== cachedAddress) {
325
+ saveWalletAddress(type, currentAddress);
326
+ }
327
+ return currentAddress || cachedAddress;
218
328
  } catch (error) {
219
329
  console.error("Failed to get current wallet:", error);
220
- return null;
330
+ return cachedAddress;
221
331
  }
222
332
  }
223
333
  function onAccountsChanged(callback) {
@@ -268,6 +378,18 @@ function onWalletDisconnect(callback) {
268
378
  solana.removeListener?.("disconnect", handler);
269
379
  };
270
380
  }
381
+ async function switchNetwork(networkType) {
382
+ const cachedAddress = getCachedWalletAddress(networkType);
383
+ if (cachedAddress) {
384
+ saveConnectedNetworkType(networkType);
385
+ clearWalletDisconnection(networkType);
386
+ const currentAddress = await getCurrentWallet(networkType);
387
+ if (currentAddress) {
388
+ return currentAddress;
389
+ }
390
+ }
391
+ return null;
392
+ }
271
393
 
272
394
  // src/services/svm/payment-header.ts
273
395
  var import_web3 = require("@solana/web3.js");
@@ -347,12 +469,12 @@ async function createSvmPaymentHeader(params) {
347
469
  )
348
470
  );
349
471
  const { blockhash } = await connection.getLatestBlockhash("confirmed");
350
- const message = new import_web3.TransactionMessage({
472
+ const message2 = new import_web3.TransactionMessage({
351
473
  payerKey: feePayerPubkey,
352
474
  recentBlockhash: blockhash,
353
475
  instructions
354
476
  }).compileToV0Message();
355
- const transaction = new import_web3.VersionedTransaction(message);
477
+ const transaction = new import_web3.VersionedTransaction(message2);
356
478
  if (typeof wallet?.signTransaction !== "function") {
357
479
  throw new Error("Connected wallet does not support signTransaction");
358
480
  }
@@ -387,6 +509,7 @@ function getDefaultSolanaRpcUrl(network) {
387
509
  }
388
510
 
389
511
  // src/services/svm/payment-handler.ts
512
+ init_types();
390
513
  async function handleSvmPayment(endpoint, config, requestInit) {
391
514
  const { wallet, network, rpcUrl, maxPaymentAmount } = config;
392
515
  const initialResponse = await fetch(endpoint, {
@@ -411,7 +534,8 @@ async function handleSvmPayment(endpoint, config, requestInit) {
411
534
  "already_used": "This payment has already been used",
412
535
  "network_mismatch": "Payment network does not match",
413
536
  "invalid_payment": "Invalid payment data",
414
- "verification_failed": "Payment verification failed"
537
+ "verification_failed": "Payment verification failed",
538
+ "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."
415
539
  };
416
540
  const errorMessage = ERROR_MESSAGES[rawResponse.error] || `Payment failed: ${rawResponse.error}`;
417
541
  const error = new Error(errorMessage);
@@ -479,7 +603,8 @@ async function handleSvmPayment(endpoint, config, requestInit) {
479
603
  "already_used": "This payment has already been used",
480
604
  "network_mismatch": "Payment network does not match",
481
605
  "invalid_payment": "Invalid payment data",
482
- "verification_failed": "Payment verification failed"
606
+ "verification_failed": "Payment verification failed",
607
+ "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."
483
608
  };
484
609
  const errorMessage = ERROR_MESSAGES[retryData.error] || `Payment failed: ${retryData.error}`;
485
610
  const error = new Error(errorMessage);
@@ -609,6 +734,7 @@ function getChainIdFromNetwork(network) {
609
734
  }
610
735
 
611
736
  // src/services/evm/payment-handler.ts
737
+ init_types();
612
738
  async function handleEvmPayment(endpoint, config, requestInit) {
613
739
  const { wallet, network, maxPaymentAmount } = config;
614
740
  const initialResponse = await fetch(endpoint, {
@@ -779,6 +905,7 @@ async function handleEvmPayment(endpoint, config, requestInit) {
779
905
 
780
906
  // src/utils/payment-helpers.ts
781
907
  var import_ethers2 = require("ethers");
908
+ init_common();
782
909
  function parsePaymentRequired(response) {
783
910
  if (response && typeof response === "object") {
784
911
  if ("x402Version" in response && "accepts" in response) {
@@ -802,9 +929,15 @@ function getSupportedNetworkTypes(paymentRequirements) {
802
929
  });
803
930
  return Array.from(networkTypes);
804
931
  }
805
- async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL) {
806
- endpoint = `${endpoint}/${merchantId}`;
932
+ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL, additionalParams) {
933
+ const fullEndpoint = `${endpoint}/${merchantId}`;
807
934
  let response;
935
+ const requestInit = additionalParams && Object.keys(additionalParams).length > 0 ? {
936
+ body: JSON.stringify(additionalParams),
937
+ headers: {
938
+ "Content-Type": "application/json"
939
+ }
940
+ } : {};
808
941
  if (networkType === "solana" /* SOLANA */ || networkType === "svm" /* SVM */) {
809
942
  const solana = window.solana;
810
943
  if (!solana) {
@@ -813,11 +946,11 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL) {
813
946
  if (!solana.isConnected) {
814
947
  await solana.connect();
815
948
  }
816
- response = await handleSvmPayment(endpoint, {
949
+ response = await handleSvmPayment(fullEndpoint, {
817
950
  wallet: solana,
818
951
  network: "solana"
819
952
  // Will use backend's network configuration
820
- });
953
+ }, requestInit);
821
954
  } else if (networkType === "evm" /* EVM */) {
822
955
  if (!window.ethereum) {
823
956
  throw new Error("\u8BF7\u5B89\u88C5 MetaMask \u94B1\u5305");
@@ -826,8 +959,8 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL) {
826
959
  const signer = await provider.getSigner();
827
960
  const wallet = {
828
961
  address: await signer.getAddress(),
829
- signTypedData: async (domain, types, message) => {
830
- return await signer.signTypedData(domain, types, message);
962
+ signTypedData: async (domain, types, message2) => {
963
+ return await signer.signTypedData(domain, types, message2);
831
964
  },
832
965
  // Get current chain ID from wallet
833
966
  getChainId: async () => {
@@ -842,35 +975,16 @@ async function makePayment(networkType, merchantId, endpoint = PROD_BACK_URL) {
842
975
  });
843
976
  }
844
977
  };
845
- response = await handleEvmPayment(endpoint, {
978
+ response = await handleEvmPayment(fullEndpoint, {
846
979
  wallet,
847
980
  network: "base"
848
981
  // Will use backend's network configuration
849
- });
982
+ }, requestInit);
850
983
  } else {
851
984
  throw new Error(`\u4E0D\u652F\u6301\u7684\u7F51\u7EDC\u7C7B\u578B: ${networkType}`);
852
985
  }
853
986
  return response;
854
987
  }
855
- async function handlePayment(endpoint, networkType, callbacks) {
856
- try {
857
- callbacks?.onStart?.();
858
- const response = await makePayment(networkType, "", endpoint);
859
- if (!response.ok) {
860
- const errorText = await response.text();
861
- throw new Error(`\u8BF7\u6C42\u5931\u8D25 (${response.status}): ${errorText}`);
862
- }
863
- const result = await response.json();
864
- callbacks?.onSuccess?.(result);
865
- return result;
866
- } catch (err) {
867
- const errorMessage = err.message || "\u652F\u4ED8\u5931\u8D25";
868
- callbacks?.onError?.(errorMessage);
869
- throw err;
870
- } finally {
871
- callbacks?.onFinish?.();
872
- }
873
- }
874
988
 
875
989
  // src/utils/network.ts
876
990
  var NETWORK_TYPE_MAP = {
@@ -894,6 +1008,7 @@ var NETWORK_TYPE_MAP = {
894
1008
  };
895
1009
  function getNetworkDisplayName(network) {
896
1010
  const displayNames = {
1011
+ "evm": "EVM",
897
1012
  "ethereum": "Ethereum",
898
1013
  "sepolia": "Sepolia Testnet",
899
1014
  "base": "Base",
@@ -1056,60 +1171,28 @@ var WalletStore = class {
1056
1171
  init() {
1057
1172
  if (this.initialized) return;
1058
1173
  this.initialized = true;
1059
- this.autoReconnect();
1060
1174
  onAccountsChanged((accounts) => {
1061
- const connectedType = getConnectedNetworkType();
1062
- if (connectedType === "evm" /* EVM */) {
1175
+ if (this.state.networkType === "evm" /* EVM */) {
1063
1176
  if (accounts.length === 0) {
1064
1177
  this.setState({ address: null });
1065
- console.log("\u{1F50C} Wallet disconnected");
1066
- } else {
1067
- if (!isWalletManuallyDisconnected()) {
1068
- this.setState({ address: accounts[0] });
1069
- console.log("\u{1F504} Account changed:", accounts[0]);
1070
- }
1178
+ } else if (!isWalletManuallyDisconnected("evm" /* EVM */)) {
1179
+ this.setState({ address: accounts[0] });
1180
+ saveWalletAddress("evm" /* EVM */, accounts[0]);
1071
1181
  }
1072
1182
  }
1073
1183
  });
1074
1184
  onChainChanged(() => {
1075
- const connectedType = getConnectedNetworkType();
1076
- if (connectedType === "evm" /* EVM */) {
1077
- console.log("\u26A0\uFE0F Network changed detected - disconnecting wallet");
1078
- disconnectWallet();
1079
- this.setState({
1080
- address: null,
1081
- networkType: null,
1082
- error: "Network changed. Please reconnect your wallet."
1083
- });
1185
+ if (this.state.networkType === "evm" /* EVM */) {
1186
+ this.handleDisconnect("evm" /* EVM */, "Chain changed. Please reconnect your wallet.");
1084
1187
  }
1085
1188
  });
1086
1189
  onWalletDisconnect(() => {
1087
- const connectedType = getConnectedNetworkType();
1088
- if (connectedType === "solana" /* SOLANA */ || connectedType === "svm" /* SVM */) {
1089
- console.log("\u26A0\uFE0F Solana wallet disconnected");
1090
- disconnectWallet();
1091
- this.setState({
1092
- address: null,
1093
- networkType: null
1094
- });
1190
+ const svmTypes = ["solana" /* SOLANA */, "svm" /* SVM */];
1191
+ if (this.state.networkType && svmTypes.includes(this.state.networkType)) {
1192
+ this.handleDisconnect(this.state.networkType);
1095
1193
  }
1096
1194
  });
1097
1195
  }
1098
- async autoReconnect() {
1099
- if (!isWalletManuallyDisconnected()) {
1100
- const connectedType = getConnectedNetworkType();
1101
- if (connectedType) {
1102
- const currentAddress = await getCurrentWallet(connectedType);
1103
- if (currentAddress) {
1104
- this.setState({
1105
- address: currentAddress,
1106
- networkType: connectedType
1107
- });
1108
- console.log("\u{1F504} Auto-reconnected wallet:", currentAddress);
1109
- }
1110
- }
1111
- }
1112
- }
1113
1196
  // Get current state
1114
1197
  getState() {
1115
1198
  return this.state;
@@ -1130,18 +1213,32 @@ var WalletStore = class {
1130
1213
  notifyListeners() {
1131
1214
  this.listeners.forEach((listener) => listener());
1132
1215
  }
1216
+ // Handle wallet disconnect (internal helper)
1217
+ handleDisconnect(networkType, error) {
1218
+ removeWalletAddress(networkType);
1219
+ markWalletDisconnected(networkType);
1220
+ if (typeof window !== "undefined") {
1221
+ localStorage.removeItem("connected_network_type");
1222
+ }
1223
+ this.setState({
1224
+ address: null,
1225
+ networkType: null,
1226
+ error: error || null
1227
+ });
1228
+ }
1133
1229
  // Connect wallet
1134
1230
  async connect(type) {
1231
+ if (this.state.address && this.state.networkType && this.state.networkType !== type) {
1232
+ saveWalletAddress(this.state.networkType, this.state.address);
1233
+ }
1135
1234
  this.setState({ isConnecting: true, error: null });
1136
1235
  try {
1137
1236
  const walletAddress = await connectWallet(type);
1138
- console.log("\u2705 Wallet connected:", walletAddress, "Network:", type);
1139
1237
  this.setState({
1140
1238
  address: walletAddress,
1141
1239
  networkType: type,
1142
1240
  isConnecting: false
1143
1241
  });
1144
- console.log("\u{1F4DD} Store state updated");
1145
1242
  } catch (err) {
1146
1243
  this.setState({
1147
1244
  error: err.message || "Failed to connect wallet",
@@ -1150,20 +1247,67 @@ var WalletStore = class {
1150
1247
  throw err;
1151
1248
  }
1152
1249
  }
1250
+ // Switch network (use cached wallet if available)
1251
+ async switchNetwork(type) {
1252
+ if (this.state.address && this.state.networkType) {
1253
+ saveWalletAddress(this.state.networkType, this.state.address);
1254
+ }
1255
+ this.setState({ isConnecting: true, error: null });
1256
+ try {
1257
+ const address = await switchNetwork(type);
1258
+ if (address) {
1259
+ this.setState({
1260
+ address,
1261
+ networkType: type,
1262
+ isConnecting: false
1263
+ });
1264
+ } else {
1265
+ this.setState({
1266
+ address: null,
1267
+ networkType: type,
1268
+ isConnecting: true
1269
+ });
1270
+ await this.connect(type);
1271
+ }
1272
+ } catch (err) {
1273
+ this.setState({
1274
+ error: err.message || "Failed to switch network",
1275
+ isConnecting: false
1276
+ });
1277
+ throw err;
1278
+ }
1279
+ }
1153
1280
  // Disconnect wallet
1154
1281
  disconnect() {
1155
- disconnectWallet();
1156
- this.setState({
1157
- address: null,
1158
- networkType: null,
1159
- error: null
1160
- });
1161
- console.log("\u{1F50C} Wallet disconnected from store");
1282
+ const currentNetwork = this.state.networkType;
1283
+ if (currentNetwork) {
1284
+ this.handleDisconnect(currentNetwork);
1285
+ } else {
1286
+ this.setState({
1287
+ address: null,
1288
+ networkType: null,
1289
+ error: null
1290
+ });
1291
+ }
1162
1292
  }
1163
1293
  // Clear error
1164
1294
  clearError() {
1165
1295
  this.setState({ error: null });
1166
1296
  }
1297
+ // Ensure network matches expected type (for page-specific network requirements)
1298
+ async ensureNetwork(expectedNetwork) {
1299
+ if (isWalletManuallyDisconnected(expectedNetwork)) {
1300
+ return;
1301
+ }
1302
+ if (this.state.networkType === expectedNetwork && this.state.address) {
1303
+ return;
1304
+ }
1305
+ if (this.state.networkType !== expectedNetwork) {
1306
+ await this.switchNetwork(expectedNetwork);
1307
+ } else if (!this.state.address) {
1308
+ await this.connect(expectedNetwork);
1309
+ }
1310
+ }
1167
1311
  };
1168
1312
  var walletStore = new WalletStore();
1169
1313
  if (typeof window !== "undefined") {
@@ -1181,24 +1325,43 @@ function useWallet() {
1181
1325
  return {
1182
1326
  ...state,
1183
1327
  connect: (type) => walletStore.connect(type),
1328
+ switchNetwork: (type) => walletStore.switchNetwork(type),
1329
+ ensureNetwork: (type) => walletStore.ensureNetwork(type),
1184
1330
  disconnect: () => walletStore.disconnect(),
1185
1331
  clearError: () => walletStore.clearError()
1186
1332
  };
1187
1333
  }
1188
1334
 
1189
- // src/react/hooks/usePayment.ts
1335
+ // src/react/hooks/usePageNetwork.ts
1190
1336
  var import_react2 = require("react");
1337
+ function usePageNetwork(expectedNetwork, options = {}) {
1338
+ const {
1339
+ autoSwitch = true,
1340
+ switchOnMount = true
1341
+ } = options;
1342
+ const wallet = useWallet();
1343
+ (0, import_react2.useEffect)(() => {
1344
+ if (!autoSwitch || !switchOnMount) return;
1345
+ wallet.ensureNetwork(expectedNetwork).catch((err) => {
1346
+ console.error("Failed to ensure network:", err);
1347
+ });
1348
+ }, [expectedNetwork]);
1349
+ return wallet;
1350
+ }
1351
+
1352
+ // src/react/hooks/usePayment.ts
1353
+ var import_react3 = require("react");
1191
1354
  function usePayment() {
1192
- const [isProcessing, setIsProcessing] = (0, import_react2.useState)(false);
1193
- const [result, setResult] = (0, import_react2.useState)(null);
1194
- const [error, setError] = (0, import_react2.useState)(null);
1195
- const clearResult = (0, import_react2.useCallback)(() => {
1355
+ const [isProcessing, setIsProcessing] = (0, import_react3.useState)(false);
1356
+ const [result, setResult] = (0, import_react3.useState)(null);
1357
+ const [error, setError] = (0, import_react3.useState)(null);
1358
+ const clearResult = (0, import_react3.useCallback)(() => {
1196
1359
  setResult(null);
1197
1360
  }, []);
1198
- const clearError = (0, import_react2.useCallback)(() => {
1361
+ const clearError = (0, import_react3.useCallback)(() => {
1199
1362
  setError(null);
1200
1363
  }, []);
1201
- const reset = (0, import_react2.useCallback)(() => {
1364
+ const reset = (0, import_react3.useCallback)(() => {
1202
1365
  setIsProcessing(false);
1203
1366
  setResult(null);
1204
1367
  setError(null);
@@ -1217,18 +1380,28 @@ function usePayment() {
1217
1380
  }
1218
1381
 
1219
1382
  // src/react/hooks/usePaymentInfo.ts
1220
- var import_react3 = require("react");
1221
- function usePaymentInfo(merchantId, endpoint = PROD_BACK_URL) {
1222
- const [paymentInfo, setPaymentInfo] = (0, import_react3.useState)(null);
1223
- const [supportedNetworks, setSupportedNetworks] = (0, import_react3.useState)([]);
1224
- const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
1225
- const [error, setError] = (0, import_react3.useState)(null);
1383
+ var import_react4 = require("react");
1384
+ init_common();
1385
+ function usePaymentInfo(merchantId, endpoint = PROD_BACK_URL, additionalParams) {
1386
+ const [paymentInfo, setPaymentInfo] = (0, import_react4.useState)(null);
1387
+ const [supportedNetworks, setSupportedNetworks] = (0, import_react4.useState)([]);
1388
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
1389
+ const [error, setError] = (0, import_react4.useState)(null);
1226
1390
  const fetchPaymentInfo = async () => {
1227
1391
  setIsLoading(true);
1228
1392
  setError(null);
1229
1393
  try {
1230
- endpoint = `${endpoint}/${merchantId}`;
1231
- const response = await fetch(endpoint, { method: "POST" });
1394
+ const fullEndpoint = `${endpoint}/${merchantId}`;
1395
+ const requestInit = {
1396
+ method: "POST",
1397
+ ...additionalParams && Object.keys(additionalParams).length > 0 ? {
1398
+ body: JSON.stringify(additionalParams),
1399
+ headers: {
1400
+ "Content-Type": "application/json"
1401
+ }
1402
+ } : {}
1403
+ };
1404
+ const response = await fetch(fullEndpoint, requestInit);
1232
1405
  if (response.status === 402) {
1233
1406
  const body = await response.json();
1234
1407
  const payment = parsePaymentRequired(body);
@@ -1247,9 +1420,9 @@ function usePaymentInfo(merchantId, endpoint = PROD_BACK_URL) {
1247
1420
  setIsLoading(false);
1248
1421
  }
1249
1422
  };
1250
- (0, import_react3.useEffect)(() => {
1423
+ (0, import_react4.useEffect)(() => {
1251
1424
  fetchPaymentInfo();
1252
- }, [endpoint]);
1425
+ }, [endpoint, merchantId]);
1253
1426
  return {
1254
1427
  paymentInfo,
1255
1428
  supportedNetworks,
@@ -1260,7 +1433,7 @@ function usePaymentInfo(merchantId, endpoint = PROD_BACK_URL) {
1260
1433
  }
1261
1434
 
1262
1435
  // src/react/components/WalletConnect.tsx
1263
- var import_react4 = __toESM(require("react"));
1436
+ var import_react5 = __toESM(require("react"));
1264
1437
 
1265
1438
  // src/react/styles/inline-styles.ts
1266
1439
  var isDarkMode = () => {
@@ -1352,12 +1525,21 @@ var baseButtonStyle = {
1352
1525
  };
1353
1526
  var getConnectButtonStyle = (isDisabled, isHovered) => {
1354
1527
  const c = getColors();
1528
+ const darkMode = isDarkMode();
1529
+ if (isDisabled) {
1530
+ return {
1531
+ ...baseButtonStyle,
1532
+ background: c.disabled,
1533
+ color: c.disabledText,
1534
+ cursor: "not-allowed",
1535
+ border: darkMode ? "1px solid #404040" : "1px solid #d4d4d4"
1536
+ };
1537
+ }
1355
1538
  return {
1356
1539
  ...baseButtonStyle,
1357
- background: isDisabled ? c.disabled : isHovered ? c.primaryHover : c.primary,
1358
- color: isDarkMode() ? "#000000" : "#ffffff",
1359
- cursor: isDisabled ? "not-allowed" : "pointer",
1360
- opacity: isDisabled ? 0.5 : 1
1540
+ background: isHovered ? c.primaryHover : c.primary,
1541
+ color: darkMode ? "#000000" : "#ffffff",
1542
+ cursor: "pointer"
1361
1543
  };
1362
1544
  };
1363
1545
  var getDisconnectButtonStyle = (isHovered) => {
@@ -1368,17 +1550,6 @@ var getDisconnectButtonStyle = (isHovered) => {
1368
1550
  color: "#ffffff"
1369
1551
  };
1370
1552
  };
1371
- var getPayButtonStyle = (isDisabled, isHovered) => {
1372
- const c = getColors();
1373
- return {
1374
- ...baseButtonStyle,
1375
- background: isDisabled ? c.disabled : isHovered ? c.successHover : c.success,
1376
- color: "#ffffff",
1377
- width: "100%",
1378
- cursor: isDisabled ? "not-allowed" : "pointer",
1379
- opacity: isDisabled ? 0.5 : 1
1380
- };
1381
- };
1382
1553
  var getInstallLinkStyle = (isHovered) => {
1383
1554
  const c = getColors();
1384
1555
  return {
@@ -1451,8 +1622,8 @@ function WalletConnect({
1451
1622
  onDisconnect
1452
1623
  }) {
1453
1624
  const { address, networkType, isConnecting, error, connect, disconnect } = useWallet();
1454
- const [hoveredButton, setHoveredButton] = (0, import_react4.useState)(null);
1455
- const [hoveredLink, setHoveredLink] = (0, import_react4.useState)(null);
1625
+ const [hoveredButton, setHoveredButton] = (0, import_react5.useState)(null);
1626
+ const [hoveredLink, setHoveredLink] = (0, import_react5.useState)(null);
1456
1627
  const handleConnect = async (network) => {
1457
1628
  try {
1458
1629
  await connect(network);
@@ -1463,9 +1634,9 @@ function WalletConnect({
1463
1634
  disconnect();
1464
1635
  onDisconnect?.();
1465
1636
  };
1466
- return /* @__PURE__ */ import_react4.default.createElement("div", { style: { ...containerStyle, ...className ? {} : {} }, className }, !address ? /* @__PURE__ */ import_react4.default.createElement("div", { style: getSectionStyle() }, /* @__PURE__ */ import_react4.default.createElement("h3", { style: getTitleStyle() }, "Connect Wallet"), supportedNetworks.length === 0 ? /* @__PURE__ */ import_react4.default.createElement("p", { style: getHintStyle() }, "No payment required") : /* @__PURE__ */ import_react4.default.createElement("div", { style: buttonsContainerStyle }, supportedNetworks.map((network) => {
1637
+ return /* @__PURE__ */ import_react5.default.createElement("div", { style: { ...containerStyle, ...className ? {} : {} }, className }, !address ? /* @__PURE__ */ import_react5.default.createElement("div", { style: getSectionStyle() }, /* @__PURE__ */ import_react5.default.createElement("h3", { style: getTitleStyle() }, "Connect Wallet"), supportedNetworks.length === 0 ? /* @__PURE__ */ import_react5.default.createElement("p", { style: getHintStyle() }, "Please install a supported wallet extension") : /* @__PURE__ */ import_react5.default.createElement("div", { style: buttonsContainerStyle }, supportedNetworks.map((network) => {
1467
1638
  const installed = isWalletInstalled(network);
1468
- return /* @__PURE__ */ import_react4.default.createElement("div", { key: network, style: walletOptionStyle }, /* @__PURE__ */ import_react4.default.createElement(
1639
+ return /* @__PURE__ */ import_react5.default.createElement("div", { key: network, style: walletOptionStyle }, /* @__PURE__ */ import_react5.default.createElement(
1469
1640
  "button",
1470
1641
  {
1471
1642
  style: getConnectButtonStyle(isConnecting || !installed, hoveredButton === network),
@@ -1475,7 +1646,7 @@ function WalletConnect({
1475
1646
  onMouseLeave: () => setHoveredButton(null)
1476
1647
  },
1477
1648
  isConnecting ? "Connecting..." : getNetworkDisplayName(network)
1478
- ), !installed && /* @__PURE__ */ import_react4.default.createElement(
1649
+ ), !installed && /* @__PURE__ */ import_react5.default.createElement(
1479
1650
  "a",
1480
1651
  {
1481
1652
  href: getWalletInstallUrl(network),
@@ -1487,7 +1658,7 @@ function WalletConnect({
1487
1658
  },
1488
1659
  "Install Wallet"
1489
1660
  ));
1490
- })), error && /* @__PURE__ */ import_react4.default.createElement("p", { style: getErrorStyle() }, error), /* @__PURE__ */ import_react4.default.createElement("p", { style: getHintStyle() }, "To switch accounts, please change it in your wallet extension")) : /* @__PURE__ */ import_react4.default.createElement("div", { style: getSectionStyle() }, /* @__PURE__ */ import_react4.default.createElement("div", { style: walletAddressStyle }, /* @__PURE__ */ import_react4.default.createElement("span", { style: getLabelStyle() }, "Connected ", networkType && `(${getNetworkDisplayName(networkType)})`), /* @__PURE__ */ import_react4.default.createElement("span", { style: getAddressStyle() }, formatAddress(address))), /* @__PURE__ */ import_react4.default.createElement("div", { style: walletActionsStyle }, /* @__PURE__ */ import_react4.default.createElement(
1661
+ })), error && /* @__PURE__ */ import_react5.default.createElement("p", { style: getErrorStyle() }, error), /* @__PURE__ */ import_react5.default.createElement("p", { style: getHintStyle() }, "To switch accounts, please change it in your wallet extension")) : /* @__PURE__ */ import_react5.default.createElement("div", { style: getSectionStyle() }, /* @__PURE__ */ import_react5.default.createElement("div", { style: walletAddressStyle }, /* @__PURE__ */ import_react5.default.createElement("span", { style: getLabelStyle() }, "Connected ", networkType && `(${getNetworkDisplayName(networkType)})`), /* @__PURE__ */ import_react5.default.createElement("span", { style: getAddressStyle() }, formatAddress(address))), /* @__PURE__ */ import_react5.default.createElement("div", { style: walletActionsStyle }, /* @__PURE__ */ import_react5.default.createElement(
1491
1662
  "button",
1492
1663
  {
1493
1664
  style: getDisconnectButtonStyle(hoveredButton === "disconnect"),
@@ -1496,65 +1667,568 @@ function WalletConnect({
1496
1667
  onMouseLeave: () => setHoveredButton(null)
1497
1668
  },
1498
1669
  "Disconnect"
1499
- )), /* @__PURE__ */ import_react4.default.createElement("p", { style: getHintStyle() }, "Switch account in your wallet to change address")));
1670
+ )), /* @__PURE__ */ import_react5.default.createElement("p", { style: getHintStyle() }, "Switch account in your wallet to change address")));
1500
1671
  }
1501
1672
 
1502
- // src/react/components/PaymentButton.tsx
1503
- var import_react5 = __toESM(require("react"));
1504
- function PaymentButton({
1505
- endpoint,
1506
- className = "",
1507
- disabled = false,
1508
- onSuccess,
1509
- onError,
1510
- onStart,
1511
- onFinish,
1512
- children = "Pay Now"
1673
+ // src/react/components/V402Checkout.tsx
1674
+ var import_react7 = __toESM(require("react"));
1675
+ var import_antd = require("antd");
1676
+ var import_icons = require("@ant-design/icons");
1677
+ init_common();
1678
+
1679
+ // src/react/utils/CryptoIcons.tsx
1680
+ var import_react6 = __toESM(require("react"));
1681
+ var SolanaIcon = ({ width = 16, height = 16, className, style }) => {
1682
+ return /* @__PURE__ */ import_react6.default.createElement(
1683
+ "svg",
1684
+ {
1685
+ xmlns: "http://www.w3.org/2000/svg",
1686
+ viewBox: "0 0 16 16",
1687
+ width,
1688
+ height,
1689
+ className,
1690
+ style
1691
+ },
1692
+ /* @__PURE__ */ import_react6.default.createElement("desc", null, "Solana SOL Fill Streamline Icon: https://streamlinehq.com"),
1693
+ /* @__PURE__ */ import_react6.default.createElement("g", { fill: "none", fillRule: "evenodd" }, /* @__PURE__ */ import_react6.default.createElement(
1694
+ "path",
1695
+ {
1696
+ d: "M16 0v16H0V0h16ZM8.395333333333333 15.505333333333333l-0.007333333333333332 0.0013333333333333333 -0.047333333333333324 0.023333333333333334 -0.013333333333333332 0.0026666666666666666 -0.009333333333333332 -0.0026666666666666666 -0.047333333333333324 -0.023333333333333334c-0.006666666666666666 -0.0026666666666666666 -0.012666666666666666 -0.0006666666666666666 -0.016 0.003333333333333333l-0.0026666666666666666 0.006666666666666666 -0.011333333333333334 0.2853333333333333 0.003333333333333333 0.013333333333333332 0.006666666666666666 0.008666666666666666 0.06933333333333333 0.049333333333333326 0.009999999999999998 0.0026666666666666666 0.008 -0.0026666666666666666 0.06933333333333333 -0.049333333333333326 0.008 -0.010666666666666666 0.0026666666666666666 -0.011333333333333334 -0.011333333333333334 -0.2846666666666666c-0.0013333333333333333 -0.006666666666666666 -0.005999999999999999 -0.011333333333333334 -0.011333333333333334 -0.011999999999999999Zm0.17666666666666667 -0.07533333333333334 -0.008666666666666666 0.0013333333333333333 -0.12333333333333332 0.062 -0.006666666666666666 0.006666666666666666 -0.002 0.007333333333333332 0.011999999999999999 0.2866666666666666 0.003333333333333333 0.008 0.005333333333333333 0.004666666666666666 0.134 0.062c0.008 0.0026666666666666666 0.015333333333333332 0 0.019333333333333334 -0.005333333333333333l0.0026666666666666666 -0.009333333333333332 -0.02266666666666667 -0.4093333333333333c-0.002 -0.008 -0.006666666666666666 -0.013333333333333332 -0.013333333333333332 -0.014666666666666665Zm-0.4766666666666666 0.0013333333333333333a0.015333333333333332 0.015333333333333332 0 0 0 -0.018 0.004l-0.004 0.009333333333333332 -0.02266666666666667 0.4093333333333333c0 0.008 0.004666666666666666 0.013333333333333332 0.011333333333333334 0.016l0.009999999999999998 -0.0013333333333333333 0.134 -0.062 0.006666666666666666 -0.005333333333333333 0.0026666666666666666 -0.007333333333333332 0.011333333333333334 -0.2866666666666666 -0.002 -0.008 -0.006666666666666666 -0.006666666666666666 -0.12266666666666666 -0.06133333333333333Z",
1697
+ strokeWidth: "0.6667"
1698
+ }
1699
+ ), /* @__PURE__ */ import_react6.default.createElement(
1700
+ "path",
1701
+ {
1702
+ fill: "#000000",
1703
+ d: "M4.862 2.862A0.6666666666666666 0.6666666666666666 0 0 1 5.333333333333333 2.6666666666666665h8.666666666666666a0.6666666666666666 0.6666666666666666 0 0 1 0.47133333333333327 1.138l-2 2A0.6666666666666666 0.6666666666666666 0 0 1 12 6H3.333333333333333a0.6666666666666666 0.6666666666666666 0 0 1 -0.47133333333333327 -1.138l2 -2Zm-2.1166666666666663 4.156666666666666A0.6666666666666666 0.6666666666666666 0 0 1 3.333333333333333 6.666666666666666h8.666666666666666a0.6666666666666666 0.6666666666666666 0 0 1 0.5546666666666666 0.29666666666666663l1.3333333333333333 2A0.6666666666666666 0.6666666666666666 0 0 1 13.333333333333332 10H4.666666666666666a0.6666666666666666 0.6666666666666666 0 0 1 -0.5546666666666666 -0.29666666666666663l-1.3333333333333333 -2a0.6666666666666666 0.6666666666666666 0 0 1 -0.03333333333333333 -0.6846666666666665Zm1.4499999999999997 3.843333333333333A0.6666666666666666 0.6666666666666666 0 0 1 4.666666666666666 10.666666666666666h8.666666666666666a0.6666666666666666 0.6666666666666666 0 0 1 0.47133333333333327 1.138l-2 2A0.6666666666666666 0.6666666666666666 0 0 1 11.333333333333332 14H2.6666666666666665a0.6666666666666666 0.6666666666666666 0 0 1 -0.47133333333333327 -1.138l2 -2Z",
1704
+ strokeWidth: "0.6667"
1705
+ }
1706
+ ))
1707
+ );
1708
+ };
1709
+ var BaseIcon = ({ width = 24, height = 24, className, style }) => {
1710
+ return /* @__PURE__ */ import_react6.default.createElement(
1711
+ "svg",
1712
+ {
1713
+ xmlns: "http://www.w3.org/2000/svg",
1714
+ viewBox: "0 0 24 24",
1715
+ fill: "none",
1716
+ stroke: "#000000",
1717
+ strokeLinecap: "round",
1718
+ strokeLinejoin: "round",
1719
+ width,
1720
+ height,
1721
+ className,
1722
+ style
1723
+ },
1724
+ /* @__PURE__ */ import_react6.default.createElement("desc", null, "Brand Coinbase Streamline Icon: https://streamlinehq.com"),
1725
+ /* @__PURE__ */ import_react6.default.createElement(
1726
+ "path",
1727
+ {
1728
+ d: "M12.95 22c-4.503 0 -8.445 -3.04 -9.61 -7.413 -1.165 -4.373 0.737 -8.988 4.638 -11.25a9.906 9.906 0 0 1 12.008 1.598l-3.335 3.367a5.185 5.185 0 0 0 -7.354 0.013 5.252 5.252 0 0 0 0 7.393 5.185 5.185 0 0 0 7.354 0.013L20 19.088A9.887 9.887 0 0 1 12.95 22z",
1729
+ strokeWidth: "2"
1730
+ }
1731
+ )
1732
+ );
1733
+ };
1734
+ var getNetworkIcon = (network) => {
1735
+ const networkLower = network.toLowerCase();
1736
+ if (networkLower.includes("solana")) {
1737
+ return SolanaIcon;
1738
+ }
1739
+ if (networkLower.includes("base")) {
1740
+ return BaseIcon;
1741
+ }
1742
+ return BaseIcon;
1743
+ };
1744
+
1745
+ // src/react/components/V402Checkout.tsx
1746
+ var { Title, Text } = import_antd.Typography;
1747
+ var notify = {
1748
+ success: (title, msg) => {
1749
+ import_antd.message.success(`${title}: ${msg}`);
1750
+ },
1751
+ error: (title, msg) => {
1752
+ import_antd.message.error(`${title}: ${msg}`);
1753
+ },
1754
+ info: (title, msg) => {
1755
+ import_antd.message.info(`${title}: ${msg}`);
1756
+ }
1757
+ };
1758
+ function V402Checkout({
1759
+ merchantId,
1760
+ headerInfo = {},
1761
+ isModal = false,
1762
+ onPaymentComplete,
1763
+ additionalParams = {},
1764
+ expectedNetwork
1513
1765
  }) {
1514
- const { networkType } = useWallet();
1515
- const { isProcessing, setIsProcessing, setResult, setError, error } = usePayment();
1516
- const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
1517
- const handleClick = async () => {
1766
+ const {
1767
+ title = "V402Pay - Make x402Pay Easier",
1768
+ subtitle = "onvoyage.ai",
1769
+ tooltipText = "V402Pay - Accept Crypto Payments Easier"
1770
+ } = headerInfo;
1771
+ let endpoint = DEV_BACK_URL;
1772
+ const {
1773
+ supportedNetworks,
1774
+ isLoading: fetchingPaymentInfo,
1775
+ paymentInfo
1776
+ } = usePaymentInfo(merchantId, endpoint, additionalParams);
1777
+ const targetNetwork = expectedNetwork || supportedNetworks[0];
1778
+ const { address, networkType, disconnect, ensureNetwork } = usePageNetwork(
1779
+ targetNetwork,
1780
+ { autoSwitch: !!targetNetwork, switchOnMount: true }
1781
+ );
1782
+ const { isProcessing, setIsProcessing, result, setResult, error, setError } = usePayment();
1783
+ const [paymentDetails, setPaymentDetails] = (0, import_react7.useState)(null);
1784
+ const handleDisconnect = () => {
1785
+ disconnect();
1786
+ setResult(null);
1787
+ setError(null);
1788
+ notify.info("Wallet Disconnected", "Your wallet has been disconnected successfully.");
1789
+ };
1790
+ (0, import_react7.useEffect)(() => {
1791
+ if (paymentInfo && paymentInfo.length > 0) {
1792
+ const firstPayment = paymentInfo[0];
1793
+ const rawAmount = firstPayment.maxAmountRequired?.toString() || "0";
1794
+ const decimals = 6;
1795
+ const humanReadableAmount = (Number(rawAmount) / Math.pow(10, decimals)).toFixed(2);
1796
+ const network = firstPayment.network || "Unknown";
1797
+ const currency = "USDC";
1798
+ setPaymentDetails({
1799
+ amount: humanReadableAmount,
1800
+ currency,
1801
+ network
1802
+ });
1803
+ }
1804
+ }, [paymentInfo]);
1805
+ (0, import_react7.useEffect)(() => {
1806
+ if (targetNetwork && !fetchingPaymentInfo && ensureNetwork) {
1807
+ ensureNetwork(targetNetwork).catch((err) => {
1808
+ console.error("Failed to ensure network:", err);
1809
+ });
1810
+ }
1811
+ }, [targetNetwork, fetchingPaymentInfo]);
1812
+ const handlePayment = async () => {
1518
1813
  if (!networkType) {
1519
- const errorMsg = "Please connect wallet first";
1520
- setError(errorMsg);
1521
- onError?.(errorMsg);
1814
+ notify.error("Wallet Not Connected", "Please connect your wallet first.");
1522
1815
  return;
1523
1816
  }
1817
+ setResult(null);
1818
+ setError(null);
1819
+ setIsProcessing(true);
1524
1820
  try {
1525
- onStart?.();
1526
- setIsProcessing(true);
1527
- setError(null);
1528
- const result = await handlePayment(endpoint, networkType);
1529
- setResult(result);
1530
- onSuccess?.(result);
1821
+ const response = await makePayment(networkType, merchantId, endpoint, additionalParams);
1822
+ const data = await response.json();
1823
+ setResult(data);
1824
+ notify.success("Payment Successful!", "Your payment has been processed successfully.");
1825
+ if (onPaymentComplete) {
1826
+ onPaymentComplete(data);
1827
+ }
1531
1828
  } catch (err) {
1532
- const errorMsg = err.message || "Payment failed";
1533
- setError(errorMsg);
1534
- onError?.(errorMsg);
1829
+ const errorMessage = err.message || "Payment failed";
1830
+ setError(errorMessage);
1831
+ notify.error("Payment Failed", errorMessage);
1535
1832
  } finally {
1536
1833
  setIsProcessing(false);
1537
- onFinish?.();
1538
1834
  }
1539
1835
  };
1540
- const isDisabled = disabled || isProcessing || !networkType;
1541
- return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement(
1542
- "button",
1836
+ const getNetworkColor = (network) => {
1837
+ if (network.toLowerCase().includes("solana")) return "#14F195";
1838
+ if (network.toLowerCase().includes("evm") || network.toLowerCase().includes("base")) return "#0052FF";
1839
+ return "#8c8c8c";
1840
+ };
1841
+ const NetworkIcon = paymentDetails ? getNetworkIcon(paymentDetails.network) : null;
1842
+ const networkColor = paymentDetails ? getNetworkColor(paymentDetails.network) : "#8c8c8c";
1843
+ const loadingColor = "#8c8c8c";
1844
+ const hasInvalidCheckoutId = !fetchingPaymentInfo && (!paymentInfo || paymentInfo.length === 0);
1845
+ return /* @__PURE__ */ import_react7.default.createElement(
1846
+ "div",
1543
1847
  {
1544
- style: getPayButtonStyle(isDisabled, isHovered),
1545
- className,
1546
- onClick: handleClick,
1547
- disabled: isDisabled,
1548
- onMouseEnter: () => setIsHovered(true),
1549
- onMouseLeave: () => setIsHovered(false)
1848
+ className: isModal ? "bg-white" : "h-screen bg-white flex items-center justify-center p-4 overflow-hidden"
1550
1849
  },
1551
- isProcessing ? "Processing..." : children
1552
- ), error && /* @__PURE__ */ import_react5.default.createElement("p", { style: getErrorStyle() }, error));
1850
+ /* @__PURE__ */ import_react7.default.createElement(
1851
+ "div",
1852
+ {
1853
+ className: "flex gap-4 items-center justify-center",
1854
+ style: {
1855
+ maxWidth: isProcessing || result || error ? "1200px" : "480px",
1856
+ transition: "max-width 0.4s ease-in-out",
1857
+ width: "100%"
1858
+ }
1859
+ },
1860
+ /* @__PURE__ */ import_react7.default.createElement(
1861
+ import_antd.Card,
1862
+ {
1863
+ className: "flex-shrink-0",
1864
+ style: {
1865
+ border: isModal ? "none" : "1px solid #e8e8e8",
1866
+ borderRadius: isModal ? "0" : "16px",
1867
+ boxShadow: isModal ? "none" : "0 4px 24px rgba(0, 0, 0, 0.06)",
1868
+ maxHeight: isModal ? "calc(100vh - 100px)" : "calc(100vh - 32px)",
1869
+ overflow: "auto",
1870
+ width: isModal ? "100%" : "480px",
1871
+ transition: "all 0.4s ease-in-out",
1872
+ transform: result || error ? "translateX(0)" : "translateX(0)"
1873
+ },
1874
+ styles: { body: { padding: isModal ? "0px" : "32px 24px" } }
1875
+ },
1876
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-3 mb-4" }, /* @__PURE__ */ import_react7.default.createElement(
1877
+ "div",
1878
+ {
1879
+ className: "w-12 h-12 rounded-xl flex items-center justify-center",
1880
+ style: {
1881
+ background: hasInvalidCheckoutId ? "#ff4d4f" : paymentDetails ? networkColor : loadingColor,
1882
+ transition: "background 0.3s ease"
1883
+ }
1884
+ },
1885
+ hasInvalidCheckoutId ? /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "20px", color: "white", fontWeight: "bold" } }, "\u2717") : paymentDetails && NetworkIcon ? /* @__PURE__ */ import_react7.default.createElement(NetworkIcon, { width: 24, height: 24 }) : /* @__PURE__ */ import_react7.default.createElement(import_icons.LoadingOutlined, { style: { fontSize: "20px", color: "white" }, spin: true })
1886
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react7.default.createElement(Title, { level: 4, style: { margin: 0, fontSize: "18px", fontWeight: 600 } }, title || "Echo Payment OnVoyage"), !hasInvalidCheckoutId && /* @__PURE__ */ import_react7.default.createElement(
1887
+ import_antd.Tooltip,
1888
+ {
1889
+ title: tooltipText,
1890
+ placement: "top"
1891
+ },
1892
+ /* @__PURE__ */ import_react7.default.createElement(
1893
+ import_icons.InfoCircleOutlined,
1894
+ {
1895
+ style: { fontSize: "14px", color: "#8c8c8c", cursor: "help" }
1896
+ }
1897
+ )
1898
+ )), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, subtitle))),
1899
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center mb-5" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-gray-50 mb-3" }, /* @__PURE__ */ import_react7.default.createElement(import_icons.LockOutlined, { style: { fontSize: "20px", color: "#595959" } })), /* @__PURE__ */ import_react7.default.createElement(Title, { level: 3, style: { margin: "0 0 6px 0", fontSize: "20px", fontWeight: 600 } }, "Payment Required"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Pay ", paymentDetails ? `$${paymentDetails.amount} ${paymentDetails.currency}` : "the required amount", " to access")),
1900
+ hasInvalidCheckoutId && /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center py-6" }, /* @__PURE__ */ import_react7.default.createElement(
1901
+ "div",
1902
+ {
1903
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-4",
1904
+ style: {
1905
+ background: "linear-gradient(135deg, #ef4444 0%, #f87171 100%)",
1906
+ boxShadow: "0 4px 20px rgba(239, 68, 68, 0.3)"
1907
+ }
1908
+ },
1909
+ /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "32px", color: "white" } }, "!")
1910
+ ), /* @__PURE__ */ import_react7.default.createElement(
1911
+ Title,
1912
+ {
1913
+ level: 4,
1914
+ style: { margin: "0 0 12px 0", fontSize: "18px", fontWeight: 600, color: "#262626" }
1915
+ },
1916
+ "Invalid Checkout ID"
1917
+ ), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", color: "#8c8c8c", display: "block", marginBottom: "16px" } }, "The checkout ID you provided is invalid or has expired."), /* @__PURE__ */ import_react7.default.createElement(
1918
+ "div",
1919
+ {
1920
+ style: {
1921
+ background: "#fef2f2",
1922
+ padding: "16px",
1923
+ borderRadius: "12px",
1924
+ border: "1px solid #fee2e2",
1925
+ marginTop: "16px"
1926
+ }
1927
+ },
1928
+ /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
1929
+ fontSize: "13px",
1930
+ color: "#dc2626",
1931
+ lineHeight: "1.6",
1932
+ fontWeight: 500
1933
+ } }, "Failed to load payment information. Please check your checkout ID.")
1934
+ )),
1935
+ !hasInvalidCheckoutId && fetchingPaymentInfo && /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center py-6" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { color: "#8c8c8c" } }, "Loading payment information...")),
1936
+ !hasInvalidCheckoutId && !fetchingPaymentInfo && !address && /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement(WalletConnect, { supportedNetworks })),
1937
+ !hasInvalidCheckoutId && address && /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(
1938
+ "div",
1939
+ {
1940
+ className: "bg-gray-50 rounded-lg p-3 mb-4",
1941
+ style: { border: "1px solid #f0f0f0" }
1942
+ },
1943
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-3 flex-1" }, /* @__PURE__ */ import_react7.default.createElement(
1944
+ "div",
1945
+ {
1946
+ className: "w-10 h-10 rounded-full bg-black flex items-center justify-center text-white text-sm font-semibold"
1947
+ },
1948
+ address.slice(0, 2).toUpperCase()
1949
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
1950
+ display: "block",
1951
+ fontSize: "12px",
1952
+ color: "#8c8c8c",
1953
+ marginBottom: "2px"
1954
+ } }, "Connected Wallet"), /* @__PURE__ */ import_react7.default.createElement(
1955
+ Text,
1956
+ {
1957
+ style: {
1958
+ fontSize: "13px",
1959
+ fontWeight: 600,
1960
+ fontFamily: "Monaco, monospace"
1961
+ }
1962
+ },
1963
+ formatAddress(address)
1964
+ ))), /* @__PURE__ */ import_react7.default.createElement(
1965
+ import_antd.Button,
1966
+ {
1967
+ type: "text",
1968
+ size: "small",
1969
+ icon: /* @__PURE__ */ import_react7.default.createElement(import_icons.DisconnectOutlined, null),
1970
+ onClick: handleDisconnect,
1971
+ style: { color: "#ff4d4f" }
1972
+ }
1973
+ ))
1974
+ ), paymentDetails && /* @__PURE__ */ import_react7.default.createElement("div", { className: "bg-gray-50 rounded-lg p-3 mb-4", style: { border: "1px solid #f0f0f0" } }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Payment Amount"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "18px", fontWeight: 600 } }, "$", paymentDetails.amount)), /* @__PURE__ */ import_react7.default.createElement(import_antd.Divider, { style: { margin: "6px 0" } }), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Currency"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", fontWeight: 500 } }, paymentDetails.currency)), /* @__PURE__ */ import_react7.default.createElement(import_antd.Divider, { style: { margin: "6px 0" } }), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex justify-between items-center mb-2" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Network"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", fontWeight: 500 } }, paymentDetails.network)), /* @__PURE__ */ import_react7.default.createElement(import_antd.Divider, { style: { margin: "6px 0" } }), /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex justify-between items-start" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Wallet Address"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
1975
+ fontSize: "11px",
1976
+ fontWeight: 500,
1977
+ fontFamily: "Monaco, monospace",
1978
+ wordBreak: "break-all",
1979
+ textAlign: "right",
1980
+ maxWidth: "60%",
1981
+ lineHeight: 1.4
1982
+ } }, address))), /* @__PURE__ */ import_react7.default.createElement(
1983
+ "div",
1984
+ {
1985
+ className: "flex items-center justify-center gap-2 mb-3 p-2 rounded-lg",
1986
+ style: { background: "#f6ffed", border: "1px solid #d9f7be" }
1987
+ },
1988
+ /* @__PURE__ */ import_react7.default.createElement(import_icons.SafetyOutlined, { style: { color: "#52c41a", fontSize: "13px" } }),
1989
+ /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "12px", color: "#52c41a", fontWeight: 500 } }, "Secure payment powered by v402pay")
1990
+ ), /* @__PURE__ */ import_react7.default.createElement(
1991
+ import_antd.Button,
1992
+ {
1993
+ type: "primary",
1994
+ size: "large",
1995
+ onClick: handlePayment,
1996
+ disabled: isProcessing || !paymentDetails,
1997
+ loading: isProcessing,
1998
+ block: true,
1999
+ style: {
2000
+ height: "44px",
2001
+ fontSize: "14px",
2002
+ fontWeight: 600,
2003
+ borderRadius: "8px",
2004
+ ...!isProcessing && paymentDetails && {
2005
+ background: "#1a1a1a",
2006
+ borderColor: "#1a1a1a"
2007
+ },
2008
+ marginBottom: "10px"
2009
+ }
2010
+ },
2011
+ isProcessing ? "Processing..." : !paymentDetails ? "Loading..." : `Pay $${paymentDetails.amount} ${paymentDetails.currency}`
2012
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#8c8c8c" } }, "Don't have USDC?", " "), /* @__PURE__ */ import_react7.default.createElement(
2013
+ "a",
2014
+ {
2015
+ href: "https://faucet.circle.com/",
2016
+ target: "_blank",
2017
+ rel: "noopener noreferrer",
2018
+ className: "text-blue-600 hover:text-blue-700 text-sm font-medium inline-flex items-center gap-1"
2019
+ },
2020
+ "Get it here ",
2021
+ /* @__PURE__ */ import_react7.default.createElement(import_icons.LinkOutlined, { style: { fontSize: "12px" } })
2022
+ )), isModal && result && /* @__PURE__ */ import_react7.default.createElement(
2023
+ "div",
2024
+ {
2025
+ className: "mt-4 p-4 rounded-lg",
2026
+ style: { background: "#f6ffed", border: "1px solid #b7eb8f" }
2027
+ },
2028
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center" }, /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "20px" } }, "\u2713"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
2029
+ fontSize: "14px",
2030
+ color: "#52c41a",
2031
+ fontWeight: 600,
2032
+ marginLeft: "8px"
2033
+ } }, "Payment Successful!"))
2034
+ ), isModal && error && /* @__PURE__ */ import_react7.default.createElement(
2035
+ "div",
2036
+ {
2037
+ className: "mt-4 p-4 rounded-lg",
2038
+ style: { background: "#fff2f0", border: "1px solid #ffccc7" }
2039
+ },
2040
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center mb-3" }, /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "20px" } }, "\u2717"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
2041
+ fontSize: "14px",
2042
+ color: "#ff4d4f",
2043
+ fontWeight: 600,
2044
+ marginLeft: "8px",
2045
+ display: "block",
2046
+ marginTop: "4px"
2047
+ } }, "Payment Failed")),
2048
+ /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
2049
+ fontSize: "13px",
2050
+ color: "#ff4d4f",
2051
+ display: "block",
2052
+ textAlign: "center"
2053
+ } }, error)
2054
+ ))
2055
+ ),
2056
+ !isModal && (isProcessing || result || error) && /* @__PURE__ */ import_react7.default.createElement(
2057
+ import_antd.Card,
2058
+ {
2059
+ title: /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center gap-2" }, isProcessing && !result && !error ? /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(import_icons.LoadingOutlined, { style: { color: "#14b8a6", fontSize: "16px" } }), /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: { fontSize: "16px", color: "#262626" } }, "Processing Payment")) : result ? /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement("span", { style: { color: "#52c41a", fontSize: "18px" } }, "\u2713"), /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: { fontSize: "16px", color: "#262626" } }, "Payment Successful")) : /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement("span", { style: { color: "#ff4d4f", fontSize: "18px" } }, "\u2717"), /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: { fontSize: "16px", color: "#262626" } }, "Payment Failed"))),
2060
+ extra: !isProcessing && /* @__PURE__ */ import_react7.default.createElement(
2061
+ import_antd.Button,
2062
+ {
2063
+ type: "text",
2064
+ size: "small",
2065
+ onClick: () => {
2066
+ setResult(null);
2067
+ setError(null);
2068
+ }
2069
+ },
2070
+ "Close"
2071
+ ),
2072
+ style: {
2073
+ border: "1px solid #e8e8e8",
2074
+ borderRadius: "16px",
2075
+ boxShadow: "0 4px 24px rgba(0, 0, 0, 0.06)",
2076
+ maxHeight: "calc(100vh - 32px)",
2077
+ width: "480px",
2078
+ animation: "slideInRight 0.4s ease-out"
2079
+ },
2080
+ styles: {
2081
+ body: {
2082
+ padding: "24px",
2083
+ maxHeight: "calc(100vh - 120px)",
2084
+ overflow: "auto"
2085
+ }
2086
+ }
2087
+ },
2088
+ isProcessing && !result && !error && /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center py-10" }, /* @__PURE__ */ import_react7.default.createElement("div", { className: "relative inline-block" }, /* @__PURE__ */ import_react7.default.createElement(
2089
+ "div",
2090
+ {
2091
+ className: "absolute inset-0 rounded-full blur-xl opacity-40",
2092
+ style: {
2093
+ background: "linear-gradient(135deg, #14b8a6 0%, #06b6d4 100%)",
2094
+ animation: "pulse 2s ease-in-out infinite"
2095
+ }
2096
+ }
2097
+ ), /* @__PURE__ */ import_react7.default.createElement(
2098
+ import_antd.Spin,
2099
+ {
2100
+ indicator: /* @__PURE__ */ import_react7.default.createElement(import_icons.LoadingOutlined, { style: { fontSize: 56, color: "#14b8a6" } })
2101
+ }
2102
+ )), /* @__PURE__ */ import_react7.default.createElement("div", { className: "mt-6" }, /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: { fontSize: "18px", color: "#262626", letterSpacing: "-0.02em" } }, "Verifying Payment")), /* @__PURE__ */ import_react7.default.createElement("div", { className: "mt-2 mb-6" }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", color: "#8c8c8c", lineHeight: "1.6" } }, "Please wait while we confirm your transaction")), /* @__PURE__ */ import_react7.default.createElement(
2103
+ "div",
2104
+ {
2105
+ className: "mt-4 p-4 rounded-xl",
2106
+ style: {
2107
+ background: "linear-gradient(135deg, #f0fdfa 0%, #ecfeff 100%)",
2108
+ border: "1px solid #ccfbf1"
2109
+ }
2110
+ },
2111
+ /* @__PURE__ */ import_react7.default.createElement("div", { className: "flex items-center justify-center gap-2" }, /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "16px" } }, "\u23F1\uFE0F"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "13px", color: "#0f766e", fontWeight: 500 } }, "This may take a few moments"))
2112
+ )),
2113
+ result && /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center mb-6" }, /* @__PURE__ */ import_react7.default.createElement(
2114
+ "div",
2115
+ {
2116
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-4",
2117
+ style: {
2118
+ background: "linear-gradient(135deg, #10b981 0%, #34d399 100%)",
2119
+ boxShadow: "0 4px 20px rgba(16, 185, 129, 0.3)"
2120
+ }
2121
+ },
2122
+ /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "32px", color: "white" } }, "\u2713")
2123
+ ), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: {
2124
+ fontSize: "20px",
2125
+ color: "#262626",
2126
+ display: "block",
2127
+ marginBottom: "8px"
2128
+ } }, "Payment Successful!"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", color: "#8c8c8c" } }, "Your transaction has been confirmed"))), /* @__PURE__ */ import_react7.default.createElement(import_antd.Divider, { style: { margin: "20px 0", borderColor: "#f0f0f0" } }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "12px", color: "#8c8c8c", fontWeight: 500 } }, "RESPONSE DATA")), /* @__PURE__ */ import_react7.default.createElement(
2129
+ "pre",
2130
+ {
2131
+ style: {
2132
+ background: "#fafafa",
2133
+ padding: "20px",
2134
+ borderRadius: "12px",
2135
+ fontSize: "12px",
2136
+ lineHeight: "1.8",
2137
+ overflow: "auto",
2138
+ margin: 0,
2139
+ fontFamily: "Monaco, Courier New, monospace",
2140
+ whiteSpace: "pre-wrap",
2141
+ wordBreak: "break-word",
2142
+ border: "1px solid #e8e8e8",
2143
+ color: "#262626"
2144
+ }
2145
+ },
2146
+ JSON.stringify(result, null, 2)
2147
+ )),
2148
+ error && /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement("div", { className: "text-center mb-6" }, /* @__PURE__ */ import_react7.default.createElement(
2149
+ "div",
2150
+ {
2151
+ className: "inline-flex items-center justify-center w-16 h-16 rounded-full mb-4",
2152
+ style: {
2153
+ background: "linear-gradient(135deg, #ef4444 0%, #f87171 100%)",
2154
+ boxShadow: "0 4px 20px rgba(239, 68, 68, 0.3)"
2155
+ }
2156
+ },
2157
+ /* @__PURE__ */ import_react7.default.createElement("span", { style: { fontSize: "32px", color: "white" } }, "\u2717")
2158
+ ), /* @__PURE__ */ import_react7.default.createElement("div", null, /* @__PURE__ */ import_react7.default.createElement(Text, { strong: true, style: {
2159
+ fontSize: "20px",
2160
+ color: "#262626",
2161
+ display: "block",
2162
+ marginBottom: "8px"
2163
+ } }, "Payment Failed"), /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "14px", color: "#8c8c8c" } }, "Something went wrong with your transaction"))), /* @__PURE__ */ import_react7.default.createElement(import_antd.Divider, { style: { margin: "20px 0", borderColor: "#f0f0f0" } }, /* @__PURE__ */ import_react7.default.createElement(Text, { style: { fontSize: "12px", color: "#8c8c8c", fontWeight: 500 } }, "ERROR DETAILS")), /* @__PURE__ */ import_react7.default.createElement(
2164
+ "div",
2165
+ {
2166
+ style: {
2167
+ background: "#fef2f2",
2168
+ padding: "20px",
2169
+ borderRadius: "12px",
2170
+ border: "1px solid #fee2e2"
2171
+ }
2172
+ },
2173
+ /* @__PURE__ */ import_react7.default.createElement(Text, { style: {
2174
+ fontSize: "14px",
2175
+ color: "#dc2626",
2176
+ lineHeight: "1.6",
2177
+ fontWeight: 500
2178
+ } }, error)
2179
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { className: "mt-4 text-center" }, /* @__PURE__ */ import_react7.default.createElement(
2180
+ import_antd.Button,
2181
+ {
2182
+ size: "large",
2183
+ onClick: handlePayment,
2184
+ style: {
2185
+ height: "44px",
2186
+ fontSize: "14px",
2187
+ fontWeight: 600,
2188
+ borderRadius: "8px",
2189
+ background: "#1a1a1a",
2190
+ borderColor: "#1a1a1a",
2191
+ color: "white",
2192
+ paddingLeft: "32px",
2193
+ paddingRight: "32px"
2194
+ }
2195
+ },
2196
+ "Try Again"
2197
+ )))
2198
+ )
2199
+ ),
2200
+ /* @__PURE__ */ import_react7.default.createElement("style", { dangerouslySetInnerHTML: {
2201
+ __html: `
2202
+ @keyframes slideInRight {
2203
+ from {
2204
+ opacity: 0;
2205
+ transform: translateX(100px);
2206
+ }
2207
+ to {
2208
+ opacity: 1;
2209
+ transform: translateX(0);
2210
+ }
2211
+ }
2212
+
2213
+ @keyframes pulse {
2214
+ 0%, 100% {
2215
+ transform: scale(1);
2216
+ opacity: 0.4;
2217
+ }
2218
+ 50% {
2219
+ transform: scale(1.1);
2220
+ opacity: 0.6;
2221
+ }
2222
+ }
2223
+ `
2224
+ } })
2225
+ );
1553
2226
  }
1554
2227
  // Annotate the CommonJS export names for ESM import in node:
1555
2228
  0 && (module.exports = {
1556
- PaymentButton,
2229
+ V402Checkout,
1557
2230
  WalletConnect,
2231
+ usePageNetwork,
1558
2232
  usePayment,
1559
2233
  usePaymentInfo,
1560
2234
  useWallet