@dynamic-labs/ethereum-aa 4.58.0 → 4.59.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.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,25 @@
1
1
 
2
+ ## [4.59.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.58.1...v4.59.0) (2026-01-30)
3
+
4
+
5
+ ### Features
6
+
7
+ * add password requirement to auto-create wallet flow ([#10324](https://github.com/dynamic-labs/dynamic-auth/issues/10324)) ([f81162d](https://github.com/dynamic-labs/dynamic-auth/commit/f81162dfb8607580192d0683ed6ecb82481d97fd))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * ensure useReinitialize will load state from local storage ([#10312](https://github.com/dynamic-labs/dynamic-auth/issues/10312)) ([647ac6c](https://github.com/dynamic-labs/dynamic-auth/commit/647ac6c35a7a3a747897943b4667d63e57968227))
13
+
14
+ ### [4.58.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.58.0...v4.58.1) (2026-01-29)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * fix ZeroDev multi-wallet switching issue ([#10293](https://github.com/dynamic-labs/dynamic-auth/issues/10293)) ([f3ef7ea](https://github.com/dynamic-labs/dynamic-auth/commit/f3ef7ea5790a70304ef697a04417fdbcc043a620))
20
+ * allow the web-extension to be recreated ([#10318](https://github.com/dynamic-labs/dynamic-auth/issues/10318)) ([3ad3ddb](https://github.com/dynamic-labs/dynamic-auth/commit/3ad3ddbfe80297889679f28679e25bb20d492c22))
21
+ * patch critical vuln for @remix-run/node ([#10322](https://github.com/dynamic-labs/dynamic-auth/issues/10322)) ([a83a102](https://github.com/dynamic-labs/dynamic-auth/commit/a83a1025e992f8d04f0f9e3b3b3878ba6010ceb5))
22
+
2
23
  ## [4.58.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.57.2...v4.58.0) (2026-01-28)
3
24
 
4
25
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.58.0";
6
+ var version = "4.59.0";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.58.0";
2
+ var version = "4.59.0";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/ethereum-aa",
3
- "version": "4.58.0",
3
+ "version": "4.59.0",
4
4
  "description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -22,14 +22,14 @@
22
22
  "@zerodev/ecdsa-validator": "5.4.9",
23
23
  "@zerodev/multi-chain-ecdsa-validator": "5.4.5",
24
24
  "@zerodev/sdk": "5.5.7",
25
- "@dynamic-labs/assert-package-version": "4.58.0",
26
- "@dynamic-labs/ethereum-aa-core": "4.58.0",
27
- "@dynamic-labs/ethereum-core": "4.58.0",
28
- "@dynamic-labs/logger": "4.58.0",
29
- "@dynamic-labs/types": "4.58.0",
30
- "@dynamic-labs/utils": "4.58.0",
31
- "@dynamic-labs/wallet-book": "4.58.0",
32
- "@dynamic-labs/wallet-connector-core": "4.58.0"
25
+ "@dynamic-labs/assert-package-version": "4.59.0",
26
+ "@dynamic-labs/ethereum-aa-core": "4.59.0",
27
+ "@dynamic-labs/ethereum-core": "4.59.0",
28
+ "@dynamic-labs/logger": "4.59.0",
29
+ "@dynamic-labs/types": "4.59.0",
30
+ "@dynamic-labs/utils": "4.59.0",
31
+ "@dynamic-labs/wallet-book": "4.59.0",
32
+ "@dynamic-labs/wallet-connector-core": "4.59.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "viem": "^2.28.4"
@@ -25,7 +25,8 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
25
25
  constructor(opts) {
26
26
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
27
27
  super(opts);
28
- // provider map maintains the kernel clients per chain
28
+ // Provider map maintains kernel clients per wallet address and chain
29
+ // Structure: { [walletAddress]: { [chainId]: { kernelClient, ... } } }
29
30
  this.providerMap = {};
30
31
  // eoa connector map maintains the eoa address and connector for each smart wallet address
31
32
  this.eoaConnectorMap = {};
@@ -90,15 +91,21 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
90
91
  throw new Error('confirmTransactionStatus not implemented in ZeroDevConnector');
91
92
  }
92
93
  get currentNetworkProvider() {
93
- // check if the last used chain id is in the provider map
94
- if (this.providerMap[this.lastUsedChainId]) {
95
- return this.providerMap[this.lastUsedChainId];
94
+ if (!this.activeWalletAddress) {
95
+ return undefined;
96
+ }
97
+ const walletProviders = this.providerMap[this.activeWalletAddress];
98
+ if (!walletProviders) {
99
+ return undefined;
96
100
  }
97
- // if not, check if the default chain id is in the provider map
98
- if (this.defaultChainId) {
99
- return this.providerMap[this.defaultChainId];
101
+ // Check if the last used chain id is in the provider map for this wallet
102
+ if (walletProviders[this.lastUsedChainId]) {
103
+ return walletProviders[this.lastUsedChainId];
104
+ }
105
+ // If not, check if the default chain id is in the provider map
106
+ if (this.defaultChainId && walletProviders[this.defaultChainId]) {
107
+ return walletProviders[this.defaultChainId];
100
108
  }
101
- // if no chain id is found, return undefined
102
109
  return undefined;
103
110
  }
104
111
  get lastUsedChainId() {
@@ -116,7 +123,14 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
116
123
  return (_a = this.currentNetworkProvider) === null || _a === void 0 ? void 0 : _a.kernelClientWithSponsorship;
117
124
  }
118
125
  supportsNetworkSwitching() {
119
- return (Object.keys(this.providerMap).length > 1 && this.evmNetworks.length > 1);
126
+ if (!this.activeWalletAddress) {
127
+ return false;
128
+ }
129
+ const walletProviders = this.providerMap[this.activeWalletAddress];
130
+ if (!walletProviders) {
131
+ return false;
132
+ }
133
+ return (Object.keys(walletProviders).length > 1 && this.evmNetworks.length > 1);
120
134
  }
121
135
  getPublicRpcForChain(chainId) {
122
136
  var _a, _b;
@@ -131,8 +145,11 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
131
145
  return;
132
146
  if (!networkChainId)
133
147
  return;
148
+ if (!this.activeWalletAddress)
149
+ return;
134
150
  const chainId = networkChainId.toString();
135
- if (!this.providerMap[chainId]) {
151
+ const walletProviders = this.providerMap[this.activeWalletAddress];
152
+ if (!(walletProviders === null || walletProviders === void 0 ? void 0 : walletProviders[chainId])) {
136
153
  throw new Error(`No provider found for chainId: ${chainId}`);
137
154
  }
138
155
  utils.StorageService.setItem(constants.ZERO_DEV_LAST_USED_CHAIN_ID_KEY, chainId);
@@ -173,32 +190,21 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
173
190
  if (smartWalletAddress !== eoaAddress) {
174
191
  throw new Error('In EIP-7702 mode, smart wallet and EOA addresses must be the same');
175
192
  }
176
- this.eoaConnectorMap[smartWalletAddress] = {
177
- eoaAddress,
178
- eoaConnector,
179
- properties,
180
- };
181
- yield this.setEoaConnector({
182
- connector: eoaConnector,
183
- eoaAddress,
184
- properties,
185
- });
186
- }
187
- else {
188
- // Existing implementation for regular ZeroDev
189
- this.eoaConnectorMap[smartWalletAddress] = {
190
- eoaAddress,
191
- eoaConnector,
192
- properties,
193
- };
194
- if (shouldSetEoaConnector) {
195
- yield this.setEoaConnector({
196
- connector: eoaConnector,
197
- eoaAddress,
198
- properties,
199
- });
200
- }
201
193
  }
194
+ // Register the EOA connector mapping
195
+ this.eoaConnectorMap[smartWalletAddress] = {
196
+ eoaAddress,
197
+ eoaConnector,
198
+ properties,
199
+ };
200
+ // Always generate providers for all wallets, but only set active state for primary
201
+ yield this.setEoaConnector({
202
+ connector: eoaConnector,
203
+ eoaAddress,
204
+ isPrimary: shouldSetEoaConnector,
205
+ properties,
206
+ smartWalletAddress,
207
+ });
202
208
  });
203
209
  }
204
210
  determineSmartAccountStatus(eoaConnector, verifiedCredentials) {
@@ -210,7 +216,7 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
210
216
  this.is7702EnabledOnDashboard && !this.hasExistingSmartAccount;
211
217
  }
212
218
  setEoaConnector(_a) {
213
- return _tslib.__awaiter(this, arguments, void 0, function* ({ eoaAddress, connector, properties, }) {
219
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ eoaAddress, connector, properties, smartWalletAddress, isPrimary = true, }) {
214
220
  var _b, _c;
215
221
  if (!connector) {
216
222
  logger.logger.error('No EOA connector provided');
@@ -219,8 +225,12 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
219
225
  this.kernelClientDeferredPromise = this.kernelClientDeferredPromise
220
226
  ? this.kernelClientDeferredPromise
221
227
  : new utils.DeferredPromise();
222
- this.eoaConnector = connector;
223
- this.eoaAddress = eoaAddress;
228
+ // Only set active wallet state if this is the primary wallet
229
+ if (isPrimary) {
230
+ this.eoaConnector = connector;
231
+ this.eoaAddress = eoaAddress;
232
+ this.activeWalletAddress = smartWalletAddress;
233
+ }
224
234
  if (properties) {
225
235
  this.ecdsaProviderType =
226
236
  (_b = properties.ecdsaProviderType) !== null && _b !== void 0 ? _b : this.ecdsaProviderType;
@@ -233,12 +243,15 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
233
243
  this.enableKernelV3Migration =
234
244
  (_c = properties.enableKernelV3Migration) !== null && _c !== void 0 ? _c : this.enableKernelV3Migration;
235
245
  }
236
- if (ethereumCore.isEthWalletConnector(this.eoaConnector) &&
237
- !this.eoaConnector.getActiveAccount()) {
238
- yield this.eoaConnector.getConnectedAccounts();
246
+ // Ensure the correct EOA account is active before getting the signer
247
+ if (walletConnectorCore.isDynamicWaasConnector(connector)) {
248
+ yield connector.validateActiveWallet(eoaAddress);
239
249
  }
240
- const signer = yield this.eoaConnector.getSigner();
241
- yield this.generateProviderMap(signer);
250
+ if (ethereumCore.isEthWalletConnector(connector) && !connector.getActiveAccount()) {
251
+ yield connector.getConnectedAccounts();
252
+ }
253
+ const signer = yield connector.getSigner();
254
+ yield this.generateProviderMap(signer, smartWalletAddress);
242
255
  this.kernelClientDeferredPromise.resolve();
243
256
  });
244
257
  }
@@ -261,10 +274,11 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
261
274
  * Each chain gets two clients: one without sponsorship and one with sponsorship
262
275
  *
263
276
  * @param signer - The wallet client to use for signing transactions
277
+ * @param walletAddress - The smart wallet address to store the providers under
264
278
  */
265
- generateProviderMap(signer) {
279
+ generateProviderMap(signer, walletAddress) {
266
280
  return _tslib.__awaiter(this, void 0, void 0, function* () {
267
- const providerMap = {};
281
+ const chainProviderMap = {};
268
282
  yield Promise.all(this.providersFromApi.map((provider) => _tslib.__awaiter(this, void 0, void 0, function* () {
269
283
  const { chain, clientId } = provider;
270
284
  const [kernelClient, kernelClientWithSponsorship] = yield Promise.all([
@@ -273,36 +287,37 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
273
287
  paymaster: createEcdsaKernelAccountClient.PaymasterTypeEnum.NONE,
274
288
  projectId: clientId,
275
289
  signer,
290
+ walletAddress,
276
291
  }),
277
292
  this.getOrCreateKernelClient({
278
293
  chainId: chain,
279
294
  paymaster: createEcdsaKernelAccountClient.PaymasterTypeEnum.SPONSOR,
280
295
  projectId: clientId,
281
296
  signer,
297
+ walletAddress,
282
298
  }),
283
299
  ]);
284
- providerMap[chain] = {
300
+ chainProviderMap[chain] = {
285
301
  kernelClient,
286
302
  kernelClientWithSponsorship,
287
303
  signerAddress: signer.account.address,
288
304
  };
289
305
  yield this.warnIfProjectChainNotEnabled(utils.parseChainId(chain));
290
306
  })));
291
- // Filter out duplicate chains and store the provider map
292
- const uniqueChainProviderMap = Object.entries(providerMap).reduce((acc, [chain, providers]) => {
307
+ // Filter out duplicate chains and store under the wallet address
308
+ const uniqueChainProviderMap = Object.entries(chainProviderMap).reduce((acc, [chain, providers]) => {
293
309
  if (!acc[chain]) {
294
310
  acc[chain] = providers;
295
311
  }
296
312
  return acc;
297
313
  }, {});
298
- this.providerMap = uniqueChainProviderMap;
314
+ this.providerMap[walletAddress] = uniqueChainProviderMap;
299
315
  });
300
316
  }
301
317
  createKernelClient(_a) {
302
318
  return _tslib.__awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, paymasterRpcOverride, bundlerRpcOverride, }) {
303
- const { eoaConnector } = this;
304
- if (!eoaConnector)
305
- throw new utils.DynamicError('No EOA connector');
319
+ if (!signer)
320
+ throw new utils.DynamicError('No signer provided');
306
321
  const chain = ethereumCore.chainsMap[chainId];
307
322
  let kernelClient;
308
323
  const params = {
@@ -335,13 +350,14 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
335
350
  });
336
351
  }
337
352
  getOrCreateKernelClient(_a) {
338
- return _tslib.__awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, }) {
353
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, walletAddress, }) {
354
+ const walletProviders = this.providerMap[walletAddress];
339
355
  if (chainId &&
340
- this.providerMap[chainId] &&
341
- this.providerMap[chainId].signerAddress === signer.account.address) {
356
+ (walletProviders === null || walletProviders === void 0 ? void 0 : walletProviders[chainId]) &&
357
+ walletProviders[chainId].signerAddress === signer.account.address) {
342
358
  return paymaster === createEcdsaKernelAccountClient.PaymasterTypeEnum.SPONSOR
343
- ? this.providerMap[chainId].kernelClientWithSponsorship
344
- : this.providerMap[chainId].kernelClient;
359
+ ? walletProviders[chainId].kernelClientWithSponsorship
360
+ : walletProviders[chainId].kernelClient;
345
361
  }
346
362
  return this.createKernelClient({
347
363
  chainId,
@@ -705,8 +721,11 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
705
721
  }
706
722
  signMessageForChain(messageToSign, chainId) {
707
723
  return _tslib.__awaiter(this, void 0, void 0, function* () {
708
- var _a;
709
- const client = (_a = this.providerMap[chainId]) === null || _a === void 0 ? void 0 : _a.kernelClient;
724
+ var _a, _b;
725
+ if (!this.activeWalletAddress) {
726
+ throw new utils.DynamicError('No active wallet address');
727
+ }
728
+ const client = (_b = (_a = this.providerMap[this.activeWalletAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) === null || _b === void 0 ? void 0 : _b.kernelClient;
710
729
  if (!client) {
711
730
  throw new utils.DynamicError(`Provider for Chain ID ${chainId} not available. Please make sure that Chain ID ${chainId} is enabled in both the Dynamic dashboard and the ZeroDev dashboard.`);
712
731
  }
@@ -729,18 +748,45 @@ class ZeroDevConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
729
748
  return this.kernelClient.signMessage({ message: messageToSign });
730
749
  });
731
750
  }
751
+ afterWalletSelectHook(walletAddress) {
752
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
753
+ yield this.validateActiveWallet(walletAddress);
754
+ });
755
+ }
732
756
  validateActiveWallet(expectedAddress) {
733
757
  return _tslib.__awaiter(this, void 0, void 0, function* () {
758
+ var _a, _b;
734
759
  const eoa = this.eoaConnectorMap[expectedAddress];
735
760
  if (!eoa) {
736
761
  throw new utils.DynamicError('No EOA connector');
737
762
  }
738
763
  const { eoaAddress, eoaConnector, properties } = eoa;
764
+ // Validate the underlying EOA connector
739
765
  yield eoaConnector.validateActiveWallet(eoaAddress);
766
+ // Check if we have providers for this wallet with the correct kernel account address
767
+ const existingProviders = this.providerMap[expectedAddress];
768
+ if (existingProviders) {
769
+ // Verify the kernel account address matches the expected address
770
+ const chainId = this.lastUsedChainId;
771
+ const provider = existingProviders[chainId];
772
+ const kernelAccountAddress = (_b = (_a = provider === null || provider === void 0 ? void 0 : provider.kernelClient) === null || _a === void 0 ? void 0 : _a.account) === null || _b === void 0 ? void 0 : _b.address;
773
+ if (kernelAccountAddress &&
774
+ kernelAccountAddress.toLowerCase() === expectedAddress.toLowerCase()) {
775
+ // Providers are valid, just switch to them
776
+ this.activeWalletAddress = expectedAddress;
777
+ this.eoaConnector = eoaConnector;
778
+ this.eoaAddress = eoaAddress;
779
+ this.userOperationCache = {};
780
+ return;
781
+ }
782
+ // Providers have wrong kernel account, need to regenerate
783
+ }
784
+ // Generate providers for this wallet
740
785
  yield this.setEoaConnector({
741
786
  connector: eoaConnector,
742
787
  eoaAddress,
743
788
  properties,
789
+ smartWalletAddress: expectedAddress,
744
790
  });
745
791
  });
746
792
  }
@@ -12,6 +12,7 @@ export declare class ZeroDevConnector extends AccountAbstractionBaseConnector im
12
12
  clientId: string;
13
13
  eoaConnector: InternalWalletConnector | undefined;
14
14
  eoaAddress: string | undefined;
15
+ private activeWalletAddress;
15
16
  private providerMap;
16
17
  private eoaConnectorMap;
17
18
  ChainWallet: typeof EthereumWallet;
@@ -108,6 +109,7 @@ export declare class ZeroDevConnector extends AccountAbstractionBaseConnector im
108
109
  * Each chain gets two clients: one without sponsorship and one with sponsorship
109
110
  *
110
111
  * @param signer - The wallet client to use for signing transactions
112
+ * @param walletAddress - The smart wallet address to store the providers under
111
113
  */
112
114
  private generateProviderMap;
113
115
  private createKernelClient;
@@ -141,6 +143,7 @@ export declare class ZeroDevConnector extends AccountAbstractionBaseConnector im
141
143
  signMessage(messageToSign: string): Promise<string | undefined>;
142
144
  signMessageForChain(messageToSign: string, chainId: string): Promise<string | undefined>;
143
145
  private internalSignMessage;
146
+ afterWalletSelectHook(walletAddress: string): Promise<void>;
144
147
  validateActiveWallet(expectedAddress: string): Promise<void>;
145
148
  isAtomicSupported(chainId?: number): Promise<boolean>;
146
149
  isPaymasterServiceSupported(chainId?: number): Promise<boolean>;
@@ -21,7 +21,8 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
21
21
  constructor(opts) {
22
22
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
23
23
  super(opts);
24
- // provider map maintains the kernel clients per chain
24
+ // Provider map maintains kernel clients per wallet address and chain
25
+ // Structure: { [walletAddress]: { [chainId]: { kernelClient, ... } } }
25
26
  this.providerMap = {};
26
27
  // eoa connector map maintains the eoa address and connector for each smart wallet address
27
28
  this.eoaConnectorMap = {};
@@ -86,15 +87,21 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
86
87
  throw new Error('confirmTransactionStatus not implemented in ZeroDevConnector');
87
88
  }
88
89
  get currentNetworkProvider() {
89
- // check if the last used chain id is in the provider map
90
- if (this.providerMap[this.lastUsedChainId]) {
91
- return this.providerMap[this.lastUsedChainId];
90
+ if (!this.activeWalletAddress) {
91
+ return undefined;
92
+ }
93
+ const walletProviders = this.providerMap[this.activeWalletAddress];
94
+ if (!walletProviders) {
95
+ return undefined;
92
96
  }
93
- // if not, check if the default chain id is in the provider map
94
- if (this.defaultChainId) {
95
- return this.providerMap[this.defaultChainId];
97
+ // Check if the last used chain id is in the provider map for this wallet
98
+ if (walletProviders[this.lastUsedChainId]) {
99
+ return walletProviders[this.lastUsedChainId];
100
+ }
101
+ // If not, check if the default chain id is in the provider map
102
+ if (this.defaultChainId && walletProviders[this.defaultChainId]) {
103
+ return walletProviders[this.defaultChainId];
96
104
  }
97
- // if no chain id is found, return undefined
98
105
  return undefined;
99
106
  }
100
107
  get lastUsedChainId() {
@@ -112,7 +119,14 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
112
119
  return (_a = this.currentNetworkProvider) === null || _a === void 0 ? void 0 : _a.kernelClientWithSponsorship;
113
120
  }
114
121
  supportsNetworkSwitching() {
115
- return (Object.keys(this.providerMap).length > 1 && this.evmNetworks.length > 1);
122
+ if (!this.activeWalletAddress) {
123
+ return false;
124
+ }
125
+ const walletProviders = this.providerMap[this.activeWalletAddress];
126
+ if (!walletProviders) {
127
+ return false;
128
+ }
129
+ return (Object.keys(walletProviders).length > 1 && this.evmNetworks.length > 1);
116
130
  }
117
131
  getPublicRpcForChain(chainId) {
118
132
  var _a, _b;
@@ -127,8 +141,11 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
127
141
  return;
128
142
  if (!networkChainId)
129
143
  return;
144
+ if (!this.activeWalletAddress)
145
+ return;
130
146
  const chainId = networkChainId.toString();
131
- if (!this.providerMap[chainId]) {
147
+ const walletProviders = this.providerMap[this.activeWalletAddress];
148
+ if (!(walletProviders === null || walletProviders === void 0 ? void 0 : walletProviders[chainId])) {
132
149
  throw new Error(`No provider found for chainId: ${chainId}`);
133
150
  }
134
151
  StorageService.setItem(ZERO_DEV_LAST_USED_CHAIN_ID_KEY, chainId);
@@ -169,32 +186,21 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
169
186
  if (smartWalletAddress !== eoaAddress) {
170
187
  throw new Error('In EIP-7702 mode, smart wallet and EOA addresses must be the same');
171
188
  }
172
- this.eoaConnectorMap[smartWalletAddress] = {
173
- eoaAddress,
174
- eoaConnector,
175
- properties,
176
- };
177
- yield this.setEoaConnector({
178
- connector: eoaConnector,
179
- eoaAddress,
180
- properties,
181
- });
182
- }
183
- else {
184
- // Existing implementation for regular ZeroDev
185
- this.eoaConnectorMap[smartWalletAddress] = {
186
- eoaAddress,
187
- eoaConnector,
188
- properties,
189
- };
190
- if (shouldSetEoaConnector) {
191
- yield this.setEoaConnector({
192
- connector: eoaConnector,
193
- eoaAddress,
194
- properties,
195
- });
196
- }
197
189
  }
190
+ // Register the EOA connector mapping
191
+ this.eoaConnectorMap[smartWalletAddress] = {
192
+ eoaAddress,
193
+ eoaConnector,
194
+ properties,
195
+ };
196
+ // Always generate providers for all wallets, but only set active state for primary
197
+ yield this.setEoaConnector({
198
+ connector: eoaConnector,
199
+ eoaAddress,
200
+ isPrimary: shouldSetEoaConnector,
201
+ properties,
202
+ smartWalletAddress,
203
+ });
198
204
  });
199
205
  }
200
206
  determineSmartAccountStatus(eoaConnector, verifiedCredentials) {
@@ -206,7 +212,7 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
206
212
  this.is7702EnabledOnDashboard && !this.hasExistingSmartAccount;
207
213
  }
208
214
  setEoaConnector(_a) {
209
- return __awaiter(this, arguments, void 0, function* ({ eoaAddress, connector, properties, }) {
215
+ return __awaiter(this, arguments, void 0, function* ({ eoaAddress, connector, properties, smartWalletAddress, isPrimary = true, }) {
210
216
  var _b, _c;
211
217
  if (!connector) {
212
218
  logger.error('No EOA connector provided');
@@ -215,8 +221,12 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
215
221
  this.kernelClientDeferredPromise = this.kernelClientDeferredPromise
216
222
  ? this.kernelClientDeferredPromise
217
223
  : new DeferredPromise();
218
- this.eoaConnector = connector;
219
- this.eoaAddress = eoaAddress;
224
+ // Only set active wallet state if this is the primary wallet
225
+ if (isPrimary) {
226
+ this.eoaConnector = connector;
227
+ this.eoaAddress = eoaAddress;
228
+ this.activeWalletAddress = smartWalletAddress;
229
+ }
220
230
  if (properties) {
221
231
  this.ecdsaProviderType =
222
232
  (_b = properties.ecdsaProviderType) !== null && _b !== void 0 ? _b : this.ecdsaProviderType;
@@ -229,12 +239,15 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
229
239
  this.enableKernelV3Migration =
230
240
  (_c = properties.enableKernelV3Migration) !== null && _c !== void 0 ? _c : this.enableKernelV3Migration;
231
241
  }
232
- if (isEthWalletConnector(this.eoaConnector) &&
233
- !this.eoaConnector.getActiveAccount()) {
234
- yield this.eoaConnector.getConnectedAccounts();
242
+ // Ensure the correct EOA account is active before getting the signer
243
+ if (isDynamicWaasConnector(connector)) {
244
+ yield connector.validateActiveWallet(eoaAddress);
235
245
  }
236
- const signer = yield this.eoaConnector.getSigner();
237
- yield this.generateProviderMap(signer);
246
+ if (isEthWalletConnector(connector) && !connector.getActiveAccount()) {
247
+ yield connector.getConnectedAccounts();
248
+ }
249
+ const signer = yield connector.getSigner();
250
+ yield this.generateProviderMap(signer, smartWalletAddress);
238
251
  this.kernelClientDeferredPromise.resolve();
239
252
  });
240
253
  }
@@ -257,10 +270,11 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
257
270
  * Each chain gets two clients: one without sponsorship and one with sponsorship
258
271
  *
259
272
  * @param signer - The wallet client to use for signing transactions
273
+ * @param walletAddress - The smart wallet address to store the providers under
260
274
  */
261
- generateProviderMap(signer) {
275
+ generateProviderMap(signer, walletAddress) {
262
276
  return __awaiter(this, void 0, void 0, function* () {
263
- const providerMap = {};
277
+ const chainProviderMap = {};
264
278
  yield Promise.all(this.providersFromApi.map((provider) => __awaiter(this, void 0, void 0, function* () {
265
279
  const { chain, clientId } = provider;
266
280
  const [kernelClient, kernelClientWithSponsorship] = yield Promise.all([
@@ -269,36 +283,37 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
269
283
  paymaster: PaymasterTypeEnum.NONE,
270
284
  projectId: clientId,
271
285
  signer,
286
+ walletAddress,
272
287
  }),
273
288
  this.getOrCreateKernelClient({
274
289
  chainId: chain,
275
290
  paymaster: PaymasterTypeEnum.SPONSOR,
276
291
  projectId: clientId,
277
292
  signer,
293
+ walletAddress,
278
294
  }),
279
295
  ]);
280
- providerMap[chain] = {
296
+ chainProviderMap[chain] = {
281
297
  kernelClient,
282
298
  kernelClientWithSponsorship,
283
299
  signerAddress: signer.account.address,
284
300
  };
285
301
  yield this.warnIfProjectChainNotEnabled(parseChainId(chain));
286
302
  })));
287
- // Filter out duplicate chains and store the provider map
288
- const uniqueChainProviderMap = Object.entries(providerMap).reduce((acc, [chain, providers]) => {
303
+ // Filter out duplicate chains and store under the wallet address
304
+ const uniqueChainProviderMap = Object.entries(chainProviderMap).reduce((acc, [chain, providers]) => {
289
305
  if (!acc[chain]) {
290
306
  acc[chain] = providers;
291
307
  }
292
308
  return acc;
293
309
  }, {});
294
- this.providerMap = uniqueChainProviderMap;
310
+ this.providerMap[walletAddress] = uniqueChainProviderMap;
295
311
  });
296
312
  }
297
313
  createKernelClient(_a) {
298
314
  return __awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, paymasterRpcOverride, bundlerRpcOverride, }) {
299
- const { eoaConnector } = this;
300
- if (!eoaConnector)
301
- throw new DynamicError('No EOA connector');
315
+ if (!signer)
316
+ throw new DynamicError('No signer provided');
302
317
  const chain = chainsMap[chainId];
303
318
  let kernelClient;
304
319
  const params = {
@@ -331,13 +346,14 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
331
346
  });
332
347
  }
333
348
  getOrCreateKernelClient(_a) {
334
- return __awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, }) {
349
+ return __awaiter(this, arguments, void 0, function* ({ chainId, projectId, signer, paymaster, walletAddress, }) {
350
+ const walletProviders = this.providerMap[walletAddress];
335
351
  if (chainId &&
336
- this.providerMap[chainId] &&
337
- this.providerMap[chainId].signerAddress === signer.account.address) {
352
+ (walletProviders === null || walletProviders === void 0 ? void 0 : walletProviders[chainId]) &&
353
+ walletProviders[chainId].signerAddress === signer.account.address) {
338
354
  return paymaster === PaymasterTypeEnum.SPONSOR
339
- ? this.providerMap[chainId].kernelClientWithSponsorship
340
- : this.providerMap[chainId].kernelClient;
355
+ ? walletProviders[chainId].kernelClientWithSponsorship
356
+ : walletProviders[chainId].kernelClient;
341
357
  }
342
358
  return this.createKernelClient({
343
359
  chainId,
@@ -701,8 +717,11 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
701
717
  }
702
718
  signMessageForChain(messageToSign, chainId) {
703
719
  return __awaiter(this, void 0, void 0, function* () {
704
- var _a;
705
- const client = (_a = this.providerMap[chainId]) === null || _a === void 0 ? void 0 : _a.kernelClient;
720
+ var _a, _b;
721
+ if (!this.activeWalletAddress) {
722
+ throw new DynamicError('No active wallet address');
723
+ }
724
+ const client = (_b = (_a = this.providerMap[this.activeWalletAddress]) === null || _a === void 0 ? void 0 : _a[chainId]) === null || _b === void 0 ? void 0 : _b.kernelClient;
706
725
  if (!client) {
707
726
  throw new DynamicError(`Provider for Chain ID ${chainId} not available. Please make sure that Chain ID ${chainId} is enabled in both the Dynamic dashboard and the ZeroDev dashboard.`);
708
727
  }
@@ -725,18 +744,45 @@ class ZeroDevConnector extends AccountAbstractionBaseConnector {
725
744
  return this.kernelClient.signMessage({ message: messageToSign });
726
745
  });
727
746
  }
747
+ afterWalletSelectHook(walletAddress) {
748
+ return __awaiter(this, void 0, void 0, function* () {
749
+ yield this.validateActiveWallet(walletAddress);
750
+ });
751
+ }
728
752
  validateActiveWallet(expectedAddress) {
729
753
  return __awaiter(this, void 0, void 0, function* () {
754
+ var _a, _b;
730
755
  const eoa = this.eoaConnectorMap[expectedAddress];
731
756
  if (!eoa) {
732
757
  throw new DynamicError('No EOA connector');
733
758
  }
734
759
  const { eoaAddress, eoaConnector, properties } = eoa;
760
+ // Validate the underlying EOA connector
735
761
  yield eoaConnector.validateActiveWallet(eoaAddress);
762
+ // Check if we have providers for this wallet with the correct kernel account address
763
+ const existingProviders = this.providerMap[expectedAddress];
764
+ if (existingProviders) {
765
+ // Verify the kernel account address matches the expected address
766
+ const chainId = this.lastUsedChainId;
767
+ const provider = existingProviders[chainId];
768
+ const kernelAccountAddress = (_b = (_a = provider === null || provider === void 0 ? void 0 : provider.kernelClient) === null || _a === void 0 ? void 0 : _a.account) === null || _b === void 0 ? void 0 : _b.address;
769
+ if (kernelAccountAddress &&
770
+ kernelAccountAddress.toLowerCase() === expectedAddress.toLowerCase()) {
771
+ // Providers are valid, just switch to them
772
+ this.activeWalletAddress = expectedAddress;
773
+ this.eoaConnector = eoaConnector;
774
+ this.eoaAddress = eoaAddress;
775
+ this.userOperationCache = {};
776
+ return;
777
+ }
778
+ // Providers have wrong kernel account, need to regenerate
779
+ }
780
+ // Generate providers for this wallet
736
781
  yield this.setEoaConnector({
737
782
  connector: eoaConnector,
738
783
  eoaAddress,
739
784
  properties,
785
+ smartWalletAddress: expectedAddress,
740
786
  });
741
787
  });
742
788
  }
package/src/types.d.ts CHANGED
@@ -35,10 +35,13 @@ export type ZeroDevWalletProperties = {
35
35
  enableKernelV3Migration?: boolean;
36
36
  defaultToKernelWithSponsorship?: boolean;
37
37
  };
38
- export type ProviderMap = {
38
+ export type ChainProviderMap = {
39
39
  [chainId: string]: {
40
40
  signerAddress: string;
41
41
  kernelClient: KernelClient;
42
42
  kernelClientWithSponsorship: KernelClient;
43
43
  };
44
44
  };
45
+ export type ProviderMap = {
46
+ [walletAddress: string]: ChainProviderMap;
47
+ };