@dynamic-labs/ethereum-aa 4.58.0 → 4.58.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.
- package/CHANGELOG.md +9 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +9 -9
- package/src/ZeroDevConnector.cjs +105 -59
- package/src/ZeroDevConnector.d.ts +3 -0
- package/src/ZeroDevConnector.js +105 -59
- package/src/types.d.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.58.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.58.0...v4.58.1) (2026-01-29)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* 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))
|
|
8
|
+
* 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))
|
|
9
|
+
* 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))
|
|
10
|
+
|
|
2
11
|
## [4.58.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.57.2...v4.58.0) (2026-01-28)
|
|
3
12
|
|
|
4
13
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/ethereum-aa",
|
|
3
|
-
"version": "4.58.
|
|
3
|
+
"version": "4.58.1",
|
|
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.
|
|
26
|
-
"@dynamic-labs/ethereum-aa-core": "4.58.
|
|
27
|
-
"@dynamic-labs/ethereum-core": "4.58.
|
|
28
|
-
"@dynamic-labs/logger": "4.58.
|
|
29
|
-
"@dynamic-labs/types": "4.58.
|
|
30
|
-
"@dynamic-labs/utils": "4.58.
|
|
31
|
-
"@dynamic-labs/wallet-book": "4.58.
|
|
32
|
-
"@dynamic-labs/wallet-connector-core": "4.58.
|
|
25
|
+
"@dynamic-labs/assert-package-version": "4.58.1",
|
|
26
|
+
"@dynamic-labs/ethereum-aa-core": "4.58.1",
|
|
27
|
+
"@dynamic-labs/ethereum-core": "4.58.1",
|
|
28
|
+
"@dynamic-labs/logger": "4.58.1",
|
|
29
|
+
"@dynamic-labs/types": "4.58.1",
|
|
30
|
+
"@dynamic-labs/utils": "4.58.1",
|
|
31
|
+
"@dynamic-labs/wallet-book": "4.58.1",
|
|
32
|
+
"@dynamic-labs/wallet-connector-core": "4.58.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"viem": "^2.28.4"
|
package/src/ZeroDevConnector.cjs
CHANGED
|
@@ -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
|
-
//
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
if (!this.activeWalletAddress) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const walletProviders = this.providerMap[this.activeWalletAddress];
|
|
98
|
+
if (!walletProviders) {
|
|
99
|
+
return undefined;
|
|
96
100
|
}
|
|
97
|
-
//
|
|
98
|
-
if (this.
|
|
99
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
223
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
yield
|
|
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
|
-
|
|
241
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
292
|
-
const uniqueChainProviderMap = Object.entries(
|
|
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
|
-
|
|
304
|
-
|
|
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
|
-
|
|
341
|
-
|
|
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
|
-
?
|
|
344
|
-
:
|
|
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
|
-
|
|
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>;
|
package/src/ZeroDevConnector.js
CHANGED
|
@@ -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
|
-
//
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
if (!this.activeWalletAddress) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const walletProviders = this.providerMap[this.activeWalletAddress];
|
|
94
|
+
if (!walletProviders) {
|
|
95
|
+
return undefined;
|
|
92
96
|
}
|
|
93
|
-
//
|
|
94
|
-
if (this.
|
|
95
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
219
|
-
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
yield
|
|
242
|
+
// Ensure the correct EOA account is active before getting the signer
|
|
243
|
+
if (isDynamicWaasConnector(connector)) {
|
|
244
|
+
yield connector.validateActiveWallet(eoaAddress);
|
|
235
245
|
}
|
|
236
|
-
|
|
237
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
288
|
-
const uniqueChainProviderMap = Object.entries(
|
|
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
|
-
|
|
300
|
-
|
|
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
|
-
|
|
337
|
-
|
|
352
|
+
(walletProviders === null || walletProviders === void 0 ? void 0 : walletProviders[chainId]) &&
|
|
353
|
+
walletProviders[chainId].signerAddress === signer.account.address) {
|
|
338
354
|
return paymaster === PaymasterTypeEnum.SPONSOR
|
|
339
|
-
?
|
|
340
|
-
:
|
|
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
|
-
|
|
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
|
|
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
|
+
};
|