coinley-checkout 0.3.1 → 0.3.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.
- package/dist/coinley-checkout.es.js +2279 -1345
- package/dist/coinley-checkout.es.js.map +1 -1
- package/dist/coinley-checkout.umd.js +6 -17
- package/dist/coinley-checkout.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -2
@@ -1,441 +1,617 @@
|
|
1
|
-
var
|
2
|
-
var
|
3
|
-
var
|
4
|
-
var
|
5
|
-
var
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
}
|
29
|
-
|
30
|
-
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __defProps = Object.defineProperties;
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
8
|
+
var __spreadValues = (a, b) => {
|
9
|
+
for (var prop in b || (b = {}))
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
12
|
+
if (__getOwnPropSymbols)
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
14
|
+
if (__propIsEnum.call(b, prop))
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
16
|
+
}
|
17
|
+
return a;
|
18
|
+
};
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
20
|
+
var __async = (__this, __arguments, generator) => {
|
21
|
+
return new Promise((resolve, reject) => {
|
22
|
+
var fulfilled = (value) => {
|
23
|
+
try {
|
24
|
+
step(generator.next(value));
|
25
|
+
} catch (e) {
|
26
|
+
reject(e);
|
27
|
+
}
|
28
|
+
};
|
29
|
+
var rejected = (value) => {
|
30
|
+
try {
|
31
|
+
step(generator.throw(value));
|
32
|
+
} catch (e) {
|
33
|
+
reject(e);
|
34
|
+
}
|
35
|
+
};
|
36
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
37
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
38
|
+
});
|
39
|
+
};
|
40
|
+
import React, { createContext, useContext, useState, useEffect, forwardRef, useImperativeHandle } from "react";
|
41
|
+
const styles = "";
|
42
|
+
const NETWORK_TYPES = {
|
31
43
|
ETHEREUM: "ethereum",
|
32
44
|
BSC: "bsc",
|
33
45
|
TRON: "tron",
|
34
46
|
ALGORAND: "algorand"
|
35
|
-
}
|
47
|
+
};
|
48
|
+
const WALLET_TYPES = {
|
36
49
|
METAMASK: "metamask",
|
37
50
|
TRONLINK: "tronlink",
|
38
51
|
TRUST_WALLET: "trust_wallet",
|
39
52
|
LUTE: "lute"
|
40
|
-
}
|
41
|
-
|
53
|
+
};
|
54
|
+
const NETWORK_CONFIG = {
|
55
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
42
56
|
chainId: "0x1",
|
43
57
|
chainName: "Ethereum Mainnet",
|
44
58
|
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
45
59
|
rpcUrls: ["https://mainnet.infura.io/v3/"],
|
46
60
|
blockExplorerUrls: ["https://etherscan.io/"],
|
47
|
-
supportedWallets: [
|
61
|
+
supportedWallets: [WALLET_TYPES.METAMASK, WALLET_TYPES.TRUST_WALLET]
|
48
62
|
},
|
49
|
-
[
|
63
|
+
[NETWORK_TYPES.BSC]: {
|
50
64
|
chainId: "0x38",
|
51
65
|
chainName: "BNB Smart Chain",
|
52
66
|
nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 },
|
53
67
|
rpcUrls: ["https://bsc-dataseed.binance.org/"],
|
54
68
|
blockExplorerUrls: ["https://bscscan.com/"],
|
55
|
-
supportedWallets: [
|
69
|
+
supportedWallets: [WALLET_TYPES.METAMASK, WALLET_TYPES.TRUST_WALLET]
|
56
70
|
},
|
57
|
-
[
|
71
|
+
[NETWORK_TYPES.TRON]: {
|
58
72
|
fullHost: "https://api.trongrid.io",
|
59
73
|
explorerUrl: "https://tronscan.org",
|
60
|
-
supportedWallets: [
|
74
|
+
supportedWallets: [WALLET_TYPES.TRONLINK]
|
61
75
|
},
|
62
|
-
[
|
76
|
+
[NETWORK_TYPES.ALGORAND]: {
|
63
77
|
network: "mainnet",
|
64
78
|
explorerUrl: "https://algoexplorer.io",
|
65
|
-
supportedWallets: [
|
79
|
+
supportedWallets: [WALLET_TYPES.LUTE]
|
66
80
|
}
|
67
|
-
}
|
81
|
+
};
|
82
|
+
const TOKEN_CONFIG = {
|
68
83
|
USDT: {
|
69
|
-
[
|
84
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
70
85
|
address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
71
86
|
decimals: 6
|
72
87
|
},
|
73
|
-
[
|
88
|
+
[NETWORK_TYPES.BSC]: {
|
74
89
|
address: "0x55d398326f99059fF775485246999027B3197955",
|
75
90
|
decimals: 18
|
76
91
|
},
|
77
|
-
[
|
92
|
+
[NETWORK_TYPES.TRON]: {
|
78
93
|
address: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
79
94
|
decimals: 6
|
95
|
+
},
|
96
|
+
[NETWORK_TYPES.ALGORAND]: {
|
97
|
+
address: "312769",
|
98
|
+
// USDT ASA ID on Algorand
|
99
|
+
decimals: 6
|
80
100
|
}
|
81
101
|
},
|
82
102
|
USDC: {
|
83
|
-
[
|
103
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
84
104
|
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
85
105
|
decimals: 6
|
86
106
|
},
|
87
|
-
[
|
107
|
+
[NETWORK_TYPES.BSC]: {
|
88
108
|
address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
|
89
109
|
decimals: 18
|
90
110
|
},
|
91
|
-
[
|
111
|
+
[NETWORK_TYPES.TRON]: {
|
92
112
|
address: "TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8",
|
93
113
|
decimals: 6
|
114
|
+
},
|
115
|
+
[NETWORK_TYPES.ALGORAND]: {
|
116
|
+
address: "31566704",
|
117
|
+
// USDC ASA ID on Algorand
|
118
|
+
decimals: 6
|
119
|
+
}
|
120
|
+
},
|
121
|
+
PYUSD: {
|
122
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
123
|
+
address: "0x6c3ea9036406852006290770BEdFcAbA0e23A0e8",
|
124
|
+
decimals: 6
|
125
|
+
}
|
126
|
+
},
|
127
|
+
FRAX: {
|
128
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
129
|
+
address: "0x853d955aCEf822Db058eb8505911ED77F175b99e",
|
130
|
+
decimals: 18
|
131
|
+
},
|
132
|
+
[NETWORK_TYPES.BSC]: {
|
133
|
+
address: "0x90C97F71E18723b0Cf0dfa30ee176Ab653E89F40",
|
134
|
+
decimals: 18
|
135
|
+
}
|
136
|
+
},
|
137
|
+
USDP: {
|
138
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
139
|
+
address: "0x8E870D67F660D95d5be530380D0eC0bd388289E1",
|
140
|
+
decimals: 18
|
141
|
+
}
|
142
|
+
},
|
143
|
+
DAI: {
|
144
|
+
[NETWORK_TYPES.ETHEREUM]: {
|
145
|
+
address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
146
|
+
decimals: 18
|
147
|
+
}
|
148
|
+
},
|
149
|
+
BUSD: {
|
150
|
+
[NETWORK_TYPES.BSC]: {
|
151
|
+
address: "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
|
152
|
+
decimals: 18
|
153
|
+
}
|
154
|
+
},
|
155
|
+
USDJ: {
|
156
|
+
[NETWORK_TYPES.TRON]: {
|
157
|
+
address: "TMwFHYXLJaRUPeW6421aqXL4ZEzPRFGkGT",
|
158
|
+
decimals: 18
|
94
159
|
}
|
95
160
|
},
|
96
161
|
ALGO: {
|
97
|
-
[
|
162
|
+
[NETWORK_TYPES.ALGORAND]: {
|
98
163
|
address: "native",
|
99
164
|
decimals: 6
|
100
165
|
}
|
101
166
|
}
|
102
167
|
};
|
103
|
-
let
|
104
|
-
const
|
105
|
-
if (
|
106
|
-
return
|
168
|
+
let Web3Cache = null;
|
169
|
+
const getWeb3Instance = () => __async(void 0, null, function* () {
|
170
|
+
if (Web3Cache) {
|
171
|
+
return Web3Cache;
|
172
|
+
}
|
107
173
|
try {
|
108
|
-
if (typeof window
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
174
|
+
if (typeof window !== "undefined" && window.Web3) {
|
175
|
+
Web3Cache = window.Web3;
|
176
|
+
return Web3Cache;
|
177
|
+
}
|
178
|
+
const Web3Module = yield import("web3");
|
179
|
+
Web3Cache = Web3Module.default || Web3Module.Web3 || Web3Module;
|
180
|
+
return Web3Cache;
|
181
|
+
} catch (error) {
|
182
|
+
console.error("Failed to load Web3:", error);
|
183
|
+
throw new Error("Web3 is required for blockchain transactions. Please ensure web3 is installed: npm install web3");
|
114
184
|
}
|
115
|
-
})
|
116
|
-
|
117
|
-
|
118
|
-
[
|
119
|
-
[
|
120
|
-
[
|
185
|
+
});
|
186
|
+
const detectWallets = () => {
|
187
|
+
const wallets = {
|
188
|
+
[WALLET_TYPES.METAMASK]: false,
|
189
|
+
[WALLET_TYPES.TRUST_WALLET]: false,
|
190
|
+
[WALLET_TYPES.TRONLINK]: false,
|
191
|
+
[WALLET_TYPES.LUTE]: false
|
121
192
|
};
|
122
|
-
if (typeof window
|
123
|
-
return
|
193
|
+
if (typeof window === "undefined") {
|
194
|
+
return wallets;
|
195
|
+
}
|
124
196
|
try {
|
125
|
-
|
126
|
-
|
127
|
-
|
197
|
+
wallets[WALLET_TYPES.METAMASK] = !!(window.ethereum && window.ethereum.isMetaMask);
|
198
|
+
wallets[WALLET_TYPES.TRONLINK] = !!window.tronWeb;
|
199
|
+
wallets[WALLET_TYPES.TRUST_WALLET] = !!(window.ethereum && window.ethereum.isTrust);
|
200
|
+
wallets[WALLET_TYPES.LUTE] = !!(window.algorand && window.algorand.isLute);
|
201
|
+
} catch (error) {
|
202
|
+
console.warn("Error detecting wallets:", error);
|
128
203
|
}
|
129
|
-
return
|
130
|
-
}
|
131
|
-
|
132
|
-
|
204
|
+
return wallets;
|
205
|
+
};
|
206
|
+
const getSupportedWalletsForNetwork = (network) => {
|
207
|
+
const networkConfig = NETWORK_CONFIG[network];
|
208
|
+
if (!networkConfig)
|
133
209
|
return [];
|
134
|
-
const
|
135
|
-
return
|
136
|
-
}
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
210
|
+
const availableWallets = detectWallets();
|
211
|
+
return networkConfig.supportedWallets.filter((wallet) => availableWallets[wallet]);
|
212
|
+
};
|
213
|
+
const connectWallet = (walletType, network) => __async(void 0, null, function* () {
|
214
|
+
switch (walletType) {
|
215
|
+
case WALLET_TYPES.METAMASK:
|
216
|
+
return yield connectMetaMask(network);
|
217
|
+
case WALLET_TYPES.TRONLINK:
|
218
|
+
return yield connectTronLink();
|
219
|
+
case WALLET_TYPES.TRUST_WALLET:
|
220
|
+
return yield connectTrustWallet(network);
|
221
|
+
case WALLET_TYPES.LUTE:
|
222
|
+
return yield connectLute();
|
146
223
|
default:
|
147
|
-
throw new Error(`Unsupported wallet type: ${
|
224
|
+
throw new Error(`Unsupported wallet type: ${walletType}`);
|
148
225
|
}
|
149
|
-
})
|
150
|
-
|
226
|
+
});
|
227
|
+
const connectMetaMask = (network) => __async(void 0, null, function* () {
|
228
|
+
if (typeof window === "undefined" || !window.ethereum || !window.ethereum.isMetaMask) {
|
151
229
|
throw new Error("MetaMask is not installed. Please install MetaMask extension.");
|
230
|
+
}
|
152
231
|
try {
|
153
|
-
const
|
232
|
+
const accounts = yield window.ethereum.request({
|
154
233
|
method: "eth_requestAccounts"
|
155
234
|
});
|
156
|
-
if (!
|
235
|
+
if (!accounts || accounts.length === 0) {
|
157
236
|
throw new Error("No accounts found. Please unlock MetaMask.");
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
237
|
+
}
|
238
|
+
const networkConfig = NETWORK_CONFIG[network];
|
239
|
+
if (networkConfig && networkConfig.chainId) {
|
240
|
+
yield switchEVMNetwork(networkConfig);
|
241
|
+
}
|
242
|
+
return {
|
243
|
+
address: accounts[0],
|
244
|
+
network,
|
245
|
+
walletType: WALLET_TYPES.METAMASK
|
163
246
|
};
|
164
|
-
} catch (
|
165
|
-
|
247
|
+
} catch (error) {
|
248
|
+
if (error.code === 4001) {
|
249
|
+
throw new Error("User rejected the connection request");
|
250
|
+
}
|
251
|
+
throw new Error(`Failed to connect MetaMask: ${error.message}`);
|
166
252
|
}
|
167
|
-
})
|
168
|
-
|
169
|
-
|
253
|
+
});
|
254
|
+
const connectTronLink = () => __async(void 0, null, function* () {
|
255
|
+
var _a;
|
256
|
+
if (typeof window === "undefined" || !window.tronWeb) {
|
170
257
|
throw new Error("TronLink is not installed. Please install TronLink extension.");
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
258
|
+
}
|
259
|
+
let attempts = 0;
|
260
|
+
const maxAttempts = 10;
|
261
|
+
while (!window.tronWeb.ready && attempts < maxAttempts) {
|
262
|
+
yield new Promise((resolve) => setTimeout(resolve, 1e3));
|
263
|
+
attempts++;
|
264
|
+
}
|
265
|
+
if (!window.tronWeb.ready) {
|
176
266
|
throw new Error("TronLink is not ready. Please unlock your TronLink wallet and try again.");
|
177
|
-
|
178
|
-
|
267
|
+
}
|
268
|
+
const address = (_a = window.tronWeb.defaultAddress) == null ? void 0 : _a.base58;
|
269
|
+
if (!address) {
|
179
270
|
throw new Error("No account found in TronLink. Please make sure you have an account set up.");
|
271
|
+
}
|
180
272
|
return {
|
181
|
-
address
|
182
|
-
network:
|
183
|
-
walletType:
|
273
|
+
address,
|
274
|
+
network: NETWORK_TYPES.TRON,
|
275
|
+
walletType: WALLET_TYPES.TRONLINK
|
184
276
|
};
|
185
|
-
})
|
186
|
-
|
277
|
+
});
|
278
|
+
const connectTrustWallet = (network) => __async(void 0, null, function* () {
|
279
|
+
if (typeof window === "undefined" || !window.ethereum || !window.ethereum.isTrust) {
|
187
280
|
throw new Error("Trust Wallet is not installed. Please install Trust Wallet extension.");
|
281
|
+
}
|
188
282
|
try {
|
189
|
-
const
|
283
|
+
const accounts = yield window.ethereum.request({
|
190
284
|
method: "eth_requestAccounts"
|
191
285
|
});
|
192
|
-
if (!
|
286
|
+
if (!accounts || accounts.length === 0) {
|
193
287
|
throw new Error("No accounts found. Please unlock Trust Wallet.");
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
288
|
+
}
|
289
|
+
const networkConfig = NETWORK_CONFIG[network];
|
290
|
+
if (networkConfig && networkConfig.chainId) {
|
291
|
+
yield switchEVMNetwork(networkConfig);
|
292
|
+
}
|
293
|
+
return {
|
294
|
+
address: accounts[0],
|
295
|
+
network,
|
296
|
+
walletType: WALLET_TYPES.TRUST_WALLET
|
199
297
|
};
|
200
|
-
} catch (
|
201
|
-
|
298
|
+
} catch (error) {
|
299
|
+
if (error.code === 4001) {
|
300
|
+
throw new Error("User rejected the connection request");
|
301
|
+
}
|
302
|
+
throw new Error(`Failed to connect Trust Wallet: ${error.message}`);
|
202
303
|
}
|
203
|
-
})
|
204
|
-
|
304
|
+
});
|
305
|
+
const connectLute = () => __async(void 0, null, function* () {
|
306
|
+
if (typeof window === "undefined" || !window.algorand || !window.algorand.isLute) {
|
205
307
|
throw new Error("Lute wallet is not installed. Please install Lute wallet extension.");
|
308
|
+
}
|
206
309
|
try {
|
207
|
-
const
|
208
|
-
if (!
|
310
|
+
const accounts = yield window.algorand.connect();
|
311
|
+
if (!accounts || accounts.length === 0) {
|
209
312
|
throw new Error("No accounts found. Please unlock Lute wallet.");
|
313
|
+
}
|
210
314
|
return {
|
211
|
-
address:
|
212
|
-
network:
|
213
|
-
walletType:
|
315
|
+
address: accounts[0],
|
316
|
+
network: NETWORK_TYPES.ALGORAND,
|
317
|
+
walletType: WALLET_TYPES.LUTE
|
214
318
|
};
|
215
|
-
} catch (
|
216
|
-
throw new Error(`Failed to connect Lute wallet: ${
|
319
|
+
} catch (error) {
|
320
|
+
throw new Error(`Failed to connect Lute wallet: ${error.message}`);
|
217
321
|
}
|
218
|
-
})
|
219
|
-
|
322
|
+
});
|
323
|
+
const switchEVMNetwork = (networkConfig) => __async(void 0, null, function* () {
|
324
|
+
if (typeof window === "undefined" || !window.ethereum) {
|
220
325
|
throw new Error("Ethereum provider not found");
|
326
|
+
}
|
221
327
|
try {
|
222
328
|
yield window.ethereum.request({
|
223
329
|
method: "wallet_switchEthereumChain",
|
224
|
-
params: [{ chainId:
|
330
|
+
params: [{ chainId: networkConfig.chainId }]
|
225
331
|
});
|
226
|
-
} catch (
|
227
|
-
if (
|
332
|
+
} catch (switchError) {
|
333
|
+
if (switchError.code === 4902) {
|
228
334
|
try {
|
229
335
|
yield window.ethereum.request({
|
230
336
|
method: "wallet_addEthereumChain",
|
231
|
-
params: [
|
337
|
+
params: [networkConfig]
|
232
338
|
});
|
233
|
-
} catch (
|
234
|
-
throw new Error(`Failed to add ${
|
339
|
+
} catch (addError) {
|
340
|
+
throw new Error(`Failed to add ${networkConfig.chainName} to wallet: ${addError.message}`);
|
235
341
|
}
|
236
|
-
else
|
237
|
-
throw
|
342
|
+
} else if (switchError.code === 4001) {
|
343
|
+
throw new Error("User rejected network switch request");
|
344
|
+
} else {
|
345
|
+
throw new Error(`Failed to switch to ${networkConfig.chainName}: ${switchError.message}`);
|
346
|
+
}
|
238
347
|
}
|
239
|
-
})
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
case
|
246
|
-
return yield
|
247
|
-
case
|
248
|
-
return yield
|
348
|
+
});
|
349
|
+
const sendTransaction = (walletConnection, transactionData) => __async(void 0, null, function* () {
|
350
|
+
const { walletType, network, address } = walletConnection;
|
351
|
+
const { to, amount, tokenAddress, tokenDecimals } = transactionData;
|
352
|
+
switch (walletType) {
|
353
|
+
case WALLET_TYPES.METAMASK:
|
354
|
+
case WALLET_TYPES.TRUST_WALLET:
|
355
|
+
return yield sendEVMTransaction(address, to, amount, tokenAddress, tokenDecimals);
|
356
|
+
case WALLET_TYPES.TRONLINK:
|
357
|
+
return yield sendTronTransaction(to, amount, tokenAddress, tokenDecimals);
|
358
|
+
case WALLET_TYPES.LUTE:
|
359
|
+
return yield sendAlgorandTransaction(address, to, amount);
|
249
360
|
default:
|
250
|
-
throw new Error(`Unsupported wallet type: ${
|
361
|
+
throw new Error(`Unsupported wallet type: ${walletType}`);
|
251
362
|
}
|
252
|
-
})
|
253
|
-
|
363
|
+
});
|
364
|
+
const sendEVMTransaction = (from, to, amount, tokenAddress, tokenDecimals) => __async(void 0, null, function* () {
|
365
|
+
if (typeof window === "undefined" || !window.ethereum) {
|
254
366
|
throw new Error("Ethereum provider not found");
|
367
|
+
}
|
255
368
|
try {
|
256
|
-
const
|
257
|
-
|
369
|
+
const Web3 = yield getWeb3Instance();
|
370
|
+
const web3 = new Web3(window.ethereum);
|
371
|
+
const amountInWei = web3.utils.toBN(
|
372
|
+
Math.floor(parseFloat(amount) * Math.pow(10, tokenDecimals || 18))
|
258
373
|
);
|
259
|
-
if (
|
260
|
-
const
|
374
|
+
if (tokenAddress && tokenAddress !== "native") {
|
375
|
+
const tokenABI = [
|
261
376
|
{
|
262
|
-
constant:
|
377
|
+
constant: false,
|
263
378
|
inputs: [
|
264
379
|
{ name: "_to", type: "address" },
|
265
380
|
{ name: "_value", type: "uint256" }
|
266
381
|
],
|
267
382
|
name: "transfer",
|
268
383
|
outputs: [{ name: "", type: "bool" }],
|
269
|
-
payable:
|
384
|
+
payable: false,
|
270
385
|
stateMutability: "nonpayable",
|
271
386
|
type: "function"
|
272
387
|
}
|
273
388
|
];
|
274
|
-
|
275
|
-
|
276
|
-
return
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
389
|
+
const contract = new web3.eth.Contract(tokenABI, tokenAddress);
|
390
|
+
const receipt = yield contract.methods.transfer(to, amountInWei).send({ from });
|
391
|
+
return receipt.transactionHash;
|
392
|
+
} else {
|
393
|
+
const receipt = yield web3.eth.sendTransaction({
|
394
|
+
from,
|
395
|
+
to,
|
396
|
+
value: amountInWei
|
397
|
+
});
|
398
|
+
return receipt.transactionHash;
|
399
|
+
}
|
400
|
+
} catch (error) {
|
401
|
+
if (error.code === 4001) {
|
402
|
+
throw new Error("Transaction was rejected by user");
|
403
|
+
}
|
404
|
+
throw new Error(`Transaction failed: ${error.message}`);
|
283
405
|
}
|
284
|
-
})
|
285
|
-
|
406
|
+
});
|
407
|
+
const sendTronTransaction = (to, amount, tokenAddress, tokenDecimals) => __async(void 0, null, function* () {
|
408
|
+
if (typeof window === "undefined" || !window.tronWeb || !window.tronWeb.ready) {
|
286
409
|
throw new Error("TronLink is not ready");
|
410
|
+
}
|
287
411
|
try {
|
288
|
-
const
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
412
|
+
const amountInSun = Math.floor(parseFloat(amount) * Math.pow(10, tokenDecimals || 6));
|
413
|
+
if (tokenAddress && tokenAddress !== "native") {
|
414
|
+
const contract = yield window.tronWeb.contract().at(tokenAddress);
|
415
|
+
const result = yield contract.transfer(to, amountInSun).send({
|
416
|
+
feeLimit: 1e8,
|
417
|
+
callValue: 0
|
418
|
+
});
|
419
|
+
return result;
|
420
|
+
} else {
|
421
|
+
const result = yield window.tronWeb.trx.sendTransaction(to, amountInSun);
|
422
|
+
return result.txid;
|
423
|
+
}
|
424
|
+
} catch (error) {
|
425
|
+
throw new Error(`TRON transaction failed: ${error.message}`);
|
295
426
|
}
|
296
|
-
})
|
297
|
-
|
427
|
+
});
|
428
|
+
const sendAlgorandTransaction = (from, to, amount) => __async(void 0, null, function* () {
|
429
|
+
if (typeof window === "undefined" || !window.algorand) {
|
298
430
|
throw new Error("Algorand wallet is not available");
|
431
|
+
}
|
299
432
|
try {
|
300
|
-
const
|
301
|
-
|
302
|
-
|
303
|
-
|
433
|
+
const microAlgos = Math.floor(parseFloat(amount) * 1e6);
|
434
|
+
const txn = {
|
435
|
+
from,
|
436
|
+
to,
|
437
|
+
amount: microAlgos,
|
304
438
|
type: "pay"
|
305
|
-
}
|
306
|
-
|
307
|
-
|
308
|
-
|
439
|
+
};
|
440
|
+
const signedTxn = yield window.algorand.signTransaction(txn);
|
441
|
+
const result = yield window.algorand.sendTransaction(signedTxn);
|
442
|
+
return result.txId;
|
443
|
+
} catch (error) {
|
444
|
+
throw new Error(`Algorand transaction failed: ${error.message}`);
|
309
445
|
}
|
310
|
-
})
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
446
|
+
});
|
447
|
+
const getWalletInstallUrl = (walletType) => {
|
448
|
+
const urls = {
|
449
|
+
[WALLET_TYPES.METAMASK]: "https://metamask.io/",
|
450
|
+
[WALLET_TYPES.TRONLINK]: "https://www.tronlink.org/",
|
451
|
+
[WALLET_TYPES.TRUST_WALLET]: "https://trustwallet.com/",
|
452
|
+
[WALLET_TYPES.LUTE]: "https://lute.app/"
|
453
|
+
};
|
454
|
+
return urls[walletType] || "";
|
455
|
+
};
|
456
|
+
let apiConfig = {
|
317
457
|
apiKey: null,
|
318
458
|
apiSecret: null,
|
319
459
|
apiUrl: "http://localhost:9000",
|
320
460
|
merchantWalletAddresses: {}
|
321
461
|
// Changed to object for multi-network support
|
322
462
|
};
|
323
|
-
const
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
463
|
+
const initializeApi = (config) => {
|
464
|
+
apiConfig = __spreadValues(__spreadValues({}, apiConfig), config);
|
465
|
+
console.log("API initialized with:", {
|
466
|
+
apiUrl: apiConfig.apiUrl,
|
467
|
+
apiKey: apiConfig.apiKey ? `${apiConfig.apiKey.substring(0, 6)}...` : null,
|
468
|
+
hasWalletAddresses: Object.keys(apiConfig.merchantWalletAddresses || {}).length > 0
|
328
469
|
});
|
329
|
-
}
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
470
|
+
};
|
471
|
+
const getHeaders = () => {
|
472
|
+
return {
|
473
|
+
"Content-Type": "application/json",
|
474
|
+
"x-api-key": apiConfig.apiKey,
|
475
|
+
"x-api-secret": apiConfig.apiSecret
|
476
|
+
};
|
477
|
+
};
|
478
|
+
const createPayment = (paymentData) => __async(void 0, null, function* () {
|
334
479
|
try {
|
335
|
-
console.log("Creating payment with data:",
|
336
|
-
|
337
|
-
|
338
|
-
|
480
|
+
console.log("Creating payment with data:", paymentData);
|
481
|
+
console.log("API URL:", `${apiConfig.apiUrl}/api/payments/create`);
|
482
|
+
const enhancedPaymentData = __spreadProps(__spreadValues({}, paymentData), {
|
483
|
+
merchantWalletAddresses: __spreadValues(__spreadValues({}, apiConfig.merchantWalletAddresses), paymentData.merchantWalletAddresses)
|
484
|
+
});
|
485
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/payments/create`, {
|
339
486
|
method: "POST",
|
340
|
-
headers:
|
341
|
-
body: JSON.stringify(
|
487
|
+
headers: getHeaders(),
|
488
|
+
body: JSON.stringify(enhancedPaymentData)
|
342
489
|
});
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
490
|
+
console.log("Create payment response status:", response.status);
|
491
|
+
if (!response.ok) {
|
492
|
+
const errorData = yield response.json();
|
493
|
+
console.error("Error creating payment:", errorData);
|
494
|
+
throw new Error(errorData.error || `Failed to create payment: ${response.status}`);
|
495
|
+
}
|
496
|
+
const data = yield response.json();
|
497
|
+
console.log("Create payment response data:", data);
|
498
|
+
return data;
|
499
|
+
} catch (error) {
|
500
|
+
console.error("Create payment error:", error);
|
501
|
+
throw error;
|
351
502
|
}
|
352
|
-
})
|
503
|
+
});
|
504
|
+
const getPayment = (paymentId) => __async(void 0, null, function* () {
|
353
505
|
try {
|
354
|
-
console.log("Getting payment:",
|
355
|
-
const
|
506
|
+
console.log("Getting payment:", paymentId);
|
507
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/payments/${paymentId}`, {
|
356
508
|
method: "GET",
|
357
|
-
headers:
|
509
|
+
headers: getHeaders()
|
358
510
|
});
|
359
|
-
if (!
|
360
|
-
const
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
511
|
+
if (!response.ok) {
|
512
|
+
const errorData = yield response.json();
|
513
|
+
console.error("Error getting payment:", errorData);
|
514
|
+
throw new Error(errorData.error || `Failed to get payment: ${response.status}`);
|
515
|
+
}
|
516
|
+
const data = yield response.json();
|
517
|
+
console.log("Get payment response:", data);
|
518
|
+
return data;
|
519
|
+
} catch (error) {
|
520
|
+
console.error("Get payment error:", error);
|
521
|
+
throw error;
|
367
522
|
}
|
368
|
-
})
|
523
|
+
});
|
524
|
+
const processPayment = (processData) => __async(void 0, null, function* () {
|
369
525
|
try {
|
370
|
-
console.log("Processing payment with data:",
|
371
|
-
|
526
|
+
console.log("Processing payment with data:", processData);
|
527
|
+
console.log("API URL:", `${apiConfig.apiUrl}/api/payments/process`);
|
528
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/payments/process`, {
|
372
529
|
method: "POST",
|
373
|
-
headers:
|
374
|
-
body: JSON.stringify(
|
530
|
+
headers: getHeaders(),
|
531
|
+
body: JSON.stringify(processData)
|
375
532
|
});
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
533
|
+
console.log("Process payment response status:", response.status);
|
534
|
+
if (!response.ok) {
|
535
|
+
const errorData = yield response.json();
|
536
|
+
console.error("Error processing payment:", errorData);
|
537
|
+
throw new Error(errorData.error || `Failed to process payment: ${response.status}`);
|
538
|
+
}
|
539
|
+
const data = yield response.json();
|
540
|
+
console.log("Process payment response data:", data);
|
541
|
+
return data;
|
542
|
+
} catch (error) {
|
543
|
+
console.error("Process payment error:", error);
|
544
|
+
throw error;
|
384
545
|
}
|
385
|
-
})
|
546
|
+
});
|
547
|
+
const getSupportedNetworks = () => __async(void 0, null, function* () {
|
386
548
|
try {
|
387
|
-
const
|
549
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/networks`, {
|
388
550
|
method: "GET",
|
389
|
-
headers:
|
551
|
+
headers: getHeaders()
|
390
552
|
});
|
391
|
-
if (!
|
392
|
-
const
|
393
|
-
throw new Error(
|
394
|
-
}
|
395
|
-
|
396
|
-
|
397
|
-
|
553
|
+
if (!response.ok) {
|
554
|
+
const errorData = yield response.json();
|
555
|
+
throw new Error(errorData.error || `Failed to get networks: ${response.status}`);
|
556
|
+
}
|
557
|
+
const data = yield response.json();
|
558
|
+
return data;
|
559
|
+
} catch (error) {
|
560
|
+
console.error("Get supported networks error:", error);
|
561
|
+
throw error;
|
398
562
|
}
|
399
|
-
})
|
563
|
+
});
|
564
|
+
const getMerchantProfile = () => __async(void 0, null, function* () {
|
400
565
|
try {
|
401
|
-
const
|
566
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/merchants/profile`, {
|
402
567
|
method: "GET",
|
403
|
-
headers:
|
568
|
+
headers: getHeaders()
|
404
569
|
});
|
405
|
-
if (!
|
406
|
-
const
|
407
|
-
throw new Error(
|
408
|
-
}
|
409
|
-
const
|
410
|
-
|
411
|
-
|
412
|
-
|
570
|
+
if (!response.ok) {
|
571
|
+
const errorData = yield response.json();
|
572
|
+
throw new Error(errorData.error || `Failed to get merchant profile: ${response.status}`);
|
573
|
+
}
|
574
|
+
const data = yield response.json();
|
575
|
+
if (data.merchant && data.merchant.walletAddresses) {
|
576
|
+
apiConfig.merchantWalletAddresses = __spreadValues(__spreadValues({}, apiConfig.merchantWalletAddresses), data.merchant.walletAddresses);
|
577
|
+
}
|
578
|
+
return data;
|
579
|
+
} catch (error) {
|
580
|
+
console.error("Get merchant profile error:", error);
|
581
|
+
throw error;
|
413
582
|
}
|
414
|
-
})
|
583
|
+
});
|
584
|
+
const validateWalletAddress = (address, network) => __async(void 0, null, function* () {
|
415
585
|
try {
|
416
|
-
const
|
586
|
+
const response = yield fetch(`${apiConfig.apiUrl}/api/wallets/validate`, {
|
417
587
|
method: "POST",
|
418
|
-
headers:
|
419
|
-
body: JSON.stringify({ address
|
588
|
+
headers: getHeaders(),
|
589
|
+
body: JSON.stringify({ address, network })
|
420
590
|
});
|
421
|
-
if (!
|
422
|
-
const
|
423
|
-
throw new Error(
|
424
|
-
}
|
425
|
-
|
426
|
-
|
427
|
-
|
591
|
+
if (!response.ok) {
|
592
|
+
const errorData = yield response.json();
|
593
|
+
throw new Error(errorData.error || `Failed to validate address: ${response.status}`);
|
594
|
+
}
|
595
|
+
const data = yield response.json();
|
596
|
+
return data;
|
597
|
+
} catch (error) {
|
598
|
+
console.error("Validate wallet address error:", error);
|
599
|
+
throw error;
|
428
600
|
}
|
429
|
-
})
|
430
|
-
|
601
|
+
});
|
602
|
+
const generateMockTransactionHash = (network = "ethereum") => {
|
603
|
+
const prefixes = {
|
431
604
|
ethereum: "0x",
|
432
605
|
bsc: "0x",
|
433
606
|
tron: "",
|
434
607
|
algorand: ""
|
435
|
-
}
|
436
|
-
|
608
|
+
};
|
609
|
+
const prefix = prefixes[network] || "0x";
|
610
|
+
const hash = Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
|
611
|
+
return `${prefix}${hash}`;
|
437
612
|
};
|
438
|
-
var
|
613
|
+
var jsxRuntime = { exports: {} };
|
614
|
+
var reactJsxRuntime_production_min = {};
|
439
615
|
/**
|
440
616
|
* @license React
|
441
617
|
* react-jsx-runtime.production.min.js
|
@@ -445,129 +621,182 @@ var be = { exports: {} }, ne = {};
|
|
445
621
|
* This source code is licensed under the MIT license found in the
|
446
622
|
* LICENSE file in the root directory of this source tree.
|
447
623
|
*/
|
448
|
-
var
|
449
|
-
function
|
450
|
-
var
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
624
|
+
var f = React, k = Symbol.for("react.element"), l = Symbol.for("react.fragment"), m = Object.prototype.hasOwnProperty, n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, p = { key: true, ref: true, __self: true, __source: true };
|
625
|
+
function q(c, a, g) {
|
626
|
+
var b, d = {}, e = null, h = null;
|
627
|
+
void 0 !== g && (e = "" + g);
|
628
|
+
void 0 !== a.key && (e = "" + a.key);
|
629
|
+
void 0 !== a.ref && (h = a.ref);
|
630
|
+
for (b in a)
|
631
|
+
m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
|
632
|
+
if (c && c.defaultProps)
|
633
|
+
for (b in a = c.defaultProps, a)
|
634
|
+
void 0 === d[b] && (d[b] = a[b]);
|
635
|
+
return { $$typeof: k, type: c, key: e, ref: h, props: d, _owner: n.current };
|
458
636
|
}
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
637
|
+
reactJsxRuntime_production_min.Fragment = l;
|
638
|
+
reactJsxRuntime_production_min.jsx = q;
|
639
|
+
reactJsxRuntime_production_min.jsxs = q;
|
640
|
+
{
|
641
|
+
jsxRuntime.exports = reactJsxRuntime_production_min;
|
642
|
+
}
|
643
|
+
var jsxRuntimeExports = jsxRuntime.exports;
|
644
|
+
const ThemeContext = createContext();
|
645
|
+
const useTheme = () => useContext(ThemeContext);
|
646
|
+
const ThemeProvider = ({ initialTheme = "light", children }) => {
|
647
|
+
const [theme, setTheme] = useState(initialTheme);
|
648
|
+
const toggleTheme = () => {
|
649
|
+
setTheme((prevTheme) => prevTheme === "light" ? "dark" : "light");
|
467
650
|
};
|
468
|
-
|
469
|
-
document.documentElement.classList.remove("light", "dark")
|
470
|
-
|
471
|
-
},
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
651
|
+
useEffect(() => {
|
652
|
+
document.documentElement.classList.remove("light", "dark");
|
653
|
+
document.documentElement.classList.add(theme);
|
654
|
+
}, [theme]);
|
655
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(ThemeContext.Provider, { value: { theme, setTheme, toggleTheme }, children });
|
656
|
+
};
|
657
|
+
const CoinleyContext = createContext();
|
658
|
+
const useCoinley = () => useContext(CoinleyContext);
|
659
|
+
const CoinleyProvider = ({
|
660
|
+
apiKey,
|
661
|
+
apiSecret,
|
662
|
+
apiUrl = "http://localhost:9000",
|
663
|
+
merchantWalletAddress = null,
|
476
664
|
// New prop for merchant wallet address
|
477
|
-
merchantSolWalletAddress
|
665
|
+
merchantSolWalletAddress = null,
|
478
666
|
// New prop for Solana wallet address
|
479
|
-
debug
|
480
|
-
children
|
667
|
+
debug = false,
|
668
|
+
children
|
481
669
|
}) => {
|
482
|
-
const [
|
483
|
-
|
484
|
-
|
485
|
-
|
670
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
671
|
+
const [error, setError] = useState(null);
|
672
|
+
const [paymentData, setPaymentData] = useState(null);
|
673
|
+
useEffect(() => {
|
674
|
+
if (!apiKey || !apiSecret) {
|
675
|
+
setError("API key and secret are required");
|
486
676
|
return;
|
487
677
|
}
|
488
678
|
try {
|
489
|
-
|
490
|
-
apiKey
|
491
|
-
apiSecret
|
492
|
-
apiUrl
|
493
|
-
merchantWalletAddress
|
679
|
+
initializeApi({
|
680
|
+
apiKey,
|
681
|
+
apiSecret,
|
682
|
+
apiUrl,
|
683
|
+
merchantWalletAddress,
|
494
684
|
// Pass wallet address to API service
|
495
|
-
merchantSolWalletAddress
|
496
|
-
}), e(!0), h && console.log("Coinley SDK initialized with:", {
|
497
|
-
apiKey: s,
|
498
|
-
apiUrl: t,
|
499
|
-
merchantWalletAddress: c ? `${c.substring(0, 6)}...${c.substring(c.length - 4)}` : "Not provided",
|
500
|
-
merchantSolWalletAddress: u ? `${u.substring(0, 6)}...${u.substring(u.length - 4)}` : "Not provided"
|
685
|
+
merchantSolWalletAddress
|
501
686
|
});
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
687
|
+
setIsInitialized(true);
|
688
|
+
if (debug) {
|
689
|
+
console.log("Coinley SDK initialized with:", {
|
690
|
+
apiKey,
|
691
|
+
apiUrl,
|
692
|
+
merchantWalletAddress: merchantWalletAddress ? `${merchantWalletAddress.substring(0, 6)}...${merchantWalletAddress.substring(merchantWalletAddress.length - 4)}` : "Not provided",
|
693
|
+
merchantSolWalletAddress: merchantSolWalletAddress ? `${merchantSolWalletAddress.substring(0, 6)}...${merchantSolWalletAddress.substring(merchantSolWalletAddress.length - 4)}` : "Not provided"
|
694
|
+
});
|
695
|
+
}
|
696
|
+
} catch (err) {
|
697
|
+
setError(err.message);
|
698
|
+
if (debug) {
|
699
|
+
console.error("Coinley SDK initialization error:", err);
|
700
|
+
}
|
701
|
+
}
|
702
|
+
}, [apiKey, apiSecret, apiUrl, merchantWalletAddress, merchantSolWalletAddress, debug]);
|
703
|
+
const storePaymentData = (data) => {
|
704
|
+
setPaymentData(data);
|
705
|
+
return data;
|
706
|
+
};
|
707
|
+
const value = {
|
708
|
+
apiKey,
|
709
|
+
apiSecret,
|
710
|
+
apiUrl,
|
711
|
+
merchantWalletAddress,
|
712
|
+
merchantSolWalletAddress,
|
713
|
+
isInitialized,
|
714
|
+
error,
|
715
|
+
debug,
|
716
|
+
paymentData,
|
717
|
+
storePaymentData
|
517
718
|
};
|
518
|
-
return /* @__PURE__ */
|
719
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(CoinleyContext.Provider, { value, children });
|
720
|
+
};
|
721
|
+
var __defProp2 = Object.defineProperty;
|
722
|
+
var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
|
723
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
724
|
+
var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
|
725
|
+
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
726
|
+
var __spreadValues2 = (a, b) => {
|
727
|
+
for (var prop in b || (b = {}))
|
728
|
+
if (__hasOwnProp2.call(b, prop))
|
729
|
+
__defNormalProp2(a, prop, b[prop]);
|
730
|
+
if (__getOwnPropSymbols2)
|
731
|
+
for (var prop of __getOwnPropSymbols2(b)) {
|
732
|
+
if (__propIsEnum2.call(b, prop))
|
733
|
+
__defNormalProp2(a, prop, b[prop]);
|
734
|
+
}
|
735
|
+
return a;
|
519
736
|
};
|
520
|
-
var
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
if (s != null && se)
|
532
|
-
for (var c of se(s))
|
533
|
-
r.indexOf(c) < 0 && je.call(s, c) && (t[c] = s[c]);
|
534
|
-
return t;
|
737
|
+
var __objRest = (source, exclude) => {
|
738
|
+
var target = {};
|
739
|
+
for (var prop in source)
|
740
|
+
if (__hasOwnProp2.call(source, prop) && exclude.indexOf(prop) < 0)
|
741
|
+
target[prop] = source[prop];
|
742
|
+
if (source != null && __getOwnPropSymbols2)
|
743
|
+
for (var prop of __getOwnPropSymbols2(source)) {
|
744
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum2.call(source, prop))
|
745
|
+
target[prop] = source[prop];
|
746
|
+
}
|
747
|
+
return target;
|
535
748
|
};
|
536
749
|
/**
|
537
750
|
* @license QR Code generator library (TypeScript)
|
538
751
|
* Copyright (c) Project Nayuki.
|
539
752
|
* SPDX-License-Identifier: MIT
|
540
753
|
*/
|
541
|
-
var
|
542
|
-
((
|
543
|
-
const
|
754
|
+
var qrcodegen;
|
755
|
+
((qrcodegen2) => {
|
756
|
+
const _QrCode = class _QrCode2 {
|
544
757
|
/*-- Constructor (low level) and fields --*/
|
545
758
|
// Creates a new QR Code with the given version number,
|
546
759
|
// error correction level, data codeword bytes, and mask number.
|
547
760
|
// This is a low-level API that most users should not use directly.
|
548
761
|
// A mid-level API is the encodeSegments() function.
|
549
|
-
constructor(
|
550
|
-
|
762
|
+
constructor(version, errorCorrectionLevel, dataCodewords, msk) {
|
763
|
+
this.version = version;
|
764
|
+
this.errorCorrectionLevel = errorCorrectionLevel;
|
765
|
+
this.modules = [];
|
766
|
+
this.isFunction = [];
|
767
|
+
if (version < _QrCode2.MIN_VERSION || version > _QrCode2.MAX_VERSION)
|
551
768
|
throw new RangeError("Version value out of range");
|
552
|
-
if (
|
769
|
+
if (msk < -1 || msk > 7)
|
553
770
|
throw new RangeError("Mask value out of range");
|
554
|
-
this.size =
|
555
|
-
let
|
556
|
-
for (let
|
557
|
-
|
558
|
-
for (let
|
559
|
-
this.modules.push(
|
771
|
+
this.size = version * 4 + 17;
|
772
|
+
let row = [];
|
773
|
+
for (let i = 0; i < this.size; i++)
|
774
|
+
row.push(false);
|
775
|
+
for (let i = 0; i < this.size; i++) {
|
776
|
+
this.modules.push(row.slice());
|
777
|
+
this.isFunction.push(row.slice());
|
778
|
+
}
|
560
779
|
this.drawFunctionPatterns();
|
561
|
-
const
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
780
|
+
const allCodewords = this.addEccAndInterleave(dataCodewords);
|
781
|
+
this.drawCodewords(allCodewords);
|
782
|
+
if (msk == -1) {
|
783
|
+
let minPenalty = 1e9;
|
784
|
+
for (let i = 0; i < 8; i++) {
|
785
|
+
this.applyMask(i);
|
786
|
+
this.drawFormatBits(i);
|
787
|
+
const penalty = this.getPenaltyScore();
|
788
|
+
if (penalty < minPenalty) {
|
789
|
+
msk = i;
|
790
|
+
minPenalty = penalty;
|
791
|
+
}
|
792
|
+
this.applyMask(i);
|
568
793
|
}
|
569
794
|
}
|
570
|
-
|
795
|
+
assert(0 <= msk && msk <= 7);
|
796
|
+
this.mask = msk;
|
797
|
+
this.applyMask(msk);
|
798
|
+
this.drawFormatBits(msk);
|
799
|
+
this.isFunction = [];
|
571
800
|
}
|
572
801
|
/*-- Static factory functions (high level) --*/
|
573
802
|
// Returns a QR Code representing the given Unicode text string at the given error correction level.
|
@@ -575,17 +804,17 @@ var K;
|
|
575
804
|
// Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
|
576
805
|
// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
|
577
806
|
// ecl argument if it can be done without increasing the version.
|
578
|
-
static encodeText(
|
579
|
-
const
|
580
|
-
return
|
807
|
+
static encodeText(text, ecl) {
|
808
|
+
const segs = qrcodegen2.QrSegment.makeSegments(text);
|
809
|
+
return _QrCode2.encodeSegments(segs, ecl);
|
581
810
|
}
|
582
811
|
// Returns a QR Code representing the given binary data at the given error correction level.
|
583
812
|
// This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
584
813
|
// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
585
814
|
// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
|
586
|
-
static encodeBinary(
|
587
|
-
const
|
588
|
-
return
|
815
|
+
static encodeBinary(data, ecl) {
|
816
|
+
const seg = qrcodegen2.QrSegment.makeBytes(data);
|
817
|
+
return _QrCode2.encodeSegments([seg], ecl);
|
589
818
|
}
|
590
819
|
/*-- Static factory functions (mid level) --*/
|
591
820
|
// Returns a QR Code representing the given segments with the given encoding parameters.
|
@@ -597,43 +826,52 @@ var K;
|
|
597
826
|
// This function allows the user to create a custom sequence of segments that switches
|
598
827
|
// between modes (such as alphanumeric and byte) to encode text in less space.
|
599
828
|
// This is a mid-level API; the high-level API is encodeText() and encodeBinary().
|
600
|
-
static encodeSegments(
|
601
|
-
if (!(
|
829
|
+
static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
830
|
+
if (!(_QrCode2.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= _QrCode2.MAX_VERSION) || mask < -1 || mask > 7)
|
602
831
|
throw new RangeError("Invalid value");
|
603
|
-
let
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
832
|
+
let version;
|
833
|
+
let dataUsedBits;
|
834
|
+
for (version = minVersion; ; version++) {
|
835
|
+
const dataCapacityBits2 = _QrCode2.getNumDataCodewords(version, ecl) * 8;
|
836
|
+
const usedBits = QrSegment.getTotalBits(segs, version);
|
837
|
+
if (usedBits <= dataCapacityBits2) {
|
838
|
+
dataUsedBits = usedBits;
|
608
839
|
break;
|
609
840
|
}
|
610
|
-
if (
|
841
|
+
if (version >= maxVersion)
|
611
842
|
throw new RangeError("Data too long");
|
612
843
|
}
|
613
|
-
for (const
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
844
|
+
for (const newEcl of [_QrCode2.Ecc.MEDIUM, _QrCode2.Ecc.QUARTILE, _QrCode2.Ecc.HIGH]) {
|
845
|
+
if (boostEcl && dataUsedBits <= _QrCode2.getNumDataCodewords(version, newEcl) * 8)
|
846
|
+
ecl = newEcl;
|
847
|
+
}
|
848
|
+
let bb = [];
|
849
|
+
for (const seg of segs) {
|
850
|
+
appendBits(seg.mode.modeBits, 4, bb);
|
851
|
+
appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
|
852
|
+
for (const b of seg.getData())
|
853
|
+
bb.push(b);
|
620
854
|
}
|
621
|
-
|
622
|
-
const
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
for (;
|
628
|
-
|
629
|
-
|
855
|
+
assert(bb.length == dataUsedBits);
|
856
|
+
const dataCapacityBits = _QrCode2.getNumDataCodewords(version, ecl) * 8;
|
857
|
+
assert(bb.length <= dataCapacityBits);
|
858
|
+
appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);
|
859
|
+
appendBits(0, (8 - bb.length % 8) % 8, bb);
|
860
|
+
assert(bb.length % 8 == 0);
|
861
|
+
for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)
|
862
|
+
appendBits(padByte, 8, bb);
|
863
|
+
let dataCodewords = [];
|
864
|
+
while (dataCodewords.length * 8 < bb.length)
|
865
|
+
dataCodewords.push(0);
|
866
|
+
bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));
|
867
|
+
return new _QrCode2(version, ecl, dataCodewords, mask);
|
630
868
|
}
|
631
869
|
/*-- Accessor methods --*/
|
632
870
|
// Returns the color of the module (pixel) at the given coordinates, which is false
|
633
871
|
// for light or true for dark. The top left corner has the coordinates (x=0, y=0).
|
634
872
|
// If the given coordinates are out of bounds, then false (light) is returned.
|
635
|
-
getModule(
|
636
|
-
return 0 <=
|
873
|
+
getModule(x, y) {
|
874
|
+
return 0 <= x && x < this.size && 0 <= y && y < this.size && this.modules[y][x];
|
637
875
|
}
|
638
876
|
// Modified to expose modules for easy access
|
639
877
|
getModules() {
|
@@ -642,178 +880,253 @@ var K;
|
|
642
880
|
/*-- Private helper methods for constructor: Drawing function modules --*/
|
643
881
|
// Reads this object's version field, and draws and marks all function modules.
|
644
882
|
drawFunctionPatterns() {
|
645
|
-
for (let
|
646
|
-
this.setFunctionModule(6,
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
883
|
+
for (let i = 0; i < this.size; i++) {
|
884
|
+
this.setFunctionModule(6, i, i % 2 == 0);
|
885
|
+
this.setFunctionModule(i, 6, i % 2 == 0);
|
886
|
+
}
|
887
|
+
this.drawFinderPattern(3, 3);
|
888
|
+
this.drawFinderPattern(this.size - 4, 3);
|
889
|
+
this.drawFinderPattern(3, this.size - 4);
|
890
|
+
const alignPatPos = this.getAlignmentPatternPositions();
|
891
|
+
const numAlign = alignPatPos.length;
|
892
|
+
for (let i = 0; i < numAlign; i++) {
|
893
|
+
for (let j = 0; j < numAlign; j++) {
|
894
|
+
if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0))
|
895
|
+
this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
|
896
|
+
}
|
897
|
+
}
|
898
|
+
this.drawFormatBits(0);
|
899
|
+
this.drawVersion();
|
653
900
|
}
|
654
901
|
// Draws two copies of the format bits (with its own error correction code)
|
655
902
|
// based on the given mask and this object's error correction level field.
|
656
|
-
drawFormatBits(
|
657
|
-
const
|
658
|
-
let
|
659
|
-
for (let
|
660
|
-
|
661
|
-
const
|
662
|
-
|
663
|
-
for (let
|
664
|
-
this.setFunctionModule(8,
|
665
|
-
this.setFunctionModule(8, 7,
|
666
|
-
|
667
|
-
|
668
|
-
for (let
|
669
|
-
this.setFunctionModule(
|
670
|
-
for (let
|
671
|
-
this.setFunctionModule(
|
672
|
-
|
903
|
+
drawFormatBits(mask) {
|
904
|
+
const data = this.errorCorrectionLevel.formatBits << 3 | mask;
|
905
|
+
let rem = data;
|
906
|
+
for (let i = 0; i < 10; i++)
|
907
|
+
rem = rem << 1 ^ (rem >>> 9) * 1335;
|
908
|
+
const bits = (data << 10 | rem) ^ 21522;
|
909
|
+
assert(bits >>> 15 == 0);
|
910
|
+
for (let i = 0; i <= 5; i++)
|
911
|
+
this.setFunctionModule(8, i, getBit(bits, i));
|
912
|
+
this.setFunctionModule(8, 7, getBit(bits, 6));
|
913
|
+
this.setFunctionModule(8, 8, getBit(bits, 7));
|
914
|
+
this.setFunctionModule(7, 8, getBit(bits, 8));
|
915
|
+
for (let i = 9; i < 15; i++)
|
916
|
+
this.setFunctionModule(14 - i, 8, getBit(bits, i));
|
917
|
+
for (let i = 0; i < 8; i++)
|
918
|
+
this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));
|
919
|
+
for (let i = 8; i < 15; i++)
|
920
|
+
this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));
|
921
|
+
this.setFunctionModule(8, this.size - 8, true);
|
673
922
|
}
|
674
923
|
// Draws two copies of the version bits (with its own error correction code),
|
675
924
|
// based on this object's version field, iff 7 <= version <= 40.
|
676
925
|
drawVersion() {
|
677
926
|
if (this.version < 7)
|
678
927
|
return;
|
679
|
-
let
|
680
|
-
for (let
|
681
|
-
|
682
|
-
const
|
683
|
-
|
684
|
-
for (let
|
685
|
-
const
|
686
|
-
|
928
|
+
let rem = this.version;
|
929
|
+
for (let i = 0; i < 12; i++)
|
930
|
+
rem = rem << 1 ^ (rem >>> 11) * 7973;
|
931
|
+
const bits = this.version << 12 | rem;
|
932
|
+
assert(bits >>> 18 == 0);
|
933
|
+
for (let i = 0; i < 18; i++) {
|
934
|
+
const color = getBit(bits, i);
|
935
|
+
const a = this.size - 11 + i % 3;
|
936
|
+
const b = Math.floor(i / 3);
|
937
|
+
this.setFunctionModule(a, b, color);
|
938
|
+
this.setFunctionModule(b, a, color);
|
687
939
|
}
|
688
940
|
}
|
689
941
|
// Draws a 9*9 finder pattern including the border separator,
|
690
942
|
// with the center module at (x, y). Modules can be out of bounds.
|
691
|
-
drawFinderPattern(
|
692
|
-
for (let
|
693
|
-
for (let
|
694
|
-
const
|
695
|
-
|
943
|
+
drawFinderPattern(x, y) {
|
944
|
+
for (let dy = -4; dy <= 4; dy++) {
|
945
|
+
for (let dx = -4; dx <= 4; dx++) {
|
946
|
+
const dist = Math.max(Math.abs(dx), Math.abs(dy));
|
947
|
+
const xx = x + dx;
|
948
|
+
const yy = y + dy;
|
949
|
+
if (0 <= xx && xx < this.size && 0 <= yy && yy < this.size)
|
950
|
+
this.setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
696
951
|
}
|
952
|
+
}
|
697
953
|
}
|
698
954
|
// Draws a 5*5 alignment pattern, with the center module
|
699
955
|
// at (x, y). All modules must be in bounds.
|
700
|
-
drawAlignmentPattern(
|
701
|
-
for (let
|
702
|
-
for (let
|
703
|
-
this.setFunctionModule(
|
956
|
+
drawAlignmentPattern(x, y) {
|
957
|
+
for (let dy = -2; dy <= 2; dy++) {
|
958
|
+
for (let dx = -2; dx <= 2; dx++)
|
959
|
+
this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);
|
960
|
+
}
|
704
961
|
}
|
705
962
|
// Sets the color of a module and marks it as a function module.
|
706
963
|
// Only used by the constructor. Coordinates must be in bounds.
|
707
|
-
setFunctionModule(
|
708
|
-
this.modules[
|
964
|
+
setFunctionModule(x, y, isDark) {
|
965
|
+
this.modules[y][x] = isDark;
|
966
|
+
this.isFunction[y][x] = true;
|
709
967
|
}
|
710
968
|
/*-- Private helper methods for constructor: Codewords and masking --*/
|
711
969
|
// Returns a new byte string representing the given data with the appropriate error correction
|
712
970
|
// codewords appended to it, based on this object's version and error correction level.
|
713
|
-
addEccAndInterleave(
|
714
|
-
const
|
715
|
-
|
971
|
+
addEccAndInterleave(data) {
|
972
|
+
const ver = this.version;
|
973
|
+
const ecl = this.errorCorrectionLevel;
|
974
|
+
if (data.length != _QrCode2.getNumDataCodewords(ver, ecl))
|
716
975
|
throw new RangeError("Invalid argument");
|
717
|
-
const
|
718
|
-
|
719
|
-
const
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
976
|
+
const numBlocks = _QrCode2.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
977
|
+
const blockEccLen = _QrCode2.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];
|
978
|
+
const rawCodewords = Math.floor(_QrCode2.getNumRawDataModules(ver) / 8);
|
979
|
+
const numShortBlocks = numBlocks - rawCodewords % numBlocks;
|
980
|
+
const shortBlockLen = Math.floor(rawCodewords / numBlocks);
|
981
|
+
let blocks = [];
|
982
|
+
const rsDiv = _QrCode2.reedSolomonComputeDivisor(blockEccLen);
|
983
|
+
for (let i = 0, k2 = 0; i < numBlocks; i++) {
|
984
|
+
let dat = data.slice(k2, k2 + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
|
985
|
+
k2 += dat.length;
|
986
|
+
const ecc = _QrCode2.reedSolomonComputeRemainder(dat, rsDiv);
|
987
|
+
if (i < numShortBlocks)
|
988
|
+
dat.push(0);
|
989
|
+
blocks.push(dat.concat(ecc));
|
725
990
|
}
|
726
|
-
let
|
727
|
-
for (let
|
728
|
-
|
729
|
-
(
|
991
|
+
let result = [];
|
992
|
+
for (let i = 0; i < blocks[0].length; i++) {
|
993
|
+
blocks.forEach((block, j) => {
|
994
|
+
if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
|
995
|
+
result.push(block[i]);
|
730
996
|
});
|
731
|
-
|
997
|
+
}
|
998
|
+
assert(result.length == rawCodewords);
|
999
|
+
return result;
|
732
1000
|
}
|
733
1001
|
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
|
734
1002
|
// data area of this QR Code. Function modules need to be marked off before this is called.
|
735
|
-
drawCodewords(
|
736
|
-
if (
|
1003
|
+
drawCodewords(data) {
|
1004
|
+
if (data.length != Math.floor(_QrCode2.getNumRawDataModules(this.version) / 8))
|
737
1005
|
throw new RangeError("Invalid argument");
|
738
|
-
let
|
739
|
-
for (let
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
1006
|
+
let i = 0;
|
1007
|
+
for (let right = this.size - 1; right >= 1; right -= 2) {
|
1008
|
+
if (right == 6)
|
1009
|
+
right = 5;
|
1010
|
+
for (let vert = 0; vert < this.size; vert++) {
|
1011
|
+
for (let j = 0; j < 2; j++) {
|
1012
|
+
const x = right - j;
|
1013
|
+
const upward = (right + 1 & 2) == 0;
|
1014
|
+
const y = upward ? this.size - 1 - vert : vert;
|
1015
|
+
if (!this.isFunction[y][x] && i < data.length * 8) {
|
1016
|
+
this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
|
1017
|
+
i++;
|
1018
|
+
}
|
745
1019
|
}
|
1020
|
+
}
|
746
1021
|
}
|
747
|
-
|
1022
|
+
assert(i == data.length * 8);
|
748
1023
|
}
|
749
1024
|
// XORs the codeword modules in this QR Code with the given mask pattern.
|
750
1025
|
// The function modules must be marked and the codeword bits must be drawn
|
751
1026
|
// before masking. Due to the arithmetic of XOR, calling applyMask() with
|
752
1027
|
// the same mask value a second time will undo the mask. A final well-formed
|
753
1028
|
// QR Code needs exactly one (not zero, two, etc.) mask applied.
|
754
|
-
applyMask(
|
755
|
-
if (
|
1029
|
+
applyMask(mask) {
|
1030
|
+
if (mask < 0 || mask > 7)
|
756
1031
|
throw new RangeError("Mask value out of range");
|
757
|
-
for (let
|
758
|
-
for (let
|
759
|
-
let
|
760
|
-
switch (
|
1032
|
+
for (let y = 0; y < this.size; y++) {
|
1033
|
+
for (let x = 0; x < this.size; x++) {
|
1034
|
+
let invert;
|
1035
|
+
switch (mask) {
|
761
1036
|
case 0:
|
762
|
-
|
1037
|
+
invert = (x + y) % 2 == 0;
|
763
1038
|
break;
|
764
1039
|
case 1:
|
765
|
-
|
1040
|
+
invert = y % 2 == 0;
|
766
1041
|
break;
|
767
1042
|
case 2:
|
768
|
-
|
1043
|
+
invert = x % 3 == 0;
|
769
1044
|
break;
|
770
1045
|
case 3:
|
771
|
-
|
1046
|
+
invert = (x + y) % 3 == 0;
|
772
1047
|
break;
|
773
1048
|
case 4:
|
774
|
-
|
1049
|
+
invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
|
775
1050
|
break;
|
776
1051
|
case 5:
|
777
|
-
|
1052
|
+
invert = x * y % 2 + x * y % 3 == 0;
|
778
1053
|
break;
|
779
1054
|
case 6:
|
780
|
-
|
1055
|
+
invert = (x * y % 2 + x * y % 3) % 2 == 0;
|
781
1056
|
break;
|
782
1057
|
case 7:
|
783
|
-
|
1058
|
+
invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
|
784
1059
|
break;
|
785
1060
|
default:
|
786
1061
|
throw new Error("Unreachable");
|
787
1062
|
}
|
788
|
-
!this.isFunction[
|
1063
|
+
if (!this.isFunction[y][x] && invert)
|
1064
|
+
this.modules[y][x] = !this.modules[y][x];
|
789
1065
|
}
|
1066
|
+
}
|
790
1067
|
}
|
791
1068
|
// Calculates and returns the penalty score based on state of this QR Code's current modules.
|
792
1069
|
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
|
793
1070
|
getPenaltyScore() {
|
794
|
-
let
|
795
|
-
for (let
|
796
|
-
let
|
797
|
-
|
798
|
-
|
799
|
-
|
1071
|
+
let result = 0;
|
1072
|
+
for (let y = 0; y < this.size; y++) {
|
1073
|
+
let runColor = false;
|
1074
|
+
let runX = 0;
|
1075
|
+
let runHistory = [0, 0, 0, 0, 0, 0, 0];
|
1076
|
+
for (let x = 0; x < this.size; x++) {
|
1077
|
+
if (this.modules[y][x] == runColor) {
|
1078
|
+
runX++;
|
1079
|
+
if (runX == 5)
|
1080
|
+
result += _QrCode2.PENALTY_N1;
|
1081
|
+
else if (runX > 5)
|
1082
|
+
result++;
|
1083
|
+
} else {
|
1084
|
+
this.finderPenaltyAddHistory(runX, runHistory);
|
1085
|
+
if (!runColor)
|
1086
|
+
result += this.finderPenaltyCountPatterns(runHistory) * _QrCode2.PENALTY_N3;
|
1087
|
+
runColor = this.modules[y][x];
|
1088
|
+
runX = 1;
|
1089
|
+
}
|
1090
|
+
}
|
1091
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * _QrCode2.PENALTY_N3;
|
800
1092
|
}
|
801
|
-
for (let
|
802
|
-
let
|
803
|
-
|
804
|
-
|
805
|
-
|
1093
|
+
for (let x = 0; x < this.size; x++) {
|
1094
|
+
let runColor = false;
|
1095
|
+
let runY = 0;
|
1096
|
+
let runHistory = [0, 0, 0, 0, 0, 0, 0];
|
1097
|
+
for (let y = 0; y < this.size; y++) {
|
1098
|
+
if (this.modules[y][x] == runColor) {
|
1099
|
+
runY++;
|
1100
|
+
if (runY == 5)
|
1101
|
+
result += _QrCode2.PENALTY_N1;
|
1102
|
+
else if (runY > 5)
|
1103
|
+
result++;
|
1104
|
+
} else {
|
1105
|
+
this.finderPenaltyAddHistory(runY, runHistory);
|
1106
|
+
if (!runColor)
|
1107
|
+
result += this.finderPenaltyCountPatterns(runHistory) * _QrCode2.PENALTY_N3;
|
1108
|
+
runColor = this.modules[y][x];
|
1109
|
+
runY = 1;
|
1110
|
+
}
|
1111
|
+
}
|
1112
|
+
result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * _QrCode2.PENALTY_N3;
|
806
1113
|
}
|
807
|
-
for (let
|
808
|
-
for (let
|
809
|
-
const
|
810
|
-
|
1114
|
+
for (let y = 0; y < this.size - 1; y++) {
|
1115
|
+
for (let x = 0; x < this.size - 1; x++) {
|
1116
|
+
const color = this.modules[y][x];
|
1117
|
+
if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1])
|
1118
|
+
result += _QrCode2.PENALTY_N2;
|
811
1119
|
}
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
1120
|
+
}
|
1121
|
+
let dark = 0;
|
1122
|
+
for (const row of this.modules)
|
1123
|
+
dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);
|
1124
|
+
const total = this.size * this.size;
|
1125
|
+
const k2 = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;
|
1126
|
+
assert(0 <= k2 && k2 <= 9);
|
1127
|
+
result += k2 * _QrCode2.PENALTY_N4;
|
1128
|
+
assert(0 <= result && result <= 2568888);
|
1129
|
+
return result;
|
817
1130
|
}
|
818
1131
|
/*-- Private helper functions --*/
|
819
1132
|
// Returns an ascending list of positions of alignment patterns for this version number.
|
@@ -822,87 +1135,113 @@ var K;
|
|
822
1135
|
getAlignmentPatternPositions() {
|
823
1136
|
if (this.version == 1)
|
824
1137
|
return [];
|
825
|
-
{
|
826
|
-
const
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
1138
|
+
else {
|
1139
|
+
const numAlign = Math.floor(this.version / 7) + 2;
|
1140
|
+
const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
|
1141
|
+
let result = [6];
|
1142
|
+
for (let pos = this.size - 7; result.length < numAlign; pos -= step)
|
1143
|
+
result.splice(1, 0, pos);
|
1144
|
+
return result;
|
831
1145
|
}
|
832
1146
|
}
|
833
1147
|
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
|
834
1148
|
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
|
835
1149
|
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
|
836
|
-
static getNumRawDataModules(
|
837
|
-
if (
|
1150
|
+
static getNumRawDataModules(ver) {
|
1151
|
+
if (ver < _QrCode2.MIN_VERSION || ver > _QrCode2.MAX_VERSION)
|
838
1152
|
throw new RangeError("Version number out of range");
|
839
|
-
let
|
840
|
-
if (
|
841
|
-
const
|
842
|
-
|
1153
|
+
let result = (16 * ver + 128) * ver + 64;
|
1154
|
+
if (ver >= 2) {
|
1155
|
+
const numAlign = Math.floor(ver / 7) + 2;
|
1156
|
+
result -= (25 * numAlign - 10) * numAlign - 55;
|
1157
|
+
if (ver >= 7)
|
1158
|
+
result -= 36;
|
843
1159
|
}
|
844
|
-
|
1160
|
+
assert(208 <= result && result <= 29648);
|
1161
|
+
return result;
|
845
1162
|
}
|
846
1163
|
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
|
847
1164
|
// QR Code of the given version number and error correction level, with remainder bits discarded.
|
848
1165
|
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
|
849
|
-
static getNumDataCodewords(
|
850
|
-
return Math.floor(
|
1166
|
+
static getNumDataCodewords(ver, ecl) {
|
1167
|
+
return Math.floor(_QrCode2.getNumRawDataModules(ver) / 8) - _QrCode2.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * _QrCode2.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
851
1168
|
}
|
852
1169
|
// Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
|
853
1170
|
// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
|
854
|
-
static reedSolomonComputeDivisor(
|
855
|
-
if (
|
1171
|
+
static reedSolomonComputeDivisor(degree) {
|
1172
|
+
if (degree < 1 || degree > 255)
|
856
1173
|
throw new RangeError("Degree out of range");
|
857
|
-
let
|
858
|
-
for (let i = 0; i <
|
859
|
-
|
860
|
-
|
861
|
-
let
|
862
|
-
for (let i = 0; i <
|
863
|
-
for (let
|
864
|
-
|
865
|
-
|
1174
|
+
let result = [];
|
1175
|
+
for (let i = 0; i < degree - 1; i++)
|
1176
|
+
result.push(0);
|
1177
|
+
result.push(1);
|
1178
|
+
let root = 1;
|
1179
|
+
for (let i = 0; i < degree; i++) {
|
1180
|
+
for (let j = 0; j < result.length; j++) {
|
1181
|
+
result[j] = _QrCode2.reedSolomonMultiply(result[j], root);
|
1182
|
+
if (j + 1 < result.length)
|
1183
|
+
result[j] ^= result[j + 1];
|
1184
|
+
}
|
1185
|
+
root = _QrCode2.reedSolomonMultiply(root, 2);
|
866
1186
|
}
|
867
|
-
return
|
1187
|
+
return result;
|
868
1188
|
}
|
869
1189
|
// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
|
870
|
-
static reedSolomonComputeRemainder(
|
871
|
-
let
|
872
|
-
for (const
|
873
|
-
const
|
874
|
-
|
1190
|
+
static reedSolomonComputeRemainder(data, divisor) {
|
1191
|
+
let result = divisor.map((_) => 0);
|
1192
|
+
for (const b of data) {
|
1193
|
+
const factor = b ^ result.shift();
|
1194
|
+
result.push(0);
|
1195
|
+
divisor.forEach((coef, i) => result[i] ^= _QrCode2.reedSolomonMultiply(coef, factor));
|
875
1196
|
}
|
876
|
-
return
|
1197
|
+
return result;
|
877
1198
|
}
|
878
1199
|
// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
|
879
1200
|
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
|
880
|
-
static reedSolomonMultiply(
|
881
|
-
if (
|
1201
|
+
static reedSolomonMultiply(x, y) {
|
1202
|
+
if (x >>> 8 != 0 || y >>> 8 != 0)
|
882
1203
|
throw new RangeError("Byte out of range");
|
883
|
-
let
|
884
|
-
for (let i = 7; i >= 0; i--)
|
885
|
-
|
886
|
-
|
1204
|
+
let z = 0;
|
1205
|
+
for (let i = 7; i >= 0; i--) {
|
1206
|
+
z = z << 1 ^ (z >>> 7) * 285;
|
1207
|
+
z ^= (y >>> i & 1) * x;
|
1208
|
+
}
|
1209
|
+
assert(z >>> 8 == 0);
|
1210
|
+
return z;
|
887
1211
|
}
|
888
1212
|
// Can only be called immediately after a light run is added, and
|
889
1213
|
// returns either 0, 1, or 2. A helper function for getPenaltyScore().
|
890
|
-
finderPenaltyCountPatterns(
|
891
|
-
const
|
892
|
-
|
893
|
-
const
|
894
|
-
return (
|
1214
|
+
finderPenaltyCountPatterns(runHistory) {
|
1215
|
+
const n2 = runHistory[1];
|
1216
|
+
assert(n2 <= this.size * 3);
|
1217
|
+
const core = n2 > 0 && runHistory[2] == n2 && runHistory[3] == n2 * 3 && runHistory[4] == n2 && runHistory[5] == n2;
|
1218
|
+
return (core && runHistory[0] >= n2 * 4 && runHistory[6] >= n2 ? 1 : 0) + (core && runHistory[6] >= n2 * 4 && runHistory[0] >= n2 ? 1 : 0);
|
895
1219
|
}
|
896
1220
|
// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
|
897
|
-
finderPenaltyTerminateAndCount(
|
898
|
-
|
1221
|
+
finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {
|
1222
|
+
if (currentRunColor) {
|
1223
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
1224
|
+
currentRunLength = 0;
|
1225
|
+
}
|
1226
|
+
currentRunLength += this.size;
|
1227
|
+
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
1228
|
+
return this.finderPenaltyCountPatterns(runHistory);
|
899
1229
|
}
|
900
1230
|
// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
|
901
|
-
finderPenaltyAddHistory(
|
902
|
-
|
1231
|
+
finderPenaltyAddHistory(currentRunLength, runHistory) {
|
1232
|
+
if (runHistory[0] == 0)
|
1233
|
+
currentRunLength += this.size;
|
1234
|
+
runHistory.pop();
|
1235
|
+
runHistory.unshift(currentRunLength);
|
903
1236
|
}
|
904
1237
|
};
|
905
|
-
|
1238
|
+
_QrCode.MIN_VERSION = 1;
|
1239
|
+
_QrCode.MAX_VERSION = 40;
|
1240
|
+
_QrCode.PENALTY_N1 = 3;
|
1241
|
+
_QrCode.PENALTY_N2 = 3;
|
1242
|
+
_QrCode.PENALTY_N3 = 40;
|
1243
|
+
_QrCode.PENALTY_N4 = 10;
|
1244
|
+
_QrCode.ECC_CODEWORDS_PER_BLOCK = [
|
906
1245
|
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
907
1246
|
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
908
1247
|
[-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
|
@@ -913,7 +1252,8 @@ var K;
|
|
913
1252
|
// Quartile
|
914
1253
|
[-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
|
915
1254
|
// High
|
916
|
-
]
|
1255
|
+
];
|
1256
|
+
_QrCode.NUM_ERROR_CORRECTION_BLOCKS = [
|
917
1257
|
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
918
1258
|
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
919
1259
|
[-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],
|
@@ -924,95 +1264,113 @@ var K;
|
|
924
1264
|
// Quartile
|
925
1265
|
[-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]
|
926
1266
|
// High
|
927
|
-
]
|
928
|
-
|
929
|
-
|
1267
|
+
];
|
1268
|
+
qrcodegen2.QrCode = _QrCode;
|
1269
|
+
function appendBits(val, len, bb) {
|
1270
|
+
if (len < 0 || len > 31 || val >>> len != 0)
|
930
1271
|
throw new RangeError("Value out of range");
|
931
|
-
for (let
|
932
|
-
|
1272
|
+
for (let i = len - 1; i >= 0; i--)
|
1273
|
+
bb.push(val >>> i & 1);
|
933
1274
|
}
|
934
|
-
function
|
935
|
-
return (
|
1275
|
+
function getBit(x, i) {
|
1276
|
+
return (x >>> i & 1) != 0;
|
936
1277
|
}
|
937
|
-
function
|
938
|
-
if (!
|
1278
|
+
function assert(cond) {
|
1279
|
+
if (!cond)
|
939
1280
|
throw new Error("Assertion error");
|
940
1281
|
}
|
941
|
-
const
|
1282
|
+
const _QrSegment = class _QrSegment2 {
|
942
1283
|
/*-- Constructor (low level) and fields --*/
|
943
1284
|
// Creates a new QR Code segment with the given attributes and data.
|
944
1285
|
// The character count (numChars) must agree with the mode and the bit buffer length,
|
945
1286
|
// but the constraint isn't checked. The given bit buffer is cloned and stored.
|
946
|
-
constructor(
|
947
|
-
|
1287
|
+
constructor(mode, numChars, bitData) {
|
1288
|
+
this.mode = mode;
|
1289
|
+
this.numChars = numChars;
|
1290
|
+
this.bitData = bitData;
|
1291
|
+
if (numChars < 0)
|
948
1292
|
throw new RangeError("Invalid argument");
|
949
|
-
this.bitData =
|
1293
|
+
this.bitData = bitData.slice();
|
950
1294
|
}
|
951
1295
|
/*-- Static factory functions (mid level) --*/
|
952
1296
|
// Returns a segment representing the given binary data encoded in
|
953
1297
|
// byte mode. All input byte arrays are acceptable. Any text string
|
954
1298
|
// can be converted to UTF-8 bytes and encoded as a byte mode segment.
|
955
|
-
static makeBytes(
|
956
|
-
let
|
957
|
-
for (const
|
958
|
-
|
959
|
-
return new
|
1299
|
+
static makeBytes(data) {
|
1300
|
+
let bb = [];
|
1301
|
+
for (const b of data)
|
1302
|
+
appendBits(b, 8, bb);
|
1303
|
+
return new _QrSegment2(_QrSegment2.Mode.BYTE, data.length, bb);
|
960
1304
|
}
|
961
1305
|
// Returns a segment representing the given string of decimal digits encoded in numeric mode.
|
962
|
-
static makeNumeric(
|
963
|
-
if (!
|
1306
|
+
static makeNumeric(digits) {
|
1307
|
+
if (!_QrSegment2.isNumeric(digits))
|
964
1308
|
throw new RangeError("String contains non-numeric characters");
|
965
|
-
let
|
966
|
-
for (let
|
967
|
-
const
|
968
|
-
|
1309
|
+
let bb = [];
|
1310
|
+
for (let i = 0; i < digits.length; ) {
|
1311
|
+
const n2 = Math.min(digits.length - i, 3);
|
1312
|
+
appendBits(parseInt(digits.substring(i, i + n2), 10), n2 * 3 + 1, bb);
|
1313
|
+
i += n2;
|
969
1314
|
}
|
970
|
-
return new
|
1315
|
+
return new _QrSegment2(_QrSegment2.Mode.NUMERIC, digits.length, bb);
|
971
1316
|
}
|
972
1317
|
// Returns a segment representing the given text string encoded in alphanumeric mode.
|
973
1318
|
// The characters allowed are: 0 to 9, A to Z (uppercase only), space,
|
974
1319
|
// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
975
|
-
static makeAlphanumeric(
|
976
|
-
if (!
|
1320
|
+
static makeAlphanumeric(text) {
|
1321
|
+
if (!_QrSegment2.isAlphanumeric(text))
|
977
1322
|
throw new RangeError("String contains unencodable characters in alphanumeric mode");
|
978
|
-
let
|
979
|
-
|
980
|
-
|
981
|
-
|
1323
|
+
let bb = [];
|
1324
|
+
let i;
|
1325
|
+
for (i = 0; i + 2 <= text.length; i += 2) {
|
1326
|
+
let temp = _QrSegment2.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
|
1327
|
+
temp += _QrSegment2.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
|
1328
|
+
appendBits(temp, 11, bb);
|
982
1329
|
}
|
983
|
-
|
1330
|
+
if (i < text.length)
|
1331
|
+
appendBits(_QrSegment2.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);
|
1332
|
+
return new _QrSegment2(_QrSegment2.Mode.ALPHANUMERIC, text.length, bb);
|
984
1333
|
}
|
985
1334
|
// Returns a new mutable list of zero or more segments to represent the given Unicode text string.
|
986
1335
|
// The result may use various segment modes and switch modes to optimize the length of the bit stream.
|
987
|
-
static makeSegments(
|
988
|
-
|
1336
|
+
static makeSegments(text) {
|
1337
|
+
if (text == "")
|
1338
|
+
return [];
|
1339
|
+
else if (_QrSegment2.isNumeric(text))
|
1340
|
+
return [_QrSegment2.makeNumeric(text)];
|
1341
|
+
else if (_QrSegment2.isAlphanumeric(text))
|
1342
|
+
return [_QrSegment2.makeAlphanumeric(text)];
|
1343
|
+
else
|
1344
|
+
return [_QrSegment2.makeBytes(_QrSegment2.toUtf8ByteArray(text))];
|
989
1345
|
}
|
990
1346
|
// Returns a segment representing an Extended Channel Interpretation
|
991
1347
|
// (ECI) designator with the given assignment value.
|
992
|
-
static makeEci(
|
993
|
-
let
|
994
|
-
if (
|
1348
|
+
static makeEci(assignVal) {
|
1349
|
+
let bb = [];
|
1350
|
+
if (assignVal < 0)
|
995
1351
|
throw new RangeError("ECI assignment value out of range");
|
996
|
-
if (
|
997
|
-
|
998
|
-
else if (
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1352
|
+
else if (assignVal < 1 << 7)
|
1353
|
+
appendBits(assignVal, 8, bb);
|
1354
|
+
else if (assignVal < 1 << 14) {
|
1355
|
+
appendBits(2, 2, bb);
|
1356
|
+
appendBits(assignVal, 14, bb);
|
1357
|
+
} else if (assignVal < 1e6) {
|
1358
|
+
appendBits(6, 3, bb);
|
1359
|
+
appendBits(assignVal, 21, bb);
|
1360
|
+
} else
|
1003
1361
|
throw new RangeError("ECI assignment value out of range");
|
1004
|
-
return new
|
1362
|
+
return new _QrSegment2(_QrSegment2.Mode.ECI, 0, bb);
|
1005
1363
|
}
|
1006
1364
|
// Tests whether the given string can be encoded as a segment in numeric mode.
|
1007
1365
|
// A string is encodable iff each character is in the range 0 to 9.
|
1008
|
-
static isNumeric(
|
1009
|
-
return
|
1366
|
+
static isNumeric(text) {
|
1367
|
+
return _QrSegment2.NUMERIC_REGEX.test(text);
|
1010
1368
|
}
|
1011
1369
|
// Tests whether the given string can be encoded as a segment in alphanumeric mode.
|
1012
1370
|
// A string is encodable iff each character is in the following set: 0 to 9, A to Z
|
1013
1371
|
// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
1014
|
-
static isAlphanumeric(
|
1015
|
-
return
|
1372
|
+
static isAlphanumeric(text) {
|
1373
|
+
return _QrSegment2.ALPHANUMERIC_REGEX.test(text);
|
1016
1374
|
}
|
1017
1375
|
/*-- Methods --*/
|
1018
1376
|
// Returns a new copy of the data bits of this segment.
|
@@ -1021,176 +1379,244 @@ var K;
|
|
1021
1379
|
}
|
1022
1380
|
// (Package-private) Calculates and returns the number of bits needed to encode the given segments at
|
1023
1381
|
// the given version. The result is infinity if a segment has too many characters to fit its length field.
|
1024
|
-
static getTotalBits(
|
1025
|
-
let
|
1026
|
-
for (const
|
1027
|
-
const
|
1028
|
-
if (
|
1029
|
-
return
|
1030
|
-
|
1382
|
+
static getTotalBits(segs, version) {
|
1383
|
+
let result = 0;
|
1384
|
+
for (const seg of segs) {
|
1385
|
+
const ccbits = seg.mode.numCharCountBits(version);
|
1386
|
+
if (seg.numChars >= 1 << ccbits)
|
1387
|
+
return Infinity;
|
1388
|
+
result += 4 + ccbits + seg.bitData.length;
|
1031
1389
|
}
|
1032
|
-
return
|
1390
|
+
return result;
|
1033
1391
|
}
|
1034
1392
|
// Returns a new array of bytes representing the given string encoded in UTF-8.
|
1035
|
-
static toUtf8ByteArray(
|
1036
|
-
|
1037
|
-
let
|
1038
|
-
for (let
|
1039
|
-
|
1040
|
-
|
1393
|
+
static toUtf8ByteArray(str) {
|
1394
|
+
str = encodeURI(str);
|
1395
|
+
let result = [];
|
1396
|
+
for (let i = 0; i < str.length; i++) {
|
1397
|
+
if (str.charAt(i) != "%")
|
1398
|
+
result.push(str.charCodeAt(i));
|
1399
|
+
else {
|
1400
|
+
result.push(parseInt(str.substring(i + 1, i + 3), 16));
|
1401
|
+
i += 2;
|
1402
|
+
}
|
1403
|
+
}
|
1404
|
+
return result;
|
1041
1405
|
}
|
1042
1406
|
};
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1407
|
+
_QrSegment.NUMERIC_REGEX = /^[0-9]*$/;
|
1408
|
+
_QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/;
|
1409
|
+
_QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
1410
|
+
let QrSegment = _QrSegment;
|
1411
|
+
qrcodegen2.QrSegment = _QrSegment;
|
1412
|
+
})(qrcodegen || (qrcodegen = {}));
|
1413
|
+
((qrcodegen2) => {
|
1414
|
+
((QrCode2) => {
|
1415
|
+
const _Ecc = class _Ecc {
|
1050
1416
|
// The QR Code can tolerate about 30% erroneous codewords
|
1051
1417
|
/*-- Constructor and fields --*/
|
1052
|
-
constructor(
|
1053
|
-
this.ordinal =
|
1418
|
+
constructor(ordinal, formatBits) {
|
1419
|
+
this.ordinal = ordinal;
|
1420
|
+
this.formatBits = formatBits;
|
1054
1421
|
}
|
1055
1422
|
};
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
(
|
1060
|
-
|
1061
|
-
|
1423
|
+
_Ecc.LOW = new _Ecc(0, 1);
|
1424
|
+
_Ecc.MEDIUM = new _Ecc(1, 0);
|
1425
|
+
_Ecc.QUARTILE = new _Ecc(2, 3);
|
1426
|
+
_Ecc.HIGH = new _Ecc(3, 2);
|
1427
|
+
QrCode2.Ecc = _Ecc;
|
1428
|
+
})(qrcodegen2.QrCode || (qrcodegen2.QrCode = {}));
|
1429
|
+
})(qrcodegen || (qrcodegen = {}));
|
1430
|
+
((qrcodegen2) => {
|
1431
|
+
((QrSegment2) => {
|
1432
|
+
const _Mode = class _Mode {
|
1062
1433
|
/*-- Constructor and fields --*/
|
1063
|
-
constructor(
|
1064
|
-
this.modeBits =
|
1434
|
+
constructor(modeBits, numBitsCharCount) {
|
1435
|
+
this.modeBits = modeBits;
|
1436
|
+
this.numBitsCharCount = numBitsCharCount;
|
1065
1437
|
}
|
1066
1438
|
/*-- Method --*/
|
1067
1439
|
// (Package-private) Returns the bit width of the character count field for a segment in
|
1068
1440
|
// this mode in a QR Code at the given version number. The result is in the range [0, 16].
|
1069
|
-
numCharCountBits(
|
1070
|
-
return this.numBitsCharCount[Math.floor((
|
1441
|
+
numCharCountBits(ver) {
|
1442
|
+
return this.numBitsCharCount[Math.floor((ver + 7) / 17)];
|
1071
1443
|
}
|
1072
1444
|
};
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1445
|
+
_Mode.NUMERIC = new _Mode(1, [10, 12, 14]);
|
1446
|
+
_Mode.ALPHANUMERIC = new _Mode(2, [9, 11, 13]);
|
1447
|
+
_Mode.BYTE = new _Mode(4, [8, 16, 16]);
|
1448
|
+
_Mode.KANJI = new _Mode(8, [8, 10, 12]);
|
1449
|
+
_Mode.ECI = new _Mode(7, [0, 0, 0]);
|
1450
|
+
QrSegment2.Mode = _Mode;
|
1451
|
+
})(qrcodegen2.QrSegment || (qrcodegen2.QrSegment = {}));
|
1452
|
+
})(qrcodegen || (qrcodegen = {}));
|
1453
|
+
var qrcodegen_default = qrcodegen;
|
1077
1454
|
/**
|
1078
1455
|
* @license qrcode.react
|
1079
1456
|
* Copyright (c) Paul O'Shannessy
|
1080
1457
|
* SPDX-License-Identifier: ISC
|
1081
1458
|
*/
|
1082
|
-
var
|
1083
|
-
L:
|
1084
|
-
M:
|
1085
|
-
Q:
|
1086
|
-
H:
|
1087
|
-
}
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1459
|
+
var ERROR_LEVEL_MAP = {
|
1460
|
+
L: qrcodegen_default.QrCode.Ecc.LOW,
|
1461
|
+
M: qrcodegen_default.QrCode.Ecc.MEDIUM,
|
1462
|
+
Q: qrcodegen_default.QrCode.Ecc.QUARTILE,
|
1463
|
+
H: qrcodegen_default.QrCode.Ecc.HIGH
|
1464
|
+
};
|
1465
|
+
var DEFAULT_SIZE = 128;
|
1466
|
+
var DEFAULT_LEVEL = "L";
|
1467
|
+
var DEFAULT_BGCOLOR = "#FFFFFF";
|
1468
|
+
var DEFAULT_FGCOLOR = "#000000";
|
1469
|
+
var DEFAULT_INCLUDEMARGIN = false;
|
1470
|
+
var DEFAULT_MINVERSION = 1;
|
1471
|
+
var SPEC_MARGIN_SIZE = 4;
|
1472
|
+
var DEFAULT_MARGIN_SIZE = 0;
|
1473
|
+
var DEFAULT_IMG_SCALE = 0.1;
|
1474
|
+
function generatePath(modules, margin = 0) {
|
1475
|
+
const ops = [];
|
1476
|
+
modules.forEach(function(row, y) {
|
1477
|
+
let start = null;
|
1478
|
+
row.forEach(function(cell, x) {
|
1479
|
+
if (!cell && start !== null) {
|
1480
|
+
ops.push(
|
1481
|
+
`M${start + margin} ${y + margin}h${x - start}v1H${start + margin}z`
|
1482
|
+
);
|
1483
|
+
start = null;
|
1097
1484
|
return;
|
1098
1485
|
}
|
1099
|
-
if (
|
1100
|
-
if (!
|
1486
|
+
if (x === row.length - 1) {
|
1487
|
+
if (!cell) {
|
1101
1488
|
return;
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1489
|
+
}
|
1490
|
+
if (start === null) {
|
1491
|
+
ops.push(`M${x + margin},${y + margin} h1v1H${x + margin}z`);
|
1492
|
+
} else {
|
1493
|
+
ops.push(
|
1494
|
+
`M${start + margin},${y + margin} h${x + 1 - start}v1H${start + margin}z`
|
1495
|
+
);
|
1496
|
+
}
|
1105
1497
|
return;
|
1106
1498
|
}
|
1107
|
-
|
1499
|
+
if (cell && start === null) {
|
1500
|
+
start = x;
|
1501
|
+
}
|
1108
1502
|
});
|
1109
|
-
})
|
1503
|
+
});
|
1504
|
+
return ops.join("");
|
1110
1505
|
}
|
1111
|
-
function
|
1112
|
-
return
|
1506
|
+
function excavateModules(modules, excavation) {
|
1507
|
+
return modules.slice().map((row, y) => {
|
1508
|
+
if (y < excavation.y || y >= excavation.y + excavation.h) {
|
1509
|
+
return row;
|
1510
|
+
}
|
1511
|
+
return row.map((cell, x) => {
|
1512
|
+
if (x < excavation.x || x >= excavation.x + excavation.w) {
|
1513
|
+
return cell;
|
1514
|
+
}
|
1515
|
+
return false;
|
1516
|
+
});
|
1517
|
+
});
|
1113
1518
|
}
|
1114
|
-
function
|
1115
|
-
if (
|
1519
|
+
function getImageSettings(cells, size, margin, imageSettings) {
|
1520
|
+
if (imageSettings == null) {
|
1116
1521
|
return null;
|
1117
|
-
const u = s.length + t * 2, h = Math.floor(r * Tt), y = u / r, w = (c.width || h) * y, e = (c.height || h) * y, n = c.x == null ? s.length / 2 - w / 2 : c.x * y, o = c.y == null ? s.length / 2 - e / 2 : c.y * y, i = c.opacity == null ? 1 : c.opacity;
|
1118
|
-
let l = null;
|
1119
|
-
if (c.excavate) {
|
1120
|
-
let d = Math.floor(n), m = Math.floor(o), g = Math.ceil(w + n - d), b = Math.ceil(e + o - m);
|
1121
|
-
l = { x: d, y: m, w: g, h: b };
|
1122
1522
|
}
|
1123
|
-
const
|
1124
|
-
|
1523
|
+
const numCells = cells.length + margin * 2;
|
1524
|
+
const defaultSize = Math.floor(size * DEFAULT_IMG_SCALE);
|
1525
|
+
const scale = numCells / size;
|
1526
|
+
const w = (imageSettings.width || defaultSize) * scale;
|
1527
|
+
const h = (imageSettings.height || defaultSize) * scale;
|
1528
|
+
const x = imageSettings.x == null ? cells.length / 2 - w / 2 : imageSettings.x * scale;
|
1529
|
+
const y = imageSettings.y == null ? cells.length / 2 - h / 2 : imageSettings.y * scale;
|
1530
|
+
const opacity = imageSettings.opacity == null ? 1 : imageSettings.opacity;
|
1531
|
+
let excavation = null;
|
1532
|
+
if (imageSettings.excavate) {
|
1533
|
+
let floorX = Math.floor(x);
|
1534
|
+
let floorY = Math.floor(y);
|
1535
|
+
let ceilW = Math.ceil(w + x - floorX);
|
1536
|
+
let ceilH = Math.ceil(h + y - floorY);
|
1537
|
+
excavation = { x: floorX, y: floorY, w: ceilW, h: ceilH };
|
1538
|
+
}
|
1539
|
+
const crossOrigin = imageSettings.crossOrigin;
|
1540
|
+
return { x, y, h, w, excavation, opacity, crossOrigin };
|
1125
1541
|
}
|
1126
|
-
function
|
1127
|
-
|
1542
|
+
function getMarginSize(includeMargin, marginSize) {
|
1543
|
+
if (marginSize != null) {
|
1544
|
+
return Math.max(Math.floor(marginSize), 0);
|
1545
|
+
}
|
1546
|
+
return includeMargin ? SPEC_MARGIN_SIZE : DEFAULT_MARGIN_SIZE;
|
1128
1547
|
}
|
1129
|
-
function
|
1130
|
-
value
|
1131
|
-
level
|
1132
|
-
minVersion
|
1133
|
-
includeMargin
|
1134
|
-
marginSize
|
1135
|
-
imageSettings
|
1136
|
-
size
|
1137
|
-
boostLevel
|
1548
|
+
function useQRCode({
|
1549
|
+
value,
|
1550
|
+
level,
|
1551
|
+
minVersion,
|
1552
|
+
includeMargin,
|
1553
|
+
marginSize,
|
1554
|
+
imageSettings,
|
1555
|
+
size,
|
1556
|
+
boostLevel
|
1138
1557
|
}) {
|
1139
|
-
let
|
1140
|
-
const
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1558
|
+
let qrcode = React.useMemo(() => {
|
1559
|
+
const values = Array.isArray(value) ? value : [value];
|
1560
|
+
const segments = values.reduce((accum, v) => {
|
1561
|
+
accum.push(...qrcodegen_default.QrSegment.makeSegments(v));
|
1562
|
+
return accum;
|
1563
|
+
}, []);
|
1564
|
+
return qrcodegen_default.QrCode.encodeSegments(
|
1565
|
+
segments,
|
1566
|
+
ERROR_LEVEL_MAP[level],
|
1567
|
+
minVersion,
|
1145
1568
|
void 0,
|
1146
1569
|
void 0,
|
1147
|
-
|
1570
|
+
boostLevel
|
1148
1571
|
);
|
1149
|
-
}, [
|
1150
|
-
const { cells
|
1151
|
-
let
|
1152
|
-
const
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1572
|
+
}, [value, level, minVersion, boostLevel]);
|
1573
|
+
const { cells, margin, numCells, calculatedImageSettings } = React.useMemo(() => {
|
1574
|
+
let cells2 = qrcode.getModules();
|
1575
|
+
const margin2 = getMarginSize(includeMargin, marginSize);
|
1576
|
+
const numCells2 = cells2.length + margin2 * 2;
|
1577
|
+
const calculatedImageSettings2 = getImageSettings(
|
1578
|
+
cells2,
|
1579
|
+
size,
|
1580
|
+
margin2,
|
1581
|
+
imageSettings
|
1157
1582
|
);
|
1158
1583
|
return {
|
1159
|
-
cells:
|
1160
|
-
margin:
|
1161
|
-
numCells:
|
1162
|
-
calculatedImageSettings:
|
1584
|
+
cells: cells2,
|
1585
|
+
margin: margin2,
|
1586
|
+
numCells: numCells2,
|
1587
|
+
calculatedImageSettings: calculatedImageSettings2
|
1163
1588
|
};
|
1164
|
-
}, [
|
1589
|
+
}, [qrcode, size, imageSettings, includeMargin, marginSize]);
|
1165
1590
|
return {
|
1166
|
-
qrcode
|
1167
|
-
margin
|
1168
|
-
cells
|
1169
|
-
numCells
|
1170
|
-
calculatedImageSettings
|
1591
|
+
qrcode,
|
1592
|
+
margin,
|
1593
|
+
cells,
|
1594
|
+
numCells,
|
1595
|
+
calculatedImageSettings
|
1171
1596
|
};
|
1172
1597
|
}
|
1173
|
-
var
|
1598
|
+
var SUPPORTS_PATH2D = function() {
|
1174
1599
|
try {
|
1175
1600
|
new Path2D().addPath(new Path2D());
|
1176
|
-
} catch (
|
1177
|
-
return
|
1601
|
+
} catch (e) {
|
1602
|
+
return false;
|
1178
1603
|
}
|
1179
|
-
return
|
1180
|
-
}()
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1604
|
+
return true;
|
1605
|
+
}();
|
1606
|
+
var QRCodeCanvas = React.forwardRef(
|
1607
|
+
function QRCodeCanvas2(props, forwardedRef) {
|
1608
|
+
const _a = props, {
|
1609
|
+
value,
|
1610
|
+
size = DEFAULT_SIZE,
|
1611
|
+
level = DEFAULT_LEVEL,
|
1612
|
+
bgColor = DEFAULT_BGCOLOR,
|
1613
|
+
fgColor = DEFAULT_FGCOLOR,
|
1614
|
+
includeMargin = DEFAULT_INCLUDEMARGIN,
|
1615
|
+
minVersion = DEFAULT_MINVERSION,
|
1616
|
+
boostLevel,
|
1617
|
+
marginSize,
|
1618
|
+
imageSettings
|
1619
|
+
} = _a, extraProps = __objRest(_a, [
|
1194
1620
|
"value",
|
1195
1621
|
"size",
|
1196
1622
|
"level",
|
@@ -1201,92 +1627,131 @@ var Mt = function() {
|
|
1201
1627
|
"boostLevel",
|
1202
1628
|
"marginSize",
|
1203
1629
|
"imageSettings"
|
1204
|
-
])
|
1205
|
-
|
1206
|
-
|
1630
|
+
]);
|
1631
|
+
const _b = extraProps, { style } = _b, otherProps = __objRest(_b, ["style"]);
|
1632
|
+
const imgSrc = imageSettings == null ? void 0 : imageSettings.src;
|
1633
|
+
const _canvas = React.useRef(null);
|
1634
|
+
const _image = React.useRef(null);
|
1635
|
+
const setCanvasRef = React.useCallback(
|
1636
|
+
(node) => {
|
1637
|
+
_canvas.current = node;
|
1638
|
+
if (typeof forwardedRef === "function") {
|
1639
|
+
forwardedRef(node);
|
1640
|
+
} else if (forwardedRef) {
|
1641
|
+
forwardedRef.current = node;
|
1642
|
+
}
|
1207
1643
|
},
|
1208
|
-
[
|
1209
|
-
)
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1644
|
+
[forwardedRef]
|
1645
|
+
);
|
1646
|
+
const [isImgLoaded, setIsImageLoaded] = React.useState(false);
|
1647
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
1648
|
+
value,
|
1649
|
+
level,
|
1650
|
+
minVersion,
|
1651
|
+
boostLevel,
|
1652
|
+
includeMargin,
|
1653
|
+
marginSize,
|
1654
|
+
imageSettings,
|
1655
|
+
size
|
1218
1656
|
});
|
1219
|
-
|
1220
|
-
if (
|
1221
|
-
const
|
1222
|
-
|
1657
|
+
React.useEffect(() => {
|
1658
|
+
if (_canvas.current != null) {
|
1659
|
+
const canvas = _canvas.current;
|
1660
|
+
const ctx = canvas.getContext("2d");
|
1661
|
+
if (!ctx) {
|
1223
1662
|
return;
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1663
|
+
}
|
1664
|
+
let cellsToDraw = cells;
|
1665
|
+
const image = _image.current;
|
1666
|
+
const haveImageToRender = calculatedImageSettings != null && image !== null && image.complete && image.naturalHeight !== 0 && image.naturalWidth !== 0;
|
1667
|
+
if (haveImageToRender) {
|
1668
|
+
if (calculatedImageSettings.excavation != null) {
|
1669
|
+
cellsToDraw = excavateModules(
|
1670
|
+
cells,
|
1671
|
+
calculatedImageSettings.excavation
|
1672
|
+
);
|
1673
|
+
}
|
1674
|
+
}
|
1675
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
1676
|
+
canvas.height = canvas.width = size * pixelRatio;
|
1677
|
+
const scale = size / numCells * pixelRatio;
|
1678
|
+
ctx.scale(scale, scale);
|
1679
|
+
ctx.fillStyle = bgColor;
|
1680
|
+
ctx.fillRect(0, 0, numCells, numCells);
|
1681
|
+
ctx.fillStyle = fgColor;
|
1682
|
+
if (SUPPORTS_PATH2D) {
|
1683
|
+
ctx.fill(new Path2D(generatePath(cellsToDraw, margin)));
|
1684
|
+
} else {
|
1685
|
+
cells.forEach(function(row, rdx) {
|
1686
|
+
row.forEach(function(cell, cdx) {
|
1687
|
+
if (cell) {
|
1688
|
+
ctx.fillRect(cdx + margin, rdx + margin, 1, 1);
|
1689
|
+
}
|
1690
|
+
});
|
1236
1691
|
});
|
1237
|
-
}
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
return v != null && (ee = /* @__PURE__ */ S.createElement(
|
1251
|
-
"img",
|
1252
|
-
{
|
1253
|
-
src: v,
|
1254
|
-
key: v,
|
1255
|
-
style: { display: "none" },
|
1256
|
-
onLoad: () => {
|
1257
|
-
V(!0);
|
1258
|
-
},
|
1259
|
-
ref: j,
|
1260
|
-
crossOrigin: I == null ? void 0 : I.crossOrigin
|
1692
|
+
}
|
1693
|
+
if (calculatedImageSettings) {
|
1694
|
+
ctx.globalAlpha = calculatedImageSettings.opacity;
|
1695
|
+
}
|
1696
|
+
if (haveImageToRender) {
|
1697
|
+
ctx.drawImage(
|
1698
|
+
image,
|
1699
|
+
calculatedImageSettings.x + margin,
|
1700
|
+
calculatedImageSettings.y + margin,
|
1701
|
+
calculatedImageSettings.w,
|
1702
|
+
calculatedImageSettings.h
|
1703
|
+
);
|
1704
|
+
}
|
1261
1705
|
}
|
1262
|
-
)
|
1706
|
+
});
|
1707
|
+
React.useEffect(() => {
|
1708
|
+
setIsImageLoaded(false);
|
1709
|
+
}, [imgSrc]);
|
1710
|
+
const canvasStyle = __spreadValues2({ height: size, width: size }, style);
|
1711
|
+
let img = null;
|
1712
|
+
if (imgSrc != null) {
|
1713
|
+
img = /* @__PURE__ */ React.createElement(
|
1714
|
+
"img",
|
1715
|
+
{
|
1716
|
+
src: imgSrc,
|
1717
|
+
key: imgSrc,
|
1718
|
+
style: { display: "none" },
|
1719
|
+
onLoad: () => {
|
1720
|
+
setIsImageLoaded(true);
|
1721
|
+
},
|
1722
|
+
ref: _image,
|
1723
|
+
crossOrigin: calculatedImageSettings == null ? void 0 : calculatedImageSettings.crossOrigin
|
1724
|
+
}
|
1725
|
+
);
|
1726
|
+
}
|
1727
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
1263
1728
|
"canvas",
|
1264
|
-
|
1265
|
-
style:
|
1266
|
-
height:
|
1267
|
-
width:
|
1268
|
-
ref:
|
1729
|
+
__spreadValues2({
|
1730
|
+
style: canvasStyle,
|
1731
|
+
height: size,
|
1732
|
+
width: size,
|
1733
|
+
ref: setCanvasRef,
|
1269
1734
|
role: "img"
|
1270
|
-
},
|
1271
|
-
),
|
1735
|
+
}, otherProps)
|
1736
|
+
), img);
|
1272
1737
|
}
|
1273
1738
|
);
|
1274
|
-
|
1275
|
-
var
|
1276
|
-
function(
|
1277
|
-
const
|
1278
|
-
value
|
1279
|
-
size
|
1280
|
-
level
|
1281
|
-
bgColor
|
1282
|
-
fgColor
|
1283
|
-
includeMargin
|
1284
|
-
minVersion
|
1285
|
-
boostLevel
|
1286
|
-
title
|
1287
|
-
marginSize
|
1288
|
-
imageSettings
|
1289
|
-
} =
|
1739
|
+
QRCodeCanvas.displayName = "QRCodeCanvas";
|
1740
|
+
var QRCodeSVG = React.forwardRef(
|
1741
|
+
function QRCodeSVG2(props, forwardedRef) {
|
1742
|
+
const _a = props, {
|
1743
|
+
value,
|
1744
|
+
size = DEFAULT_SIZE,
|
1745
|
+
level = DEFAULT_LEVEL,
|
1746
|
+
bgColor = DEFAULT_BGCOLOR,
|
1747
|
+
fgColor = DEFAULT_FGCOLOR,
|
1748
|
+
includeMargin = DEFAULT_INCLUDEMARGIN,
|
1749
|
+
minVersion = DEFAULT_MINVERSION,
|
1750
|
+
boostLevel,
|
1751
|
+
title,
|
1752
|
+
marginSize,
|
1753
|
+
imageSettings
|
1754
|
+
} = _a, otherProps = __objRest(_a, [
|
1290
1755
|
"value",
|
1291
1756
|
"size",
|
1292
1757
|
"level",
|
@@ -1298,126 +1763,266 @@ var Ie = S.forwardRef(
|
|
1298
1763
|
"title",
|
1299
1764
|
"marginSize",
|
1300
1765
|
"imageSettings"
|
1301
|
-
])
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1766
|
+
]);
|
1767
|
+
const { margin, cells, numCells, calculatedImageSettings } = useQRCode({
|
1768
|
+
value,
|
1769
|
+
level,
|
1770
|
+
minVersion,
|
1771
|
+
boostLevel,
|
1772
|
+
includeMargin,
|
1773
|
+
marginSize,
|
1774
|
+
imageSettings,
|
1775
|
+
size
|
1310
1776
|
});
|
1311
|
-
let
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
height: p.h,
|
1320
|
-
width: p.w,
|
1321
|
-
x: p.x + g,
|
1322
|
-
y: p.y + g,
|
1323
|
-
preserveAspectRatio: "none",
|
1324
|
-
opacity: p.opacity,
|
1325
|
-
crossOrigin: p.crossOrigin
|
1777
|
+
let cellsToDraw = cells;
|
1778
|
+
let image = null;
|
1779
|
+
if (imageSettings != null && calculatedImageSettings != null) {
|
1780
|
+
if (calculatedImageSettings.excavation != null) {
|
1781
|
+
cellsToDraw = excavateModules(
|
1782
|
+
cells,
|
1783
|
+
calculatedImageSettings.excavation
|
1784
|
+
);
|
1326
1785
|
}
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1786
|
+
image = /* @__PURE__ */ React.createElement(
|
1787
|
+
"image",
|
1788
|
+
{
|
1789
|
+
href: imageSettings.src,
|
1790
|
+
height: calculatedImageSettings.h,
|
1791
|
+
width: calculatedImageSettings.w,
|
1792
|
+
x: calculatedImageSettings.x + margin,
|
1793
|
+
y: calculatedImageSettings.y + margin,
|
1794
|
+
preserveAspectRatio: "none",
|
1795
|
+
opacity: calculatedImageSettings.opacity,
|
1796
|
+
crossOrigin: calculatedImageSettings.crossOrigin
|
1797
|
+
}
|
1798
|
+
);
|
1799
|
+
}
|
1800
|
+
const fgPath = generatePath(cellsToDraw, margin);
|
1801
|
+
return /* @__PURE__ */ React.createElement(
|
1330
1802
|
"svg",
|
1331
|
-
|
1332
|
-
height:
|
1333
|
-
width:
|
1334
|
-
viewBox: `0 0 ${
|
1335
|
-
ref:
|
1803
|
+
__spreadValues2({
|
1804
|
+
height: size,
|
1805
|
+
width: size,
|
1806
|
+
viewBox: `0 0 ${numCells} ${numCells}`,
|
1807
|
+
ref: forwardedRef,
|
1336
1808
|
role: "img"
|
1337
|
-
},
|
1338
|
-
!!
|
1339
|
-
/* @__PURE__ */
|
1809
|
+
}, otherProps),
|
1810
|
+
!!title && /* @__PURE__ */ React.createElement("title", null, title),
|
1811
|
+
/* @__PURE__ */ React.createElement(
|
1340
1812
|
"path",
|
1341
1813
|
{
|
1342
|
-
fill:
|
1343
|
-
d: `M0,0 h${
|
1814
|
+
fill: bgColor,
|
1815
|
+
d: `M0,0 h${numCells}v${numCells}H0z`,
|
1344
1816
|
shapeRendering: "crispEdges"
|
1345
1817
|
}
|
1346
1818
|
),
|
1347
|
-
/* @__PURE__ */
|
1348
|
-
|
1819
|
+
/* @__PURE__ */ React.createElement("path", { fill: fgColor, d: fgPath, shapeRendering: "crispEdges" }),
|
1820
|
+
image
|
1349
1821
|
);
|
1350
1822
|
}
|
1351
1823
|
);
|
1352
|
-
|
1353
|
-
const
|
1354
|
-
walletAddress
|
1355
|
-
amount
|
1356
|
-
currency
|
1357
|
-
|
1358
|
-
|
1824
|
+
QRCodeSVG.displayName = "QRCodeSVG";
|
1825
|
+
const QRCode = ({
|
1826
|
+
walletAddress,
|
1827
|
+
amount,
|
1828
|
+
currency,
|
1829
|
+
network,
|
1830
|
+
theme = "light",
|
1831
|
+
size = 200
|
1359
1832
|
}) => {
|
1360
|
-
const [
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1833
|
+
const [qrData, setQrData] = useState("");
|
1834
|
+
const [qrError, setQrError] = useState(null);
|
1835
|
+
useEffect(() => {
|
1836
|
+
if (!walletAddress || walletAddress === "No address configured") {
|
1837
|
+
setQrError("No wallet address configured for this network");
|
1364
1838
|
return;
|
1365
1839
|
}
|
1366
1840
|
try {
|
1367
|
-
let
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1841
|
+
let paymentData;
|
1842
|
+
switch (network) {
|
1843
|
+
case "tron":
|
1844
|
+
if (currency === "TRX") {
|
1845
|
+
paymentData = `tronlink://transfer?to=${walletAddress}&amount=${amount}`;
|
1846
|
+
} else {
|
1847
|
+
paymentData = walletAddress;
|
1848
|
+
}
|
1849
|
+
break;
|
1850
|
+
case "algorand":
|
1851
|
+
paymentData = `algorand://${walletAddress}?amount=${Math.floor(parseFloat(amount) * 1e6)}`;
|
1852
|
+
break;
|
1853
|
+
case "bsc":
|
1854
|
+
if (currency === "BNB") {
|
1855
|
+
paymentData = `ethereum:${walletAddress}@56?value=${convertToWei(amount)}`;
|
1856
|
+
} else {
|
1857
|
+
const tokenAddress = getTokenAddressForCurrency(currency, "bsc");
|
1858
|
+
if (tokenAddress) {
|
1859
|
+
paymentData = `ethereum:${tokenAddress}/transfer?address=${walletAddress}&uint256=${convertToSmallestUnit(amount, currency)}@56`;
|
1860
|
+
} else {
|
1861
|
+
paymentData = walletAddress;
|
1862
|
+
}
|
1863
|
+
}
|
1864
|
+
break;
|
1865
|
+
case "ethereum":
|
1866
|
+
default:
|
1867
|
+
if (currency === "ETH") {
|
1868
|
+
paymentData = `ethereum:${walletAddress}@1?value=${convertToWei(amount)}`;
|
1869
|
+
} else {
|
1870
|
+
const tokenAddress = getTokenAddressForCurrency(currency, "ethereum");
|
1871
|
+
if (tokenAddress) {
|
1872
|
+
paymentData = `ethereum:${tokenAddress}/transfer?address=${walletAddress}&uint256=${convertToSmallestUnit(amount, currency)}`;
|
1873
|
+
} else {
|
1874
|
+
paymentData = walletAddress;
|
1875
|
+
}
|
1876
|
+
}
|
1877
|
+
break;
|
1878
|
+
}
|
1879
|
+
setQrData(paymentData);
|
1880
|
+
setQrError(null);
|
1881
|
+
} catch (err) {
|
1882
|
+
console.error("Error generating QR code:", err);
|
1883
|
+
setQrError("Error generating payment QR code");
|
1884
|
+
}
|
1885
|
+
}, [walletAddress, amount, currency, network]);
|
1886
|
+
const getTokenAddressForCurrency = (currency2, network2) => {
|
1887
|
+
var _a;
|
1888
|
+
const tokenAddresses = {
|
1889
|
+
ethereum: {
|
1890
|
+
"USDT": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
1891
|
+
"USDC": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
1892
|
+
},
|
1893
|
+
bsc: {
|
1894
|
+
"USDT": "0x55d398326f99059fF775485246999027B3197955",
|
1895
|
+
"USDC": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"
|
1896
|
+
},
|
1897
|
+
tron: {
|
1898
|
+
"USDT": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
1899
|
+
"USDC": "TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8"
|
1900
|
+
}
|
1901
|
+
};
|
1902
|
+
return ((_a = tokenAddresses[network2]) == null ? void 0 : _a[currency2]) || "";
|
1903
|
+
};
|
1904
|
+
const convertToSmallestUnit = (amount2, currency2) => {
|
1905
|
+
const decimals = currency2 === "USDT" || currency2 === "USDC" ? 6 : 18;
|
1906
|
+
return Math.floor(parseFloat(amount2) * Math.pow(10, decimals)).toString();
|
1907
|
+
};
|
1908
|
+
const convertToWei = (amount2) => {
|
1909
|
+
return Math.floor(parseFloat(amount2) * 1e18).toString();
|
1910
|
+
};
|
1911
|
+
const getNetworkDisplayName = (network2) => {
|
1912
|
+
const names = {
|
1913
|
+
ethereum: "Ethereum",
|
1914
|
+
bsc: "BSC",
|
1915
|
+
tron: "Tron",
|
1916
|
+
algorand: "Algorand"
|
1917
|
+
};
|
1918
|
+
return names[network2] || network2;
|
1919
|
+
};
|
1920
|
+
const getWalletSuggestions = (network2) => {
|
1921
|
+
const suggestions = {
|
1922
|
+
ethereum: ["MetaMask", "Trust Wallet", "Coinbase Wallet"],
|
1923
|
+
bsc: ["MetaMask", "Trust Wallet", "SafePal"],
|
1924
|
+
tron: ["TronLink", "Trust Wallet"],
|
1925
|
+
algorand: ["Pera Wallet", "MyAlgo Wallet"]
|
1926
|
+
};
|
1927
|
+
return suggestions[network2] || ["MetaMask", "Trust Wallet"];
|
1928
|
+
};
|
1929
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center", children: [
|
1930
|
+
qrError ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 rounded-lg bg-red-100 mb-3 text-red-700 text-center", children: [
|
1931
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-8 w-8 mx-auto mb-2", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
1932
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium", children: qrError })
|
1933
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 rounded-lg bg-white mb-3 shadow-sm border", children: qrData && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
1934
|
+
QRCodeSVG,
|
1384
1935
|
{
|
1385
|
-
value:
|
1386
|
-
size
|
1387
|
-
bgColor:
|
1388
|
-
fgColor:
|
1936
|
+
value: qrData,
|
1937
|
+
size,
|
1938
|
+
bgColor: theme === "dark" ? "#374151" : "#FFFFFF",
|
1939
|
+
fgColor: theme === "dark" ? "#FFFFFF" : "#000000",
|
1389
1940
|
level: "H",
|
1390
|
-
includeMargin:
|
1941
|
+
includeMargin: true
|
1391
1942
|
}
|
1392
1943
|
) }),
|
1393
|
-
/* @__PURE__ */
|
1394
|
-
/* @__PURE__ */
|
1395
|
-
|
1944
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-sm text-gray-700 mb-4", children: [
|
1945
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold text-gray-800 flex items-center justify-center", children: [
|
1946
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M12 12h-4.01M12 12V8.01" }) }),
|
1947
|
+
"Scan to Pay with ",
|
1948
|
+
currency
|
1949
|
+
] }),
|
1950
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
|
1951
|
+
"Scan with your ",
|
1952
|
+
getNetworkDisplayName(network),
|
1953
|
+
" wallet app"
|
1954
|
+
] })
|
1396
1955
|
] }),
|
1397
|
-
/* @__PURE__ */
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
/* @__PURE__ */ a.jsx("li", { children: "2. Scan the QR code above" }),
|
1403
|
-
/* @__PURE__ */ a.jsxs("li", { children: [
|
1404
|
-
"3. Confirm the payment amount (",
|
1405
|
-
r,
|
1956
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mb-4 p-3 bg-gray-50 rounded-lg", children: [
|
1957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
|
1958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-700", children: "Amount to Pay:" }),
|
1959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-lg font-bold text-[#7042D2]", children: [
|
1960
|
+
amount,
|
1406
1961
|
" ",
|
1407
|
-
|
1962
|
+
currency
|
1963
|
+
] })
|
1964
|
+
] }),
|
1965
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mt-1", children: [
|
1966
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "Network:" }),
|
1967
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-gray-700", children: getNetworkDisplayName(network) })
|
1968
|
+
] })
|
1969
|
+
] }),
|
1970
|
+
!qrError && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mb-4", children: [
|
1971
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mb-1 text-center", children: "Or copy wallet address:" }),
|
1972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1973
|
+
"div",
|
1974
|
+
{
|
1975
|
+
className: "text-xs font-mono p-2 rounded bg-gray-100 text-gray-700 break-all text-center select-all cursor-pointer border",
|
1976
|
+
onClick: () => {
|
1977
|
+
var _a;
|
1978
|
+
return (_a = navigator.clipboard) == null ? void 0 : _a.writeText(walletAddress);
|
1979
|
+
},
|
1980
|
+
title: "Click to copy",
|
1981
|
+
children: walletAddress
|
1982
|
+
}
|
1983
|
+
)
|
1984
|
+
] }),
|
1985
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 rounded bg-blue-50 border border-blue-200", children: [
|
1986
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-medium mb-2 text-blue-800 flex items-center", children: [
|
1987
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 mr-1", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
1988
|
+
"Payment Instructions"
|
1989
|
+
] }),
|
1990
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ol", { className: "text-xs space-y-1 text-blue-700", children: [
|
1991
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
1992
|
+
"1. Open your crypto wallet app (",
|
1993
|
+
getWalletSuggestions(network).join(", "),
|
1408
1994
|
")"
|
1409
1995
|
] }),
|
1410
|
-
/* @__PURE__ */
|
1411
|
-
|
1996
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: "2. Scan the QR code above or copy the wallet address" }),
|
1997
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
1998
|
+
"3. Send exactly ",
|
1999
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
2000
|
+
amount,
|
2001
|
+
" ",
|
2002
|
+
currency
|
2003
|
+
] }),
|
2004
|
+
" on ",
|
2005
|
+
getNetworkDisplayName(network),
|
2006
|
+
" network"
|
2007
|
+
] }),
|
2008
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: '4. Click "I have sent the payment" button below after sending' })
|
2009
|
+
] }),
|
2010
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 p-2 bg-yellow-50 border border-yellow-200 rounded", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-yellow-800", children: [
|
2011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Important:" }),
|
2012
|
+
" Make sure you're sending on the correct network (",
|
2013
|
+
getNetworkDisplayName(network),
|
2014
|
+
") and using the exact amount shown above."
|
2015
|
+
] }) })
|
1412
2016
|
] }) })
|
1413
2017
|
] });
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
|
2018
|
+
};
|
2019
|
+
const PaymentStatus = ({ status, message, theme = "light" }) => {
|
2020
|
+
const renderIcon = () => {
|
2021
|
+
switch (status) {
|
1417
2022
|
case "processing":
|
1418
|
-
return /* @__PURE__ */
|
2023
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-4 border-t-blue-500 border-blue-500/20" });
|
1419
2024
|
case "success":
|
1420
|
-
return /* @__PURE__ */
|
2025
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-full h-12 w-12 bg-green-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
1421
2026
|
"svg",
|
1422
2027
|
{
|
1423
2028
|
xmlns: "http://www.w3.org/2000/svg",
|
@@ -1426,11 +2031,11 @@ const Vt = ({
|
|
1426
2031
|
viewBox: "0 0 24 24",
|
1427
2032
|
stroke: "currentColor",
|
1428
2033
|
strokeWidth: 2,
|
1429
|
-
children: /* @__PURE__ */
|
2034
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
1430
2035
|
}
|
1431
2036
|
) });
|
1432
2037
|
case "error":
|
1433
|
-
return /* @__PURE__ */
|
2038
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-full h-12 w-12 bg-red-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
1434
2039
|
"svg",
|
1435
2040
|
{
|
1436
2041
|
xmlns: "http://www.w3.org/2000/svg",
|
@@ -1439,14 +2044,15 @@ const Vt = ({
|
|
1439
2044
|
viewBox: "0 0 24 24",
|
1440
2045
|
stroke: "currentColor",
|
1441
2046
|
strokeWidth: 2,
|
1442
|
-
children: /* @__PURE__ */
|
2047
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
1443
2048
|
}
|
1444
2049
|
) });
|
1445
2050
|
default:
|
1446
2051
|
return null;
|
1447
2052
|
}
|
1448
|
-
}
|
1449
|
-
|
2053
|
+
};
|
2054
|
+
const getStatusTitle = () => {
|
2055
|
+
switch (status) {
|
1450
2056
|
case "processing":
|
1451
2057
|
return "Processing Payment";
|
1452
2058
|
case "success":
|
@@ -1456,374 +2062,617 @@ const Vt = ({
|
|
1456
2062
|
default:
|
1457
2063
|
return "Unknown Status";
|
1458
2064
|
}
|
1459
|
-
}
|
1460
|
-
|
2065
|
+
};
|
2066
|
+
const getMessageClasses = () => {
|
2067
|
+
switch (status) {
|
1461
2068
|
case "processing":
|
1462
|
-
return
|
2069
|
+
return theme === "dark" ? "text-blue-300" : "text-blue-600";
|
1463
2070
|
case "success":
|
1464
|
-
return
|
2071
|
+
return theme === "dark" ? "text-green-300" : "text-green-600";
|
1465
2072
|
case "error":
|
1466
|
-
return
|
2073
|
+
return theme === "dark" ? "text-red-300" : "text-red-600";
|
1467
2074
|
default:
|
1468
|
-
return
|
2075
|
+
return theme === "dark" ? "text-gray-300" : "text-gray-600";
|
1469
2076
|
}
|
1470
2077
|
};
|
1471
|
-
return /* @__PURE__ */
|
1472
|
-
/* @__PURE__ */
|
1473
|
-
/* @__PURE__ */
|
1474
|
-
/* @__PURE__ */
|
1475
|
-
|
1476
|
-
|
2078
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6", children: [
|
2079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: renderIcon() }),
|
2080
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: `text-xl font-bold mb-2 ${theme === "dark" ? "text-white" : "text-gray-900"}`, children: getStatusTitle() }),
|
2081
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-center ${getMessageClasses()}`, children: message }),
|
2082
|
+
status === "processing" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 text-xs ${theme === "dark" ? "text-gray-400" : "text-gray-500"}`, children: "This may take a few moments. Please do not close this window." }),
|
2083
|
+
status === "success" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `mt-4 p-2 rounded ${theme === "dark" ? "bg-gray-700" : "bg-gray-100"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs ${theme === "dark" ? "text-gray-300" : "text-gray-600"}`, children: "Your payment has been successfully processed. You will receive a confirmation shortly." }) })
|
1477
2084
|
] });
|
1478
|
-
}
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
2085
|
+
};
|
2086
|
+
const PaymentMethods = ({ onSelect, selected, theme = "light", supportedNetworks = [] }) => {
|
2087
|
+
const [selectedNetwork, setSelectedNetwork] = useState(NETWORK_TYPES.ETHEREUM);
|
2088
|
+
const [availableWallets, setAvailableWallets] = useState({});
|
2089
|
+
const [showMore, setShowMore] = useState(false);
|
2090
|
+
useEffect(() => {
|
2091
|
+
setAvailableWallets(detectWallets());
|
1482
2092
|
}, []);
|
1483
|
-
const
|
2093
|
+
const networks = [
|
1484
2094
|
{
|
1485
|
-
id:
|
1486
|
-
name: "
|
1487
|
-
description: "
|
1488
|
-
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSj0euZAOXsLTJFQxgiKzlX7z8xbfBk-7kmJA&s",
|
1489
|
-
networks: [A.ETHEREUM, A.BSC, A.TRON]
|
2095
|
+
id: NETWORK_TYPES.ETHEREUM,
|
2096
|
+
name: "Ethereum",
|
2097
|
+
description: "ERC-20 tokens"
|
1490
2098
|
},
|
1491
2099
|
{
|
1492
|
-
id:
|
1493
|
-
name: "
|
1494
|
-
description: "
|
1495
|
-
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ43MuDqq54iD1ZCRL_uthAPkfwSSL-J5qI_Q&s",
|
1496
|
-
networks: [A.ETHEREUM, A.BSC, A.TRON]
|
2100
|
+
id: NETWORK_TYPES.BSC,
|
2101
|
+
name: "BSC (Binance Smart Chain)",
|
2102
|
+
description: "BEP-20 tokens"
|
1497
2103
|
},
|
1498
2104
|
{
|
1499
|
-
id:
|
1500
|
-
name: "
|
1501
|
-
description: "
|
1502
|
-
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHSjyW2sSnBhwztCwVW97i1BtV40g7heMMxg&s",
|
1503
|
-
networks: [A.BSC]
|
2105
|
+
id: NETWORK_TYPES.TRON,
|
2106
|
+
name: "Tron",
|
2107
|
+
description: "TRC-20 tokens"
|
1504
2108
|
},
|
1505
2109
|
{
|
1506
|
-
id:
|
1507
|
-
name: "
|
1508
|
-
description: "
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
2110
|
+
id: NETWORK_TYPES.ALGORAND,
|
2111
|
+
name: "Algorand",
|
2112
|
+
description: "ASA tokens"
|
2113
|
+
}
|
2114
|
+
];
|
2115
|
+
const getPaymentMethodsForNetwork = (network) => {
|
2116
|
+
const methods = [];
|
2117
|
+
switch (network) {
|
2118
|
+
case NETWORK_TYPES.ETHEREUM:
|
2119
|
+
methods.push(
|
2120
|
+
{
|
2121
|
+
id: "USDT",
|
2122
|
+
name: "USDT",
|
2123
|
+
description: "Tether USD",
|
2124
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSj0euZAOXsLTJFQxgiKzlX7z8xbfBk-7kmJA&s",
|
2125
|
+
network: NETWORK_TYPES.ETHEREUM
|
2126
|
+
},
|
2127
|
+
{
|
2128
|
+
id: "USDC",
|
2129
|
+
name: "USDC",
|
2130
|
+
description: "USD Coin",
|
2131
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ43MuDqq54iD1ZCRL_uthAPkfwSSL-J5qI_Q&s",
|
2132
|
+
network: NETWORK_TYPES.ETHEREUM
|
2133
|
+
},
|
2134
|
+
{
|
2135
|
+
id: "PYUSD",
|
2136
|
+
name: "PYUSD",
|
2137
|
+
description: "PayPal USD",
|
2138
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/28492.png",
|
2139
|
+
network: NETWORK_TYPES.ETHEREUM
|
2140
|
+
},
|
2141
|
+
{
|
2142
|
+
id: "FRAX",
|
2143
|
+
name: "FRAX",
|
2144
|
+
description: "Frax",
|
2145
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/6952.png",
|
2146
|
+
network: NETWORK_TYPES.ETHEREUM
|
2147
|
+
},
|
2148
|
+
{
|
2149
|
+
id: "USDP",
|
2150
|
+
name: "USDP",
|
2151
|
+
description: "Pax Dollar",
|
2152
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/6662.png",
|
2153
|
+
network: NETWORK_TYPES.ETHEREUM
|
2154
|
+
},
|
2155
|
+
{
|
2156
|
+
id: "DAI",
|
2157
|
+
name: "DAI",
|
2158
|
+
description: "Dai Stablecoin",
|
2159
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/4943.png",
|
2160
|
+
network: NETWORK_TYPES.ETHEREUM
|
2161
|
+
},
|
2162
|
+
{
|
2163
|
+
id: "ETH",
|
2164
|
+
name: "ETH",
|
2165
|
+
description: "Ethereum",
|
2166
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcyJyRKN0dRJWVZqoLzYgkRHdJsxKGq8nHUw&s",
|
2167
|
+
network: NETWORK_TYPES.ETHEREUM
|
2168
|
+
}
|
2169
|
+
);
|
2170
|
+
break;
|
2171
|
+
case NETWORK_TYPES.BSC:
|
2172
|
+
methods.push(
|
2173
|
+
{
|
2174
|
+
id: "USDT",
|
2175
|
+
name: "USDT",
|
2176
|
+
description: "Tether USD",
|
2177
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSj0euZAOXsLTJFQxgiKzlX7z8xbfBk-7kmJA&s",
|
2178
|
+
network: NETWORK_TYPES.BSC
|
2179
|
+
},
|
2180
|
+
{
|
2181
|
+
id: "USDC",
|
2182
|
+
name: "USDC",
|
2183
|
+
description: "USD Coin",
|
2184
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ43MuDqq54iD1ZCRL_uthAPkfwSSL-J5qI_Q&s",
|
2185
|
+
network: NETWORK_TYPES.BSC
|
2186
|
+
},
|
2187
|
+
{
|
2188
|
+
id: "BUSD",
|
2189
|
+
name: "BUSD",
|
2190
|
+
description: "Binance USD",
|
2191
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/4687.png",
|
2192
|
+
network: NETWORK_TYPES.BSC
|
2193
|
+
},
|
2194
|
+
{
|
2195
|
+
id: "FRAX",
|
2196
|
+
name: "FRAX",
|
2197
|
+
description: "Frax",
|
2198
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/6952.png",
|
2199
|
+
network: NETWORK_TYPES.BSC
|
2200
|
+
},
|
2201
|
+
{
|
2202
|
+
id: "BNB",
|
2203
|
+
name: "BNB",
|
2204
|
+
description: "Binance Coin",
|
2205
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHSjyW2sSnBhwztCwVW97i1BtV40g7heMMxg&s",
|
2206
|
+
network: NETWORK_TYPES.BSC
|
2207
|
+
}
|
2208
|
+
);
|
2209
|
+
break;
|
2210
|
+
case NETWORK_TYPES.TRON:
|
2211
|
+
methods.push(
|
2212
|
+
{
|
2213
|
+
id: "USDT",
|
2214
|
+
name: "USDT",
|
2215
|
+
description: "Tether USD",
|
2216
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSj0euZAOXsLTJFQxgiKzlX7z8xbfBk-7kmJA&s",
|
2217
|
+
network: NETWORK_TYPES.TRON
|
2218
|
+
},
|
2219
|
+
{
|
2220
|
+
id: "USDC",
|
2221
|
+
name: "USDC",
|
2222
|
+
description: "USD Coin",
|
2223
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ43MuDqq54iD1ZCRL_uthAPkfwSSL-J5qI_Q&s",
|
2224
|
+
network: NETWORK_TYPES.TRON
|
2225
|
+
},
|
2226
|
+
{
|
2227
|
+
id: "USDJ",
|
2228
|
+
name: "USDJ",
|
2229
|
+
description: "JUST Stablecoin",
|
2230
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/5446.png",
|
2231
|
+
network: NETWORK_TYPES.TRON
|
2232
|
+
},
|
2233
|
+
{
|
2234
|
+
id: "TRX",
|
2235
|
+
name: "TRX",
|
2236
|
+
description: "Tron",
|
2237
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQKLpLNsGRHbZfCUXAjZLPSp_YFZvX5dMnAoA&s",
|
2238
|
+
network: NETWORK_TYPES.TRON
|
2239
|
+
}
|
2240
|
+
);
|
2241
|
+
break;
|
2242
|
+
case NETWORK_TYPES.ALGORAND:
|
2243
|
+
methods.push(
|
2244
|
+
{
|
2245
|
+
id: "USDC",
|
2246
|
+
name: "USDC",
|
2247
|
+
description: "USD Coin",
|
2248
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ43MuDqq54iD1ZCRL_uthAPkfwSSL-J5qI_Q&s",
|
2249
|
+
network: NETWORK_TYPES.ALGORAND
|
2250
|
+
},
|
2251
|
+
{
|
2252
|
+
id: "USDT",
|
2253
|
+
name: "USDT",
|
2254
|
+
description: "Tether USD",
|
2255
|
+
logo: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSj0euZAOXsLTJFQxgiKzlX7z8xbfBk-7kmJA&s",
|
2256
|
+
network: NETWORK_TYPES.ALGORAND
|
2257
|
+
},
|
2258
|
+
{
|
2259
|
+
id: "ALGO",
|
2260
|
+
name: "ALGO",
|
2261
|
+
description: "Algorand",
|
2262
|
+
logo: "https://s2.coinmarketcap.com/static/img/coins/64x64/4030.png",
|
2263
|
+
network: NETWORK_TYPES.ALGORAND
|
2264
|
+
}
|
2265
|
+
);
|
2266
|
+
break;
|
2267
|
+
}
|
2268
|
+
return methods;
|
2269
|
+
};
|
2270
|
+
const handleNetworkChange = (networkId) => {
|
2271
|
+
setSelectedNetwork(networkId);
|
2272
|
+
setShowMore(false);
|
2273
|
+
if ((selected == null ? void 0 : selected.network) !== networkId) {
|
2274
|
+
onSelect(null);
|
2275
|
+
}
|
2276
|
+
};
|
2277
|
+
const handleSelectPaymentMethod = (method) => {
|
2278
|
+
var _a;
|
2279
|
+
onSelect({
|
2280
|
+
currency: method.id,
|
2281
|
+
network: selectedNetwork,
|
2282
|
+
tokenConfig: (_a = TOKEN_CONFIG[method.id]) == null ? void 0 : _a[selectedNetwork],
|
2283
|
+
method
|
1540
2284
|
});
|
1541
2285
|
};
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
2286
|
+
const availableMethods = getPaymentMethodsForNetwork(selectedNetwork);
|
2287
|
+
const visibleMethods = showMore ? availableMethods : availableMethods.slice(0, 4);
|
2288
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2289
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: `text-lg font-medium mb-4 ${theme === "dark" ? "text-white" : "text-gray-800"}`, children: "Select Payment Method" }),
|
2290
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [
|
2291
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: `block text-sm font-medium mb-2 ${theme === "dark" ? "text-white" : "text-gray-700"}`, children: "Blockchain Network" }),
|
2292
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2293
|
+
"select",
|
2294
|
+
{
|
2295
|
+
value: selectedNetwork,
|
2296
|
+
onChange: (e) => handleNetworkChange(e.target.value),
|
2297
|
+
className: `w-full p-3 rounded-lg border transition-colors ${theme === "dark" ? "bg-gray-700 border-gray-600 text-white focus:border-[#7042D2]" : "bg-white border-gray-300 text-gray-900 focus:border-[#7042D2]"} focus:outline-none focus:ring-2 focus:ring-[#7042D2] focus:ring-opacity-50`,
|
2298
|
+
children: networks.filter((network) => supportedNetworks.length === 0 || supportedNetworks.includes(network.id)).map((network) => /* @__PURE__ */ jsxRuntimeExports.jsxs("option", { value: network.id, children: [
|
2299
|
+
network.name,
|
2300
|
+
" - ",
|
2301
|
+
network.description
|
2302
|
+
] }, network.id))
|
2303
|
+
}
|
2304
|
+
)
|
2305
|
+
] }),
|
2306
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
|
2307
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: `block text-sm font-medium mb-3 ${theme === "dark" ? "text-white" : "text-gray-700"}`, children: "Choose Cryptocurrency" }),
|
2308
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-3 mb-4", children: visibleMethods.map((method) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2309
|
+
"button",
|
2310
|
+
{
|
2311
|
+
onClick: () => handleSelectPaymentMethod(method),
|
2312
|
+
className: `p-4 rounded-lg transition-all duration-200 border-2 ${(selected == null ? void 0 : selected.currency) === method.id && (selected == null ? void 0 : selected.network) === selectedNetwork ? theme === "dark" ? "bg-blue-900/30 border-[#7042D2] ring-2 ring-[#7042D2] ring-opacity-50" : "bg-blue-50 border-[#7042D2] ring-2 ring-[#7042D2] ring-opacity-50" : theme === "dark" ? "bg-gray-700 hover:bg-gray-600 border-gray-600 hover:border-gray-500" : "bg-white hover:bg-gray-50 border-gray-200 hover:border-gray-300"}`,
|
2313
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center text-center", children: [
|
2314
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 h-10 w-10 bg-white rounded-full flex items-center justify-center mb-2 shadow-sm", children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: method.logo, alt: method.name, className: "h-6 w-6" }) }),
|
2315
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2316
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: `font-medium text-sm ${theme === "dark" ? "text-white" : "text-gray-900"}`, children: method.name }),
|
2317
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs ${theme === "dark" ? "text-gray-300" : "text-gray-500"}`, children: method.description })
|
2318
|
+
] }),
|
2319
|
+
(selected == null ? void 0 : selected.currency) === method.id && (selected == null ? void 0 : selected.network) === selectedNetwork && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2320
|
+
"svg",
|
1560
2321
|
{
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
fillRule: "evenodd",
|
1593
|
-
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
|
1594
|
-
clipRule: "evenodd"
|
1595
|
-
}
|
1596
|
-
)
|
1597
|
-
}
|
1598
|
-
)
|
1599
|
-
] })
|
1600
|
-
}
|
1601
|
-
) })
|
1602
|
-
] }, d.id);
|
1603
|
-
}) }),
|
1604
|
-
/* @__PURE__ */ a.jsxs("div", { className: "mt-4 p-3 rounded-lg bg-gray-50 dark:bg-gray-800", children: [
|
1605
|
-
/* @__PURE__ */ a.jsx("h4", { className: `text-sm font-medium mb-2 ${t === "dark" ? "text-white" : "text-gray-800"}`, children: "Detected Wallets:" }),
|
1606
|
-
/* @__PURE__ */ a.jsx("div", { className: "space-y-1", children: Object.entries(u).map(([d, m]) => /* @__PURE__ */ a.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
1607
|
-
/* @__PURE__ */ a.jsx("span", { className: `capitalize ${t === "dark" ? "text-gray-300" : "text-gray-600"}`, children: d.replace("_", " ") }),
|
1608
|
-
/* @__PURE__ */ a.jsx("span", { className: `px-2 py-1 rounded-full ${m ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"}`, children: m ? "Available" : "Not detected" })
|
1609
|
-
] }, d)) })
|
1610
|
-
] })
|
2322
|
+
xmlns: "http://www.w3.org/2000/svg",
|
2323
|
+
className: "h-4 w-4 text-[#7042D2]",
|
2324
|
+
viewBox: "0 0 20 20",
|
2325
|
+
fill: "currentColor",
|
2326
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2327
|
+
"path",
|
2328
|
+
{
|
2329
|
+
fillRule: "evenodd",
|
2330
|
+
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
|
2331
|
+
clipRule: "evenodd"
|
2332
|
+
}
|
2333
|
+
)
|
2334
|
+
}
|
2335
|
+
) })
|
2336
|
+
] })
|
2337
|
+
},
|
2338
|
+
`${method.id}-${method.network}`
|
2339
|
+
)) }),
|
2340
|
+
availableMethods.length > 4 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2341
|
+
"button",
|
2342
|
+
{
|
2343
|
+
onClick: () => setShowMore(!showMore),
|
2344
|
+
className: `w-full py-2 px-4 rounded-lg text-sm font-medium transition-colors ${theme === "dark" ? "bg-gray-700 text-gray-300 hover:bg-gray-600" : "bg-gray-100 text-gray-600 hover:bg-gray-200"}`,
|
2345
|
+
children: showMore ? "Show Less" : `Show More (${availableMethods.length - 4} more)`
|
2346
|
+
}
|
2347
|
+
)
|
2348
|
+
] }),
|
2349
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `p-3 rounded-lg text-sm ${theme === "dark" ? "bg-gray-800 text-gray-300" : "bg-gray-50 text-gray-600"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
|
2350
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `w-2 h-2 rounded-full mr-2 ${availableWallets[getRequiredWallet(selectedNetwork)] ? "bg-green-500" : "bg-red-500"}` }),
|
2351
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: getNetworkRequirement(selectedNetwork) })
|
2352
|
+
] }) })
|
1611
2353
|
] });
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
2354
|
+
function getRequiredWallet(network) {
|
2355
|
+
switch (network) {
|
2356
|
+
case NETWORK_TYPES.ETHEREUM:
|
2357
|
+
case NETWORK_TYPES.BSC:
|
2358
|
+
return "metamask";
|
2359
|
+
case NETWORK_TYPES.TRON:
|
2360
|
+
return "tronlink";
|
2361
|
+
case NETWORK_TYPES.ALGORAND:
|
2362
|
+
return "lute";
|
2363
|
+
default:
|
2364
|
+
return "metamask";
|
2365
|
+
}
|
2366
|
+
}
|
2367
|
+
function getNetworkRequirement(network) {
|
2368
|
+
const wallet = getRequiredWallet(network);
|
2369
|
+
const isAvailable = availableWallets[wallet];
|
2370
|
+
const walletNames = {
|
2371
|
+
metamask: "MetaMask",
|
2372
|
+
tronlink: "TronLink",
|
2373
|
+
lute: "Lute Wallet"
|
2374
|
+
};
|
2375
|
+
return isAvailable ? `${walletNames[wallet]} detected - Ready to pay` : `${walletNames[wallet]} required - Please install to continue`;
|
2376
|
+
}
|
2377
|
+
};
|
2378
|
+
const logo = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAAAkCAYAAABv9hOhAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAmVSURBVHgB7Vzdcdu4Fv5I+X2VCoK83pkb2xVc2ikgTgVWKog8twDJBexYrsBKBXYKWJtbQWRnZl+NrWC172txcQBQBA8B/kiKV87qm4FFgMAhAX48ODg4dISOGB4/XKsfObl9e+Y9n3wViHt3QHY5ud2fYId1caDSJyc/V+kMW4q4S2VFFurcCR0Oj+/H3kq9vSv1VyDDKX5s0Fh8VSlTifrcx/cByR046QRbjE6EQmnQok9aGzlQ+QRZluDHh1BJaWFNKsJApQvs0JlQc+e4jzgelqX1HNUczfHjQqCqkRLsUCWU0jL94buHE659LGQ5G51SfafAUcfZn572Sv63hKZL1u6lYeYpk9jBo6HieKysgmulbR6VAX7lEmuSHpLWkU5tIoVW+3q6cxEhdbOaqMcPF4gzNVVEI2VsJXi5oHE4d/JSpY/YwUOoRYkwA1qxWWPcIvtSlhDbc/FBWc5i+RbblR8ZsGaKzDIJPKV42Rir9EqlNzZJ7OCzoRZTlG0lTYalBlosbsr1o33zg4JQijBKm6V0WLgRtN1hm+DSaruXDq6x//XY4wX0oJWNo9R5VF61xL1rRY4jIsrw6F4iioQuz7JX5nz8Wh2bulGU0o+2kziZMqSTu7X9UwLGCBZOGWnEFOWXoQk0ZZ945FCS+D4QKN873W8Kv122Kv6Jfmns+QrJITl89+09cwH0LakOkS3OEPWuS42yrHiQiydjX8Q9IqVw6kjVdh1bI1FphPoV1RTGvpFryklVulTpJnD+jrX/aK9NeET5YR7Z+7lC+Jr0sD9gvQeeoF2/PjrXIfI9orxqpfEboxmkGFyn6yzsNnj664MiAH9rBLkKlJa6IU+4LsnyNyu7t7/n6rxUBvgAxj9jizWZSMNJdAd1lgjMH6IPA5gBGgXOX7SUk9hrbsK/JFpcM3eUruq47NIvd3xIEVyyOp/QDu9Z/nJJKL0K4ys6RYAlcZaItAdcabGh0kSHk3R/rIsXi4nO39p8FBU3paa5NclEA9V1oMeokoo0xBDdMLTt1oHZPWhGv0NdLr9rv8YoxmfiuY8E9aDzgpWle+RzUiu7T8pQpgq0V0dkmJmVGL6oPTu1zfJA+ZG2m3I7CZp0M+eYmF5otCyji821xlrPZqI378BTnqr0qz2mAXjv6eBYJdKcNG3R4A1q5Ejb/n+oDia128QemoTRBtLKy/fphFOH+jJEe4JcoNovaa+T2uuIwLXGMH1PbUqccyNbFgLfWpvq6yqyZA3p0U5f2tfU1iG5IcflAGavzE00LYia+o9O3T9smfDIoXpJQI5gcvLk1r9j5wbOOV/bKfz7fX0Ue4LufedIPPft3ie/zgThfUWqfx2Ql3hk1T1D3kc9g8T5iqwGQqWr4fG3Ea3w2i73N+QWGLG8RGHg+jCFMWzz4zf2NyQnDcgJXWeE1SBRaDkOKuMLFXqQr9EMfj8pjGab19yHa5ATBAwZUlTHI6Ql+QpSwi5eYmt8f0YjsvH/j39r08lNgVS0YGX0kJuIStPuIczAUd18t95F0yoQ8Hu/E6wWVdA0vr7l/Bs0Y8Dy5y3a+Izw3Ljm90lTpK+/3BhP84M9q0kGaoqa2s1dv/GrbKqf7/7zO54PguVTtF9Su6tTbn9JFMv7JqQobKscCcKuhDo5TZDoZownLD8PlPswD8iawthkOYly49ztb+7jcrEk8tIPZT3bqbV9DhS5hGKRUAa7uvhilnu+nxGcCPdYDYLlJbrhVyZDYDvQ9+TvsBqEc0zay51KScm4hDph1y5p15IfypBpj8hEKu29dhH04lOVPw1EHzwnNmGTESTWwyYWG5vA97qPCcpjnaCs9U5Z/dL0WfihlNFNEQYmGkAbY8bwyjLSFAO7n/ecg8kJtCn77aBj/Z9YXmI7sKkXjMuiY25L5VOcQHVKTd1MTJpHbbN8JaMb9ax/7jdTsvwJVsOM5QW69SVheYntAO8XEYH2VaMV0ismi9uIpJVye8rFFGw8YqV5RlYLNUBvqWzyrWhCCh4h2t7ZN0BhF8w8ctou/0cok2+Odgb2c0Bi9fFpQopyP/OVMp/uvvCG8TJqIATtMc8o+uD18Ojh7uzdt1b7PMMkGPXZFr6HRw+4ifxU5wrl/Sq+TKaBP22QQ+fHrKzr6u57w7cHJ9AMqtdEvnNPm8TJS3jGg/xQHz3OTao8VcpQOQkjaSIsFUPV9kyWZZNW/qg4O9DBebS1szpoq4O/heRVpvsRrG4Cs8oZO2V0TJ2eoDpVTeHfN6NrXKDqWpBo5+d5TnADOl/pDQL1875N7O9jTd0UPC6uer6CyM2QRsk3cL2BcTkWT+RgnKnzVxSqQnt6tv6Fyp8tZRzdf1VkVRolGk9u/7vqw6A3KbTjL+1vH367iAbk0NZLEF5W59OiQPgNJw+8+0Z2DV9JUQ8uL2+ToHzfEmWnJ72w1x55VC9f0vdR7Of1PfVCTtQxwubBITwxXCW3gUOmfpBMeTSmiXU6QRwnVtSJzke9q6Lu4oOdMsd6Fbka6G0KkVEgbGQTQdztkxThuG8a6ARhMlG7bZvuctB9+cZHwH5DCaOFEvjJdIQwuAbMMUMgINAfD8UD41yo6dHaRgNb0reSzK+aFvNwYU1QIpWJOliHVGNU96DqkML/Bk3RLf6b6h2hvWf9n8IY9XucPhARDxva+FwIhMtQg0rEJiNLGSZI7lyvDMsXhbG1LKLeMvTBTodH9vN0IhVWnP6mNg1gDOaEnc+N+DxsIwQJQ6qBlcOnAZJDRPyMeiJ9QflhSHbuJyazCVze3JE79ZRzpCj6RY7pBH6NRNe5QfvVqgxcy4uIF5hPzCO/JlG2k44pP36g8Ip+qYyM78yZyxdPr1w3g/5yJoqv9apSGfuTX95uYgoRzrHE6hAbkrNtcG3LOVZzhnLbboqaT8aqU17mnermS+KY6Yzv5QBP7LOoOB64WR2MRxGgWsvhakNed+mkbZCzbSACSVR9Vm3BXQWEz3UNqoSquhCmJtTXbg4vjXDQFDjLtZD+pUjPQtA+F0021eRu/40NKz7ADtuMkB8urWtU/Yzq9u1UaQ+pow0WTzdV77hDlGgZgmuQLdT8HBmi1Hjfl3HnO2wbEhT2qWDniAeNIdD+z6jqQlXcuHL6MMHFYpEuDfYo2sSUtsPzQiDs6CQySTQgRldkWU6UKf+KRROxOaR4h5cF0kzk+pm2qdydUJF2D8yXH3NyPP21tf9dbYdOkDAOU3JFtF6R76EraO9PrfJC39hZv5NidG835b085Eb3qi4G/A2inrQKnVgMFAAAAABJRU5ErkJggg==";
|
2379
|
+
const CoinleyModal = ({
|
2380
|
+
isOpen,
|
2381
|
+
onClose,
|
2382
|
+
payment,
|
2383
|
+
paymentStatus,
|
2384
|
+
selectedPaymentMethod,
|
2385
|
+
onPaymentMethodSelect,
|
2386
|
+
onPayment,
|
2387
|
+
onBack,
|
2388
|
+
error,
|
2389
|
+
theme = "light",
|
2390
|
+
merchantName,
|
2391
|
+
transactionHash,
|
2392
|
+
walletConnection,
|
2393
|
+
onConnectWallet,
|
2394
|
+
testMode = false,
|
2395
|
+
supportedNetworks = [],
|
2396
|
+
availableWallets = {},
|
2397
|
+
supportedWallets = [],
|
2398
|
+
step = "select-currency",
|
2399
|
+
merchantWalletAddresses = {}
|
2400
|
+
// Add this prop
|
1632
2401
|
}) => {
|
1633
|
-
const
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
}
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
2402
|
+
const [paymentType, setPaymentType] = useState("wallet");
|
2403
|
+
const getWalletAddressForNetwork = () => {
|
2404
|
+
if (!selectedPaymentMethod)
|
2405
|
+
return "No network selected";
|
2406
|
+
const networkAddress = merchantWalletAddresses[selectedPaymentMethod.network];
|
2407
|
+
if (networkAddress) {
|
2408
|
+
return networkAddress;
|
2409
|
+
}
|
2410
|
+
if (payment == null ? void 0 : payment.recipientWallet) {
|
2411
|
+
return payment.recipientWallet;
|
2412
|
+
}
|
2413
|
+
return "No wallet address configured for this network";
|
2414
|
+
};
|
2415
|
+
const formatAmount = (amount) => {
|
2416
|
+
return parseFloat(amount).toFixed(2);
|
2417
|
+
};
|
2418
|
+
const formatTransactionHash = (hash) => {
|
2419
|
+
if (!hash)
|
2420
|
+
return "";
|
2421
|
+
if (hash.length <= 14)
|
2422
|
+
return hash;
|
2423
|
+
return `${hash.slice(0, 8)}...${hash.slice(-6)}`;
|
2424
|
+
};
|
2425
|
+
const getNetworkDisplayName = (network) => {
|
2426
|
+
const names = {
|
2427
|
+
ethereum: "Ethereum",
|
2428
|
+
bsc: "BSC",
|
2429
|
+
tron: "Tron",
|
2430
|
+
algorand: "Algorand"
|
2431
|
+
};
|
2432
|
+
return names[network] || network;
|
2433
|
+
};
|
2434
|
+
const getWalletDisplayName = (walletType) => {
|
2435
|
+
const names = {
|
2436
|
+
[WALLET_TYPES.METAMASK]: "MetaMask",
|
2437
|
+
[WALLET_TYPES.TRONLINK]: "TronLink",
|
2438
|
+
[WALLET_TYPES.TRUST_WALLET]: "Trust Wallet",
|
2439
|
+
[WALLET_TYPES.LUTE]: "Lute Wallet"
|
2440
|
+
};
|
2441
|
+
return names[walletType] || walletType;
|
2442
|
+
};
|
2443
|
+
const getWalletIcon = (walletType) => {
|
2444
|
+
const icons = {
|
2445
|
+
[WALLET_TYPES.METAMASK]: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT3ymr3UNKopfI0NmUY95Dr-0589vG-91KuAA&s",
|
2446
|
+
[WALLET_TYPES.TRONLINK]: "https://www.tronlink.org/images/logo.png",
|
2447
|
+
[WALLET_TYPES.TRUST_WALLET]: "https://trustwallet.com/assets/images/trust_logotype.svg",
|
2448
|
+
[WALLET_TYPES.LUTE]: "https://lute.app/logo.png"
|
2449
|
+
};
|
2450
|
+
return icons[walletType] || "";
|
2451
|
+
};
|
2452
|
+
if (!isOpen)
|
2453
|
+
return null;
|
2454
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 overflow-y-auto bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative p-6 w-full max-w-md mx-auto rounded-lg shadow-xl bg-white text-gray-800", children: [
|
2455
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mb-6 bg-[#F1ECFB] p-3 rounded-xl", children: [
|
2456
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-bold text-gray-900", children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: logo, className: "w-32", alt: "Coinley Logo" }) }) }),
|
2457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1653
2458
|
"button",
|
1654
2459
|
{
|
1655
|
-
onClick:
|
2460
|
+
onClick: onClose,
|
1656
2461
|
className: "text-gray-500 hover:text-gray-700 focus:outline-none",
|
1657
|
-
children: /* @__PURE__ */
|
2462
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
1658
2463
|
}
|
1659
2464
|
)
|
1660
2465
|
] }),
|
1661
|
-
/* @__PURE__ */
|
1662
|
-
|
1663
|
-
/* @__PURE__ */
|
2466
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6 bg-[#F1ECFB] p-3 rounded-xl", children: [
|
2467
|
+
payment && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6 p-4 rounded-lg", children: [
|
2468
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-lg text-gray-800 font-semibold", children: [
|
1664
2469
|
"PAY: ",
|
1665
|
-
|
2470
|
+
merchantName
|
1666
2471
|
] }),
|
1667
|
-
/* @__PURE__ */
|
1668
|
-
/* @__PURE__ */
|
1669
|
-
/* @__PURE__ */
|
2472
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mt-2 bg-gray-100 px-3 rounded-lg", children: [
|
2473
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-gray-700", children: "Amount:" }),
|
2474
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-bold text-xl text-[#7042D2]", children: [
|
1670
2475
|
"$",
|
1671
|
-
|
2476
|
+
formatAmount(payment.totalAmount || payment.amount)
|
1672
2477
|
] })
|
1673
2478
|
] }),
|
1674
|
-
/* @__PURE__ */
|
2479
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs mt-1 text-right", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-500", children: [
|
1675
2480
|
"Payment ID: ",
|
1676
|
-
|
2481
|
+
payment.id ? payment.id.slice(0, 8) : "",
|
1677
2482
|
"..."
|
1678
2483
|
] }) })
|
1679
2484
|
] }),
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
/* @__PURE__ */
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
2485
|
+
step === "select-currency" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2487
|
+
PaymentMethods,
|
2488
|
+
{
|
2489
|
+
onSelect: onPaymentMethodSelect,
|
2490
|
+
selected: selectedPaymentMethod,
|
2491
|
+
theme,
|
2492
|
+
supportedNetworks
|
2493
|
+
}
|
2494
|
+
),
|
2495
|
+
selectedPaymentMethod && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
2496
|
+
"button",
|
2497
|
+
{
|
2498
|
+
onClick: () => onPaymentMethodSelect(selectedPaymentMethod),
|
2499
|
+
className: "w-full py-3 px-4 bg-[#7042D2] hover:bg-[#7042D2] text-white font-medium rounded-lg transition-colors",
|
2500
|
+
children: [
|
2501
|
+
"Proceed with ",
|
2502
|
+
selectedPaymentMethod.currency,
|
2503
|
+
" on ",
|
2504
|
+
getNetworkDisplayName(selectedPaymentMethod.network)
|
2505
|
+
]
|
2506
|
+
}
|
2507
|
+
) })
|
2508
|
+
] }),
|
2509
|
+
step === "confirm" && selectedPaymentMethod && payment && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2510
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 rounded-lg mb-4 bg-gray-100", children: [
|
2511
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium mb-2 text-gray-800", children: "Payment Details" }),
|
2512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
2513
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
2514
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[#7042D2] font-semibold", children: "Currency:" }),
|
2515
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: selectedPaymentMethod.currency })
|
1696
2516
|
] }),
|
1697
|
-
/* @__PURE__ */
|
1698
|
-
/* @__PURE__ */
|
1699
|
-
/* @__PURE__ */
|
2517
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
2518
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[#7042D2] font-semibold", children: "Network:" }),
|
2519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: getNetworkDisplayName(selectedPaymentMethod.network) })
|
1700
2520
|
] }),
|
1701
|
-
/* @__PURE__ */
|
1702
|
-
/* @__PURE__ */
|
1703
|
-
/* @__PURE__ */
|
2521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
2522
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[#7042D2] font-semibold", children: "Fee:" }),
|
2523
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "1.75%" })
|
1704
2524
|
] })
|
1705
2525
|
] })
|
1706
2526
|
] }),
|
1707
|
-
|
2527
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex border-b border-gray-200", children: [
|
2528
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2529
|
+
"button",
|
2530
|
+
{
|
2531
|
+
onClick: () => setPaymentType("wallet"),
|
2532
|
+
className: `py-2 px-4 text-sm font-medium ${paymentType === "wallet" ? "border-b-2 border-[#7042D2] text-[#7042D2]" : "text-gray-500 hover:text-gray-700"}`,
|
2533
|
+
children: "Connect Wallet"
|
2534
|
+
}
|
2535
|
+
),
|
2536
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2537
|
+
"button",
|
2538
|
+
{
|
2539
|
+
onClick: () => setPaymentType("qrcode"),
|
2540
|
+
className: `py-2 px-4 text-sm font-medium ${paymentType === "qrcode" ? "border-b-2 border-[#7042D2] text-[#7042D2]" : "text-gray-500 hover:text-gray-700"}`,
|
2541
|
+
children: "QR Code"
|
2542
|
+
}
|
2543
|
+
)
|
2544
|
+
] }) }),
|
2545
|
+
testMode ? (
|
1708
2546
|
// Test mode payment option
|
1709
|
-
/* @__PURE__ */
|
1710
|
-
/* @__PURE__ */
|
1711
|
-
/* @__PURE__ */
|
1712
|
-
/* @__PURE__ */
|
1713
|
-
/* @__PURE__ */
|
2547
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 rounded-lg mb-4 bg-blue-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
|
2548
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-[#7042D2] rounded-full p-2 mr-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6 text-white", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 10V3L4 14h7v7l9-11h-7z" }) }) }),
|
2549
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2550
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-gray-800", children: "Test Mode Payment" }),
|
2551
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600", children: 'Click "Pay Now" to simulate a successful payment' })
|
1714
2552
|
] })
|
1715
2553
|
] }) })
|
2554
|
+
) : paymentType === "qrcode" ? (
|
2555
|
+
// QR Code payment option
|
2556
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2557
|
+
QRCode,
|
2558
|
+
{
|
2559
|
+
walletAddress: getWalletAddressForNetwork(),
|
2560
|
+
amount: payment.totalAmount || payment.amount,
|
2561
|
+
currency: selectedPaymentMethod.currency,
|
2562
|
+
network: selectedPaymentMethod.network,
|
2563
|
+
theme
|
2564
|
+
}
|
2565
|
+
) })
|
1716
2566
|
) : (
|
1717
|
-
//
|
1718
|
-
/* @__PURE__ */
|
1719
|
-
/* @__PURE__ */
|
1720
|
-
|
1721
|
-
/* @__PURE__ */
|
1722
|
-
|
1723
|
-
/* @__PURE__ */
|
1724
|
-
/* @__PURE__ */ a.jsxs("p", { className: "text-sm text-gray-600", children: [
|
2567
|
+
// Wallet connection option
|
2568
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 mb-4", children: [
|
2569
|
+
supportedWallets.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 rounded-lg bg-yellow-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
|
2570
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6 text-yellow-500 mr-2", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
2571
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-gray-800", children: "No Compatible Wallets" }),
|
2573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600", children: [
|
1725
2574
|
"No wallets detected for ",
|
1726
|
-
|
2575
|
+
getNetworkDisplayName(selectedPaymentMethod.network),
|
1727
2576
|
" network"
|
1728
2577
|
] })
|
1729
2578
|
] })
|
1730
|
-
] }) }) :
|
1731
|
-
/* @__PURE__ */
|
1732
|
-
/* @__PURE__ */
|
2579
|
+
] }) }) : supportedWallets.map((walletType) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 rounded-lg bg-blue-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
2580
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
|
2581
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1733
2582
|
"img",
|
1734
2583
|
{
|
1735
|
-
src:
|
1736
|
-
alt:
|
1737
|
-
className: "w-8 h-8 mr-
|
1738
|
-
onError: (
|
1739
|
-
|
2584
|
+
src: getWalletIcon(walletType),
|
2585
|
+
alt: getWalletDisplayName(walletType),
|
2586
|
+
className: "w-8 h-8 mr-3",
|
2587
|
+
onError: (e) => {
|
2588
|
+
e.target.style.display = "none";
|
1740
2589
|
}
|
1741
2590
|
}
|
1742
2591
|
),
|
1743
|
-
/* @__PURE__ */
|
1744
|
-
/* @__PURE__ */
|
1745
|
-
/* @__PURE__ */
|
2592
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2593
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-gray-800", children: getWalletDisplayName(walletType) }),
|
2594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600", children: [
|
1746
2595
|
"Pay with ",
|
1747
|
-
|
2596
|
+
getWalletDisplayName(walletType)
|
1748
2597
|
] })
|
1749
2598
|
] })
|
1750
2599
|
] }),
|
1751
|
-
(
|
1752
|
-
/* @__PURE__ */
|
1753
|
-
/* @__PURE__ */
|
1754
|
-
] }) : /* @__PURE__ */
|
2600
|
+
(walletConnection == null ? void 0 : walletConnection.walletType) === walletType ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
|
2601
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }),
|
2602
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-green-600", children: "Connected" })
|
2603
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
1755
2604
|
"button",
|
1756
2605
|
{
|
1757
|
-
onClick: () =>
|
1758
|
-
className: "py-2 px-4 bg-[#7042D2] hover:bg-[#7042D2] text-white font-medium rounded-md",
|
2606
|
+
onClick: () => onConnectWallet(walletType),
|
2607
|
+
className: "py-2 px-4 bg-[#7042D2] hover:bg-[#7042D2] text-white font-medium rounded-md text-sm",
|
1759
2608
|
children: "Connect"
|
1760
2609
|
}
|
1761
2610
|
)
|
1762
|
-
] }) },
|
1763
|
-
/* @__PURE__ */
|
1764
|
-
/* @__PURE__ */
|
1765
|
-
|
2611
|
+
] }) }, walletType)),
|
2612
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: Object.entries(availableWallets).filter(([walletType, isAvailable]) => !isAvailable).map(([walletType]) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 rounded-lg bg-gray-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
2613
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-600", children: [
|
2614
|
+
getWalletDisplayName(walletType),
|
1766
2615
|
" not detected"
|
1767
2616
|
] }),
|
1768
|
-
/* @__PURE__ */
|
2617
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1769
2618
|
"a",
|
1770
2619
|
{
|
1771
|
-
href:
|
2620
|
+
href: getWalletInstallUrl(walletType),
|
1772
2621
|
target: "_blank",
|
1773
2622
|
rel: "noopener noreferrer",
|
1774
2623
|
className: "text-sm text-[#7042D2] hover:underline",
|
1775
2624
|
children: "Install"
|
1776
2625
|
}
|
1777
2626
|
)
|
1778
|
-
] }) },
|
2627
|
+
] }) }, walletType)) })
|
1779
2628
|
] })
|
1780
2629
|
),
|
1781
|
-
/* @__PURE__ */
|
1782
|
-
/* @__PURE__ */
|
2630
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
|
2631
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1783
2632
|
"button",
|
1784
2633
|
{
|
1785
2634
|
type: "button",
|
1786
|
-
onClick:
|
2635
|
+
onClick: onBack,
|
1787
2636
|
className: "w-full py-2 px-4 bg-gray-200 hover:bg-gray-300 text-[#7042D2] font-medium rounded-md",
|
1788
2637
|
children: "Back"
|
1789
2638
|
}
|
1790
2639
|
),
|
1791
|
-
/* @__PURE__ */
|
2640
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1792
2641
|
"button",
|
1793
2642
|
{
|
1794
2643
|
type: "button",
|
1795
|
-
onClick:
|
2644
|
+
onClick: () => onPayment(paymentType === "qrcode"),
|
1796
2645
|
className: "w-full py-2 px-4 bg-[#7042D2] hover:bg-[#7042D2] text-white font-medium rounded-md",
|
1797
|
-
disabled: !
|
1798
|
-
children: "Pay Now"
|
2646
|
+
disabled: !testMode && paymentType === "wallet" && !walletConnection,
|
2647
|
+
children: paymentType === "qrcode" ? "I have sent the payment" : "Pay Now"
|
1799
2648
|
}
|
1800
2649
|
)
|
1801
2650
|
] })
|
1802
2651
|
] }),
|
1803
|
-
|
1804
|
-
|
2652
|
+
step === "processing" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2653
|
+
PaymentStatus,
|
1805
2654
|
{
|
1806
2655
|
status: "processing",
|
1807
|
-
theme
|
2656
|
+
theme,
|
1808
2657
|
message: "Processing your payment..."
|
1809
2658
|
}
|
1810
2659
|
),
|
1811
|
-
|
1812
|
-
/* @__PURE__ */
|
1813
|
-
|
2660
|
+
step === "success" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2661
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2662
|
+
PaymentStatus,
|
1814
2663
|
{
|
1815
2664
|
status: "success",
|
1816
|
-
theme
|
2665
|
+
theme,
|
1817
2666
|
message: "Payment successful!"
|
1818
2667
|
}
|
1819
2668
|
),
|
1820
|
-
|
1821
|
-
/* @__PURE__ */
|
1822
|
-
/* @__PURE__ */
|
1823
|
-
|
2669
|
+
transactionHash && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 p-3 rounded-lg bg-gray-100", children: [
|
2670
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 mb-1", children: "Transaction Hash:" }),
|
2671
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-mono break-all text-gray-800", children: formatTransactionHash(transactionHash) }),
|
2672
|
+
selectedPaymentMethod && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
1824
2673
|
"a",
|
1825
2674
|
{
|
1826
|
-
href: `${
|
2675
|
+
href: `${getExplorerUrl(selectedPaymentMethod.network)}/${getExplorerPath(selectedPaymentMethod.network)}/${transactionHash}`,
|
1827
2676
|
target: "_blank",
|
1828
2677
|
rel: "noopener noreferrer",
|
1829
2678
|
className: "text-xs text-[#7042D2] mt-2 inline-block",
|
@@ -1832,220 +2681,305 @@ const Vt = ({
|
|
1832
2681
|
)
|
1833
2682
|
] })
|
1834
2683
|
] }),
|
1835
|
-
|
1836
|
-
/* @__PURE__ */
|
1837
|
-
|
2684
|
+
step === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
2685
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
2686
|
+
PaymentStatus,
|
1838
2687
|
{
|
1839
2688
|
status: "error",
|
1840
|
-
theme
|
1841
|
-
message:
|
2689
|
+
theme,
|
2690
|
+
message: error || "An error occurred while processing your payment."
|
1842
2691
|
}
|
1843
2692
|
),
|
1844
|
-
/* @__PURE__ */
|
2693
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
1845
2694
|
"button",
|
1846
2695
|
{
|
1847
2696
|
type: "button",
|
1848
|
-
onClick:
|
2697
|
+
onClick: onBack,
|
1849
2698
|
className: "mt-4 w-full py-2 px-4 bg-gray-200 hover:bg-gray-300 text-gray-800 font-medium rounded-md",
|
1850
2699
|
children: "Try Again"
|
1851
2700
|
}
|
1852
2701
|
)
|
1853
2702
|
] })
|
1854
2703
|
] }),
|
1855
|
-
/* @__PURE__ */
|
2704
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-xs text-gray-500", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
1856
2705
|
"Powered by ",
|
1857
|
-
/* @__PURE__ */
|
2706
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[#7042D2]", children: "Coinley" }),
|
1858
2707
|
" - Secure Cryptocurrency Payments"
|
1859
2708
|
] }) })
|
1860
|
-
] }) }) })
|
1861
|
-
}
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
2709
|
+
] }) }) });
|
2710
|
+
};
|
2711
|
+
const getExplorerUrl = (network) => {
|
2712
|
+
const explorers = {
|
2713
|
+
ethereum: "https://etherscan.io",
|
2714
|
+
bsc: "https://bscscan.com",
|
2715
|
+
tron: "https://tronscan.org",
|
2716
|
+
algorand: "https://algoexplorer.io"
|
2717
|
+
};
|
2718
|
+
return explorers[network] || "https://etherscan.io";
|
2719
|
+
};
|
2720
|
+
const getExplorerPath = (network) => {
|
2721
|
+
const paths = {
|
2722
|
+
ethereum: "tx",
|
2723
|
+
bsc: "tx",
|
2724
|
+
tron: "transaction",
|
2725
|
+
algorand: "tx"
|
2726
|
+
};
|
2727
|
+
return paths[network] || "tx";
|
2728
|
+
};
|
2729
|
+
const CoinleyCheckout = forwardRef(({
|
2730
|
+
apiKey,
|
2731
|
+
apiSecret,
|
2732
|
+
apiUrl,
|
2733
|
+
customerEmail,
|
2734
|
+
merchantName = "Merchant",
|
2735
|
+
merchantWalletAddresses = {},
|
1873
2736
|
// Object with network-specific addresses
|
1874
|
-
onSuccess
|
1875
|
-
onError
|
1876
|
-
onClose
|
1877
|
-
theme
|
1878
|
-
autoOpen
|
1879
|
-
debug
|
1880
|
-
testMode
|
1881
|
-
supportedNetworks
|
2737
|
+
onSuccess,
|
2738
|
+
onError,
|
2739
|
+
onClose,
|
2740
|
+
theme,
|
2741
|
+
autoOpen = false,
|
2742
|
+
debug = false,
|
2743
|
+
testMode = false,
|
2744
|
+
supportedNetworks = [],
|
1882
2745
|
// Array of supported networks
|
1883
|
-
preferredNetwork
|
1884
|
-
preferredWallet
|
1885
|
-
},
|
1886
|
-
const
|
1887
|
-
|
1888
|
-
const
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
2746
|
+
preferredNetwork = NETWORK_TYPES.ETHEREUM,
|
2747
|
+
preferredWallet = WALLET_TYPES.METAMASK
|
2748
|
+
}, ref) => {
|
2749
|
+
const coinleyContext = useCoinley();
|
2750
|
+
const { theme: contextTheme } = useTheme();
|
2751
|
+
const [isOpen, setIsOpen] = useState(autoOpen);
|
2752
|
+
const [payment, setPayment] = useState(null);
|
2753
|
+
const [paymentStatus, setPaymentStatus] = useState("idle");
|
2754
|
+
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(null);
|
2755
|
+
const [error, setError] = useState(null);
|
2756
|
+
const [transactionHash, setTransactionHash] = useState(null);
|
2757
|
+
const [walletConnection, setWalletConnection] = useState(null);
|
2758
|
+
const [availableWallets, setAvailableWallets] = useState({});
|
2759
|
+
const [step, setStep] = useState("select-currency");
|
2760
|
+
apiKey || (coinleyContext == null ? void 0 : coinleyContext.apiKey);
|
2761
|
+
apiSecret || (coinleyContext == null ? void 0 : coinleyContext.apiSecret);
|
2762
|
+
apiUrl || (coinleyContext == null ? void 0 : coinleyContext.apiUrl);
|
2763
|
+
const effectiveTheme = theme || contextTheme;
|
2764
|
+
const effectiveDebug = debug || (coinleyContext == null ? void 0 : coinleyContext.debug);
|
2765
|
+
const effectiveSupportedNetworks = supportedNetworks.length > 0 ? supportedNetworks : [NETWORK_TYPES.ETHEREUM, NETWORK_TYPES.BSC, NETWORK_TYPES.TRON, NETWORK_TYPES.ALGORAND];
|
2766
|
+
useImperativeHandle(ref, () => ({
|
2767
|
+
open: (paymentDetails) => {
|
2768
|
+
handleOpen(paymentDetails);
|
1892
2769
|
},
|
1893
2770
|
close: () => {
|
1894
|
-
|
2771
|
+
handleClose();
|
1895
2772
|
},
|
1896
|
-
getPayment: () =>
|
1897
|
-
getWalletConnection: () =>
|
2773
|
+
getPayment: () => payment,
|
2774
|
+
getWalletConnection: () => walletConnection
|
1898
2775
|
}));
|
1899
|
-
const
|
1900
|
-
|
2776
|
+
const log = (message, data) => {
|
2777
|
+
if (effectiveDebug) {
|
2778
|
+
console.log(`[Coinley SDK] ${message}`, data);
|
2779
|
+
}
|
1901
2780
|
};
|
1902
|
-
|
1903
|
-
if (typeof window
|
1904
|
-
const
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
2781
|
+
useEffect(() => {
|
2782
|
+
if (typeof window !== "undefined") {
|
2783
|
+
const wallets = detectWallets();
|
2784
|
+
setAvailableWallets(wallets);
|
2785
|
+
log("Available wallets detected:", wallets);
|
2786
|
+
}
|
2787
|
+
}, [effectiveDebug]);
|
2788
|
+
const handleOpen = (paymentDetails) => __async(void 0, null, function* () {
|
2789
|
+
if (!paymentDetails || !paymentDetails.amount) {
|
2790
|
+
setError("Payment amount is required");
|
2791
|
+
if (onError)
|
2792
|
+
onError(new Error("Payment amount is required"));
|
1911
2793
|
return;
|
1912
2794
|
}
|
1913
|
-
|
2795
|
+
setPaymentStatus("loading");
|
2796
|
+
setIsOpen(true);
|
2797
|
+
setStep("select-currency");
|
1914
2798
|
try {
|
1915
|
-
|
1916
|
-
const
|
1917
|
-
amount:
|
1918
|
-
currency:
|
1919
|
-
network:
|
1920
|
-
customerEmail:
|
1921
|
-
callbackUrl:
|
1922
|
-
metadata:
|
1923
|
-
merchantWalletAddresses:
|
2799
|
+
log("Creating payment with details:", paymentDetails);
|
2800
|
+
const paymentResponse = yield createPayment({
|
2801
|
+
amount: paymentDetails.amount,
|
2802
|
+
currency: paymentDetails.currency || "USDT",
|
2803
|
+
network: paymentDetails.network || preferredNetwork,
|
2804
|
+
customerEmail: paymentDetails.customerEmail || customerEmail,
|
2805
|
+
callbackUrl: paymentDetails.callbackUrl,
|
2806
|
+
metadata: paymentDetails.metadata || {},
|
2807
|
+
merchantWalletAddresses: __spreadValues(__spreadValues({}, merchantWalletAddresses), paymentDetails.merchantWalletAddresses)
|
1924
2808
|
});
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
2809
|
+
log("Payment created:", paymentResponse);
|
2810
|
+
setPayment(paymentResponse.payment);
|
2811
|
+
setPaymentStatus("idle");
|
2812
|
+
setError(null);
|
2813
|
+
log("Payment created and state updated");
|
2814
|
+
} catch (err) {
|
2815
|
+
log("Error creating payment:", err);
|
2816
|
+
setError(err.message || "Failed to create payment");
|
2817
|
+
setPaymentStatus("error");
|
2818
|
+
if (onError)
|
2819
|
+
onError(err);
|
2820
|
+
}
|
2821
|
+
});
|
2822
|
+
const handleClose = () => {
|
2823
|
+
setIsOpen(false);
|
2824
|
+
setTransactionHash(null);
|
2825
|
+
setWalletConnection(null);
|
2826
|
+
setSelectedPaymentMethod(null);
|
2827
|
+
setStep("select-currency");
|
2828
|
+
if (onClose)
|
2829
|
+
onClose();
|
2830
|
+
};
|
2831
|
+
const handlePaymentMethodSelect = (paymentMethod) => {
|
2832
|
+
log("Payment method selected:", paymentMethod);
|
2833
|
+
setSelectedPaymentMethod(paymentMethod);
|
2834
|
+
setStep("confirm");
|
2835
|
+
};
|
2836
|
+
const handleBack = () => {
|
2837
|
+
if (step === "confirm") {
|
2838
|
+
setStep("select-currency");
|
2839
|
+
setWalletConnection(null);
|
2840
|
+
}
|
2841
|
+
};
|
2842
|
+
const handleConnectWallet = (walletType) => __async(void 0, null, function* () {
|
2843
|
+
if (!selectedPaymentMethod) {
|
2844
|
+
setError("Please select a payment method first");
|
1938
2845
|
return;
|
1939
2846
|
}
|
1940
2847
|
try {
|
1941
|
-
|
1942
|
-
const
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
}
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
2848
|
+
log("Connecting wallet:", { walletType, network: selectedPaymentMethod.network });
|
2849
|
+
const connection = yield connectWallet(walletType, selectedPaymentMethod.network);
|
2850
|
+
setWalletConnection(connection);
|
2851
|
+
setError(null);
|
2852
|
+
log("Wallet connected successfully:", connection);
|
2853
|
+
} catch (err) {
|
2854
|
+
log("Wallet connection error:", err);
|
2855
|
+
setError(err.message || "Failed to connect wallet");
|
2856
|
+
}
|
2857
|
+
});
|
2858
|
+
const handlePayment = () => __async(void 0, null, function* () {
|
2859
|
+
var _a, _b;
|
2860
|
+
if (!payment || !selectedPaymentMethod) {
|
2861
|
+
setError("Missing payment information");
|
1951
2862
|
return;
|
1952
2863
|
}
|
1953
|
-
if (!
|
1954
|
-
|
2864
|
+
if (!walletConnection && !testMode) {
|
2865
|
+
setError("Please connect your wallet first");
|
1955
2866
|
return;
|
1956
2867
|
}
|
1957
|
-
|
2868
|
+
log("Starting payment process...");
|
2869
|
+
setPaymentStatus("loading");
|
2870
|
+
setTransactionHash(null);
|
1958
2871
|
try {
|
1959
|
-
let
|
1960
|
-
if (
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
2872
|
+
let txHash;
|
2873
|
+
if (testMode) {
|
2874
|
+
log("Test mode: Generating mock transaction...");
|
2875
|
+
txHash = `test_${Date.now().toString(16)}_${Math.random().toString(16).substring(2, 10)}`;
|
2876
|
+
} else {
|
2877
|
+
const merchantAddress = merchantWalletAddresses[selectedPaymentMethod.network];
|
2878
|
+
if (!merchantAddress) {
|
2879
|
+
throw new Error(`No merchant wallet address configured for ${selectedPaymentMethod.network}`);
|
2880
|
+
}
|
2881
|
+
log("Sending transaction through wallet...");
|
2882
|
+
txHash = yield sendTransaction(walletConnection, {
|
2883
|
+
to: merchantAddress,
|
2884
|
+
amount: payment.amount,
|
2885
|
+
tokenAddress: (_a = selectedPaymentMethod.tokenConfig) == null ? void 0 : _a.address,
|
2886
|
+
tokenDecimals: (_b = selectedPaymentMethod.tokenConfig) == null ? void 0 : _b.decimals
|
1971
2887
|
});
|
1972
2888
|
}
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
2889
|
+
log("Transaction hash:", txHash);
|
2890
|
+
setTransactionHash(txHash);
|
2891
|
+
log("Processing payment with backend...");
|
2892
|
+
const processResponse = yield processPayment({
|
2893
|
+
paymentId: payment.id,
|
2894
|
+
transactionHash: txHash,
|
2895
|
+
network: selectedPaymentMethod.network,
|
2896
|
+
currency: selectedPaymentMethod.currency,
|
2897
|
+
senderAddress: walletConnection == null ? void 0 : walletConnection.address
|
1980
2898
|
});
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
2899
|
+
log("Payment processed successfully:", processResponse);
|
2900
|
+
setPaymentStatus("success");
|
2901
|
+
setStep("success");
|
2902
|
+
if (onSuccess) {
|
2903
|
+
log("Calling onSuccess callback...");
|
2904
|
+
onSuccess(payment.id, txHash, {
|
2905
|
+
network: selectedPaymentMethod.network,
|
2906
|
+
currency: selectedPaymentMethod.currency,
|
2907
|
+
amount: payment.amount
|
2908
|
+
});
|
2909
|
+
}
|
2910
|
+
} catch (err) {
|
2911
|
+
log("Payment error:", err);
|
2912
|
+
setError(err.message || "Failed to process payment");
|
2913
|
+
setPaymentStatus("error");
|
2914
|
+
setStep("error");
|
2915
|
+
if (onError)
|
2916
|
+
onError(err);
|
2917
|
+
}
|
2918
|
+
});
|
2919
|
+
const getSupportedWallets = () => {
|
2920
|
+
if (!selectedPaymentMethod)
|
2921
|
+
return [];
|
2922
|
+
return getSupportedWalletsForNetwork(selectedPaymentMethod.network);
|
2923
|
+
};
|
2924
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: isOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
2925
|
+
CoinleyModal,
|
1992
2926
|
{
|
1993
|
-
isOpen
|
1994
|
-
onClose:
|
1995
|
-
payment
|
1996
|
-
paymentStatus
|
1997
|
-
selectedPaymentMethod
|
1998
|
-
onPaymentMethodSelect:
|
1999
|
-
onPayment:
|
2000
|
-
onBack:
|
2001
|
-
error
|
2002
|
-
theme:
|
2003
|
-
merchantName
|
2004
|
-
transactionHash
|
2005
|
-
walletConnection
|
2006
|
-
onConnectWallet:
|
2007
|
-
testMode
|
2008
|
-
supportedNetworks:
|
2009
|
-
availableWallets
|
2010
|
-
supportedWallets:
|
2011
|
-
step
|
2927
|
+
isOpen,
|
2928
|
+
onClose: handleClose,
|
2929
|
+
payment,
|
2930
|
+
paymentStatus,
|
2931
|
+
selectedPaymentMethod,
|
2932
|
+
onPaymentMethodSelect: handlePaymentMethodSelect,
|
2933
|
+
onPayment: handlePayment,
|
2934
|
+
onBack: handleBack,
|
2935
|
+
error,
|
2936
|
+
theme: effectiveTheme,
|
2937
|
+
merchantName,
|
2938
|
+
transactionHash,
|
2939
|
+
walletConnection,
|
2940
|
+
onConnectWallet: handleConnectWallet,
|
2941
|
+
testMode,
|
2942
|
+
supportedNetworks: effectiveSupportedNetworks,
|
2943
|
+
availableWallets,
|
2944
|
+
supportedWallets: getSupportedWallets(),
|
2945
|
+
step,
|
2946
|
+
merchantWalletAddresses
|
2012
2947
|
}
|
2013
2948
|
) });
|
2014
2949
|
});
|
2015
|
-
|
2016
|
-
const
|
2950
|
+
CoinleyCheckout.displayName = "CoinleyCheckout";
|
2951
|
+
const DEFAULT_CONFIG = {
|
2017
2952
|
apiUrl: "http://localhost:9000",
|
2018
|
-
debug:
|
2019
|
-
testMode:
|
2953
|
+
debug: false,
|
2954
|
+
testMode: false,
|
2020
2955
|
theme: "light",
|
2021
2956
|
supportedNetworks: ["ethereum", "bsc", "tron", "algorand"]
|
2022
|
-
}
|
2957
|
+
};
|
2023
2958
|
export {
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
Wt as validateWalletAddress
|
2959
|
+
CoinleyCheckout,
|
2960
|
+
CoinleyModal,
|
2961
|
+
CoinleyProvider,
|
2962
|
+
DEFAULT_CONFIG,
|
2963
|
+
NETWORK_CONFIG,
|
2964
|
+
NETWORK_TYPES,
|
2965
|
+
PaymentMethods,
|
2966
|
+
PaymentStatus,
|
2967
|
+
QRCode,
|
2968
|
+
TOKEN_CONFIG,
|
2969
|
+
ThemeProvider,
|
2970
|
+
WALLET_TYPES,
|
2971
|
+
connectWallet,
|
2972
|
+
createPayment,
|
2973
|
+
detectWallets,
|
2974
|
+
generateMockTransactionHash,
|
2975
|
+
getMerchantProfile,
|
2976
|
+
getPayment,
|
2977
|
+
getSupportedNetworks,
|
2978
|
+
getSupportedWalletsForNetwork,
|
2979
|
+
getWalletInstallUrl,
|
2980
|
+
processPayment,
|
2981
|
+
sendTransaction,
|
2982
|
+
useCoinley,
|
2983
|
+
validateWalletAddress
|
2050
2984
|
};
|
2051
2985
|
//# sourceMappingURL=coinley-checkout.es.js.map
|