coinley-test 0.0.20 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +519 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1237,7 +1237,523 @@ const ThemeProvider = ({
|
|
|
1237
1237
|
}, [theme]);
|
|
1238
1238
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `coinley-theme-${theme}`, children });
|
|
1239
1239
|
};
|
|
1240
|
-
|
|
1240
|
+
class SimplePaymentAPI {
|
|
1241
|
+
constructor(baseURL, apiKey, apiSecret) {
|
|
1242
|
+
this.baseURL = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
1243
|
+
this.apiKey = apiKey;
|
|
1244
|
+
this.apiSecret = apiSecret;
|
|
1245
|
+
}
|
|
1246
|
+
async request(endpoint, options = {}) {
|
|
1247
|
+
const url = `${this.baseURL}${endpoint}`;
|
|
1248
|
+
const headers = {
|
|
1249
|
+
"Content-Type": "application/json",
|
|
1250
|
+
"X-API-Key": this.apiKey,
|
|
1251
|
+
"X-API-Secret": this.apiSecret,
|
|
1252
|
+
...options.headers
|
|
1253
|
+
};
|
|
1254
|
+
const response = await fetch(url, {
|
|
1255
|
+
...options,
|
|
1256
|
+
headers
|
|
1257
|
+
});
|
|
1258
|
+
if (!response.ok) {
|
|
1259
|
+
const error = await response.json().catch(() => ({}));
|
|
1260
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
1261
|
+
}
|
|
1262
|
+
return response.json();
|
|
1263
|
+
}
|
|
1264
|
+
async getNetworks() {
|
|
1265
|
+
try {
|
|
1266
|
+
return await this.request("/api/networks");
|
|
1267
|
+
} catch (error) {
|
|
1268
|
+
console.error("Failed to fetch networks:", error);
|
|
1269
|
+
return {
|
|
1270
|
+
networks: [
|
|
1271
|
+
{ id: "1", name: "Ethereum", shortName: "ethereum", chainId: "0x1", type: "ethereum" },
|
|
1272
|
+
{ id: "56", name: "BSC", shortName: "bsc", chainId: "0x38", type: "bsc" }
|
|
1273
|
+
]
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
async getTokens() {
|
|
1278
|
+
try {
|
|
1279
|
+
return await this.request("/api/networks/stablecoins");
|
|
1280
|
+
} catch (error) {
|
|
1281
|
+
console.error("Failed to fetch tokens:", error);
|
|
1282
|
+
return {
|
|
1283
|
+
stablecoins: [
|
|
1284
|
+
{
|
|
1285
|
+
id: "1",
|
|
1286
|
+
name: "Tether USD",
|
|
1287
|
+
symbol: "USDT",
|
|
1288
|
+
contractAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
1289
|
+
decimals: 6,
|
|
1290
|
+
networkId: "1",
|
|
1291
|
+
Network: { shortName: "ethereum", name: "Ethereum" }
|
|
1292
|
+
}
|
|
1293
|
+
]
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
async createPayment(data) {
|
|
1298
|
+
return await this.request("/api/payments/create", {
|
|
1299
|
+
method: "POST",
|
|
1300
|
+
body: JSON.stringify(data)
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
class SimpleMetaMaskWallet {
|
|
1305
|
+
constructor() {
|
|
1306
|
+
this.account = null;
|
|
1307
|
+
this.chainId = null;
|
|
1308
|
+
}
|
|
1309
|
+
async connect() {
|
|
1310
|
+
if (!window.ethereum) {
|
|
1311
|
+
throw new Error("MetaMask not installed. Please install MetaMask extension.");
|
|
1312
|
+
}
|
|
1313
|
+
try {
|
|
1314
|
+
const accounts = await window.ethereum.request({
|
|
1315
|
+
method: "eth_requestAccounts"
|
|
1316
|
+
});
|
|
1317
|
+
const chainId = await window.ethereum.request({
|
|
1318
|
+
method: "eth_chainId"
|
|
1319
|
+
});
|
|
1320
|
+
this.account = accounts[0];
|
|
1321
|
+
this.chainId = chainId;
|
|
1322
|
+
console.log("✅ MetaMask connected:", this.account);
|
|
1323
|
+
return { account: this.account, chainId: this.chainId };
|
|
1324
|
+
} catch (error) {
|
|
1325
|
+
console.error("MetaMask connection failed:", error);
|
|
1326
|
+
throw new Error(error.message || "Failed to connect to MetaMask");
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
async sendTransaction(txParams) {
|
|
1330
|
+
if (!this.account) {
|
|
1331
|
+
throw new Error("Wallet not connected");
|
|
1332
|
+
}
|
|
1333
|
+
try {
|
|
1334
|
+
console.log("🦊 Sending MetaMask transaction:", txParams);
|
|
1335
|
+
const txHash = await window.ethereum.request({
|
|
1336
|
+
method: "eth_sendTransaction",
|
|
1337
|
+
params: [{
|
|
1338
|
+
...txParams,
|
|
1339
|
+
from: this.account
|
|
1340
|
+
}]
|
|
1341
|
+
});
|
|
1342
|
+
console.log("✅ Transaction sent:", txHash);
|
|
1343
|
+
return txHash;
|
|
1344
|
+
} catch (error) {
|
|
1345
|
+
console.error("Transaction failed:", error);
|
|
1346
|
+
if (error.code === 4001) {
|
|
1347
|
+
throw new Error("Transaction cancelled by user");
|
|
1348
|
+
} else if (error.message.includes("insufficient funds")) {
|
|
1349
|
+
throw new Error("Insufficient funds in wallet");
|
|
1350
|
+
} else {
|
|
1351
|
+
throw new Error(error.message || "Transaction failed");
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
isConnected() {
|
|
1356
|
+
return !!this.account;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
const SimpleCoinleyPayment = ({
|
|
1360
|
+
apiKey,
|
|
1361
|
+
apiSecret,
|
|
1362
|
+
apiUrl,
|
|
1363
|
+
config,
|
|
1364
|
+
onSuccess,
|
|
1365
|
+
onError,
|
|
1366
|
+
onClose,
|
|
1367
|
+
isOpen,
|
|
1368
|
+
theme = "light"
|
|
1369
|
+
}) => {
|
|
1370
|
+
var _a, _b;
|
|
1371
|
+
const [currentStep, setCurrentStep] = useState("method");
|
|
1372
|
+
const [networks, setNetworks] = useState([]);
|
|
1373
|
+
const [tokens, setTokens] = useState([]);
|
|
1374
|
+
const [selectedNetwork, setSelectedNetwork] = useState(null);
|
|
1375
|
+
const [selectedToken, setSelectedToken] = useState(null);
|
|
1376
|
+
const [paymentMethod, setPaymentMethod] = useState(null);
|
|
1377
|
+
const [paymentData, setPaymentData] = useState(null);
|
|
1378
|
+
const [loading, setLoading] = useState(false);
|
|
1379
|
+
const [error, setError] = useState("");
|
|
1380
|
+
const [wallet, setWallet] = useState(new SimpleMetaMaskWallet());
|
|
1381
|
+
const [walletConnected, setWalletConnected] = useState(false);
|
|
1382
|
+
const [processing, setProcessing] = useState(false);
|
|
1383
|
+
const api = useRef(new SimplePaymentAPI(apiUrl, apiKey, apiSecret));
|
|
1384
|
+
useEffect(() => {
|
|
1385
|
+
if (isOpen) {
|
|
1386
|
+
loadData();
|
|
1387
|
+
resetState();
|
|
1388
|
+
}
|
|
1389
|
+
}, [isOpen]);
|
|
1390
|
+
const resetState = () => {
|
|
1391
|
+
setCurrentStep("method");
|
|
1392
|
+
setSelectedNetwork(null);
|
|
1393
|
+
setSelectedToken(null);
|
|
1394
|
+
setPaymentMethod(null);
|
|
1395
|
+
setPaymentData(null);
|
|
1396
|
+
setError("");
|
|
1397
|
+
setWalletConnected(false);
|
|
1398
|
+
setProcessing(false);
|
|
1399
|
+
setWallet(new SimpleMetaMaskWallet());
|
|
1400
|
+
};
|
|
1401
|
+
const loadData = async () => {
|
|
1402
|
+
var _a2, _b2;
|
|
1403
|
+
try {
|
|
1404
|
+
setLoading(true);
|
|
1405
|
+
setError("");
|
|
1406
|
+
console.log("🔄 Loading networks and tokens...");
|
|
1407
|
+
const [networksRes, tokensRes] = await Promise.all([
|
|
1408
|
+
api.current.getNetworks(),
|
|
1409
|
+
api.current.getTokens()
|
|
1410
|
+
]);
|
|
1411
|
+
setNetworks(networksRes.networks || []);
|
|
1412
|
+
setTokens(tokensRes.stablecoins || []);
|
|
1413
|
+
console.log("✅ Loaded networks:", (_a2 = networksRes.networks) == null ? void 0 : _a2.length);
|
|
1414
|
+
console.log("✅ Loaded tokens:", (_b2 = tokensRes.stablecoins) == null ? void 0 : _b2.length);
|
|
1415
|
+
} catch (err) {
|
|
1416
|
+
console.error("Failed to load data:", err);
|
|
1417
|
+
setError("Failed to load payment options. Using fallback data.");
|
|
1418
|
+
} finally {
|
|
1419
|
+
setLoading(false);
|
|
1420
|
+
}
|
|
1421
|
+
};
|
|
1422
|
+
const connectWallet = async () => {
|
|
1423
|
+
try {
|
|
1424
|
+
setLoading(true);
|
|
1425
|
+
setError("");
|
|
1426
|
+
const connection = await wallet.connect();
|
|
1427
|
+
setWalletConnected(true);
|
|
1428
|
+
console.log("✅ Wallet connected successfully:", connection.account);
|
|
1429
|
+
} catch (err) {
|
|
1430
|
+
console.error("Wallet connection failed:", err);
|
|
1431
|
+
setError(err.message);
|
|
1432
|
+
} finally {
|
|
1433
|
+
setLoading(false);
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
const createPayment = async () => {
|
|
1437
|
+
try {
|
|
1438
|
+
setLoading(true);
|
|
1439
|
+
setError("");
|
|
1440
|
+
const paymentPayload = {
|
|
1441
|
+
amount: config.amount,
|
|
1442
|
+
currency: selectedToken.symbol,
|
|
1443
|
+
network: selectedNetwork.shortName,
|
|
1444
|
+
customerEmail: config.customerEmail,
|
|
1445
|
+
callbackUrl: config.callbackUrl,
|
|
1446
|
+
metadata: {
|
|
1447
|
+
...config.metadata,
|
|
1448
|
+
merchantWalletAddresses: config.merchantWalletAddresses,
|
|
1449
|
+
paymentMethod,
|
|
1450
|
+
selectedNetwork: selectedNetwork.shortName,
|
|
1451
|
+
selectedToken: selectedToken.symbol
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
console.log("🔄 Creating payment:", paymentPayload);
|
|
1455
|
+
const payment = await api.current.createPayment(paymentPayload);
|
|
1456
|
+
setPaymentData(payment.payment);
|
|
1457
|
+
console.log("✅ Payment created:", payment.payment.id);
|
|
1458
|
+
if (paymentMethod === "wallet") {
|
|
1459
|
+
setCurrentStep("wallet");
|
|
1460
|
+
} else {
|
|
1461
|
+
setCurrentStep("qr");
|
|
1462
|
+
}
|
|
1463
|
+
} catch (err) {
|
|
1464
|
+
console.error("Payment creation failed:", err);
|
|
1465
|
+
setError(err.message);
|
|
1466
|
+
} finally {
|
|
1467
|
+
setLoading(false);
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
const sendTransaction = async () => {
|
|
1471
|
+
var _a2, _b2;
|
|
1472
|
+
try {
|
|
1473
|
+
setProcessing(true);
|
|
1474
|
+
setError("");
|
|
1475
|
+
const recipientAddress = ((_a2 = paymentData.metadata) == null ? void 0 : _a2.recipientWallet) || ((_b2 = config.merchantWalletAddresses) == null ? void 0 : _b2[selectedNetwork.shortName]);
|
|
1476
|
+
if (!recipientAddress) {
|
|
1477
|
+
throw new Error("Merchant wallet address not found");
|
|
1478
|
+
}
|
|
1479
|
+
console.log("🔄 Preparing transaction to:", recipientAddress);
|
|
1480
|
+
let txParams;
|
|
1481
|
+
if (selectedToken.contractAddress) {
|
|
1482
|
+
const decimals = selectedToken.decimals || 6;
|
|
1483
|
+
const amount = Math.floor(paymentData.totalAmount * Math.pow(10, decimals));
|
|
1484
|
+
const methodId = "0xa9059cbb";
|
|
1485
|
+
const recipientPadded = recipientAddress.slice(2).toLowerCase().padStart(64, "0");
|
|
1486
|
+
const amountPadded = amount.toString(16).padStart(64, "0");
|
|
1487
|
+
const data = `${methodId}${recipientPadded}${amountPadded}`;
|
|
1488
|
+
txParams = {
|
|
1489
|
+
to: selectedToken.contractAddress,
|
|
1490
|
+
data,
|
|
1491
|
+
value: "0x0"
|
|
1492
|
+
};
|
|
1493
|
+
console.log("🔄 ERC-20 Transaction:", {
|
|
1494
|
+
token: selectedToken.symbol,
|
|
1495
|
+
amount: paymentData.totalAmount,
|
|
1496
|
+
amountWithDecimals: amount,
|
|
1497
|
+
to: selectedToken.contractAddress,
|
|
1498
|
+
recipient: recipientAddress
|
|
1499
|
+
});
|
|
1500
|
+
} else {
|
|
1501
|
+
const value = Math.floor(paymentData.totalAmount * Math.pow(10, 18));
|
|
1502
|
+
txParams = {
|
|
1503
|
+
to: recipientAddress,
|
|
1504
|
+
value: `0x${value.toString(16)}`
|
|
1505
|
+
};
|
|
1506
|
+
console.log("🔄 Native Transaction:", {
|
|
1507
|
+
amount: paymentData.totalAmount,
|
|
1508
|
+
to: recipientAddress
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
const txHash = await wallet.sendTransaction(txParams);
|
|
1512
|
+
console.log("✅ Transaction successful:", txHash);
|
|
1513
|
+
setCurrentStep("success");
|
|
1514
|
+
onSuccess == null ? void 0 : onSuccess(paymentData.id, txHash, {
|
|
1515
|
+
network: selectedNetwork.name,
|
|
1516
|
+
token: selectedToken.symbol,
|
|
1517
|
+
amount: paymentData.totalAmount,
|
|
1518
|
+
method: paymentMethod
|
|
1519
|
+
});
|
|
1520
|
+
} catch (err) {
|
|
1521
|
+
console.error("Transaction failed:", err);
|
|
1522
|
+
setError(err.message);
|
|
1523
|
+
} finally {
|
|
1524
|
+
setProcessing(false);
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
if (!isOpen) return null;
|
|
1528
|
+
const isDark = theme === "dark";
|
|
1529
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `rounded-lg shadow-xl max-w-md w-full mx-4 ${isDark ? "bg-gray-900 text-white" : "bg-white text-gray-900"}`, children: [
|
|
1530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `p-4 border-b flex justify-between items-center ${isDark ? "border-gray-700" : "border-gray-200"}`, children: [
|
|
1531
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center flex-1", children: [
|
|
1532
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold", children: "Pay with Crypto" }),
|
|
1533
|
+
config.amount && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-2xl font-bold text-purple-600", children: [
|
|
1534
|
+
"$",
|
|
1535
|
+
config.amount.toFixed(2)
|
|
1536
|
+
] })
|
|
1537
|
+
] }),
|
|
1538
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1539
|
+
"button",
|
|
1540
|
+
{
|
|
1541
|
+
onClick: onClose,
|
|
1542
|
+
className: `ml-4 text-gray-500 hover:text-gray-700 ${isDark ? "hover:text-gray-300" : ""}`,
|
|
1543
|
+
children: "✕"
|
|
1544
|
+
}
|
|
1545
|
+
)
|
|
1546
|
+
] }),
|
|
1547
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 min-h-[400px]", children: [
|
|
1548
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 p-3 bg-red-100 text-red-700 rounded border border-red-200", children: [
|
|
1549
|
+
error,
|
|
1550
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1551
|
+
"button",
|
|
1552
|
+
{
|
|
1553
|
+
onClick: () => setError(""),
|
|
1554
|
+
className: "ml-2 text-red-500 hover:text-red-700",
|
|
1555
|
+
children: "✕"
|
|
1556
|
+
}
|
|
1557
|
+
)
|
|
1558
|
+
] }),
|
|
1559
|
+
currentStep === "method" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
1560
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-center mb-6", children: "Choose Payment Method" }),
|
|
1561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
|
|
1562
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1563
|
+
"button",
|
|
1564
|
+
{
|
|
1565
|
+
onClick: () => {
|
|
1566
|
+
setPaymentMethod("wallet");
|
|
1567
|
+
setCurrentStep("network");
|
|
1568
|
+
},
|
|
1569
|
+
className: `w-full p-4 border-2 rounded-lg hover:border-purple-500 text-left flex items-center space-x-3 transition-colors ${isDark ? "border-gray-600 hover:bg-gray-800" : "border-gray-200 hover:bg-gray-50"}`,
|
|
1570
|
+
children: [
|
|
1571
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "🦊" }),
|
|
1572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
1573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "MetaMask Wallet" }),
|
|
1574
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${isDark ? "text-gray-400" : "text-gray-500"}`, children: "Connect and pay instantly" })
|
|
1575
|
+
] })
|
|
1576
|
+
]
|
|
1577
|
+
}
|
|
1578
|
+
),
|
|
1579
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1580
|
+
"button",
|
|
1581
|
+
{
|
|
1582
|
+
onClick: () => {
|
|
1583
|
+
setPaymentMethod("qr");
|
|
1584
|
+
setCurrentStep("network");
|
|
1585
|
+
},
|
|
1586
|
+
className: `w-full p-4 border-2 rounded-lg hover:border-purple-500 text-left flex items-center space-x-3 transition-colors ${isDark ? "border-gray-600 hover:bg-gray-800" : "border-gray-200 hover:bg-gray-50"}`,
|
|
1587
|
+
children: [
|
|
1588
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "📱" }),
|
|
1589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
1590
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: "QR Code" }),
|
|
1591
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${isDark ? "text-gray-400" : "text-gray-500"}`, children: "Scan with mobile wallet" })
|
|
1592
|
+
] })
|
|
1593
|
+
]
|
|
1594
|
+
}
|
|
1595
|
+
)
|
|
1596
|
+
] })
|
|
1597
|
+
] }),
|
|
1598
|
+
currentStep === "network" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
1599
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
1600
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1601
|
+
"button",
|
|
1602
|
+
{
|
|
1603
|
+
onClick: () => setCurrentStep("method"),
|
|
1604
|
+
className: `${isDark ? "text-gray-400 hover:text-gray-200" : "text-gray-500 hover:text-gray-700"}`,
|
|
1605
|
+
children: "←"
|
|
1606
|
+
}
|
|
1607
|
+
),
|
|
1608
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium", children: "Select Network" })
|
|
1609
|
+
] }),
|
|
1610
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: networks.map((network) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1611
|
+
"button",
|
|
1612
|
+
{
|
|
1613
|
+
onClick: () => {
|
|
1614
|
+
setSelectedNetwork(network);
|
|
1615
|
+
setCurrentStep("token");
|
|
1616
|
+
},
|
|
1617
|
+
className: `w-full p-3 border rounded-lg hover:border-purple-500 text-left transition-colors ${isDark ? "border-gray-600 hover:bg-gray-800" : "border-gray-200 hover:bg-gray-50"}`,
|
|
1618
|
+
children: [
|
|
1619
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: network.name }),
|
|
1620
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${isDark ? "text-gray-400" : "text-gray-500"}`, children: network.shortName.toUpperCase() })
|
|
1621
|
+
]
|
|
1622
|
+
},
|
|
1623
|
+
network.id
|
|
1624
|
+
)) })
|
|
1625
|
+
] }),
|
|
1626
|
+
currentStep === "token" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
1627
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
1628
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1629
|
+
"button",
|
|
1630
|
+
{
|
|
1631
|
+
onClick: () => setCurrentStep("network"),
|
|
1632
|
+
className: `${isDark ? "text-gray-400 hover:text-gray-200" : "text-gray-500 hover:text-gray-700"}`,
|
|
1633
|
+
children: "←"
|
|
1634
|
+
}
|
|
1635
|
+
),
|
|
1636
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "font-medium", children: [
|
|
1637
|
+
"Select Token on ",
|
|
1638
|
+
selectedNetwork == null ? void 0 : selectedNetwork.name
|
|
1639
|
+
] })
|
|
1640
|
+
] }),
|
|
1641
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: tokens.filter((token) => {
|
|
1642
|
+
var _a2;
|
|
1643
|
+
return ((_a2 = token.Network) == null ? void 0 : _a2.shortName) === (selectedNetwork == null ? void 0 : selectedNetwork.shortName);
|
|
1644
|
+
}).map((token) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1645
|
+
"button",
|
|
1646
|
+
{
|
|
1647
|
+
onClick: () => {
|
|
1648
|
+
setSelectedToken(token);
|
|
1649
|
+
createPayment();
|
|
1650
|
+
},
|
|
1651
|
+
disabled: loading,
|
|
1652
|
+
className: `w-full p-3 border rounded-lg hover:border-purple-500 text-left flex justify-between transition-colors disabled:opacity-50 ${isDark ? "border-gray-600 hover:bg-gray-800" : "border-gray-200 hover:bg-gray-50"}`,
|
|
1653
|
+
children: [
|
|
1654
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
1655
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: token.name }),
|
|
1656
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `text-sm ${isDark ? "text-gray-400" : "text-gray-500"}`, children: token.symbol })
|
|
1657
|
+
] }),
|
|
1658
|
+
token.isStablecoin && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 bg-green-100 text-green-600 text-xs rounded", children: "Stablecoin" })
|
|
1659
|
+
]
|
|
1660
|
+
},
|
|
1661
|
+
token.id
|
|
1662
|
+
)) })
|
|
1663
|
+
] }),
|
|
1664
|
+
currentStep === "wallet" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
1665
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-center", children: "Connect & Pay" }),
|
|
1666
|
+
!walletConnected ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-4", children: [
|
|
1667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center mx-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "🦊" }) }),
|
|
1668
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `${isDark ? "text-gray-300" : "text-gray-600"}`, children: "Connect MetaMask to continue" }),
|
|
1669
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1670
|
+
"button",
|
|
1671
|
+
{
|
|
1672
|
+
onClick: connectWallet,
|
|
1673
|
+
disabled: loading,
|
|
1674
|
+
className: "w-full bg-purple-600 text-white py-3 px-4 rounded-lg hover:bg-purple-700 disabled:opacity-50 font-medium",
|
|
1675
|
+
children: loading ? "Connecting..." : "Connect MetaMask"
|
|
1676
|
+
}
|
|
1677
|
+
)
|
|
1678
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
1679
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 bg-green-50 rounded-lg border border-green-200", children: [
|
|
1680
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-green-600 text-sm font-medium", children: "✅ Wallet Connected" }),
|
|
1681
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-mono text-xs text-green-700 mt-1", children: [
|
|
1682
|
+
(_a = wallet.account) == null ? void 0 : _a.slice(0, 6),
|
|
1683
|
+
"...",
|
|
1684
|
+
(_b = wallet.account) == null ? void 0 : _b.slice(-4)
|
|
1685
|
+
] })
|
|
1686
|
+
] }),
|
|
1687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `p-4 rounded-lg space-y-2 ${isDark ? "bg-gray-800" : "bg-gray-50"}`, children: [
|
|
1688
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
1689
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Amount:" }),
|
|
1690
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
|
|
1691
|
+
paymentData == null ? void 0 : paymentData.totalAmount,
|
|
1692
|
+
" ",
|
|
1693
|
+
selectedToken == null ? void 0 : selectedToken.symbol
|
|
1694
|
+
] })
|
|
1695
|
+
] }),
|
|
1696
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
1697
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Network:" }),
|
|
1698
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: selectedNetwork == null ? void 0 : selectedNetwork.name })
|
|
1699
|
+
] }),
|
|
1700
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
1701
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Token:" }),
|
|
1702
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: selectedToken == null ? void 0 : selectedToken.name })
|
|
1703
|
+
] })
|
|
1704
|
+
] }),
|
|
1705
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1706
|
+
"button",
|
|
1707
|
+
{
|
|
1708
|
+
onClick: sendTransaction,
|
|
1709
|
+
disabled: processing,
|
|
1710
|
+
className: "w-full bg-green-600 text-white py-3 px-4 rounded-lg hover:bg-green-700 disabled:opacity-50 font-medium flex items-center justify-center space-x-2",
|
|
1711
|
+
children: processing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
1712
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-white" }),
|
|
1713
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Sending Transaction..." })
|
|
1714
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
1715
|
+
"Send ",
|
|
1716
|
+
paymentData == null ? void 0 : paymentData.totalAmount,
|
|
1717
|
+
" ",
|
|
1718
|
+
selectedToken == null ? void 0 : selectedToken.symbol
|
|
1719
|
+
] })
|
|
1720
|
+
}
|
|
1721
|
+
)
|
|
1722
|
+
] })
|
|
1723
|
+
] }),
|
|
1724
|
+
currentStep === "qr" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-4", children: [
|
|
1725
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium", children: "Scan QR Code" }),
|
|
1726
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `p-8 rounded-lg ${isDark ? "bg-gray-800" : "bg-gray-100"}`, children: [
|
|
1727
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `${isDark ? "text-gray-400" : "text-gray-500"}`, children: "QR Code will appear here" }),
|
|
1728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs mt-2", children: [
|
|
1729
|
+
"Send ",
|
|
1730
|
+
paymentData == null ? void 0 : paymentData.totalAmount,
|
|
1731
|
+
" ",
|
|
1732
|
+
selectedToken == null ? void 0 : selectedToken.symbol
|
|
1733
|
+
] }),
|
|
1734
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs", children: "to merchant wallet" })
|
|
1735
|
+
] }),
|
|
1736
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-xs ${isDark ? "text-gray-400" : "text-gray-500"}`, children: "Waiting for payment confirmation..." })
|
|
1737
|
+
] }),
|
|
1738
|
+
currentStep === "success" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-4", children: [
|
|
1739
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mx-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-2xl", children: "✅" }) }),
|
|
1740
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-green-600", children: "Payment Successful!" }),
|
|
1741
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: `text-sm ${isDark ? "text-gray-300" : "text-gray-600"}`, children: "Your transaction has been sent successfully" }),
|
|
1742
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1743
|
+
"button",
|
|
1744
|
+
{
|
|
1745
|
+
onClick: onClose,
|
|
1746
|
+
className: "w-full bg-purple-600 text-white py-3 px-4 rounded-lg hover:bg-purple-700 font-medium",
|
|
1747
|
+
children: "Close"
|
|
1748
|
+
}
|
|
1749
|
+
)
|
|
1750
|
+
] }),
|
|
1751
|
+
loading && currentStep !== "wallet" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" }) })
|
|
1752
|
+
] })
|
|
1753
|
+
] }) });
|
|
1754
|
+
};
|
|
1755
|
+
const SimpleCoinleyProvider = ({ children, ...props }) => children;
|
|
1756
|
+
const VERSION = "0.0.1";
|
|
1241
1757
|
const utils = {
|
|
1242
1758
|
formatAmount: (amount, decimals = 2) => amount.toFixed(decimals),
|
|
1243
1759
|
truncateAddress: (address, startChars = 6, endChars = 4) => {
|
|
@@ -1289,6 +1805,8 @@ export {
|
|
|
1289
1805
|
CoinleyProvider,
|
|
1290
1806
|
DEFAULT_CONFIG,
|
|
1291
1807
|
PaymentAPI,
|
|
1808
|
+
SimpleCoinleyPayment,
|
|
1809
|
+
SimpleCoinleyProvider,
|
|
1292
1810
|
ThemeProvider,
|
|
1293
1811
|
VERSION,
|
|
1294
1812
|
useCoinley,
|