@web3auth/no-modal 11.0.0-beta.0 → 11.0.0-beta.1

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 (100) hide show
  1. package/dist/lib.cjs/account-linking/index.js +8 -0
  2. package/dist/lib.cjs/account-linking/react.js +95 -0
  3. package/dist/lib.cjs/account-linking/rest.js +54 -0
  4. package/dist/lib.cjs/account-linking/vue.js +98 -0
  5. package/dist/lib.cjs/base/analytics.js +17 -2
  6. package/dist/lib.cjs/base/connector/constants.js +2 -0
  7. package/dist/lib.cjs/base/errors/index.js +48 -0
  8. package/dist/lib.cjs/base/utils.js +15 -3
  9. package/dist/lib.cjs/connectors/auth-connector/authConnector.js +427 -50
  10. package/dist/lib.cjs/connectors/base-evm-connector/baseEvmConnector.js +42 -23
  11. package/dist/lib.cjs/connectors/base-solana-connector/baseSolanaConnector.js +41 -24
  12. package/dist/lib.cjs/connectors/metamask-connector/metamaskConnector.js +76 -45
  13. package/dist/lib.cjs/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +41 -13
  14. package/dist/lib.cjs/index.js +20 -13
  15. package/dist/lib.cjs/noModal.js +811 -110
  16. package/dist/lib.cjs/plugins/wallet-services-plugin/plugin.js +1 -1
  17. package/dist/lib.cjs/providers/base-provider/baseProvider.js +65 -33
  18. package/dist/lib.cjs/react/context/useWeb3AuthInnerContextValue.js +34 -20
  19. package/dist/lib.cjs/react/hooks/useWallets.js +51 -0
  20. package/dist/lib.cjs/react/hooks/useWeb3AuthConnect.js +2 -2
  21. package/dist/lib.cjs/react/index.js +2 -0
  22. package/dist/lib.cjs/react/solana/hooks/useSolanaWallet.js +2 -2
  23. package/dist/lib.cjs/react/solana/provider.js +2 -0
  24. package/dist/lib.cjs/types/account-linking/index.d.ts +2 -0
  25. package/dist/lib.cjs/types/account-linking/interfaces.d.ts +90 -0
  26. package/dist/lib.cjs/types/account-linking/react.d.ts +19 -0
  27. package/dist/lib.cjs/types/account-linking/rest.d.ts +9 -0
  28. package/dist/lib.cjs/types/account-linking/vue.d.ts +20 -0
  29. package/dist/lib.cjs/types/base/analytics.d.ts +9 -0
  30. package/dist/lib.cjs/types/base/connector/baseConnector.d.ts +5 -0
  31. package/dist/lib.cjs/types/base/connector/constants.d.ts +2 -0
  32. package/dist/lib.cjs/types/base/connector/interfaces.d.ts +51 -6
  33. package/dist/lib.cjs/types/base/core/IWeb3Auth.d.ts +39 -2
  34. package/dist/lib.cjs/types/base/errors/index.d.ts +13 -0
  35. package/dist/lib.cjs/types/base/interfaces.d.ts +3 -1
  36. package/dist/lib.cjs/types/base/utils.d.ts +7 -1
  37. package/dist/lib.cjs/types/connectors/auth-connector/authConnector.d.ts +27 -3
  38. package/dist/lib.cjs/types/connectors/auth-connector/interface.d.ts +77 -2
  39. package/dist/lib.cjs/types/connectors/base-evm-connector/baseEvmConnector.d.ts +6 -0
  40. package/dist/lib.cjs/types/connectors/base-solana-connector/baseSolanaConnector.d.ts +6 -0
  41. package/dist/lib.cjs/types/index.d.ts +1 -0
  42. package/dist/lib.cjs/types/noModal.d.ts +104 -5
  43. package/dist/lib.cjs/types/providers/base-provider/baseProvider.d.ts +7 -0
  44. package/dist/lib.cjs/types/react/hooks/index.d.ts +1 -0
  45. package/dist/lib.cjs/types/react/hooks/useWallets.d.ts +8 -0
  46. package/dist/lib.cjs/types/vue/composables/index.d.ts +1 -0
  47. package/dist/lib.cjs/types/vue/composables/useWallets.d.ts +9 -0
  48. package/dist/lib.cjs/vue/composables/useWallets.js +52 -0
  49. package/dist/lib.cjs/vue/composables/useWeb3AuthConnect.js +2 -2
  50. package/dist/lib.cjs/vue/index.js +2 -0
  51. package/dist/lib.cjs/vue/solana/composables/useSolanaWallet.js +2 -2
  52. package/dist/lib.cjs/vue/solana/provider.js +3 -0
  53. package/dist/lib.cjs/vue/useWeb3AuthInnerContextValue.js +13 -4
  54. package/dist/lib.cjs/vue/wagmi/provider.js +19 -7
  55. package/dist/lib.esm/account-linking/index.js +1 -0
  56. package/dist/lib.esm/account-linking/react.js +74 -0
  57. package/dist/lib.esm/account-linking/rest.js +51 -0
  58. package/dist/lib.esm/account-linking/vue.js +78 -0
  59. package/dist/lib.esm/base/analytics.js +17 -2
  60. package/dist/lib.esm/base/connector/constants.js +2 -0
  61. package/dist/lib.esm/base/errors/index.js +48 -1
  62. package/dist/lib.esm/base/utils.js +16 -4
  63. package/dist/lib.esm/connectors/auth-connector/authConnector.js +386 -9
  64. package/dist/lib.esm/connectors/base-evm-connector/baseEvmConnector.js +43 -24
  65. package/dist/lib.esm/connectors/base-solana-connector/baseSolanaConnector.js +43 -26
  66. package/dist/lib.esm/connectors/coinbase-connector/coinbaseConnector.js +2 -2
  67. package/dist/lib.esm/connectors/injected-evm-connector/injectedEvmConnector.js +2 -2
  68. package/dist/lib.esm/connectors/injected-solana-connector/walletStandardConnector.js +3 -3
  69. package/dist/lib.esm/connectors/metamask-connector/metamaskConnector.js +80 -49
  70. package/dist/lib.esm/connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js +2 -2
  71. package/dist/lib.esm/connectors/wallet-connect-v2-connector/walletConnectV2Connector.js +43 -15
  72. package/dist/lib.esm/connectors/wallet-connect-v2-connector/wcSolanaWallet.js +1 -1
  73. package/dist/lib.esm/index.js +4 -3
  74. package/dist/lib.esm/noModal.js +828 -119
  75. package/dist/lib.esm/plugins/wallet-services-plugin/plugin.js +3 -3
  76. package/dist/lib.esm/providers/base-provider/baseProvider.js +68 -38
  77. package/dist/lib.esm/react/context/useWeb3AuthInnerContextValue.js +36 -21
  78. package/dist/lib.esm/react/hooks/useWallets.js +33 -0
  79. package/dist/lib.esm/react/hooks/useWeb3AuthConnect.js +2 -2
  80. package/dist/lib.esm/react/index.js +1 -0
  81. package/dist/lib.esm/react/solana/hooks/useSolanaWallet.js +2 -2
  82. package/dist/lib.esm/react/solana/provider.js +4 -1
  83. package/dist/lib.esm/react/wagmi/provider.js +1 -1
  84. package/dist/lib.esm/vue/composables/useCheckout.js +1 -1
  85. package/dist/lib.esm/vue/composables/useFunding.js +1 -1
  86. package/dist/lib.esm/vue/composables/useReceive.js +1 -1
  87. package/dist/lib.esm/vue/composables/useSwap.js +1 -1
  88. package/dist/lib.esm/vue/composables/useWalletConnectScanner.js +1 -1
  89. package/dist/lib.esm/vue/composables/useWalletUI.js +1 -1
  90. package/dist/lib.esm/vue/composables/useWallets.js +35 -0
  91. package/dist/lib.esm/vue/composables/useWeb3AuthConnect.js +2 -2
  92. package/dist/lib.esm/vue/index.js +1 -0
  93. package/dist/lib.esm/vue/solana/composables/useSignAndSendTransaction.js +1 -1
  94. package/dist/lib.esm/vue/solana/composables/useSignMessage.js +1 -1
  95. package/dist/lib.esm/vue/solana/composables/useSignTransaction.js +1 -1
  96. package/dist/lib.esm/vue/solana/composables/useSolanaWallet.js +2 -2
  97. package/dist/lib.esm/vue/solana/provider.js +4 -0
  98. package/dist/lib.esm/vue/useWeb3AuthInnerContextValue.js +12 -3
  99. package/dist/lib.esm/vue/wagmi/provider.js +20 -8
  100. package/package.json +43 -19
@@ -6,23 +6,24 @@ import { SMART_ACCOUNT_EIP_STANDARD, EIP7702_SUPPORTED_SMART_ACCOUNT_TYPES } fro
6
6
  import { SafeEventEmitter, serializeError, UX_MODE, cloneDeep, CookieStorage, LocalStorageAdapter, MemoryStorage } from '@web3auth/auth';
7
7
  import deepmerge from 'deepmerge';
8
8
  import { deserialize } from './base/deserialize.js';
9
+ import { WalletInitializationError, WalletLoginError, AccountLinkingError } from './base/errors/index.js';
9
10
  import { LOGIN_MODE, SMART_ACCOUNT_WALLET_SCOPE, WEB3AUTH_STATE_STORAGE_KEY } from './base/constants.js';
11
+ import { log } from './base/loglevel.js';
10
12
  import { CONNECTOR_STATUS, CONNECTOR_INITIAL_AUTHENTICATION_MODE, CONNECTOR_EVENTS } from './base/connector/constants.js';
11
13
  import { Analytics, ANALYTICS_INTEGRATION_TYPE, ANALYTICS_SDK_TYPE, ANALYTICS_EVENTS } from './base/analytics.js';
12
- import { sdkVersion, fetchProjectConfig, withAbort, getErrorAnalyticsProperties, getCaipChainId, isHexStrict, getHostname, getWhitelabelAnalyticsProperties, getAaAnalyticsProperties, getWalletServicesAnalyticsProperties, isBrowser } from './base/utils.js';
14
+ import { sdkVersion, fetchProjectConfig, withAbort, getErrorAnalyticsProperties, getCaipChainId, isHexStrict, getHostname, getWhitelabelAnalyticsProperties, getAaAnalyticsProperties, getWalletServicesAnalyticsProperties, isBrowser, parseChainNamespaceFromCitadelResponse, normalizeWalletName } from './base/utils.js';
15
+ import { WALLET_CONNECTORS } from './base/wallet/index.js';
16
+ import { CONNECTOR_NAMESPACES } from './base/chain/IChainInterface.js';
13
17
  import { CONNECTED_STATUSES, CAN_LOGOUT_STATUSES, CAN_AUTHORIZE_STATUSES } from './base/connector/connectorStatus.js';
18
+ import { assertAuthConnector, authConnector, isAuthConnector } from './connectors/auth-connector/authConnector.js';
14
19
  import { CommonJRPCProvider } from './providers/base-provider/CommonJRPCProvider.js';
15
- import { authConnector } from './connectors/auth-connector/authConnector.js';
16
20
  import { walletServicesPlugin } from './plugins/wallet-services-plugin/plugin.js';
17
- import { storageAvailable } from './base/connector/utils.js';
18
21
  import { metaMaskConnector } from './connectors/metamask-connector/metamaskConnector.js';
19
- import { WalletInitializationError, WalletLoginError } from './base/errors/index.js';
20
- import { log } from './base/loglevel.js';
21
- import { WALLET_CONNECTORS } from './base/wallet/index.js';
22
- import { CONNECTOR_NAMESPACES } from './base/chain/IChainInterface.js';
22
+ import { storageAvailable } from './base/connector/utils.js';
23
23
  import { PLUGIN_STATUS, PLUGIN_NAMESPACES } from './base/plugin/IPlugin.js';
24
24
 
25
25
  const _excluded = ["walletScope", "eipStandard"];
26
+ const PRIMARY_CONNECTED_WALLET_KEY = "__primary__";
26
27
  class Web3AuthNoModal extends SafeEventEmitter {
27
28
  constructor(options, initialState) {
28
29
  super();
@@ -35,16 +36,20 @@ class Web3AuthNoModal extends SafeEventEmitter {
35
36
  _defineProperty(this, "analytics", void 0);
36
37
  _defineProperty(this, "plugins", {});
37
38
  _defineProperty(this, "consentRequired", false);
39
+ _defineProperty(this, "projectConfig", null);
38
40
  _defineProperty(this, "storage", void 0);
39
- _defineProperty(this, "currentConnection", null);
40
- _defineProperty(this, "currentConnectionReconnected", false);
41
+ _defineProperty(this, "connectionReconnected", false);
42
+ /** Connected wallet state keyed by linked account id; the primary session uses a reserved key. */
43
+ _defineProperty(this, "connectedWalletConnectorMap", new Map());
44
+ _defineProperty(this, "activeWalletConnectorKey", PRIMARY_CONNECTED_WALLET_KEY);
41
45
  _defineProperty(this, "state", {
42
- connectedConnectorName: null,
46
+ primaryConnectorName: null,
43
47
  cachedConnector: null,
44
48
  currentChainId: null,
45
49
  idToken: null,
46
50
  accessToken: null,
47
- refreshToken: null
51
+ refreshToken: null,
52
+ activeAccount: null
48
53
  });
49
54
  if (!options.clientId) throw WalletInitializationError.invalidParams("Please provide a valid clientId in constructor");
50
55
  if (options.enableLogging) log.enableAll();else log.setLevel("error");
@@ -52,6 +57,9 @@ class Web3AuthNoModal extends SafeEventEmitter {
52
57
  this.coreOptions = options;
53
58
  this.storage = this.getStorageMethod();
54
59
  this.analytics = new Analytics();
60
+ if (options.disableAnalytics) {
61
+ this.analytics.disable();
62
+ }
55
63
  this.analytics.setGlobalProperties({
56
64
  integration_type: ANALYTICS_INTEGRATION_TYPE.NATIVE_SDK
57
65
  });
@@ -68,13 +76,13 @@ class Web3AuthNoModal extends SafeEventEmitter {
68
76
  return (_this$coreOptions$cha = this.coreOptions.chains) === null || _this$coreOptions$cha === void 0 ? void 0 : _this$coreOptions$cha.find(chain => chain.chainId === this.currentChainId);
69
77
  }
70
78
  get connected() {
71
- return Boolean(this.connectedConnector);
79
+ return Boolean(this.primaryConnector);
72
80
  }
73
81
  get connection() {
74
- return this.currentConnection;
82
+ return this.getConnectedWalletConnectionByKey(this.activeWalletConnectorKey);
75
83
  }
76
- get connectedConnectorName() {
77
- return this.state.connectedConnectorName;
84
+ get primaryConnectorName() {
85
+ return this.state.primaryConnectorName;
78
86
  }
79
87
  get cachedConnector() {
80
88
  return this.state.cachedConnector;
@@ -83,9 +91,13 @@ class Web3AuthNoModal extends SafeEventEmitter {
83
91
  var _this$coreOptions$cha2;
84
92
  return this.state.currentChainId || this.coreOptions.defaultChainId || ((_this$coreOptions$cha2 = this.coreOptions.chains) === null || _this$coreOptions$cha2 === void 0 || (_this$coreOptions$cha2 = _this$coreOptions$cha2[0]) === null || _this$coreOptions$cha2 === void 0 ? void 0 : _this$coreOptions$cha2.chainId) || null;
85
93
  }
86
- get connectedConnector() {
94
+
95
+ /**
96
+ * This is always the primary connector that is connected to the user.
97
+ */
98
+ get primaryConnector() {
87
99
  var _this$currentChain;
88
- return this.getConnector(this.connectedConnectorName, (_this$currentChain = this.currentChain) === null || _this$currentChain === void 0 ? void 0 : _this$currentChain.chainNamespace);
100
+ return this.getConnector(this.primaryConnectorName, (_this$currentChain = this.currentChain) === null || _this$currentChain === void 0 ? void 0 : _this$currentChain.chainNamespace);
89
101
  }
90
102
  get accountAbstractionProvider() {
91
103
  return this.aaProvider;
@@ -93,6 +105,29 @@ class Web3AuthNoModal extends SafeEventEmitter {
93
105
  get idToken() {
94
106
  return this.state.idToken || null;
95
107
  }
108
+ get accessToken() {
109
+ return this.state.accessToken || null;
110
+ }
111
+ get refreshToken() {
112
+ return this.state.refreshToken || null;
113
+ }
114
+ get activeAccount() {
115
+ return this.state.activeAccount;
116
+ }
117
+
118
+ /**
119
+ * This is the current active connector.
120
+ */
121
+ get activeConnector() {
122
+ const activeConnectedWallet = this.getConnectedWalletConnectorStateByKey(this.activeWalletConnectorKey);
123
+ if (activeConnectedWallet) {
124
+ return activeConnectedWallet.connector;
125
+ }
126
+ if (this.activeWalletConnectorKey !== PRIMARY_CONNECTED_WALLET_KEY) {
127
+ throw new Error(`Signing connector not found for account "${this.activeWalletConnectorKey}".`);
128
+ }
129
+ return this.primaryConnector;
130
+ }
96
131
  set provider(_) {
97
132
  throw new Error("Not implemented");
98
133
  }
@@ -135,6 +170,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
135
170
  }
136
171
 
137
172
  // init config
173
+ this.projectConfig = projectConfig;
138
174
  this.initAccountAbstractionConfig(projectConfig);
139
175
  this.initChainsConfig(projectConfig);
140
176
  await this.initCachedConnectorAndChainId();
@@ -206,13 +242,17 @@ class Web3AuthNoModal extends SafeEventEmitter {
206
242
  }) || null;
207
243
  }
208
244
  async clearCache() {
245
+ this.connectedWalletConnectorMap.clear();
246
+ this.activeWalletConnectorKey = PRIMARY_CONNECTED_WALLET_KEY;
247
+ this.connectionReconnected = false;
209
248
  await this.setState({
210
- connectedConnectorName: null,
249
+ primaryConnectorName: null,
211
250
  cachedConnector: null,
212
251
  currentChainId: null,
213
252
  idToken: null,
214
253
  accessToken: null,
215
254
  refreshToken: null,
255
+ activeAccount: null,
216
256
  hasUserConsent: undefined
217
257
  });
218
258
  }
@@ -226,14 +266,16 @@ class Web3AuthNoModal extends SafeEventEmitter {
226
266
  if (params.chainId === ((_this$currentChain2 = this.currentChain) === null || _this$currentChain2 === void 0 ? void 0 : _this$currentChain2.chainId)) return;
227
267
  const newChainConfig = this.coreOptions.chains.find(x => x.chainId === params.chainId);
228
268
  if (!newChainConfig) throw WalletInitializationError.invalidParams("Invalid chainId");
229
- if (CONNECTED_STATUSES.includes(this.status) && this.connectedConnector) {
230
- var _this$currentChain3;
269
+ if (CONNECTED_STATUSES.includes(this.status)) {
270
+ const activeConnector = this.activeConnector;
271
+ if (!activeConnector) throw WalletInitializationError.notReady("Active signing connector is not ready");
272
+
231
273
  // Single-namespace connectors cannot cross namespace boundaries — MULTICHAIN connectors
232
274
  // (Auth, WC) enforce their own switchChain policy internally.
233
- if (this.connectedConnector.connectorNamespace !== CONNECTOR_NAMESPACES.MULTICHAIN && ((_this$currentChain3 = this.currentChain) === null || _this$currentChain3 === void 0 ? void 0 : _this$currentChain3.chainNamespace) !== newChainConfig.chainNamespace) {
234
- throw WalletLoginError.connectionError(`Cannot switch between chain namespaces with ${this.connectedConnector.name}. Disconnect and reconnect with the target chain.`);
275
+ if (activeConnector.connectorNamespace !== CONNECTOR_NAMESPACES.MULTICHAIN && activeConnector.connectorNamespace !== newChainConfig.chainNamespace) {
276
+ throw WalletLoginError.connectionError(`Cannot switch between chain namespaces with ${activeConnector.name}. Disconnect and reconnect with the target chain.`);
235
277
  }
236
- await this.connectedConnector.switchChain(params);
278
+ await activeConnector.switchChain(params);
237
279
  return;
238
280
  }
239
281
  if (this.commonJRPCProvider) {
@@ -321,7 +363,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
321
363
  const completeConnection = async () => {
322
364
  try {
323
365
  // track connection completed event
324
- const userInfo = await connector.getUserInfo();
366
+ const userInfo = await this.getUserInfo();
325
367
  this.analytics.track(ANALYTICS_EVENTS.CONNECTION_COMPLETED, _objectSpread(_objectSpread({}, eventData), {}, {
326
368
  is_mfa_enabled: userInfo === null || userInfo === void 0 ? void 0 : userInfo.isMfaEnabled,
327
369
  duration: Date.now() - startTime
@@ -361,28 +403,60 @@ class Web3AuthNoModal extends SafeEventEmitter {
361
403
  async logout(options = {
362
404
  cleanup: false
363
405
  }) {
364
- if (!CAN_LOGOUT_STATUSES.includes(this.status) || !this.connectedConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
365
- if (this.connectedConnector.status === CONNECTOR_STATUS.DISCONNECTING) return;
366
- await this.connectedConnector.disconnect(options);
406
+ if (!CAN_LOGOUT_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
407
+ if (this.primaryConnector.status === CONNECTOR_STATUS.DISCONNECTING) return;
408
+ await this.primaryConnector.disconnect(options);
367
409
  }
368
410
  async getUserInfo() {
369
- var _this$connectedConnec;
370
- log.debug("Getting user info", this.status, (_this$connectedConnec = this.connectedConnector) === null || _this$connectedConnec === void 0 ? void 0 : _this$connectedConnec.name);
371
- if (!CAN_AUTHORIZE_STATUSES.includes(this.status) || !this.connectedConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
372
- return this.connectedConnector.getUserInfo();
411
+ var _this$primaryConnecto, _userInfo$linkedAccou, _userInfo$linkedAccou2;
412
+ log.debug("Getting user info", this.status, (_this$primaryConnecto = this.primaryConnector) === null || _this$primaryConnecto === void 0 ? void 0 : _this$primaryConnecto.name);
413
+ if (!CAN_AUTHORIZE_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
414
+ const userInfo = await this.primaryConnector.getUserInfo();
415
+ const linkedAccounts = (_userInfo$linkedAccou = (_userInfo$linkedAccou2 = userInfo.linkedAccounts) === null || _userInfo$linkedAccou2 === void 0 ? void 0 : _userInfo$linkedAccou2.map(account => _objectSpread(_objectSpread({}, account), {}, {
416
+ active: this.state.activeAccount ? account.id === this.state.activeAccount.id : account.isPrimary
417
+ }))) !== null && _userInfo$linkedAccou !== void 0 ? _userInfo$linkedAccou : [];
418
+ this.syncConnectedWalletLinkedAccounts(linkedAccounts);
419
+ return _objectSpread(_objectSpread({}, userInfo), {}, {
420
+ linkedAccounts
421
+ });
422
+ }
423
+ async getLinkedAccounts() {
424
+ if (!CAN_AUTHORIZE_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
425
+ assertAuthConnector(this.primaryConnector, "Linked accounts can only be fetched when connected with the AUTH connector.");
426
+ const linkedAccounts = await this.primaryConnector.getLinkedAccounts();
427
+ const resolvedLinkedAccounts = linkedAccounts.map(account => _objectSpread(_objectSpread({}, account), {}, {
428
+ active: this.state.activeAccount ? account.id === this.state.activeAccount.id : account.isPrimary
429
+ }));
430
+ this.syncConnectedWalletLinkedAccounts(resolvedLinkedAccounts);
431
+ return resolvedLinkedAccounts;
432
+ }
433
+ getConnectedAccountsWithProviders() {
434
+ if (!CONNECTED_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
435
+ if (this.status !== CONNECTOR_STATUS.AUTHORIZED) {
436
+ // before the wallet is authorized, we don't have the user info, so we return an empty array
437
+ return [];
438
+ }
439
+ const connectedAccounts = [];
440
+ for (const [, value] of this.connectedWalletConnectorMap.entries()) {
441
+ const hasWalletProvider = Boolean(value.signingProvider || value.solanaWallet);
442
+ if (hasWalletProvider && this.hasUsableConnectedSwitchConnector(value.connector)) {
443
+ connectedAccounts.push(value);
444
+ }
445
+ }
446
+ return connectedAccounts;
373
447
  }
374
448
  async enableMFA(loginParams) {
375
449
  var _authConnector$authIn2;
376
- if (!CONNECTED_STATUSES.includes(this.status) || !this.connectedConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
377
- if (this.connectedConnector.name !== WALLET_CONNECTORS.AUTH) throw WalletLoginError.unsupportedOperation(`EnableMFA is not supported for this connector.`);
378
- const authConnector = this.connectedConnector;
450
+ if (!CONNECTED_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
451
+ if (this.primaryConnector.name !== WALLET_CONNECTORS.AUTH) throw WalletLoginError.unsupportedOperation(`EnableMFA is not supported for this connector.`);
452
+ const authConnector = this.primaryConnector;
379
453
  const trackData = {
380
- connector: this.connectedConnector.name,
454
+ connector: this.primaryConnector.name,
381
455
  auth_ux_mode: (_authConnector$authIn2 = authConnector.authInstance) === null || _authConnector$authIn2 === void 0 || (_authConnector$authIn2 = _authConnector$authIn2.options) === null || _authConnector$authIn2 === void 0 ? void 0 : _authConnector$authIn2.uxMode
382
456
  };
383
457
  try {
384
458
  this.analytics.track(ANALYTICS_EVENTS.MFA_ENABLEMENT_STARTED, trackData);
385
- await this.connectedConnector.enableMFA(loginParams);
459
+ await this.primaryConnector.enableMFA(loginParams);
386
460
  } catch (error) {
387
461
  this.analytics.track(ANALYTICS_EVENTS.MFA_ENABLEMENT_FAILED, _objectSpread(_objectSpread({}, trackData), getErrorAnalyticsProperties(error)));
388
462
  throw error;
@@ -390,29 +464,29 @@ class Web3AuthNoModal extends SafeEventEmitter {
390
464
  }
391
465
  async manageMFA(loginParams) {
392
466
  var _authConnector$authIn3;
393
- if (!CONNECTED_STATUSES.includes(this.status) || !this.connectedConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
394
- if (this.connectedConnector.name !== WALLET_CONNECTORS.AUTH) throw WalletLoginError.unsupportedOperation(`ManageMFA is not supported for this connector.`);
395
- const authConnector = this.connectedConnector;
467
+ if (!CONNECTED_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
468
+ if (this.primaryConnector.name !== WALLET_CONNECTORS.AUTH) throw WalletLoginError.unsupportedOperation(`ManageMFA is not supported for this connector.`);
469
+ const authConnector = this.primaryConnector;
396
470
  const trackData = {
397
- connector: this.connectedConnector.name,
471
+ connector: this.primaryConnector.name,
398
472
  auth_ux_mode: (_authConnector$authIn3 = authConnector.authInstance) === null || _authConnector$authIn3 === void 0 || (_authConnector$authIn3 = _authConnector$authIn3.options) === null || _authConnector$authIn3 === void 0 ? void 0 : _authConnector$authIn3.uxMode
399
473
  };
400
474
  try {
401
475
  this.analytics.track(ANALYTICS_EVENTS.MFA_MANAGEMENT_SELECTED, trackData);
402
- await this.connectedConnector.manageMFA(loginParams);
476
+ await this.primaryConnector.manageMFA(loginParams);
403
477
  } catch (error) {
404
478
  this.analytics.track(ANALYTICS_EVENTS.MFA_MANAGEMENT_FAILED, _objectSpread(_objectSpread({}, trackData), getErrorAnalyticsProperties(error)));
405
479
  throw error;
406
480
  }
407
481
  }
408
482
  async getAuthTokenInfo() {
409
- if (!CAN_AUTHORIZE_STATUSES.includes(this.status) || !this.connectedConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
483
+ if (!CAN_AUTHORIZE_STATUSES.includes(this.status) || !this.primaryConnector) throw WalletLoginError.notConnectedError(`No wallet is connected`);
410
484
  const trackData = {
411
- connector: this.connectedConnector.name
485
+ connector: this.primaryConnector.name
412
486
  };
413
487
  try {
414
488
  this.analytics.track(ANALYTICS_EVENTS.IDENTITY_TOKEN_STARTED, trackData);
415
- const authTokenInfo = await this.connectedConnector.getAuthTokenInfo();
489
+ const authTokenInfo = await this.primaryConnector.getAuthTokenInfo();
416
490
  this.analytics.track(ANALYTICS_EVENTS.IDENTITY_TOKEN_COMPLETED, trackData);
417
491
  return {
418
492
  idToken: authTokenInfo.idToken
@@ -425,6 +499,76 @@ class Web3AuthNoModal extends SafeEventEmitter {
425
499
  getPlugin(name) {
426
500
  return this.plugins[name] || null;
427
501
  }
502
+ async switchAccount(account) {
503
+ const authConnector = this.getMainAuthConnector();
504
+ const switchResult = await authConnector.switchAccount(account, {
505
+ activeAccount: this.state.activeAccount,
506
+ currentChainId: this.currentChainId
507
+ });
508
+ if (!switchResult) {
509
+ return;
510
+ }
511
+ try {
512
+ var _this$projectConfig;
513
+ await this.processSwitchAccountResult(authConnector, switchResult, {
514
+ projectConfig: (_this$projectConfig = this.projectConfig) !== null && _this$projectConfig !== void 0 ? _this$projectConfig : undefined
515
+ });
516
+ await authConnector.trackSwitchAccountCompleted(switchResult.targetAccount);
517
+ } catch (error) {
518
+ await authConnector.trackSwitchAccountFailed(switchResult.targetAccount, error);
519
+ throw error;
520
+ }
521
+ }
522
+ async linkAccount(params) {
523
+ if (!(params !== null && params !== void 0 && params.connectorName)) {
524
+ throw WalletInitializationError.invalidParams("connectorName is required when calling linkAccount on the no-modal SDK");
525
+ }
526
+ const chainId = this.resolveLinkAccountChainId(params.chainId);
527
+ const isolatedConnector = await this.createLinkingWalletConnector(params.connectorName, chainId);
528
+ return this.linkAccountWithConnector(params.connectorName, chainId, isolatedConnector);
529
+ }
530
+ async unlinkAccount(address) {
531
+ var _await$authConnector$, _this$state$activeAcc;
532
+ const authConnector = this.getMainAuthConnector();
533
+ const linkedAccounts = (_await$authConnector$ = (await authConnector.getUserInfo()).linkedAccounts) !== null && _await$authConnector$ !== void 0 ? _await$authConnector$ : [];
534
+ const targetAccount = this.findLinkedAccountByAddress(linkedAccounts, address);
535
+ if (!targetAccount) {
536
+ throw AccountLinkingError.accountNotLinked(`Account with address "${address}" is not linked`);
537
+ }
538
+ if (targetAccount.connector === WALLET_CONNECTORS.AUTH || targetAccount.isPrimary) {
539
+ throw AccountLinkingError.cannotUnlinkPrimaryAccount();
540
+ }
541
+ if (((_this$state$activeAcc = this.state.activeAccount) === null || _this$state$activeAcc === void 0 ? void 0 : _this$state$activeAcc.id) === targetAccount.id) {
542
+ throw AccountLinkingError.cannotUnlinkActiveAccount();
543
+ }
544
+ const result = await authConnector.unlinkAccount({
545
+ address,
546
+ authSessionTokens: {
547
+ accessToken: this.accessToken,
548
+ idToken: this.idToken
549
+ }
550
+ });
551
+ await this.setState({
552
+ idToken: result.idToken
553
+ });
554
+
555
+ // disconnect the connector for unlinked account
556
+ const connectorToDisconnect = this.getConnectedWalletConnector(targetAccount);
557
+ if (connectorToDisconnect) {
558
+ try {
559
+ if (connectorToDisconnect.connected) {
560
+ await connectorToDisconnect.disconnect({
561
+ cleanup: true
562
+ });
563
+ }
564
+ } catch (error) {
565
+ log.debug(`Failed to disconnect linked account "${targetAccount.id}" during unlink`, error);
566
+ } finally {
567
+ this.deleteConnectedWalletConnector(targetAccount);
568
+ }
569
+ }
570
+ return result;
571
+ }
428
572
  setAnalyticsProperties(properties) {
429
573
  this.analytics.setGlobalProperties(properties);
430
574
  }
@@ -762,23 +906,26 @@ class Web3AuthNoModal extends SafeEventEmitter {
762
906
  }
763
907
  subscribeToConnectorEvents(connector) {
764
908
  connector.on(CONNECTOR_EVENTS.CONNECTED, async data => {
909
+ if (this.primaryConnectorName && this.primaryConnectorName !== data.connectorName) {
910
+ // Ignore registered connectors that are not the active primary session connector.
911
+ return;
912
+ }
765
913
  if (!this.commonJRPCProvider) throw WalletInitializationError.notFound(`CommonJrpcProvider not found`);
766
914
  const {
767
915
  ethereumProvider,
768
916
  solanaWallet
769
917
  } = data;
770
- const isSolanaOnly = connector.connectorNamespace === CHAIN_NAMESPACES.SOLANA;
771
-
772
- // Set connection and consent status SYNCHRONOUSLY before any await so the
773
- // AUTHORIZED handler (which may fire during async work below) can detect the
774
- // consent-required state. Create a deferred promise the AUTHORIZED handler
775
- // will await to ensure consent userId + pre-approval are resolved first.
776
- this.currentConnection = {
777
- ethereumProvider: isSolanaOnly ? null : ethereumProvider ? this.commonJRPCProvider : null,
778
- solanaWallet: solanaWallet !== null && solanaWallet !== void 0 ? solanaWallet : null,
779
- connectorName: data.connectorName
780
- };
781
- this.currentConnectionReconnected = data.reconnected;
918
+ // Seed the primary connector synchronously so AUTHORIZED can resolve a connection
919
+ // even while we are still restoring a previously active linked wallet.
920
+ this.setConnectedWalletConnectorState(this.buildImmediateConnectedWalletConnectorState({
921
+ connector,
922
+ ethereumProvider,
923
+ solanaWallet,
924
+ usePrimaryProxy: true
925
+ }));
926
+ this.setActiveWalletConnectorKey();
927
+ this.connectionReconnected = data.reconnected;
928
+ const connectedChainId = ethereumProvider === null || ethereumProvider === void 0 ? void 0 : ethereumProvider.chainId;
782
929
 
783
930
  // when ssr is enabled, we need to get the idToken from the connector.
784
931
  if (this.coreOptions.ssr) {
@@ -793,63 +940,67 @@ class Web3AuthNoModal extends SafeEventEmitter {
793
940
  });
794
941
  } catch (error) {
795
942
  log.error(error);
796
- this.currentConnection = null;
943
+ this.deleteConnectedWalletConnector();
944
+ this.setActiveWalletConnectorKey();
797
945
  this.status = CONNECTOR_STATUS.ERRORED;
798
946
  this.emit(CONNECTOR_EVENTS.ERRORED, error, this.loginMode);
799
947
  return;
800
948
  }
801
949
  }
950
+ // The following block only hits during rehydration
802
951
 
803
- // setup AA provider if AA is enabled (skip for EIP-7702; 7702 uses EOA + 5792/7702 RPC only)
804
- if (ethereumProvider) {
805
- var _this$currentChain4, _accountAbstractionCo;
806
- let finalProvider = (ethereumProvider === null || ethereumProvider === void 0 ? void 0 : ethereumProvider.provider) || ethereumProvider;
807
- const {
808
- accountAbstractionConfig
809
- } = this.coreOptions;
810
- const is7702 = (accountAbstractionConfig === null || accountAbstractionConfig === void 0 ? void 0 : accountAbstractionConfig.smartAccountEipStandard) === SMART_ACCOUNT_EIP_STANDARD["EIP_7702"];
811
- const isAaSupportedForCurrentChain = ((_this$currentChain4 = this.currentChain) === null || _this$currentChain4 === void 0 ? void 0 : _this$currentChain4.chainNamespace) === CHAIN_NAMESPACES.EIP155 && (accountAbstractionConfig === null || accountAbstractionConfig === void 0 || (_accountAbstractionCo = accountAbstractionConfig.chains) === null || _accountAbstractionCo === void 0 ? void 0 : _accountAbstractionCo.some(chain => {
812
- var _this$currentChain5;
813
- return chain.chainId === ((_this$currentChain5 = this.currentChain) === null || _this$currentChain5 === void 0 ? void 0 : _this$currentChain5.chainId);
814
- }));
815
- if (!is7702 && isAaSupportedForCurrentChain && (data.connectorName === WALLET_CONNECTORS.AUTH || this.coreOptions.useAAWithExternalWallet)) {
816
- var _accountAbstractionCo2;
817
- const {
818
- accountAbstractionProvider,
819
- toEoaProvider
820
- } = await import('./providers/account-abstraction-provider/index.js');
821
- // for embedded wallets, we use ws-embed provider which is AA provider, need to derive EOA provider
822
- const eoaProvider = data.connectorName === WALLET_CONNECTORS.AUTH ? await toEoaProvider(ethereumProvider) : ethereumProvider;
823
- const aaChainIds = new Set((accountAbstractionConfig === null || accountAbstractionConfig === void 0 || (_accountAbstractionCo2 = accountAbstractionConfig.chains) === null || _accountAbstractionCo2 === void 0 ? void 0 : _accountAbstractionCo2.map(chain => chain.chainId)) || []);
824
- const aaProvider = await accountAbstractionProvider({
825
- accountAbstractionConfig,
826
- provider: eoaProvider,
827
- chain: this.currentChain,
828
- chains: this.coreOptions.chains.filter(chain => aaChainIds.has(chain.chainId)),
829
- useProviderAsTransport: data.connectorName === WALLET_CONNECTORS.AUTH
952
+ const {
953
+ activeAccount
954
+ } = this.state;
955
+ // if the active account is not the primary account, i.e. not `null`, create an isolated connector and connect to the chain
956
+ if (activeAccount && !activeAccount.isPrimary && activeAccount.connector !== WALLET_CONNECTORS.AUTH) {
957
+ var _ref3, _walletConnector$prov, _linkedAccountConnect, _ref4, _walletConnector$sola, _linkedAccountConnect2;
958
+ const accountLinkingConnector = isAuthConnector(connector) ? connector : this.getConnector(WALLET_CONNECTORS.AUTH);
959
+ assertAuthConnector(accountLinkingConnector, "Account switching requires the AUTH connector to be available.");
960
+ const targetChainId = accountLinkingConnector.getChainIdForLinkedAccount(activeAccount, connectedChainId);
961
+ const walletConnector = await this.createIsolatedWalletConnector(activeAccount.connector, targetChainId);
962
+ let linkedAccountConnection = null;
963
+ if (!this.hasUsableConnectedSwitchConnector(walletConnector)) {
964
+ linkedAccountConnection = await walletConnector.connect({
965
+ chainId: targetChainId
830
966
  });
831
- this.aaProvider = aaProvider;
832
-
833
- // if external wallet is used and AA is enabled for external wallets, use AA provider
834
- // for embedded wallets, we use ws-embed provider which already supports AA
835
- if (data.connectorName !== WALLET_CONNECTORS.AUTH && this.coreOptions.useAAWithExternalWallet) {
836
- finalProvider = this.aaProvider;
967
+ if (!linkedAccountConnection) {
968
+ throw AccountLinkingError.requestFailed(`Failed to connect isolated connector "${activeAccount.connector}" for account switch.`);
837
969
  }
838
970
  }
839
- this.commonJRPCProvider.updateProviderEngineProxy(finalProvider);
971
+ const connectedWalletState = await this.resolveConnectedWalletConnectorState({
972
+ connector: walletConnector,
973
+ ethereumProvider: (_ref3 = (_walletConnector$prov = walletConnector.provider) !== null && _walletConnector$prov !== void 0 ? _walletConnector$prov : (_linkedAccountConnect = linkedAccountConnection) === null || _linkedAccountConnect === void 0 ? void 0 : _linkedAccountConnect.ethereumProvider) !== null && _ref3 !== void 0 ? _ref3 : null,
974
+ solanaWallet: (_ref4 = (_walletConnector$sola = walletConnector.solanaWallet) !== null && _walletConnector$sola !== void 0 ? _walletConnector$sola : (_linkedAccountConnect2 = linkedAccountConnection) === null || _linkedAccountConnect2 === void 0 ? void 0 : _linkedAccountConnect2.solanaWallet) !== null && _ref4 !== void 0 ? _ref4 : null,
975
+ usePrimaryProxy: false,
976
+ account: activeAccount
977
+ });
978
+ this.setConnectedWalletConnectorState(connectedWalletState, activeAccount);
979
+ this.setActiveWalletConnectorKey(activeAccount);
840
980
  }
981
+ if (ethereumProvider) {
982
+ await this.bindPrimaryEthereumSigningProxy(ethereumProvider, data.connectorName);
983
+ }
984
+ const primaryConnectedWalletState = await this.resolveConnectedWalletConnectorState({
985
+ connector,
986
+ ethereumProvider,
987
+ solanaWallet,
988
+ usePrimaryProxy: true
989
+ });
990
+ this.setConnectedWalletConnectorState(primaryConnectedWalletState);
841
991
  await this.setState({
842
- connectedConnectorName: data.connectorName
992
+ primaryConnectorName: data.connectorName,
993
+ currentChainId: connectedChainId
843
994
  });
844
995
  this.cacheWallet(data.connectorName);
845
996
  const isConnectAndSign = this.coreOptions.initialAuthenticationMode === CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
846
997
  if (this.consentRequired && !isConnectAndSign && !this.state.hasUserConsent) {
847
998
  this.status = CONNECTOR_STATUS.CONSENT_REQUIRING;
848
999
  this.emit(CONNECTOR_EVENTS.CONSENT_REQUIRING);
849
- log.debug("consent_requiring", this.status, this.connectedConnectorName);
1000
+ log.debug("consent_requiring", this.status, this.primaryConnectorName);
850
1001
  } else {
851
1002
  this.status = CONNECTOR_STATUS.CONNECTED;
852
- log.debug("connected", this.status, this.connectedConnectorName);
1003
+ log.debug("connected", this.status, this.primaryConnectorName);
853
1004
  this.connectToPlugins(_objectSpread(_objectSpread({}, data), {}, {
854
1005
  connector: data.connectorName
855
1006
  }));
@@ -858,9 +1009,36 @@ class Web3AuthNoModal extends SafeEventEmitter {
858
1009
  }));
859
1010
  }
860
1011
  });
861
- connector.on(CONNECTOR_EVENTS.DISCONNECTED, async () => {
862
- this.currentConnection = null;
863
- this.currentConnectionReconnected = false;
1012
+ connector.on(CONNECTOR_EVENTS.DISCONNECTED, async data => {
1013
+ if (this.shouldIgnoreInactiveConnectorEvent(connector, CONNECTOR_EVENTS.DISCONNECTED)) return;
1014
+ const disconnectedConnector = data === null || data === void 0 ? void 0 : data.connector;
1015
+ const {
1016
+ activeAccount
1017
+ } = this.state;
1018
+ if (!activeAccount || activeAccount && activeAccount.isPrimary || disconnectedConnector === WALLET_CONNECTORS.AUTH) {
1019
+ // If the primary session disconnects, tear down every other connected wallet connector
1020
+ // and clear the entire map.
1021
+ await Promise.all(Array.from(this.connectedWalletConnectorMap.entries()).map(async ([accountId, connectedWallet]) => {
1022
+ if (connectedWallet.connector === connector) {
1023
+ this.connectedWalletConnectorMap.delete(accountId);
1024
+ return;
1025
+ }
1026
+ try {
1027
+ if (connectedWallet.connected && connectedWallet.connector.connected) {
1028
+ await connectedWallet.connector.disconnect({
1029
+ cleanup: true
1030
+ });
1031
+ }
1032
+ } catch (error) {
1033
+ log.debug("Connected wallet connector disconnect on primary disconnect", error);
1034
+ } finally {
1035
+ this.connectedWalletConnectorMap.delete(accountId);
1036
+ }
1037
+ }));
1038
+ }
1039
+ this.connectedWalletConnectorMap.clear();
1040
+ this.activeWalletConnectorKey = PRIMARY_CONNECTED_WALLET_KEY;
1041
+ this.connectionReconnected = false;
864
1042
  // re-setup commonJRPCProvider
865
1043
  this.commonJRPCProvider.removeAllListeners();
866
1044
  this.setupCommonJRPCProvider();
@@ -868,10 +1046,10 @@ class Web3AuthNoModal extends SafeEventEmitter {
868
1046
  // get back to ready state for rehydrating.
869
1047
  this.status = CONNECTOR_STATUS.READY;
870
1048
  const cachedConnector = this.state.cachedConnector;
871
- if (this.connectedConnectorName === cachedConnector) {
1049
+ if (this.primaryConnectorName === cachedConnector) {
872
1050
  await this.clearCache();
873
1051
  }
874
- log.debug("disconnected", this.status, this.connectedConnectorName);
1052
+ log.debug("disconnected", this.status, this.primaryConnectorName);
875
1053
  await Promise.all(Object.values(this.plugins).map(async plugin => {
876
1054
  if (!plugin.SUPPORTED_CONNECTORS.includes(connector.name)) return;
877
1055
  if (plugin.status !== PLUGIN_STATUS.CONNECTED) return;
@@ -885,23 +1063,38 @@ class Web3AuthNoModal extends SafeEventEmitter {
885
1063
  });
886
1064
  }));
887
1065
  await this.setState({
888
- connectedConnectorName: null,
889
- hasUserConsent: undefined
1066
+ primaryConnectorName: null,
1067
+ hasUserConsent: undefined,
1068
+ activeAccount: null
890
1069
  });
891
1070
  this.emit(CONNECTOR_EVENTS.DISCONNECTED);
892
1071
  });
893
1072
  connector.on(CONNECTOR_EVENTS.CONNECTING, data => {
894
1073
  this.status = CONNECTOR_STATUS.CONNECTING;
895
1074
  this.emit(CONNECTOR_EVENTS.CONNECTING, data);
896
- log.debug("connecting", this.status, this.connectedConnectorName);
1075
+ log.debug("connecting", this.status, this.primaryConnectorName);
897
1076
  });
898
1077
  connector.on(CONNECTOR_EVENTS.ERRORED, async data => {
1078
+ if (this.shouldIgnoreInactiveConnectorEvent(connector, CONNECTOR_EVENTS.ERRORED)) {
1079
+ log.error("Inactive connector emitted errored event", {
1080
+ connector: connector.name,
1081
+ error: data
1082
+ });
1083
+ return;
1084
+ }
899
1085
  this.status = CONNECTOR_STATUS.ERRORED;
900
1086
  await this.clearCache();
901
1087
  this.emit(CONNECTOR_EVENTS.ERRORED, data, this.loginMode);
902
- log.debug("errored", this.status, this.connectedConnectorName);
1088
+ log.debug("errored", this.status, this.primaryConnectorName);
903
1089
  });
904
1090
  connector.on(CONNECTOR_EVENTS.REHYDRATION_ERROR, async error => {
1091
+ if (this.shouldIgnoreInactiveConnectorEvent(connector, CONNECTOR_EVENTS.REHYDRATION_ERROR)) {
1092
+ log.error("Inactive connector emitted rehydration error", {
1093
+ connector: connector.name,
1094
+ error
1095
+ });
1096
+ return;
1097
+ }
905
1098
  this.status = CONNECTOR_STATUS.READY;
906
1099
  await this.clearCache();
907
1100
  this.emit(CONNECTOR_EVENTS.REHYDRATION_ERROR, error);
@@ -911,18 +1104,19 @@ class Web3AuthNoModal extends SafeEventEmitter {
911
1104
  this.emit(CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, data);
912
1105
  });
913
1106
  connector.on(CONNECTOR_EVENTS.CACHE_CLEAR, async data => {
1107
+ if (this.shouldIgnoreInactiveConnectorEvent(connector, CONNECTOR_EVENTS.CACHE_CLEAR)) return;
914
1108
  log.debug("connector cache clear", data);
915
1109
  await this.clearCache();
916
1110
  });
917
1111
  connector.on(CONNECTOR_EVENTS.MFA_ENABLED, isMFAEnabled => {
918
1112
  var _authConnector$authIn4;
919
1113
  log.debug("mfa enabled", isMFAEnabled);
920
- const authConnector = this.connectedConnector;
1114
+ const authConnector = this.primaryConnector;
921
1115
 
922
1116
  // mfa_enabled event is only emitted when using "popup" ux_mode
923
1117
  // TODO: handle mfa_enabled event when using "redirect" ux_mode
924
1118
  this.analytics.track(ANALYTICS_EVENTS.MFA_ENABLEMENT_COMPLETED, {
925
- connector: this.connectedConnector.name,
1119
+ connector: this.primaryConnector.name,
926
1120
  auth_ux_mode: (_authConnector$authIn4 = authConnector.authInstance) === null || _authConnector$authIn4 === void 0 || (_authConnector$authIn4 = _authConnector$authIn4.options) === null || _authConnector$authIn4 === void 0 ? void 0 : _authConnector$authIn4.uxMode,
927
1121
  is_mfa_enabled: isMFAEnabled
928
1122
  });
@@ -931,7 +1125,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
931
1125
  connector.on(CONNECTOR_EVENTS.AUTHORIZING, data => {
932
1126
  this.status = CONNECTOR_STATUS.AUTHORIZING;
933
1127
  this.emit(CONNECTOR_EVENTS.AUTHORIZING, data);
934
- log.debug("authorizing", this.status, this.connectedConnectorName);
1128
+ log.debug("authorizing", this.status, this.primaryConnectorName);
935
1129
  });
936
1130
  connector.on(CONNECTOR_EVENTS.AUTHORIZED, async data => {
937
1131
  var _data$authTokenInfo$a, _data$authTokenInfo$r;
@@ -941,14 +1135,14 @@ class Web3AuthNoModal extends SafeEventEmitter {
941
1135
  refreshToken: (_data$authTokenInfo$r = data.authTokenInfo.refreshToken) !== null && _data$authTokenInfo$r !== void 0 ? _data$authTokenInfo$r : null
942
1136
  });
943
1137
  // if the user has not consented yet, we will ask for consent
944
- if (this.consentRequired && this.currentConnection && !this.state.hasUserConsent) {
1138
+ if (this.consentRequired && this.connection && !this.state.hasUserConsent) {
945
1139
  this.status = CONNECTOR_STATUS.CONSENT_REQUIRING;
946
1140
  this.emit(CONNECTOR_EVENTS.CONSENT_REQUIRING);
947
- log.debug("consent_requiring", this.status, this.connectedConnectorName);
1141
+ log.debug("consent_requiring", this.status, this.primaryConnectorName);
948
1142
  } else {
949
1143
  this.status = CONNECTOR_STATUS.AUTHORIZED;
950
1144
  this.emit(CONNECTOR_EVENTS.AUTHORIZED, data);
951
- log.debug("authorized", this.status, this.connectedConnectorName);
1145
+ log.debug("authorized", this.status, this.primaryConnectorName);
952
1146
  }
953
1147
  });
954
1148
  }
@@ -956,9 +1150,9 @@ class Web3AuthNoModal extends SafeEventEmitter {
956
1150
  if (this.status === CONNECTOR_STATUS.READY) throw WalletInitializationError.notReady("Connector is already initialized");
957
1151
  }
958
1152
  checkIfAutoConnect(connector) {
959
- var _this$currentChain6;
1153
+ var _this$currentChain3;
960
1154
  let autoConnect = this.cachedConnector === connector.name;
961
- if (autoConnect && (_this$currentChain6 = this.currentChain) !== null && _this$currentChain6 !== void 0 && _this$currentChain6.chainNamespace) {
1155
+ if (autoConnect && (_this$currentChain3 = this.currentChain) !== null && _this$currentChain3 !== void 0 && _this$currentChain3.chainNamespace) {
962
1156
  if (connector.connectorNamespace === CONNECTOR_NAMESPACES.MULTICHAIN) autoConnect = true;else autoConnect = connector.connectorNamespace === this.currentChain.chainNamespace;
963
1157
  }
964
1158
  return autoConnect;
@@ -978,7 +1172,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
978
1172
  return initialChain;
979
1173
  }
980
1174
  async completeConsentAcceptance() {
981
- const connection = this.currentConnection;
1175
+ const connection = this.connection;
982
1176
  if (!connection) {
983
1177
  throw WalletLoginError.connectionError("Cannot accept consent: no active connection");
984
1178
  }
@@ -991,22 +1185,390 @@ class Web3AuthNoModal extends SafeEventEmitter {
991
1185
  const isConnectAndSign = this.coreOptions.initialAuthenticationMode === CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
992
1186
  if (isConnectAndSign && this.state.idToken) {
993
1187
  this.status = CONNECTOR_STATUS.AUTHORIZED;
994
- log.debug("consent accepted, authorized", this.status, this.connectedConnectorName);
1188
+ log.debug("consent accepted, authorized", this.status, this.primaryConnectorName);
995
1189
  } else {
996
1190
  this.status = CONNECTOR_STATUS.CONNECTED;
997
- log.debug("consent accepted, connected", this.status, this.connectedConnectorName);
1191
+ log.debug("consent accepted, connected", this.status, this.primaryConnectorName);
998
1192
  }
999
1193
 
1000
1194
  // connect to wallet-service plugin
1001
- if (this.connectedConnectorName === WALLET_CONNECTORS.AUTH) {
1195
+ if (this.primaryConnectorName === WALLET_CONNECTORS.AUTH) {
1002
1196
  this.connectToPlugins({
1003
- connector: this.connectedConnectorName
1197
+ connector: this.primaryConnectorName
1004
1198
  });
1005
1199
  }
1006
1200
  this.emit(CONNECTOR_EVENTS.CONSENT_ACCEPTED, {
1007
- reconnected: this.currentConnectionReconnected
1201
+ reconnected: this.connectionReconnected
1008
1202
  });
1009
1203
  }
1204
+ resolveLinkAccountChainId(chainId) {
1205
+ const finalChainId = chainId || this.state.currentChainId;
1206
+ if (!finalChainId) {
1207
+ throw AccountLinkingError.walletProofFailed("No chainId is available. Please specify chainId in LinkAccountParams or ensure the SDK has an active chain.");
1208
+ }
1209
+ return finalChainId;
1210
+ }
1211
+
1212
+ /**
1213
+ * Resolves the chain ID for a switch account operation.
1214
+ * If the account's chain namespace is the same as the current chain namespace, return the current chain ID.
1215
+ * If the account's chain namespace is different from the current chain namespace, return the chainId the account was linked in.
1216
+ *
1217
+ * @param account - The account to switch to.
1218
+ * @param activeChainId - The current active chain ID.
1219
+ * @returns The resolved chain ID.
1220
+ */
1221
+ resolveSwitchAccountChainId(account, activeChainId) {
1222
+ const targetChainNamespace = account.chainNamespace ? parseChainNamespaceFromCitadelResponse(account.chainNamespace) : null;
1223
+ if (targetChainNamespace && this.currentChain.chainNamespace === targetChainNamespace) {
1224
+ return this.currentChain.chainId;
1225
+ }
1226
+ return activeChainId;
1227
+ }
1228
+ async createLinkingWalletConnector(connectorName, chainId, config) {
1229
+ return this.createIsolatedWalletConnector(connectorName, chainId, config);
1230
+ }
1231
+ async createSwitchingWalletConnector(connectorName, chainId, config) {
1232
+ return this.createIsolatedWalletConnector(connectorName, chainId, config);
1233
+ }
1234
+ getConnectedWalletConnector(account) {
1235
+ var _this$getConnectedWal, _this$getConnectedWal2;
1236
+ return (_this$getConnectedWal = (_this$getConnectedWal2 = this.getConnectedWalletConnectorState(account)) === null || _this$getConnectedWal2 === void 0 ? void 0 : _this$getConnectedWal2.connector) !== null && _this$getConnectedWal !== void 0 ? _this$getConnectedWal : null;
1237
+ }
1238
+ getConnectedWalletConnectorState(account) {
1239
+ return this.getConnectedWalletConnectorStateByKey(this.getConnectedWalletConnectorKey(account));
1240
+ }
1241
+ setConnectedWalletConnectorState(connectedWallet, account) {
1242
+ this.connectedWalletConnectorMap.set(this.getConnectedWalletConnectorKey(account), connectedWallet);
1243
+ }
1244
+ setConnectedWalletConnector(connector, account) {
1245
+ var _connector$solanaWall;
1246
+ this.setConnectedWalletConnectorState(_objectSpread(_objectSpread({}, this.getConnectedWalletLinkedAccountInfo(account)), {}, {
1247
+ connector,
1248
+ signingProvider: connector.provider,
1249
+ solanaWallet: (_connector$solanaWall = connector.solanaWallet) !== null && _connector$solanaWall !== void 0 ? _connector$solanaWall : null,
1250
+ connected: connector.connected || connector.status === CONNECTOR_STATUS.CONNECTED
1251
+ }), account);
1252
+ }
1253
+ deleteConnectedWalletConnector(account) {
1254
+ this.connectedWalletConnectorMap.delete(this.getConnectedWalletConnectorKey(account));
1255
+ }
1256
+ getConnectedWalletConnection(account) {
1257
+ return this.getConnectedWalletConnectionByKey(this.getConnectedWalletConnectorKey(account));
1258
+ }
1259
+ hasUsableConnectedSwitchConnector(connector) {
1260
+ if (!connector) return false;
1261
+ const isConnected = connector.connected || connector.status === CONNECTOR_STATUS.CONNECTED;
1262
+ return Boolean(isConnected && (connector.provider || connector.solanaWallet));
1263
+ }
1264
+ setActiveWalletConnectorKey(account) {
1265
+ this.activeWalletConnectorKey = this.getConnectedWalletConnectorKey(account);
1266
+ }
1267
+ getConnectedWalletConnectorKey(account) {
1268
+ return !account || account.isPrimary ? PRIMARY_CONNECTED_WALLET_KEY : account.id;
1269
+ }
1270
+ getConnectedWalletConnectorStateByKey(accountKey) {
1271
+ var _this$connectedWallet;
1272
+ return (_this$connectedWallet = this.connectedWalletConnectorMap.get(accountKey)) !== null && _this$connectedWallet !== void 0 ? _this$connectedWallet : null;
1273
+ }
1274
+ isLinkedAccountInfo(account) {
1275
+ return Boolean(account && "connector" in account);
1276
+ }
1277
+ toConnectedWalletLinkedAccountInfo(account) {
1278
+ return {
1279
+ id: account.id,
1280
+ isPrimary: account.isPrimary,
1281
+ eoaAddress: account.eoaAddress,
1282
+ aaAddress: account.aaAddress,
1283
+ aaProvider: account.aaProvider,
1284
+ active: account.active,
1285
+ accountType: account.accountType,
1286
+ address: account.address,
1287
+ authConnectionId: account.authConnectionId,
1288
+ groupedAuthConnectionId: account.groupedAuthConnectionId,
1289
+ chainNamespace: account.chainNamespace
1290
+ };
1291
+ }
1292
+ getConnectedWalletLinkedAccountInfo(account) {
1293
+ const existingConnectedWallet = this.getConnectedWalletConnectorState(account);
1294
+ const resolvedAccount = this.isLinkedAccountInfo(account) ? account : existingConnectedWallet;
1295
+ if (resolvedAccount) {
1296
+ return this.toConnectedWalletLinkedAccountInfo(resolvedAccount);
1297
+ }
1298
+ const isPrimaryAccount = !account || account.isPrimary;
1299
+ const accountId = account && !account.isPrimary ? account.id : PRIMARY_CONNECTED_WALLET_KEY;
1300
+ return {
1301
+ id: accountId,
1302
+ isPrimary: isPrimaryAccount,
1303
+ eoaAddress: "",
1304
+ aaAddress: undefined,
1305
+ aaProvider: undefined,
1306
+ active: this.state.activeAccount ? this.state.activeAccount.id === accountId : isPrimaryAccount,
1307
+ accountType: "",
1308
+ address: null,
1309
+ authConnectionId: null,
1310
+ groupedAuthConnectionId: null,
1311
+ chainNamespace: null
1312
+ };
1313
+ }
1314
+ syncConnectedWalletLinkedAccounts(linkedAccounts) {
1315
+ for (const linkedAccount of linkedAccounts) {
1316
+ const accountKey = this.getConnectedWalletConnectorKey(linkedAccount);
1317
+ const connectedWallet = this.connectedWalletConnectorMap.get(accountKey);
1318
+ if (!connectedWallet) {
1319
+ continue;
1320
+ }
1321
+ this.connectedWalletConnectorMap.set(accountKey, _objectSpread(_objectSpread({}, connectedWallet), this.toConnectedWalletLinkedAccountInfo(linkedAccount)));
1322
+ }
1323
+ }
1324
+ refreshConnectedWalletActiveStates(activeAccount) {
1325
+ for (const [accountKey, connectedWallet] of this.connectedWalletConnectorMap.entries()) {
1326
+ const isPrimaryAccount = accountKey === PRIMARY_CONNECTED_WALLET_KEY || connectedWallet.isPrimary;
1327
+ this.connectedWalletConnectorMap.set(accountKey, _objectSpread(_objectSpread({}, connectedWallet), {}, {
1328
+ active: activeAccount ? connectedWallet.id === activeAccount.id : isPrimaryAccount
1329
+ }));
1330
+ }
1331
+ }
1332
+ getConnectedWalletConnectionByKey(accountKey) {
1333
+ const connectedWallet = this.getConnectedWalletConnectorStateByKey(accountKey);
1334
+ if (!connectedWallet) {
1335
+ return null;
1336
+ }
1337
+ if (!connectedWallet.signingProvider && !connectedWallet.solanaWallet) {
1338
+ throw new Error(`Connected connector "${connectedWallet.connector.name}" is not ready.`);
1339
+ }
1340
+ return this.buildConnectionFromConnectedWalletConnectorState(connectedWallet);
1341
+ }
1342
+ buildConnectionFromConnectedWalletConnectorState(connectedWallet) {
1343
+ var _connectedWallet$sola;
1344
+ return {
1345
+ ethereumProvider: connectedWallet.signingProvider,
1346
+ solanaWallet: (_connectedWallet$sola = connectedWallet.solanaWallet) !== null && _connectedWallet$sola !== void 0 ? _connectedWallet$sola : null,
1347
+ connectorName: connectedWallet.connector.name
1348
+ };
1349
+ }
1350
+ buildImmediateConnectedWalletConnectorState(params) {
1351
+ var _this$commonJRPCProvi;
1352
+ const {
1353
+ connector,
1354
+ ethereumProvider,
1355
+ solanaWallet,
1356
+ usePrimaryProxy,
1357
+ account
1358
+ } = params;
1359
+ const isSolanaOnly = connector.connectorNamespace === CHAIN_NAMESPACES.SOLANA;
1360
+ const connectedWallet = _objectSpread(_objectSpread({}, this.getConnectedWalletLinkedAccountInfo(account)), {}, {
1361
+ connector,
1362
+ signingProvider: isSolanaOnly ? null : ethereumProvider ? usePrimaryProxy ? (_this$commonJRPCProvi = this.commonJRPCProvider) !== null && _this$commonJRPCProvi !== void 0 ? _this$commonJRPCProvi : ethereumProvider : ethereumProvider : null,
1363
+ solanaWallet: solanaWallet !== null && solanaWallet !== void 0 ? solanaWallet : null,
1364
+ connected: connector.connected || connector.status === CONNECTOR_STATUS.CONNECTED || connector.status === CONNECTOR_STATUS.AUTHORIZED
1365
+ });
1366
+ return connectedWallet;
1367
+ }
1368
+ async resolveConnectedWalletConnectorState(params) {
1369
+ const {
1370
+ connector,
1371
+ ethereumProvider,
1372
+ solanaWallet,
1373
+ usePrimaryProxy,
1374
+ account
1375
+ } = params;
1376
+ return this.buildImmediateConnectedWalletConnectorState({
1377
+ connector,
1378
+ ethereumProvider,
1379
+ solanaWallet,
1380
+ usePrimaryProxy,
1381
+ account
1382
+ });
1383
+ }
1384
+ async linkAccountWithConnector(connectorName, chainId, walletConnector) {
1385
+ const authConnector = this.getMainAuthConnector();
1386
+ const result = await authConnector.linkAccount({
1387
+ connectorName,
1388
+ chainId,
1389
+ walletConnector,
1390
+ authSessionTokens: {
1391
+ accessToken: this.accessToken,
1392
+ idToken: this.idToken
1393
+ }
1394
+ });
1395
+ await this.setState({
1396
+ idToken: result.idToken
1397
+ });
1398
+ await this.cacheConnectedLinkedWalletConnector(authConnector, walletConnector);
1399
+ return result;
1400
+ }
1401
+ getMainAuthConnector() {
1402
+ if (!CONNECTED_STATUSES.includes(this.status) || !this.primaryConnector) {
1403
+ throw WalletLoginError.notConnectedError("No wallet is connected. Connect with AUTH before unlinking an account.");
1404
+ }
1405
+ const mainConnector = this.primaryConnector;
1406
+ assertAuthConnector(mainConnector, "Account linking is only supported when connected with the AUTH connector.");
1407
+ return mainConnector;
1408
+ }
1409
+
1410
+ /**
1411
+ * Processes the result of a switch account operation.
1412
+ *
1413
+ * - If the target account is a primary account, we will switch back to the primary account.
1414
+ * - If the target account is an external account and already connected (i.e. connector is available with connected state), we will just switch to it without re-connecting again.
1415
+ * - If the target account is an external account and not connected (i.e. connector is not available with connected state), we will create a new isolated connector and connect to it.
1416
+ * @param authConnector - The main auth connector to use.
1417
+ * @param switchResult - The result of the switch account operation.
1418
+ * @param options - The options for the switch account operation.
1419
+ * @returns A promise that resolves when the switch account operation is complete.
1420
+ */
1421
+ async processSwitchAccountResult(authConnector, switchResult, options = {}) {
1422
+ const resolvedSwitchChainId = this.resolveSwitchAccountChainId(switchResult.targetAccount, switchResult.activeChainId);
1423
+ if (switchResult.kind === "primary") {
1424
+ var _primaryConnectedWall, _this$commonJRPCProvi2, _switchResult$solanaW;
1425
+ const existingPrimaryConnectedWalletState = this.getConnectedWalletConnectorState();
1426
+ const primaryConnectedWalletState = existingPrimaryConnectedWalletState !== null && existingPrimaryConnectedWalletState !== void 0 ? existingPrimaryConnectedWalletState : await this.resolveConnectedWalletConnectorState({
1427
+ connector: authConnector,
1428
+ ethereumProvider: switchResult.ethereumProvider,
1429
+ solanaWallet: switchResult.solanaWallet,
1430
+ usePrimaryProxy: true,
1431
+ account: switchResult.targetAccount
1432
+ });
1433
+ this.setConnectedWalletConnectorState(_objectSpread(_objectSpread({}, primaryConnectedWalletState), {}, {
1434
+ connector: authConnector,
1435
+ signingProvider: (_primaryConnectedWall = primaryConnectedWalletState.signingProvider) !== null && _primaryConnectedWall !== void 0 ? _primaryConnectedWall : switchResult.ethereumProvider ? (_this$commonJRPCProvi2 = this.commonJRPCProvider) !== null && _this$commonJRPCProvi2 !== void 0 ? _this$commonJRPCProvi2 : switchResult.ethereumProvider : null,
1436
+ solanaWallet: (_switchResult$solanaW = switchResult.solanaWallet) !== null && _switchResult$solanaW !== void 0 ? _switchResult$solanaW : primaryConnectedWalletState.solanaWallet,
1437
+ connected: authConnector.connected || authConnector.status === CONNECTOR_STATUS.CONNECTED
1438
+ }));
1439
+ this.setActiveWalletConnectorKey();
1440
+ } else {
1441
+ var _ref5, _options$walletConnec;
1442
+ const walletConnector = (_ref5 = (_options$walletConnec = options.walletConnector) !== null && _options$walletConnec !== void 0 ? _options$walletConnec : this.getConnectedWalletConnector(switchResult.targetAccount)) !== null && _ref5 !== void 0 ? _ref5 : await this.createSwitchingWalletConnector(switchResult.targetAccount.connector, resolvedSwitchChainId, options.projectConfig);
1443
+ let linkedAccountConnection = null;
1444
+ try {
1445
+ var _ref6, _walletConnector$prov2, _linkedAccountConnect3, _ref7, _walletConnector$sola2, _linkedAccountConnect4;
1446
+ if (!this.hasUsableConnectedSwitchConnector(walletConnector)) {
1447
+ const switchChainConfig = this.coreOptions.chains.find(c => c.chainId === resolvedSwitchChainId);
1448
+ if (!switchChainConfig) {
1449
+ throw WalletLoginError.connectionError(`Chain config is not available for chain ${resolvedSwitchChainId}`);
1450
+ }
1451
+ const caipChainId = getCaipChainId(switchChainConfig);
1452
+ const caipAccountId = `${caipChainId}:${switchResult.targetAccount.eoaAddress}`;
1453
+ linkedAccountConnection = await walletConnector.connect({
1454
+ chainId: resolvedSwitchChainId,
1455
+ caipAccountIds: [caipAccountId]
1456
+ });
1457
+ if (!linkedAccountConnection) {
1458
+ throw AccountLinkingError.requestFailed(`Failed to connect isolated connector "${switchResult.targetAccount.connector}" for account switch.`);
1459
+ }
1460
+ }
1461
+ await authConnector.assertSwitchAccountConnectorMatchesTarget(walletConnector, switchResult.targetAccount);
1462
+ const connectedWalletState = await this.resolveConnectedWalletConnectorState({
1463
+ connector: walletConnector,
1464
+ ethereumProvider: (_ref6 = (_walletConnector$prov2 = walletConnector.provider) !== null && _walletConnector$prov2 !== void 0 ? _walletConnector$prov2 : (_linkedAccountConnect3 = linkedAccountConnection) === null || _linkedAccountConnect3 === void 0 ? void 0 : _linkedAccountConnect3.ethereumProvider) !== null && _ref6 !== void 0 ? _ref6 : null,
1465
+ solanaWallet: (_ref7 = (_walletConnector$sola2 = walletConnector.solanaWallet) !== null && _walletConnector$sola2 !== void 0 ? _walletConnector$sola2 : (_linkedAccountConnect4 = linkedAccountConnection) === null || _linkedAccountConnect4 === void 0 ? void 0 : _linkedAccountConnect4.solanaWallet) !== null && _ref7 !== void 0 ? _ref7 : null,
1466
+ usePrimaryProxy: false,
1467
+ account: switchResult.targetAccount
1468
+ });
1469
+ this.setConnectedWalletConnectorState(connectedWalletState, switchResult.targetAccount);
1470
+ this.setActiveWalletConnectorKey(switchResult.targetAccount);
1471
+ } catch (error) {
1472
+ throw authConnector.toSwitchAccountConnectorError(switchResult.targetAccount, error);
1473
+ }
1474
+ }
1475
+ await this.setCurrentChain(resolvedSwitchChainId);
1476
+ await this.setState({
1477
+ activeAccount: switchResult.activeAccount
1478
+ });
1479
+ this.syncConnectedWalletLinkedAccounts([switchResult.targetAccount]);
1480
+ this.refreshConnectedWalletActiveStates(switchResult.activeAccount);
1481
+ const connection = this.connection;
1482
+ if (!connection) {
1483
+ throw WalletLoginError.connectionError("Failed to resolve the active connection after switching accounts.");
1484
+ }
1485
+ this.emit(CONNECTOR_EVENTS.CONNECTION_UPDATED, {
1486
+ ethereumProvider: connection.ethereumProvider,
1487
+ solanaWallet: connection.solanaWallet,
1488
+ connectorName: connection.connectorName
1489
+ });
1490
+ }
1491
+ isActiveConnectorEventSource(connector) {
1492
+ if (!this.primaryConnectorName) return true;
1493
+ const activeConnector = this.primaryConnector;
1494
+ if (activeConnector) return activeConnector === connector;
1495
+ return connector.name === this.primaryConnectorName;
1496
+ }
1497
+ shouldIgnoreInactiveConnectorEvent(connector, event) {
1498
+ if (this.isActiveConnectorEventSource(connector)) return false;
1499
+ log.debug("Ignoring connector lifecycle event from inactive connector", {
1500
+ event,
1501
+ sourceConnector: connector.name,
1502
+ activeConnector: this.primaryConnectorName
1503
+ });
1504
+ return true;
1505
+ }
1506
+ findLinkedAccountByAddress(linkedAccounts, address) {
1507
+ var _linkedAccounts$find;
1508
+ const normalizedAddress = address.toLowerCase();
1509
+ return (_linkedAccounts$find = linkedAccounts.find(account => {
1510
+ var _account$address, _account$eoaAddress;
1511
+ if (!account.chainNamespace || parseChainNamespaceFromCitadelResponse(account.chainNamespace) !== CHAIN_NAMESPACES.EIP155) {
1512
+ return false;
1513
+ }
1514
+ return ((_account$address = account.address) === null || _account$address === void 0 ? void 0 : _account$address.toLowerCase()) === normalizedAddress || ((_account$eoaAddress = account.eoaAddress) === null || _account$eoaAddress === void 0 ? void 0 : _account$eoaAddress.toLowerCase()) === normalizedAddress;
1515
+ })) !== null && _linkedAccounts$find !== void 0 ? _linkedAccounts$find : null;
1516
+ }
1517
+ findLinkedAccountByWalletAddress(linkedAccounts, address) {
1518
+ var _linkedAccounts$find2;
1519
+ return (_linkedAccounts$find2 = linkedAccounts.find(account => {
1520
+ if (!account.chainNamespace) {
1521
+ return false;
1522
+ }
1523
+ const chainNamespace = parseChainNamespaceFromCitadelResponse(account.chainNamespace);
1524
+ if (chainNamespace === CHAIN_NAMESPACES.EIP155) {
1525
+ var _account$address2, _account$eoaAddress2;
1526
+ const normalizedAddress = address.toLowerCase();
1527
+ return ((_account$address2 = account.address) === null || _account$address2 === void 0 ? void 0 : _account$address2.toLowerCase()) === normalizedAddress || ((_account$eoaAddress2 = account.eoaAddress) === null || _account$eoaAddress2 === void 0 ? void 0 : _account$eoaAddress2.toLowerCase()) === normalizedAddress;
1528
+ }
1529
+ if (chainNamespace === CHAIN_NAMESPACES.SOLANA) {
1530
+ return account.address === address || account.eoaAddress === address;
1531
+ }
1532
+ return false;
1533
+ })) !== null && _linkedAccounts$find2 !== void 0 ? _linkedAccounts$find2 : null;
1534
+ }
1535
+ async getConnectedWalletAddress(connector) {
1536
+ var _connector$solanaWall2, _accounts$;
1537
+ const solanaAddress = (_connector$solanaWall2 = connector.solanaWallet) === null || _connector$solanaWall2 === void 0 || (_connector$solanaWall2 = _connector$solanaWall2.accounts) === null || _connector$solanaWall2 === void 0 || (_connector$solanaWall2 = _connector$solanaWall2[0]) === null || _connector$solanaWall2 === void 0 ? void 0 : _connector$solanaWall2.address;
1538
+ if (solanaAddress) {
1539
+ return solanaAddress;
1540
+ }
1541
+ if (!connector.provider) {
1542
+ return null;
1543
+ }
1544
+ const accounts = await connector.provider.request({
1545
+ method: "eth_accounts"
1546
+ });
1547
+ return (_accounts$ = accounts === null || accounts === void 0 ? void 0 : accounts[0]) !== null && _accounts$ !== void 0 ? _accounts$ : null;
1548
+ }
1549
+ async cacheConnectedLinkedWalletConnector(authConnector, walletConnector) {
1550
+ try {
1551
+ var _await$authConnector$2;
1552
+ const connectedWalletAddress = await this.getConnectedWalletAddress(walletConnector);
1553
+ if (!connectedWalletAddress) {
1554
+ return;
1555
+ }
1556
+ const linkedAccounts = (_await$authConnector$2 = await authConnector.getLinkedAccounts()) !== null && _await$authConnector$2 !== void 0 ? _await$authConnector$2 : [];
1557
+ const linkedAccount = this.findLinkedAccountByWalletAddress(linkedAccounts, connectedWalletAddress);
1558
+ if (linkedAccount && !linkedAccount.isPrimary) {
1559
+ const connectedWalletState = await this.resolveConnectedWalletConnectorState({
1560
+ connector: walletConnector,
1561
+ ethereumProvider: walletConnector.provider,
1562
+ solanaWallet: walletConnector.solanaWallet,
1563
+ usePrimaryProxy: false,
1564
+ account: linkedAccount
1565
+ });
1566
+ this.setConnectedWalletConnectorState(connectedWalletState, linkedAccount);
1567
+ }
1568
+ } catch (error) {
1569
+ log.debug("Failed to cache connected linked wallet connector", error);
1570
+ }
1571
+ }
1010
1572
  async cacheWallet(walletName) {
1011
1573
  await this.setState({
1012
1574
  cachedConnector: walletName
@@ -1023,11 +1585,11 @@ class Web3AuthNoModal extends SafeEventEmitter {
1023
1585
  connectToPlugins(data) {
1024
1586
  Object.values(this.plugins).map(async plugin => {
1025
1587
  try {
1026
- var _this$currentChain7;
1588
+ var _this$currentChain4;
1027
1589
  // skip if it's not compatible with the connector
1028
1590
  if (!plugin.SUPPORTED_CONNECTORS.includes(data.connector)) return;
1029
1591
  // skip if it's not compatible with the current chain
1030
- if (plugin.pluginNamespace !== PLUGIN_NAMESPACES.MULTICHAIN && plugin.pluginNamespace !== ((_this$currentChain7 = this.currentChain) === null || _this$currentChain7 === void 0 ? void 0 : _this$currentChain7.chainNamespace)) return;
1592
+ if (plugin.pluginNamespace !== PLUGIN_NAMESPACES.MULTICHAIN && plugin.pluginNamespace !== ((_this$currentChain4 = this.currentChain) === null || _this$currentChain4 === void 0 ? void 0 : _this$currentChain4.chainNamespace)) return;
1031
1593
  // skip if it's already connected
1032
1594
  if (plugin.status === PLUGIN_STATUS.CONNECTED) return;
1033
1595
  await plugin.initWithWeb3Auth(this, this.coreOptions.uiConfig, this.analytics);
@@ -1041,6 +1603,153 @@ class Web3AuthNoModal extends SafeEventEmitter {
1041
1603
  }
1042
1604
  });
1043
1605
  }
1606
+ async bindPrimaryEthereumSigningProxy(ethereumProvider, connectorName) {
1607
+ var _this$currentChain5, _accountAbstractionCo;
1608
+ if (!this.commonJRPCProvider) throw WalletInitializationError.notFound(`CommonJrpcProvider not found`);
1609
+ let finalProvider = (ethereumProvider === null || ethereumProvider === void 0 ? void 0 : ethereumProvider.provider) || ethereumProvider;
1610
+ const {
1611
+ accountAbstractionConfig
1612
+ } = this.coreOptions;
1613
+ const is7702 = (accountAbstractionConfig === null || accountAbstractionConfig === void 0 ? void 0 : accountAbstractionConfig.smartAccountEipStandard) === SMART_ACCOUNT_EIP_STANDARD["EIP_7702"];
1614
+ const isAaSupportedForCurrentChain = ((_this$currentChain5 = this.currentChain) === null || _this$currentChain5 === void 0 ? void 0 : _this$currentChain5.chainNamespace) === CHAIN_NAMESPACES.EIP155 && (accountAbstractionConfig === null || accountAbstractionConfig === void 0 || (_accountAbstractionCo = accountAbstractionConfig.chains) === null || _accountAbstractionCo === void 0 ? void 0 : _accountAbstractionCo.some(chain => {
1615
+ var _this$currentChain6;
1616
+ return chain.chainId === ((_this$currentChain6 = this.currentChain) === null || _this$currentChain6 === void 0 ? void 0 : _this$currentChain6.chainId);
1617
+ }));
1618
+
1619
+ // setup AA provider if AA is enabled (skip for EIP-7702; 7702 uses EOA + 5792/7702 RPC only)
1620
+ if (!is7702 && isAaSupportedForCurrentChain && (connectorName === WALLET_CONNECTORS.AUTH || this.coreOptions.useAAWithExternalWallet)) {
1621
+ var _accountAbstractionCo2;
1622
+ const {
1623
+ accountAbstractionProvider,
1624
+ toEoaProvider
1625
+ } = await import('./providers/account-abstraction-provider/index.js');
1626
+ const eoaProvider = connectorName === WALLET_CONNECTORS.AUTH ? await toEoaProvider(ethereumProvider) : ethereumProvider;
1627
+ const aaChainIds = new Set((accountAbstractionConfig === null || accountAbstractionConfig === void 0 || (_accountAbstractionCo2 = accountAbstractionConfig.chains) === null || _accountAbstractionCo2 === void 0 ? void 0 : _accountAbstractionCo2.map(chain => chain.chainId)) || []);
1628
+ const aaProvider = await accountAbstractionProvider({
1629
+ accountAbstractionConfig,
1630
+ provider: eoaProvider,
1631
+ chain: this.currentChain,
1632
+ chains: this.coreOptions.chains.filter(chain => aaChainIds.has(chain.chainId)),
1633
+ useProviderAsTransport: connectorName === WALLET_CONNECTORS.AUTH
1634
+ });
1635
+ this.aaProvider = aaProvider;
1636
+ if (connectorName !== WALLET_CONNECTORS.AUTH && this.coreOptions.useAAWithExternalWallet) {
1637
+ finalProvider = this.aaProvider;
1638
+ }
1639
+ }
1640
+ this.commonJRPCProvider.updateProviderEngineProxy(finalProvider);
1641
+ }
1642
+ getChainConfigForIsolatedConnector(chainId) {
1643
+ const chainConfig = this.coreOptions.chains.find(chain => chain.chainId === chainId);
1644
+ if (!chainConfig) {
1645
+ throw WalletInitializationError.invalidParams(`Chain config is not available for chain ${chainId}`);
1646
+ }
1647
+ return chainConfig;
1648
+ }
1649
+ async resolveInstalledDiscoveredWalletConnector(params) {
1650
+ const {
1651
+ connectorName,
1652
+ chainConfig,
1653
+ config,
1654
+ isMipdEnabled
1655
+ } = params;
1656
+ if (!isBrowser() || !isMipdEnabled) return null;
1657
+ if (chainConfig.chainNamespace === CHAIN_NAMESPACES.EIP155) {
1658
+ const {
1659
+ createMipd,
1660
+ injectedEvmConnector
1661
+ } = await import('./connectors/injected-evm-connector/index.js');
1662
+ const providerDetail = createMipd().getProviders().find(detail => normalizeWalletName(detail.info.name) === connectorName);
1663
+ if (providerDetail) {
1664
+ return injectedEvmConnector(providerDetail)(config);
1665
+ }
1666
+ return null;
1667
+ }
1668
+ if (chainConfig.chainNamespace === CHAIN_NAMESPACES.SOLANA) {
1669
+ const {
1670
+ createSolanaMipd,
1671
+ hasSolanaWalletStandardFeatures,
1672
+ walletStandardConnector
1673
+ } = await import('./connectors/injected-solana-connector/index.js');
1674
+ const wallet = createSolanaMipd().get().find(candidate => hasSolanaWalletStandardFeatures(candidate) && normalizeWalletName(candidate.name) === connectorName);
1675
+ if (wallet) {
1676
+ return walletStandardConnector(wallet)(config);
1677
+ }
1678
+ }
1679
+ return null;
1680
+ }
1681
+ async resolveDiscoveredWalletConnector(connectorName, chainId, config, effectiveProjectConfig) {
1682
+ var _this$coreOptions$mul2;
1683
+ const chainConfig = this.getChainConfigForIsolatedConnector(chainId);
1684
+ const isExternalWalletEnabled = Boolean(effectiveProjectConfig === null || effectiveProjectConfig === void 0 ? void 0 : effectiveProjectConfig.externalWalletAuth);
1685
+ const isMipdEnabled = isExternalWalletEnabled && ((_this$coreOptions$mul2 = this.coreOptions.multiInjectedProviderDiscovery) !== null && _this$coreOptions$mul2 !== void 0 ? _this$coreOptions$mul2 : true);
1686
+ const installedConnector = await this.resolveInstalledDiscoveredWalletConnector({
1687
+ connectorName,
1688
+ chainConfig,
1689
+ config,
1690
+ isMipdEnabled
1691
+ });
1692
+ if (installedConnector) {
1693
+ return installedConnector;
1694
+ }
1695
+ const isBuiltInConnectorName = Object.values(WALLET_CONNECTORS).includes(connectorName);
1696
+ const supportsWalletConnectFallback = chainConfig.chainNamespace === CHAIN_NAMESPACES.EIP155 || chainConfig.chainNamespace === CHAIN_NAMESPACES.SOLANA;
1697
+
1698
+ // Named discovered wallets (for example Phantom) can reuse WalletConnect as a transport fallback
1699
+ // when an injected connector for the target chain namespace is unavailable.
1700
+ if (!isBuiltInConnectorName && isExternalWalletEnabled && supportsWalletConnectFallback) {
1701
+ const {
1702
+ walletConnectV2Connector
1703
+ } = await import('./connectors/wallet-connect-v2-connector/index.js');
1704
+ return walletConnectV2Connector()(config);
1705
+ }
1706
+ throw AccountLinkingError.unsupportedConnector(`Connector "${connectorName}" does not support automatic wallet linking. ` + `Use ${WALLET_CONNECTORS.METAMASK}, ${WALLET_CONNECTORS.WALLET_CONNECT_V2}, or an installed compatible wallet.`);
1707
+ }
1708
+
1709
+ /**
1710
+ * Create a new connector instance that is NOT registered in this.connectors and NOT
1711
+ * subscribed to the main SDK event loop. Its lifecycle events are therefore isolated
1712
+ * and will not mutate any global SDK state (connectedConnectorName, connection, idToken).
1713
+ */
1714
+ async createIsolatedWalletConnector(connectorName, chainId, projectConfig) {
1715
+ var _ref8;
1716
+ const effectiveProjectConfig = (_ref8 = projectConfig !== null && projectConfig !== void 0 ? projectConfig : this.projectConfig) !== null && _ref8 !== void 0 ? _ref8 : undefined;
1717
+ const config = {
1718
+ projectConfig: effectiveProjectConfig,
1719
+ coreOptions: this.coreOptions,
1720
+ analytics: this.analytics
1721
+ };
1722
+ let connector;
1723
+ switch (connectorName) {
1724
+ case WALLET_CONNECTORS.METAMASK:
1725
+ connector = metaMaskConnector()(config);
1726
+ break;
1727
+ case WALLET_CONNECTORS.WALLET_CONNECT_V2:
1728
+ {
1729
+ const {
1730
+ walletConnectV2Connector
1731
+ } = await import('./connectors/wallet-connect-v2-connector/index.js');
1732
+ connector = walletConnectV2Connector()(config);
1733
+ break;
1734
+ }
1735
+ case WALLET_CONNECTORS.AUTH:
1736
+ throw AccountLinkingError.unsupportedConnector(`Connector "${connectorName}" does not support automatic wallet linking.`);
1737
+ default:
1738
+ {
1739
+ connector = await this.resolveDiscoveredWalletConnector(connectorName, chainId, config, effectiveProjectConfig);
1740
+ break;
1741
+ }
1742
+ }
1743
+
1744
+ // Init the isolated connector WITHOUT subscribing to the main event loop.
1745
+ // This is the key difference from setupConnector(), which calls subscribeToConnectorEvents().
1746
+ // autoConnect: false ensures the connector does not attempt to rehydrate a previous session.
1747
+ await connector.init({
1748
+ chainId,
1749
+ autoConnect: false
1750
+ });
1751
+ return connector;
1752
+ }
1044
1753
  async setState(newState) {
1045
1754
  this.state = _objectSpread(_objectSpread({}, this.state), newState);
1046
1755
  await this.storage.set(WEB3AUTH_STATE_STORAGE_KEY, JSON.stringify(this.state));