UNPKG

@dynamic-labs/sdk-react-core

Version:

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

259 lines (256 loc) 14.2 kB
'use client' import { __awaiter } from '../../../../../../_virtual/_tslib.js'; import { isPasskeyWalletConnector, isEmailWalletConnector } from '@dynamic-labs/wallet-connector-core'; import { DynamicError, StorageService } from '@dynamic-labs/utils'; import '@dynamic-labs/sdk-api-core'; import '../../../../config/ApiEndpoint.js'; import '../../../../store/state/projectSettings/projectSettings.js'; import { findEmbeddedWalletFromVerifiedCredentials } from '../../../../utils/functions/findEmbeddedWalletFromVerifiedCredentials/findEmbeddedWalletFromVerifiedCredentials.js'; import '../../../../utils/constants/values.js'; import { USER_NOT_LOGGED_IN } from '../../../../utils/constants/errors.js'; import '@dynamic-labs/multi-wallet'; import '../../../../shared/logger.js'; import { EMBEDDED_WALLET_SESSION_SETTINGS } from '../../../../utils/constants/localStorage.js'; import '../../../../utils/constants/colors.js'; import 'react-international-phone'; import '@dynamic-labs/iconic'; import 'react'; import 'react/jsx-runtime'; import '../../../../context/ViewContext/ViewContext.js'; import '@dynamic-labs/wallet-book'; import '../../../../shared/consts/index.js'; import '../../../../store/state/nonce/nonce.js'; import { removeElementById } from '../../../../utils/functions/removeElementById/removeElementById.js'; import '../../../../store/state/dynamicContextProps/dynamicContextProps.js'; import '../../../../store/state/primaryWalletId/primaryWalletId.js'; import '../../../../store/state/user/user.js'; import '../../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js'; import { completePasskeyRecovery as completePasskeyRecovery$1, updatePasskeyRecoveryEmail, initEmbeddedWalletSession as initEmbeddedWalletSession$1 } from '../../../../data/api/embeddedWallets/embeddedWallets.js'; import '../../../../locale/locale.js'; import { refreshUserJwt } from '../../../../data/api/user/user.js'; import { iframeElementId } from '../../PasskeyRecovery/constants.js'; const initEmbeddedWalletSession = (_a) => __awaiter(void 0, [_a], void 0, function* ({ authenticatorType, iframeContainer, iframeElementId, environmentId, user, wallet, sessionExpiration, }) { var _b; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } if (!(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !(wallet === null || wallet === void 0 ? void 0 : wallet.id) || !isPasskeyWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } const turnkeyRecoveryHandler = (_b = wallet.connector) === null || _b === void 0 ? void 0 : _b.getAuthenticatorHandler(); if (authenticatorType === 'passkey' && turnkeyRecoveryHandler.isSessionActive()) { return addNewPasskeyAuthenticator({ environmentId, user, wallet, }); } const publicKey = yield turnkeyRecoveryHandler.initRecovery(authenticatorType, iframeContainer, iframeElementId, sessionExpiration); if (!publicKey) { throw new DynamicError('Something went wrong'); } const response = yield initEmbeddedWalletSession$1({ authenticatorType, environmentId, publicKey, walletId: wallet.id, }); turnkeyRecoveryHandler.recoveryUserId = authenticatorType === 'passkey' ? response.turnkeyRecoveryUserId : response.turnkeyUserId; return; }); const passkeyRecoveryBundleValidation = (_c) => __awaiter(void 0, [_c], void 0, function* ({ user, bundleInput, wallet, }) { var _d, _e, _f, _g; if (!bundleInput) { throw new DynamicError('Code must be informed'); } if (!(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !(wallet === null || wallet === void 0 ? void 0 : wallet.id) || !isPasskeyWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } const organizationId = (_f = (_e = (_d = user.verifiedCredentials) === null || _d === void 0 ? void 0 : _d.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === wallet.id)) === null || _e === void 0 ? void 0 : _e.walletProperties) === null || _f === void 0 ? void 0 : _f.turnkeySubOrganizationId; const turnkeyRecoveryHandler = (_g = wallet.connector) === null || _g === void 0 ? void 0 : _g.getAuthenticatorHandler(); yield turnkeyRecoveryHandler.verifyRecoveryCode(bundleInput, organizationId); const sessionSettings = { createdAt: new Date().getTime(), emailCode: bundleInput, userId: turnkeyRecoveryHandler.recoveryUserId, }; StorageService.setItem(EMBEDDED_WALLET_SESSION_SETTINGS, sessionSettings); }); const resentRecoveryEmail = (_h) => __awaiter(void 0, [_h], void 0, function* ({ authenticatorType, user, environmentId, wallet, }) { var _j; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } if (!(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !(wallet === null || wallet === void 0 ? void 0 : wallet.id) || !isPasskeyWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } const publicKey = (_j = wallet.connector) === null || _j === void 0 ? void 0 : _j.getAuthenticatorHandler().publicKey; if (!publicKey) { throw new DynamicError('Could not proceed with your request. Please restart the process.'); } return initEmbeddedWalletSession$1({ authenticatorType, environmentId, publicKey, walletId: wallet === null || wallet === void 0 ? void 0 : wallet.id, }); }); const completePasskeyRecovery = (_k) => __awaiter(void 0, [_k], void 0, function* ({ user, environmentId, wallet, }) { const { connector, user: updatedUser } = yield recoverTurnkeyWallet({ addPasskeyAuthenticator: false, environmentId, user, wallet, }); // clear iframeStamper and its reference connector.getAuthenticatorHandler().clear(); // deletes iframe container after usage removeElementById(iframeElementId); return updatedUser; }); const addNewPasskeyAuthenticator = (_l) => __awaiter(void 0, [_l], void 0, function* ({ user, environmentId, wallet, }) { const { user: updatedUser } = yield recoverTurnkeyWallet({ addPasskeyAuthenticator: true, environmentId, user, wallet, }); return updatedUser; }); const recoverTurnkeyWallet = (_m) => __awaiter(void 0, [_m], void 0, function* ({ wallet, user, environmentId, addPasskeyAuthenticator, }) { var _o, _p, _q; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } if (!wallet || !wallet.connector || !wallet.id || !isPasskeyWalletConnector(wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } const connector = wallet.connector; connector.setEmail(user.email); const turnkeySubOrganizationId = (_q = (_p = (_o = user.verifiedCredentials) === null || _o === void 0 ? void 0 : _o.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === wallet.id)) === null || _p === void 0 ? void 0 : _p.walletProperties) === null || _q === void 0 ? void 0 : _q.turnkeySubOrganizationId; if (!turnkeySubOrganizationId) { throw new DynamicError('The authentication token is invalid - turnkeySubOrganizationId is missing'); } const turnkeyRecoveryHandler = wallet.connector.getAuthenticatorHandler(); const { attestation, challenge } = yield connector.getWebAuthnAttestation(); if (addPasskeyAuthenticator) { yield turnkeyRecoveryHandler.addPasskeyAuthenticator({ attestation, challenge, turnkeySubOrganizationId, }); } else { yield turnkeyRecoveryHandler.completeRecovery({ attestation, challenge, turnkeySubOrganizationId, }); } const updatedUser = yield completePasskeyRecovery$1({ attestation: attestation, challenge, environmentId, walletId: wallet.id, }); if (!updatedUser) { throw new DynamicError('No user returned from passkey recovery'); } const chain = connector.connectedChain; const embeddedWalletVerifiedCredential = findEmbeddedWalletFromVerifiedCredentials(updatedUser, [chain]); if (!embeddedWalletVerifiedCredential) { throw new DynamicError('EmbeddedWalletVerifiedCredential not found'); } connector.setVerifiedCredentials(updatedUser.verifiedCredentials); return { connector, user: updatedUser, }; }); const canRestoreEmbeddedWalletSession = (sessionExpirationTime) => { if (!(sessionExpirationTime === null || sessionExpirationTime === void 0 ? void 0 : sessionExpirationTime.amount)) { return false; } const sessionSettings = StorageService.getItem(EMBEDDED_WALLET_SESSION_SETTINGS); if (!sessionSettings) { return false; } const sessionExpiration = sessionExpirationTime.amount * (sessionExpirationTime.unit === 'minutes' ? 60 : 3600); const recoveryExpirationSeconds = (sessionSettings === null || sessionSettings === void 0 ? void 0 : sessionSettings.createdAt) + sessionExpiration * 1000; const expirationTime = new Date(recoveryExpirationSeconds); if (new Date() >= expirationTime) { StorageService.removeItem(EMBEDDED_WALLET_SESSION_SETTINGS); return false; } return true; }; const restoreEmbeddedWalletSession = (_r) => __awaiter(void 0, [_r], void 0, function* ({ user, iframeContainer, iframeElementId, wallet, sessionExpiration, }) { var _s, _t, _u, _v; if (!user) { throw new DynamicError(USER_NOT_LOGGED_IN); } if (!(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !(wallet === null || wallet === void 0 ? void 0 : wallet.id) || !isPasskeyWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } const sessionSettings = StorageService.getItem(EMBEDDED_WALLET_SESSION_SETTINGS); const turnkeyRecoveryHandler = (_s = wallet.connector) === null || _s === void 0 ? void 0 : _s.getAuthenticatorHandler(); if (!sessionSettings || Boolean(turnkeyRecoveryHandler.recoveryUserId)) { return false; } const publicKey = yield turnkeyRecoveryHandler.initRecovery('email', iframeContainer, iframeElementId, sessionExpiration); if (!publicKey) { throw new DynamicError('Could not open embedded wallet connection communication'); } turnkeyRecoveryHandler.recoveryUserId = sessionSettings.userId; const organizationId = (_v = (_u = (_t = user.verifiedCredentials) === null || _t === void 0 ? void 0 : _t.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === wallet.id)) === null || _u === void 0 ? void 0 : _u.walletProperties) === null || _v === void 0 ? void 0 : _v.turnkeySubOrganizationId; yield turnkeyRecoveryHandler.verifyRecoveryCode(sessionSettings.emailCode, organizationId); return true; }); const addEmailRecovery = (_w) => __awaiter(void 0, [_w], void 0, function* ({ user, environmentId, wallet, }) { var _x, _y; if (!(user === null || user === void 0 ? void 0 : user.email)) { throw new DynamicError(USER_NOT_LOGGED_IN); } if (!(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !(wallet === null || wallet === void 0 ? void 0 : wallet.id) || !isPasskeyWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector) || !isEmailWalletConnector(wallet === null || wallet === void 0 ? void 0 : wallet.connector)) { throw new DynamicError('Connector is missing. Please make sure you added EthereumWalletConnectors and/or SolanaWalletConnectors to DynamicProvider settings'); } const { turnkeySubOrganizationId, turnkeyUserId } = (_y = (_x = user.verifiedCredentials) === null || _x === void 0 ? void 0 : _x.find(({ walletName, id }) => (walletName === null || walletName === void 0 ? void 0 : walletName.startsWith('turnkey')) && id === wallet.id)) === null || _y === void 0 ? void 0 : _y.walletProperties; if (!turnkeySubOrganizationId || !turnkeyUserId) { throw new DynamicError('The authentication token is invalid - turnkeySubOrganizationId or turnkeyUserID is missing'); } const turnkeyRecoveryHandler = wallet.connector.getAuthenticatorHandler(); const { signedRequest } = (yield turnkeyRecoveryHandler.addEmailRecovery({ email: user.email, organizationId: turnkeySubOrganizationId, turnkeyUserId, })); yield updatePasskeyRecoveryEmail({ environmentId, updateRecoveryEmailRequest: { turnkeySignedRequest: signedRequest }, }); wallet.connector.setEmail(user.email); return refreshUserJwt({ environmentId }); }); export { addEmailRecovery, addNewPasskeyAuthenticator, canRestoreEmbeddedWalletSession, completePasskeyRecovery, initEmbeddedWalletSession, passkeyRecoveryBundleValidation, resentRecoveryEmail, restoreEmbeddedWalletSession };