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