UNPKG

@turnkey/react-wallet-kit

Version:

The easiest and most powerful way to integrate Turnkey's Embedded Wallets into your React applications.

324 lines (321 loc) 14.7 kB
import { slicedToArray as _slicedToArray, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator, objectSpread2 as _objectSpread2 } from '../../../_virtual/_rollupPluginBabelHelpers.mjs'; import { jsxs, jsx } from 'react/jsx-runtime'; import { useEffect } from 'react'; import clsx from 'clsx'; import { WalletSource } from '@turnkey/core'; import { useModal } from '../../../providers/modal/Hook.mjs'; import { useTurnkey } from '../../../providers/client/Hook.mjs'; import { isWalletConnect } from '../../../utils/utils.mjs'; import { WalletButton } from './WalletButton.mjs'; import { ExternalWalletChainSelector } from './ExternalWalletChainSelector.mjs'; import { WalletConnectFlow } from './WalletConnectFlow.mjs'; import { canDisconnect } from './utils.mjs'; import { ActionPage } from '../Action.mjs'; import { SuccessPage } from '../../design/Success.mjs'; import { DisconnectWalletScreen } from './DisconnectWalletScreen.mjs'; import { WalletSelectorMode } from '../../../types/base.mjs'; function ExternalWalletSelector(props) { var mode = props.mode; var _useModal = useModal(), pushPage = _useModal.pushPage, popPage = _useModal.popPage, closeModal = _useModal.closeModal, isMobile = _useModal.isMobile; var _useTurnkey = useTurnkey(), walletProviders = _useTurnkey.walletProviders, wallets = _useTurnkey.wallets, loginOrSignupWithWallet = _useTurnkey.loginOrSignupWithWallet, connectWalletAccount = _useTurnkey.connectWalletAccount, disconnectWalletAccount = _useTurnkey.disconnectWalletAccount; // Derive config based on mode var isConnectMode = mode === WalletSelectorMode.Connect; var sessionKey = isConnectMode ? undefined : props.sessionKey; var shouldShowDisconnect = isConnectMode; var successPageDuration = isConnectMode ? props.successPageDuration : undefined; var onSuccess = isConnectMode ? props.onSuccess : undefined; // Auth mode: show ActionPage and call loginOrSignupWithWallet var handleAuthSelect = /*#__PURE__*/function () { var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(provider) { return _regenerator().w(function (_context2) { while (1) switch (_context2.n) { case 0: pushPage({ key: "Wallet Login/Signup", content: jsx(ActionPage, { title: "Authenticating with ".concat(provider.info.name, "..."), action: function () { var _action = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() { return _regenerator().w(function (_context) { while (1) switch (_context.n) { case 0: _context.n = 1; return loginOrSignupWithWallet(_objectSpread2({ walletProvider: provider }, sessionKey && { sessionKey: sessionKey })); case 1: return _context.a(2); } }, _callee); })); function action() { return _action.apply(this, arguments); } return action; }(), icon: jsx("img", { className: "size-11 rounded-full", src: provider.info.icon || "" }) }), showTitle: false }); case 1: return _context2.a(2); } }, _callee2); })); return function handleAuthSelect(_x) { return _ref.apply(this, arguments); }; }(); // Connect mode: show ActionPage, connect wallet, show success var handleConnectSelect = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(provider) { return _regenerator().w(function (_context4) { while (1) switch (_context4.n) { case 0: pushPage({ key: "Connect ".concat(provider.info.name), content: jsx(ActionPage, { title: "Connecting ".concat(provider.info.name), icon: jsx("img", { className: "size-11 rounded-full", src: provider.info.icon || "" }), closeOnComplete: false, action: function () { var _action2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() { var account; return _regenerator().w(function (_context3) { while (1) switch (_context3.n) { case 0: _context3.n = 1; return connectWalletAccount(provider); case 1: account = _context3.v; onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess("connect", account); if (successPageDuration && successPageDuration > 0) { pushPage({ key: "Connecting Success", content: jsx(SuccessPage, { text: "Successfully connected wallet!", onComplete: function onComplete() { return closeModal(); }, duration: successPageDuration }), preventBack: true, showTitle: false }); } else { closeModal(); } case 2: return _context3.a(2); } }, _callee3); })); function action() { return _action2.apply(this, arguments); } return action; }() }), showTitle: false }); case 1: return _context4.a(2); } }, _callee4); })); return function handleConnectSelect(_x2) { return _ref2.apply(this, arguments); }; }(); // Connect mode: show disconnect confirmation, then disconnect var handleDisconnect = /*#__PURE__*/function () { var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(provider) { return _regenerator().w(function (_context6) { while (1) switch (_context6.n) { case 0: pushPage({ key: "Disconnect ".concat(provider.info.name), content: jsx(DisconnectWalletScreen, { provider: provider, onDisconnect: function () { var _onDisconnect = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() { var address, connectedWallets, matchedAccount; return _regenerator().w(function (_context5) { while (1) switch (_context5.n) { case 0: address = provider.connectedAddresses[0]; // Find the matching account from connected wallets connectedWallets = wallets.filter(function (w) { return w.source === WalletSource.Connected; }); matchedAccount = connectedWallets.flatMap(function (w) { return w.accounts; }).find(function (a) { return a.address === address; }); _context5.n = 1; return disconnectWalletAccount(provider); case 1: onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess("disconnect", matchedAccount); if (successPageDuration && successPageDuration > 0) { pushPage({ key: "Disconnect Success", content: jsx(SuccessPage, { text: "Successfully disconnected wallet!", onComplete: function onComplete() { return closeModal(); }, duration: successPageDuration }), preventBack: true, showTitle: false }); } else { closeModal(); } case 2: return _context5.a(2); } }, _callee5); })); function onDisconnect() { return _onDisconnect.apply(this, arguments); } return onDisconnect; }() }), showTitle: false }); case 1: return _context6.a(2); } }, _callee6); })); return function handleDisconnect(_x3) { return _ref3.apply(this, arguments); }; }(); // Select the appropriate handler based on mode var onSelect = isConnectMode ? handleConnectSelect : handleAuthSelect; // Group providers by name var grouped = walletProviders.reduce(function (acc, provider) { var name = provider.info.name; if (!acc[name]) acc[name] = []; acc[name].push(provider); return acc; }, {}); var pushStandardChainSelector = function pushStandardChainSelector(group) { pushPage({ key: "Select chain", content: jsx(ExternalWalletChainSelector, { providers: group, onSelect: onSelect, onDisconnect: isConnectMode ? handleDisconnect : undefined }) }); }; var pushWalletConnectFlow = function pushWalletConnectFlow(group) { pushPage({ key: "WalletConnect", content: jsx(WalletConnectFlow, { providers: group, mode: mode, sessionKey: sessionKey, onDisconnect: isConnectMode ? handleDisconnect : undefined }), showTitle: false }); }; // ───────────────────────────────────────────────────────────────────────────── // Selection handlers // ───────────────────────────────────────────────────────────────────────────── var handleSelectGroup = function handleSelectGroup(group) { var provider = group[0]; var isConnected = !!canDisconnect(provider, shouldShowDisconnect); // Single chain - direct action if (group.length === 1) { if (isConnected) { handleDisconnect(provider); } else { onSelect(provider); } return; } // Multiple chains - need chain selector if (isWalletConnect(provider)) { pushWalletConnectFlow(group); } else { pushStandardChainSelector(group); } }; // ───────────────────────────────────────────────────────────────────────────── // Auto-navigation when only one provider group exists // ───────────────────────────────────────────────────────────────────────────── useEffect(function () { var groupedValues = Object.values(grouped); if (groupedValues.length === 1) { popPage(); // Remove this page to prevent back-button loops handleSelectGroup(groupedValues[0]); } }, [grouped]); // ───────────────────────────────────────────────────────────────────────────── // Render // ───────────────────────────────────────────────────────────────────────────── if (Object.keys(grouped).length === 0) { return jsxs("div", { className: clsx("flex flex-col h-40 mt-4 gap-2 justify-center items-center text-xs text-center text-icon-text-light dark:text-icon-text-dark", isMobile ? "w-full" : "w-80"), children: [jsx("span", { className: "text-sm font-medium", children: "No wallet providers available." }), jsx("span", { children: "Only wallets supporting EIP-1193 (Ethereum) or the Solana wallet standard are supported." })] }); } return jsx("div", { className: clsx("min-h-42 max-h-64 mt-12 overflow-y-auto tk-scrollbar p-0.5", isMobile ? "w-full" : "w-80"), children: jsx("div", { className: "flex flex-col gap-2", children: Object.entries(grouped).map(function (_ref4) { var _first$info$icon, _first$info$name; var _ref5 = _slicedToArray(_ref4, 2), name = _ref5[0], group = _ref5[1]; var first = group[0]; return jsx(WalletButton, { icon: (_first$info$icon = first.info.icon) !== null && _first$info$icon !== void 0 ? _first$info$icon : "", name: (_first$info$name = first.info.name) !== null && _first$info$name !== void 0 ? _first$info$name : "", chains: group.map(function (c) { return { namespace: c.chainInfo.namespace, isConnected: !!canDisconnect(c, shouldShowDisconnect) }; }), onClick: function onClick() { return handleSelectGroup(group); }, shouldShowDisconnect: shouldShowDisconnect, isMobile: isMobile }, name); }) }) }); } export { ExternalWalletSelector, WalletSelectorMode }; //# sourceMappingURL=ExternalWalletSelector.mjs.map