UNPKG

@dynamic-labs/sdk-react-core

Version:

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

524 lines (521 loc) 31.7 kB
'use client' import { __awaiter } from '../../../../../../_virtual/_tslib.js'; import { useCallback, useMemo } from 'react'; import { JwtVerifiedCredentialFormatEnum } from '@dynamic-labs/sdk-api-core'; import { DynamicError, EmbeddedWalletException, StorageService } from '@dynamic-labs/utils'; import { isSessionKeyCompatibleWalletConnector } from '@dynamic-labs/wallet-connector-core'; import '../../../../context/DynamicContext/DynamicContext.js'; import '../../../../store/state/loadingAndLifecycle/loadingAndLifecycle.js'; import { logger } from '../../../../shared/logger.js'; import '@dynamic-labs/iconic'; import 'react/jsx-runtime'; import '../../../../context/ViewContext/ViewContext.js'; import '@dynamic-labs/wallet-book'; import { EMBEDDED_WALLET_SESSION_SETTINGS } from '../../../constants/localStorage.js'; import '../../../constants/colors.js'; import '../../../constants/values.js'; import '../../../../shared/consts/index.js'; import '../../../../events/dynamicEvents.js'; import '../../../../context/CaptchaContext/CaptchaContext.js'; import '../../../../context/ErrorContext/ErrorContext.js'; import { findEmbeddedWalletFromVerifiedCredentials } from '../../../functions/findEmbeddedWalletFromVerifiedCredentials/findEmbeddedWalletFromVerifiedCredentials.js'; import { findTurnkeyWalletByPrimaryChain } from '../../../functions/findTurnkeyWallet/findTurnkeyWallet.js'; import '@dynamic-labs/multi-wallet'; import 'react-international-phone'; import { getUserWalletsFromVerifiedCredentials } from '../../../functions/getUserWalletsFromVerifiedCredentials/getUserWalletsFromVerifiedCredentials.js'; import '../../../../store/state/nonce/nonce.js'; import { addPasskeyIdentifierToWalletConnector } from '../../../functions/addPasskeyIdentifierToWalletConnector/addPasskeyIdentifierToWalletConnector.js'; import '../../../../store/state/projectSettings/projectSettings.js'; import { getUserVerifiedCredentialType } from '../../../functions/getUserVerifiedCredentialType/getUserVerifiedCredentialType.js'; import { hasEmbeddedWallet } from '../../../functions/hasEmbeddedWallet/hasEmbeddedWallet.js'; import { getEmbeddedWalletAuthHandler } from '../../../functions/getEmbeddedWalletAuthHandler/getEmbeddedWalletAuthHandler.js'; import { getEmbeddedWalletSessionExpiration } from '../../../functions/getEmbeddedWalletSessionExpiration/getEmbeddedWalletSessionExpiration.js'; import '../../../../config/ApiEndpoint.js'; import { getCreateEmbeddedWalletAccountRequest, createEmbeddedWalletAccount, completePasskeyRecovery, getUserPasskeys, initEmbeddedWalletSession } from '../../../../data/api/embeddedWallets/embeddedWallets.js'; import '../../../../store/state/user/user.js'; import '../../../../locale/locale.js'; import { refreshUserJwt } from '../../../../data/api/user/user.js'; import '../../../../store/state/dynamicContextProps/dynamicContextProps.js'; import '../../../../store/state/primaryWalletId/primaryWalletId.js'; import '../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js'; import '../../../../context/AccessDeniedContext/AccessDeniedContext.js'; import '../../../../context/AccountExistsContext/AccountExistsContext.js'; import { useInternalUserWallets } from '../../../../context/UserWalletsContext/UserWalletsContext.js'; import { USER_NOT_LOGGED_IN, ACTIVE_SESSION, SESSION_RESTORED, INVALID_REQUEST, INVALID_WALLET_DATA, SESSION_CREATED, ERROR_SENDING_CODE, CODE_SENT } from '../../../constants/errors.js'; import '../../../../store/state/authMode/authMode.js'; import '../../../../context/VerificationContext/VerificationContext.js'; import 'react-dom'; import { useElementById } from '../../useElementById/useElementById.js'; import '../../../functions/compareChains/compareChains.js'; import { findPrimaryEmbeddedChain } from '../../../../views/Passkey/utils/findPrimaryEmbeddedChain/findPrimaryEmbeddedChain.js'; import { getPrimaryTurnkeyWalletId } from '../../../functions/getPrimaryTurnkeyWalletId/getPrimaryTurnkeyWalletId.js'; import '../../../../context/ThemeContext/ThemeContext.js'; import { useSmartWallets } from '../../useSmartWallets/useSmartWallets.js'; import '../../useUserUpdateRequest/useUpdateUser/userFieldsSchema.js'; import { usePasskeyRecovery } from '../../usePasskeyRecovery/usePasskeyRecovery.js'; import 'bs58'; import '@dynamic-labs/types'; import '../../../../context/SocialRedirectContext/SocialRedirectContext.js'; import '../../../../context/LoadingContext/LoadingContext.js'; import { useWalletContext } from '../../../../context/WalletContext/WalletContext.js'; import { useIsTurnkeyWallet } from '../../useIsTurnkeyWallet/useIsTurnkeyWallet.js'; import { cleanupExport, initExport, exportCredential } from '../../../../views/EmbeddedReveal/utils/turnkeyExport/turnkeyExport.js'; import { canRestoreEmbeddedWalletSession, restoreEmbeddedWalletSession } from '../../../../views/Passkey/utils/passkeyRecovery/passkeyRecovery.js'; import { validateTurnkeyProviderEnabled } from '../../../validations/validateTurnkeyProviderEnabled/validateTurnkeyProviderEnabled.js'; import { getNewVerifiedCredentialsFromDiff } from '../../../functions/getNewVerifiedCredentialsFromDiff/getNewVerifiedCredentialsFromDiff.js'; import { EmbeddedWalletVersion, iframeContainerId, iframeElementId, revealIframeElementId, revealIframeContainerId } from './constants.js'; import { useTurnkey } from './useTurnkey/useTurnkey.js'; import 'yup'; import '../../../../context/MockContext/MockContext.js'; import '../../../../views/CollectUserDataView/useFields.js'; import '../../../../context/FieldsStateContext/FieldsStateContext.js'; import '../../../../context/UserFieldEditorContext/UserFieldEditorContext.js'; import '@dynamic-labs/rpc-providers'; import '../../../../store/state/walletOptions/walletOptions.js'; import 'react-i18next'; import '../../../../components/Accordion/components/AccordionItem/AccordionItem.js'; import '../../../../components/Alert/Alert.js'; import '../../../../components/ShadowDOM/ShadowDOM.js'; import '../../../../components/IconButton/IconButton.js'; import '../../../../components/InlineWidget/InlineWidget.js'; import '../../../../components/Input/Input.js'; import '../../../../components/IsBrowser/IsBrowser.js'; import '../../../../components/MenuList/Dropdown/Dropdown.js'; import '../../../../components/OverlayCard/OverlayCard.js'; import '../../../../components/Transition/ZoomTransition/ZoomTransition.js'; import '../../../../components/Transition/SlideInUpTransition/SlideInUpTransition.js'; import '../../../../components/Transition/OpacityTransition/OpacityTransition.js'; import '../../../../components/PasskeyCreatedSuccessBanner/PasskeyCreatedSuccessBanner.js'; import '../../../../components/Popper/Popper/Popper.js'; import '../../../../components/Popper/PopperContext/PopperContext.js'; import 'react-focus-lock'; import 'qrcode'; import 'formik'; import '../../useSubdomainCheck/useSubdomainCheck.js'; import '../../../../context/WalletGroupContext/WalletGroupContext.js'; import '../../../../context/IpConfigurationContext/IpConfigurationContext.js'; import '../../../../context/ConnectWithOtpContext/ConnectWithOtpContext.js'; import '../../../../widgets/DynamicBridgeWidget/views/WalletsView/components/SecondaryWallets/SecondaryWallets.js'; import '@hcaptcha/react-hcaptcha'; import '../../../../widgets/DynamicWidget/context/DynamicWidgetContext.js'; import '../../../../context/FooterAnimationContext/index.js'; import '../../../../context/ErrorContext/hooks/useErrorText/useErrorText.js'; import '../../../../context/PasskeyContext/PasskeyContext.js'; import '../../../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js'; import '../../../../store/state/sendBalances.js'; import '../../../../store/state/connectorsInitializing/connectorsInitializing.js'; import '../../../../components/OverlayCardBase/OverlayCardTarget/OverlayCardTarget.js'; import '../../../../widgets/DynamicWidget/components/DynamicWidgetHeader/DynamicWidgetHeader.js'; import '../../../../views/TransactionConfirmationView/TransactionConfirmationView.js'; import '../../../../widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.js'; import '../../../../context/OnrampContext/OnrampContext.js'; import '../../../../widgets/DynamicWidget/views/ReceiveWalletFunds/ReceiveWalletFunds.js'; import '../../../../../index.js'; import '../../../../store/state/tokenBalances.js'; import '../../../../shared/utils/functions/getInitialUrl/getInitialUrl.js'; import { useInternalDynamicContext } from '../../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js'; const isConnectorSessionKeyActive = (connector) => { var _a; if (!connector || !isSessionKeyCompatibleWalletConnector(connector)) return false; return Boolean((_a = connector.sessionKeys) === null || _a === void 0 ? void 0 : _a.publicKey); }; // Hook exposed to customers /** * * @returns { * createEmbeddedWallet, - creates Secure enclave embedded wallet according to the settings * createOrRestoreSession, - creates or restores a embedded wallet session * createPasskey, - creates a new passkey both for an existing wallet or a wallet to be created * getPasskeys, - gets all passkeys for the user * isLoadingEmbeddedWallet, - loading state of the embedded wallet * isSessionActive, - checks if the embedded wallet session is active * revealEmbeddedWalletKey - export the recovery phrase or private key of the embedded wallet * sendOneTimeCode, - sends a one-time code to the user so they can create a session or add a new passkey * userHasEmbeddedWallet, - checks if the user has an embedded wallet * } */ const useSecureEnclaveEmbeddedWallet = () => { var _a, _b, _c, _d, _e; const { projectSettings, primaryWallet, user, environmentId, walletConnectorOptions, } = useInternalDynamicContext(); const { addedWalletsIds } = useInternalUserWallets(); const { createTurnkeyWallet } = useTurnkey(); const { hasRecoveryEmail } = useIsTurnkeyWallet(); const { createRootElement } = useElementById(); const { isLoadingEmbeddedWallet, setIsLoadingEmbeddedWallet } = useWalletContext(); const { getEOAWallet } = useSmartWallets(); const wallet = (_a = (primaryWallet && getEOAWallet(primaryWallet))) !== null && _a !== void 0 ? _a : primaryWallet; const userHasEmbeddedWallet = useCallback(() => hasEmbeddedWallet(user, 'turnkey'), [user]); const getWalletVersion = useCallback(() => { if (isSessionKeyCompatibleWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { return EmbeddedWalletVersion.V2; } return EmbeddedWalletVersion.V1; }, [wallet === null || wallet === void 0 ? void 0 : wallet.connector]); const { shouldInitRecovery, initPasskeyRecoveryProcess } = usePasskeyRecovery(); /** * Creates a new secure enclave embedded wallet according to the settings from the dashboard * @param chain - optional chain parameter to create the wallet for * @param options - optional parameter contained more settings for the wallet creation * @returns Promise<Wallet | undefined> */ const createEmbeddedWallet = useCallback((chains, options) => __awaiter(void 0, void 0, void 0, function* () { var _f; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } const userWalletsCredentials = getUserWalletsFromVerifiedCredentials(user); const primaryChain = findPrimaryEmbeddedChain(projectSettings); const embeddedWalletVerifiedCredential = findEmbeddedWalletFromVerifiedCredentials(user, chains !== null && chains !== void 0 ? chains : [primaryChain]); const isManualMode = ((_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _f === void 0 ? void 0 : _f.automaticEmbeddedWalletCreation) === false; // if user has a wallet and it's not embedded, // throw error to follow another flow and set up the right wallet // However, if the user is in manual mode continue. if ((userWalletsCredentials === null || userWalletsCredentials === void 0 ? void 0 : userWalletsCredentials.length) && !embeddedWalletVerifiedCredential && !isManualMode) { throw new EmbeddedWalletException('User already has a linked branded wallet, and manual mode creation is not enabled.'); } validateTurnkeyProviderEnabled(projectSettings); // TEMP: immediately disable loading state setIsLoadingEmbeddedWallet(false); return createTurnkeyWallet(chains, options); }), [createTurnkeyWallet, projectSettings, setIsLoadingEmbeddedWallet, user]); /** * Creates a new secure enclave embedded wallet account * @param chain - chain parameter to create the wallet for * @returns Promise<UserProfile | undefined> */ const createEmbeddedWalletAccount$1 = useCallback((_g) => __awaiter(void 0, [_g], void 0, function* ({ chain }) { var _h, _j, _k; if (!user) { throw new Error(USER_NOT_LOGGED_IN); } validateTurnkeyProviderEnabled(projectSettings); const primaryChain = findPrimaryEmbeddedChain(projectSettings); const embeddedWalletVerifiedCredential = findEmbeddedWalletFromVerifiedCredentials(user, [primaryChain]); const turnkeyWalletId = (_h = embeddedWalletVerifiedCredential === null || embeddedWalletVerifiedCredential === void 0 ? void 0 : embeddedWalletVerifiedCredential.walletProperties) === null || _h === void 0 ? void 0 : _h.turnkeyHDWalletId; if (!turnkeyWalletId) { throw new DynamicError('No HD wallet was found for this user to derive a wallet account. Use createEmbeddedWallet first', 'NoHdWalletFound'); } const requestToStamp = yield getCreateEmbeddedWalletAccountRequest({ chain, environmentId, }); if (isSessionKeyCompatibleWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { yield ((_j = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _j === void 0 ? void 0 : _j.createOrRestoreSession({ ignoreRestore: true, })); } else if (yield shouldInitRecovery()) { yield initPasskeyRecoveryProcess('email'); } const signedRequest = yield ((_k = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _k === void 0 ? void 0 : _k.stampCreateWalletAccountRequest({ request: requestToStamp, })); const verifiedUser = yield createEmbeddedWalletAccount({ createEmbeddedWalletAccountRequest: signedRequest, environmentId, }); const newWalletIds = getNewVerifiedCredentialsFromDiff(user.verifiedCredentials, verifiedUser.user.verifiedCredentials) .filter(({ format }) => format === JwtVerifiedCredentialFormatEnum.Blockchain) .map(({ id }) => id); addedWalletsIds.current = addedWalletsIds.current.concat(newWalletIds); return refreshUserJwt({ environmentId }); }), [ environmentId, wallet === null || wallet === void 0 ? void 0 : wallet.connector, initPasskeyRecoveryProcess, projectSettings, shouldInitRecovery, user, addedWalletsIds, ]); /** * Creates or restores a secure enclave embedded wallet session * If it detects that the session is possible to be restored, it will restore it * @param oneTimeCode - optional one-time code parameter. If not informed it tries to restore a session * @returns Promise<'session_created' | 'session_restored'> - returns a string indicating the status of the session */ const createOrRestoreSession = useCallback((options) => __awaiter(void 0, void 0, void 0, function* () { var _l, _m, _o, _p, _q, _r; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } const primaryConnector = primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector; if (primaryConnector && isSessionKeyCompatibleWalletConnector(primaryConnector)) { return primaryConnector.createOrRestoreSession(); } const eoaConnector = wallet === null || wallet === void 0 ? void 0 : wallet.connector; if (eoaConnector && isSessionKeyCompatibleWalletConnector(eoaConnector)) { return eoaConnector.createOrRestoreSession(); } const turnkeyRecoveryHandler = getEmbeddedWalletAuthHandler(wallet === null || wallet === void 0 ? void 0 : wallet.connector); if (turnkeyRecoveryHandler.isSessionActive()) { return ACTIVE_SESSION; } const turnkeyAuthIframeContainerRef = createRootElement(iframeContainerId); // try to restore session if possible if (canRestoreEmbeddedWalletSession((_l = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _l === void 0 ? void 0 : _l.sessionKeyDuration)) { try { const sessionRestored = yield restoreEmbeddedWalletSession({ iframeContainer: turnkeyAuthIframeContainerRef.current, iframeElementId, sessionExpiration: getEmbeddedWalletSessionExpiration((_o = (_m = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _m === void 0 ? void 0 : _m.embeddedWallets) === null || _o === void 0 ? void 0 : _o.sessionKeyDuration), user, wallet: primaryWallet, }); if (sessionRestored) return SESSION_RESTORED; } catch (err) { logger.error('Failed to restore embedded wallet', err); } } if (!(options === null || options === void 0 ? void 0 : options.oneTimeCode)) { throw new DynamicError('One-time code is required to create a session.', INVALID_REQUEST); } // tries to create a new session with the informed one-time code // verify user has a turnkey wallet and email VC if (!userHasEmbeddedWallet() || !hasRecoveryEmail) { throw new DynamicError('User does not have a secure enclave wallet or a verified email', INVALID_WALLET_DATA); } if (!primaryWallet) { throw new DynamicError('No primary wallet found'); } const primaryTurnkeyWalletId = getPrimaryTurnkeyWalletId(primaryWallet.id, (user === null || user === void 0 ? void 0 : user.verifiedCredentials) || []); const organizationId = (_r = (_q = (_p = user === null || user === void 0 ? void 0 : user.verifiedCredentials) === null || _p === void 0 ? void 0 : _p.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === primaryTurnkeyWalletId)) === null || _q === void 0 ? void 0 : _q.walletProperties) === null || _r === void 0 ? void 0 : _r.turnkeySubOrganizationId; yield turnkeyRecoveryHandler.verifyRecoveryCode(options.oneTimeCode, organizationId); const sessionSettings = { createdAt: new Date().getTime(), emailCode: options.oneTimeCode, userId: turnkeyRecoveryHandler.recoveryUserId, }; StorageService.setItem(EMBEDDED_WALLET_SESSION_SETTINGS, sessionSettings); return SESSION_CREATED; }), [ createRootElement, user, hasRecoveryEmail, primaryWallet, (_c = (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _b === void 0 ? void 0 : _b.embeddedWallets) === null || _c === void 0 ? void 0 : _c.sessionKeyDuration, userHasEmbeddedWallet, wallet === null || wallet === void 0 ? void 0 : wallet.connector, ]); /** * Creates a new passkey both for an existing wallet or a wallet to be created * @param options - optional parameter to inform a one-time code to create a session, * @returns Promise<WebAuthnAttestation> */ const createPasskey = useCallback((options) => __awaiter(void 0, void 0, void 0, function* () { var _s, _t; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } validateTurnkeyProviderEnabled(projectSettings); const turnkeyWallet = findTurnkeyWalletByPrimaryChain(walletConnectorOptions, (_s = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _s === void 0 ? void 0 : _s.chainConfigurations, user.verifiedCredentials); if (!(turnkeyWallet === null || turnkeyWallet === void 0 ? void 0 : turnkeyWallet.walletConnector)) { throw new DynamicError('Wallet connector not found', INVALID_WALLET_DATA); } const walletConnector = turnkeyWallet.walletConnector; walletConnector.setEmail(user === null || user === void 0 ? void 0 : user.email); if (user && !(user === null || user === void 0 ? void 0 : user.email)) { addPasskeyIdentifierToWalletConnector(walletConnector, user); } const hasEmailVC = getUserVerifiedCredentialType(user, JwtVerifiedCredentialFormatEnum.Email); // return a new passkey if the user doesn't have a wallet yet or // none of the requirements to add a passkey to an existing wallet are met if (!('id' in turnkeyWallet) || !hasEmailVC) { return walletConnector.getWebAuthnAttestation(); } const turnkeySubOrganizationId = (_t = turnkeyWallet === null || turnkeyWallet === void 0 ? void 0 : turnkeyWallet.walletProperties) === null || _t === void 0 ? void 0 : _t.turnkeySubOrganizationId; if (!turnkeySubOrganizationId) { throw new DynamicError('No sub organization id found for the wallet', INVALID_WALLET_DATA); } const turnkAuthenticatorHandler = getEmbeddedWalletAuthHandler(walletConnector); // add new passkey to the wallet through an active session yield createOrRestoreSession(options); const { attestation, challenge, displayName } = yield walletConnector.getWebAuthnAttestation(); yield turnkAuthenticatorHandler.addPasskeyAuthenticator({ attestation, challenge, turnkeySubOrganizationId, }); const updatedUser = yield completePasskeyRecovery({ attestation: attestation, challenge, environmentId, walletId: turnkeyWallet === null || turnkeyWallet === void 0 ? void 0 : turnkeyWallet.id, }); if (!updatedUser) { throw new DynamicError('Error completing passkey recovery'); } return { attestation, challenge, displayName }; }), [ createOrRestoreSession, environmentId, projectSettings, user, walletConnectorOptions, ]); /** * Gets all passkeys for the user * @returns Promise<Passkey[]> */ const getPasskeys = useCallback(() => __awaiter(void 0, void 0, void 0, function* () { if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } const data = yield getUserPasskeys({ environmentId: environmentId, }); return data.passkeys; }), [user, environmentId]); const isEmailAuthSessionActive = useMemo(() => { var _a; const eoaConnector = wallet === null || wallet === void 0 ? void 0 : wallet.connector; if (!eoaConnector || !('getAuthenticatorHandler' in eoaConnector)) return false; return (_a = getEmbeddedWalletAuthHandler(eoaConnector)) === null || _a === void 0 ? void 0 : _a.isSessionActive(); }, [wallet === null || wallet === void 0 ? void 0 : wallet.connector]); const isSessionKeySessionAAActive = useMemo(() => isConnectorSessionKeyActive(wallet === null || wallet === void 0 ? void 0 : wallet.connector), [wallet === null || wallet === void 0 ? void 0 : wallet.connector]); const isSessionKeySessionActive = useMemo(() => isConnectorSessionKeyActive(primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector), [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.connector]); /** * Checks if the embedded wallet session is active */ const isSessionActive = isEmailAuthSessionActive || isSessionKeySessionActive || isSessionKeySessionAAActive; /** * export the recovery phrase or private key of the embedded wallet * @param options - optional parameter object containing the type of key to reveal 'recoveryPhrase' | 'privateKey' * and the html container id to render the iframe into * @returns Promise<string> - returns the embedded wallet recovery phrase or private key */ const revealEmbeddedWalletKey = useCallback((_u) => __awaiter(void 0, [_u], void 0, function* ({ type, htmlContainerId, }) { var _v, _w, _x, _y, _z, _0; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } yield cleanupExport({ wallet: wallet, }); const turnkeyWallet = findTurnkeyWalletByPrimaryChain(walletConnectorOptions, (_v = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _v === void 0 ? void 0 : _v.chainConfigurations, user === null || user === void 0 ? void 0 : user.verifiedCredentials); const turnkeyHDWalletId = (_w = turnkeyWallet === null || turnkeyWallet === void 0 ? void 0 : turnkeyWallet.walletProperties) === null || _w === void 0 ? void 0 : _w.turnkeyHDWalletId; if (type === 'recoveryPhrase' && !turnkeyHDWalletId) { type = 'privateKey'; } const iframeContainerElement = createRootElement(revealIframeElementId, htmlContainerId || revealIframeContainerId); // hide the iframe container until the export is done // since it will show unrelated turnkey content iframeContainerElement.current.style.display = 'none'; if (isSessionKeyCompatibleWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { yield ((_x = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _x === void 0 ? void 0 : _x.createOrRestoreSession()); } yield initExport({ iframeContainer: iframeContainerElement.current, iframeElementId: revealIframeElementId, wallet: wallet, }); try { yield exportCredential({ address: type === 'privateKey' ? wallet === null || wallet === void 0 ? void 0 : wallet.address : undefined, environmentId, user, wallet: wallet, }); } catch (_1) { if (isSessionKeyCompatibleWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector) && ((_y = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _y === void 0 ? void 0 : _y.removeSessionKeys)) { yield ((_z = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _z === void 0 ? void 0 : _z.removeSessionKeys()); yield ((_0 = wallet === null || wallet === void 0 ? void 0 : wallet.connector) === null || _0 === void 0 ? void 0 : _0.createOrRestoreSession({ ignoreRestore: true, })); } yield exportCredential({ address: type === 'privateKey' ? wallet === null || wallet === void 0 ? void 0 : wallet.address : undefined, environmentId, user, wallet: wallet, }); } // show the iframe container after the export is done // to show the exported content only iframeContainerElement.current.style.display = 'block'; return true; }), [ createRootElement, environmentId, wallet, (_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _d === void 0 ? void 0 : _d.embeddedWallets) === null || _e === void 0 ? void 0 : _e.chainConfigurations, user, walletConnectorOptions, ]); /** * Sends a one-time code to the user so they can create a session or add a new passkey * @returns Promise<'code_sent'> */ const sendOneTimeCode = useCallback(() => __awaiter(void 0, void 0, void 0, function* () { var _2, _3; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } const targetTurnkeyWallet = findTurnkeyWalletByPrimaryChain(walletConnectorOptions, (_2 = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _2 === void 0 ? void 0 : _2.chainConfigurations, user.verifiedCredentials); if (!targetTurnkeyWallet || !('id' in targetTurnkeyWallet)) { throw new DynamicError('User does not have a valid secure enclave wallet', INVALID_WALLET_DATA); } const turnkeyAuthenticatorHandler = getEmbeddedWalletAuthHandler(targetTurnkeyWallet === null || targetTurnkeyWallet === void 0 ? void 0 : targetTurnkeyWallet.walletConnector); const targetTurnkeyWalletId = targetTurnkeyWallet.id; const isSessionActive = turnkeyAuthenticatorHandler.isSessionActive(); if (isSessionActive) { throw new DynamicError('Session is active. No need to create a new one', ACTIVE_SESSION); } const turnkeyAuthIframeContainerRef = createRootElement(iframeContainerId); const publicKey = yield turnkeyAuthenticatorHandler.initRecovery('email', turnkeyAuthIframeContainerRef.current, iframeElementId, getEmbeddedWalletSessionExpiration((_3 = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk.embeddedWallets) === null || _3 === void 0 ? void 0 : _3.sessionKeyDuration)); if (!publicKey) { throw new DynamicError(ERROR_SENDING_CODE); } const response = yield initEmbeddedWalletSession({ authenticatorType: 'email', environmentId, publicKey, walletId: targetTurnkeyWalletId, }); turnkeyAuthenticatorHandler.recoveryUserId = response.turnkeyUserId; return CODE_SENT; }), [ createRootElement, user, environmentId, projectSettings, walletConnectorOptions, ]); return useMemo(() => ({ createEmbeddedWallet, createEmbeddedWalletAccount: createEmbeddedWalletAccount$1, createOrRestoreSession, createPasskey, getPasskeys, getWalletVersion, isLoadingEmbeddedWallet, isSessionActive, revealEmbeddedWalletKey, sendOneTimeCode, userHasEmbeddedWallet, }), [ createEmbeddedWallet, createEmbeddedWalletAccount$1, createOrRestoreSession, createPasskey, getPasskeys, getWalletVersion, isLoadingEmbeddedWallet, isSessionActive, revealEmbeddedWalletKey, sendOneTimeCode, userHasEmbeddedWallet, ]); }; export { isConnectorSessionKeyActive, useSecureEnclaveEmbeddedWallet };