@web3auth/no-modal 11.0.0-beta.2 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/lib.cjs/account-linking/errors.js +111 -0
  2. package/dist/lib.cjs/account-linking/index.js +4 -0
  3. package/dist/lib.cjs/account-linking/rest.js +6 -6
  4. package/dist/lib.cjs/account-linking/vue.js +0 -1
  5. package/dist/lib.cjs/base/connector/constants.js +2 -0
  6. package/dist/lib.cjs/base/errors/index.js +21 -50
  7. package/dist/lib.cjs/base/utils.js +1 -1
  8. package/dist/lib.cjs/connectors/auth-connector/authConnector.js +47 -34
  9. package/dist/lib.cjs/connectors/metamask-connector/metamaskConnector.js +40 -31
  10. package/dist/lib.cjs/index.js +21 -16
  11. package/dist/lib.cjs/noModal.js +29 -11
  12. package/dist/lib.cjs/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +8 -4
  13. package/dist/lib.cjs/providers/account-abstraction-provider/providers/utils.js +0 -17
  14. package/dist/lib.cjs/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +15 -0
  15. package/dist/lib.cjs/react/context/useWeb3AuthInnerContextValue.js +11 -4
  16. package/dist/lib.cjs/react/wagmi/index.js +6 -0
  17. package/dist/lib.cjs/react/wagmi/provider.js +60 -41
  18. package/dist/lib.cjs/types/account-linking/errors.d.ts +17 -0
  19. package/dist/lib.cjs/types/account-linking/index.d.ts +1 -0
  20. package/dist/lib.cjs/types/base/connector/constants.d.ts +1 -0
  21. package/dist/lib.cjs/types/base/connector/interfaces.d.ts +1 -1
  22. package/dist/lib.cjs/types/base/errors/index.d.ts +2 -13
  23. package/dist/lib.cjs/types/connectors/auth-connector/authConnector.d.ts +2 -2
  24. package/dist/lib.cjs/types/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.d.ts +1 -0
  25. package/dist/lib.cjs/types/react/wagmi/constants.d.ts +2 -0
  26. package/dist/lib.cjs/types/react/wagmi/provider.d.ts +7 -0
  27. package/dist/lib.cjs/types/vue/wagmi/constants.d.ts +2 -0
  28. package/dist/lib.cjs/types/vue/wagmi/provider.d.ts +7 -1
  29. package/dist/lib.cjs/vue/useWeb3AuthInnerContextValue.js +13 -6
  30. package/dist/lib.cjs/vue/wagmi/index.js +6 -0
  31. package/dist/lib.cjs/vue/wagmi/provider.js +53 -26
  32. package/dist/lib.esm/account-linking/errors.js +92 -0
  33. package/dist/lib.esm/account-linking/index.js +1 -0
  34. package/dist/lib.esm/account-linking/rest.js +3 -3
  35. package/dist/lib.esm/account-linking/vue.js +0 -1
  36. package/dist/lib.esm/base/connector/constants.js +2 -1
  37. package/dist/lib.esm/base/errors/index.js +21 -50
  38. package/dist/lib.esm/base/utils.js +1 -1
  39. package/dist/lib.esm/connectors/auth-connector/authConnector.js +29 -15
  40. package/dist/lib.esm/connectors/base-solana-connector/baseSolanaConnector.js +1 -1
  41. package/dist/lib.esm/connectors/metamask-connector/metamaskConnector.js +42 -33
  42. package/dist/lib.esm/index.js +3 -2
  43. package/dist/lib.esm/noModal.js +25 -5
  44. package/dist/lib.esm/providers/account-abstraction-provider/providers/AccountAbstractionProvider.js +10 -5
  45. package/dist/lib.esm/providers/account-abstraction-provider/providers/utils.js +0 -3
  46. package/dist/lib.esm/providers/account-abstraction-provider/rpc/ethRpcMiddlewares.js +17 -3
  47. package/dist/lib.esm/react/context/useWeb3AuthInnerContextValue.js +11 -4
  48. package/dist/lib.esm/react/wagmi/index.js +1 -1
  49. package/dist/lib.esm/react/wagmi/provider.js +59 -42
  50. package/dist/lib.esm/vue/useWeb3AuthInnerContextValue.js +11 -4
  51. package/dist/lib.esm/vue/wagmi/index.js +1 -1
  52. package/dist/lib.esm/vue/wagmi/provider.js +48 -25
  53. package/package.json +19 -19
@@ -12,11 +12,11 @@ import { getSiteName } from '../utils.js';
12
12
  import { CONNECTOR_NAMESPACES } from '../../base/chain/IChainInterface.js';
13
13
  import { WALLET_CONNECTORS } from '../../base/wallet/index.js';
14
14
  import { getCaipChainId, citadelServerUrl } from '../../base/utils.js';
15
- import { WalletLoginError, Web3AuthError } from '../../base/errors/index.js';
15
+ import { WalletLoginError, isUserRejectedError, WalletOperationsError, Web3AuthError } from '../../base/errors/index.js';
16
16
  import { ANALYTICS_EVENTS } from '../../base/analytics.js';
17
+ import { getSolanaChainByChainConfig, walletSignMessage } from '../../base/wallet/solana.js';
17
18
  import { BaseConnector } from '../../base/connector/baseConnector.js';
18
19
  import { CONNECTOR_CATEGORY, CONNECTOR_STATUS, CONNECTOR_EVENTS } from '../../base/connector/constants.js';
19
- import { getSolanaChainByChainConfig, walletSignMessage } from '../../base/wallet/solana.js';
20
20
 
21
21
  /**
22
22
  * Configuration options for the MetaMask connector using \@metamask/connect-evm
@@ -113,7 +113,11 @@ class MetaMaskConnector extends BaseConnector {
113
113
  supportedNetworks: caipSupportedNetworks
114
114
  },
115
115
  ui,
116
- debug: (_this$connectorSettin0 = this.connectorSettings) === null || _this$connectorSettin0 === void 0 ? void 0 : _this$connectorSettin0.debug
116
+ debug: (_this$connectorSettin0 = this.connectorSettings) === null || _this$connectorSettin0 === void 0 ? void 0 : _this$connectorSettin0.debug,
117
+ analytics: {
118
+ integrationType: "web3auth",
119
+ enabled: !this.coreOptions.disableAnalytics
120
+ }
117
121
  });
118
122
 
119
123
  // Listen for QR code URI from the multichain client (for mobile wallet connection)
@@ -133,19 +137,27 @@ class MetaMaskConnector extends BaseConnector {
133
137
  dapp,
134
138
  eventHandlers: {
135
139
  accountsChanged: _accounts => {
136
- if (_accounts.length === 0) {
140
+ if (_accounts.length === 0 && this.connected) {
137
141
  this.disconnect();
138
142
  }
139
143
  },
140
144
  chainChanged: _chainId => {},
141
145
  connect: _result => {},
142
- disconnect: () => this.disconnect()
146
+ disconnect: () => {
147
+ if (this.connected) {
148
+ this.disconnect();
149
+ }
150
+ }
143
151
  },
144
152
  api: {
145
153
  supportedNetworks: hexSupportedNetworks
146
154
  },
147
155
  ui,
148
- debug: (_this$connectorSettin1 = this.connectorSettings) === null || _this$connectorSettin1 === void 0 ? void 0 : _this$connectorSettin1.debug
156
+ debug: (_this$connectorSettin1 = this.connectorSettings) === null || _this$connectorSettin1 === void 0 ? void 0 : _this$connectorSettin1.debug,
157
+ analytics: {
158
+ integrationType: "web3auth",
159
+ enabled: !this.coreOptions.disableAnalytics
160
+ }
149
161
  });
150
162
  this.evmProvider = this.evmClient.getProvider();
151
163
  }
@@ -157,7 +169,11 @@ class MetaMaskConnector extends BaseConnector {
157
169
  api: {
158
170
  supportedNetworks: solanaSupportedNetworks
159
171
  },
160
- skipAutoRegister: true
172
+ skipAutoRegister: true,
173
+ analytics: {
174
+ integrationType: "web3auth",
175
+ enabled: !this.coreOptions.disableAnalytics
176
+ }
161
177
  });
162
178
  this.solanaProvider = this.solanaClient.getWallet();
163
179
  }
@@ -172,32 +188,20 @@ class MetaMaskConnector extends BaseConnector {
172
188
  return;
173
189
  }
174
190
  const coreStatus = this.multichainClient.status;
175
- if (coreStatus === "connected") {
191
+ // only connect if the multichain client is connected and autoConnect is true (i.e during the rehydration)
192
+ if (coreStatus === "connected" && options.autoConnect) {
176
193
  this.status = CONNECTOR_STATUS.CONNECTED;
177
194
  this.rehydrated = true;
178
- if (options.autoConnect) {
179
- this.emit(CONNECTOR_EVENTS.CONNECTED, {
180
- connectorName: WALLET_CONNECTORS.METAMASK,
181
- reconnected: this.rehydrated,
182
- ethereumProvider: this.evmProvider,
183
- solanaWallet: this.solanaProvider
184
- });
185
- if (options.getAuthTokenInfo) {
186
- await this.getAuthTokenInfo();
187
- }
188
- }
189
- } else if (coreStatus === "loaded" || coreStatus === "disconnected") {
190
- this.status = CONNECTOR_STATUS.READY;
191
- this.emit(CONNECTOR_EVENTS.READY, WALLET_CONNECTORS.METAMASK);
192
- } else if (coreStatus === "pending") {
193
- // 'pending' implies that a transport failed to resume the connection
194
- // if (options.autoConnect) {
195
- // this.rehydrated = false;
196
- // this.emit(CONNECTOR_EVENTS.REHYDRATION_ERROR, new Error("Failed to resume existing MetaMask Connect session.") as Web3AuthError);
197
- // } else {
195
+ this.emit(CONNECTOR_EVENTS.CONNECTED, {
196
+ connectorName: WALLET_CONNECTORS.METAMASK,
197
+ reconnected: true,
198
+ ethereumProvider: this.evmProvider,
199
+ solanaWallet: this.solanaProvider
200
+ });
201
+ if (options.getAuthTokenInfo) await this.getAuthTokenInfo();
202
+ } else if (coreStatus === "connected" || coreStatus === "loaded" || coreStatus === "disconnected" || coreStatus === "pending") {
198
203
  this.status = CONNECTOR_STATUS.READY;
199
204
  this.emit(CONNECTOR_EVENTS.READY, WALLET_CONNECTORS.METAMASK);
200
- // }
201
205
  } else {
202
206
  // Something unexpected happened
203
207
  this.status = CONNECTOR_STATUS.ERRORED;
@@ -234,11 +238,15 @@ class MetaMaskConnector extends BaseConnector {
234
238
  connector: WALLET_CONNECTORS.METAMASK
235
239
  });
236
240
  const evmConnectedPromise = new Promise(resolve => {
237
- var _this$evmProvider;
238
- // Wait for EVM provider to be ready
239
- (_this$evmProvider = this.evmProvider) === null || _this$evmProvider === void 0 || _this$evmProvider.once("connect", () => {
241
+ if (this.evmClient.status === "connected") {
240
242
  resolve();
241
- });
243
+ } else {
244
+ var _this$evmProvider;
245
+ // Wait for EVM provider to be ready
246
+ (_this$evmProvider = this.evmProvider) === null || _this$evmProvider === void 0 || _this$evmProvider.once("connect", () => {
247
+ resolve();
248
+ });
249
+ }
242
250
  });
243
251
 
244
252
  // Connect using the multichain client
@@ -308,6 +316,7 @@ class MetaMaskConnector extends BaseConnector {
308
316
  duration: Date.now() - startTime
309
317
  }));
310
318
  }
319
+ if (isUserRejectedError(error)) throw WalletOperationsError.userRejected();
311
320
  if (error instanceof Web3AuthError) throw error;
312
321
  throw WalletLoginError.connectionError("Failed to login with MetaMask wallet", error);
313
322
  }
@@ -1,7 +1,7 @@
1
1
  export { Web3AuthNoModal } from './noModal.js';
2
2
  export { ANALYTICS_EVENTS, ANALYTICS_INTEGRATION_TYPE, ANALYTICS_SDK_TYPE, Analytics } from './base/analytics.js';
3
3
  export { AUTH_CONNECTION, MFA_FACTOR, MFA_LEVELS, UX_MODE, WEB3AUTH_NETWORK, getED25519Key } from '@web3auth/auth';
4
- export { AccountLinkingError, WalletInitializationError, WalletLoginError, WalletOperationsError, WalletProviderError, Web3AuthError } from './base/errors/index.js';
4
+ export { AccountLinkingError, formatAccountLinkingErrorMessage, getAccountLinkingRequestError } from './account-linking/errors.js';
5
5
  export { BUTTON_POSITION, CONFIRMATION_STRATEGY } from '@web3auth/ws-embed';
6
6
  export { BaseConnector } from './base/connector/baseConnector.js';
7
7
  export { BaseEvmConnector } from './connectors/base-evm-connector/baseEvmConnector.js';
@@ -10,7 +10,7 @@ export { BaseSolanaConnector } from './connectors/base-solana-connector/baseSola
10
10
  export { BiconomySmartAccount, KernelSmartAccount, MetamaskSmartAccount, NexusSmartAccount, SMART_ACCOUNT, SafeSmartAccount, TrustSmartAccount } from '@toruslabs/ethereum-controllers';
11
11
  export { CAN_AUTHORIZE_STATUSES, CAN_LOGOUT_STATUSES, CONNECTED_STATUSES } from './base/connector/connectorStatus.js';
12
12
  export { CHAIN_NAMESPACES, cloneDeep } from '@toruslabs/base-controllers';
13
- export { CONNECTOR_CATEGORY, CONNECTOR_EVENTS, CONNECTOR_INITIAL_AUTHENTICATION_MODE, CONNECTOR_STATUS } from './base/connector/constants.js';
13
+ export { CONNECTOR_CATEGORY, CONNECTOR_EVENTS, CONNECTOR_INITIAL_AUTHENTICATION_MODE, CONNECTOR_STATUS, WEB3AUTH_CONNECTOR_ID } from './base/connector/constants.js';
14
14
  export { CONNECTOR_NAMES, EVM_CONNECTORS, MULTI_CHAIN_CONNECTORS, SOLANA_CONNECTORS, WALLET_CONNECTORS, WEB3AUTH_ICON } from './base/wallet/index.js';
15
15
  export { CONNECTOR_NAMESPACES } from './base/chain/IChainInterface.js';
16
16
  export { CommonJRPCProvider } from './providers/base-provider/CommonJRPCProvider.js';
@@ -21,6 +21,7 @@ export { EIP_7702_SUPPORTED_SMART_ACCOUNTS, LOGIN_MODE, MODAL_SIGN_IN_METHODS, S
21
21
  export { EVM_PLUGINS, PLUGIN_EVENTS, PLUGIN_NAMESPACES, PLUGIN_STATUS, SOLANA_PLUGINS, WALLET_PLUGINS } from './base/plugin/IPlugin.js';
22
22
  export { PROVIDER_EVENTS } from './base/provider/IProvider.js';
23
23
  export { WalletConnectV2Provider } from './connectors/wallet-connect-v2-connector/WalletConnectV2Provider.js';
24
+ export { WalletInitializationError, WalletLoginError, WalletOperationsError, WalletProviderError, Web3AuthError, isUserRejectedError } from './base/errors/index.js';
24
25
  export { WalletServicesPluginError } from './base/plugin/errors.js';
25
26
  export { Web3AuthContextKey } from './base/composables/index.js';
26
27
  export { accountAbstractionProvider, toEoaProvider } from './providers/account-abstraction-provider/providers/AccountAbstractionProvider.js';
@@ -3,11 +3,11 @@ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import { CHAIN_NAMESPACES, BUTTON_POSITION, CONFIRMATION_STRATEGY } from '@toruslabs/base-controllers';
5
5
  import { SMART_ACCOUNT_EIP_STANDARD, EIP7702_SUPPORTED_SMART_ACCOUNT_TYPES } from '@toruslabs/ethereum-controllers';
6
- import { SafeEventEmitter, serializeError, UX_MODE, cloneDeep, CookieStorage, LocalStorageAdapter, MemoryStorage } from '@web3auth/auth';
6
+ import { SafeEventEmitter, BUILD_ENV, 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';
10
9
  import { LOGIN_MODE, SMART_ACCOUNT_WALLET_SCOPE, WEB3AUTH_STATE_STORAGE_KEY } from './base/constants.js';
10
+ import { WalletInitializationError, WalletLoginError } from './base/errors/index.js';
11
11
  import { log } from './base/loglevel.js';
12
12
  import { CONNECTOR_STATUS, CONNECTOR_INITIAL_AUTHENTICATION_MODE, CONNECTOR_EVENTS } from './base/connector/constants.js';
13
13
  import { Analytics, ANALYTICS_INTEGRATION_TYPE, ANALYTICS_SDK_TYPE, ANALYTICS_EVENTS } from './base/analytics.js';
@@ -16,6 +16,7 @@ import { WALLET_CONNECTORS } from './base/wallet/index.js';
16
16
  import { CONNECTOR_NAMESPACES } from './base/chain/IChainInterface.js';
17
17
  import { CONNECTED_STATUSES, CAN_LOGOUT_STATUSES, CAN_AUTHORIZE_STATUSES } from './base/connector/connectorStatus.js';
18
18
  import { assertAuthConnector, authConnector, isAuthConnector } from './connectors/auth-connector/authConnector.js';
19
+ import { AccountLinkingError } from './account-linking/errors.js';
19
20
  import { CommonJRPCProvider } from './providers/base-provider/CommonJRPCProvider.js';
20
21
  import { walletServicesPlugin } from './plugins/wallet-services-plugin/plugin.js';
21
22
  import { metaMaskConnector } from './connectors/metamask-connector/metamaskConnector.js';
@@ -54,7 +55,9 @@ class Web3AuthNoModal extends SafeEventEmitter {
54
55
  if (!options.clientId) throw WalletInitializationError.invalidParams("Please provide a valid clientId in constructor");
55
56
  if (options.enableLogging) log.enableAll();else log.setLevel("error");
56
57
  if (!options.initialAuthenticationMode) options.initialAuthenticationMode = CONNECTOR_INITIAL_AUTHENTICATION_MODE.CONNECT_AND_SIGN;
57
- this.coreOptions = options;
58
+ this.coreOptions = _objectSpread(_objectSpread({}, options), {}, {
59
+ authBuildEnv: options.authBuildEnv || BUILD_ENV.PRODUCTION
60
+ });
58
61
  this.storage = this.getStorageMethod();
59
62
  this.analytics = new Analytics();
60
63
  if (options.disableAnalytics) {
@@ -952,7 +955,8 @@ class Web3AuthNoModal extends SafeEventEmitter {
952
955
  activeAccount,
953
956
  currentChainId
954
957
  } = 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
958
+ let rehydrateWithLinkedAccount = false;
959
+ // for rehydration, if the active account is not the primary account, i.e. not `null`, create an isolated connector and connect to the chain
956
960
  if (activeAccount && !activeAccount.isPrimary && activeAccount.connector !== WALLET_CONNECTORS.AUTH) {
957
961
  var _ref3, _walletConnector$prov, _linkedAccountConnect, _ref4, _walletConnector$sola, _linkedAccountConnect2;
958
962
  const accountLinkingConnector = isAuthConnector(connector) ? connector : this.getConnector(WALLET_CONNECTORS.AUTH);
@@ -977,6 +981,7 @@ class Web3AuthNoModal extends SafeEventEmitter {
977
981
  });
978
982
  this.setConnectedWalletConnectorState(connectedWalletState, activeAccount);
979
983
  this.setActiveWalletConnectorKey(activeAccount);
984
+ rehydrateWithLinkedAccount = true;
980
985
  }
981
986
  if (ethereumProvider) {
982
987
  await this.bindPrimaryEthereumSigningProxy(ethereumProvider, data.connectorName);
@@ -1014,12 +1019,19 @@ class Web3AuthNoModal extends SafeEventEmitter {
1014
1019
  connector: data.connectorName
1015
1020
  }));
1016
1021
  }
1022
+
1017
1023
  // `pendingUserConsent` signals listeners (LoginModal, React/Vue contexts) to skip processing this CONNECTED event,
1018
1024
  // so the upcoming AUTHORIZED -> CONSENT_REQUIRING transition is not overridden by a late CONNECTED handler in CONNECT_AND_SIGN mode.
1019
1025
  this.emit(CONNECTOR_EVENTS.CONNECTED, _objectSpread(_objectSpread({}, data), {}, {
1020
1026
  loginMode: this.loginMode,
1021
1027
  pendingUserConsent
1022
1028
  }));
1029
+
1030
+ // if we're rehydrating with a linked account, we need to emit a CONNECTION_UPDATED event
1031
+ // so that upstream listeners and context are updated with the linked connection.
1032
+ if (rehydrateWithLinkedAccount) {
1033
+ this.emit(CONNECTOR_EVENTS.CONNECTION_UPDATED, this.connection);
1034
+ }
1023
1035
  }
1024
1036
  });
1025
1037
  connector.on(CONNECTOR_EVENTS.DISCONNECTED, async data => {
@@ -1239,7 +1251,15 @@ class Web3AuthNoModal extends SafeEventEmitter {
1239
1251
  return activeChainId;
1240
1252
  }
1241
1253
  async createLinkingWalletConnector(connectorName, chainId, config) {
1242
- return this.createIsolatedWalletConnector(connectorName, chainId, config);
1254
+ try {
1255
+ const linkingConnector = await this.createIsolatedWalletConnector(connectorName, chainId, config);
1256
+ return linkingConnector;
1257
+ } catch (error) {
1258
+ if (error instanceof AccountLinkingError && error.code === 5405) {
1259
+ throw error;
1260
+ }
1261
+ throw AccountLinkingError.walletProofFailed(error instanceof Error ? error.message : String(error), error);
1262
+ }
1243
1263
  }
1244
1264
  async createSwitchingWalletConnector(connectorName, chainId, config) {
1245
1265
  return this.createIsolatedWalletConnector(connectorName, chainId, config);
@@ -5,7 +5,7 @@ export { SMART_ACCOUNT } from '@toruslabs/ethereum-controllers';
5
5
  import { JRPCEngineV2, providerFromEngineV2, providerErrors } from '@web3auth/auth';
6
6
  import { defineChain, createPublicClient, http, createWalletClient, custom } from 'viem';
7
7
  import { createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
8
- import { createEoaMiddleware, providerAsMiddleware, createAaMiddleware } from '../rpc/ethRpcMiddlewares.js';
8
+ import { createEoaMiddleware, providerAsMiddleware, createAaMiddleware, createEip7702And5792MiddlewareForAaProvider } from '../rpc/ethRpcMiddlewares.js';
9
9
  import { getProviderHandlers } from './utils.js';
10
10
  import { BaseProvider } from '../../base-provider/baseProvider.js';
11
11
  import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
@@ -55,9 +55,10 @@ class AccountAbstractionProvider extends BaseProvider {
55
55
  }
56
56
  async setupProvider(eoaProvider) {
57
57
  var _bundlerConfig$transp;
58
- const {
59
- currentChain
60
- } = this;
58
+ const currentChain = this.currentChain;
59
+ if (!currentChain) {
60
+ throw WalletInitializationError.invalidProviderConfigError(`AA chain config not found for chain ${this.chainId}`);
61
+ }
61
62
  const {
62
63
  chainNamespace
63
64
  } = currentChain;
@@ -134,9 +135,13 @@ class AccountAbstractionProvider extends BaseProvider {
134
135
  eoaProvider,
135
136
  handlers: providerHandlers
136
137
  });
138
+
139
+ // middleware to handle EIP-7702 and EIP-5792 methods,
140
+ // currently, we do not support EIP-7702 and EIP-5792 methods for account abstraction provider
141
+ const eip7702And5792Middleware = await createEip7702And5792MiddlewareForAaProvider();
137
142
  const eoaMiddleware = providerAsMiddleware(eoaProvider);
138
143
  const engine = JRPCEngineV2.create({
139
- middleware: [aaMiddleware, eoaMiddleware]
144
+ middleware: [aaMiddleware, eip7702And5792Middleware, eoaMiddleware]
140
145
  });
141
146
  const provider = providerFromEngineV2(engine);
142
147
  this.updateProviderEngineProxy(provider);
@@ -2,7 +2,6 @@ import _objectSpread from '@babel/runtime/helpers/objectSpread2';
2
2
  import { isHexString, add0x } from '@toruslabs/metadata-helpers';
3
3
  import { providerErrors } from '@web3auth/auth';
4
4
  import { createWalletClient, http } from 'viem';
5
- import { log } from '../../../base/loglevel.js';
6
5
 
7
6
  function getProviderHandlers({
8
7
  bundlerClient,
@@ -20,8 +19,6 @@ function getProviderHandlers({
20
19
  const [smartAccounts, eoaAccounts] = await Promise.all([smartAccount.getAddress(), eoaProvider.request({
21
20
  method: "eth_accounts"
22
21
  })]);
23
- log.info("smartAccounts", smartAccounts);
24
- log.info("eoaAccounts", eoaAccounts);
25
22
  return [smartAccounts, ...eoaAccounts];
26
23
  },
27
24
  getPrivateKey: async _ => {
@@ -1,6 +1,6 @@
1
1
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
2
- import { METHOD_TYPES } from '@toruslabs/ethereum-controllers';
3
- import { createScaffoldMiddlewareV2, rpcErrors } from '@web3auth/auth';
2
+ import { METHOD_TYPES, EIP_5792_METHODS, EIP_7702_METHODS } from '@toruslabs/ethereum-controllers';
3
+ import { createScaffoldMiddlewareV2, providerErrors, rpcErrors } from '@web3auth/auth';
4
4
 
5
5
  async function createAaMiddleware({
6
6
  eoaProvider,
@@ -181,6 +181,20 @@ async function createEoaMiddleware({
181
181
  eth_requestAccounts: requestAccounts
182
182
  });
183
183
  }
184
+ async function createEip7702And5792MiddlewareForAaProvider() {
185
+ const eip5792Methods = Object.values(EIP_5792_METHODS);
186
+ const eip7702Methods = Object.values(EIP_7702_METHODS);
187
+ const eip7702And5792Methods = [...eip5792Methods, ...eip7702Methods];
188
+ return async ({
189
+ request,
190
+ next
191
+ }) => {
192
+ if (eip7702And5792Methods.includes(request.method)) {
193
+ throw providerErrors.unsupportedMethod(`${request.method} is not supported for account abstraction provider`);
194
+ }
195
+ return next(request);
196
+ };
197
+ }
184
198
  function providerAsMiddleware(provider) {
185
199
  return async ({
186
200
  request
@@ -192,4 +206,4 @@ function providerAsMiddleware(provider) {
192
206
  };
193
207
  }
194
208
 
195
- export { createAaMiddleware, createEoaMiddleware, providerAsMiddleware };
209
+ export { createAaMiddleware, createEip7702And5792MiddlewareForAaProvider, createEoaMiddleware, providerAsMiddleware };
@@ -127,19 +127,26 @@ function useWeb3AuthInnerContextValue({
127
127
  const authorizedListener = () => {
128
128
  setStatus(web3Auth.status);
129
129
  if (web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
130
+ var _web3Auth$currentChai7, _web3Auth$currentChai8;
131
+ setIsInitialized(true);
130
132
  setIsConnected(true);
133
+ // on rehydration, `AUTHORIZED` event can be fired first in `CONNECT_AND_SIGN` mode, before `CONNECTED` event.
134
+ // Update the connection state here, so that clients can use the connection state immediately.
135
+ setConnection(web3Auth.connection);
136
+ setChainId(web3Auth.currentChainId);
137
+ setChainNamespace((_web3Auth$currentChai7 = (_web3Auth$currentChai8 = web3Auth.currentChain) === null || _web3Auth$currentChai8 === void 0 ? void 0 : _web3Auth$currentChai8.chainNamespace) !== null && _web3Auth$currentChai7 !== void 0 ? _web3Auth$currentChai7 : null);
131
138
  setIsAuthorized(true);
132
139
  }
133
140
  };
134
141
  const consentAcceptedListener = () => {
135
142
  setStatus(web3Auth.status);
136
143
  if (web3Auth.status === CONNECTOR_STATUS.CONNECTED || web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
137
- var _web3Auth$currentChai7, _web3Auth$currentChai8;
144
+ var _web3Auth$currentChai9, _web3Auth$currentChai0;
138
145
  setIsInitialized(true);
139
146
  setIsConnected(true);
140
147
  setConnection(web3Auth.connection);
141
148
  setChainId(web3Auth.currentChainId);
142
- setChainNamespace((_web3Auth$currentChai7 = (_web3Auth$currentChai8 = web3Auth.currentChain) === null || _web3Auth$currentChai8 === void 0 ? void 0 : _web3Auth$currentChai8.chainNamespace) !== null && _web3Auth$currentChai7 !== void 0 ? _web3Auth$currentChai7 : null);
149
+ setChainNamespace((_web3Auth$currentChai9 = (_web3Auth$currentChai0 = web3Auth.currentChain) === null || _web3Auth$currentChai0 === void 0 ? void 0 : _web3Auth$currentChai0.chainNamespace) !== null && _web3Auth$currentChai9 !== void 0 ? _web3Auth$currentChai9 : null);
143
150
  if (web3Auth.status === CONNECTOR_STATUS.AUTHORIZED) {
144
151
  setIsAuthorized(true);
145
152
  }
@@ -149,11 +156,11 @@ function useWeb3AuthInnerContextValue({
149
156
  if (typeof nextIsMFAEnabled === "boolean") setIsMFAEnabled(nextIsMFAEnabled);
150
157
  };
151
158
  const connectionUpdatedListener = () => {
152
- var _web3Auth$currentChai9, _web3Auth$currentChai0;
159
+ var _web3Auth$currentChai1, _web3Auth$currentChai10;
153
160
  setStatus(web3Auth.status);
154
161
  setConnection(web3Auth.connection);
155
162
  setChainId(web3Auth.currentChainId);
156
- setChainNamespace((_web3Auth$currentChai9 = (_web3Auth$currentChai0 = web3Auth.currentChain) === null || _web3Auth$currentChai0 === void 0 ? void 0 : _web3Auth$currentChai0.chainNamespace) !== null && _web3Auth$currentChai9 !== void 0 ? _web3Auth$currentChai9 : null);
163
+ setChainNamespace((_web3Auth$currentChai1 = (_web3Auth$currentChai10 = web3Auth.currentChain) === null || _web3Auth$currentChai10 === void 0 ? void 0 : _web3Auth$currentChai10.chainNamespace) !== null && _web3Auth$currentChai1 !== void 0 ? _web3Auth$currentChai1 : null);
157
164
  };
158
165
  if (web3Auth) {
159
166
  web3Auth.on(CONNECTOR_EVENTS.NOT_READY, notReadyListener);
@@ -1 +1 @@
1
- export { WagmiProvider } from './provider.js';
1
+ export { WagmiProvider, connectWeb3AuthWithWagmi, createWeb3AuthConnectorForWagmi, disconnectWeb3AuthFromWagmi, getWeb3authConnector, resetConnectorState, setupConnector } from './provider.js';
@@ -1,42 +1,61 @@
1
1
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
2
2
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
3
3
  import { useMemo, createElement, useRef, useEffect, Fragment } from 'react';
4
- import { defineChain } from 'viem';
5
- import { createConfig, WagmiProvider as WagmiProvider$1, webSocket, http, fallback, useConfig, useReconnect, useConnectionEffect } from 'wagmi';
6
- import { injected } from 'wagmi/connectors';
4
+ import { defineChain, isAddress } from 'viem';
5
+ import { createConfig, WagmiProvider as WagmiProvider$1, injected, webSocket, http, fallback, useConfig, useReconnect, useConnectionEffect } from 'wagmi';
7
6
  import { defaultWagmiConfig } from './constants.js';
8
7
  import { useWeb3Auth } from '../hooks/useWeb3Auth.js';
9
8
  import { CHAIN_NAMESPACES } from '@toruslabs/base-controllers';
10
9
  import { WalletInitializationError } from '../../base/errors/index.js';
11
- import { useWeb3AuthDisconnect } from '../hooks/useWeb3AuthDisconnect.js';
10
+ import { WEB3AUTH_CONNECTOR_ID } from '../../base/connector/constants.js';
12
11
  import { log } from '../../base/loglevel.js';
12
+ import { useWeb3AuthDisconnect } from '../hooks/useWeb3AuthDisconnect.js';
13
13
 
14
14
  const _excluded = ["children"];
15
- const WEB3AUTH_CONNECTOR_ID = "web3auth";
16
15
  function getWeb3authConnector(config) {
17
16
  return config.connectors.find(c => c.id === WEB3AUTH_CONNECTOR_ID);
18
17
  }
19
18
 
20
- // Helper to initialize connectors for the given wallets
19
+ // Helper to create a Web3Auth connector to connect with wagmi
21
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- async function setupConnector(provider, config) {
23
- let connector = getWeb3authConnector(config);
24
- if (connector) return connector;
25
-
26
- // Create new connector if not already existing
27
- connector = injected({
21
+ function createWeb3AuthConnectorForWagmi(provider) {
22
+ const baseConnector = injected({
28
23
  target: {
29
24
  provider: provider,
30
25
  id: WEB3AUTH_CONNECTOR_ID,
31
26
  name: "Web3Auth"
32
27
  }
33
28
  });
29
+ return config => {
30
+ const connector = baseConnector(config);
31
+ const baseOnAccountsChanged = connector.onAccountsChanged.bind(connector);
32
+
33
+ // we need to handle the `accountsChanged` event emitted on the cross-namespace chain switch.
34
+ // on evm -> solana, the accountsChanged event is emitted with the solana address, which is not valid for evm.
35
+ // that causes the `invalid account address` error in wagmi. So, here, we're filtering out the solana addresses.
36
+ connector.onAccountsChanged = accounts => {
37
+ if (accounts.length > 0 && !accounts.every(account => typeof account === "string" && isAddress(account))) {
38
+ log.warn("onAccountsChanged::accountsChanged event received on non-EVM address");
39
+ return;
40
+ }
41
+ baseOnAccountsChanged(accounts);
42
+ };
43
+ return connector;
44
+ };
45
+ }
46
+
47
+ // Helper to initialize connectors for the given wallets
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ function setupConnector(provider, config) {
50
+ let connector = getWeb3authConnector(config);
51
+ if (connector) return connector;
52
+
53
+ // Create new connector if not already existing
54
+ connector = createWeb3AuthConnectorForWagmi(provider);
34
55
  const result = config._internal.connectors.setup(connector);
35
56
  config._internal.connectors.setState(current => [...current, result]);
36
57
  return result;
37
58
  }
38
-
39
- // Helper to connect a wallet and update wagmi state
40
59
  async function connectWeb3AuthWithWagmi(connector, config) {
41
60
  var _config$storage, _config$storage2;
42
61
  await Promise.all([(_config$storage = config.storage) === null || _config$storage === void 0 ? void 0 : _config$storage.removeItem(`${connector.id}.disconnected`), (_config$storage2 = config.storage) === null || _config$storage2 === void 0 ? void 0 : _config$storage2.setItem("recentConnectorId", connector.id)]);
@@ -76,6 +95,7 @@ async function disconnectWeb3AuthFromWagmi(config) {
76
95
  function Web3AuthWagmiProvider({
77
96
  children
78
97
  }) {
98
+ var _connection$ethereumP, _connection$connector;
79
99
  const {
80
100
  isConnected,
81
101
  connection,
@@ -89,59 +109,56 @@ function Web3AuthWagmiProvider({
89
109
  mutate: reconnect
90
110
  } = useReconnect();
91
111
  const suppressWagmiDisconnect = useRef(false);
92
- const lastSyncedBinding = useRef({
93
- provider: null,
94
- connectorName: null
95
- });
112
+ const lastSyncedProvider = useRef((_connection$ethereumP = connection === null || connection === void 0 ? void 0 : connection.ethereumProvider) !== null && _connection$ethereumP !== void 0 ? _connection$ethereumP : null);
113
+ const lastSyncedConnectorName = useRef((_connection$connector = connection === null || connection === void 0 ? void 0 : connection.connectorName) !== null && _connection$connector !== void 0 ? _connection$connector : null);
96
114
  useConnectionEffect({
97
115
  onDisconnect: async () => {
98
116
  log.info("Disconnected from wagmi");
99
117
  const isSuppressed = suppressWagmiDisconnect.current;
100
118
  suppressWagmiDisconnect.current = false;
101
119
  if (!isSuppressed && isConnected) await disconnect();
102
- const connector = getWeb3authConnector(wagmiConfig);
120
+
103
121
  // reset wagmi connector state if the provider handles disconnection because of the accountsChanged event
104
122
  // from the connected provider
105
- if (connector) {
123
+ if (getWeb3authConnector(wagmiConfig)) {
106
124
  resetConnectorState(wagmiConfig);
107
125
  }
108
126
  }
109
127
  });
110
128
  useEffect(() => {
111
- (async () => {
112
- const shouldBindToWagmi = isConnected && chainNamespace === CHAIN_NAMESPACES.EIP155 && Boolean(connection === null || connection === void 0 ? void 0 : connection.ethereumProvider);
129
+ (async _connection$ethereumP2 => {
130
+ const newConnection = connection !== null && connection !== void 0 ? connection : null;
131
+ const newEth = (_connection$ethereumP2 = connection === null || connection === void 0 ? void 0 : connection.ethereumProvider) !== null && _connection$ethereumP2 !== void 0 ? _connection$ethereumP2 : null;
132
+ const w3aWagmiConnector = getWeb3authConnector(wagmiConfig);
133
+ const shouldBindToWagmi = isConnected && chainNamespace === CHAIN_NAMESPACES.EIP155 && Boolean(newConnection && newEth);
113
134
  if (shouldBindToWagmi) {
114
- const hasSameBinding = lastSyncedBinding.current.provider === connection.ethereumProvider && lastSyncedBinding.current.connectorName === connection.connectorName;
115
- if (hasSameBinding && wagmiConfig.state.status === "connected") {
135
+ const hasSameBinding = lastSyncedProvider.current === newEth && lastSyncedConnectorName.current === newConnection.connectorName && wagmiConfig.state.status === "connected";
136
+ if (hasSameBinding) {
137
+ // rehydration: already connected to the same provider, so no need to reconnect
116
138
  return;
117
139
  }
118
- if (!hasSameBinding && getWeb3authConnector(wagmiConfig)) {
119
- if (wagmiConfig.state.status === "connected") {
120
- suppressWagmiDisconnect.current = true;
121
- await disconnectWeb3AuthFromWagmi(wagmiConfig);
122
- } else {
123
- resetConnectorState(wagmiConfig);
124
- }
140
+
141
+ // `ethereumProvider` is a stable proxy (`commonJRPCProvider`) across account switches,
142
+ // so key wagmi resyncs off the Web3Auth connection object instead of provider identity.
143
+ if (w3aWagmiConnector) {
144
+ resetConnectorState(wagmiConfig);
125
145
  }
126
- const connector = await setupConnector(connection.ethereumProvider, wagmiConfig);
146
+ lastSyncedProvider.current = newEth;
147
+ lastSyncedConnectorName.current = newConnection.connectorName;
148
+ const connector = setupConnector(newEth, wagmiConfig);
127
149
  if (!connector) {
150
+ log.error("Failed to setup react wagmi connector");
128
151
  throw new Error("Failed to setup connector");
129
152
  }
130
153
  await connectWeb3AuthWithWagmi(connector, wagmiConfig);
131
- lastSyncedBinding.current = {
132
- provider: connection.ethereumProvider,
133
- connectorName: connection.connectorName
134
- };
135
154
  reconnect();
136
155
  } else {
137
- lastSyncedBinding.current = {
138
- provider: null,
139
- connectorName: null
140
- };
156
+ lastSyncedProvider.current = null;
157
+ lastSyncedConnectorName.current = null;
141
158
  if (wagmiConfig.state.status === "connected") {
142
159
  suppressWagmiDisconnect.current = true;
143
160
  await disconnectWeb3AuthFromWagmi(wagmiConfig);
144
- } else if (getWeb3authConnector(wagmiConfig)) {
161
+ } else if (w3aWagmiConnector) {
145
162
  resetConnectorState(wagmiConfig);
146
163
  }
147
164
  }
@@ -240,4 +257,4 @@ function WagmiProvider(_ref) {
240
257
  }), createElement(Web3AuthWagmiProvider, null, children));
241
258
  }
242
259
 
243
- export { WagmiProvider };
260
+ export { WagmiProvider, connectWeb3AuthWithWagmi, createWeb3AuthConnectorForWagmi, disconnectWeb3AuthFromWagmi, getWeb3authConnector, resetConnectorState, setupConnector };
@@ -99,20 +99,27 @@ function useWeb3AuthInnerContextValue({
99
99
  };
100
100
  const authorizedListener = () => {
101
101
  status.value = web3Auth.value.status;
102
+ // on rehydration, `AUTHORIZED` event can be fired first in `CONNECT_AND_SIGN` mode, before `CONNECTED` event.
103
+ // Update the connection state here, so that clients can use the connection state immediately.
102
104
  if (web3Auth.value.status === CONNECTOR_STATUS.AUTHORIZED) {
105
+ var _currentChain$chainNa2, _currentChain2;
106
+ if (!isInitialized.value) isInitialized.value = true;
103
107
  isAuthorized.value = true;
104
108
  isConnected.value = true;
109
+ connection.value = web3Auth.value.connection;
110
+ chainId.value = web3Auth.value.currentChainId;
111
+ chainNamespace.value = (_currentChain$chainNa2 = (_currentChain2 = web3Auth.value.currentChain) === null || _currentChain2 === void 0 ? void 0 : _currentChain2.chainNamespace) !== null && _currentChain$chainNa2 !== void 0 ? _currentChain$chainNa2 : null;
105
112
  }
106
113
  };
107
114
  const consentAcceptedListener = () => {
108
115
  status.value = web3Auth.value.status;
109
116
  if (web3Auth.value.status === CONNECTOR_STATUS.CONNECTED || web3Auth.value.status === CONNECTOR_STATUS.AUTHORIZED) {
110
- var _currentChain$chainNa2, _currentChain2;
117
+ var _currentChain$chainNa3, _currentChain3;
111
118
  if (!isInitialized.value) isInitialized.value = true;
112
119
  isConnected.value = true;
113
120
  connection.value = web3Auth.value.connection;
114
121
  chainId.value = web3Auth.value.currentChainId;
115
- chainNamespace.value = (_currentChain$chainNa2 = (_currentChain2 = web3Auth.value.currentChain) === null || _currentChain2 === void 0 ? void 0 : _currentChain2.chainNamespace) !== null && _currentChain$chainNa2 !== void 0 ? _currentChain$chainNa2 : null;
122
+ chainNamespace.value = (_currentChain$chainNa3 = (_currentChain3 = web3Auth.value.currentChain) === null || _currentChain3 === void 0 ? void 0 : _currentChain3.chainNamespace) !== null && _currentChain$chainNa3 !== void 0 ? _currentChain$chainNa3 : null;
116
123
  if (web3Auth.value.status === CONNECTOR_STATUS.AUTHORIZED) {
117
124
  isAuthorized.value = true;
118
125
  }
@@ -135,11 +142,11 @@ function useWeb3AuthInnerContextValue({
135
142
  isMFAEnabled.value = true;
136
143
  };
137
144
  const connectionUpdatedListener = () => {
138
- var _currentChain$chainNa3, _currentChain3;
145
+ var _currentChain$chainNa4, _currentChain4;
139
146
  status.value = web3Auth.value.status;
140
147
  connection.value = web3Auth.value.connection;
141
148
  chainId.value = web3Auth.value.currentChainId;
142
- chainNamespace.value = (_currentChain$chainNa3 = (_currentChain3 = web3Auth.value.currentChain) === null || _currentChain3 === void 0 ? void 0 : _currentChain3.chainNamespace) !== null && _currentChain$chainNa3 !== void 0 ? _currentChain$chainNa3 : null;
149
+ chainNamespace.value = (_currentChain$chainNa4 = (_currentChain4 = web3Auth.value.currentChain) === null || _currentChain4 === void 0 ? void 0 : _currentChain4.chainNamespace) !== null && _currentChain$chainNa4 !== void 0 ? _currentChain$chainNa4 : null;
143
150
  };
144
151
  if (prevWeb3Auth && newWeb3Auth !== prevWeb3Auth) {
145
152
  prevWeb3Auth.removeListener(CONNECTOR_EVENTS.NOT_READY, notReadyListener);
@@ -1 +1 @@
1
- export { WagmiProvider } from './provider.js';
1
+ export { WagmiProvider, connectWeb3AuthWithWagmi, createWeb3AuthConnectorForWagmi, disconnectWeb3AuthFromWagmi, getWeb3authConnector, resetConnectorState, setupConnector } from './provider.js';