@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
JavaScript
'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