UNPKG

@dynamic-labs/sdk-react-core

Version:

A React SDK for implementing wallet web3 authentication and authorization to your website.

244 lines (239 loc) 23.9 kB
'use client' 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _tslib = require('../../../../../../_virtual/_tslib.cjs'); var jsxRuntime = require('react/jsx-runtime'); var React = require('react'); var reactI18next = require('react-i18next'); var walletConnectorCore = require('@dynamic-labs/wallet-connector-core'); var Typography = require('../../../../components/Typography/Typography.cjs'); var TypographyButton = require('../../../../components/TypographyButton/TypographyButton.cjs'); require('../../../../context/DynamicContext/DynamicContext.cjs'); require('../../../../store/state/loadingAndLifecycle/loadingAndLifecycle.cjs'); require('@dynamic-labs/sdk-api-core'); var logger = require('../../../../shared/logger.cjs'); require('@dynamic-labs/iconic'); var add = require('../../../../shared/assets/add.cjs'); var androidTouchId = require('../../../../shared/assets/android-touch-id.cjs'); var checkCircle = require('../../../../shared/assets/check-circle.cjs'); var chevronLeft = require('../../../../shared/assets/chevron-left.cjs'); var exportPrivateKey = require('../../../../shared/assets/export-private-key.cjs'); var exportRecoveryPhrase = require('../../../../shared/assets/export-recovery-phrase.cjs'); var footerInfoIcon = require('../../../../shared/assets/footer-info-icon.cjs'); var session = require('../../../../shared/assets/session.cjs'); var shield = require('../../../../shared/assets/shield.cjs'); var signInWithEmail = require('../../../../shared/assets/sign-in-with-email.cjs'); var ViewContext = require('../../../../context/ViewContext/ViewContext.cjs'); require('@dynamic-labs/wallet-book'); require('@dynamic-labs/utils'); require('../../../../utils/constants/colors.cjs'); require('../../../../utils/constants/values.cjs'); require('../../../../shared/consts/index.cjs'); require('../../../../events/dynamicEvents.cjs'); require('../../../../context/CaptchaContext/CaptchaContext.cjs'); require('../../../../context/ErrorContext/ErrorContext.cjs'); require('@dynamic-labs/multi-wallet'); require('react-international-phone'); require('../../../../store/state/nonce/nonce.cjs'); var projectSettings = require('../../../../store/state/projectSettings/projectSettings.cjs'); require('../../../../config/ApiEndpoint.cjs'); require('../../../../store/state/user/user.cjs'); require('../../../../locale/locale.cjs'); require('../../../../store/state/dynamicContextProps/dynamicContextProps.cjs'); require('../../../../store/state/primaryWalletId/primaryWalletId.cjs'); require('../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs'); var isZKSyncEnabled = require('../../../../utils/functions/isZKSyncEnabled/isZKSyncEnabled.cjs'); require('../../../../context/AccessDeniedContext/AccessDeniedContext.cjs'); require('../../../../context/AccountExistsContext/AccountExistsContext.cjs'); require('../../../../context/UserWalletsContext/UserWalletsContext.cjs'); require('../../../../store/state/authMode/authMode.cjs'); require('../../../../context/VerificationContext/VerificationContext.cjs'); require('react-dom'); require('../../../../utils/functions/compareChains/compareChains.cjs'); require('../../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.cjs'); var ThemeContext = require('../../../../context/ThemeContext/ThemeContext.cjs'); var useSmartWallets = require('../../../../utils/hooks/useSmartWallets/useSmartWallets.cjs'); require('../../../../utils/hooks/useUserUpdateRequest/useUpdateUser/userFieldsSchema.cjs'); var usePasskeyRecovery = require('../../../../utils/hooks/usePasskeyRecovery/usePasskeyRecovery.cjs'); require('bs58'); require('@dynamic-labs/types'); require('../../../../context/SocialRedirectContext/SocialRedirectContext.cjs'); require('../../../../context/LoadingContext/LoadingContext.cjs'); require('../../../../context/WalletContext/WalletContext.cjs'); var useIsTurnkeyWallet = require('../../../../utils/hooks/useIsTurnkeyWallet/useIsTurnkeyWallet.cjs'); require('../../../../utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/constants.cjs'); require('yup'); require('../../../../context/MockContext/MockContext.cjs'); require('../../../../views/CollectUserDataView/useFields.cjs'); require('../../../../context/FieldsStateContext/FieldsStateContext.cjs'); require('../../../../context/UserFieldEditorContext/UserFieldEditorContext.cjs'); require('@dynamic-labs/rpc-providers'); require('../../../../store/state/walletOptions/walletOptions.cjs'); var classNames = require('../../../../utils/functions/classNames/classNames.cjs'); require('../../../../components/Accordion/components/AccordionItem/AccordionItem.cjs'); var spinner = require('../../../../components/Spinner/spinner.cjs'); require('../../../../components/Alert/Alert.cjs'); var Badge = require('../../../../components/Badge/Badge.cjs'); var Icon = require('../../../../components/Icon/Icon.cjs'); require('../../../../components/ShadowDOM/ShadowDOM.cjs'); var IconButton = require('../../../../components/IconButton/IconButton.cjs'); require('../../../../components/InlineWidget/InlineWidget.cjs'); require('../../../../components/Input/Input.cjs'); require('../../../../components/IsBrowser/IsBrowser.cjs'); require('../../../../components/MenuList/Dropdown/Dropdown.cjs'); require('../../../../components/OverlayCard/OverlayCard.cjs'); require('../../../../components/Transition/ZoomTransition/ZoomTransition.cjs'); require('../../../../components/Transition/SlideInUpTransition/SlideInUpTransition.cjs'); require('../../../../components/Transition/OpacityTransition/OpacityTransition.cjs'); var ModalHeader = require('../../../../components/ModalHeader/ModalHeader.cjs'); require('../../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.cjs'); require('../../../../components/Popper/Popper/Popper.cjs'); require('../../../../components/Popper/PopperContext/PopperContext.cjs'); require('react-focus-lock'); require('qrcode'); require('formik'); require('../../../../utils/hooks/useSubdomainCheck/useSubdomainCheck.cjs'); require('../../../../context/WalletGroupContext/WalletGroupContext.cjs'); require('../../../../context/IpConfigurationContext/IpConfigurationContext.cjs'); require('../../../../context/ConnectWithOtpContext/ConnectWithOtpContext.cjs'); require('../../../DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.cjs'); require('@hcaptcha/react-hcaptcha'); var DynamicWidgetContext = require('../../context/DynamicWidgetContext.cjs'); require('../../../../context/FooterAnimationContext/index.cjs'); require('../../../../context/ErrorContext/hooks/useErrorText/useErrorText.cjs'); var PasskeyDeviceIcon = require('../../../../views/Passkey/PasskeyDeviceIcon/PasskeyDeviceIcon.cjs'); require('../../../../context/PasskeyContext/PasskeyContext.cjs'); require('../../helpers/convertExchangeKeyAndProviderEnum.cjs'); require('../../../../store/state/sendBalances.cjs'); require('../../../../store/state/connectorsInitializing/connectorsInitializing.cjs'); require('../../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.cjs'); require('../../components/DynamicWidgetHeader/DynamicWidgetHeader.cjs'); require('../../../../views/TransactionConfirmationView/TransactionConfirmationView.cjs'); require('../ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.cjs'); var useEmbeddedReveal = require('../../../../utils/hooks/useEmbeddedReveal/useEmbeddedReveal.cjs'); var useEmbeddedWalletAuthenticator = require('../../../../utils/hooks/useEmbeddedWalletAuthenticator/useEmbeddedWalletAuthenticator.cjs'); require('../../../../context/OnrampContext/OnrampContext.cjs'); require('../ReceiveWalletFunds/ReceiveWalletFunds.cjs'); require('../../../../../index.cjs'); require('../../../../store/state/tokenBalances.cjs'); require('../../../../shared/utils/functions/getInitialUrl/getInitialUrl.cjs'); var useInternalDynamicContext = require('../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs'); const AccountAndSecuritySettingsView = () => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; const { clearStackAndPush } = ViewContext.useViewContext(); const { primaryWallet, user, setShowAuthFlow } = useInternalDynamicContext.useInternalDynamicContext(); const projectSettings$1 = projectSettings.useProjectSettings(); const { setDynamicWidgetView } = DynamicWidgetContext.useWidgetContext(); const { addEmbeddedWalletRecoveryEmail } = useEmbeddedWalletAuthenticator.useEmbeddedWalletAuthenticator(); const { initExportProcess } = useEmbeddedReveal.useEmbeddedReveal(); const { isTurnkeyWallet, isTurnkeyWalletWithoutAuthenticator, hasRecoveryEmail, } = useIsTurnkeyWallet.useIsTurnkeyWallet(); const { theme } = ThemeContext.useThemeContext(); const { t } = reactI18next.useTranslation(); const { initPasskeyRecoveryProcess, shouldInitRecovery } = usePasskeyRecovery.usePasskeyRecovery(); const [isLoading, setIsLoading] = React.useState(false); const { getEOAWallet } = useSmartWallets.useSmartWallets(); const turnkeyWalletProperties = (_b = (_a = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _a === void 0 ? void 0 : _a.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && ((primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id) ? id === (primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.id) : true))) === null || _b === void 0 ? void 0 : _b.walletProperties; const isTurnkeyHDWallet = turnkeyWalletProperties === null || turnkeyWalletProperties === void 0 ? void 0 : turnkeyWalletProperties.turnkeyHDWalletId; const isPasskeyEnabled = Boolean((_f = (_e = (_d = (_c = projectSettings$1 === null || projectSettings$1 === void 0 ? void 0 : projectSettings$1.sdk) === null || _c === void 0 ? void 0 : _c.embeddedWallets) === null || _d === void 0 ? void 0 : _d.supportedSecurityMethods) === null || _e === void 0 ? void 0 : _e.passkey) === null || _f === void 0 ? void 0 : _f.isEnabled); const isTurnkeyWalletWithAuthenticator = isTurnkeyWallet && !isTurnkeyWalletWithoutAuthenticator; const eoaWallet = primaryWallet && getEOAWallet(primaryWallet); const wallet = eoaWallet !== null && eoaWallet !== void 0 ? eoaWallet : primaryWallet; const isMfaEnabled = Boolean((_h = (_g = projectSettings$1 === null || projectSettings$1 === void 0 ? void 0 : projectSettings$1.security) === null || _g === void 0 ? void 0 : _g.mfa) === null || _h === void 0 ? void 0 : _h.enabled); const isSessionKeyCompatible = (primaryWallet && walletConnectorCore.isSessionKeyCompatibleWallet(primaryWallet)) || (eoaWallet && walletConnectorCore.isSessionKeyCompatibleWallet(eoaWallet)); const shouldShowPasskeyMFA = isPasskeyEnabled && isTurnkeyWallet && !isSessionKeyCompatible; const isEmbeddedWallet = Boolean(wallet && ((_k = (_j = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _j === void 0 ? void 0 : _j.key) === null || _k === void 0 ? void 0 : _k.startsWith('turnkey'))); const isV3WaasWallet = Boolean(wallet && ((_m = (_l = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _l === void 0 ? void 0 : _l.key) === null || _m === void 0 ? void 0 : _m.startsWith('dynamicwaas'))); const isZKSyncWallet = React.useMemo(() => isZKSyncEnabled.isZKSyncEnabled(projectSettings$1), [projectSettings$1]); const handleExportClick = React.useCallback((recoveryPhrase) => _tslib.__awaiter(void 0, void 0, void 0, function* () { if (!isSessionKeyCompatible) { if (yield shouldInitRecovery()) { yield initPasskeyRecoveryProcess(undefined, { type: 'reveal', }); } } return initExportProcess(recoveryPhrase); }), [ shouldInitRecovery, initPasskeyRecoveryProcess, initExportProcess, isSessionKeyCompatible, ]); const handlePasskeyClick = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () { if (isTurnkeyWalletWithoutAuthenticator) { try { setIsLoading(true); yield initPasskeyRecoveryProcess('passkey'); } catch (error) { logger.logger.error('Failed to init passkey recovery:', error); } finally { setIsLoading(false); } } else { setDynamicWidgetView('manage-passkeys'); } }), [ isTurnkeyWalletWithoutAuthenticator, setIsLoading, initPasskeyRecoveryProcess, setDynamicWidgetView, ]); const handleBackClick = React.useCallback(() => setDynamicWidgetView('settings'), [setDynamicWidgetView]); const handleMfaClick = React.useCallback(() => setDynamicWidgetView('manage-mfa'), [setDynamicWidgetView]); const handleSessionManagementClick = React.useCallback(() => setDynamicWidgetView('session-management'), [setDynamicWidgetView]); const handlePasskeyButtonClick = React.useCallback(() => handlePasskeyClick(), [handlePasskeyClick]); const handleExportButtonClick = React.useCallback(() => handleExportClick(), [handleExportClick]); const handleExportWithPhraseClick = React.useCallback(() => handleExportClick(true), [handleExportClick]); const handleDeleteAccountClick = React.useCallback(() => { clearStackAndPush('user-delete-account', {}, { onBackClick: () => { setShowAuthFlow(false); }, }); setShowAuthFlow(true); }, [clearStackAndPush, setShowAuthFlow]); const renderPasskeysButtonEndSlot = () => { if (isTurnkeyWalletWithAuthenticator) return (jsxRuntime.jsx(checkCircle.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--success' })); if (isLoading) return jsxRuntime.jsx(spinner.Spinner, {}); return jsxRuntime.jsx(add.ReactComponent, {}); }; const renderEmailButtonEndSlot = () => { if (hasRecoveryEmail) return (jsxRuntime.jsx(checkCircle.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--success' })); if (isLoading) return jsxRuntime.jsx(spinner.Spinner, {}); return jsxRuntime.jsx(add.ReactComponent, { "data-testid": 'email-add-icon' }); }; const backButton = (jsxRuntime.jsx(IconButton.IconButton, { type: 'button', onClick: handleBackClick, "data-testid": 'back-button', children: jsxRuntime.jsx(chevronLeft.ReactComponent, {}) })); const securitySectionTitleClasses = React.useMemo(() => classNames.classNames('settings-view__body__section__title', { 'settings-view__body__section__title__info-icon': !isTurnkeyWalletWithAuthenticator, }), [isTurnkeyWalletWithAuthenticator]); const passkeyButtonClasses = React.useMemo(() => classNames.classNames('settings-view__body__section__button', { 'settings-view__body__section__button__badge': !isTurnkeyWalletWithAuthenticator, }), [isTurnkeyWalletWithAuthenticator]); const exportIconClasses = React.useMemo(() => `settings-view__body__section__button__icon${theme.theme.name === 'dark' ? '__stroke' : ''}`, [theme.theme.name]); const identitySectionTitleClasses = React.useMemo(() => classNames.classNames('settings-view__body__section__title', 'settings-view__body__section__title__info-icon'), []); const emailButtonClasses = React.useMemo(() => classNames.classNames('settings-view__body__section__button', 'settings-view__body__section__button__badge'), []); return (jsxRuntime.jsxs("div", { className: 'account-and-security-settings-view', children: [jsxRuntime.jsx(ModalHeader.ModalHeader, { leading: backButton, children: jsxRuntime.jsx("div", { className: 'send-balance-page-layout__header-content', children: jsxRuntime.jsx(Typography.Typography, { variant: 'title', color: 'primary', copykey: 'dyn_settings.account_security.title', children: t('dyn_settings.account_security.title') }) }) }), jsxRuntime.jsx("div", { className: 'account-wrap', children: jsxRuntime.jsxs("div", { className: 'settings-view__body', children: [jsxRuntime.jsxs("div", { className: 'settings-view__body__section', children: [shouldShowPasskeyMFA || (isMfaEnabled && (jsxRuntime.jsx("div", { className: securitySectionTitleClasses, children: t('dyn_settings.security_section.title') }))), shouldShowPasskeyMFA && (jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'manage-passkeys-button', onClick: handlePasskeyButtonClick, buttonClassName: passkeyButtonClasses, startSlot: // eslint-disable-next-line react/jsx-wrap-multilines jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(PasskeyDeviceIcon.PasskeyDeviceIcon, { className: 'settings-view__body__section__button__icon', defaultIcon: jsxRuntime.jsx(androidTouchId.ReactComponent, { "data-testid": 'default-icon' }) }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.security_section.passkey_button', children: t('dyn_settings.security_section.passkey_button') }), !isTurnkeyWalletWithAuthenticator && (jsxRuntime.jsx(Badge.Badge, { text: t('dyn_settings.tags.recommended'), copykey: 'dyn_settings.tags.recommended', variant: 'secondary' }))] }), endSlot: renderPasskeysButtonEndSlot(), disabled: isLoading, showInternalLoading: false })), isMfaEnabled && (jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'manage-mfa-button', onClick: handleMfaClick, buttonClassName: 'settings-view__body__section__button', startSlot: // eslint-disable-next-line react/jsx-wrap-multilines jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(shield.ReactComponent, { className: 'settings-view__body__section__button__icon' }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.security_section.mfa_button', children: t('dyn_settings.security_section.mfa_button') })] }), endSlot: jsxRuntime.jsx(chevronLeft.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--rotate' }), disabled: isLoading, showInternalLoading: false }))] }), isZKSyncWallet && (jsxRuntime.jsxs("div", { className: 'settings-view__body__section', children: [jsxRuntime.jsx("div", { className: identitySectionTitleClasses, children: t('dyn_settings.session_management.title') }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'session-management-button', onClick: handleSessionManagementClick, buttonClassName: 'settings-view__body__section__button', startSlot: jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(session.ReactComponent, { className: 'settings-view__body__section__button__icon' }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.session_management.session_management_button', children: t('dyn_settings.session_management.session_management_button') })] }), endSlot: jsxRuntime.jsx(chevronLeft.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--rotate' }), disabled: isLoading, showInternalLoading: false })] })), (isEmbeddedWallet || isV3WaasWallet) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isTurnkeyWallet && !hasRecoveryEmail && !isSessionKeyCompatible && (jsxRuntime.jsxs("div", { className: 'settings-view__body__section', children: [jsxRuntime.jsxs("div", { className: identitySectionTitleClasses, children: [t('dyn_settings.identity_section.title'), jsxRuntime.jsx(Icon.Icon, { size: 'small', children: jsxRuntime.jsx(footerInfoIcon.ReactComponent, { className: 'settings-view__body__section__title__info-icon', "data-testid": 'email-info-icon-title' }) })] }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'manage-email-recovery-button', onClick: addEmbeddedWalletRecoveryEmail, buttonClassName: emailButtonClasses, startSlot: // eslint-disable-next-line react/jsx-wrap-multilines jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(signInWithEmail.ReactComponent, { className: 'settings-view__body__section__button__icon email' }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.identity_section.add_email_button', children: t('dyn_settings.identity_section.add_email_button') }), jsxRuntime.jsx(Badge.Badge, { text: t('dyn_settings.tags.recommended'), copykey: 'dyn_settings.tags.recommended', variant: 'secondary' })] }), endSlot: renderEmailButtonEndSlot(), disabled: isLoading || hasRecoveryEmail, showInternalLoading: false })] })), jsxRuntime.jsxs("div", { className: 'settings-view__body__section', children: [jsxRuntime.jsx("div", { className: 'settings-view__body__section__title', children: t('dyn_settings.export_section.title') }), jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'embedded-reveal-account-button', onClick: handleExportButtonClick, buttonClassName: 'settings-view__body__section__button', startSlot: // eslint-disable-next-line react/jsx-wrap-multilines jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(exportPrivateKey.ReactComponent, { className: exportIconClasses }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.export_section.private_key_button', children: t('dyn_settings.export_section.private_key_button') })] }), endSlot: jsxRuntime.jsx(chevronLeft.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--rotate' }), showInternalLoading: false }), isTurnkeyHDWallet && (jsxRuntime.jsx(TypographyButton.TypographyButton, { dataTestId: 'embedded-reveal-button', onClick: handleExportWithPhraseClick, buttonClassName: 'settings-view__body__section__button', startSlot: // eslint-disable-next-line react/jsx-wrap-multilines jsxRuntime.jsxs("div", { className: 'settings-view__body__section__button__start-slot', children: [jsxRuntime.jsx(exportRecoveryPhrase.ReactComponent, { className: exportIconClasses }), jsxRuntime.jsx(Typography.Typography, { color: 'primary', weight: 'medium', copykey: 'dyn_settings.export_section.srp_button', children: t('dyn_settings.export_section.srp_button') })] }), endSlot: jsxRuntime.jsx(chevronLeft.ReactComponent, { className: 'settings-view__body__section__button__icon-secondary--rotate' }), showInternalLoading: false }))] })] }))] }) }), jsxRuntime.jsx("div", { className: 'account-and-security-settings-view__delete-account-container', children: jsxRuntime.jsx(Typography.Typography, { onClick: handleDeleteAccountClick, "data-testid": 'delete-account-button', color: 'error-1', variant: 'body_small', weight: 'medium', className: 'account-and-security-settings-view__delete-account-container__delete-button', children: t('dyn_settings.delete_account.title') }) })] })); }; exports.AccountAndSecuritySettingsView = AccountAndSecuritySettingsView;