UNPKG

@enclavemoney/enclave-wallet-sdk

Version:

A simple enclave wallet SDK for React applications

870 lines 88.4 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; 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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WalletProvider = exports.useWallet = void 0; var react_1 = __importStar(require("react")); var ui_1 = require("./ui"); var index_1 = __importDefault(require("../index")); var firebase_1 = require("../config/firebase"); var services_1 = require("../services/services"); var quoteServices_1 = require("../services/quoteServices"); var utils_1 = require("./utils"); var theme_1 = require("../types/theme"); // Add Bitcoin mainnet chain ID constant var BITCOIN_MAINNET_CHAIN_ID = 8253038; var WalletContext = (0, react_1.createContext)(null); var useWallet = function () { var context = (0, react_1.useContext)(WalletContext); if (!context) { throw new Error("useWallet must be used within a WalletProvider"); } return context; }; exports.useWallet = useWallet; var WalletProvider = function (_a) { var children = _a.children, config = _a.config; // Extract values from config with defaults var sdkKey = config.sdkKey; var theme = (0, theme_1.mapAppearanceToTheme)(config.appearance); var cornerRadius = (0, theme_1.mapCornerRadius)(config.cornerRadius); var fontFamily = config.fontFamily || "Inter, sans-serif"; var _b = (0, react_1.useState)(null), walletSDK = _b[0], setWalletSDK = _b[1]; var _c = (0, react_1.useState)(false), isLoggedIn = _c[0], setIsLoggedIn = _c[1]; var _d = (0, react_1.useState)(null), username = _d[0], setUsername = _d[1]; var _e = (0, react_1.useState)(null), evmWalletAddress = _e[0], setEvmWalletAddress = _e[1]; var _f = (0, react_1.useState)(null), solanaAddress = _f[0], setSolanaAddress = _f[1]; var _g = (0, react_1.useState)(null), bitcoinWalletAddress = _g[0], setBitcoinWalletAddress = _g[1]; var _h = (0, react_1.useState)(null), balance = _h[0], setBalance = _h[1]; var _j = (0, react_1.useState)(false), showSwapModal = _j[0], setShowSwapModal = _j[1]; var _k = (0, react_1.useState)(null), swapParams = _k[0], setSwapParams = _k[1]; var _l = (0, react_1.useState)([]), tokenOptions = _l[0], setTokenOptions = _l[1]; var _m = (0, react_1.useState)(false), tokensLoading = _m[0], setTokensLoading = _m[1]; // Add transfer-related state var _o = (0, react_1.useState)(null), transferParams = _o[0], setTransferParams = _o[1]; // Add new states for crypto balance functionality var _p = (0, react_1.useState)(null), cryptoBalance = _p[0], setCryptoBalance = _p[1]; var _q = (0, react_1.useState)(false), loading = _q[0], setLoading = _q[1]; var _r = (0, react_1.useState)(false), showActivity = _r[0], setShowActivity = _r[1]; var _s = (0, react_1.useState)(null), activity = _s[0], setActivity = _s[1]; var _t = (0, react_1.useState)(true), showMessagePopup = _t[0], setShowMessagePopup = _t[1]; var _u = (0, react_1.useState)("success"), messageType = _u[0], setMessageType = _u[1]; var _v = (0, react_1.useState)(null), transactionId = _v[0], setTransactionId = _v[1]; var _w = (0, react_1.useState)(theme), walletTheme = _w[0], setWalletTheme = _w[1]; var _x = (0, react_1.useState)(cornerRadius), walletCornerRadius = _x[0], setWalletCornerRadius = _x[1]; // Computed theme that includes primaryColor var _y = (0, react_1.useState)((0, theme_1.getThemeStyles)(config.primaryColor || "#1657FF")[theme]), currentTheme = _y[0], setCurrentTheme = _y[1]; // Update currentTheme when config.primaryColor or theme changes (0, react_1.useEffect)(function () { setCurrentTheme((0, theme_1.getThemeStyles)(config.primaryColor || "#1657FF")[walletTheme]); }, [config.primaryColor, walletTheme]); // Add popup login state var _z = (0, react_1.useState)(false), isPopupAuthenticated = _z[0], setIsPopupAuthenticated = _z[1]; var _0 = (0, react_1.useState)(null), popupLoginData = _0[0], setPopupLoginData = _0[1]; // Function to refresh Firebase token var refreshFirebaseToken = function () { return __awaiter(void 0, void 0, void 0, function () { var currentUser, newIdToken, newRefreshToken, savedLogin, parsedLogin, updatedLogin, error_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, , 4]); currentUser = firebase_1.auth.currentUser; if (!currentUser) return [3 /*break*/, 2]; return [4 /*yield*/, currentUser.getIdToken(true)]; case 1: newIdToken = _a.sent(); newRefreshToken = currentUser.refreshToken; // Update localStorage with new tokens if (typeof window !== "undefined") { savedLogin = localStorage.getItem("enclave_wallet_login"); if (savedLogin) { parsedLogin = JSON.parse(savedLogin); updatedLogin = __assign(__assign({}, parsedLogin), { result: __assign(__assign({}, parsedLogin.result), { token: newIdToken, refreshToken: newRefreshToken }) }); localStorage.setItem("enclave_wallet_login", JSON.stringify(updatedLogin)); console.log("Firebase tokens refreshed successfully"); } } _a.label = 2; case 2: return [3 /*break*/, 4]; case 3: error_1 = _a.sent(); console.error("Error refreshing Firebase token:", error_1); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; var refreshTokenOptions = function () { return __awaiter(void 0, void 0, void 0, function () { var response, error_2; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, 3, 4]); setTokensLoading(true); return [4 /*yield*/, (0, services_1.getAllTokens)(sdkKey)]; case 1: response = _a.sent(); if (response === null || response === void 0 ? void 0 : response.success) { setTokenOptions(response.tokens); } return [3 /*break*/, 4]; case 2: error_2 = _a.sent(); console.error("Error fetching token options:", error_2); return [3 /*break*/, 4]; case 3: setTokensLoading(false); return [7 /*endfinally*/]; case 4: return [2 /*return*/]; } }); }); }; var refreshBalance = function (showLoading) { if (showLoading === void 0) { showLoading = false; } return __awaiter(void 0, void 0, void 0, function () { var sdkInstance, balance_1, error_3; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, 4, 5]); if (showLoading) { setLoading(true); } sdkInstance = window.__walletSDKInstance; if (!sdkInstance) return [3 /*break*/, 2]; return [4 /*yield*/, sdkInstance.getUserCryptoBalance()]; case 1: balance_1 = _a.sent(); if (balance_1) { setCryptoBalance(balance_1); // Store balance in localStorage for persistence if (typeof window !== "undefined" && balance_1 !== null) { localStorage.setItem("enclave_crypto_balance", JSON.stringify(balance_1)); } } _a.label = 2; case 2: return [3 /*break*/, 5]; case 3: error_3 = _a.sent(); console.error("Error fetching balance:", error_3); return [3 /*break*/, 5]; case 4: setLoading(false); return [7 /*endfinally*/]; case 5: return [2 /*return*/]; } }); }); }; // Initialize crypto balance from localStorage on mount (0, react_1.useEffect)(function () { if (typeof window !== "undefined") { var savedBalance = localStorage.getItem("enclave_crypto_balance"); if (savedBalance) { try { setCryptoBalance(JSON.parse(savedBalance)); } catch (error) { console.error("Error parsing saved balance:", error); } } // Initialize popup login data from localStorage var savedPopupLoginData = localStorage.getItem("enclave_popup_login_data"); if (savedPopupLoginData) { try { var parsedData = JSON.parse(savedPopupLoginData); setPopupLoginData(parsedData); setIsPopupAuthenticated(true); } catch (error) { console.error("Error parsing saved popup login data:", error); } } } }, []); // Listen for storage changes to trigger balance refresh (0, react_1.useEffect)(function () { var handleStorageChange = function (e) { if (e.key === "enclave_wallet_login") { if (e.newValue) { refreshBalance(true); refreshTokenOptions(); } else { setCryptoBalance(null); // Clear popup login data when main login is cleared setIsPopupAuthenticated(false); setPopupLoginData(null); // Clear balance from localStorage when user logs out if (typeof window !== "undefined") { localStorage.removeItem("enclave_crypto_balance"); localStorage.removeItem("enclave_popup_login_data"); } } } }; if (typeof window !== "undefined") { window.addEventListener("storage", handleStorageChange); return function () { return window.removeEventListener("storage", handleStorageChange); }; } }, []); // Initial balance load (0, react_1.useEffect)(function () { if (typeof window !== "undefined") { var userSession = localStorage.getItem("enclave_wallet_login"); if (userSession) { refreshBalance(true); // Show loading on initial load } } }, [sdkKey]); // Balance polling effect (0, react_1.useEffect)(function () { if (typeof window !== "undefined") { var userSession = localStorage.getItem("enclave_wallet_login"); if (!userSession) return; var pollInterval_1 = setInterval(function () { refreshBalance(false); // Don't show loading during polling }, 10000); return function () { return clearInterval(pollInterval_1); }; } }, [sdkKey]); // Firebase token refresh effect (0, react_1.useEffect)(function () { if (typeof window !== "undefined") { var userSession = localStorage.getItem("enclave_wallet_login"); if (!userSession) return; // Refresh token every 50 minutes (Firebase tokens typically expire in 1 hour) var tokenRefreshInterval_1 = setInterval(function () { refreshFirebaseToken(); }, 50 * 60 * 1000); // 50 minutes return function () { return clearInterval(tokenRefreshInterval_1); }; } }, []); // Listen for Firebase auth state changes (0, react_1.useEffect)(function () { var unsubscribe = firebase_1.auth.onAuthStateChanged(function (user) { if (user) { // User is signed in, refresh token refreshFirebaseToken(); } else { // User is signed out, clear localStorage if (typeof window !== "undefined") { localStorage.removeItem("enclave_wallet_login"); localStorage.removeItem("enclave_crypto_balance"); localStorage.removeItem("enclave_popup_login_data"); } } }); return function () { return unsubscribe(); }; }, []); (0, react_1.useEffect)(function () { var _a, _b, _c, _d, _e, _f, _g, _h, _j; // Create WalletSDK instance - it will automatically load saved config from localStorage var sdk = new index_1.default(sdkKey, config); setWalletSDK(sdk); // Set the theme and corner radius from the final config (which includes saved preferences) var finalConfig = sdk.getConfig(); var finalTheme = (0, theme_1.mapAppearanceToTheme)(finalConfig.appearance); var finalCornerRadius = (0, theme_1.mapCornerRadius)(finalConfig.cornerRadius); setWalletTheme(finalTheme); setWalletCornerRadius(finalCornerRadius); // Check initial login state and refresh Firebase token if (typeof window !== "undefined") { var saved = localStorage.getItem("enclave_wallet_login"); if (saved) { var parsed = JSON.parse(saved); setIsLoggedIn(true); setUsername(((_a = parsed.result) === null || _a === void 0 ? void 0 : _a.displayName) || ((_b = parsed.result) === null || _b === void 0 ? void 0 : _b.username) || null); setEvmWalletAddress(((_d = (_c = parsed.result) === null || _c === void 0 ? void 0 : _c.wallet) === null || _d === void 0 ? void 0 : _d.scw_address) || null); setSolanaAddress(((_f = (_e = parsed.result) === null || _e === void 0 ? void 0 : _e.wallet) === null || _f === void 0 ? void 0 : _f.solana_program_wallet) || null); setBitcoinWalletAddress(((_j = (_h = (_g = parsed.result) === null || _g === void 0 ? void 0 : _g.wallet) === null || _h === void 0 ? void 0 : _h.bitcoin_wallet) === null || _j === void 0 ? void 0 : _j.native_segwit_address) || null); // Refresh Firebase token on component mount refreshFirebaseToken(); // Fetch initial balance and tokens if logged in refreshBalance(false); refreshTokenOptions(); } } }, [sdkKey, config]); var connect = function () { if (walletSDK) { // Check if domain is localhost:3000 or demo.enclave.money var currentHostname = window.location.hostname; var currentOrigin = window.location.origin; if (currentOrigin === "https://localhost:3000" || currentHostname === "demo.enclave.money" || currentHostname === "localhost" || currentHostname === "app.enclave.money") { walletSDK.openWalletModal(); } else { loginWithRedirect(); } } }; var disconnect = function () { if (walletSDK) { walletSDK.logout(); setIsLoggedIn(false); setUsername(null); setEvmWalletAddress(null); setBalance(null); setCryptoBalance(null); // Clear popup login data setIsPopupAuthenticated(false); setPopupLoginData(null); // Clear balance from localStorage when user disconnects if (typeof window !== "undefined") { firebase_1.auth.signOut(); localStorage.removeItem("enclave_wallet_login"); localStorage.removeItem("enclave_crypto_balance"); localStorage.removeItem("enclave_popup_login_data"); } } }; // Listen for session changes and update balance (0, react_1.useEffect)(function () { if (!walletSDK) return; var checkSession = function () { return __awaiter(void 0, void 0, void 0, function () { var saved, parsed, sdkInstance; var _a, _b, _c, _d, _e, _f, _g, _h, _j; return __generator(this, function (_k) { if (typeof window !== "undefined") { saved = localStorage.getItem("enclave_wallet_login"); if (saved) { parsed = JSON.parse(saved); setIsLoggedIn(true); setUsername(((_a = parsed.result) === null || _a === void 0 ? void 0 : _a.displayName) || ((_b = parsed.result) === null || _b === void 0 ? void 0 : _b.username) || null); setEvmWalletAddress(((_d = (_c = parsed.result) === null || _c === void 0 ? void 0 : _c.wallet) === null || _d === void 0 ? void 0 : _d.scw_address) || null); setSolanaAddress(((_f = (_e = parsed.result) === null || _e === void 0 ? void 0 : _e.wallet) === null || _f === void 0 ? void 0 : _f.solana_program_wallet) || null); setBitcoinWalletAddress(((_j = (_h = (_g = parsed.result) === null || _g === void 0 ? void 0 : _g.wallet) === null || _h === void 0 ? void 0 : _h.bitcoin_wallet) === null || _j === void 0 ? void 0 : _j.native_segwit_address) || null); // Fetch updated balance } else { setIsLoggedIn(false); setUsername(null); setEvmWalletAddress(null); setBalance(null); setCryptoBalance(null); setSolanaAddress(null); setBitcoinWalletAddress(null); sdkInstance = window.__walletSDKInstance; if (sdkInstance) { sdkInstance.setUsername(null); } // Clear balance from localStorage when session is not found localStorage.removeItem("enclave_crypto_balance"); } } return [2 /*return*/]; }); }); }; // Check session every 1 seconds var interval = setInterval(checkSession, 1000); return function () { return clearInterval(interval); }; }, [walletSDK]); var swap = function (params) { if (!isLoggedIn) { connect(); return; } setSwapParams(params); setShowSwapModal(true); walletSDK === null || walletSDK === void 0 ? void 0 : walletSDK.openWalletModal(params); }; var executeTransfer = function (params) { if (!isLoggedIn) { connect(); return; } setTransferParams(params); walletSDK === null || walletSDK === void 0 ? void 0 : walletSDK.openWalletModal(undefined, params); }; var executeHeadlessTransfer = function (params) { return __awaiter(void 0, void 0, void 0, function () { var sdkInstance, userName, loadingToast, tokenFromBalance, isBitcoin, tokenData, response, btcTransferParams, chainData, transferParams_1, btcResponse, transferInitiatedToast_1, multiTransactionId_1, pollTransactionStatus, transferResponse, transactionId_1, successToastId_1, error_4; var _a, _b, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: sdkInstance = window.__walletSDKInstance; if (!sdkInstance) { throw new Error("SDK instance not found"); } userName = sdkInstance.getUsername(); if (!userName) { throw new Error("User not logged in"); } loadingToast = ui_1.toast.loading("Processing transfer..."); _d.label = 1; case 1: _d.trys.push([1, 6, , 7]); tokenFromBalance = null; if (cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.data) { tokenFromBalance = cryptoBalance.data.find(function (token) { var _a; return (_a = token.chainIds) === null || _a === void 0 ? void 0 : _a.some(function (chain) { return chain.address.toLowerCase() === params.inputToken.address.toLowerCase() && chain.chainId === params.inputToken.chainId; }); }); } isBitcoin = (tokenFromBalance === null || tokenFromBalance === void 0 ? void 0 : tokenFromBalance.chainId) === BITCOIN_MAINNET_CHAIN_ID && (tokenFromBalance === null || tokenFromBalance === void 0 ? void 0 : tokenFromBalance.symbol) === "BTC"; tokenData = tokenFromBalance || { symbol: params.inputToken.symbol || "", name: params.inputToken.name || "", decimals: params.inputToken.decimals || (isBitcoin ? 8 : 6), logoURI: params.inputToken.logoURI || "", chainIds: params.inputToken.chainIds || [ { chainId: params.inputToken.chainId, address: params.inputToken.address, balance: params.inputToken.balance || "0", }, ], }; response = void 0; if (!isBitcoin) return [3 /*break*/, 3]; btcTransferParams = { username: userName, inputAmount: params.inputAmount || "0", recipient: params.recipient, outputChainId: params.inputToken.chainId, metadata: { token: { tokenSymbol: tokenData.symbol, tokenName: tokenData.name, decimals: tokenData.decimals, logoURI: tokenData.logoURI, }, receiver: { username: "", walletAddress: params.recipient, solanaWalletAddress: "", ensName: "", sns: "", }, }, }; return [4 /*yield*/, (0, services_1.executeBitcoinTransfer)(btcTransferParams, sdkKey)]; case 2: response = _d.sent(); return [3 /*break*/, 5]; case 3: chainData = (_a = tokenData.chainIds) === null || _a === void 0 ? void 0 : _a.find(function (chain) { return chain.chainId === params.inputToken.chainId; }); transferParams_1 = { username: userName, inputAmount: params.inputAmount || "0", outputToken: (chainData === null || chainData === void 0 ? void 0 : chainData.address) || params.inputToken.address, outputDecimals: tokenData.decimals, outputChainId: params.inputToken.chainId, recipient: params.recipient, userBalance: tokenData.chainIds || [ { chainId: params.inputToken.chainId, address: params.inputToken.address, balance: params.inputToken.balance || "0", }, ], metadata: { token: { tokenSymbol: tokenData.symbol, tokenName: tokenData.name, decimals: tokenData.decimals, logoURI: tokenData.logoURI, }, receiver: { username: "", walletAddress: params.recipient, solanaWalletAddress: "", ensName: "", sns: "", }, }, }; return [4 /*yield*/, (0, services_1.executeTransferFlow)(transferParams_1, sdkKey)]; case 4: response = _d.sent(); _d.label = 5; case 5: // Dismiss loading toast ui_1.toast.dismiss(loadingToast); if (isBitcoin) { btcResponse = response; if (btcResponse.success && ((_b = btcResponse.transactionDetails) === null || _b === void 0 ? void 0 : _b.multiTransactionId)) { console.log("Bitcoin transfer initiated:", btcResponse); transferInitiatedToast_1 = ui_1.toast.loading("Transfer initiated..."); setActivity(btcResponse); multiTransactionId_1 = btcResponse.transactionDetails.multiTransactionId; pollTransactionStatus = function () { return __awaiter(void 0, void 0, void 0, function () { var isCompleted, attempts, maxAttempts, _loop_1; return __generator(this, function (_a) { switch (_a.label) { case 0: isCompleted = false; attempts = 0; maxAttempts = 60; _loop_1 = function () { var transactionInfo, status_1, successToastId_2, error_5; return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 3, , 4]); return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 5000); })]; case 1: _b.sent(); // Wait 5 seconds return [4 /*yield*/, (0, services_1.getTransactionInfo)(multiTransactionId_1, sdkKey)]; case 2: transactionInfo = _b.sent(); if (transactionInfo) { status_1 = transactionInfo.overallStatus; if (status_1 === "COMPLETED") { ui_1.toast.dismiss(transferInitiatedToast_1); successToastId_2 = ui_1.toast.success(react_1.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "12px", } }, react_1.default.createElement("span", null, "Transfer completed"), react_1.default.createElement("button", { onClick: function () { if (walletSDK) { // Store the transaction data in localStorage if (typeof window !== "undefined") { localStorage.setItem("enclave_transaction_data", JSON.stringify({ transactionId: multiTransactionId_1, })); } walletSDK.openWalletModal(); } ui_1.toast.dismiss(successToastId_2); }, style: { color: "white", borderRadius: "20px", padding: "4px 8px", fontSize: "13px", fontWeight: "500", cursor: "pointer", background: "black", border: "1px solid rgba(255, 255, 255, 0.33)", } }, "View")), { duration: 6000 }); isCompleted = true; // Refresh balance after successful completion refreshBalance(false); } else if (status_1 === "FAILED") { ui_1.toast.dismiss(transferInitiatedToast_1); ui_1.toast.error("Transfer failed"); isCompleted = true; } // If status is still PENDING, continue polling } attempts++; return [3 /*break*/, 4]; case 3: error_5 = _b.sent(); console.error("Error polling transaction status:", error_5); attempts++; return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }; _a.label = 1; case 1: if (!(!isCompleted && attempts < maxAttempts)) return [3 /*break*/, 3]; return [5 /*yield**/, _loop_1()]; case 2: _a.sent(); return [3 /*break*/, 1]; case 3: // If polling times out if (!isCompleted) { ui_1.toast.dismiss(transferInitiatedToast_1); ui_1.toast.error("Transfer status check timed out"); } return [2 /*return*/]; } }); }); }; // Start polling in background pollTransactionStatus(); } else { console.error("Bitcoin transfer failed:", btcResponse); ui_1.toast.error("Bitcoin transfer failed"); } } else { transferResponse = response; if (transferResponse.outputDetails && (transferResponse.onChainTransfer || transferResponse.relayTransfer)) { console.log("Transfer completed:", transferResponse); transactionId_1 = ((_c = transferResponse.transactionDetails) === null || _c === void 0 ? void 0 : _c.multiTransactionId) || ""; successToastId_1 = ui_1.toast.success(react_1.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "12px", } }, react_1.default.createElement("span", null, "Transfer completed"), transactionId_1 && (react_1.default.createElement("button", { onClick: function () { if (walletSDK) { // Store the transaction data in localStorage if (typeof window !== "undefined") { localStorage.setItem("enclave_transaction_data", JSON.stringify({ transactionId: transactionId_1, })); } walletSDK.openWalletModal(); } ui_1.toast.dismiss(successToastId_1); }, style: { color: "white", borderRadius: "20px", padding: "4px 8px", fontSize: "13px", fontWeight: "500", cursor: "pointer", background: "black", border: "1px solid rgba(255, 255, 255, 0.33)", } }, "View"))), { duration: 6000 }); // Refresh balance after successful completion refreshBalance(false); } else { console.error("Transfer failed:", transferResponse); ui_1.toast.error("Transfer failed"); } } return [2 /*return*/, response]; case 6: error_4 = _d.sent(); console.error("Error executing headless transfer:", error_4); // Dismiss loading toast and show error toast ui_1.toast.dismiss(loadingToast); ui_1.toast.error("Transfer failed"); throw error_4; case 7: return [2 /*return*/]; } }); }); }; // Add unified calculateQuote function var calculateQuoteWrapper = function (params) { return __awaiter(void 0, void 0, void 0, function () { var sdkInstance, userName, requestParams, error_6; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); sdkInstance = window.__walletSDKInstance; if (!sdkInstance) { throw new Error("SDK instance not found"); } userName = sdkInstance.getUsername(); if (!userName) { throw new Error("User not logged in"); } requestParams = __assign({ username: userName, fromTokens: params.fromTokens, toToken: params.toToken, quoteType: params.quoteType }, (params.action && { action: params.action })); return [4 /*yield*/, (0, quoteServices_1.calculateQuote)(requestParams, sdkKey)]; case 1: return [2 /*return*/, _a.sent()]; case 2: error_6 = _a.sent(); console.error("Error calculating quote:", error_6); return [2 /*return*/, null]; case 3: return [2 /*return*/]; } }); }); }; // Add unified executeSwap function var executeSwap = function (params) { return __awaiter(void 0, void 0, void 0, function () { var sdkInstance, userName, requestParams, error_7; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); sdkInstance = window.__walletSDKInstance; if (!sdkInstance) { throw new Error("SDK instance not found"); } userName = sdkInstance.getUsername(); if (!userName) { throw new Error("User not logged in"); } requestParams = __assign({ username: userName, fromTokens: params.fromTokens, toToken: params.toToken, isHeadless: params.isHeadless, quoteChoice: params.quoteChoice, quoteType: params.quoteType, quoteId: params.quoteId }, (params.action && { action: params.action })); return [4 /*yield*/, (0, quoteServices_1.executeSwapQuote)(requestParams, sdkKey)]; case 1: return [2 /*return*/, _a.sent()]; case 2: error_7 = _a.sent(); console.error("Error executing quote:", error_7); return [2 /*return*/, null]; case 3: return [2 /*return*/]; } }); }); }; var openWalletModal = function () { if (walletSDK) { walletSDK.openWalletModal(); } }; // Add initial token fetch (0, react_1.useEffect)(function () { refreshTokenOptions(); }, [sdkKey]); // Add token refresh on login/logout (0, react_1.useEffect)(function () { if (isLoggedIn) { refreshBalance(true); } else { setTokenOptions([]); } }, [isLoggedIn]); // Add quote calculation function var calculateDemoQuote = function (params) { return __awaiter(void 0, void 0, void 0, function () { var sdkInstance, userName, metadata, userBalance, defaultBalance, userBalance, defaultBalance, userBalance, defaultBalance, metadata, error_8; var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u; return __generator(this, function (_v) { switch (_v.label) { case 0: sdkInstance = window.__walletSDKInstance; if (!sdkInstance) { throw new Error("SDK instance not found"); } userName = sdkInstance.getUsername(); if (!userName) { throw new Error("User not logged in"); } _v.label = 1; case 1: _v.trys.push([1, 8, , 9]); if (!(params.fromToken.chainId === BITCOIN_MAINNET_CHAIN_ID)) return [3 /*break*/, 3]; metadata = { inputToken: { tokenName: ((_a = params.fromToken.metadata) === null || _a === void 0 ? void 0 : _a.tokenName) || "", tokenSymbol: ((_b = params.fromToken.metadata) === null || _b === void 0 ? void 0 : _b.tokenSymbol) || "", tokenAddress: params.fromToken.tokenAddress, decimals: ((_c = params.fromToken.metadata) === null || _c === void 0 ? void 0 : _c.decimals) || 0, logoURI: ((_d = params.fromToken.metadata) === null || _d === void 0 ? void 0 : _d.logoURI) || "", }, outputToken: { tokenName: ((_e = params.toToken.metadata) === null || _e === void 0 ? void 0 : _e.tokenName) || "", tokenSymbol: ((_f = params.toToken.metadata) === null || _f === void 0 ? void 0 : _f.tokenSymbol) || "", tokenAddress: params.toToken.tokenAddress, decimals: ((_g = params.toToken.metadata) === null || _g === void 0 ? void 0 : _g.decimals) || 0, logoURI: ((_h = params.toToken.metadata) === null || _h === void 0 ? void 0 : _h.logoURI) || "", }, }; userBalance = (_j = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.data) === null || _j === void 0 ? void 0 : _j.find(function (token) { var _a; return (_a = token.chainIds) === null || _a === void 0 ? void 0 : _a.some(function (chain) { return chain.address.toLowerCase() === params.fromToken.tokenAddress.toLowerCase() && chain.chainId === params.fromToken.chainId; }); }); defaultBalance = [ { chainId: params.fromToken.chainId, address: params.fromToken.tokenAddress, balance: "0", }, ]; return [4 /*yield*/, (0, services_1.getMultiFromBTCLifiSwapQuote)({ username: userName, inputAmount: params.fromToken.amount, outputToken: params.toToken.tokenAddress, outputChainId: params.toToken.chainId, metadata: metadata, proMode: false, userBalance: (userBalance === null || userBalance === void 0 ? void 0 : userBalance.chainIds) || defaultBalance, }, sdkKey)]; case 2: return [2 /*return*/, _v.sent()]; case 3: if (!(params.toToken.chainId === BITCOIN_MAINNET_CHAIN_ID)) return [3 /*break*/, 5]; userBalance = (_k = cryptoBalance === null || cryptoBalance === void 0 ? void 0 : cryptoBalance.data) === null || _k === void 0 ? void 0 : _k.find(function (token) { var _a; return (_a = token.chainIds) === null || _a === void 0 ? void 0 : _a.some(function (chain) { return chain.address.toLowerCase() === params.fromToken.tokenAddress.toLowerCase() && chain.chainId === params.fromToken.chainId; }); }); defaultBalance = [ { chainId: params.from