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