UNPKG

@web3auth/auth-adapter

Version:
256 lines (252 loc) 11.5 kB
import _objectSpread from '@babel/runtime/helpers/objectSpread2'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { UX_MODE, Auth, WEB3AUTH_NETWORK, SUPPORTED_KEY_CURVES } from '@web3auth/auth'; import { BaseAdapter, WALLET_ADAPTERS, ADAPTER_NAMESPACES, ADAPTER_CATEGORY, ADAPTER_STATUS, CHAIN_NAMESPACES, WalletInitializationError, log, ADAPTER_EVENTS, WalletLoginError, Web3AuthError } from '@web3auth/base'; import deepmerge from 'deepmerge'; import { getAuthDefaultOptions } from './config.js'; class AuthAdapter extends BaseAdapter { constructor(params = {}) { super(params); _defineProperty(this, "name", WALLET_ADAPTERS.AUTH); _defineProperty(this, "adapterNamespace", ADAPTER_NAMESPACES.MULTICHAIN); _defineProperty(this, "type", ADAPTER_CATEGORY.IN_APP); _defineProperty(this, "authInstance", null); _defineProperty(this, "status", ADAPTER_STATUS.NOT_READY); _defineProperty(this, "currentChainNamespace", CHAIN_NAMESPACES.EIP155); _defineProperty(this, "privateKeyProvider", null); _defineProperty(this, "authOptions", void 0); _defineProperty(this, "loginSettings", { loginProvider: "" }); this.setAdapterSettings(_objectSpread(_objectSpread({}, params.adapterSettings), {}, { chainConfig: params.chainConfig, clientId: params.clientId || "", sessionTime: params.sessionTime, web3AuthNetwork: params.web3AuthNetwork, useCoreKitKey: params.useCoreKitKey, privateKeyProvider: params.privateKeyProvider })); this.loginSettings = params.loginSettings || { loginProvider: "" }; this.privateKeyProvider = params.privateKeyProvider || null; } get chainConfigProxy() { return this.chainConfig ? _objectSpread({}, this.chainConfig) : null; } get provider() { if (this.status !== ADAPTER_STATUS.NOT_READY && this.privateKeyProvider) { return this.privateKeyProvider; } return null; } set provider(_) { throw new Error("Not implemented"); } async init(options) { super.checkInitializationRequirements(); if (!this.clientId) throw WalletInitializationError.invalidParams("clientId is required before auth's initialization"); if (!this.authOptions) throw WalletInitializationError.invalidParams("authOptions is required before auth's initialization"); const isRedirectResult = this.authOptions.uxMode === UX_MODE.REDIRECT; this.authOptions = _objectSpread(_objectSpread({}, this.authOptions), {}, { replaceUrlOnRedirect: isRedirectResult, useCoreKitKey: this.useCoreKitKey }); this.authInstance = new Auth(_objectSpread(_objectSpread({}, this.authOptions), {}, { clientId: this.clientId, network: this.authOptions.network || this.web3AuthNetwork || WEB3AUTH_NETWORK.SAPPHIRE_MAINNET })); log.debug("initializing auth adapter init"); await this.authInstance.init(); if (!this.chainConfig) throw WalletInitializationError.invalidParams("chainConfig is required before initialization"); this.status = ADAPTER_STATUS.READY; this.emit(ADAPTER_EVENTS.READY, WALLET_ADAPTERS.AUTH); try { log.debug("initializing auth adapter"); const finalPrivKey = this._getFinalPrivKey(); // connect only if it is redirect result or if connect (adapter is cached/already connected in same session) is true if (finalPrivKey && (options.autoConnect || isRedirectResult)) { this.rehydrated = true; await this.connect(); } } catch (error) { log.error("Failed to connect with cached auth provider", error); this.emit(ADAPTER_EVENTS.ERRORED, error); } } async connect(params = { loginProvider: "" }) { super.checkConnectionRequirements(); this.status = ADAPTER_STATUS.CONNECTING; this.emit(ADAPTER_EVENTS.CONNECTING, _objectSpread(_objectSpread({}, params), {}, { adapter: WALLET_ADAPTERS.AUTH })); try { await this.connectWithProvider(params); return this.provider; } catch (error) { log.error("Failed to connect with auth provider", error); // ready again to be connected this.status = ADAPTER_STATUS.READY; this.emit(ADAPTER_EVENTS.ERRORED, error); if (error !== null && error !== void 0 && error.message.includes("user closed popup")) { throw WalletLoginError.popupClosed(); } else if (error instanceof Web3AuthError) { throw error; } throw WalletLoginError.connectionError("Failed to login with auth", error); } } async enableMFA(params = { loginProvider: "" }) { if (this.status !== ADAPTER_STATUS.CONNECTED) throw WalletLoginError.notConnectedError("Not connected with wallet"); if (!this.authInstance) throw WalletInitializationError.notReady("authInstance is not ready"); try { await this.authInstance.enableMFA(params); } catch (error) { log.error("Failed to enable MFA with auth provider", error); if (error instanceof Web3AuthError) { throw error; } throw WalletLoginError.connectionError("Failed to enable MFA with auth", error); } } async manageMFA(params = { loginProvider: "" }) { if (this.status !== ADAPTER_STATUS.CONNECTED) throw WalletLoginError.notConnectedError("Not connected with wallet"); if (!this.authInstance) throw WalletInitializationError.notReady("authInstance is not ready"); try { await this.authInstance.manageMFA(params); } catch (error) { log.error("Failed to manage MFA with auth provider", error); if (error instanceof Web3AuthError) { throw error; } throw WalletLoginError.connectionError("Failed to manage MFA with auth", error); } } async disconnect(options = { cleanup: false }) { if (this.status !== ADAPTER_STATUS.CONNECTED) throw WalletLoginError.notConnectedError("Not connected with wallet"); if (!this.authInstance) throw WalletInitializationError.notReady("authInstance is not ready"); await this.authInstance.logout(); if (options.cleanup) { this.status = ADAPTER_STATUS.NOT_READY; this.authInstance = null; this.privateKeyProvider = null; } else { // ready to be connected again this.status = ADAPTER_STATUS.READY; } this.rehydrated = false; this.emit(ADAPTER_EVENTS.DISCONNECTED); } async authenticateUser() { if (this.status !== ADAPTER_STATUS.CONNECTED) throw WalletLoginError.notConnectedError("Not connected with wallet, Please login/connect first"); const userInfo = await this.getUserInfo(); return { idToken: userInfo.idToken }; } async getUserInfo() { if (this.status !== ADAPTER_STATUS.CONNECTED) throw WalletLoginError.notConnectedError("Not connected with wallet"); if (!this.authInstance) throw WalletInitializationError.notReady("authInstance is not ready"); const userInfo = this.authInstance.getUserInfo(); return userInfo; } // should be called only before initialization. setAdapterSettings(adapterSettings) { super.setAdapterSettings(adapterSettings); const defaultOptions = getAuthDefaultOptions(); log.info("setting adapter settings", adapterSettings); this.authOptions = deepmerge.all([defaultOptions.adapterSettings, this.authOptions || {}, adapterSettings || {}]); if (adapterSettings.web3AuthNetwork) { this.authOptions.network = adapterSettings.web3AuthNetwork; } if (adapterSettings.privateKeyProvider) { this.privateKeyProvider = adapterSettings.privateKeyProvider; } } async addChain(chainConfig, init = false) { var _this$privateKeyProvi; super.checkAddChainRequirements(chainConfig, init); (_this$privateKeyProvi = this.privateKeyProvider) === null || _this$privateKeyProvi === void 0 || _this$privateKeyProvi.addChain(chainConfig); this.addChainConfig(chainConfig); } async switchChain(params, init = false) { var _this$privateKeyProvi2; super.checkSwitchChainRequirements(params, init); await ((_this$privateKeyProvi2 = this.privateKeyProvider) === null || _this$privateKeyProvi2 === void 0 ? void 0 : _this$privateKeyProvi2.switchChain(params)); this.setAdapterSettings({ chainConfig: this.getChainConfig(params.chainId) }); } _getFinalPrivKey() { if (!this.authInstance) return ""; let finalPrivKey = this.authInstance.privKey; // coreKitKey is available only for custom verifiers by default if (this.useCoreKitKey) { // this is to check if the user has already logged in but coreKitKey is not available. // when useCoreKitKey is set to true. // This is to ensure that when there is no user session active, we don't throw an exception. if (this.authInstance.privKey && !this.authInstance.coreKitKey) { throw WalletLoginError.coreKitKeyNotFound(); } finalPrivKey = this.authInstance.coreKitKey; } return finalPrivKey; } _getFinalEd25519PrivKey() { if (!this.authInstance) return ""; let finalPrivKey = this.authInstance.ed25519PrivKey; // coreKitKey is available only for custom verifiers by default if (this.useCoreKitKey) { // this is to check if the user has already logged in but coreKitKey is not available. // when useCoreKitKey is set to true. // This is to ensure that when there is no user session active, we don't throw an exception. if (this.authInstance.ed25519PrivKey && !this.authInstance.coreKitEd25519Key) { throw WalletLoginError.coreKitKeyNotFound(); } finalPrivKey = this.authInstance.coreKitEd25519Key; } return finalPrivKey; } async connectWithProvider(params = { loginProvider: "" }) { var _params$extraLoginOpt; if (!this.privateKeyProvider) throw WalletInitializationError.invalidParams("PrivateKey Provider is required before initialization"); if (!this.authInstance) throw WalletInitializationError.notReady("authInstance is not ready"); const keyAvailable = this._getFinalPrivKey(); // if not logged in then login if (!keyAvailable || (_params$extraLoginOpt = params.extraLoginOptions) !== null && _params$extraLoginOpt !== void 0 && _params$extraLoginOpt.id_token) { var _params$extraLoginOpt2; // always use "other" curve to return token with all keys encoded so wallet service can switch between evm and solana namespace this.loginSettings.curve = SUPPORTED_KEY_CURVES.OTHER; if (!params.loginProvider && !this.loginSettings.loginProvider) throw WalletInitializationError.invalidParams("loginProvider is required for login"); await this.authInstance.login(deepmerge.all([this.loginSettings, params, { extraLoginOptions: _objectSpread(_objectSpread({}, params.extraLoginOptions || {}), {}, { login_hint: params.login_hint || ((_params$extraLoginOpt2 = params.extraLoginOptions) === null || _params$extraLoginOpt2 === void 0 ? void 0 : _params$extraLoginOpt2.login_hint) }) }])); } let finalPrivKey = this._getFinalPrivKey(); if (finalPrivKey) { if (this.currentChainNamespace === CHAIN_NAMESPACES.SOLANA) { finalPrivKey = this._getFinalEd25519PrivKey(); } await this.privateKeyProvider.setupProvider(finalPrivKey); this.status = ADAPTER_STATUS.CONNECTED; this.emit(ADAPTER_EVENTS.CONNECTED, { adapter: WALLET_ADAPTERS.AUTH, reconnected: this.rehydrated, provider: this.provider }); } } } export { AuthAdapter };