@web3auth/no-modal 11.1.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/lib.cjs/account-linking/react.js +1 -0
  2. package/dist/lib.cjs/account-linking/vue.js +1 -0
  3. package/dist/lib.cjs/base/connector/baseConnector.js +42 -11
  4. package/dist/lib.cjs/base/errors/index.js +5 -1
  5. package/dist/lib.cjs/base/utils.js +1 -1
  6. package/dist/lib.cjs/connectors/auth-connector/authConnector.js +15 -6
  7. package/dist/lib.cjs/connectors/coinbase-connector/coinbaseConnector.js +5 -5
  8. package/dist/lib.cjs/connectors/injected-evm-connector/injectedEvmConnector.js +6 -5
  9. package/dist/lib.cjs/connectors/injected-solana-connector/walletStandardConnector.js +6 -5
  10. package/dist/lib.cjs/connectors/metamask-connector/metamaskConnector.js +82 -31
  11. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +8 -6
  12. package/dist/lib.cjs/index.js +8 -7
  13. package/dist/lib.cjs/noModal.js +44 -21
  14. package/dist/lib.cjs/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +9 -2
  15. package/dist/lib.cjs/react/context/useWeb3AuthInnerContextValue.js +10 -0
  16. package/dist/lib.cjs/react/solana/provider.js +65 -32
  17. package/dist/lib.cjs/types/base/connector/baseConnector.d.ts +2 -1
  18. package/dist/lib.cjs/types/base/connector/interfaces.d.ts +1 -0
  19. package/dist/lib.cjs/types/base/errors/index.d.ts +1 -0
  20. package/dist/lib.cjs/types/base/interfaces.d.ts +2 -1
  21. package/dist/lib.cjs/types/connectors/metamask-connector/metamaskConnector.d.ts +1 -0
  22. package/dist/lib.cjs/types/vue/solana/provider.d.ts +2 -2
  23. package/dist/lib.cjs/vue/solana/provider.js +55 -21
  24. package/dist/lib.cjs/vue/useWeb3AuthInnerContextValue.js +12 -2
  25. package/dist/lib.esm/base/connector/baseConnector.js +42 -11
  26. package/dist/lib.esm/base/errors/index.js +5 -1
  27. package/dist/lib.esm/base/utils.js +1 -1
  28. package/dist/lib.esm/connectors/auth-connector/authConnector.js +13 -5
  29. package/dist/lib.esm/connectors/coinbase-connector/coinbaseConnector.js +5 -5
  30. package/dist/lib.esm/connectors/injected-evm-connector/injectedEvmConnector.js +6 -5
  31. package/dist/lib.esm/connectors/injected-solana-connector/walletStandardConnector.js +6 -5
  32. package/dist/lib.esm/connectors/metamask-connector/metamaskConnector.js +86 -31
  33. package/dist/lib.esm/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +8 -7
  34. package/dist/lib.esm/index.js +1 -1
  35. package/dist/lib.esm/noModal.js +44 -21
  36. package/dist/lib.esm/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +9 -2
  37. package/dist/lib.esm/react/context/useWeb3AuthInnerContextValue.js +10 -0
  38. package/dist/lib.esm/react/solana/provider.js +64 -30
  39. package/dist/lib.esm/vue/solana/provider.js +55 -19
  40. package/dist/lib.esm/vue/useWeb3AuthInnerContextValue.js +10 -0
  41. package/package.json +2 -2
@@ -161,6 +161,14 @@ function useWeb3AuthInnerContextValue({
161
161
  chainId.value = web3Auth.value.currentChainId;
162
162
  chainNamespace.value = (_web3Auth$value$curre7 = (_web3Auth$value$curre8 = web3Auth.value.currentChain) === null || _web3Auth$value$curre8 === void 0 ? void 0 : _web3Auth$value$curre8.chainNamespace) !== null && _web3Auth$value$curre7 !== void 0 ? _web3Auth$value$curre7 : null;
163
163
  };
164
+ const connectorDataUpdatedListener = data => {
165
+ const updatedData = data.data;
166
+ if (updatedData.chainId && chainId.value !== updatedData.chainId) {
167
+ var _web3Auth$value$curre9;
168
+ chainId.value = updatedData.chainId;
169
+ chainNamespace.value = (_web3Auth$value$curre9 = web3Auth.value.currentChain) === null || _web3Auth$value$curre9 === void 0 ? void 0 : _web3Auth$value$curre9.chainNamespace;
170
+ }
171
+ };
164
172
  if (prevWeb3Auth && newWeb3Auth !== prevWeb3Auth) {
165
173
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.NOT_READY, notReadyListener);
166
174
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.READY, readyListener);
@@ -172,6 +180,7 @@ function useWeb3AuthInnerContextValue({
172
180
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.REHYDRATION_ERROR, errorListener);
173
181
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
174
182
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
183
+ prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorDataUpdatedListener);
175
184
  if (prevWeb3Auth.loginMode === constants$1.LOGIN_MODE.MODAL) {
176
185
  prevWeb3Auth.removeListener(constants.CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
177
186
  }
@@ -188,6 +197,7 @@ function useWeb3AuthInnerContextValue({
188
197
  newWeb3Auth.on(constants.CONNECTOR_EVENTS.REHYDRATION_ERROR, errorListener);
189
198
  newWeb3Auth.on(constants.CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
190
199
  newWeb3Auth.on(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
200
+ newWeb3Auth.on(constants.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorDataUpdatedListener);
191
201
  if (newWeb3Auth.loginMode === constants$1.LOGIN_MODE.MODAL) {
192
202
  newWeb3Auth.on(constants.CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
193
203
  }
@@ -198,9 +208,9 @@ function useWeb3AuthInnerContextValue({
198
208
  vue.watch(connection, (newConnection, prevConnection) => {
199
209
  var _prevConnection$ether, _newConnection$ethere;
200
210
  const handleChainChange = newChainId => {
201
- var _web3Auth$value$curre9, _web3Auth$value;
211
+ var _web3Auth$value$curre0, _web3Auth$value;
202
212
  chainId.value = newChainId;
203
- chainNamespace.value = (_web3Auth$value$curre9 = (_web3Auth$value = web3Auth.value) === null || _web3Auth$value === void 0 || (_web3Auth$value = _web3Auth$value.currentChain) === null || _web3Auth$value === void 0 ? void 0 : _web3Auth$value.chainNamespace) !== null && _web3Auth$value$curre9 !== void 0 ? _web3Auth$value$curre9 : null;
213
+ chainNamespace.value = (_web3Auth$value$curre0 = (_web3Auth$value = web3Auth.value) === null || _web3Auth$value === void 0 || (_web3Auth$value = _web3Auth$value.currentChain) === null || _web3Auth$value === void 0 ? void 0 : _web3Auth$value.chainNamespace) !== null && _web3Auth$value$curre0 !== void 0 ? _web3Auth$value$curre0 : null;
204
214
  };
205
215
  const prevProvider = (_prevConnection$ether = prevConnection === null || prevConnection === void 0 ? void 0 : prevConnection.ethereumProvider) !== null && _prevConnection$ether !== void 0 ? _prevConnection$ether : null;
206
216
  const newProvider = (_newConnection$ethere = newConnection === null || newConnection === void 0 ? void 0 : newConnection.ethereumProvider) !== null && _newConnection$ethere !== void 0 ? _newConnection$ethere : null;
@@ -130,17 +130,28 @@ class BaseConnector extends SafeEventEmitter {
130
130
  return cached;
131
131
  }
132
132
  async verifyAndAuthorize(params) {
133
- const tokens = await verifySignedChallenge({
134
- chainNamespace: params.chainNamespace,
135
- signedMessage: params.signedMessage,
136
- challenge: params.challenge,
137
- connector: this.name,
138
- authServer: params.authServer,
139
- web3AuthClientId: this.coreOptions.clientId,
140
- web3AuthNetwork: this.coreOptions.web3AuthNetwork,
141
- sessionTimeout: this.coreOptions.sessionTime,
142
- deviceInfo: getDeviceInfo()
143
- });
133
+ let tokens;
134
+ try {
135
+ tokens = await verifySignedChallenge({
136
+ chainNamespace: params.chainNamespace,
137
+ signedMessage: params.signedMessage,
138
+ challenge: params.challenge,
139
+ connector: this.name,
140
+ authServer: params.authServer,
141
+ web3AuthClientId: this.coreOptions.clientId,
142
+ web3AuthNetwork: this.coreOptions.web3AuthNetwork,
143
+ sessionTimeout: this.coreOptions.sessionTime,
144
+ deviceInfo: getDeviceInfo()
145
+ });
146
+ } catch (error) {
147
+ if (error instanceof Response && error.status === 401) {
148
+ const body = await error.clone().json().catch(() => ({}));
149
+ if (body.message === "ACCESS_CONTROL_DENIED") {
150
+ throw WalletLoginError.userBlocked("User is blocked by the application", error);
151
+ }
152
+ }
153
+ throw error;
154
+ }
144
155
  await this.saveAuthTokenInfo(tokens);
145
156
  const tokenInfo = {
146
157
  idToken: tokens.idToken,
@@ -154,6 +165,26 @@ class BaseConnector extends SafeEventEmitter {
154
165
  });
155
166
  return tokenInfo;
156
167
  }
168
+ async authorizeOrDisconnect(getAuthTokenInfo, chainId) {
169
+ if (!getAuthTokenInfo) return;
170
+ try {
171
+ await this.getAuthTokenInfo(chainId);
172
+ } catch (error) {
173
+ log.error("Authorization failed after connect; disconnecting wallet to keep state consistent", error);
174
+ const wasRehydrated = this.rehydrated;
175
+ try {
176
+ // getAuthTokenInfo moved status to AUTHORIZING; restore CONNECTED so disconnect requirements pass.
177
+ if (!this.connected) this.status = CONNECTOR_STATUS.CONNECTED;
178
+ await this.disconnect();
179
+ } catch (disconnectError) {
180
+ log.error("Failed to disconnect wallet after authorization error", disconnectError);
181
+ } finally {
182
+ // disconnect() resets rehydrated=false; restore so caller catch emits the right event.
183
+ this.rehydrated = wasRehydrated;
184
+ }
185
+ throw error;
186
+ }
187
+ }
157
188
  async clearWalletSession() {
158
189
  if (!this.authSessionManager) return;
159
190
  try {
@@ -163,6 +163,9 @@ class WalletLoginError extends Web3AuthError {
163
163
  static userNotLoggedIn(extraMessage = "", cause) {
164
164
  return WalletLoginError.fromCode(5119, extraMessage, cause);
165
165
  }
166
+ static userBlocked(extraMessage = "", cause) {
167
+ return WalletLoginError.fromCode(5120, extraMessage, cause);
168
+ }
166
169
  }
167
170
  _defineProperty(WalletLoginError, "messages", {
168
171
  5000: "Custom",
@@ -174,7 +177,8 @@ _defineProperty(WalletLoginError, "messages", {
174
177
  5116: "Chain config has not been added. Please add the chain config before calling switchChain",
175
178
  5117: "Unsupported operation",
176
179
  5118: "useSFAKey flag is enabled but SFA key is not available",
177
- 5119: "User not logged in."
180
+ 5119: "User not logged in.",
181
+ 5120: "User is blocked by the application"
178
182
  });
179
183
  class WalletOperationsError extends Web3AuthError {
180
184
  constructor(code, message, cause) {
@@ -149,7 +149,7 @@ const getWalletServicesAnalyticsProperties = walletServicesConfig => {
149
149
  ws_default_portfolio: walletServicesConfig === null || walletServicesConfig === void 0 || (_walletServicesConfig10 = walletServicesConfig.whiteLabel) === null || _walletServicesConfig10 === void 0 ? void 0 : _walletServicesConfig10.defaultPortfolio
150
150
  };
151
151
  };
152
- const sdkVersion = "11.1.0";
152
+ const sdkVersion = "11.2.0";
153
153
  const getErrorAnalyticsProperties = error => {
154
154
  try {
155
155
  const code = error instanceof Web3AuthError ? error.code : error === null || error === void 0 ? void 0 : error.code;
@@ -206,7 +206,8 @@ class AuthConnector extends BaseConnector {
206
206
  return {
207
207
  ethereumProvider: this.provider,
208
208
  solanaWallet: this._solanaWallet,
209
- connectorName: this.name
209
+ connectorName: this.name,
210
+ connectorNamespace: this.connectorNamespace
210
211
  };
211
212
  } catch (error) {
212
213
  var _message;
@@ -817,7 +818,7 @@ class AuthConnector extends BaseConnector {
817
818
  }
818
819
  throw WalletLoginError.sfaKeyNotFound("This typically occurs when the authentication method used does not provide SFA keys (e.g., default auth connection).");
819
820
  }
820
-
821
+ const connectorNamespace = this.connectorNamespace;
821
822
  // setup WS embed if chainNamespace is EIP155 or SOLANA
822
823
  if (chainNamespace === CHAIN_NAMESPACES.EIP155 || chainNamespace === CHAIN_NAMESPACES.SOLANA) {
823
824
  // wait for ws embed instance to be ready.
@@ -843,7 +844,8 @@ class AuthConnector extends BaseConnector {
843
844
  connectorName: WALLET_CONNECTORS.AUTH,
844
845
  reconnected: this.rehydrated,
845
846
  ethereumProvider: this.provider,
846
- solanaWallet: this._solanaWallet
847
+ solanaWallet: this._solanaWallet,
848
+ connectorNamespace
847
849
  });
848
850
  if (params.getAuthTokenInfo) {
849
851
  await this.getAuthTokenInfo();
@@ -860,7 +862,8 @@ class AuthConnector extends BaseConnector {
860
862
  connectorName: WALLET_CONNECTORS.AUTH,
861
863
  ethereumProvider: this.provider,
862
864
  solanaWallet: this._solanaWallet,
863
- reconnected: this.rehydrated
865
+ reconnected: this.rehydrated,
866
+ connectorNamespace
864
867
  });
865
868
  }
866
869
  }
@@ -963,7 +966,12 @@ class AuthConnector extends BaseConnector {
963
966
  if (error instanceof Web3AuthError) {
964
967
  throw error;
965
968
  }
966
- reject(WalletLoginError.connectionError(error instanceof Error ? error.message : error || "Failed to login with social"));
969
+ const errorMessage = error instanceof Error ? error.message : error;
970
+ if (errorMessage === "Access control denied") {
971
+ reject(WalletLoginError.userBlocked(errorMessage, error));
972
+ return;
973
+ }
974
+ reject(WalletLoginError.connectionError(errorMessage || "Failed to login with social"));
967
975
  });
968
976
  });
969
977
  }
@@ -99,15 +99,15 @@ class CoinbaseConnector extends BaseEvmConnector {
99
99
  connectorName: WALLET_CONNECTORS.COINBASE,
100
100
  reconnected: this.rehydrated,
101
101
  ethereumProvider: this.provider,
102
- solanaWallet: null
102
+ solanaWallet: null,
103
+ connectorNamespace: this.connectorNamespace
103
104
  });
104
- if (getAuthTokenInfo) {
105
- await this.getAuthTokenInfo();
106
- }
105
+ await this.authorizeOrDisconnect(getAuthTokenInfo);
107
106
  return {
108
107
  ethereumProvider: this.provider,
109
108
  solanaWallet: null,
110
- connectorName: this.name
109
+ connectorName: this.name,
110
+ connectorNamespace: this.connectorNamespace
111
111
  };
112
112
  } catch (error) {
113
113
  // ready again to be connected
@@ -89,19 +89,20 @@ class InjectedEvmConnector extends BaseEvmConnector {
89
89
  }
90
90
  };
91
91
  this.injectedProvider.on("accountsChanged", accountDisconnectHandler);
92
+ const connectorNamespace = this.connectorNamespace;
92
93
  this.emit(CONNECTOR_EVENTS.CONNECTED, {
93
94
  connectorName: this.name,
94
95
  reconnected: this.rehydrated,
95
96
  ethereumProvider: this.injectedProvider,
96
- solanaWallet: null
97
+ solanaWallet: null,
98
+ connectorNamespace
97
99
  });
98
- if (getAuthTokenInfo) {
99
- await this.getAuthTokenInfo();
100
- }
100
+ await this.authorizeOrDisconnect(getAuthTokenInfo);
101
101
  return {
102
102
  ethereumProvider: this.injectedProvider,
103
103
  solanaWallet: null,
104
- connectorName: this.name
104
+ connectorName: this.name,
105
+ connectorNamespace
105
106
  };
106
107
  } catch (error) {
107
108
  // ready again to be connected
@@ -76,19 +76,20 @@ class WalletStandardConnector extends BaseSolanaConnector {
76
76
  }
77
77
  if (this.wallet.accounts.length === 0) throw WalletLoginError.connectionError();
78
78
  this.status = CONNECTOR_STATUS.CONNECTED;
79
+ const connectorNamespace = this.connectorNamespace;
79
80
  this.emit(CONNECTOR_EVENTS.CONNECTED, {
80
81
  connectorName: this.name,
81
82
  reconnected: this.rehydrated,
82
83
  ethereumProvider: null,
83
- solanaWallet: this.solanaWallet
84
+ solanaWallet: this.solanaWallet,
85
+ connectorNamespace
84
86
  });
85
- if (getAuthTokenInfo) {
86
- await this.getAuthTokenInfo();
87
- }
87
+ await this.authorizeOrDisconnect(getAuthTokenInfo);
88
88
  return {
89
89
  ethereumProvider: null,
90
90
  solanaWallet: this.solanaWallet,
91
- connectorName: this.name
91
+ connectorName: this.name,
92
+ connectorNamespace
92
93
  };
93
94
  } catch (error) {
94
95
  // ready again to be connected
@@ -15,6 +15,7 @@ import { getCaipChainId, citadelServerUrl } from '../../base/utils.js';
15
15
  import { WalletLoginError, isUserRejectedError, WalletOperationsError, Web3AuthError } from '../../base/errors/index.js';
16
16
  import { ANALYTICS_EVENTS } from '../../base/analytics.js';
17
17
  import { getSolanaChainByChainConfig, walletSignMessage } from '../../base/wallet/solana.js';
18
+ import { log } from '../../base/loglevel.js';
18
19
  import { BaseConnector } from '../../base/connector/baseConnector.js';
19
20
  import { CONNECTOR_CATEGORY, CONNECTOR_STATUS, CONNECTOR_EVENTS } from '../../base/connector/constants.js';
20
21
 
@@ -22,6 +23,11 @@ import { CONNECTOR_CATEGORY, CONNECTOR_STATUS, CONNECTOR_EVENTS } from '../../ba
22
23
  * Configuration options for the MetaMask connector using \@metamask/connect-evm
23
24
  */
24
25
 
26
+ // `@metamask/connect-evm` announces its SDK-backed provider over EIP-6963 with this
27
+ // RDNS value. Web3Auth uses the dedicated `metaMaskConnector` for MetaMask, so MIPD
28
+ // discovery should ignore this provider to avoid treating the QR/deeplink transport
29
+ // as a native injected wallet.
30
+ const METAMASK_ERC_6963_PROVIDER_RDNS = "io.metamask.mmc";
25
31
  class MetaMaskConnector extends BaseConnector {
26
32
  constructor(connectorOptions) {
27
33
  super(connectorOptions);
@@ -197,13 +203,25 @@ class MetaMaskConnector extends BaseConnector {
197
203
  if (coreStatus === "connected" && options.autoConnect) {
198
204
  this.status = CONNECTOR_STATUS.CONNECTED;
199
205
  this.rehydrated = true;
206
+
207
+ // Force sync the chain state before connect with rehydrated state.
208
+ // during rehydration, `createEVMClient` (from above) cause re-creating session for connected the evm provider,
209
+ // triggering `switchChain` internally and unintentionally update the connector data with the new chain id.
210
+ // This creates issue in rehydration flow, where Web3Auth connects to the incorrect chain id, not the rehydrated chain id.
211
+ // Force sync the chain state with the rehydrated chain id to avoid this issue.
212
+ await this.forceSyncChainState(chainConfig);
200
213
  this.emit(CONNECTOR_EVENTS.CONNECTED, {
201
214
  connectorName: WALLET_CONNECTORS.METAMASK,
202
215
  reconnected: true,
203
216
  ethereumProvider: this.evmProvider,
204
- solanaWallet: this.solanaProvider
217
+ solanaWallet: this.solanaProvider,
218
+ connectorNamespace: this.connectorNamespace
205
219
  });
206
- if (options.getAuthTokenInfo) await this.getAuthTokenInfo(options.chainId);
220
+ try {
221
+ await this.authorizeOrDisconnect(options.getAuthTokenInfo, options.chainId);
222
+ } catch (error) {
223
+ this.emit(CONNECTOR_EVENTS.REHYDRATION_ERROR, error);
224
+ }
207
225
  } else if (coreStatus === "connected" || coreStatus === "loaded" || coreStatus === "disconnected" || coreStatus === "pending") {
208
226
  this.status = CONNECTOR_STATUS.READY;
209
227
  this.emit(CONNECTOR_EVENTS.READY, WALLET_CONNECTORS.METAMASK);
@@ -273,7 +291,7 @@ class MetaMaskConnector extends BaseConnector {
273
291
 
274
292
  // sync the chain state after connect
275
293
  // metamask might not be connected to the requested chain, so we need to sync the chain state to/from Web3Auth state after connect.
276
- await this.syncChainStateAfterConnect(chainConfig);
294
+ await this.forceSyncChainState(chainConfig);
277
295
 
278
296
  // check if connected
279
297
  if (this.multichainClient.status !== "connected") {
@@ -293,15 +311,15 @@ class MetaMaskConnector extends BaseConnector {
293
311
  connectorName: WALLET_CONNECTORS.METAMASK,
294
312
  reconnected: this.rehydrated,
295
313
  ethereumProvider: this.evmProvider,
296
- solanaWallet: this.solanaProvider
314
+ solanaWallet: this.solanaProvider,
315
+ connectorNamespace: this.connectorNamespace
297
316
  });
298
- if (getAuthTokenInfo) {
299
- await this.getAuthTokenInfo(chainId);
300
- }
317
+ await this.authorizeOrDisconnect(getAuthTokenInfo, chainId);
301
318
  return {
302
319
  ethereumProvider: this.evmProvider,
303
320
  solanaWallet: this.solanaProvider,
304
- connectorName: this.name
321
+ connectorName: this.name,
322
+ connectorNamespace: this.connectorNamespace
305
323
  };
306
324
  } catch (error) {
307
325
  // Ready again to be connected
@@ -327,10 +345,12 @@ class MetaMaskConnector extends BaseConnector {
327
345
  }) {
328
346
  if (!this.multichainClient) throw WalletLoginError.connectionError("Multichain client is not available");
329
347
  this.checkDisconnectionRequirements();
330
- await this.clearWalletSession();
348
+ await this.clearMultichainWalletSessions();
331
349
 
332
350
  // Disconnect using the multichain client
333
- await this.multichainClient.disconnect();
351
+ if (this.multichainClient.status === "connected") {
352
+ await this.multichainClient.disconnect();
353
+ }
334
354
  if (options.cleanup) {
335
355
  this.status = CONNECTOR_STATUS.NOT_READY;
336
356
  this.initializationPromise = null;
@@ -386,32 +406,41 @@ class MetaMaskConnector extends BaseConnector {
386
406
  }
387
407
  async switchChain(params, init = false) {
388
408
  super.checkSwitchChainRequirements(params, init);
409
+ await this.ensureInitialized();
389
410
  const targetChainConfig = this.coreOptions.chains.find(c => c.chainId === params.chainId);
390
- if ((targetChainConfig === null || targetChainConfig === void 0 ? void 0 : targetChainConfig.chainNamespace) === CHAIN_NAMESPACES.SOLANA) {
391
- // no need to switch chain for Solana
411
+ if (!targetChainConfig) throw WalletLoginError.connectionError("Chain config is not available");
412
+ if (targetChainConfig.chainNamespace === CHAIN_NAMESPACES.SOLANA) {
413
+ if (!this.solanaWallet) {
414
+ throw WalletLoginError.unsupportedOperation("switchChain requires a Solana client, but no Solana chains are configured.");
415
+ }
416
+
417
+ // For solana case, we don't have the `switchChain` method like `evmClient`.
418
+ // So, we just need to sync with the connected solana chain to the Web3Auth state.
419
+ await this.forceSyncChainState(targetChainConfig);
392
420
  return;
393
421
  }
394
- await this.ensureInitialized();
395
422
  if (!this.evmClient) {
396
423
  throw WalletLoginError.unsupportedOperation("switchChain requires an EVM client, but no EVM chains are configured.");
397
424
  }
398
- const chainConfig = this.coreOptions.chains.find(x => x.chainId === params.chainId && [CHAIN_NAMESPACES.EIP155].includes(x.chainNamespace));
399
- const chainConfiguration = chainConfig ? {
425
+ const chainConfiguration = targetChainConfig ? {
400
426
  chainId: params.chainId,
401
- chainName: chainConfig.displayName,
402
- rpcUrls: [chainConfig.rpcTarget],
403
- blockExplorerUrls: chainConfig.blockExplorerUrl ? [chainConfig.blockExplorerUrl] : undefined,
427
+ chainName: targetChainConfig.displayName,
428
+ rpcUrls: [targetChainConfig.rpcTarget],
429
+ blockExplorerUrls: targetChainConfig.blockExplorerUrl ? [targetChainConfig.blockExplorerUrl] : undefined,
404
430
  nativeCurrency: {
405
- name: chainConfig.tickerName,
406
- symbol: chainConfig.ticker,
407
- decimals: chainConfig.decimals || 18
431
+ name: targetChainConfig.tickerName,
432
+ symbol: targetChainConfig.ticker,
433
+ decimals: targetChainConfig.decimals || 18
408
434
  },
409
- iconUrls: chainConfig.logo ? [chainConfig.logo] : undefined
435
+ iconUrls: targetChainConfig.logo ? [targetChainConfig.logo] : undefined
410
436
  } : undefined;
411
437
  await this.evmClient.switchChain({
412
438
  chainId: params.chainId,
413
439
  chainConfiguration
414
440
  });
441
+ this.updateConnectorData({
442
+ chainId: params.chainId
443
+ });
415
444
  }
416
445
  async generateChallengeAndSign(authServerUrl, accounts, chainId) {
417
446
  const activeChainConfig = this.resolveAuthChainConfig(chainId);
@@ -470,7 +499,12 @@ class MetaMaskConnector extends BaseConnector {
470
499
  }
471
500
  await this.initializationPromise;
472
501
  }
473
- async syncChainStateAfterConnect(chainConfig) {
502
+
503
+ /**
504
+ * Syncs the chain state with the Web3Auth state.
505
+ * @param chainConfig - The chain config to sync.
506
+ */
507
+ async forceSyncChainState(chainConfig) {
474
508
  var _this$evmProvider2;
475
509
  // EVM connectors can switch chains, so align the wallet with the requested chain
476
510
  // before Web3Auth persists the active chain in controller state.
@@ -491,13 +525,9 @@ class MetaMaskConnector extends BaseConnector {
491
525
  if (!connectedChainConfig) {
492
526
  throw WalletLoginError.connectionError("Connected chain is not available in the chains config");
493
527
  }
494
- if (connectedChainConfig.chainId !== chainConfig.chainId) {
495
- // since, switchChain is not supported for solana (in metamask connect),
496
- // we will make use of the connector data to update the Web3Auth state.
497
- this.updateConnectorData({
498
- chainId: connectedChainConfig.chainId
499
- });
500
- }
528
+ this.updateConnectorData({
529
+ chainId: chainConfig.chainId
530
+ });
501
531
  }
502
532
  }
503
533
  }
@@ -512,6 +542,31 @@ class MetaMaskConnector extends BaseConnector {
512
542
  // Keep the old fallback for callers that do not pass a chainId yet.
513
543
  return isSolanaOnly ? this.coreOptions.chains.find(x => x.chainNamespace === CHAIN_NAMESPACES.SOLANA) : this.evmProvider ? this.coreOptions.chains.find(x => x.chainId === evmChainId) : undefined;
514
544
  }
545
+ async clearMultichainWalletSessions() {
546
+ const addresses = new Set();
547
+ if (this.evmProvider) {
548
+ const evmAccounts = await this.evmProvider.request({
549
+ method: EVM_METHOD_TYPES.GET_ACCOUNTS
550
+ });
551
+ evmAccounts.forEach(account => addresses.add(account));
552
+ }
553
+ if (this.solanaProvider) {
554
+ this.solanaProvider.accounts.forEach(account => addresses.add(account.address));
555
+ }
556
+ if (addresses.size === 0) {
557
+ await this.clearWalletSession();
558
+ return;
559
+ }
560
+
561
+ // MetaMask can authorize both EVM and Solana accounts in one session, but BaseConnector
562
+ // caches SIWW tokens under one address at a time. Clear every connected address on disconnect.
563
+ for (const address of addresses) {
564
+ this.initSessionManager(address);
565
+ await this.clearWalletSession().catch(error => {
566
+ log.error("Failed to clear multichain wallet session", error);
567
+ });
568
+ }
569
+ }
515
570
  }
516
571
 
517
572
  /**
@@ -541,4 +596,4 @@ const metaMaskConnector = params => {
541
596
  };
542
597
  };
543
598
 
544
- export { metaMaskConnector };
599
+ export { METAMASK_ERC_6963_PROVIDER_RDNS, metaMaskConnector };
@@ -169,7 +169,7 @@ class WalletConnectV2Connector extends BaseConnector {
169
169
  }));
170
170
  }
171
171
  };
172
-
172
+ const connectorNamespace = this.connectorNamespace;
173
173
  // if already connected
174
174
  if (this.connected) {
175
175
  await this.onConnectHandler({
@@ -179,7 +179,8 @@ class WalletConnectV2Connector extends BaseConnector {
179
179
  return {
180
180
  ethereumProvider: this.provider,
181
181
  solanaWallet: this._solanaWallet,
182
- connectorName: this.name
182
+ connectorName: this.name,
183
+ connectorNamespace
183
184
  };
184
185
  }
185
186
  if (this.status !== CONNECTOR_STATUS.CONNECTING) {
@@ -192,7 +193,8 @@ class WalletConnectV2Connector extends BaseConnector {
192
193
  return {
193
194
  ethereumProvider: this.provider,
194
195
  solanaWallet: this._solanaWallet,
195
- connectorName: this.name
196
+ connectorName: this.name,
197
+ connectorNamespace
196
198
  };
197
199
  } catch (error) {
198
200
  log.error("Wallet connect v2 connector error while connecting", error);
@@ -473,11 +475,10 @@ class WalletConnectV2Connector extends BaseConnector {
473
475
  connectorName: WALLET_CONNECTORS.WALLET_CONNECT_V2,
474
476
  reconnected: this.rehydrated,
475
477
  ethereumProvider: this.provider,
476
- solanaWallet: this._solanaWallet
478
+ solanaWallet: this._solanaWallet,
479
+ connectorNamespace: this.connectorNamespace
477
480
  });
478
- if (getAuthTokenInfo) {
479
- await this.getAuthTokenInfo();
480
- }
481
+ await this.authorizeOrDisconnect(getAuthTokenInfo);
481
482
  }
482
483
  subscribeEvents() {
483
484
  if (!this.connector) throw WalletInitializationError.notReady("Wallet connector is not ready yet");
@@ -19,6 +19,7 @@ export { DEFAULT_EIP155_METHODS, DEFAULT_EIP_155_EVENTS, DEFAULT_SOLANA_EVENTS,
19
19
  export { EIP1193_EVENTS } from './providers/base-provider/utils.js';
20
20
  export { EIP_7702_SUPPORTED_SMART_ACCOUNTS, LOGIN_MODE, MODAL_SIGN_IN_METHODS, SMART_ACCOUNT_WALLET_SCOPE, SOLANA_CAIP_CHAIN_MAP, WALLET_REGISTRY_URL, WEB3AUTH_STATE_STORAGE_KEY, WIDGET_TYPE } from './base/constants.js';
21
21
  export { EVM_PLUGINS, PLUGIN_EVENTS, PLUGIN_NAMESPACES, PLUGIN_STATUS, SOLANA_PLUGINS, WALLET_PLUGINS } from './base/plugin/IPlugin.js';
22
+ export { METAMASK_ERC_6963_PROVIDER_RDNS, metaMaskConnector } from './connectors/metamask-connector/metamaskConnector.js';
22
23
  export { PROVIDER_EVENTS } from './base/provider/IProvider.js';
23
24
  export { WalletConnectV2Provider } from './connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js';
24
25
  export { WalletInitializationError, WalletLoginError, WalletOperationsError, WalletProviderError, Web3AuthError, isUserRejectedError } from './base/errors/index.js';
@@ -39,7 +40,6 @@ export { hasSolanaWalletStandardFeatures } from './connectors/injected-solana-co
39
40
  export { injectedEvmConnector } from './connectors/injected-evm-connector/injectedEvmConnector.js';
40
41
  export { log } from './base/loglevel.js';
41
42
  export { makeAccountLinkingRequest, makeAccountUnlinkingRequest } from './account-linking/rest.js';
42
- export { metaMaskConnector } from './connectors/metamask-connector/metamaskConnector.js';
43
43
  export { walletConnectV2Connector } from './connectors/wallet-connect-v2-connector/walletConnectV2Connector.js';
44
44
  export { walletServicesPlugin } from './plugins/wallet-services-plugin/plugin.js';
45
45
  export { walletStandardConnector } from './connectors/injected-solana-connector/walletStandardConnector.js';