@web3auth/modal
Version:
Multi chain wallet aggregator for web3Auth
611 lines (575 loc) • 34 kB
JavaScript
import _objectSpread from '@babel/runtime/helpers/objectSpread2';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { serializeError } from '@web3auth/auth';
import { Web3AuthNoModal, cloneDeep, WALLET_CONNECTORS, LOGIN_MODE, log, CONNECTOR_STATUS, sdkVersion, ANALYTICS_SDK_TYPE, withAbort, CONNECTOR_EVENTS, ANALYTICS_EVENTS, getErrorAnalyticsProperties, WalletInitializationError, fetchProjectConfig, fetchWalletRegistry, CONNECTOR_CATEGORY, CONNECTOR_NAMES, CONNECTOR_NAMESPACES } from '@web3auth/no-modal';
import deepmerge from 'deepmerge';
import { defaultConnectorsModalConfig, walletRegistryUrl } from './config.js';
import { AUTH_PROVIDERS_NAMES, AUTH_PROVIDERS, capitalizeFirstLetter } from './ui/config.js';
import { LOGIN_MODAL_EVENTS } from './ui/interfaces.js';
import { LoginModal } from './ui/loginModal.js';
import { getUserLanguage } from './ui/utils.js';
class Web3Auth extends Web3AuthNoModal {
constructor(options, initialState) {
super(options, initialState);
_defineProperty(this, "loginModal", void 0);
_defineProperty(this, "options", void 0);
_defineProperty(this, "modalConfig", cloneDeep(defaultConnectorsModalConfig));
_defineProperty(this, "onInitExternalWallets", async params => {
if (params.externalWalletsInitialized) return;
// initialize WC connector only as other external wallets are initialized in initModal
await this.initExternalConnectors(this.connectors.filter(x => x.name === WALLET_CONNECTORS.WALLET_CONNECT_V2), {
externalWalletsInitialized: true,
externalWalletsVisibility: true
});
});
_defineProperty(this, "onSocialLogin", async params => {
try {
await this.connectTo(WALLET_CONNECTORS.AUTH, params.loginParams, LOGIN_MODE.MODAL);
} catch (error) {
log.error(`Error while connecting to connector: ${params.connector}`, error);
}
});
_defineProperty(this, "onExternalWalletLogin", async params => {
try {
var _params$loginParams;
const connector = this.getConnector(params.connector, (_params$loginParams = params.loginParams) === null || _params$loginParams === void 0 ? void 0 : _params$loginParams.chainNamespace);
// auto-connect WalletConnect in background to generate QR code URI without interfering with user's selected connection
const shouldStartConnectionInBackground = connector.name === WALLET_CONNECTORS.WALLET_CONNECT_V2;
if (shouldStartConnectionInBackground) {
const initialChain = this.getInitialChainIdForConnector(connector);
await connector.connect({
chainId: initialChain.chainId
});
} else {
await this.connectTo(params.connector, params.loginParams, LOGIN_MODE.MODAL);
}
} catch (error) {
log.error(`Error while connecting to connector: ${params.connector}`, error);
}
});
_defineProperty(this, "onModalVisibility", async visibility => {
log.debug("is login modal visible", visibility);
this.emit(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, visibility);
// handle WC session refresh
const wcConnector = this.getConnector(WALLET_CONNECTORS.WALLET_CONNECT_V2);
if (wcConnector) {
const walletConnectStatus = wcConnector === null || wcConnector === void 0 ? void 0 : wcConnector.status;
log.debug("trying refreshing wc session", visibility, walletConnectStatus);
if (visibility && (walletConnectStatus === CONNECTOR_STATUS.READY || walletConnectStatus === CONNECTOR_STATUS.CONNECTING)) {
log.debug("refreshing wc session");
// refreshing session for wallet connect whenever modal is opened.
try {
const initialChain = this.getInitialChainIdForConnector(wcConnector);
wcConnector.connect({
chainId: initialChain.chainId
});
} catch (error) {
log.error(`Error while disconnecting to wallet connect in core`, error);
}
}
if (!visibility && this.status === CONNECTOR_STATUS.CONNECTED && (walletConnectStatus === CONNECTOR_STATUS.READY || walletConnectStatus === CONNECTOR_STATUS.CONNECTING)) {
log.debug("this stops wc connector from trying to reconnect once proposal expires");
wcConnector.status = CONNECTOR_STATUS.READY;
}
}
});
_defineProperty(this, "getChainNamespaces", () => {
var _this$coreOptions$cha;
return [...new Set(((_this$coreOptions$cha = this.coreOptions.chains) === null || _this$coreOptions$cha === void 0 ? void 0 : _this$coreOptions$cha.map(x => x.chainNamespace)) || [])];
});
this.options = _objectSpread({}, options);
if (!this.options.uiConfig) this.options.uiConfig = {
logoLight: "",
logoDark: ""
};
if (this.options.modalConfig) this.modalConfig = this.options.modalConfig;
log.info("modalConfig", this.modalConfig);
}
async init(options) {
// init analytics
const startTime = Date.now();
this.analytics.init();
this.analytics.identify(this.options.clientId, {
web3auth_client_id: this.options.clientId,
web3auth_network: this.options.web3AuthNetwork
});
this.analytics.setGlobalProperties({
dapp_url: window.location.origin,
sdk_name: ANALYTICS_SDK_TYPE.WEB_MODAL,
sdk_version: sdkVersion,
// Required for organization analytics
web3auth_client_id: this.options.clientId,
web3auth_network: this.options.web3AuthNetwork
});
let trackData = {};
try {
var _authConnector$authIn, _this$coreOptions$uiC;
const {
signal
} = options || {};
super.checkInitRequirements();
// get project config and wallet registry
const {
projectConfig,
walletRegistry
} = await this.getProjectAndWalletConfig();
// init config
this.initUIConfig(projectConfig);
super.initAccountAbstractionConfig(projectConfig);
super.initChainsConfig(projectConfig);
super.initCachedConnectorAndChainId();
super.initWalletServicesConfig(projectConfig);
this.analytics.setGlobalProperties({
team_id: projectConfig.teamId
});
trackData = this.getInitializationTrackData();
// init login modal
const {
filteredWalletRegistry,
disabledExternalWallets
} = this.filterWalletRegistry(walletRegistry, projectConfig);
this.loginModal = new LoginModal(_objectSpread(_objectSpread({}, this.options.uiConfig), {}, {
connectorListener: this,
web3authClientId: this.options.clientId,
web3authNetwork: this.options.web3AuthNetwork,
authBuildEnv: this.options.authBuildEnv,
chainNamespaces: this.getChainNamespaces(),
walletRegistry: filteredWalletRegistry,
analytics: this.analytics
}), {
onInitExternalWallets: this.onInitExternalWallets,
onSocialLogin: this.onSocialLogin,
onExternalWalletLogin: this.onExternalWalletLogin,
onModalVisibility: this.onModalVisibility
});
await withAbort(() => this.loginModal.initModal(), signal);
// setup common JRPC provider
await withAbort(() => this.setupCommonJRPCProvider(), signal);
// initialize connectors
this.on(CONNECTOR_EVENTS.CONNECTORS_UPDATED, ({
connectors: newConnectors
}) => {
const onAbortHandler = () => {
var _this$connectors;
log.debug("init aborted");
if (((_this$connectors = this.connectors) === null || _this$connectors === void 0 ? void 0 : _this$connectors.length) > 0) {
super.cleanup();
}
};
withAbort(() => this.initConnectors({
connectors: newConnectors,
projectConfig,
disabledExternalWallets
}), signal, onAbortHandler);
});
await withAbort(() => super.loadConnectors({
projectConfig,
modalMode: true
}), signal);
// initialize plugins
await withAbort(() => super.initPlugins(), signal);
// track completion event
const authConnector = this.getConnector(WALLET_CONNECTORS.AUTH);
trackData = _objectSpread(_objectSpread({}, trackData), {}, {
connectors: this.connectors.map(connector => connector.name),
plugins: Object.keys(this.plugins),
auth_ux_mode: (authConnector === null || authConnector === void 0 || (_authConnector$authIn = authConnector.authInstance) === null || _authConnector$authIn === void 0 || (_authConnector$authIn = _authConnector$authIn.options) === null || _authConnector$authIn === void 0 ? void 0 : _authConnector$authIn.uxMode) || ((_this$coreOptions$uiC = this.coreOptions.uiConfig) === null || _this$coreOptions$uiC === void 0 ? void 0 : _this$coreOptions$uiC.uxMode)
});
this.analytics.track(ANALYTICS_EVENTS.SDK_INITIALIZATION_COMPLETED, _objectSpread(_objectSpread({}, trackData), {}, {
duration: Date.now() - startTime
}));
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") return;
// track failure event
this.analytics.track(ANALYTICS_EVENTS.SDK_INITIALIZATION_FAILED, _objectSpread(_objectSpread(_objectSpread({}, trackData), getErrorAnalyticsProperties(error)), {}, {
duration: Date.now() - startTime
}));
log.error("Failed to initialize modal", error);
throw error;
}
}
async connect() {
if (!this.loginModal) throw WalletInitializationError.notReady("Login modal is not initialized");
// if already connected return provider
if (this.connectedConnectorName && this.status === CONNECTOR_STATUS.CONNECTED && this.provider) return this.provider;
this.loginModal.open();
return new Promise((resolve, reject) => {
// remove all listeners when promise is resolved or rejected.
// this is to prevent memory leaks if user clicks connect button multiple times.
const handleConnected = () => {
this.removeListener(CONNECTOR_EVENTS.ERRORED, handleError);
this.removeListener(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, handleVisibility);
return resolve(this.provider);
};
const handleError = err => {
this.removeListener(CONNECTOR_EVENTS.CONNECTED, handleConnected);
this.removeListener(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, handleVisibility);
return reject(err);
};
const handleVisibility = visibility => {
// modal is closed but user is not connected to any wallet.
if (!visibility && this.status !== CONNECTOR_STATUS.CONNECTED) {
this.removeListener(CONNECTOR_EVENTS.CONNECTED, handleConnected);
this.removeListener(CONNECTOR_EVENTS.ERRORED, handleError);
return reject(new Error("User closed the modal"));
}
};
this.once(CONNECTOR_EVENTS.CONNECTED, handleConnected);
this.once(CONNECTOR_EVENTS.ERRORED, handleError);
this.once(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, handleVisibility);
});
}
initUIConfig(projectConfig) {
super.initUIConfig(projectConfig);
this.options.uiConfig = deepmerge(cloneDeep(projectConfig.whitelabel || {}), this.options.uiConfig || {});
if (!this.options.uiConfig.defaultLanguage) this.options.uiConfig.defaultLanguage = getUserLanguage(this.options.uiConfig.defaultLanguage);
if (!this.options.uiConfig.mode) this.options.uiConfig.mode = "light";
const uiConfig = deepmerge.all([projectConfig.loginModal || {}, this.options.uiConfig], {
arrayMerge: (_, sourceArray) => sourceArray
});
this.options.uiConfig = _objectSpread(_objectSpread({}, uiConfig), {}, {
logoLight: uiConfig.logoLight || "",
logoDark: uiConfig.logoDark || ""
});
// merge login methods order from project config and user config, with user config taking precedence
const defaultAuthConnections = projectConfig.embeddedWalletAuth.filter(x => x.isDefault).map(x => x.authConnection);
const mergedAuthConnections = [...(this.options.uiConfig.loginMethodsOrder || []), ...defaultAuthConnections];
const loginMethodsOrder = [];
const authConnectionSet = new Set();
for (const authConnection of mergedAuthConnections) {
if (authConnectionSet.has(authConnection)) continue;
authConnectionSet.add(authConnection);
loginMethodsOrder.push(authConnection);
}
this.options.uiConfig.loginMethodsOrder = loginMethodsOrder;
}
getInitializationTrackData() {
var _this$modalConfig, _this$modalConfig2, _this$modalConfig3, _this$options$uiConfi, _this$options$uiConfi2, _this$options$uiConfi3, _this$options$uiConfi4, _this$options$uiConfi5, _this$options$uiConfi6, _this$options$uiConfi7, _this$options$uiConfi8, _this$options$uiConfi9, _this$options$uiConfi0, _this$options$uiConfi1, _this$options$uiConfi10, _this$options$uiConfi11, _this$options$uiConfi12;
return _objectSpread(_objectSpread({}, super.getInitializationTrackData()), {}, {
modal_hide_wallet_discovery: (_this$modalConfig = this.modalConfig) === null || _this$modalConfig === void 0 ? void 0 : _this$modalConfig.hideWalletDiscovery,
modal_connectors: Object.keys(((_this$modalConfig2 = this.modalConfig) === null || _this$modalConfig2 === void 0 ? void 0 : _this$modalConfig2.connectors) || {}),
modal_auth_connector_login_methods: Object.keys(((_this$modalConfig3 = this.modalConfig) === null || _this$modalConfig3 === void 0 || (_this$modalConfig3 = _this$modalConfig3.connectors) === null || _this$modalConfig3 === void 0 || (_this$modalConfig3 = _this$modalConfig3[WALLET_CONNECTORS.AUTH]) === null || _this$modalConfig3 === void 0 ? void 0 : _this$modalConfig3.loginMethods) || {}),
// UI config
ui_login_methods_order: (_this$options$uiConfi = this.options.uiConfig) === null || _this$options$uiConfi === void 0 ? void 0 : _this$options$uiConfi.loginMethodsOrder,
ui_modal_z_index: (_this$options$uiConfi2 = this.options.uiConfig) === null || _this$options$uiConfi2 === void 0 ? void 0 : _this$options$uiConfi2.modalZIndex,
ui_display_errors_on_modal: (_this$options$uiConfi3 = this.options.uiConfig) === null || _this$options$uiConfi3 === void 0 ? void 0 : _this$options$uiConfi3.displayErrorsOnModal,
ui_login_grid_col: (_this$options$uiConfi4 = this.options.uiConfig) === null || _this$options$uiConfi4 === void 0 ? void 0 : _this$options$uiConfi4.loginGridCol,
ui_primary_button: (_this$options$uiConfi5 = this.options.uiConfig) === null || _this$options$uiConfi5 === void 0 ? void 0 : _this$options$uiConfi5.primaryButton,
ui_modal_widget_type: (_this$options$uiConfi6 = this.options.uiConfig) === null || _this$options$uiConfi6 === void 0 ? void 0 : _this$options$uiConfi6.widgetType,
ui_modal_target_id_used: Boolean((_this$options$uiConfi7 = this.options.uiConfig) === null || _this$options$uiConfi7 === void 0 ? void 0 : _this$options$uiConfi7.targetId),
ui_modal_logo_alignment: (_this$options$uiConfi8 = this.options.uiConfig) === null || _this$options$uiConfi8 === void 0 ? void 0 : _this$options$uiConfi8.logoAlignment,
ui_modal_border_radius_type: (_this$options$uiConfi9 = this.options.uiConfig) === null || _this$options$uiConfi9 === void 0 ? void 0 : _this$options$uiConfi9.borderRadiusType,
ui_modal_button_radius_type: (_this$options$uiConfi0 = this.options.uiConfig) === null || _this$options$uiConfi0 === void 0 ? void 0 : _this$options$uiConfi0.buttonRadiusType,
ui_modal_sign_in_methods: (_this$options$uiConfi1 = this.options.uiConfig) === null || _this$options$uiConfi1 === void 0 ? void 0 : _this$options$uiConfi1.signInMethods,
ui_modal_add_previous_login_hint: (_this$options$uiConfi10 = this.options.uiConfig) === null || _this$options$uiConfi10 === void 0 ? void 0 : _this$options$uiConfi10.addPreviousLoginHint,
ui_modal_display_installed_external_wallets: (_this$options$uiConfi11 = this.options.uiConfig) === null || _this$options$uiConfi11 === void 0 ? void 0 : _this$options$uiConfi11.displayInstalledExternalWallets,
ui_modal_display_external_wallets_count: (_this$options$uiConfi12 = this.options.uiConfig) === null || _this$options$uiConfi12 === void 0 ? void 0 : _this$options$uiConfi12.displayExternalWalletsCount
});
}
filterWalletRegistry(walletRegistry, projectConfig) {
const {
disableAllRecommendedWallets,
disableAllOtherWallets,
disabledWallets
} = projectConfig.externalWalletAuth || {};
// add disabled wallets to set
const disabledExternalWallets = new Set(disabledWallets || []);
if (disableAllRecommendedWallets) {
Object.keys(walletRegistry.default).forEach(wallet => disabledExternalWallets.add(wallet));
}
if (disableAllOtherWallets) {
Object.keys(walletRegistry.others).forEach(wallet => disabledExternalWallets.add(wallet));
}
// always show MetaMask, force enable it
disabledExternalWallets.delete(WALLET_CONNECTORS.METAMASK);
// remove wallets that are disabled in project config from wallet registry
const filteredWalletRegistry = cloneDeep(walletRegistry);
disabledExternalWallets.forEach(wallet => {
delete filteredWalletRegistry.default[wallet];
delete filteredWalletRegistry.others[wallet];
});
return {
disabledExternalWallets,
filteredWalletRegistry
};
}
async getProjectAndWalletConfig() {
var _this$options$account, _this$modalConfig4;
const [projectConfigResult, walletRegistryResult] = await Promise.allSettled([fetchProjectConfig({
clientId: this.options.clientId,
web3AuthNetwork: this.options.web3AuthNetwork,
aaProvider: (_this$options$account = this.options.accountAbstractionConfig) === null || _this$options$account === void 0 ? void 0 : _this$options$account.smartAccountType,
authBuildEnv: this.options.authBuildEnv
}), fetchWalletRegistry(walletRegistryUrl)]);
// handle project config result
if (projectConfigResult.status === "rejected") {
const error = await serializeError(projectConfigResult.reason);
log.error("Failed to fetch project configurations", error);
throw WalletInitializationError.notReady("failed to fetch project configurations", error);
}
const projectConfig = projectConfigResult.value;
// handle wallet registry result
let walletRegistry = {
others: {},
default: {}
};
const isExternalWalletEnabled = Boolean(projectConfig.externalWalletAuth);
if (isExternalWalletEnabled && !((_this$modalConfig4 = this.modalConfig) !== null && _this$modalConfig4 !== void 0 && _this$modalConfig4.hideWalletDiscovery)) {
if (walletRegistryResult.status === "fulfilled") {
walletRegistry = walletRegistryResult.value;
} else {
log.error("Failed to fetch wallet registry", walletRegistryResult.reason);
}
}
return {
projectConfig,
walletRegistry
};
}
async initConnectors({
connectors,
projectConfig,
disabledExternalWallets
}) {
// filter connectors based on config
const filteredConnectorNames = await this.filterConnectors({
projectConfig,
disabledExternalWallets
});
// initialize connectors based on availability
const {
hasInAppConnectors,
hasExternalConnectors
} = await this.checkConnectorAvailability(filteredConnectorNames);
const filteredConnectors = connectors.filter(x => filteredConnectorNames.includes(x.name));
// initialize in-app and cached connector (if there are only external connectors enabled)
await this.initInAppAndCachedConnectors(filteredConnectors);
if (hasExternalConnectors) {
if (hasInAppConnectors) {
// show connect button if both in-app and external wallets are available
this.loginModal.initExternalWalletContainer();
// initialize installed external wallets (except WC), don't mark external wallets as fully initialized
this.initExternalConnectors(filteredConnectors.filter(x => x.type === CONNECTOR_CATEGORY.EXTERNAL && x.name !== WALLET_CONNECTORS.WALLET_CONNECT_V2), {
externalWalletsInitialized: false,
showExternalWalletsOnly: false,
externalWalletsVisibility: false
});
} else {
// if no in app wallet is available then initialize all external wallets in modal
await this.initExternalConnectors(filteredConnectors.filter(x => x.type === CONNECTOR_CATEGORY.EXTERNAL), {
externalWalletsInitialized: true,
showExternalWalletsOnly: true,
externalWalletsVisibility: true
});
}
}
// emit ready event if connector is ready
if (this.status === CONNECTOR_STATUS.NOT_READY) {
this.status = CONNECTOR_STATUS.READY;
this.emit(CONNECTOR_EVENTS.READY);
}
}
async filterConnectors({
projectConfig,
disabledExternalWallets
}) {
var _this$modalConfig5;
// Auth connector config: populate this with the default config for auth connectors.
const loginMethods = {};
const embedWalletConfigMap = new Map();
for (const authConnectionConfig of projectConfig.embeddedWalletAuth || []) {
const {
isDefault,
authConnection,
groupedAuthConnectionId,
authConnectionId
} = authConnectionConfig;
if (isDefault) {
loginMethods[authConnection] = {
name: AUTH_PROVIDERS_NAMES[authConnection],
authConnection: authConnection,
authConnectionId: authConnectionId,
groupedAuthConnectionId: groupedAuthConnectionId,
extraLoginOptions: authConnectionConfig.jwtParameters,
isDefault: true,
showOnModal: true
};
}
embedWalletConfigMap.set(groupedAuthConnectionId || authConnectionId, authConnectionConfig);
}
const dashboardConnectorConfig = {
[WALLET_CONNECTORS.AUTH]: {
label: WALLET_CONNECTORS.AUTH,
loginMethods
}
};
// populate the user config data with the dashboard config.
if ((_this$modalConfig5 = this.modalConfig) !== null && _this$modalConfig5 !== void 0 && (_this$modalConfig5 = _this$modalConfig5.connectors) !== null && _this$modalConfig5 !== void 0 && _this$modalConfig5[WALLET_CONNECTORS.AUTH]) {
if (!this.modalConfig.connectors[WALLET_CONNECTORS.AUTH].loginMethods) this.modalConfig.connectors[WALLET_CONNECTORS.AUTH].loginMethods = {};
}
const authProviders = new Set(AUTH_PROVIDERS);
Object.keys(this.modalConfig.connectors[WALLET_CONNECTORS.AUTH].loginMethods).forEach(key => {
const userConfig = this.modalConfig.connectors[WALLET_CONNECTORS.AUTH].loginMethods[key];
const {
authConnectionId,
groupedAuthConnectionId
} = userConfig;
if (!authProviders.has(key)) {
throw WalletInitializationError.invalidParams(`Invalid auth connection: ${key}`);
}
// only throw error if one of them is defined in the config.
if (groupedAuthConnectionId || authConnectionId) {
if (!embedWalletConfigMap.has(groupedAuthConnectionId || authConnectionId)) throw WalletInitializationError.invalidParams(`Invalid auth connection config, authConnection: ${key}. Missing AuthConnectionConfig from the dashboard.`);
const configFromDashboard = embedWalletConfigMap.get(groupedAuthConnectionId || authConnectionId);
this.modalConfig.connectors[WALLET_CONNECTORS.AUTH].loginMethods[key] = {
authConnection: configFromDashboard.authConnection,
authConnectionId: configFromDashboard.authConnectionId,
groupedAuthConnectionId: configFromDashboard.groupedAuthConnectionId,
isDefault: configFromDashboard.isDefault || false,
extraLoginOptions: _objectSpread(_objectSpread({}, configFromDashboard.jwtParameters), userConfig.extraLoginOptions)
};
}
});
this.modalConfig.connectors = deepmerge(dashboardConnectorConfig, cloneDeep(this.modalConfig.connectors || {}));
// merge default connectors with the custom configured connectors.
const allConnectorNames = [...new Set([...Object.keys(this.modalConfig.connectors || {}), ...this.connectors.map(connector => connector.name)])];
const connectorNames = allConnectorNames.map(connectorName => {
var _this$modalConfig6, _this$modalConfig$con, _this$modalConfig$con2;
// start with the default config of connector.
const defaultConnectorConfig = {
label: CONNECTOR_NAMES[connectorName] || connectorName.split("-").map(capitalizeFirstLetter).join(" "),
showOnModal: true
};
this.modalConfig.connectors[connectorName] = _objectSpread(_objectSpread({}, defaultConnectorConfig), ((_this$modalConfig6 = this.modalConfig) === null || _this$modalConfig6 === void 0 || (_this$modalConfig6 = _this$modalConfig6.connectors) === null || _this$modalConfig6 === void 0 ? void 0 : _this$modalConfig6[connectorName]) || {});
// check if connector is configured/added by user and exist in connectors map.
const connector = this.getConnector(connectorName);
log.debug("connector config", connectorName, (_this$modalConfig$con = this.modalConfig.connectors) === null || _this$modalConfig$con === void 0 || (_this$modalConfig$con = _this$modalConfig$con[connectorName]) === null || _this$modalConfig$con === void 0 ? void 0 : _this$modalConfig$con.showOnModal, connector);
// check if connector is configured/added by user and exist in connectors map.
const connectorConfig = (_this$modalConfig$con2 = this.modalConfig.connectors) === null || _this$modalConfig$con2 === void 0 ? void 0 : _this$modalConfig$con2[connectorName];
if (!connector) {
if (connectorConfig.showOnModal) throw WalletInitializationError.invalidParams(`Connector ${connectorName} is not configured`);
return;
}
// skip connector if it is hidden by user
if (!connectorConfig.showOnModal) return;
// skip external connector if external wallets are disabled except for MetaMask
const isExternalWalletEnabled = Boolean(projectConfig.externalWalletAuth);
if (connector.type === CONNECTOR_CATEGORY.EXTERNAL && connector.name !== WALLET_CONNECTORS.METAMASK) {
if (!isExternalWalletEnabled) return;
if (disabledExternalWallets.has(connectorName)) return;
}
// skip WC connector if external wallets are disabled or hideWalletDiscovery is true
if (connectorName === WALLET_CONNECTORS.WALLET_CONNECT_V2) {
var _this$modalConfig7;
if (!isExternalWalletEnabled) return;
if ((_this$modalConfig7 = this.modalConfig) !== null && _this$modalConfig7 !== void 0 && _this$modalConfig7.hideWalletDiscovery) return;
}
this.modalConfig.connectors[connectorName] = connectorConfig;
return connectorName;
});
// const connectorNames = await Promise.all(connectorConfigurationPromises);
return connectorNames.filter(name => name !== undefined);
}
async checkConnectorAvailability(connectorNames) {
// currently all default in app and external wallets can be hidden or shown based on config.
// check if in app connectors are available
const hasInAppConnectors = this.connectors.some(connector => {
var _this$modalConfig$con3, _this$modalConfig$con4;
if (connector.type !== CONNECTOR_CATEGORY.IN_APP) return false;
if (((_this$modalConfig$con3 = this.modalConfig.connectors) === null || _this$modalConfig$con3 === void 0 || (_this$modalConfig$con3 = _this$modalConfig$con3[connector.name]) === null || _this$modalConfig$con3 === void 0 ? void 0 : _this$modalConfig$con3.showOnModal) !== true) return false;
if (!((_this$modalConfig$con4 = this.modalConfig.connectors) !== null && _this$modalConfig$con4 !== void 0 && (_this$modalConfig$con4 = _this$modalConfig$con4[connector.name]) !== null && _this$modalConfig$con4 !== void 0 && _this$modalConfig$con4.loginMethods)) return true;
if (Object.values(this.modalConfig.connectors[connector.name].loginMethods).some(method => method.showOnModal)) return true;
return false;
});
log.debug(hasInAppConnectors, this.connectors, connectorNames, "hasInAppWallets");
// check if external connectors are available
const hasExternalConnectors = connectorNames.some(connectorName => {
var _this$getConnector, _this$modalConfig$con5;
if (connectorName === WALLET_CONNECTORS.WALLET_CONNECT_V2) return true;
return ((_this$getConnector = this.getConnector(connectorName)) === null || _this$getConnector === void 0 ? void 0 : _this$getConnector.type) === CONNECTOR_CATEGORY.EXTERNAL && ((_this$modalConfig$con5 = this.modalConfig.connectors) === null || _this$modalConfig$con5 === void 0 || (_this$modalConfig$con5 = _this$modalConfig$con5[connectorName]) === null || _this$modalConfig$con5 === void 0 ? void 0 : _this$modalConfig$con5.showOnModal);
});
return {
hasInAppConnectors,
hasExternalConnectors
};
}
async initInAppAndCachedConnectors(connectors) {
await Promise.all(connectors.map(async connector => {
const connectorName = connector.name;
try {
// skip if connector is already initialized
if (connector.status !== CONNECTOR_STATUS.NOT_READY) return;
// only initialize a external connectors here if it is a cached connector.
if (this.cachedConnector !== connectorName && connector.type === CONNECTOR_CATEGORY.EXTERNAL) return;
// in-app wallets or cached wallet (being connected or already connected) are initialized first.
// if connector is configured then only initialize in app or cached connector.
// external wallets are initialized on INIT_EXTERNAL_WALLET event.
this.subscribeToConnectorEvents(connector);
const initialChain = this.getInitialChainIdForConnector(connector);
const autoConnect = super.checkIfAutoConnect(connector);
await connector.init({
autoConnect,
chainId: initialChain.chainId
});
// note: not adding cachedWallet to modal if it is external wallet.
// adding it later if no in-app wallets are available.
if (connector.type === CONNECTOR_CATEGORY.IN_APP) {
var _this$modalConfig$con6, _this$options$uiConfi13, _this$options$uiConfi14, _this$options$uiConfi15;
log.info("connectorInitResults", connectorName);
const loginMethods = ((_this$modalConfig$con6 = this.modalConfig.connectors[connectorName]) === null || _this$modalConfig$con6 === void 0 ? void 0 : _this$modalConfig$con6.loginMethods) || {};
this.loginModal.addSocialLogins(connectorName, loginMethods, ((_this$options$uiConfi13 = this.options.uiConfig) === null || _this$options$uiConfi13 === void 0 ? void 0 : _this$options$uiConfi13.loginMethodsOrder) || AUTH_PROVIDERS, _objectSpread(_objectSpread({}, this.options.uiConfig), {}, {
loginGridCol: ((_this$options$uiConfi14 = this.options.uiConfig) === null || _this$options$uiConfi14 === void 0 ? void 0 : _this$options$uiConfi14.loginGridCol) || 3,
primaryButton: ((_this$options$uiConfi15 = this.options.uiConfig) === null || _this$options$uiConfi15 === void 0 ? void 0 : _this$options$uiConfi15.primaryButton) || "socialLogin"
}));
}
} catch (error) {
log.error(error, "error while initializing connector ", connectorName);
}
}));
}
async initExternalConnectors(externalConnectors, options) {
const connectorsConfig = {};
const connectorChainNamespaceMap = {};
// we do it like this because we don't want one slow connector to delay the load of the entire external wallet section.
externalConnectors.forEach(async connector => {
const connectorName = connector.name;
log.debug("init external wallet", this.cachedConnector, connectorName, connector.status);
// a wallet can support multiple chain namespaces e.g. Phantom has EvmInjected connector and WalletStandard connector.
if (!connectorChainNamespaceMap[connectorName]) connectorChainNamespaceMap[connectorName] = new Set();
if (connector.connectorNamespace === CONNECTOR_NAMESPACES.MULTICHAIN) {
this.getChainNamespaces().forEach(x => connectorChainNamespaceMap[connectorName].add(x));
} else {
connectorChainNamespaceMap[connectorName].add(connector.connectorNamespace);
}
// initialize connectors
// skip initializing cached connector here as it is already being initialized in initModal before.
if (connector.status === CONNECTOR_STATUS.NOT_READY && this.cachedConnector !== connectorName) {
try {
this.subscribeToConnectorEvents(connector);
const initialChain = this.getInitialChainIdForConnector(connector);
await connector.init({
autoConnect: this.cachedConnector === connectorName,
chainId: initialChain.chainId
});
} catch (error) {
log.error(error, "error while initializing connector", connectorName);
}
}
// update connector config
if ([CONNECTOR_STATUS.NOT_READY, CONNECTOR_STATUS.READY, CONNECTOR_STATUS.CONNECTING, CONNECTOR_STATUS.CONNECTED].includes(connector.status)) {
const connectorModalConfig = this.modalConfig.connectors[connectorName];
connectorsConfig[connectorName] = _objectSpread(_objectSpread({}, connectorModalConfig), {}, {
isInjected: connector.isInjected,
icon: connector.icon,
chainNamespaces: Array.from(connectorChainNamespaceMap[connectorName])
});
this.loginModal.addWalletLogins(connectorsConfig, {
showExternalWalletsOnly: !!options.showExternalWalletsOnly,
externalWalletsVisibility: !!options.externalWalletsVisibility,
externalWalletsInitialized: !!options.externalWalletsInitialized
});
}
});
}
}
export { Web3Auth };