@enclavemoney/enclave-wallet-sdk
Version:
A simple enclave wallet SDK for React applications
395 lines (394 loc) • 20.3 kB
JavaScript
"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;