@web3auth/modal
Version:
Multi chain wallet aggregator for web3Auth
399 lines (395 loc) • 18.7 kB
JavaScript
'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;