UNPKG

@web3auth/modal

Version:

Multi chain wallet aggregator for web3Auth

399 lines (395 loc) 18.7 kB
'use client'; 'use strict'; var _objectSpread = require('@babel/runtime/helpers/objectSpread2'); var _defineProperty = require('@babel/runtime/helpers/defineProperty'); var jsxRuntime = require('react/jsx-runtime'); require('./css/index.css.js'); var auth = require('@web3auth/auth'); var noModal = require('@web3auth/no-modal'); var Bowser = require('bowser'); var client = require('react-dom/client'); var utils = require('../utils.js'); var Widget = require('./components/Widget/Widget.js'); var constants = require('./constants.js'); var AnalyticsContext = require('./context/AnalyticsContext.js'); var ThemeContext = require('./context/ThemeContext.js'); var interfaces = require('./interfaces.js'); var localeImport = require('./localeImport.js'); var utils$1 = require('./utils.js'); function createWrapperForModal(parentZIndex) { const existingWrapper = document.getElementById("w3a-parent-container"); if (existingWrapper) existingWrapper.remove(); const parent = document.createElement("section"); parent.classList.add("w3a-parent-container"); parent.setAttribute("id", "w3a-parent-container"); parent.style.zIndex = parentZIndex; parent.style.position = "relative"; document.body.appendChild(parent); } function createWrapperForEmbed(targetId) { const targetElement = document.getElementById(targetId); if (!targetElement) { noModal.log.error(`Element with ID ${targetId} not found`); return; } targetElement.innerHTML = `<div id="w3a-parent-container" class="w3a-parent-container"></div>`; } class LoginModal { constructor(_uiConfig, callbacks) { _defineProperty(this, "uiConfig", void 0); _defineProperty(this, "stateEmitter", void 0); _defineProperty(this, "chainNamespaces", void 0); _defineProperty(this, "walletRegistry", void 0); _defineProperty(this, "callbacks", void 0); _defineProperty(this, "externalWalletsConfig", void 0); _defineProperty(this, "analytics", void 0); _defineProperty(this, "initModal", async () => { const darkState = { isDark: this.isDark }; const useLang = this.uiConfig.defaultLanguage || auth.LANGUAGES.en; // Load new language resource if (useLang === auth.LANGUAGES.de) { Promise.resolve().then(function () { return require('./i18n/german.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.ja) { Promise.resolve().then(function () { return require('./i18n/japanese.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.ko) { Promise.resolve().then(function () { return require('./i18n/korean.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.zh) { Promise.resolve().then(function () { return require('./i18n/mandarin.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.es) { Promise.resolve().then(function () { return require('./i18n/spanish.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.fr) { Promise.resolve().then(function () { return require('./i18n/french.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.pt) { Promise.resolve().then(function () { return require('./i18n/portuguese.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.nl) { Promise.resolve().then(function () { return require('./i18n/dutch.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.tr) { Promise.resolve().then(function () { return require('./i18n/turkish.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } else if (useLang === auth.LANGUAGES.en) { Promise.resolve().then(function () { return require('./i18n/english.json.js'); }).then(messages => { localeImport.addResourceBundle(useLang, "translation", messages.default); return localeImport.changeLanguage(useLang); }).catch(error => { noModal.log.error(error); }); } return new Promise(resolve => { var _this$uiConfig, _this$uiConfig$theme, _this$uiConfig2; this.stateEmitter.once("MOUNTED", () => { noModal.log.info("rendered"); this.setState({ status: interfaces.MODAL_STATUS.INITIALIZED, web3authClientId: this.uiConfig.web3authClientId, web3authNetwork: this.uiConfig.web3authNetwork, authBuildEnv: this.uiConfig.authBuildEnv }); return resolve(); }); if (this.uiConfig.widgetType === noModal.WIDGET_TYPE.MODAL) { createWrapperForModal(this.uiConfig.modalZIndex); } else if (this.uiConfig.widgetType === noModal.WIDGET_TYPE.EMBED) { createWrapperForEmbed(this.uiConfig.targetId); } else { throw noModal.WalletInitializationError.invalidParams(`Invalid widget type: ${this.uiConfig.widgetType}`); } const container = document.getElementById("w3a-parent-container"); if (darkState.isDark) { container.classList.add("w3a--dark"); } else { container.classList.remove("w3a--dark"); } const root = client.createRoot(container); root.render(jsxRuntime.jsx(ThemeContext.ThemedContext.Provider, { value: darkState, children: jsxRuntime.jsx(AnalyticsContext.AnalyticsContext.Provider, { value: { analytics: this.analytics }, children: jsxRuntime.jsx(Widget, { stateListener: this.stateEmitter, appLogo: darkState.isDark ? this.uiConfig.logoDark : this.uiConfig.logoLight, appName: this.uiConfig.appName, chainNamespaces: this.chainNamespaces, walletRegistry: this.walletRegistry, deviceDetails: this.deviceDetails, handleShowExternalWallets: this.handleShowExternalWallets, handleExternalWalletClick: this.handleExternalWalletClick, handleSocialLoginClick: this.handleSocialLoginClick, closeModal: this.closeModal, uiConfig: this.uiConfig }) }) })); const isDefaultColors = ((_this$uiConfig = this.uiConfig) === null || _this$uiConfig === void 0 || (_this$uiConfig = _this$uiConfig.theme) === null || _this$uiConfig === void 0 ? void 0 : _this$uiConfig.primary) === constants.DEFAULT_PRIMARY_COLOR && ((_this$uiConfig$theme = this.uiConfig.theme) === null || _this$uiConfig$theme === void 0 ? void 0 : _this$uiConfig$theme.onPrimary) === constants.DEFAULT_ON_PRIMARY_COLOR; if ((_this$uiConfig2 = this.uiConfig) !== null && _this$uiConfig2 !== void 0 && _this$uiConfig2.theme && !isDefaultColors) { import('color').then(({ default: Color }) => { const rootElement = document.getElementById("w3a-parent-container"); auth.applyWhiteLabelTheme(Color, rootElement, this.uiConfig.theme); return; }).catch(error => { noModal.log.error(error); }); } }); }); _defineProperty(this, "addSocialLogins", (connector, loginMethods, loginMethodsOrder, uiConfig) => { this.setState({ socialLoginsConfig: { connector, loginMethods, loginMethodsOrder, uiConfig } }); noModal.log.info("addSocialLogins", connector, loginMethods, loginMethodsOrder, uiConfig); }); _defineProperty(this, "addWalletLogins", (externalWalletsConfig, options) => { this.externalWalletsConfig = externalWalletsConfig; const isMMAvailable = !!externalWalletsConfig[noModal.WALLET_CONNECTORS.METAMASK]; this.setState({ externalWalletsConfig, externalWalletsInitialized: !!options.externalWalletsInitialized, showExternalWalletsOnly: !!options.showExternalWalletsOnly, externalWalletsVisibility: isMMAvailable ? false : !!options.externalWalletsVisibility }); }); _defineProperty(this, "open", () => { var _this$analytics, _this$walletRegistry, _this$walletRegistry2; this.setState({ modalVisibility: true }); (_this$analytics = this.analytics) === null || _this$analytics === void 0 || _this$analytics.track(noModal.ANALYTICS_EVENTS.LOGIN_MODAL_OPENED, _objectSpread(_objectSpread({ chain_namespaces: this.chainNamespaces, wallet_registry_count: Object.keys((_this$walletRegistry = this.walletRegistry) === null || _this$walletRegistry === void 0 ? void 0 : _this$walletRegistry.default).length + Object.keys((_this$walletRegistry2 = this.walletRegistry) === null || _this$walletRegistry2 === void 0 ? void 0 : _this$walletRegistry2.others).length, external_wallet_connectors: Object.keys(this.externalWalletsConfig || {}) }, noModal.getWhitelabelAnalyticsProperties(this.uiConfig)), utils.getLoginModalAnalyticsProperties(this.uiConfig))); if (this.callbacks.onModalVisibility) { this.callbacks.onModalVisibility(true); } }); _defineProperty(this, "closeModal", () => { var _this$analytics2; this.setState({ modalVisibility: false, externalWalletsVisibility: false }); (_this$analytics2 = this.analytics) === null || _this$analytics2 === void 0 || _this$analytics2.track(noModal.ANALYTICS_EVENTS.LOGIN_MODAL_CLOSED); if (this.callbacks.onModalVisibility) { this.callbacks.onModalVisibility(false); } }); _defineProperty(this, "initExternalWalletContainer", () => { this.setState({ hasExternalWallets: true }); }); _defineProperty(this, "handleShowExternalWallets", status => { if (this.callbacks.onInitExternalWallets) { this.callbacks.onInitExternalWallets({ externalWalletsInitialized: status }); } }); _defineProperty(this, "handleExternalWalletClick", params => { noModal.log.info("external wallet clicked", params); const { connector, chainNamespace } = params; if (this.callbacks.onExternalWalletLogin) { this.callbacks.onExternalWalletLogin({ connector, loginParams: { chainNamespace } }); } }); _defineProperty(this, "handleSocialLoginClick", params => { var _this$analytics3; noModal.log.info("social login clicked", params); const { connector, loginParams } = params; (_this$analytics3 = this.analytics) === null || _this$analytics3 === void 0 || _this$analytics3.track(noModal.ANALYTICS_EVENTS.SOCIAL_LOGIN_SELECTED, { connector, auth_connection: loginParams.authConnection, auth_connection_id: loginParams.authConnectionId, group_auth_connection_id: loginParams.groupedAuthConnectionId }); if (this.callbacks.onSocialLogin) { this.callbacks.onSocialLogin({ connector, loginParams }); } }); _defineProperty(this, "setState", newState => { this.stateEmitter.emit("STATE_UPDATED", newState); }); _defineProperty(this, "handleConnectorData", connectorData => { if (connectorData.connectorName === noModal.WALLET_CONNECTORS.WALLET_CONNECT_V2) { const walletConnectData = connectorData.data; if (walletConnectData.uri) { this.setState({ walletConnectUri: walletConnectData.uri }); } } if (connectorData.connectorName === noModal.WALLET_CONNECTORS.METAMASK) { const metamaskData = connectorData.data; if (metamaskData.uri) { this.setState({ metamaskConnectUri: metamaskData.uri }); } } }); _defineProperty(this, "subscribeCoreEvents", listener => { listener.on(noModal.CONNECTOR_EVENTS.CONNECTING, data => { var _this$externalWallets; noModal.log.info("connecting with connector", data); // don't show loader in case of wallet connect, because currently it listens for incoming connections without any user interaction if ((data === null || data === void 0 ? void 0 : data.connector) === noModal.WALLET_CONNECTORS.WALLET_CONNECT_V2) return; // don't show loader in case of metamask qr code, because currently it listens for incoming connections without any user interaction const isMetamaskInjected = (_this$externalWallets = this.externalWalletsConfig) === null || _this$externalWallets === void 0 || (_this$externalWallets = _this$externalWallets[noModal.WALLET_CONNECTORS.METAMASK]) === null || _this$externalWallets === void 0 ? void 0 : _this$externalWallets.isInjected; if ((data === null || data === void 0 ? void 0 : data.connector) === noModal.WALLET_CONNECTORS.METAMASK && !isMetamaskInjected && this.deviceDetails.platform === "desktop") return; this.setState({ status: interfaces.MODAL_STATUS.CONNECTING }); }); listener.on(noModal.CONNECTOR_EVENTS.CONNECTED, data => { noModal.log.debug("connected with connector", data); // only show success if not being reconnected again. if (!data.reconnected && data.loginMode === noModal.LOGIN_MODE.MODAL) { this.setState({ status: interfaces.MODAL_STATUS.CONNECTED, modalVisibility: true, postLoadingMessage: "modal.post-loading.connected" }); } else { this.setState({ status: interfaces.MODAL_STATUS.CONNECTED }); } }); // TODO: send connector name in error listener.on(noModal.CONNECTOR_EVENTS.ERRORED, (error, loginMode) => { noModal.log.error("error", error, error.message); if (loginMode === noModal.LOGIN_MODE.NO_MODAL) return; if (error.code === 5000) { if (this.uiConfig.displayErrorsOnModal) this.setState({ modalVisibility: true, postLoadingMessage: error.message || "modal.post-loading.something-wrong", status: interfaces.MODAL_STATUS.ERRORED });else this.setState({ modalVisibility: false }); } else { this.setState({ modalVisibility: true, status: interfaces.MODAL_STATUS.INITIALIZED }); } }); listener.on(noModal.CONNECTOR_EVENTS.DISCONNECTED, () => { this.setState({ status: interfaces.MODAL_STATUS.INITIALIZED, externalWalletsVisibility: false }); // this.toggleMessage(""); }); listener.on(noModal.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorData => { this.handleConnectorData(connectorData); }); }); this.uiConfig = _uiConfig; if (!_uiConfig.logoDark) this.uiConfig.logoDark = constants.DEFAULT_LOGO_DARK; if (!_uiConfig.logoLight) this.uiConfig.logoLight = constants.DEFAULT_LOGO_LIGHT; if (!_uiConfig.mode) this.uiConfig.mode = "light"; if (!_uiConfig.modalZIndex) this.uiConfig.modalZIndex = "99998"; if (typeof _uiConfig.displayErrorsOnModal === "undefined") this.uiConfig.displayErrorsOnModal = true; if (!_uiConfig.appName) this.uiConfig.appName = "Web3Auth"; if (!_uiConfig.loginGridCol) this.uiConfig.loginGridCol = 3; if (!_uiConfig.primaryButton) this.uiConfig.primaryButton = "socialLogin"; if (!_uiConfig.defaultLanguage) this.uiConfig.defaultLanguage = utils$1.getUserLanguage(_uiConfig.defaultLanguage); if (!_uiConfig.widgetType) this.uiConfig.widgetType = noModal.WIDGET_TYPE.MODAL; if (_uiConfig.widgetType === noModal.WIDGET_TYPE.EMBED && !_uiConfig.targetId) { noModal.log.error("targetId is required for embed widget"); throw noModal.WalletInitializationError.invalidParams("targetId is required for embed widget"); } this.stateEmitter = new auth.SafeEventEmitter(); this.chainNamespaces = _uiConfig.chainNamespaces; this.walletRegistry = _uiConfig.walletRegistry; this.callbacks = callbacks; this.analytics = _uiConfig.analytics; this.subscribeCoreEvents(this.uiConfig.connectorListener); } get isDark() { return this.uiConfig.mode === "dark" || this.uiConfig.mode === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches; } get deviceDetails() { if (typeof window === "undefined") return { platform: "mobile", browser: "chrome", os: "ios" }; const browserData = Bowser.getParser(window.navigator.userAgent); return { platform: browserData.getPlatformType(), browser: browserData.getBrowserName().toLowerCase(), os: browserData.getOSName() }; } } exports.LoginModal = LoginModal;