Skip to content

Commit 6a2b20b

Browse files
committed
handle connecting to Metamask multiple times
1 parent e4df8b5 commit 6a2b20b

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

packages/modal/src/modalManager.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,7 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
420420
if (connector.status !== CONNECTOR_STATUS.NOT_READY) return;
421421

422422
// only initialize a external connectors here if it is a cached connector.
423-
if (
424-
this.cachedConnector !== connectorName &&
425-
connectorName !== WALLET_CONNECTORS.METAMASK &&
426-
connector.type === CONNECTOR_CATEGORY.EXTERNAL
427-
)
428-
return;
423+
if (this.cachedConnector !== connectorName && connector.type === CONNECTOR_CATEGORY.EXTERNAL) return;
429424

430425
// in-app wallets or cached wallet (being connected or already connected) are initialized first.
431426
// if connector is configured then only initialize in app or cached connector.
@@ -533,6 +528,8 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
533528
private onModalVisibility = async (visibility: boolean): Promise<void> => {
534529
log.debug("is login modal visible", visibility);
535530
this.emit(LOGIN_MODAL_EVENTS.MODAL_VISIBILITY, visibility);
531+
532+
// handle WC session refresh
536533
const wcConnector = this.getConnector(WALLET_CONNECTORS.WALLET_CONNECT_V2);
537534
if (wcConnector) {
538535
const walletConnectStatus = wcConnector?.status;
@@ -557,6 +554,32 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
557554
wcConnector.status = CONNECTOR_STATUS.READY;
558555
}
559556
}
557+
558+
// handle MM session refresh if MM is not injected
559+
const metamaskConnector = this.getConnector(WALLET_CONNECTORS.METAMASK);
560+
if (metamaskConnector && !metamaskConnector.isInjected) {
561+
const status = metamaskConnector?.status;
562+
log.debug("trying refreshing MM session", visibility, status);
563+
if (visibility && (status === CONNECTOR_STATUS.READY || status === CONNECTOR_STATUS.CONNECTING)) {
564+
log.debug("refreshing MM session");
565+
566+
// refreshing session for MM whenever modal is opened.
567+
try {
568+
const initialChain = this.getInitialChainIdForConnector(metamaskConnector);
569+
metamaskConnector.connect({ chainId: initialChain.chainId });
570+
} catch (error) {
571+
log.error(`Error while connecting to MM`, error);
572+
}
573+
}
574+
if (
575+
!visibility &&
576+
this.status === CONNECTOR_STATUS.CONNECTED &&
577+
(status === CONNECTOR_STATUS.READY || status === CONNECTOR_STATUS.CONNECTING)
578+
) {
579+
log.debug("this stops MM connector from trying to reconnect once proposal expires");
580+
metamaskConnector.status = CONNECTOR_STATUS.READY;
581+
}
582+
}
560583
};
561584

562585
private getChainNamespaces = (): ChainNamespaceType[] => {

packages/no-modal/src/connectors/metamask-connector/metamaskConnector.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ class MetaMaskConnector extends BaseEvmConnector<void> {
7979
iconUrl,
8080
};
8181

82-
// Initialize the MetaMask SDK
82+
// initialize the MetaMask SDK
8383
const metamaskOptions = deepmerge(this.metamaskOptions || { headless: true }, { dappMetadata: appMetadata }); // TODO: only use headless for Modal SDK
8484
this.metamaskSDK = new MetaMaskSDK(metamaskOptions);
85-
await this.metamaskSDK.init();
85+
// Note: in case there is an existing SDK instance in memory (window.mmsdk exists), it won't initialize the new SDK instance and return the existing instance instead of undefined
86+
const initResult = await this.metamaskSDK.init();
87+
if (initResult) {
88+
this.metamaskSDK = initResult;
89+
}
8690
this.isInjected = this.metamaskSDK.isExtensionActive();
8791

8892
this.status = CONNECTOR_STATUS.READY;
@@ -103,15 +107,18 @@ class MetaMaskConnector extends BaseEvmConnector<void> {
103107
const chainConfig = this.coreOptions.chains.find((x) => x.chainId === chainId);
104108
if (!chainConfig) throw WalletLoginError.connectionError("Chain config is not available");
105109
try {
106-
// when metamask is not injected and headless is true, broadcast the uri to the login modal
107-
if (!this.metamaskSDK.isExtensionActive() && this.metamaskOptions.headless) {
108-
this.metamaskSDK.getProvider().on("display_uri", (uri) => {
109-
this.updateConnectorData({ uri } as MetaMaskConnectorData);
110-
});
111-
}
112110
if (this.status !== CONNECTOR_STATUS.CONNECTING) {
113111
this.status = CONNECTOR_STATUS.CONNECTING;
114112
this.emit(CONNECTOR_EVENTS.CONNECTING, { connector: WALLET_CONNECTORS.METAMASK });
113+
if (!this.metamaskSDK.isInitialized()) {
114+
await this.metamaskSDK.init();
115+
}
116+
// when metamask is not injected and headless is true, broadcast the uri to the login modal
117+
if (!this.metamaskSDK.isExtensionActive() && this.metamaskOptions.headless) {
118+
this.metamaskSDK.getProvider().on("display_uri", (uri) => {
119+
this.updateConnectorData({ uri } as MetaMaskConnectorData);
120+
});
121+
}
115122
await this.metamaskSDK.connect();
116123
}
117124

packages/no-modal/src/noModal.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export class Web3AuthNoModal extends SafeEventEmitter<Web3AuthNoModalEvents> imp
371371

372372
protected async loadConnectors({ projectConfig, modalMode }: { projectConfig: ProjectConfig; modalMode?: boolean }) {
373373
// always add auth and metaMask connector
374-
const connectorFns = [...(this.coreOptions.connectors || []), authConnector(), metaMaskConnector(modalMode ? { headless: true } : undefined)];
374+
const connectorFns = [...(this.coreOptions.connectors || []), authConnector()];
375375
const config = {
376376
projectConfig,
377377
coreOptions: this.coreOptions,
@@ -411,6 +411,9 @@ export class Web3AuthNoModal extends SafeEventEmitter<Web3AuthNoModalEvents> imp
411411
}
412412
}
413413

414+
// it's safe to add it here as if there is a MetaMask injected provider, this won't override it
415+
connectorFns.push(metaMaskConnector(modalMode ? { headless: true } : undefined));
416+
414417
// add WalletConnectV2 connector if external wallets are enabled
415418
if (isExternalWalletEnabled && (chainNamespaces.has(CHAIN_NAMESPACES.SOLANA) || chainNamespaces.has(CHAIN_NAMESPACES.EIP155))) {
416419
const { walletConnectV2Connector } = await import("./connectors/wallet-connect-v2-connector");

0 commit comments

Comments
 (0)