UNPKG

@turnkey/react-wallet-kit

Version:

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

407 lines (403 loc) 14.5 kB
'use strict'; var jsxRuntime = require('react/jsx-runtime'); var reactFontawesome = require('@fortawesome/react-fontawesome'); var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons'); var core = require('@turnkey/core'); var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons'); var clsx = require('clsx'); var OAuth = require('./OAuth.js'); var Email = require('./Email.js'); var OrSeparator = require('./OrSeparator.js'); var OTP = require('./OTP.js'); var Phone = require('./Phone.js'); var Action = require('./Action.js'); var Passkey = require('./Passkey.js'); var Spinners = require('../design/Spinners.js'); var Failure = require('../design/Failure.js'); var Hook$1 = require('../../providers/modal/Hook.js'); var Hook = require('../../providers/client/Hook.js'); var base = require('../../types/base.js'); var WalletAuthButton = require('./wallet/WalletAuthButton.js'); var ExternalWalletSelector = require('./wallet/ExternalWalletSelector.js'); function AuthComponent({ sessionKey, logo, logoClassName, title }) { const { config, clientState, handleGoogleOauth, handleAppleOauth, handleFacebookOauth, handleXOauth, handleDiscordOauth, initOtp, loginWithPasskey, signUpWithPasskey } = Hook.useTurnkey(); const { pushPage, isMobile, openSheet } = Hook$1.useModal(); if (!config || clientState === base.ClientState.Loading) { // Don't check ClientState.Error here. We already check in the modal root return jsxRuntime.jsx("div", { className: "flex flex-col items-center w-96 py-5", children: jsxRuntime.jsx(Spinners.Spinner, { strokeWidth: 2, className: "w-48 h-48" }) }); } const { methods = {}, methodOrder = [], oauthOrder = [] } = config.ui?.authModal || {}; const handleEmailSubmit = async email => { try { const { otpId, otpEncryptionTargetBundle } = await initOtp({ otpType: core.OtpType.Email, contact: email }); pushPage({ key: "Verify OTP", content: jsxRuntime.jsx(OTP.OtpVerification, { contact: email, otpId: otpId, otpEncryptionTargetBundle: otpEncryptionTargetBundle, otpType: core.OtpType.Email, otpLength: config.auth?.otpLength !== undefined ? Number(config.auth.otpLength) : undefined, alphanumeric: config.auth?.otpAlphanumeric, ...(sessionKey && { sessionKey }) }), showTitle: false }); } catch (error) { throw new Error(`Error initializing OTP: ${error}`); } }; const handlePhoneSubmit = async (phone, formattedPhone) => { try { const { otpId, otpEncryptionTargetBundle } = await initOtp({ otpType: core.OtpType.Sms, contact: phone }); pushPage({ key: "Verify OTP", content: jsxRuntime.jsx(OTP.OtpVerification, { contact: phone, // Pass in the formatted phone number seperately. In the case that some weird formatting occurs, we don't want to send it into the initOtp request formattedContact: formattedPhone, otpId: otpId, otpEncryptionTargetBundle: otpEncryptionTargetBundle, otpType: core.OtpType.Sms, otpLength: config.auth?.otpLength !== undefined ? Number(config.auth.otpLength) : undefined, alphanumeric: config.auth?.otpAlphanumeric, ...(sessionKey && { sessionKey }) }), showTitle: false }); } catch (error) { throw new Error(`Error initializing OTP: ${error}`); } }; const handlePasskeyLogin = () => { pushPage({ key: "Passkey Login", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with passkey...", action: async () => { await loginWithPasskey({ ...(sessionKey && { sessionKey: sessionKey }) }); }, icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeSolidSvgIcons.faFingerprint }) }), showTitle: false }); }; const handlePasskeySignUp = () => { pushPage({ key: "Passkey Sign Up", content: jsxRuntime.jsx(Action.ActionPage, { title: "Creating account with passkey...", action: async () => { await signUpWithPasskey({ ...(sessionKey && { sessionKey: sessionKey }) }); }, icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeSolidSvgIcons.faFingerprint }) }), showTitle: false }); }; const handleGoogle = async () => { pushPage({ key: "Google OAuth", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with Google...", action: () => handleGoogleOauth({ additionalState: { openModal: "true", ...(sessionKey && { sessionKey }) } // Tell the provider to reopen the auth modal and show the loading state }), icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeBrandsSvgIcons.faGoogle }) }), showTitle: false }); }; const handleApple = async () => { pushPage({ key: "Apple OAuth", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with Apple...", action: () => handleAppleOauth({ additionalState: { openModal: "true", ...(sessionKey && { sessionKey }) } // Tell the provider to reopen the auth modal and show the loading state }), icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeBrandsSvgIcons.faApple }) }), showTitle: false }); }; const handleFacebook = async () => { pushPage({ key: "Facebook OAuth", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with Facebook...", action: () => handleFacebookOauth({ additionalState: { openModal: "true", ...(sessionKey && { sessionKey }) } // Tell the provider to reopen the auth modal and show the loading state }), icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeBrandsSvgIcons.faFacebook }) }), showTitle: false }); }; const handleX = async () => { pushPage({ key: "X OAuth", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with X...", action: () => handleXOauth({ additionalState: { openModal: "true", ...(sessionKey && { sessionKey }) } // Tell the provider to reopen the auth modal and show the loading state }), icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeBrandsSvgIcons.faXTwitter }) }), showTitle: false }); }; const handleDiscord = async () => { pushPage({ key: "Discord OAuth", content: jsxRuntime.jsx(Action.ActionPage, { title: "Authenticating with Discord...", action: () => handleDiscordOauth({ additionalState: { openModal: "true", ...(sessionKey && { sessionKey }) } // Tell the provider to reopen the auth modal and show the loading state }), icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { size: "3x", icon: freeBrandsSvgIcons.faDiscord }) }), showTitle: false }); }; const handleShowWalletSelector = async () => { try { pushPage({ key: "Select wallet provider", content: jsxRuntime.jsx(ExternalWalletSelector.ExternalWalletSelector, { mode: base.WalletSelectorMode.Auth, sessionKey: sessionKey }) }); } catch (error) { throw new Error(`Error fetching wallet providers: ${error}`); } }; const oauthButtonMap = { google: methods.googleOauthEnabled ? jsxRuntime.jsx(OAuth.OAuthButton, { name: "Google", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeBrandsSvgIcons.faGoogle }), onClick: handleGoogle }, "google") : null, apple: methods.appleOauthEnabled ? jsxRuntime.jsx(OAuth.OAuthButton, { name: "Apple", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeBrandsSvgIcons.faApple }), onClick: handleApple }, "apple") : null, facebook: methods.facebookOauthEnabled ? jsxRuntime.jsx(OAuth.OAuthButton, { name: "Facebook", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeBrandsSvgIcons.faFacebook }), onClick: handleFacebook }, "facebook") : null, x: methods.xOauthEnabled ? jsxRuntime.jsx(OAuth.OAuthButton, { name: "X", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeBrandsSvgIcons.faXTwitter }), onClick: handleX }, "x") : null, discord: methods.discordOauthEnabled ? jsxRuntime.jsx(OAuth.OAuthButton, { name: "Discord", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeBrandsSvgIcons.faDiscord }), onClick: handleDiscord }, "discord") : null }; const oauthButtons = oauthOrder.map(provider => oauthButtonMap[provider]).filter(Boolean); const oauthBlock = oauthButtons.length > 0 && oauthButtons.length <= 5 ? jsxRuntime.jsx("div", { className: "w-full h-11 flex flex-row justify-center items-center gap-2", children: oauthButtons }, "socials") : oauthButtons.length > 0 ? jsxRuntime.jsxs("div", { className: "w-full h-11 flex flex-row justify-center items-center gap-2", children: [oauthButtons.slice(0, 4), jsxRuntime.jsx(OAuth.OAuthButton, { name: "More", icon: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faEllipsisH }), onClick: () => openSheet({ key: "Select a social method", content: jsxRuntime.jsx("div", { className: "w-full h-full flex flex-wrap justify-center items-center gap-2", children: oauthButtons.map(button => jsxRuntime.jsx("div", { className: "w-16 h-11", children: button }, button?.key)) }) }) }, "more")] }, "socials") : null; // -- Individual Auth Method Components -- const methodComponents = { socials: oauthBlock, email: methods.emailOtpAuthEnabled ? jsxRuntime.jsx(Email.EmailInput, { onContinue: handleEmailSubmit }) : null, sms: methods.smsOtpAuthEnabled ? jsxRuntime.jsx(Phone.PhoneNumberInput, { onContinue: handlePhoneSubmit }) : null, passkey: methods.passkeyAuthEnabled ? jsxRuntime.jsx(Passkey.PasskeyButtons, { onLogin: handlePasskeyLogin, onSignUp: handlePasskeySignUp }) : null, wallet: methods.walletAuthEnabled ? jsxRuntime.jsx(WalletAuthButton.WalletAuthButton, { onContinue: handleShowWalletSelector }) : null }; // -- Final Rendering Order -- const rendered = methodOrder.map(key => methodComponents[key]).filter(Boolean); return jsxRuntime.jsxs("div", { className: clsx("flex flex-col items-center ", isMobile ? "w-full" : "w-96"), children: [config.authProxyConfigId ? rendered.length > 0 ? jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [logo ? jsxRuntime.jsxs("div", { className: "mt-3 mb-4 flex flex-col items-center", children: [jsxRuntime.jsx("img", { src: logo, className: `max-w-32 mt-3 w-fit max-h-16 h-fit object-contain ${logoClassName}` }), jsxRuntime.jsx("h2", { className: "text-lg font-medium mb-4 text-center", children: title ?? "Log in or sign up" })] }) : jsxRuntime.jsx("div", { className: "mt-12" }), rendered.map((component, index) => jsxRuntime.jsxs("div", { className: "w-full", children: [index > 0 && jsxRuntime.jsx(OrSeparator.OrSeparator, {}), component] }, index))] }) : jsxRuntime.jsx(Failure.DeveloperError, { developerTitle: "No Auth Methods Enabled", developerMessages: ["You are using Turnkey's Auth Proxy, but no auth methods are enabled.", "To use this modal, you must enable auth methods within the Turnkey dashboard.", "If you disabled autoFetchWalletKitConfig in the TurnkeyProvider, please ensure that you are passing in the correct auth methods in the TurnkeyProvider's auth config."], userMessages: ["No authentication methods are available."] }) : jsxRuntime.jsx(Failure.DeveloperError, { developerTitle: "Proxy not Enabled", developerMessages: ["You have not passed in authProxyConfigId into the TurnkeyProvider.", "To use this modal, you must be using Turnkey's Auth Proxy.", "Please enable it in the Turnkey dashboard and pass in the authProxyConfigId into the TurnkeyProvider."], // Users should never see this message ever. We should give a reward for anyone who does see this. userMessages: ["You touched fuzzy.... and got dizzy."] }), jsxRuntime.jsx("div", { className: "text-icon-text-light/70 dark:text-icon-text-dark/70 text-xs mt-4 text-center", children: jsxRuntime.jsxs("span", { children: ["By continuing, you agree to our", " ", jsxRuntime.jsx("a", { href: "https://www.turnkey.com/legal/terms", target: "_blank", rel: "noopener noreferrer", className: "font-bold no-underline text-icon-text-light/80 dark:text-icon-text-dark/80", children: "Terms of Service" }), " ", "&", " ", jsxRuntime.jsx("a", { href: "https://www.turnkey.com/legal/privacy", target: "_blank", rel: "noopener noreferrer", className: "font-bold no-underline text-icon-text-light/80 dark:text-icon-text-dark/80", children: "Privacy Policy" }), "."] }) })] }); } exports.AuthComponent = AuthComponent; //# sourceMappingURL=index.js.map