coinley-test 0.0.22 → 0.0.23
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 +887 -8
- 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,7 @@ const ThemeProvider = ({
|
|
|
1237
1237
|
}, [theme]);
|
|
1238
1238
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `coinley-theme-${theme}`, children });
|
|
1239
1239
|
};
|
|
1240
|
-
class SimplePaymentAPI {
|
|
1240
|
+
let SimplePaymentAPI$1 = class SimplePaymentAPI {
|
|
1241
1241
|
constructor(baseURL, apiKey, apiSecret) {
|
|
1242
1242
|
this.baseURL = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
1243
1243
|
this.apiKey = apiKey;
|
|
@@ -1300,8 +1300,8 @@ class SimplePaymentAPI {
|
|
|
1300
1300
|
body: JSON.stringify(data)
|
|
1301
1301
|
});
|
|
1302
1302
|
}
|
|
1303
|
-
}
|
|
1304
|
-
class SimpleMetaMaskWallet {
|
|
1303
|
+
};
|
|
1304
|
+
let SimpleMetaMaskWallet$1 = class SimpleMetaMaskWallet {
|
|
1305
1305
|
constructor() {
|
|
1306
1306
|
this.account = null;
|
|
1307
1307
|
this.chainId = null;
|
|
@@ -1439,7 +1439,7 @@ class SimpleMetaMaskWallet {
|
|
|
1439
1439
|
isConnected() {
|
|
1440
1440
|
return !!this.account;
|
|
1441
1441
|
}
|
|
1442
|
-
}
|
|
1442
|
+
};
|
|
1443
1443
|
const SimpleCoinleyPayment = ({
|
|
1444
1444
|
apiKey,
|
|
1445
1445
|
apiSecret,
|
|
@@ -1461,10 +1461,10 @@ const SimpleCoinleyPayment = ({
|
|
|
1461
1461
|
const [paymentData, setPaymentData] = useState(null);
|
|
1462
1462
|
const [loading, setLoading] = useState(false);
|
|
1463
1463
|
const [error, setError] = useState("");
|
|
1464
|
-
const [wallet, setWallet] = useState(new SimpleMetaMaskWallet());
|
|
1464
|
+
const [wallet, setWallet] = useState(new SimpleMetaMaskWallet$1());
|
|
1465
1465
|
const [walletConnected, setWalletConnected] = useState(false);
|
|
1466
1466
|
const [processing, setProcessing] = useState(false);
|
|
1467
|
-
const api = useRef(new SimplePaymentAPI(apiUrl, apiKey, apiSecret));
|
|
1467
|
+
const api = useRef(new SimplePaymentAPI$1(apiUrl, apiKey, apiSecret));
|
|
1468
1468
|
useEffect(() => {
|
|
1469
1469
|
if (isOpen) {
|
|
1470
1470
|
loadData();
|
|
@@ -1480,7 +1480,7 @@ const SimpleCoinleyPayment = ({
|
|
|
1480
1480
|
setError("");
|
|
1481
1481
|
setWalletConnected(false);
|
|
1482
1482
|
setProcessing(false);
|
|
1483
|
-
setWallet(new SimpleMetaMaskWallet());
|
|
1483
|
+
setWallet(new SimpleMetaMaskWallet$1());
|
|
1484
1484
|
};
|
|
1485
1485
|
const loadData = async () => {
|
|
1486
1486
|
var _a2, _b2;
|
|
@@ -1836,8 +1836,837 @@ const SimpleCoinleyPayment = ({
|
|
|
1836
1836
|
] })
|
|
1837
1837
|
] }) });
|
|
1838
1838
|
};
|
|
1839
|
+
class SimplePaymentAPI2 {
|
|
1840
|
+
constructor(baseURL, apiKey, apiSecret) {
|
|
1841
|
+
this.baseURL = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
1842
|
+
this.apiKey = apiKey;
|
|
1843
|
+
this.apiSecret = apiSecret;
|
|
1844
|
+
}
|
|
1845
|
+
async request(endpoint, options = {}) {
|
|
1846
|
+
const url = `${this.baseURL}${endpoint}`;
|
|
1847
|
+
const headers = {
|
|
1848
|
+
"Content-Type": "application/json",
|
|
1849
|
+
"X-API-Key": this.apiKey,
|
|
1850
|
+
"X-API-Secret": this.apiSecret,
|
|
1851
|
+
...options.headers
|
|
1852
|
+
};
|
|
1853
|
+
const response = await fetch(url, {
|
|
1854
|
+
...options,
|
|
1855
|
+
headers
|
|
1856
|
+
});
|
|
1857
|
+
if (!response.ok) {
|
|
1858
|
+
const error = await response.json().catch(() => ({}));
|
|
1859
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
1860
|
+
}
|
|
1861
|
+
return response.json();
|
|
1862
|
+
}
|
|
1863
|
+
async getNetworks() {
|
|
1864
|
+
try {
|
|
1865
|
+
return await this.request("/api/networks");
|
|
1866
|
+
} catch (error) {
|
|
1867
|
+
console.error("Failed to fetch networks:", error);
|
|
1868
|
+
return {
|
|
1869
|
+
networks: [
|
|
1870
|
+
{ id: "1", name: "Ethereum", shortName: "ethereum", chainId: "0x1", type: "ethereum" },
|
|
1871
|
+
{ id: "56", name: "BSC", shortName: "bsc", chainId: "0x38", type: "bsc" }
|
|
1872
|
+
]
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
async getTokens() {
|
|
1877
|
+
try {
|
|
1878
|
+
return await this.request("/api/networks/stablecoins");
|
|
1879
|
+
} catch (error) {
|
|
1880
|
+
console.error("Failed to fetch tokens:", error);
|
|
1881
|
+
return {
|
|
1882
|
+
stablecoins: [
|
|
1883
|
+
{
|
|
1884
|
+
id: "1",
|
|
1885
|
+
name: "Tether USD",
|
|
1886
|
+
symbol: "USDT",
|
|
1887
|
+
contractAddress: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
1888
|
+
decimals: 6,
|
|
1889
|
+
networkId: "1",
|
|
1890
|
+
Network: { shortName: "ethereum", name: "Ethereum" }
|
|
1891
|
+
}
|
|
1892
|
+
]
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
async createPayment(data) {
|
|
1897
|
+
return await this.request("/api/payments/create", {
|
|
1898
|
+
method: "POST",
|
|
1899
|
+
body: JSON.stringify(data)
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
async verifyQRPayment(paymentId) {
|
|
1903
|
+
return await this.request("/api/payments/verify-qr", {
|
|
1904
|
+
method: "POST",
|
|
1905
|
+
body: JSON.stringify({ paymentId })
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
class SimpleMetaMaskWallet2 {
|
|
1910
|
+
constructor() {
|
|
1911
|
+
this.account = null;
|
|
1912
|
+
this.chainId = null;
|
|
1913
|
+
}
|
|
1914
|
+
async connect() {
|
|
1915
|
+
if (!window.ethereum) {
|
|
1916
|
+
throw new Error("MetaMask not installed. Please install MetaMask extension.");
|
|
1917
|
+
}
|
|
1918
|
+
if (window.ethereum.providers) {
|
|
1919
|
+
console.log("🔍 Multiple wallets detected:", window.ethereum.providers.length);
|
|
1920
|
+
const metamaskProvider = window.ethereum.providers.find((provider) => provider.isMetaMask);
|
|
1921
|
+
if (!metamaskProvider) {
|
|
1922
|
+
throw new Error("MetaMask not found among installed wallets");
|
|
1923
|
+
}
|
|
1924
|
+
console.log("🦊 Using MetaMask provider specifically");
|
|
1925
|
+
window.ethereum = metamaskProvider;
|
|
1926
|
+
} else if (!window.ethereum.isMetaMask) {
|
|
1927
|
+
throw new Error("Please use MetaMask wallet");
|
|
1928
|
+
}
|
|
1929
|
+
try {
|
|
1930
|
+
console.log("🦊 Requesting MetaMask account access...");
|
|
1931
|
+
const accounts = await window.ethereum.request({
|
|
1932
|
+
method: "eth_requestAccounts"
|
|
1933
|
+
});
|
|
1934
|
+
if (!accounts || accounts.length === 0) {
|
|
1935
|
+
throw new Error("No accounts found in MetaMask");
|
|
1936
|
+
}
|
|
1937
|
+
const chainId = await window.ethereum.request({
|
|
1938
|
+
method: "eth_chainId"
|
|
1939
|
+
});
|
|
1940
|
+
this.account = accounts[0];
|
|
1941
|
+
this.chainId = chainId;
|
|
1942
|
+
console.log("✅ MetaMask connected successfully:");
|
|
1943
|
+
console.log(" Account:", this.account);
|
|
1944
|
+
console.log(" Chain ID:", this.chainId);
|
|
1945
|
+
return { account: this.account, chainId: this.chainId };
|
|
1946
|
+
} catch (error) {
|
|
1947
|
+
console.error("MetaMask connection failed:", error);
|
|
1948
|
+
throw new Error(error.message || "Failed to connect to MetaMask");
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
async sendTransaction(txParams) {
|
|
1952
|
+
if (!this.account) {
|
|
1953
|
+
throw new Error("Wallet not connected");
|
|
1954
|
+
}
|
|
1955
|
+
try {
|
|
1956
|
+
console.log("🦊 Sending MetaMask transaction:", txParams);
|
|
1957
|
+
if (!window.ethereum.isMetaMask) {
|
|
1958
|
+
throw new Error("Not using MetaMask provider");
|
|
1959
|
+
}
|
|
1960
|
+
const fullTxParams = {
|
|
1961
|
+
...txParams,
|
|
1962
|
+
from: this.account
|
|
1963
|
+
};
|
|
1964
|
+
try {
|
|
1965
|
+
const gasEstimate = await window.ethereum.request({
|
|
1966
|
+
method: "eth_estimateGas",
|
|
1967
|
+
params: [fullTxParams]
|
|
1968
|
+
});
|
|
1969
|
+
const gasLimit = Math.floor(parseInt(gasEstimate, 16) * 1.2);
|
|
1970
|
+
fullTxParams.gas = `0x${gasLimit.toString(16)}`;
|
|
1971
|
+
console.log("⛽ Gas estimate:", parseInt(gasEstimate, 16));
|
|
1972
|
+
console.log("⛽ Gas limit (with buffer):", gasLimit);
|
|
1973
|
+
} catch (gasError) {
|
|
1974
|
+
console.warn("Gas estimation failed:", gasError);
|
|
1975
|
+
fullTxParams.gas = "0x15F90";
|
|
1976
|
+
}
|
|
1977
|
+
console.log("📤 Final transaction params:", fullTxParams);
|
|
1978
|
+
const txHash = await window.ethereum.request({
|
|
1979
|
+
method: "eth_sendTransaction",
|
|
1980
|
+
params: [fullTxParams]
|
|
1981
|
+
});
|
|
1982
|
+
console.log("✅ Transaction sent successfully:", txHash);
|
|
1983
|
+
return txHash;
|
|
1984
|
+
} catch (error) {
|
|
1985
|
+
console.error("Transaction failed:", error);
|
|
1986
|
+
if (error.code === 4001) {
|
|
1987
|
+
throw new Error("Transaction cancelled by user");
|
|
1988
|
+
} else if (error.message.includes("insufficient funds")) {
|
|
1989
|
+
throw new Error("Insufficient funds in wallet");
|
|
1990
|
+
} else if (error.message.includes("gas")) {
|
|
1991
|
+
throw new Error("Gas estimation failed. You may not have enough ETH for gas fees.");
|
|
1992
|
+
} else {
|
|
1993
|
+
throw new Error(error.message || "Transaction failed");
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
isConnected() {
|
|
1998
|
+
return !!this.account;
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
const EnhancedQRCode = ({
|
|
2002
|
+
walletAddress,
|
|
2003
|
+
amount,
|
|
2004
|
+
currency,
|
|
2005
|
+
network,
|
|
2006
|
+
theme = "light"
|
|
2007
|
+
}) => {
|
|
2008
|
+
const [qrData, setQrData] = useState("");
|
|
2009
|
+
const [isGenerating, setIsGenerating] = useState(true);
|
|
2010
|
+
useEffect(() => {
|
|
2011
|
+
const generateQRData = () => {
|
|
2012
|
+
setIsGenerating(true);
|
|
2013
|
+
setTimeout(() => {
|
|
2014
|
+
setQrData(`${walletAddress}?amount=${amount}¤cy=${currency}&network=${network}`);
|
|
2015
|
+
setIsGenerating(false);
|
|
2016
|
+
}, 1e3);
|
|
2017
|
+
};
|
|
2018
|
+
if (walletAddress) {
|
|
2019
|
+
generateQRData();
|
|
2020
|
+
}
|
|
2021
|
+
}, [walletAddress, amount, currency, network]);
|
|
2022
|
+
const formatWalletAddress = (address) => {
|
|
2023
|
+
if (!address || address.length <= 16) return address;
|
|
2024
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
2025
|
+
};
|
|
2026
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center", children: [
|
|
2027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 rounded-lg bg-white mb-3 shadow-sm border", children: isGenerating ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center", style: { width: 200, height: 200 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [
|
|
2028
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600 mx-auto mb-2" }),
|
|
2029
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-600", children: "Generating QR Code..." })
|
|
2030
|
+
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center bg-gray-100 rounded-lg", style: { width: 200, height: 200 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center p-4", children: [
|
|
2031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-2xl mb-2", children: "📱" }),
|
|
2032
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-600", children: "QR Code" }),
|
|
2033
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mt-1", children: "Scan to pay" })
|
|
2034
|
+
] }) }) }),
|
|
2035
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-sm text-gray-700 mb-4", children: [
|
|
2036
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-semibold text-gray-800 flex items-center justify-center", children: [
|
|
2037
|
+
/* @__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" }) }),
|
|
2038
|
+
"Scan to Pay with ",
|
|
2039
|
+
currency
|
|
2040
|
+
] }),
|
|
2041
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
|
|
2042
|
+
"Scan with your ",
|
|
2043
|
+
network,
|
|
2044
|
+
" wallet app"
|
|
2045
|
+
] })
|
|
2046
|
+
] }),
|
|
2047
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mb-4 p-3 bg-gray-50 rounded-lg", children: [
|
|
2048
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
|
|
2049
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-gray-700", children: "Amount to Pay:" }),
|
|
2050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-lg font-bold text-[#7042D2]", children: [
|
|
2051
|
+
amount,
|
|
2052
|
+
" ",
|
|
2053
|
+
currency
|
|
2054
|
+
] })
|
|
2055
|
+
] }),
|
|
2056
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mt-1", children: [
|
|
2057
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "Network:" }),
|
|
2058
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-gray-700", children: network })
|
|
2059
|
+
] }),
|
|
2060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center mt-1", children: [
|
|
2061
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500", children: "Recipient:" }),
|
|
2062
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-gray-700", children: formatWalletAddress(walletAddress) })
|
|
2063
|
+
] })
|
|
2064
|
+
] }),
|
|
2065
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 rounded bg-blue-50 border border-blue-200", children: [
|
|
2066
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-medium mb-2 text-blue-800 flex items-center", children: [
|
|
2067
|
+
/* @__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" }) }),
|
|
2068
|
+
"Payment Instructions"
|
|
2069
|
+
] }),
|
|
2070
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("ol", { className: "text-xs space-y-1 text-blue-700", children: [
|
|
2071
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: "1. Open your crypto wallet app" }),
|
|
2072
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: "2. Scan the QR code above" }),
|
|
2073
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
|
|
2074
|
+
"3. Send exactly ",
|
|
2075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
2076
|
+
amount,
|
|
2077
|
+
" ",
|
|
2078
|
+
currency
|
|
2079
|
+
] })
|
|
2080
|
+
] }),
|
|
2081
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: '4. Click "I have sent the payment" button below' })
|
|
2082
|
+
] })
|
|
2083
|
+
] }) })
|
|
2084
|
+
] });
|
|
2085
|
+
};
|
|
2086
|
+
const EnhancedPaymentStatus = ({
|
|
2087
|
+
status,
|
|
2088
|
+
message,
|
|
2089
|
+
theme = "light",
|
|
2090
|
+
payment = null,
|
|
2091
|
+
transactionHash = null,
|
|
2092
|
+
selectedPaymentMethod = null,
|
|
2093
|
+
merchantName = "Merchant",
|
|
2094
|
+
onClose = null
|
|
2095
|
+
}) => {
|
|
2096
|
+
const [copiedHash, setCopiedHash] = useState(false);
|
|
2097
|
+
const copyTransactionHash = async () => {
|
|
2098
|
+
if (transactionHash) {
|
|
2099
|
+
try {
|
|
2100
|
+
await navigator.clipboard.writeText(transactionHash);
|
|
2101
|
+
setCopiedHash(true);
|
|
2102
|
+
setTimeout(() => setCopiedHash(false), 2e3);
|
|
2103
|
+
} catch (err) {
|
|
2104
|
+
console.error("Failed to copy transaction hash:", err);
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
const formatTransactionHash = (hash) => {
|
|
2109
|
+
if (!hash) return "";
|
|
2110
|
+
if (hash.length <= 16) return hash;
|
|
2111
|
+
return `${hash.slice(0, 8)}...${hash.slice(-8)}`;
|
|
2112
|
+
};
|
|
2113
|
+
const renderIcon = () => {
|
|
2114
|
+
switch (status) {
|
|
2115
|
+
case "processing":
|
|
2116
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "animate-spin rounded-full h-12 w-12 border-4 border-t-purple-600 border-blue-500/20" });
|
|
2117
|
+
case "success":
|
|
2118
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-full h-16 w-16 bg-green-500 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2119
|
+
"svg",
|
|
2120
|
+
{
|
|
2121
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2122
|
+
className: "h-10 w-10 text-white",
|
|
2123
|
+
fill: "none",
|
|
2124
|
+
viewBox: "0 0 24 24",
|
|
2125
|
+
stroke: "currentColor",
|
|
2126
|
+
strokeWidth: 3,
|
|
2127
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
2128
|
+
}
|
|
2129
|
+
) });
|
|
2130
|
+
case "error":
|
|
2131
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-full h-12 w-12 bg-red-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2132
|
+
"svg",
|
|
2133
|
+
{
|
|
2134
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2135
|
+
className: "h-8 w-8 text-red-500",
|
|
2136
|
+
fill: "none",
|
|
2137
|
+
viewBox: "0 0 24 24",
|
|
2138
|
+
stroke: "currentColor",
|
|
2139
|
+
strokeWidth: 2,
|
|
2140
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
2141
|
+
}
|
|
2142
|
+
) });
|
|
2143
|
+
default:
|
|
2144
|
+
return null;
|
|
2145
|
+
}
|
|
2146
|
+
};
|
|
2147
|
+
if (status === "success") {
|
|
2148
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6 px-4", children: [
|
|
2149
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6", children: renderIcon() }),
|
|
2150
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-2xl font-bold mb-3 text-gray-900", children: "Payment Successful!" }),
|
|
2151
|
+
payment && selectedPaymentMethod && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-center max-w-[235px] mb-6 text-gray-600", children: [
|
|
2152
|
+
"Your payment of ",
|
|
2153
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[#7042D2] font-semibold", children: [
|
|
2154
|
+
payment.totalAmount || payment.amount,
|
|
2155
|
+
" ",
|
|
2156
|
+
selectedPaymentMethod.currency
|
|
2157
|
+
] }),
|
|
2158
|
+
" has been completed."
|
|
2159
|
+
] }),
|
|
2160
|
+
transactionHash && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full mb-6 px-4", children: [
|
|
2161
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium mb-2 text-gray-700", children: "Transaction Hash:" }),
|
|
2162
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2163
|
+
"div",
|
|
2164
|
+
{
|
|
2165
|
+
className: "flex items-center justify-between p-3 rounded-lg border cursor-pointer transition-colors bg-gray-50 border-gray-200 hover:bg-gray-100",
|
|
2166
|
+
onClick: copyTransactionHash,
|
|
2167
|
+
children: [
|
|
2168
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-sm text-gray-700", children: formatTransactionHash(transactionHash) }),
|
|
2169
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center", children: [
|
|
2170
|
+
copiedHash ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-500 text-xs font-medium mr-2", children: "Copied!" }) : null,
|
|
2171
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2172
|
+
"svg",
|
|
2173
|
+
{
|
|
2174
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2175
|
+
className: "h-4 w-4 text-gray-500",
|
|
2176
|
+
fill: "none",
|
|
2177
|
+
viewBox: "0 0 24 24",
|
|
2178
|
+
stroke: "currentColor",
|
|
2179
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" })
|
|
2180
|
+
}
|
|
2181
|
+
)
|
|
2182
|
+
] })
|
|
2183
|
+
]
|
|
2184
|
+
}
|
|
2185
|
+
)
|
|
2186
|
+
] }),
|
|
2187
|
+
onClose && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2188
|
+
"button",
|
|
2189
|
+
{
|
|
2190
|
+
onClick: onClose,
|
|
2191
|
+
className: "w-full py-3 px-4 bg-[#7042D2] text-white font-medium rounded-2xl text-lg shadow-md hover:bg-[#5b34b1] transition-colors",
|
|
2192
|
+
children: "Close"
|
|
2193
|
+
}
|
|
2194
|
+
)
|
|
2195
|
+
] });
|
|
2196
|
+
}
|
|
2197
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center py-6", children: [
|
|
2198
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: renderIcon() }),
|
|
2199
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-bold mb-2 text-gray-900", children: status === "processing" ? "Processing Payment" : status === "error" ? "Payment Failed" : "Unknown Status" }),
|
|
2200
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-center text-gray-600", children: message })
|
|
2201
|
+
] });
|
|
2202
|
+
};
|
|
2203
|
+
const ScreenTransition = ({
|
|
2204
|
+
currentStep,
|
|
2205
|
+
targetStep,
|
|
2206
|
+
children,
|
|
2207
|
+
className = "",
|
|
2208
|
+
duration = 300
|
|
2209
|
+
}) => {
|
|
2210
|
+
const [isVisible, setIsVisible] = useState(currentStep === targetStep);
|
|
2211
|
+
const [shouldRender, setShouldRender] = useState(currentStep === targetStep);
|
|
2212
|
+
useEffect(() => {
|
|
2213
|
+
if (currentStep === targetStep) {
|
|
2214
|
+
setShouldRender(true);
|
|
2215
|
+
setTimeout(() => setIsVisible(true), 10);
|
|
2216
|
+
} else {
|
|
2217
|
+
setIsVisible(false);
|
|
2218
|
+
setTimeout(() => setShouldRender(false), duration);
|
|
2219
|
+
}
|
|
2220
|
+
}, [currentStep, targetStep, duration]);
|
|
2221
|
+
if (!shouldRender) return null;
|
|
2222
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2223
|
+
"div",
|
|
2224
|
+
{
|
|
2225
|
+
className: `
|
|
2226
|
+
transition-all duration-300 ease-out
|
|
2227
|
+
${isVisible ? "transform translate-y-0 opacity-100" : "transform translate-y-full opacity-0"}
|
|
2228
|
+
${className}
|
|
2229
|
+
`,
|
|
2230
|
+
style: {
|
|
2231
|
+
transitionDuration: `${duration}ms`
|
|
2232
|
+
},
|
|
2233
|
+
children
|
|
2234
|
+
}
|
|
2235
|
+
);
|
|
2236
|
+
};
|
|
2237
|
+
const EnhancedSimpleCoinleyPayment = ({
|
|
2238
|
+
apiKey,
|
|
2239
|
+
apiSecret,
|
|
2240
|
+
apiUrl,
|
|
2241
|
+
config,
|
|
2242
|
+
onSuccess,
|
|
2243
|
+
onError,
|
|
2244
|
+
onClose,
|
|
2245
|
+
isOpen,
|
|
2246
|
+
theme = "light"
|
|
2247
|
+
}) => {
|
|
2248
|
+
var _a, _b;
|
|
2249
|
+
const [currentStep, setCurrentStep] = useState("method");
|
|
2250
|
+
const [networks, setNetworks] = useState([]);
|
|
2251
|
+
const [tokens, setTokens] = useState([]);
|
|
2252
|
+
const [selectedNetwork, setSelectedNetwork] = useState(null);
|
|
2253
|
+
const [selectedToken, setSelectedToken] = useState(null);
|
|
2254
|
+
const [paymentMethod, setPaymentMethod] = useState(null);
|
|
2255
|
+
const [paymentData, setPaymentData] = useState(null);
|
|
2256
|
+
const [loading, setLoading] = useState(false);
|
|
2257
|
+
const [error, setError] = useState("");
|
|
2258
|
+
const [wallet, setWallet] = useState(new SimpleMetaMaskWallet2());
|
|
2259
|
+
const [walletConnected, setWalletConnected] = useState(false);
|
|
2260
|
+
const [processing, setProcessing] = useState(false);
|
|
2261
|
+
const [paymentType, setPaymentType] = useState("wallet");
|
|
2262
|
+
const api = useRef(new SimplePaymentAPI2(apiUrl, apiKey, apiSecret));
|
|
2263
|
+
useEffect(() => {
|
|
2264
|
+
if (isOpen) {
|
|
2265
|
+
loadData();
|
|
2266
|
+
resetState();
|
|
2267
|
+
}
|
|
2268
|
+
}, [isOpen]);
|
|
2269
|
+
const resetState = () => {
|
|
2270
|
+
setCurrentStep("method");
|
|
2271
|
+
setSelectedNetwork(null);
|
|
2272
|
+
setSelectedToken(null);
|
|
2273
|
+
setPaymentMethod(null);
|
|
2274
|
+
setPaymentData(null);
|
|
2275
|
+
setError("");
|
|
2276
|
+
setWalletConnected(false);
|
|
2277
|
+
setProcessing(false);
|
|
2278
|
+
setWallet(new SimpleMetaMaskWallet2());
|
|
2279
|
+
setPaymentType("wallet");
|
|
2280
|
+
};
|
|
2281
|
+
const loadData = async () => {
|
|
2282
|
+
var _a2, _b2;
|
|
2283
|
+
try {
|
|
2284
|
+
setLoading(true);
|
|
2285
|
+
setError("");
|
|
2286
|
+
console.log("🔄 Loading networks and tokens...");
|
|
2287
|
+
const [networksRes, tokensRes] = await Promise.all([
|
|
2288
|
+
api.current.getNetworks(),
|
|
2289
|
+
api.current.getTokens()
|
|
2290
|
+
]);
|
|
2291
|
+
setNetworks(networksRes.networks || []);
|
|
2292
|
+
setTokens(tokensRes.stablecoins || []);
|
|
2293
|
+
console.log("✅ Loaded networks:", (_a2 = networksRes.networks) == null ? void 0 : _a2.length);
|
|
2294
|
+
console.log("✅ Loaded tokens:", (_b2 = tokensRes.stablecoins) == null ? void 0 : _b2.length);
|
|
2295
|
+
} catch (err) {
|
|
2296
|
+
console.error("Failed to load data:", err);
|
|
2297
|
+
setError("Failed to load payment options. Using fallback data.");
|
|
2298
|
+
} finally {
|
|
2299
|
+
setLoading(false);
|
|
2300
|
+
}
|
|
2301
|
+
};
|
|
2302
|
+
const connectWallet = async () => {
|
|
2303
|
+
try {
|
|
2304
|
+
setLoading(true);
|
|
2305
|
+
setError("");
|
|
2306
|
+
const connection = await wallet.connect();
|
|
2307
|
+
setWalletConnected(true);
|
|
2308
|
+
console.log("✅ Wallet connected successfully:", connection.account);
|
|
2309
|
+
} catch (err) {
|
|
2310
|
+
console.error("Wallet connection failed:", err);
|
|
2311
|
+
setError(err.message);
|
|
2312
|
+
} finally {
|
|
2313
|
+
setLoading(false);
|
|
2314
|
+
}
|
|
2315
|
+
};
|
|
2316
|
+
const createPayment = async () => {
|
|
2317
|
+
try {
|
|
2318
|
+
setLoading(true);
|
|
2319
|
+
setError("");
|
|
2320
|
+
const paymentPayload = {
|
|
2321
|
+
amount: config.amount,
|
|
2322
|
+
currency: selectedToken.symbol,
|
|
2323
|
+
network: selectedNetwork.shortName,
|
|
2324
|
+
customerEmail: config.customerEmail,
|
|
2325
|
+
callbackUrl: config.callbackUrl,
|
|
2326
|
+
metadata: {
|
|
2327
|
+
...config.metadata,
|
|
2328
|
+
merchantWalletAddresses: config.merchantWalletAddresses,
|
|
2329
|
+
paymentMethod,
|
|
2330
|
+
selectedNetwork: selectedNetwork.shortName,
|
|
2331
|
+
selectedToken: selectedToken.symbol
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
console.log("🔄 Creating payment:", paymentPayload);
|
|
2335
|
+
const payment = await api.current.createPayment(paymentPayload);
|
|
2336
|
+
setPaymentData(payment.payment);
|
|
2337
|
+
console.log("✅ Payment created:", payment.payment.id);
|
|
2338
|
+
setCurrentStep("confirm");
|
|
2339
|
+
} catch (err) {
|
|
2340
|
+
console.error("Payment creation failed:", err);
|
|
2341
|
+
setError(err.message);
|
|
2342
|
+
} finally {
|
|
2343
|
+
setLoading(false);
|
|
2344
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
const sendTransaction = async () => {
|
|
2347
|
+
var _a2, _b2;
|
|
2348
|
+
try {
|
|
2349
|
+
setProcessing(true);
|
|
2350
|
+
setError("");
|
|
2351
|
+
const recipientAddress = ((_a2 = paymentData.metadata) == null ? void 0 : _a2.recipientWallet) || ((_b2 = config.merchantWalletAddresses) == null ? void 0 : _b2[selectedNetwork.shortName]);
|
|
2352
|
+
if (!recipientAddress) {
|
|
2353
|
+
throw new Error("Merchant wallet address not found");
|
|
2354
|
+
}
|
|
2355
|
+
console.log("🔄 Preparing transaction to:", recipientAddress);
|
|
2356
|
+
let txParams;
|
|
2357
|
+
if (selectedToken.contractAddress) {
|
|
2358
|
+
const decimals = selectedToken.decimals || 6;
|
|
2359
|
+
const amount = Math.floor(paymentData.totalAmount * Math.pow(10, decimals));
|
|
2360
|
+
const methodId = "0xa9059cbb";
|
|
2361
|
+
const recipientPadded = recipientAddress.slice(2).toLowerCase().padStart(64, "0");
|
|
2362
|
+
const amountPadded = amount.toString(16).padStart(64, "0");
|
|
2363
|
+
const data = `${methodId}${recipientPadded}${amountPadded}`;
|
|
2364
|
+
txParams = {
|
|
2365
|
+
to: selectedToken.contractAddress,
|
|
2366
|
+
data,
|
|
2367
|
+
value: "0x0"
|
|
2368
|
+
};
|
|
2369
|
+
console.log("🔄 ERC-20 Transaction:", {
|
|
2370
|
+
token: selectedToken.symbol,
|
|
2371
|
+
amount: paymentData.totalAmount,
|
|
2372
|
+
amountWithDecimals: amount,
|
|
2373
|
+
to: selectedToken.contractAddress,
|
|
2374
|
+
recipient: recipientAddress
|
|
2375
|
+
});
|
|
2376
|
+
} else {
|
|
2377
|
+
const value = Math.floor(paymentData.totalAmount * Math.pow(10, 18));
|
|
2378
|
+
txParams = {
|
|
2379
|
+
to: recipientAddress,
|
|
2380
|
+
value: `0x${value.toString(16)}`
|
|
2381
|
+
};
|
|
2382
|
+
console.log("🔄 Native Transaction:", {
|
|
2383
|
+
amount: paymentData.totalAmount,
|
|
2384
|
+
to: recipientAddress
|
|
2385
|
+
});
|
|
2386
|
+
}
|
|
2387
|
+
const txHash = await wallet.sendTransaction(txParams);
|
|
2388
|
+
console.log("✅ Transaction successful:", txHash);
|
|
2389
|
+
setCurrentStep("success");
|
|
2390
|
+
onSuccess == null ? void 0 : onSuccess(paymentData.id, txHash, {
|
|
2391
|
+
network: selectedNetwork.name,
|
|
2392
|
+
currency: selectedToken.symbol,
|
|
2393
|
+
amount: paymentData.totalAmount,
|
|
2394
|
+
method: paymentMethod
|
|
2395
|
+
});
|
|
2396
|
+
} catch (err) {
|
|
2397
|
+
console.error("Transaction failed:", err);
|
|
2398
|
+
setError(err.message);
|
|
2399
|
+
onError == null ? void 0 : onError(err.message);
|
|
2400
|
+
} finally {
|
|
2401
|
+
setProcessing(false);
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
const handleQRPaymentVerification = async () => {
|
|
2405
|
+
if (!paymentData) {
|
|
2406
|
+
setError("Payment information is missing");
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
2409
|
+
setCurrentStep("processing");
|
|
2410
|
+
setError(null);
|
|
2411
|
+
try {
|
|
2412
|
+
console.log("🔄 Starting QR payment verification...");
|
|
2413
|
+
const verificationResult = await api.current.verifyQRPayment(paymentData.id);
|
|
2414
|
+
if (verificationResult.verified) {
|
|
2415
|
+
console.log("✅ QR payment verified successfully:", verificationResult);
|
|
2416
|
+
setCurrentStep("success");
|
|
2417
|
+
if (onSuccess) {
|
|
2418
|
+
onSuccess(paymentData.id, verificationResult.payment.transactionHash, {
|
|
2419
|
+
network: selectedNetwork.name,
|
|
2420
|
+
currency: selectedToken.symbol,
|
|
2421
|
+
amount: verificationResult.payment.amount,
|
|
2422
|
+
verificationType: "QR_PAYMENT"
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
} else {
|
|
2426
|
+
setError(verificationResult.message || "Transaction not detected yet. Please wait a moment and try again.");
|
|
2427
|
+
setCurrentStep("confirm");
|
|
2428
|
+
}
|
|
2429
|
+
} catch (error2) {
|
|
2430
|
+
console.error("QR payment verification error:", error2);
|
|
2431
|
+
const errorMessage = error2.message || "Failed to verify payment. Please try again.";
|
|
2432
|
+
setError(errorMessage);
|
|
2433
|
+
setCurrentStep("confirm");
|
|
2434
|
+
if (onError) onError(errorMessage);
|
|
2435
|
+
}
|
|
2436
|
+
};
|
|
2437
|
+
const formatAmount = (amount) => {
|
|
2438
|
+
return parseFloat(amount).toFixed(2);
|
|
2439
|
+
};
|
|
2440
|
+
const getNetworkDisplayName = (network) => {
|
|
2441
|
+
const names = {
|
|
2442
|
+
ethereum: "Ethereum",
|
|
2443
|
+
bsc: "BSC",
|
|
2444
|
+
tron: "Tron",
|
|
2445
|
+
algorand: "Algorand",
|
|
2446
|
+
solana: "Solana"
|
|
2447
|
+
};
|
|
2448
|
+
return names[network] || network;
|
|
2449
|
+
};
|
|
2450
|
+
const getWalletAddressForNetwork = () => {
|
|
2451
|
+
var _a2;
|
|
2452
|
+
if (!selectedNetwork) return "No network selected";
|
|
2453
|
+
const networkAddress = (_a2 = config.merchantWalletAddresses) == null ? void 0 : _a2[selectedNetwork.shortName];
|
|
2454
|
+
if (networkAddress) return networkAddress;
|
|
2455
|
+
if (paymentData == null ? void 0 : paymentData.recipientWallet) return paymentData.recipientWallet;
|
|
2456
|
+
return "No wallet address configured for this network";
|
|
2457
|
+
};
|
|
2458
|
+
if (!isOpen) return null;
|
|
2459
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed inset-0 z-50", children: [
|
|
2460
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 transition-opacity", onClick: onClose, "aria-hidden": "true" }),
|
|
2461
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative pt-6 w-full max-w-md mx-auto shadow-xl bg-gray-100 rounded-3xl overflow-hidden", children: [
|
|
2462
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white flex justify-between items-center mb-6 mr-3 ml-3 py-4 px-2 rounded-full", children: [
|
|
2463
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex items-center gap-2 px-4", children: [
|
|
2464
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-white font-bold text-sm", children: "C" }) }),
|
|
2465
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-lg font-semibold text-gray-800", children: "Payment Details" })
|
|
2466
|
+
] }),
|
|
2467
|
+
currentStep !== "success" && currentStep !== "processing" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2468
|
+
"button",
|
|
2469
|
+
{
|
|
2470
|
+
onClick: onClose,
|
|
2471
|
+
className: "text-gray-500 hover:text-gray-700 focus:outline-none",
|
|
2472
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6 mr-2", 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" }) })
|
|
2473
|
+
}
|
|
2474
|
+
)
|
|
2475
|
+
] }),
|
|
2476
|
+
paymentData && currentStep !== "success" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [
|
|
2477
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-600", children: "Total Amount" }),
|
|
2478
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-3xl md:text-9xl lg:text-9xl font-bold text-[#7042D2] mt-2 leading-tight tracking-tight", children: [
|
|
2479
|
+
"$",
|
|
2480
|
+
formatAmount(paymentData.totalAmount || paymentData.amount)
|
|
2481
|
+
] }),
|
|
2482
|
+
paymentData.feeChargedTo === "customer" && paymentData.feeAmount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 text-sm text-gray-500", children: "Processing fee included" }),
|
|
2483
|
+
paymentData.feeChargedTo === "merchant" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 text-sm text-gray-500", children: "No additional fees" }),
|
|
2484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-600 mt-4", children: "Payment to:" }),
|
|
2485
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-base font-semibold mt-1 flex gap-2 items-center justify-center", children: [
|
|
2486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M15.3 7.50065L15.8 10.0007H4.2L4.7 7.50065H15.3ZM16.6667 3.33398H3.33333V5.00065H16.6667V3.33398ZM16.6667 5.83398H3.33333L2.5 10.0007V11.6673H3.33333V16.6673H11.6667V11.6673H15V16.6673H16.6667V11.6673H17.5V10.0007L16.6667 5.83398ZM5 15.0007V11.6673H10V15.0007H5Z", fill: "#7042D2" }) }),
|
|
2487
|
+
config.merchantName || "Merchant"
|
|
2488
|
+
] })
|
|
2489
|
+
] }) }),
|
|
2490
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
2491
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScreenTransition, { currentStep, targetStep: "method", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pb-6 pt-6 px-6 bg-white rounded-t-2xl", children: [
|
|
2492
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-center mb-6", children: "Choose Payment Method" }),
|
|
2493
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 mb-6", children: [
|
|
2494
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Select Network" }),
|
|
2495
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: networks.map((network) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2496
|
+
"button",
|
|
2497
|
+
{
|
|
2498
|
+
onClick: () => setSelectedNetwork(network),
|
|
2499
|
+
className: `w-full p-3 border rounded-lg text-left transition-colors ${(selectedNetwork == null ? void 0 : selectedNetwork.id) === network.id ? "border-purple-500 bg-purple-50" : "border-gray-200 hover:bg-gray-50"}`,
|
|
2500
|
+
children: [
|
|
2501
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: network.name }),
|
|
2502
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500", children: network.shortName.toUpperCase() })
|
|
2503
|
+
]
|
|
2504
|
+
},
|
|
2505
|
+
network.id
|
|
2506
|
+
)) })
|
|
2507
|
+
] }),
|
|
2508
|
+
selectedNetwork && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 mb-6", children: [
|
|
2509
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Select Token" }),
|
|
2510
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: tokens.filter((token) => {
|
|
2511
|
+
var _a2;
|
|
2512
|
+
return ((_a2 = token.Network) == null ? void 0 : _a2.shortName) === (selectedNetwork == null ? void 0 : selectedNetwork.shortName);
|
|
2513
|
+
}).map((token) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2514
|
+
"button",
|
|
2515
|
+
{
|
|
2516
|
+
onClick: () => setSelectedToken(token),
|
|
2517
|
+
className: `w-full p-3 border rounded-lg text-left flex justify-between transition-colors ${(selectedToken == null ? void 0 : selectedToken.id) === token.id ? "border-purple-500 bg-purple-50" : "border-gray-200 hover:bg-gray-50"}`,
|
|
2518
|
+
children: [
|
|
2519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
2520
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: token.name }),
|
|
2521
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500", children: token.symbol })
|
|
2522
|
+
] }),
|
|
2523
|
+
token.isStablecoin && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-1 bg-green-100 text-green-600 text-xs rounded", children: "Stablecoin" })
|
|
2524
|
+
]
|
|
2525
|
+
},
|
|
2526
|
+
token.id
|
|
2527
|
+
)) })
|
|
2528
|
+
] }),
|
|
2529
|
+
selectedNetwork && selectedToken && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2530
|
+
"button",
|
|
2531
|
+
{
|
|
2532
|
+
onClick: createPayment,
|
|
2533
|
+
disabled: loading,
|
|
2534
|
+
className: "w-full bg-purple-600 text-white py-3 px-4 rounded-lg hover:bg-purple-700 disabled:opacity-50 font-medium",
|
|
2535
|
+
children: loading ? "Creating Payment..." : "Continue"
|
|
2536
|
+
}
|
|
2537
|
+
)
|
|
2538
|
+
] }) }),
|
|
2539
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScreenTransition, { currentStep, targetStep: "confirm", children: selectedNetwork && selectedToken && paymentData && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
2540
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 px-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex border-b border-gray-200", children: [
|
|
2541
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2542
|
+
"button",
|
|
2543
|
+
{
|
|
2544
|
+
onClick: () => setPaymentType("wallet"),
|
|
2545
|
+
className: `py-2 px-4 text-sm font-medium ${paymentType === "wallet" ? "border-b-2 border-purple-600 text-purple-600" : "text-gray-500 hover:text-gray-700"}`,
|
|
2546
|
+
children: "Connect Wallet"
|
|
2547
|
+
}
|
|
2548
|
+
),
|
|
2549
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2550
|
+
"button",
|
|
2551
|
+
{
|
|
2552
|
+
onClick: () => setPaymentType("qrcode"),
|
|
2553
|
+
className: `py-2 px-4 text-sm font-medium ${paymentType === "qrcode" ? "border-b-2 border-purple-600 text-purple-600" : "text-gray-500 hover:text-gray-700"}`,
|
|
2554
|
+
children: "QR Code"
|
|
2555
|
+
}
|
|
2556
|
+
)
|
|
2557
|
+
] }) }),
|
|
2558
|
+
paymentType === "wallet" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 rounded-2xl mb-4 bg-white", children: [
|
|
2559
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium mb-2 text-gray-800", children: "Payment Details" }),
|
|
2560
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 bg-[#EDE4FF] p-3 rounded-xl", children: [
|
|
2561
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
|
2562
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Currency:" }),
|
|
2563
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: selectedToken.symbol })
|
|
2564
|
+
] }),
|
|
2565
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-b border-gray-400" }),
|
|
2566
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
|
2567
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: "Network:" }),
|
|
2568
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: getNetworkDisplayName(selectedNetwork.shortName) })
|
|
2569
|
+
] }),
|
|
2570
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-b border-gray-400" }),
|
|
2571
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between border-t pt-2 mt-1", children: [
|
|
2572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-bold", children: "Total:" }),
|
|
2573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-bold text-lg", children: [
|
|
2574
|
+
"$",
|
|
2575
|
+
formatAmount(paymentData.totalAmount)
|
|
2576
|
+
] })
|
|
2577
|
+
] })
|
|
2578
|
+
] })
|
|
2579
|
+
] }),
|
|
2580
|
+
paymentType === "qrcode" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2581
|
+
EnhancedQRCode,
|
|
2582
|
+
{
|
|
2583
|
+
walletAddress: getWalletAddressForNetwork(),
|
|
2584
|
+
amount: paymentData.totalAmount || paymentData.amount,
|
|
2585
|
+
currency: selectedToken.symbol,
|
|
2586
|
+
network: selectedNetwork.shortName,
|
|
2587
|
+
theme
|
|
2588
|
+
}
|
|
2589
|
+
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3 mb-4 px-4", children: !walletConnected ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-4", children: [
|
|
2590
|
+
/* @__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: "🦊" }) }),
|
|
2591
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600", children: "Connect MetaMask to continue" }),
|
|
2592
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2593
|
+
"button",
|
|
2594
|
+
{
|
|
2595
|
+
onClick: connectWallet,
|
|
2596
|
+
disabled: loading,
|
|
2597
|
+
className: "w-full bg-purple-600 text-white py-3 px-4 rounded-lg hover:bg-purple-700 disabled:opacity-50 font-medium",
|
|
2598
|
+
children: loading ? "Connecting..." : "Connect MetaMask"
|
|
2599
|
+
}
|
|
2600
|
+
)
|
|
2601
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 bg-green-50 rounded-lg border border-green-200", children: [
|
|
2602
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-green-600 text-sm font-medium", children: "✅ Wallet Connected" }),
|
|
2603
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "font-mono text-xs text-green-700 mt-1", children: [
|
|
2604
|
+
(_a = wallet.account) == null ? void 0 : _a.slice(0, 6),
|
|
2605
|
+
"...",
|
|
2606
|
+
(_b = wallet.account) == null ? void 0 : _b.slice(-4)
|
|
2607
|
+
] })
|
|
2608
|
+
] }) }) }),
|
|
2609
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-3 rounded-lg bg-red-50 mb-4 text-red-600 text-sm", children: error }),
|
|
2610
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3 mb-3 px-4", children: [
|
|
2611
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2612
|
+
"button",
|
|
2613
|
+
{
|
|
2614
|
+
type: "button",
|
|
2615
|
+
onClick: () => setCurrentStep("method"),
|
|
2616
|
+
className: "w-full py-2 px-4 bg-gray-200 hover:bg-gray-300 text-purple-600 font-medium rounded-md",
|
|
2617
|
+
children: "Back"
|
|
2618
|
+
}
|
|
2619
|
+
),
|
|
2620
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2621
|
+
"button",
|
|
2622
|
+
{
|
|
2623
|
+
type: "button",
|
|
2624
|
+
onClick: paymentType === "qrcode" ? handleQRPaymentVerification : sendTransaction,
|
|
2625
|
+
className: "bg-green-600 text-white w-full py-2 px-4 font-medium rounded-md",
|
|
2626
|
+
disabled: paymentType === "wallet" && !walletConnected,
|
|
2627
|
+
children: paymentType === "qrcode" ? "I have sent the payment" : "Pay Now"
|
|
2628
|
+
}
|
|
2629
|
+
)
|
|
2630
|
+
] })
|
|
2631
|
+
] }) }),
|
|
2632
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScreenTransition, { currentStep, targetStep: "processing", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2633
|
+
EnhancedPaymentStatus,
|
|
2634
|
+
{
|
|
2635
|
+
status: "processing",
|
|
2636
|
+
theme,
|
|
2637
|
+
message: "Processing your payment..."
|
|
2638
|
+
}
|
|
2639
|
+
) }),
|
|
2640
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScreenTransition, { currentStep, targetStep: "success", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2641
|
+
EnhancedPaymentStatus,
|
|
2642
|
+
{
|
|
2643
|
+
status: "success",
|
|
2644
|
+
theme,
|
|
2645
|
+
message: "Payment successful!",
|
|
2646
|
+
payment: paymentData,
|
|
2647
|
+
transactionHash: "0x123...abc",
|
|
2648
|
+
selectedPaymentMethod: { currency: selectedToken == null ? void 0 : selectedToken.symbol },
|
|
2649
|
+
merchantName: config.merchantName || "Merchant",
|
|
2650
|
+
onClose
|
|
2651
|
+
}
|
|
2652
|
+
) })
|
|
2653
|
+
] }),
|
|
2654
|
+
currentStep !== "success" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center text-xs text-gray-500 flex items-center justify-center gap-1 py-6 bg-white rounded-b-3xl", children: [
|
|
2655
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
2656
|
+
"Powered by ",
|
|
2657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-purple-600", children: "Coinley" }),
|
|
2658
|
+
" - Secure Cryptocurrency Payments"
|
|
2659
|
+
] }),
|
|
2660
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { className: "inline w-4 h-4 text-green-500 ml-1", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: [
|
|
2661
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "2", fill: "none" }),
|
|
2662
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 12l2 2 4-4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
2663
|
+
] })
|
|
2664
|
+
] })
|
|
2665
|
+
] }) }) })
|
|
2666
|
+
] });
|
|
2667
|
+
};
|
|
1839
2668
|
const SimpleCoinleyProvider = ({ children, ...props }) => children;
|
|
1840
|
-
const VERSION = "0.0.
|
|
2669
|
+
const VERSION = "0.0.2";
|
|
1841
2670
|
const utils = {
|
|
1842
2671
|
formatAmount: (amount, decimals = 2) => amount.toFixed(decimals),
|
|
1843
2672
|
truncateAddress: (address, startChars = 6, endChars = 4) => {
|
|
@@ -1882,16 +2711,66 @@ const DEFAULT_CONFIG = {
|
|
|
1882
2711
|
testMode: false,
|
|
1883
2712
|
autoOpen: false
|
|
1884
2713
|
};
|
|
2714
|
+
const USAGE_EXAMPLES = {
|
|
2715
|
+
// Original simple component (still works)
|
|
2716
|
+
simple: `
|
|
2717
|
+
import { SimpleCoinleyPayment } from 'coinley-test';
|
|
2718
|
+
|
|
2719
|
+
<SimpleCoinleyPayment
|
|
2720
|
+
apiKey="your-api-key"
|
|
2721
|
+
apiSecret="your-api-secret"
|
|
2722
|
+
apiUrl="https://your-api-url.com"
|
|
2723
|
+
isOpen={isOpen}
|
|
2724
|
+
config={{
|
|
2725
|
+
amount: 100,
|
|
2726
|
+
customerEmail: "customer@example.com",
|
|
2727
|
+
merchantWalletAddresses: {
|
|
2728
|
+
ethereum: "0x...",
|
|
2729
|
+
bsc: "0x..."
|
|
2730
|
+
}
|
|
2731
|
+
}}
|
|
2732
|
+
onSuccess={(paymentId, txHash, details) => console.log('Success!')}
|
|
2733
|
+
onError={(error) => console.error('Error:', error)}
|
|
2734
|
+
onClose={() => setIsOpen(false)}
|
|
2735
|
+
/>
|
|
2736
|
+
`,
|
|
2737
|
+
// Enhanced component with modern design
|
|
2738
|
+
enhanced: `
|
|
2739
|
+
import { EnhancedSimpleCoinleyPayment } from 'coinley-test';
|
|
2740
|
+
|
|
2741
|
+
<EnhancedSimpleCoinleyPayment
|
|
2742
|
+
apiKey="your-api-key"
|
|
2743
|
+
apiSecret="your-api-secret"
|
|
2744
|
+
apiUrl="https://your-api-url.com"
|
|
2745
|
+
isOpen={isOpen}
|
|
2746
|
+
config={{
|
|
2747
|
+
amount: 100,
|
|
2748
|
+
customerEmail: "customer@example.com",
|
|
2749
|
+
merchantName: "Your Store",
|
|
2750
|
+
merchantWalletAddresses: {
|
|
2751
|
+
ethereum: "0x...",
|
|
2752
|
+
bsc: "0x..."
|
|
2753
|
+
}
|
|
2754
|
+
}}
|
|
2755
|
+
onSuccess={(paymentId, txHash, details) => console.log('Success!')}
|
|
2756
|
+
onError={(error) => console.error('Error:', error)}
|
|
2757
|
+
onClose={() => setIsOpen(false)}
|
|
2758
|
+
theme="light" // or "dark"
|
|
2759
|
+
/>
|
|
2760
|
+
`
|
|
2761
|
+
};
|
|
1885
2762
|
export {
|
|
1886
2763
|
CoinleyCheckout,
|
|
1887
2764
|
CoinleyError,
|
|
1888
2765
|
CoinleyPayment,
|
|
1889
2766
|
CoinleyProvider,
|
|
1890
2767
|
DEFAULT_CONFIG,
|
|
2768
|
+
EnhancedSimpleCoinleyPayment,
|
|
1891
2769
|
PaymentAPI,
|
|
1892
2770
|
SimpleCoinleyPayment,
|
|
1893
2771
|
SimpleCoinleyProvider,
|
|
1894
2772
|
ThemeProvider,
|
|
2773
|
+
USAGE_EXAMPLES,
|
|
1895
2774
|
VERSION,
|
|
1896
2775
|
useCoinley,
|
|
1897
2776
|
utils
|