@web3auth/no-modal 11.0.2 → 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 (48) 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 +23 -16
  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/config.js +0 -3
  12. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/index.js +0 -1
  13. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +8 -6
  14. package/dist/lib.cjs/index.js +8 -8
  15. package/dist/lib.cjs/noModal.js +48 -22
  16. package/dist/lib.cjs/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +9 -2
  17. package/dist/lib.cjs/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +1 -43
  18. package/dist/lib.cjs/react/context/useWeb3AuthInnerContextValue.js +10 -0
  19. package/dist/lib.cjs/react/solana/provider.js +65 -32
  20. package/dist/lib.cjs/types/base/connector/baseConnector.d.ts +2 -1
  21. package/dist/lib.cjs/types/base/connector/interfaces.d.ts +1 -0
  22. package/dist/lib.cjs/types/base/errors/index.d.ts +1 -0
  23. package/dist/lib.cjs/types/base/interfaces.d.ts +2 -1
  24. package/dist/lib.cjs/types/connectors/metamask-connector/metamaskConnector.d.ts +1 -0
  25. package/dist/lib.cjs/types/connectors/wallet-connect-v2-connector/config.d.ts +0 -1
  26. package/dist/lib.cjs/types/vue/solana/provider.d.ts +2 -2
  27. package/dist/lib.cjs/vue/solana/provider.js +55 -21
  28. package/dist/lib.cjs/vue/useWeb3AuthInnerContextValue.js +12 -2
  29. package/dist/lib.esm/base/connector/baseConnector.js +42 -11
  30. package/dist/lib.esm/base/errors/index.js +5 -1
  31. package/dist/lib.esm/base/utils.js +1 -1
  32. package/dist/lib.esm/connectors/auth-connector/authConnector.js +21 -15
  33. package/dist/lib.esm/connectors/coinbase-connector/coinbaseConnector.js +5 -5
  34. package/dist/lib.esm/connectors/injected-evm-connector/injectedEvmConnector.js +6 -5
  35. package/dist/lib.esm/connectors/injected-solana-connector/walletStandardConnector.js +6 -5
  36. package/dist/lib.esm/connectors/metamask-connector/metamaskConnector.js +86 -31
  37. package/dist/lib.esm/connectors/wallet-connect-v2-connector/config.js +1 -4
  38. package/dist/lib.esm/connectors/wallet-connect-v2-connector/index.js +1 -1
  39. package/dist/lib.esm/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +8 -7
  40. package/dist/lib.esm/index.js +2 -2
  41. package/dist/lib.esm/noModal.js +48 -22
  42. package/dist/lib.esm/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +9 -2
  43. package/dist/lib.esm/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +1 -9
  44. package/dist/lib.esm/react/context/useWeb3AuthInnerContextValue.js +10 -0
  45. package/dist/lib.esm/react/solana/provider.js +64 -30
  46. package/dist/lib.esm/vue/solana/provider.js +55 -19
  47. package/dist/lib.esm/vue/useWeb3AuthInnerContextValue.js +10 -0
  48. package/package.json +7 -7
@@ -7,6 +7,8 @@ var baseControllers = require('@toruslabs/base-controllers');
7
7
  var ethereumControllers = require('@toruslabs/ethereum-controllers');
8
8
  var auth = require('@web3auth/auth');
9
9
  var deepmerge = require('deepmerge');
10
+ var errors = require('./account-linking/errors.js');
11
+ require('@toruslabs/http-helpers');
10
12
  var analytics = require('./base/analytics.js');
11
13
  var IChainInterface = require('./base/chain/IChainInterface.js');
12
14
  require('@toruslabs/session-manager');
@@ -27,7 +29,6 @@ var plugin = require('./plugins/wallet-services-plugin/plugin.js');
27
29
  require('./providers/base-provider/utils.js');
28
30
  var CommonJRPCProvider = require('./providers/base-provider/CommonJRPCProvider.js');
29
31
  require('./providers/base-provider/commonPrivateKeyProvider.js');
30
- var errors = require('./account-linking/errors.js');
31
32
 
32
33
  const _excluded = ["walletScope", "eipStandard"];
33
34
  const PRIMARY_CONNECTED_WALLET_KEY = "__primary__";
@@ -56,7 +57,8 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
56
57
  idToken: null,
57
58
  accessToken: null,
58
59
  refreshToken: null,
59
- activeAccount: null
60
+ activeAccount: null,
61
+ cachedConnectorNamespace: null
60
62
  });
61
63
  if (!options.clientId) throw index.WalletInitializationError.invalidParams("Please provide a valid clientId in constructor");
62
64
  if (options.enableLogging) loglevel.log.enableAll();else loglevel.log.setLevel("error");
@@ -248,6 +250,7 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
248
250
  await this.setState({
249
251
  primaryConnectorName: null,
250
252
  cachedConnector: null,
253
+ cachedConnectorNamespace: null,
251
254
  currentChainId: null,
252
255
  idToken: null,
253
256
  accessToken: null,
@@ -258,7 +261,10 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
258
261
  }
259
262
  async cleanup() {
260
263
  for (const connector of this.connectors) {
261
- if (connector.cleanup) await connector.cleanup();
264
+ // if the connector is not ready, we don't need to cleanup
265
+ // this means that we load the connector (coz of the dashboard config) but the clients did not use it (i.e. with `showOnModal` set to false)
266
+ // example use case: external wallet **ONLY** login mode but the ClientID has enabled Auth connection in dashboard.
267
+ if (connector.cleanup && connector.status !== constants.CONNECTOR_STATUS.NOT_READY) await connector.cleanup();
262
268
  }
263
269
  }
264
270
  async switchChain(params) {
@@ -780,7 +786,9 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
780
786
  chains: this.coreOptions.chains
781
787
  });
782
788
  // sync chainId
783
- this.commonJRPCProvider.on("chainChanged", async chainId => this.setCurrentChain(chainId));
789
+ this.commonJRPCProvider.on("chainChanged", async chainId => {
790
+ await this.setCurrentChain(chainId);
791
+ });
784
792
  }
785
793
  async setupConnector(connector) {
786
794
  this.subscribeToConnectorEvents(connector);
@@ -844,12 +852,19 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
844
852
  injectedEvmConnector
845
853
  } = await Promise.resolve().then(function () { return require('./connectors/injected-evm-connector/index.js'); });
846
854
  const evmMipd = createMipd();
855
+ // `@metamask/connect-evm` SDK announces its own EIP-6963 provider (`io.metamask.mmc`) so
856
+ // it can be discovered by generic wallet pickers. We already register MetaMask via
857
+ // `metaMaskConnector`, so we must exclude the SDK-announced provider here; otherwise
858
+ // it is misclassified as an injected wallet and the modal shows MetaMask as installed,
859
+ // even when the user does not have the extension installed.
860
+ const isNonSdkAnnouncedProvider = providerDetail => providerDetail.info.rdns !== metamaskConnector.METAMASK_ERC_6963_PROVIDER_RDNS;
847
861
  // subscribe to new injected connectors
848
862
  evmMipd.subscribe(providerDetails => {
849
- const newConnectors = providerDetails.map(providerDetail => injectedEvmConnector(providerDetail)(config));
863
+ const filteredProviderDetails = providerDetails.filter(isNonSdkAnnouncedProvider);
864
+ const newConnectors = filteredProviderDetails.map(providerDetail => injectedEvmConnector(providerDetail)(config));
850
865
  this.setConnectors(newConnectors);
851
866
  });
852
- connectorFns.push(...evmMipd.getProviders().map(injectedEvmConnector));
867
+ connectorFns.push(...evmMipd.getProviders().filter(isNonSdkAnnouncedProvider).map(injectedEvmConnector));
853
868
  }
854
869
  }
855
870
  // add WalletConnectV2 connector if external wallets are enabled
@@ -981,7 +996,7 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
981
996
  await this.setState({
982
997
  primaryConnectorName: data.connectorName
983
998
  });
984
- this.cacheWallet(data.connectorName);
999
+ this.cacheWallet(data.connectorName, data.connectorNamespace);
985
1000
  const isConnectAndSign = this.coreOptions.initialAuthenticationMode === constants.CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
986
1001
  const pendingUserConsent = this.consentRequired && !this.state.hasUserConsent;
987
1002
  if (pendingUserConsent && !isConnectAndSign) {
@@ -996,7 +1011,6 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
996
1011
  if (this.status !== constants.CONNECTOR_STATUS.CONSENT_REQUIRING && this.status !== constants.CONNECTOR_STATUS.AUTHORIZED) {
997
1012
  this.status = constants.CONNECTOR_STATUS.CONNECTED;
998
1013
  }
999
- loglevel.log.debug("connected", this.status, this.primaryConnectorName);
1000
1014
  // Defer plugin connection until consent is accepted; otherwise plugins would start before the consent step completes.
1001
1015
  // `completeConsentAcceptance` connects the plugins once the user accepts the consent.
1002
1016
  if (!pendingUserConsent) {
@@ -1111,7 +1125,14 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1111
1125
  // External wallets can resolve to a different active chain than the requested one,
1112
1126
  // so let connector-reported chain updates reconcile Web3Auth state after connect.
1113
1127
  if (typeof (data === null || data === void 0 ? void 0 : data.data) === "object" && (data === null || data === void 0 ? void 0 : data.data) !== null && "chainId" in data.data && typeof data.data.chainId === "string") {
1128
+ const previousChain = this.currentChain;
1114
1129
  await this.setCurrentChain(data.data.chainId);
1130
+ const currentChain = this.currentChain;
1131
+ const connectorEthereumProvider = connector.provider;
1132
+ if ((previousChain === null || previousChain === void 0 ? void 0 : previousChain.chainNamespace) !== (currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) && (currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === baseControllers.CHAIN_NAMESPACES.EIP155 && connectorEthereumProvider) {
1133
+ // from sol -> evm namespace switch, we need to re-create AccountAbstractionProvider
1134
+ await this.bindPrimaryEthereumSigningProxy(connectorEthereumProvider, connector.name);
1135
+ }
1115
1136
  }
1116
1137
  loglevel.log.debug("connector data updated", data);
1117
1138
  this.emit(constants.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, data);
@@ -1165,7 +1186,7 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1165
1186
  }
1166
1187
  checkIfAutoConnect(connector) {
1167
1188
  var _this$currentChain3;
1168
- let autoConnect = this.cachedConnector === connector.name;
1189
+ let autoConnect = this.cachedConnector === connector.name && this.state.cachedConnectorNamespace === connector.connectorNamespace;
1169
1190
  if (autoConnect && (_this$currentChain3 = this.currentChain) !== null && _this$currentChain3 !== void 0 && _this$currentChain3.chainNamespace) {
1170
1191
  if (connector.connectorNamespace === IChainInterface.CONNECTOR_NAMESPACES.MULTICHAIN) autoConnect = true;else autoConnect = connector.connectorNamespace === this.currentChain.chainNamespace;
1171
1192
  }
@@ -1178,10 +1199,15 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1178
1199
  getInitialChainIdForConnector(connector) {
1179
1200
  var _initialChain;
1180
1201
  let initialChain = this.currentChain;
1181
- if (((_initialChain = initialChain) === null || _initialChain === void 0 ? void 0 : _initialChain.chainNamespace) !== connector.connectorNamespace && connector.connectorNamespace !== IChainInterface.CONNECTOR_NAMESPACES.MULTICHAIN) {
1202
+ const defaultChainId = this.coreOptions.defaultChainId;
1203
+ const isMultiChainConnector = connector.connectorNamespace === IChainInterface.CONNECTOR_NAMESPACES.MULTICHAIN;
1204
+ // if the connector is a multi-chain connector and a default chain id is set, use the default chain id
1205
+ if (isMultiChainConnector && defaultChainId) {
1206
+ initialChain = this.coreOptions.chains.find(chain => chain.chainId === defaultChainId) || this.currentChain;
1207
+ } else if (((_initialChain = initialChain) === null || _initialChain === void 0 ? void 0 : _initialChain.chainNamespace) !== connector.connectorNamespace && connector.connectorNamespace !== IChainInterface.CONNECTOR_NAMESPACES.MULTICHAIN) {
1182
1208
  initialChain = this.coreOptions.chains.find(x => x.chainNamespace === connector.connectorNamespace);
1183
- if (!initialChain) throw index.WalletInitializationError.invalidParams(`No chain found for ${connector.connectorNamespace}`);
1184
1209
  }
1210
+ if (!initialChain) throw index.WalletInitializationError.invalidParams(`No chain found for ${connector.connectorNamespace}`);
1185
1211
  return initialChain;
1186
1212
  }
1187
1213
  async completeConsentAcceptance() {
@@ -1365,7 +1391,8 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1365
1391
  return {
1366
1392
  ethereumProvider: connectedWallet.signingProvider,
1367
1393
  solanaWallet: (_connectedWallet$sola = connectedWallet.solanaWallet) !== null && _connectedWallet$sola !== void 0 ? _connectedWallet$sola : null,
1368
- connectorName: connectedWallet.connector.name
1394
+ connectorName: connectedWallet.connector.name,
1395
+ connectorNamespace: connectedWallet.connector.connectorNamespace
1369
1396
  };
1370
1397
  }
1371
1398
  buildImmediateConnectedWalletConnectorState(params) {
@@ -1502,11 +1529,7 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1502
1529
  if (!connection) {
1503
1530
  throw index.WalletLoginError.connectionError("Failed to resolve the active connection after switching accounts.");
1504
1531
  }
1505
- this.emit(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, {
1506
- ethereumProvider: connection.ethereumProvider,
1507
- solanaWallet: connection.solanaWallet,
1508
- connectorName: connection.connectorName
1509
- });
1532
+ this.emit(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, connection);
1510
1533
  }
1511
1534
  isActiveConnectorEventSource(connector) {
1512
1535
  if (!this.primaryConnectorName) return true;
@@ -1589,9 +1612,10 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1589
1612
  loglevel.log.debug("Failed to cache connected linked wallet connector", error);
1590
1613
  }
1591
1614
  }
1592
- async cacheWallet(walletName) {
1615
+ async cacheWallet(walletName, connectorNamespace) {
1593
1616
  await this.setState({
1594
- cachedConnector: walletName
1617
+ cachedConnector: walletName,
1618
+ cachedConnectorNamespace: connectorNamespace
1595
1619
  });
1596
1620
  }
1597
1621
  async setCurrentChain(chainId) {
@@ -1627,9 +1651,11 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1627
1651
  });
1628
1652
  }
1629
1653
  async bindPrimaryEthereumSigningProxy(ethereumProvider, connectorName) {
1630
- var _this$currentChain5, _accountAbstractionCo;
1654
+ var _this$primaryConnecto2, _this$currentChain5, _accountAbstractionCo;
1631
1655
  if (!this.commonJRPCProvider) throw index.WalletInitializationError.notFound(`CommonJrpcProvider not found`);
1632
- let finalProvider = (ethereumProvider === null || ethereumProvider === void 0 ? void 0 : ethereumProvider.provider) || ethereumProvider;
1656
+ const primaryConnectorProvider = connectorName === this.primaryConnectorName ? (_this$primaryConnecto2 = this.primaryConnector) === null || _this$primaryConnecto2 === void 0 ? void 0 : _this$primaryConnecto2.provider : null;
1657
+ const baseEthereumProvider = ethereumProvider === this.commonJRPCProvider || ethereumProvider === this.aaProvider ? primaryConnectorProvider !== null && primaryConnectorProvider !== void 0 ? primaryConnectorProvider : ethereumProvider : ethereumProvider;
1658
+ let finalProvider = (baseEthereumProvider === null || baseEthereumProvider === void 0 ? void 0 : baseEthereumProvider.provider) || baseEthereumProvider;
1633
1659
  const {
1634
1660
  accountAbstractionConfig
1635
1661
  } = this.coreOptions;
@@ -1645,7 +1671,7 @@ class Web3AuthNoModal extends auth.SafeEventEmitter {
1645
1671
  accountAbstractionProvider,
1646
1672
  toEoaProvider
1647
1673
  } = await Promise.resolve().then(function () { return require('./providers/account-abstraction-provider/index.js'); });
1648
- const eoaProvider = connectorName === index$1.WALLET_CONNECTORS.AUTH ? await toEoaProvider(ethereumProvider) : ethereumProvider;
1674
+ const eoaProvider = connectorName === index$1.WALLET_CONNECTORS.AUTH ? await toEoaProvider(baseEthereumProvider) : baseEthereumProvider;
1649
1675
  const aaChainIds = new Set((accountAbstractionConfig === null || accountAbstractionConfig === void 0 || (_accountAbstractionCo2 = accountAbstractionConfig.chains) === null || _accountAbstractionCo2 === void 0 ? void 0 : _accountAbstractionCo2.map(chain => chain.chainId)) || []);
1650
1676
  const aaProvider = await accountAbstractionProvider({
1651
1677
  accountAbstractionConfig,
@@ -70,7 +70,7 @@ class AccountAbstractionProvider extends baseProvider.BaseProvider {
70
70
  });
71
71
  }
72
72
  async setupProvider(eoaProvider) {
73
- var _bundlerConfig$transp;
73
+ var _await$eoaProvider$re, _bundlerConfig$transp;
74
74
  const currentChain = this.currentChain;
75
75
  if (!currentChain) {
76
76
  throw index.WalletInitializationError.invalidProviderConfigError(`AA chain config not found for chain ${this.chainId}`);
@@ -113,7 +113,14 @@ class AccountAbstractionProvider extends baseProvider.BaseProvider {
113
113
  chain,
114
114
  transport: viem.http(currentChain.rpcTarget)
115
115
  });
116
- const [eoaAddress] = await eoaProvider.request({
116
+ // Firstly, try to get the accounts from the existing connected provider with `eth_accounts` method.
117
+ // We don't wanna do `eth_requestAccounts` method here, coz if the wallet is already connected, it will trigger chainChanged event and unintentionally update the AaProvider re-bind and
118
+ // re-bind run this again, so we will end up in infinite loop.
119
+ const existingAccounts = (_await$eoaProvider$re = await eoaProvider.request({
120
+ method: ethereumControllers.METHOD_TYPES.GET_ACCOUNTS
121
+ })) !== null && _await$eoaProvider$re !== void 0 ? _await$eoaProvider$re : [];
122
+ // only if the existing accounts are not found (that means wallet isn't connected), then we will trigger `eth_requestAccounts` method to get the accounts.
123
+ const [eoaAddress] = existingAccounts.length > 0 ? existingAccounts : await eoaProvider.request({
117
124
  method: ethereumControllers.METHOD_TYPES.ETH_REQUEST_ACCOUNTS
118
125
  });
119
126
  const walletClient = viem.createWalletClient({
@@ -3,41 +3,6 @@
3
3
  var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
4
4
  var ethereumControllers = require('@toruslabs/ethereum-controllers');
5
5
  var auth = require('@web3auth/auth');
6
- require('@babel/runtime/helpers/defineProperty');
7
- require('@toruslabs/base-controllers');
8
- require('@toruslabs/constants');
9
- require('@toruslabs/http-helpers');
10
- require('@toruslabs/secure-pub-sub');
11
- require('@web3auth/ws-embed');
12
- require('deepmerge');
13
- require('@segment/analytics-next');
14
- require('../../../base/loglevel.js');
15
- require('@toruslabs/session-manager');
16
- require('../../../base/errors/index.js');
17
- require('../../../base/constants.js');
18
- require('../../../base/wallet/index.js');
19
- require('../../../base/connector/connectorStatus.js');
20
- require('../../../base/connector/constants.js');
21
- require('jwt-decode');
22
- require('../../../base/plugin/errors.js');
23
- require('../../../base/plugin/IPlugin.js');
24
- require('@toruslabs/eccrypto');
25
- require('@toruslabs/metadata-helpers');
26
- require('../../../connectors/auth-connector/authSolanaWallet.js');
27
- require('viem');
28
- require('viem/siwe');
29
- require('mipd');
30
- require('@solana/wallet-standard-features');
31
- require('@wallet-standard/app');
32
- require('@wallet-standard/features');
33
- require('@metamask/connect-evm');
34
- require('@metamask/connect-multichain');
35
- require('@metamask/connect-solana');
36
- var config = require('../../../connectors/wallet-connect-v2-connector/config.js');
37
- require('@walletconnect/sign-client');
38
- require('@walletconnect/utils');
39
- require('../../../connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js');
40
- require('../../../connectors/wallet-connect-v2-connector/wcSolanaWallet.js');
41
6
 
42
7
  async function createAaMiddleware({
43
8
  eoaProvider,
@@ -234,17 +199,10 @@ function providerAsMiddleware(provider) {
234
199
  return async ({
235
200
  request
236
201
  }) => {
237
- const result = await provider.request({
202
+ return provider.request({
238
203
  method: request.method,
239
204
  params: request.params
240
205
  });
241
- if (result === undefined && config.NULL_ON_SUCCESS_METHODS.includes(request.method)) {
242
- // For some RPC requests, such as `wallet_switchEthereumChain`, the standard rpc result is `null`.
243
- // However, some wallet providers might return `undefined` instead and causing the JRPCEngineV2 to throw `Nothing ended the request` error.
244
- // So, we handle this case by returning `null` instead, so that JRPCEngineV2 won't throw `Nothing ended the request` error
245
- return null;
246
- }
247
- return result;
248
206
  };
249
207
  }
250
208
 
@@ -175,6 +175,14 @@ function useWeb3AuthInnerContextValue({
175
175
  setChainId(web3Auth.currentChainId);
176
176
  setChainNamespace((_web3Auth$currentChai1 = (_web3Auth$currentChai10 = web3Auth.currentChain) === null || _web3Auth$currentChai10 === void 0 ? void 0 : _web3Auth$currentChai10.chainNamespace) !== null && _web3Auth$currentChai1 !== void 0 ? _web3Auth$currentChai1 : null);
177
177
  };
178
+ const connectorDataUpdatedListener = data => {
179
+ const updatedData = data.data;
180
+ if (updatedData.chainId) {
181
+ var _web3Auth$currentChai11;
182
+ setChainId(updatedData.chainId);
183
+ setChainNamespace((_web3Auth$currentChai11 = web3Auth.currentChain) === null || _web3Auth$currentChai11 === void 0 ? void 0 : _web3Auth$currentChai11.chainNamespace);
184
+ }
185
+ };
178
186
  if (web3Auth) {
179
187
  web3Auth.on(constants.CONNECTOR_EVENTS.NOT_READY, notReadyListener);
180
188
  web3Auth.on(constants.CONNECTOR_EVENTS.READY, readyListener);
@@ -186,6 +194,7 @@ function useWeb3AuthInnerContextValue({
186
194
  web3Auth.on(constants.CONNECTOR_EVENTS.REHYDRATION_ERROR, rehydrationErrorListener);
187
195
  web3Auth.on(constants.CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
188
196
  web3Auth.on(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
197
+ web3Auth.on(constants.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorDataUpdatedListener);
189
198
  if (web3Auth.loginMode === constants$1.LOGIN_MODE.MODAL) {
190
199
  web3Auth.on(constants.CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
191
200
  }
@@ -202,6 +211,7 @@ function useWeb3AuthInnerContextValue({
202
211
  web3Auth.removeListener(constants.CONNECTOR_EVENTS.MFA_ENABLED, mfaEnabledListener);
203
212
  web3Auth.removeListener(constants.CONNECTOR_EVENTS.AUTHORIZED, authorizedListener);
204
213
  web3Auth.removeListener(constants.CONNECTOR_EVENTS.CONNECTION_UPDATED, connectionUpdatedListener);
214
+ web3Auth.removeListener(constants.CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, connectorDataUpdatedListener);
205
215
  if (web3Auth.loginMode === constants$1.LOGIN_MODE.MODAL) {
206
216
  web3Auth.removeListener(constants.CONNECTOR_EVENTS.CONSENT_ACCEPTED, consentAcceptedListener);
207
217
  }
@@ -12,13 +12,12 @@ var baseControllers = require('@toruslabs/base-controllers');
12
12
  require('@toruslabs/session-manager');
13
13
  require('@web3auth/auth');
14
14
  require('../../base/errors/index.js');
15
- require('@toruslabs/constants');
16
- require('@toruslabs/http-helpers');
17
- require('../../base/constants.js');
15
+ var utils = require('../../base/utils.js');
18
16
  require('../../base/wallet/index.js');
19
17
  require('../../base/connector/connectorStatus.js');
20
18
  require('../../base/connector/constants.js');
21
19
  require('jwt-decode');
20
+ require('../../base/constants.js');
22
21
  require('../../base/plugin/errors.js');
23
22
  require('../../base/plugin/IPlugin.js');
24
23
  require('../context/Web3AuthInnerContext.js');
@@ -54,12 +53,28 @@ function makePlaceholder(rpc) {
54
53
  });
55
54
  }
56
55
  function dispose(client) {
57
- void client.actions.disconnectWallet().catch(() => {});
58
56
  client.destroy();
59
57
  }
58
+ function resolveSolanaChain(web3Auth, connection) {
59
+ var _web3Auth$coreOptions3;
60
+ const currentChain = web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.currentChain;
61
+ if ((currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA) {
62
+ return currentChain;
63
+ }
64
+ const connectedScope = connection !== null && connection !== void 0 && connection.solanaWallet && "scope" in connection.solanaWallet && typeof connection.solanaWallet.scope === "string" ? connection.solanaWallet.scope : null;
65
+ if (connectedScope) {
66
+ var _web3Auth$coreOptions2;
67
+ const connectedChain = web3Auth === null || web3Auth === void 0 || (_web3Auth$coreOptions2 = web3Auth.coreOptions.chains) === null || _web3Auth$coreOptions2 === void 0 ? void 0 : _web3Auth$coreOptions2.find(chain => {
68
+ return chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA && utils.getCaipChainId(chain) === connectedScope;
69
+ });
70
+ if (connectedChain) return connectedChain;
71
+ }
72
+ return (web3Auth === null || web3Auth === void 0 || (_web3Auth$coreOptions3 = web3Auth.coreOptions.chains) === null || _web3Auth$coreOptions3 === void 0 ? void 0 : _web3Auth$coreOptions3.find(chain => chain.chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA)) || null;
73
+ }
60
74
  /**
61
- * Builds the SolanaClient for Framework Kit React hooks: placeholder when idle, Web3Auth-backed when
62
- * connected on Solana. Ref + state so React re-renders on swap and effects dispose the right instance.
75
+ * Builds the SolanaClient for Framework Kit React hooks.
76
+ * For multichain wallets, keep the Solana client warm across namespace switches so
77
+ * switching back to Solana can reuse the existing wallet session.
63
78
  */
64
79
  function useFrameworkKitSolanaClient() {
65
80
  const {
@@ -72,12 +87,13 @@ function useFrameworkKitSolanaClient() {
72
87
  chainId,
73
88
  chainNamespace
74
89
  } = useChain.useChain();
75
- const ref = react.useRef(null);
90
+ const solClientRef = react.useRef(null);
91
+ const connectedClientRef = react.useRef(null);
76
92
  const [client$1, setClient] = react.useState(() => {
77
93
  const c = makePlaceholder({
78
94
  rpcTarget: DEVNET_ENDPOINT
79
95
  });
80
- ref.current = c;
96
+ solClientRef.current = c;
81
97
  return c;
82
98
  });
83
99
  react.useEffect(() => {
@@ -86,53 +102,61 @@ function useFrameworkKitSolanaClient() {
86
102
  });
87
103
  }, [isInitialized, web3Auth]);
88
104
  react.useEffect(() => () => {
89
- const c = ref.current;
90
- if (c) {
91
- dispose(c);
92
- ref.current = null;
105
+ const connectedClient = connectedClientRef.current;
106
+ const currentClient = solClientRef.current;
107
+ if (currentClient) {
108
+ dispose(currentClient);
109
+ solClientRef.current = null;
110
+ }
111
+ if (connectedClient && connectedClient !== currentClient) {
112
+ dispose(connectedClient);
93
113
  }
114
+ connectedClientRef.current = null;
94
115
  }, []);
95
116
  react.useEffect(() => {
96
117
  let stale = false;
97
- const adopt = next => {
118
+ const adopt = nextClient => {
98
119
  if (stale) {
99
- dispose(next);
120
+ dispose(nextClient);
100
121
  return;
101
122
  }
102
- const prev = ref.current;
103
- if (prev === next) return;
104
- if (prev) dispose(prev);
105
- ref.current = next;
106
- setClient(next);
123
+ const prevClient = solClientRef.current;
124
+ if (prevClient === nextClient) return;
125
+ if (prevClient) dispose(prevClient);
126
+ solClientRef.current = nextClient;
127
+ setClient(nextClient);
107
128
  };
108
- (async _web3Auth$currentChai => {
129
+ (async () => {
109
130
  const rpc = placeholderRpc(isInitialized, web3Auth);
110
- const solanaWallet = connection === null || connection === void 0 ? void 0 : connection.solanaWallet;
111
- const onSolana = isConnected && Boolean(solanaWallet) && chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA && (web3Auth === null || web3Auth === void 0 || (_web3Auth$currentChai = web3Auth.currentChain) === null || _web3Auth$currentChai === void 0 ? void 0 : _web3Auth$currentChai.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA;
112
- if (!onSolana) {
113
- adopt(makePlaceholder(rpc));
114
- return;
115
- }
116
131
  const conn = connection;
117
- if (!conn || !solanaWallet) {
132
+ const currentChain = web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.currentChain;
133
+ if ((currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) !== baseControllers.CHAIN_NAMESPACES.SOLANA) {
118
134
  adopt(makePlaceholder(rpc));
119
135
  return;
120
136
  }
121
- // only reconnect for the primary connector
122
- if (conn.connectorName !== (web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.primaryConnectorName)) {
137
+ const preferredSolanaChain = resolveSolanaChain(web3Auth, conn);
138
+ const shouldKeepSolanaClient = isConnected && Boolean(conn === null || conn === void 0 ? void 0 : conn.solanaWallet) && Boolean(preferredSolanaChain) &&
139
+ // only manage the client for the primary connector
140
+ (conn === null || conn === void 0 ? void 0 : conn.connectorName) === (web3Auth === null || web3Auth === void 0 ? void 0 : web3Auth.primaryConnectorName);
141
+ if (!shouldKeepSolanaClient) {
142
+ const connectedClient = connectedClientRef.current;
143
+ connectedClientRef.current = null;
144
+ if (connectedClient) {
145
+ dispose(connectedClient);
146
+ }
123
147
  adopt(makePlaceholder(rpc));
124
148
  return;
125
149
  }
126
150
  try {
127
151
  const solanaWalletId = "wallet-standard:" + conn.connectorName;
128
- const connector = client.createWalletStandardConnector(solanaWallet, {
152
+ const connector = client.createWalletStandardConnector(conn.solanaWallet, {
129
153
  id: solanaWalletId,
130
154
  name: conn.connectorName
131
155
  });
132
156
  const {
133
157
  rpcTarget,
134
158
  wsTarget
135
- } = web3Auth.currentChain;
159
+ } = preferredSolanaChain;
136
160
  const wired = client.createClient({
137
161
  endpoint: rpcTarget,
138
162
  websocketEndpoint: wsTarget,
@@ -145,7 +169,16 @@ function useFrameworkKitSolanaClient() {
145
169
  dispose(wired);
146
170
  return;
147
171
  }
148
- adopt(wired);
172
+ const prevConnectedClient = connectedClientRef.current;
173
+ connectedClientRef.current = wired;
174
+ if (chainNamespace === baseControllers.CHAIN_NAMESPACES.SOLANA && (currentChain === null || currentChain === void 0 ? void 0 : currentChain.chainNamespace) === baseControllers.CHAIN_NAMESPACES.SOLANA) {
175
+ adopt(wired);
176
+ } else {
177
+ adopt(makePlaceholder(rpc));
178
+ }
179
+ if (prevConnectedClient && prevConnectedClient !== wired) {
180
+ dispose(prevConnectedClient);
181
+ }
149
182
  } catch (e) {
150
183
  loglevel.log.error("Failed to create or connect Solana client", e);
151
184
  adopt(makePlaceholder(rpc));
@@ -40,6 +40,7 @@ export declare abstract class BaseConnector<T> extends SafeEventEmitter<Connecto
40
40
  challenge: string;
41
41
  authServer: string;
42
42
  }): Promise<AuthTokenInfo>;
43
+ protected authorizeOrDisconnect(getAuthTokenInfo?: boolean, chainId?: string): Promise<void>;
43
44
  protected clearWalletSession(): Promise<void>;
44
45
  abstract init(options?: ConnectorInitOptions): Promise<void>;
45
46
  abstract connect(params: T & BaseConnectorLoginParams): Promise<Connection | null>;
@@ -47,7 +48,7 @@ export declare abstract class BaseConnector<T> extends SafeEventEmitter<Connecto
47
48
  abstract getUserInfo(): Promise<Partial<UserInfo>>;
48
49
  abstract enableMFA(params?: T): Promise<void>;
49
50
  abstract manageMFA(params?: T): Promise<void>;
50
- abstract getAuthTokenInfo(): Promise<AuthTokenInfo>;
51
+ abstract getAuthTokenInfo(chainId?: string): Promise<AuthTokenInfo>;
51
52
  abstract generateChallengeAndSign(authServerUrl?: string, accounts?: string[]): Promise<{
52
53
  challenge: string;
53
54
  signature: string;
@@ -79,6 +79,7 @@ export interface Connection {
79
79
  readonly ethereumProvider: IProvider | null;
80
80
  readonly solanaWallet: Wallet | null;
81
81
  readonly connectorName: WALLET_CONNECTOR_TYPE | string;
82
+ readonly connectorNamespace: ConnectorNamespaceType;
82
83
  }
83
84
  export interface IConnector<T> extends SafeEventEmitter {
84
85
  connectorNamespace: ConnectorNamespaceType;
@@ -48,6 +48,7 @@ export declare class WalletLoginError extends Web3AuthError {
48
48
  static unsupportedOperation(extraMessage?: string, cause?: unknown): IWeb3AuthError;
49
49
  static sfaKeyNotFound(extraMessage?: string, cause?: unknown): IWeb3AuthError;
50
50
  static userNotLoggedIn(extraMessage?: string, cause?: unknown): IWeb3AuthError;
51
+ static userBlocked(extraMessage?: string, cause?: unknown): IWeb3AuthError;
51
52
  }
52
53
  export declare class WalletOperationsError extends Web3AuthError {
53
54
  protected static messages: ErrorCodes;
@@ -1,7 +1,7 @@
1
1
  import { type BUTTON_POSITION_TYPE } from "@toruslabs/base-controllers";
2
2
  import type { SmartAccountEipStandardType, SmartAccountType } from "@toruslabs/ethereum-controllers";
3
3
  import { AuthConnectionConfigItem, type WhiteLabelData } from "@web3auth/auth";
4
- import { type ChainNamespaceType, type CustomChainConfig } from "./chain/IChainInterface";
4
+ import { type ChainNamespaceType, ConnectorNamespaceType, type CustomChainConfig } from "./chain/IChainInterface";
5
5
  import { LinkedAccountInfo } from "./connector";
6
6
  import { LOGIN_MODE, MODAL_SIGN_IN_METHODS, SMART_ACCOUNT_WALLET_SCOPE, WIDGET_TYPE } from "./constants";
7
7
  import { WALLET_CONNECTOR_TYPE } from "./wallet";
@@ -11,6 +11,7 @@ export interface WhitelistResponse {
11
11
  }
12
12
  export interface IWeb3AuthState {
13
13
  cachedConnector: string | null;
14
+ cachedConnectorNamespace: ConnectorNamespaceType | null;
14
15
  primaryConnectorName: WALLET_CONNECTOR_TYPE | null;
15
16
  currentChainId: string;
16
17
  idToken: string | null;
@@ -21,6 +21,7 @@ export interface MetaMaskConnectorSettings {
21
21
  export interface MetaMaskConnectorOptions extends BaseConnectorSettings {
22
22
  connectorSettings?: MetaMaskConnectorSettings;
23
23
  }
24
+ export declare const METAMASK_ERC_6963_PROVIDER_RDNS = "io.metamask.mmc";
24
25
  /**
25
26
  * Factory function to create a MetaMask connector
26
27
  *
@@ -12,7 +12,6 @@ export declare enum DEFAULT_EIP155_METHODS {
12
12
  ADD_ETHEREUM_CHAIN = "wallet_addEthereumChain",
13
13
  SWITCH_ETHEREUM_CHAIN = "wallet_switchEthereumChain"
14
14
  }
15
- export declare const NULL_ON_SUCCESS_METHODS: string[];
16
15
  export declare enum DEFAULT_SOLANA_METHODS {
17
16
  SIGN_TRANSACTION = "solana_signTransaction",
18
17
  SIGN_MESSAGE = "solana_signMessage"
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Syncs Web3Auth Solana connection with Framework Kit client.
3
- * When user is connected via Web3Auth and current chain is Solana, creates a Framework Kit client
4
- * with Web3Auth as the wallet connector and connects it (same pattern as Wagmi provider).
3
+ * For multichain wallets, keep the Solana client warm across namespace switches so
4
+ * switching back to Solana can reuse the existing wallet session.
5
5
  */
6
6
  export declare const SolanaProvider: import("vue").DefineComponent<{}, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
7
7
  [key: string]: any;