UNPKG

@enclavemoney/enclave-wallet-sdk

Version:

A simple enclave wallet SDK for React applications

395 lines (394 loc) 20.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Dashboard = void 0; var react_1 = __importStar(require("react")); var lucide_react_1 = require("lucide-react"); var QRNetworks_1 = require("../ui/QRNetworks"); var Activity_1 = __importDefault(require("../Activity/Activity")); var Spinner_1 = __importDefault(require("../ui/Spinner")); var WalletProvider_1 = require("../WalletProvider"); var TokenLogo_1 = require("../ui/TokenLogo"); var theme_1 = require("../../types/theme"); var Dashboard = function (_a) { var _b, _c, _d, _e, _f, _g; var result = _a.result, onLogout = _a.onLogout, onShowSwap = _a.onShowSwap, onShowTransfer = _a.onShowTransfer, sdkKey = _a.sdkKey, _h = _a.theme, theme = _h === void 0 ? "dark" : _h; var currentTheme = theme_1.themeStyles[theme]; var walletCornerRadius = (0, WalletProvider_1.useWallet)().walletCornerRadius; var currentRadius = theme_1.borderRadiusStyles[walletCornerRadius]; var _j = (0, react_1.useState)("assets"), activeTab = _j[0], setActiveTab = _j[1]; var _k = (0, react_1.useState)(false), showQRCode = _k[0], setShowQRCode = _k[1]; var _l = (0, react_1.useState)(false), drawerOpen = _l[0], setDrawerOpen = _l[1]; var _m = (0, WalletProvider_1.useWallet)(), cryptoBalance = _m.cryptoBalance, loading = _m.loading, refreshBalance = _m.refreshBalance, username = _m.username, evmWalletAddress = _m.evmWalletAddress, solanaAddress = _m.solanaAddress, bitcoinWalletAddress = _m.bitcoinWalletAddress; // Trigger immediate balance refresh when dashboard mounts (0, react_1.useEffect)(function () { if (username && !cryptoBalance) { refreshBalance(); } }, [username]); // Add CSS to hide scrollbars react_1.default.useEffect(function () { var style = document.createElement("style"); style.textContent = "\n .hide-scrollbar {\n -ms-overflow-style: none; /* IE and Edge */\n scrollbar-width: none; /* Firefox */\n }\n .hide-scrollbar::-webkit-scrollbar {\n display: none; /* Chrome, Safari, Opera */\n }\n \n .dashboard-button {\n transition: all 0.2s ease-in-out;\n }\n \n .dashboard-button:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n border-color: ".concat(currentTheme.primary, ";\n color: ").concat(currentTheme.text, " !important;\n opacity: 0.8 !important;\n }\n \n .dashboard-button:hover svg {\n color: ").concat(currentTheme.text, ";\n }\n "); document.head.appendChild(style); return function () { document.head.removeChild(style); }; }, []); var truncateAddress = function (address) { if (!address) return ""; return address.slice(0, 6) + "..." + address.slice(-4); }; var calculateTotalBalance = function () { var total = 0; if (cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.data) { total += cryptoBalance.data.reduce(function (sum, token) { return sum + (token.valueUsd || 0); }, 0); } return total.toFixed(2); }; var assets = __spreadArray([], (((_b = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.data) === null || _b === void 0 ? void 0 : _b.map(function (token) { return ({ name: token.name, icon: token.logoURI, amount: token.amount, valueUSD: token.valueUsd ? token.valueUsd.toFixed(2) : 0, symbol: token.symbol, priceUsd: token.priceUsd, priceChange: 0, priceChangePercentage24h: token.priceChangePercentage24h, valueChange24h: token.valueChange24h, type: "crypto", }); })) || []), true); // Sort assets by USD value in descending order var sortedAssets = assets.sort(function (a, b) { var valueA = parseFloat(a.valueUSD) || 0; var valueB = parseFloat(b.valueUSD) || 0; return valueB - valueA; // Descending order (highest value first) }); var dasboardButtons = [ { label: "Deposit", icon: react_1.default.createElement(lucide_react_1.QrCode, { size: 16 }), onClick: function () { setShowQRCode(true); }, }, { label: "Transfer", icon: react_1.default.createElement(lucide_react_1.Send, { size: 16 }), onClick: function () { return onShowTransfer(); }, }, // { // label: "Buy", // icon: <ShoppingCart size={18} />, // onClick: () => {}, // }, // { // label: "Sell", // icon: <Tag size={18} />, // onClick: () => {}, // }, { label: "Swap", icon: react_1.default.createElement(lucide_react_1.ArrowLeftRight, { size: 16 }), onClick: function () { onShowSwap(); }, }, ]; var handleLogout = function () { // Get the SDK instance from window var walletSDK = window.__walletSDKInstance; if (walletSDK) { walletSDK.logout(); } // Call the parent's onLogout callback onLogout(); }; return (react_1.default.createElement("div", { style: { width: "100%", margin: "0 auto", background: currentTheme.surface, borderRadius: 20, height: "550px", } }, showQRCode ? (react_1.default.createElement(QRNetworks_1.QRNetworks, { walletAddress: evmWalletAddress || "", solanaAddress: solanaAddress || "", bitcoinWalletAddress: bitcoinWalletAddress || "", onBack: function () { return setShowQRCode(false); }, theme: theme })) : (react_1.default.createElement("div", null, react_1.default.createElement("div", { style: { fontWeight: 600, fontSize: 18, marginBottom: 10, display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", } }, react_1.default.createElement("span", { style: { fontSize: 18, color: currentTheme.text, fontWeight: 400, } }, "Wallet Dashboard"), react_1.default.createElement("span", { style: { padding: "4px 8px", fontSize: 14, fontWeight: 400, color: currentTheme.text, borderRadius: 40, background: currentTheme.surface, display: "flex", alignItems: "center", gap: 4, position: "relative", cursor: "pointer", border: "1px solid ".concat(currentTheme.border), }, onClick: function () { return setDrawerOpen(function (v) { return !v; }); } }, react_1.default.createElement("div", { style: { background: currentTheme.surface, width: 16, height: 16, borderRadius: 100, display: "flex", alignItems: "center", justifyContent: "center", } }, (result === null || result === void 0 ? void 0 : result.photoURL) ? (react_1.default.createElement("img", { src: result === null || result === void 0 ? void 0 : result.photoURL, alt: "user", style: { width: 16, height: 16, borderRadius: 100 } })) : (react_1.default.createElement(lucide_react_1.CircleUserRound, { style: { width: 16, height: 16, color: currentTheme.text } }))), username, react_1.default.createElement(lucide_react_1.ChevronDown, { size: 16 }), drawerOpen && (react_1.default.createElement("div", { style: { position: "absolute", top: 36, right: 0, background: currentTheme.surface, boxShadow: "0 4px 16px rgba(0,0,0,0.10)", borderRadius: 10, minWidth: 120, zIndex: 10, padding: "8px 0", display: "flex", flexDirection: "column", alignItems: "stretch", border: "1px solid ".concat(currentTheme.border), } }, react_1.default.createElement("button", { onClick: handleLogout, style: { background: "none", border: "none", color: "#E53E3E", fontWeight: 400, fontSize: 15, padding: "10px 20px", textAlign: "left", cursor: "pointer", display: "flex", alignItems: "center", gap: 8, } }, react_1.default.createElement(lucide_react_1.LogOut, { size: 16 }), " Logout"))))), react_1.default.createElement("div", { style: { fontSize: 32, fontWeight: 500, color: currentTheme.text, } }, "$", (_c = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.portfolioSummary) === null || _c === void 0 ? void 0 : _c.totalValueUsd.toFixed(2)), react_1.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: 12, justifyContent: "space-between", marginBottom: 12, } }, react_1.default.createElement("div", { style: { color: ((_d = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.portfolioSummary) === null || _d === void 0 ? void 0 : _d.weightedPriceChangePercentage24h) > 0 ? currentTheme.successText : currentTheme.errorText, fontSize: 14, } }, ((_e = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.portfolioSummary) === null || _e === void 0 ? void 0 : _e.weightedPriceChangePercentage24h) > 0 ? "↑" : "↓", " ", (_f = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.portfolioSummary) === null || _f === void 0 ? void 0 : _f.weightedPriceChangePercentage24h.toFixed(2), "% ($", (_g = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.portfolioSummary) === null || _g === void 0 ? void 0 : _g.weightedPriceChange24hUsd.toFixed(2), ")", " ", react_1.default.createElement("span", { style: { color: currentTheme.textSecondary } }, "in last 24hrs"))), react_1.default.createElement("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8, marginBottom: 16, } }, dasboardButtons.map(function (action, i) { return (react_1.default.createElement("button", { key: i, onClick: action.onClick, style: { padding: "16px 2px", borderRadius: currentRadius.innerRadius, border: "1px solid ".concat(currentTheme.border), background: theme === "dark" ? currentTheme.surfaceActive : "#FAFAFA", fontSize: 13, fontWeight: 400, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", gap: 4, color: currentTheme.textSecondary, outline: "none", }, className: "dashboard-button" }, action.icon, action.label)); })), react_1.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 12, border: "1px solid ".concat(currentTheme.border), borderRadius: currentRadius.innerRadius, overflow: "hidden", background: theme === "dark" ? currentTheme.surfaceHover : "#FAFAFA", height: 56, } }, react_1.default.createElement("button", { onClick: function () { return setActiveTab("assets"); }, style: { fontSize: 14, flex: 1, borderRadius: currentRadius.innerRadius, margin: 4, background: activeTab === "assets" ? currentTheme.surface : theme === "dark" ? currentTheme.surfaceHover : "#FAFAFA", fontWeight: 600, border: "none", color: activeTab === "assets" ? currentTheme.text : currentTheme.textSecondary, boxShadow: activeTab === "assets" ? "0 4px 12px rgba(0,0,0,0.05)" : "none", cursor: "pointer", } }, "Assets"), react_1.default.createElement("button", { onClick: function () { return setActiveTab("activity"); }, style: { fontSize: 14, flex: 1, borderRadius: currentRadius.innerRadius, margin: 4, boxShadow: activeTab === "activity" ? "0 4px 12px rgba(0,0,0,0.05)" : "none", background: activeTab === "activity" ? currentTheme.surface : theme === "dark" ? currentTheme.surfaceHover : "#FAFAFA", fontWeight: 600, border: "none", color: activeTab === "activity" ? currentTheme.text : currentTheme.textSecondary, position: "relative", cursor: "pointer", } }, "Activity")), activeTab === "assets" ? (react_1.default.createElement("div", { className: "hide-scrollbar", style: { minHeight: 320, maxHeight: 320, overflowY: sortedAssets.length > 0 ? "auto" : "hidden", marginBottom: 24, } }, loading && !cryptoBalance ? (react_1.default.createElement("div", { style: { height: 320, display: "flex", alignItems: "center", justifyContent: "center", } }, react_1.default.createElement(Spinner_1.default, { theme: theme }))) : sortedAssets.length === 0 ? (react_1.default.createElement("div", { style: { height: 260, display: "flex", alignItems: "center", justifyContent: "center", color: currentTheme.textSecondary, fontSize: 16, marginBottom: 24, gap: 8, flexDirection: "column", } }, react_1.default.createElement(lucide_react_1.HandCoins, { size: 20 }), "No assets found")) : (sortedAssets.map(function (asset, idx) { return (react_1.default.createElement("div", { key: idx, style: { padding: "2px 0px", borderBottom: idx !== sortedAssets.length - 1 ? "1px solid ".concat(currentTheme.border) : "none", } }, react_1.default.createElement("div", { style: { display: "flex", alignItems: "center", padding: "12px", } }, react_1.default.createElement("div", { style: { marginRight: 12 } }, react_1.default.createElement(TokenLogo_1.TokenLogo, { logoURI: asset.icon, symbol: asset.symbol, name: asset.name, size: 36 })), react_1.default.createElement("div", { style: { flexGrow: 1 } }, react_1.default.createElement("div", { style: { fontWeight: 600, color: currentTheme.text, fontSize: 16, } }, asset.name), react_1.default.createElement("div", { style: { color: asset.priceChangePercentage24h > 0 ? currentTheme.successText : currentTheme.errorText, fontSize: 13, } }, asset.priceChangePercentage24h > 0 ? "↑" : "↓", " ", asset.priceChangePercentage24h.toFixed(2), "% ($", asset.valueChange24h.toFixed(2), ")")), react_1.default.createElement("div", { style: { textAlign: "right" } }, react_1.default.createElement("div", { style: { fontWeight: 600, color: currentTheme.text } }, Number(asset.valueUSD) < 0.01 ? "$<0.01" : "$".concat(asset.valueUSD)), react_1.default.createElement("div", { style: { fontSize: 13, color: currentTheme.textSecondary, } }, Number(asset.amount).toFixed(6), " ", asset.symbol))))); })))) : (react_1.default.createElement("div", { className: "hide-scrollbar", style: { textAlign: "center", height: 320, color: currentTheme.textSecondary, fontSize: 16, marginBottom: 24, } }, react_1.default.createElement(Activity_1.default, { sdkKey: sdkKey, theme: theme }))))))); }; exports.Dashboard = Dashboard;