UNPKG

@turnkey/react-wallet-kit

Version:

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

234 lines (230 loc) 9.44 kB
'use strict'; var jsxRuntime = require('react/jsx-runtime'); var react = require('react'); var clsx = require('clsx'); var core = require('@turnkey/core'); var Hook = require('../../../providers/modal/Hook.js'); var Hook$1 = require('../../../providers/client/Hook.js'); var utils$1 = require('../../../utils/utils.js'); var WalletButton = require('./WalletButton.js'); var ExternalWalletChainSelector = require('./ExternalWalletChainSelector.js'); var WalletConnectFlow = require('./WalletConnectFlow.js'); var utils = require('./utils.js'); var Action = require('../Action.js'); var Success = require('../../design/Success.js'); var DisconnectWalletScreen = require('./DisconnectWalletScreen.js'); var base = require('../../../types/base.js'); function ExternalWalletSelector(props) { const { mode } = props; const { pushPage, popPage, closeModal, isMobile } = Hook.useModal(); const { walletProviders, wallets, loginOrSignupWithWallet, connectWalletAccount, disconnectWalletAccount } = Hook$1.useTurnkey(); // Derive config based on mode const isConnectMode = mode === base.WalletSelectorMode.Connect; const sessionKey = isConnectMode ? undefined : props.sessionKey; const shouldShowDisconnect = isConnectMode; const successPageDuration = isConnectMode ? props.successPageDuration : undefined; const onSuccess = isConnectMode ? props.onSuccess : undefined; // Auth mode: show ActionPage and call loginOrSignupWithWallet const handleAuthSelect = async provider => { pushPage({ key: "Wallet Login/Signup", content: jsxRuntime.jsx(Action.ActionPage, { title: `Authenticating with ${provider.info.name}...`, action: async () => { await loginOrSignupWithWallet({ walletProvider: provider, ...(sessionKey && { sessionKey }) }); }, icon: jsxRuntime.jsx("img", { className: "size-11 rounded-full", src: provider.info.icon || "" }) }), showTitle: false }); }; // Connect mode: show ActionPage, connect wallet, show success const handleConnectSelect = async provider => { pushPage({ key: `Connect ${provider.info.name}`, content: jsxRuntime.jsx(Action.ActionPage, { title: `Connecting ${provider.info.name}`, icon: jsxRuntime.jsx("img", { className: "size-11 rounded-full", src: provider.info.icon || "" }), closeOnComplete: false, action: async () => { const account = await connectWalletAccount(provider); onSuccess?.("connect", account); if (successPageDuration && successPageDuration > 0) { pushPage({ key: "Connecting Success", content: jsxRuntime.jsx(Success.SuccessPage, { text: "Successfully connected wallet!", onComplete: () => closeModal(), duration: successPageDuration }), preventBack: true, showTitle: false }); } else { closeModal(); } } }), showTitle: false }); }; // Connect mode: show disconnect confirmation, then disconnect const handleDisconnect = async provider => { pushPage({ key: `Disconnect ${provider.info.name}`, content: jsxRuntime.jsx(DisconnectWalletScreen.DisconnectWalletScreen, { provider: provider, onDisconnect: async () => { const address = provider.connectedAddresses[0]; // Find the matching account from connected wallets const connectedWallets = wallets.filter(w => w.source === core.WalletSource.Connected); const matchedAccount = connectedWallets.flatMap(w => w.accounts).find(a => a.address === address); await disconnectWalletAccount(provider); onSuccess?.("disconnect", matchedAccount); if (successPageDuration && successPageDuration > 0) { pushPage({ key: "Disconnect Success", content: jsxRuntime.jsx(Success.SuccessPage, { text: "Successfully disconnected wallet!", onComplete: () => closeModal(), duration: successPageDuration }), preventBack: true, showTitle: false }); } else { closeModal(); } } }), showTitle: false }); }; // Select the appropriate handler based on mode const onSelect = isConnectMode ? handleConnectSelect : handleAuthSelect; // Group providers by name const grouped = walletProviders.reduce((acc, provider) => { const name = provider.info.name; if (!acc[name]) acc[name] = []; acc[name].push(provider); return acc; }, {}); const pushStandardChainSelector = group => { pushPage({ key: `Select chain`, content: jsxRuntime.jsx(ExternalWalletChainSelector.ExternalWalletChainSelector, { providers: group, onSelect: onSelect, onDisconnect: isConnectMode ? handleDisconnect : undefined }) }); }; const pushWalletConnectFlow = group => { pushPage({ key: "WalletConnect", content: jsxRuntime.jsx(WalletConnectFlow.WalletConnectFlow, { providers: group, mode: mode, sessionKey: sessionKey, onDisconnect: isConnectMode ? handleDisconnect : undefined }), showTitle: false }); }; // ───────────────────────────────────────────────────────────────────────────── // Selection handlers // ───────────────────────────────────────────────────────────────────────────── const handleSelectGroup = group => { const provider = group[0]; const isConnected = !!utils.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 (utils$1.isWalletConnect(provider)) { pushWalletConnectFlow(group); } else { pushStandardChainSelector(group); } }; // ───────────────────────────────────────────────────────────────────────────── // Auto-navigation when only one provider group exists // ───────────────────────────────────────────────────────────────────────────── react.useEffect(() => { const 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 jsxRuntime.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: [jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "No wallet providers available." }), jsxRuntime.jsx("span", { children: "Only wallets supporting EIP-1193 (Ethereum) or the Solana wallet standard are supported." })] }); } return jsxRuntime.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: jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: Object.entries(grouped).map(([name, group]) => { const first = group[0]; return jsxRuntime.jsx(WalletButton.WalletButton, { icon: first.info.icon ?? "", name: first.info.name ?? "", chains: group.map(c => ({ namespace: c.chainInfo.namespace, isConnected: !!utils.canDisconnect(c, shouldShowDisconnect) })), onClick: () => handleSelectGroup(group), shouldShowDisconnect: shouldShowDisconnect, isMobile: isMobile }, name); }) }) }); } Object.defineProperty(exports, "WalletSelectorMode", { enumerable: true, get: function () { return base.WalletSelectorMode; } }); exports.ExternalWalletSelector = ExternalWalletSelector; //# sourceMappingURL=ExternalWalletSelector.js.map