UNPKG

@turnkey/react-wallet-kit

Version:

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

201 lines (197 loc) 8.4 kB
'use strict'; var jsxRuntime = require('react/jsx-runtime'); var Buttons = require('../../design/Buttons.js'); var reactFontawesome = require('@fortawesome/react-fontawesome'); var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons'); var react = require('react'); var clsx = require('clsx'); var Success = require('../../design/Success.js'); var Hook = require('../../../providers/modal/Hook.js'); var Hook$1 = require('../../../providers/client/Hook.js'); var utils = require('../../../utils/utils.js'); var Action = require('../Action.js'); function MobileWalletConnectScreen(props) { const { provider: targetApp, onConnect, onSign, onSelectQRCode, successPageDuration } = props; const { pushPage, popPages, closeModal, isMobile } = Hook.useModal(); const { walletProviders } = Hook$1.useTurnkey(); const latestProviderRef = react.useRef(null); const [isConnecting, setIsConnecting] = react.useState(false); const [canSign, setCanSign] = react.useState(false); const [completed, setCompleted] = react.useState(false); const [shouldStartConnecting, setShouldStartConnecting] = react.useState(isMobile); // Find the current WalletConnect provider state const walletConnectProvider = utils.findWalletConnectProvider(walletProviders, targetApp.chainInfo.namespace); // if provider is not found then that means that the user entered this screen // while WalletConnect was still initializing, and then it failed to initialize react.useEffect(() => { if (!walletConnectProvider) { // we have to go back two pages here since thats the screen // we get wallet providers from state popPages(2); } }, [walletConnectProvider, popPages]); // Initial connection effect react.useEffect(() => { if (!shouldStartConnecting) return; if (walletConnectProvider) { latestProviderRef.current = walletConnectProvider; // we don't try to connect if WalletConnect is still initializing or we are already connecting if (!isConnecting && !walletConnectProvider.isLoading) { if (walletConnectProvider.connectedAddresses.length > 0) { // Connection already established. Try to connect if possible if (onSign) { setCanSign(true); } else { setCompleted(true); } } else { // Start connection flow setCanSign(false); handleOpenApp(`wc?uri=${encodeURIComponent(latestProviderRef?.current?.uri ?? "")}`); runConnectAction(walletConnectProvider); } } } }, [walletConnectProvider, shouldStartConnecting]); // Handle the connection action - uses the ref to get latest provider const runConnectAction = utils.useDebouncedCallback(async targetProvider => { setIsConnecting(true); try { await onConnect(targetProvider); if (onSign) { setCanSign(true); } else { // Skip signing step if no signature is required (Connect only, not signup/login) setCompleted(true); } } catch { // noop } finally { setIsConnecting(false); } }, 100); // Handle the sign action - uses the ref to get latest provider const runSignAction = utils.useDebouncedCallback(async targetProvider => { setIsConnecting(true); try { await onSign(targetProvider); setCompleted(true); } catch { // noop } finally { setIsConnecting(false); } }, 100); const handleOpenApp = linkParams => { const link = `${targetApp.uri}${linkParams ? `${linkParams}` : ""}`; window.location.href = link; }; react.useEffect(() => { if (completed) { pushPage({ key: "Connect Success", content: jsxRuntime.jsx(Success.SuccessPage, { text: "Successfully connected to WalletConnect!", onComplete: closeModal, duration: successPageDuration }), preventBack: true, showTitle: false }); } }, [completed]); return jsxRuntime.jsx("div", { className: clsx("flex flex-col items-center justify-center py-5 text-center", isMobile ? "w-full" : "w-auto"), children: !shouldStartConnecting ? jsxRuntime.jsxs("div", { className: clsx("flex flex-col gap-4 mt-6 items-center justify-center", isMobile ? "w-full" : "w-96"), children: [jsxRuntime.jsx("img", { src: targetApp.info.icon, className: "size-14 rounded-full" }), jsxRuntime.jsxs("span", { className: "text-sm text-center text-icon-text-light dark:text-icon-text-dark", children: ["You can connect", " ", targetApp.info.name ?? "this wallet provider", " using your mobile device. Open this page on your mobile device to continue or scan the QR code with your wallet app."] }), jsxRuntime.jsxs("span", { className: "text-sm text-center text-icon-text-light dark:text-icon-text-dark", children: ["Already on mobile?", " ", jsxRuntime.jsxs("span", { className: "text-primary-light dark:text-primary-dark cursor-pointer underline", onClick: () => setShouldStartConnecting(true), children: ["Try opening ", targetApp.info.name, " anyways."] })] }), jsxRuntime.jsx(Buttons.ActionButton, { onClick: () => // At this point, the user already selected the chian. So we can pass it in to redirect directly to the QR code for that chain onSelectQRCode(targetApp.chainInfo.namespace), className: "w-full text-inherit bg-button-light dark:bg-button-dark", children: jsxRuntime.jsxs("div", { className: "flex flex-row w-full justify-center items-center gap-2", children: ["Scan QR code", jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faQrcode, size: "lg", className: "text-icon-text-light dark:text-icon-text-dark" })] }) })] }) : canSign ? jsxRuntime.jsxs("div", { className: clsx("flex flex-col gap-4 mt-6 items-center justify-center", isMobile ? "w-full" : "w-72"), children: [jsxRuntime.jsx("img", { src: targetApp.info.icon, className: "size-14 rounded-full" }), jsxRuntime.jsxs("span", { className: "text-sm text-center text-icon-text-light dark:text-icon-text-dark", children: [targetApp.info.name ?? "This wallet provider", " is connected! Please sign the login request using the app to continue."] }), jsxRuntime.jsx(Buttons.ActionButton, { onClick: () => { handleOpenApp(); runSignAction(latestProviderRef.current); }, loading: isConnecting, loadingText: "Check the app...", className: "w-full text-inherit bg-button-light dark:bg-button-dark", children: jsxRuntime.jsxs("div", { className: "flex flex-row w-full justify-center items-center gap-1.5", children: ["Sign login request", jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faArrowUpRightFromSquare, size: "sm", className: "text-icon-text-light dark:text-icon-text-dark" })] }) })] }) : jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(Action.ActionPage // Run the action from a separate useEffect. No need to pass it here , { // Run the action from a separate useEffect. No need to pass it here title: `Connecting to ${targetApp.info.name}`, icon: jsxRuntime.jsx("img", { className: "size-11 rounded-full", src: targetApp.info.icon || "" }) }), jsxRuntime.jsxs("div", { className: "text-icon-text-light text-sm dark:text-icon-text-dark text-center !p-0", children: ["App not opening? Please ensure you have ", targetApp.info.name, " ", "installed or", " ", jsxRuntime.jsxs("span", { className: "text-primary-light dark:text-primary-dark cursor-pointer underline", onClick: () => { handleOpenApp(`wc?uri=${encodeURIComponent(latestProviderRef?.current?.uri ?? "")}`); }, children: ["try opening ", targetApp.info.name, " again."] })] })] }) }); } exports.MobileWalletConnectScreen = MobileWalletConnectScreen; //# sourceMappingURL=MobileWalletConnectScreen.js.map