@dynamic-labs/ethereum-aa 4.0.0-alpha.3 → 4.0.0-alpha.31

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.
@@ -4,28 +4,33 @@
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var _tslib = require('../_virtual/_tslib.cjs');
7
- var multiChainValidator = require('@zerodev/multi-chain-validator');
8
7
  var viem = require('viem');
8
+ var accounts = require('viem/accounts');
9
9
  var utils$1 = require('permissionless/utils');
10
- var constants = require('@zerodev/sdk/constants');
11
- var ecdsaValidator = require('@zerodev/ecdsa-validator');
12
- var sdkApiCore = require('@dynamic-labs/sdk-api-core');
13
- var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
14
10
  var ethereumCore = require('@dynamic-labs/ethereum-core');
11
+ var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
15
12
  var utils = require('@dynamic-labs/utils');
16
- var fetchChain = require('./utils/fetchChain.cjs');
13
+ var constants = require('./constants.cjs');
17
14
  var logger = require('./utils/logger.cjs');
18
15
  var createEcsdaKernelAccountClient = require('./utils/createEcsdaKernelAccountClient.cjs');
16
+ var getEcdsaValidator = require('./utils/getEcdsaValidator.cjs');
17
+ var getEntryPoint = require('./utils/getEntryPoint.cjs');
18
+ var getKernelVersion = require('./utils/getKernelVersion.cjs');
19
19
 
20
20
  class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
21
21
  constructor(opts) {
22
22
  var _a, _b, _c, _d;
23
23
  super(opts);
24
+ // provider map maintains the kernel clients per chain
25
+ this.providerMap = {};
26
+ // eoa connector map maintains the eoa address and connector for each smart wallet address
27
+ this.eoaConnectorMap = {};
24
28
  this.ChainWallet = ethereumCore.EthereumWallet;
25
29
  this.connectedChain = 'EVM';
26
30
  this.supportedChains = ['ETH', 'EVM'];
27
31
  this.isGasSponsorshipDisabled = false;
28
32
  this.isEmbeddedWallet = true;
33
+ this.providersFromApi = [];
29
34
  this.name = 'ZeroDev';
30
35
  this.overrideKey = 'zerodev';
31
36
  this.walletFallback = {
@@ -35,59 +40,64 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
35
40
  },
36
41
  name: 'ZeroDev',
37
42
  };
38
- const zeroDevProjectId = (_a = opts.apiProviders.zerodev) === null || _a === void 0 ? void 0 : _a.clientId;
39
- if (!zeroDevProjectId) {
40
- throw new Error('Missing ZeroDev project ID provided. Add your ZeroDev project id to your project configuration via the Dynamic Labs dashboard.');
41
- }
42
- this.projectId = zeroDevProjectId;
43
43
  this._walletUiUtils = opts.walletUiUtils;
44
44
  this.evmNetworks = utils.parseEvmNetworks(opts.evmNetworks);
45
- this.entryPoint = this.getEntryPoint((_b = opts.apiProviders.zerodev) === null || _b === void 0 ? void 0 : _b.entryPointVersion);
46
- this.kernelVersion = this.getKernelVersion((_c = opts.apiProviders.zerodev) === null || _c === void 0 ? void 0 : _c.kernelVersion);
45
+ this.entryPoint = getEntryPoint.getEntryPoint((_a = opts.apiProviders.zerodev) === null || _a === void 0 ? void 0 : _a.entryPointVersion);
46
+ this.kernelVersion = getKernelVersion.getKernelVersion((_b = opts.apiProviders.zerodev) === null || _b === void 0 ? void 0 : _b.kernelVersion, this.entryPoint);
47
+ // this is the list of providers from the api that are used for multi-chain account abstraction
48
+ this.providersFromApi =
49
+ ((_c = opts.apiProviders.zerodev) === null || _c === void 0 ? void 0 : _c.multichainAccountAbstractionProviders) || [];
50
+ const [defaultProvider] = this.providersFromApi;
51
+ this.clientId = defaultProvider === null || defaultProvider === void 0 ? void 0 : defaultProvider.clientId;
52
+ if (!this.clientId) {
53
+ throw new Error('Missing ZeroDev project ID provided. Add your ZeroDev project id to your project configuration via the Dynamic Labs dashboard.');
54
+ }
55
+ this.defaultChainId = defaultProvider === null || defaultProvider === void 0 ? void 0 : defaultProvider.chain;
47
56
  this.ecdsaProviderType = (_d = opts.apiProviders.zerodev) === null || _d === void 0 ? void 0 : _d.ecdsaProviderType;
48
57
  }
49
- getEntryPoint(entryPoint) {
50
- if (entryPoint === undefined ||
51
- entryPoint === sdkApiCore.ProviderEntryPointVersionEnum.V7) {
52
- return utils$1.ENTRYPOINT_ADDRESS_V07;
58
+ get currentNetworkProvider() {
59
+ // check if the last used chain id is in the provider map
60
+ if (this.providerMap[this.lastUsedChainId]) {
61
+ return this.providerMap[this.lastUsedChainId];
53
62
  }
54
- else if (entryPoint === sdkApiCore.ProviderEntryPointVersionEnum.V6) {
55
- return utils$1.ENTRYPOINT_ADDRESS_V06;
56
- }
57
- else {
58
- logger.logger.error('Invalid entry point version', entryPoint);
59
- return utils$1.ENTRYPOINT_ADDRESS_V07;
63
+ // if not, check if the default chain id is in the provider map
64
+ if (this.defaultChainId) {
65
+ return this.providerMap[this.defaultChainId];
60
66
  }
67
+ // if no chain id is found, return undefined
68
+ return undefined;
61
69
  }
62
- getKernelVersion(kernelVersion) {
63
- if (kernelVersion === sdkApiCore.ProviderKernelVersionEnum.V31 ||
64
- (kernelVersion === undefined &&
65
- this.entryPoint === utils$1.ENTRYPOINT_ADDRESS_V07)) {
66
- return constants.KERNEL_V3_1;
67
- }
68
- else if (kernelVersion === sdkApiCore.ProviderKernelVersionEnum.V30) {
69
- return constants.KERNEL_V3_0;
70
- }
71
- else if (kernelVersion === sdkApiCore.ProviderKernelVersionEnum.V24 ||
72
- this.entryPoint === utils$1.ENTRYPOINT_ADDRESS_V06 // v0.6 only supports v2.4
73
- ) {
74
- return constants.KERNEL_V2_4;
75
- }
76
- else {
77
- logger.logger.error('Invalid kernel version', kernelVersion);
78
- return constants.KERNEL_V3_1;
79
- }
70
+ get lastUsedChainId() {
71
+ var _a;
72
+ const storedChainId = utils.StorageService.getItem(constants.ZERO_DEV_LAST_USED_CHAIN_ID_KEY);
73
+ // returning string of unknown if no chain id is found to result in undefined provider lookup
74
+ return (_a = storedChainId !== null && storedChainId !== void 0 ? storedChainId : this.defaultChainId) !== null && _a !== void 0 ? _a : 'unknown';
80
75
  }
81
- getEcdsaValidator(ecdsaProviderType) {
82
- if (ecdsaProviderType === 'zerodev_signer_to_ecdsa') {
83
- return ecdsaValidator.signerToEcdsaValidator;
84
- }
85
- else if (ecdsaProviderType === 'zerodev_multi_chain') {
86
- return multiChainValidator.toMultiChainECDSAValidator;
87
- }
88
- else {
89
- return ecdsaValidator.signerToEcdsaValidator;
90
- }
76
+ get kernelClient() {
77
+ var _a;
78
+ return (_a = this.currentNetworkProvider) === null || _a === void 0 ? void 0 : _a.kernelClient;
79
+ }
80
+ get kernelClientWithSponsorship() {
81
+ var _a;
82
+ return (_a = this.currentNetworkProvider) === null || _a === void 0 ? void 0 : _a.kernelClientWithSponsorship;
83
+ }
84
+ supportsNetworkSwitching() {
85
+ return (Object.keys(this.providerMap).length > 1 && this.evmNetworks.length > 1);
86
+ }
87
+ switchNetwork(_a) {
88
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ networkChainId, }) {
89
+ if (!this.supportsNetworkSwitching())
90
+ return;
91
+ if (!networkChainId)
92
+ return;
93
+ const chainId = networkChainId.toString();
94
+ if (!this.providerMap[chainId]) {
95
+ throw new Error(`No provider found for chainId: ${chainId}`);
96
+ }
97
+ utils.StorageService.setItem(constants.ZERO_DEV_LAST_USED_CHAIN_ID_KEY, chainId);
98
+ const { handleChainChange } = walletConnectorCore.eventListenerHandlers(this);
99
+ handleChainChange(chainId);
100
+ });
91
101
  }
92
102
  /**
93
103
  * @deprecated You should get the EOA connector by passing the SCW to getEOAConnector,
@@ -104,35 +114,120 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
104
114
  }
105
115
  endSession() {
106
116
  return _tslib.__awaiter(this, void 0, void 0, function* () {
107
- localStorage.removeItem(fetchChain.cachedChainIdKey);
117
+ utils.StorageService.removeItem(constants.ZERO_DEV_LAST_USED_CHAIN_ID_KEY);
108
118
  });
109
119
  }
110
- setEoaConnector(connector) {
111
- return _tslib.__awaiter(this, void 0, void 0, function* () {
120
+ registerEoa(_a) {
121
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ smartWalletAddress, eoaAddress, eoaConnector, shouldSetEoaConnector = false, ecdsaProviderType, kernelVersion, entryPointVersion, }) {
122
+ const properties = {
123
+ ecdsaProviderType,
124
+ entryPointVersion,
125
+ kernelVersion,
126
+ };
127
+ this.eoaConnectorMap[smartWalletAddress] = {
128
+ eoaAddress,
129
+ eoaConnector,
130
+ properties,
131
+ };
132
+ // if this is the primary wallet, set the eoa connector and kernel clients
133
+ if (shouldSetEoaConnector && this.eoaAddress !== eoaAddress) {
134
+ yield this.setEoaConnector({
135
+ connector: eoaConnector,
136
+ eoaAddress,
137
+ properties,
138
+ });
139
+ }
140
+ });
141
+ }
142
+ setEoaConnector(_a) {
143
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ eoaAddress, connector, properties, }) {
144
+ var _b;
112
145
  if (!connector) {
113
146
  logger.logger.error('No EOA connector provided');
114
147
  return;
115
148
  }
116
149
  this.kernelClientDeferredPromise = new utils.DeferredPromise();
117
150
  this.eoaConnector = connector;
151
+ this.eoaAddress = eoaAddress;
152
+ if (properties) {
153
+ this.ecdsaProviderType =
154
+ (_b = properties.ecdsaProviderType) !== null && _b !== void 0 ? _b : this.ecdsaProviderType;
155
+ this.entryPoint = properties.entryPointVersion
156
+ ? getEntryPoint.getEntryPoint(properties.entryPointVersion)
157
+ : this.entryPoint;
158
+ this.kernelVersion = properties.entryPointVersion
159
+ ? getKernelVersion.getKernelVersion(properties.kernelVersion, this.entryPoint)
160
+ : this.kernelVersion;
161
+ }
118
162
  if (ethereumCore.isEthWalletConnector(this.eoaConnector) &&
119
163
  !this.eoaConnector.getActiveAccount()) {
120
164
  yield this.eoaConnector.getConnectedAccounts();
121
165
  }
122
166
  const signer = yield this.eoaConnector.getSigner();
123
- if (!(signer === null || signer === void 0 ? void 0 : signer.account)) {
124
- logger.logger.error('No signer account found');
125
- return;
167
+ signer.account = accounts.toAccount(eoaAddress);
168
+ yield this.generateProviderMap(signer);
169
+ this.evmNetworks = this.evmNetworks.filter((network) => Boolean(this.providerMap[network.chainId]));
170
+ this.kernelClientDeferredPromise.resolve();
171
+ });
172
+ }
173
+ warnIfProjectChainNotEnabled(chainId) {
174
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
175
+ var _a;
176
+ let chainIdToCheck = chainId;
177
+ if (!chainIdToCheck) {
178
+ const client = yield this.getPublicClient();
179
+ chainIdToCheck = (_a = client === null || client === void 0 ? void 0 : client.chain) === null || _a === void 0 ? void 0 : _a.id;
180
+ }
181
+ const isProjectChainEnabled = this.evmNetworks.some((network) => network.chainId === chainIdToCheck);
182
+ if (!isProjectChainEnabled) {
183
+ logger.logger.error(`Please make sure to enable (${chainIdToCheck}) in the Dynamic dashboard (https://app.dynamic.xyz/dashboard/configurations#evm).`);
184
+ }
185
+ });
186
+ }
187
+ generateProviderMap(signer) {
188
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
189
+ // reset the chains provider map when eoa connector changes
190
+ this.providerMap = {};
191
+ yield Promise.all(this.providersFromApi.map((provider) => _tslib.__awaiter(this, void 0, void 0, function* () {
192
+ if (!this.providerMap[provider.chain]) {
193
+ const [kernelClient, kernelClientWithSponsorship] = yield Promise.all([
194
+ this.getKernelClientWithoutSponsorshipValidation({
195
+ chainId: provider.chain,
196
+ projectId: provider.clientId,
197
+ signer,
198
+ }),
199
+ this.getKernelClientWithSponsorshipValidation({
200
+ chainId: provider.chain,
201
+ projectId: provider.clientId,
202
+ signer,
203
+ }),
204
+ ]);
205
+ this.providerMap[provider.chain] = {
206
+ kernelClient,
207
+ kernelClientWithSponsorship,
208
+ };
209
+ }
210
+ yield this.warnIfProjectChainNotEnabled(utils.parseChainId(provider.chain));
211
+ })));
212
+ });
213
+ }
214
+ getKernelClientWithoutSponsorshipValidation(_a) {
215
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ projectId, signer, chainId, }) {
216
+ if (chainId && this.providerMap[chainId]) {
217
+ return this.providerMap[chainId].kernelClient;
126
218
  }
219
+ const { eoaConnector } = this;
220
+ if (!eoaConnector)
221
+ throw new utils.DynamicError('No EOA connector');
127
222
  const kernelClient = yield createEcsdaKernelAccountClient.createEcdsaKernelAccountClient({
128
223
  bundlerRpc: ZeroDevConnector.bundlerRpc,
129
- chain: yield fetchChain.fetchChain(this.projectId),
130
- ecdsaValidator: this.getEcdsaValidator(this.ecdsaProviderType),
224
+ chain: ethereumCore.chainsMap[chainId],
225
+ ecdsaValidator: getEcdsaValidator.getEcdsaValidator(this.ecdsaProviderType),
131
226
  entryPointAddress: this.entryPoint,
132
227
  kernelVersion: this.kernelVersion,
133
228
  paymaster: 'NONE',
134
229
  paymasterRpc: ZeroDevConnector.paymasterRpc,
135
- projectId: this.projectId,
230
+ projectId,
136
231
  provider: ZeroDevConnector.bundlerProvider,
137
232
  signer: utils$1.walletClientToSmartAccountSigner(signer),
138
233
  });
@@ -140,51 +235,34 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
140
235
  this._walletUiUtils.disabledConfirmationOnce();
141
236
  return original(...args);
142
237
  });
143
- this.kernelClient = kernelClient;
144
- // set the provider with sponsorship enabled
145
- yield this.getKernelClientWithSponsorshipValidation();
146
- yield this.checkIsProjectChainEnabled();
147
- this.kernelClientDeferredPromise.resolve();
148
- });
149
- }
150
- checkIsProjectChainEnabled() {
151
- return _tslib.__awaiter(this, void 0, void 0, function* () {
152
- var _a, _b;
153
- const client = yield this.getPublicClient();
154
- const chainName = (_a = client === null || client === void 0 ? void 0 : client.chain) === null || _a === void 0 ? void 0 : _a.name;
155
- const chainId = (_b = client === null || client === void 0 ? void 0 : client.chain) === null || _b === void 0 ? void 0 : _b.id;
156
- const isProjectChainEnabled = this.evmNetworks.some((network) => network.chainId === chainId);
157
- if (!isProjectChainEnabled) {
158
- logger.logger.error(`Please make sure to enable ${chainName} (${chainId}) in the Dynamic dashboard (https://app.dynamic.xyz/dashboard/configurations#evm).`);
159
- }
238
+ return kernelClient;
160
239
  });
161
240
  }
162
- getKernelClientWithSponsorshipValidation() {
163
- return _tslib.__awaiter(this, void 0, void 0, function* () {
164
- if (this.kernelClientWithSponsorship) {
165
- return this.kernelClientWithSponsorship;
241
+ getKernelClientWithSponsorshipValidation(_a) {
242
+ return _tslib.__awaiter(this, arguments, void 0, function* ({ projectId, signer, chainId, }) {
243
+ if (chainId && this.providerMap[chainId]) {
244
+ return this.providerMap[chainId].kernelClientWithSponsorship;
166
245
  }
167
246
  const { eoaConnector } = this;
168
247
  if (!eoaConnector)
169
248
  throw new utils.DynamicError('No EOA connector');
170
- const signer = yield eoaConnector.getSigner();
171
- this.kernelClientWithSponsorship = yield createEcsdaKernelAccountClient.createEcdsaKernelAccountClient({
249
+ const kernelClientWithSponsorship = yield createEcsdaKernelAccountClient.createEcdsaKernelAccountClient({
172
250
  bundlerRpc: ZeroDevConnector.bundlerRpc,
173
- chain: yield fetchChain.fetchChain(this.projectId),
174
- ecdsaValidator: this.getEcdsaValidator(this.ecdsaProviderType),
251
+ chain: ethereumCore.chainsMap[chainId],
252
+ ecdsaValidator: getEcdsaValidator.getEcdsaValidator(this.ecdsaProviderType),
175
253
  entryPointAddress: this.entryPoint,
176
254
  kernelVersion: this.kernelVersion,
177
255
  paymaster: 'SPONSOR',
178
256
  paymasterRpc: ZeroDevConnector.paymasterRpc,
179
- projectId: this.projectId,
257
+ projectId,
180
258
  provider: ZeroDevConnector.bundlerProvider,
181
259
  signer: utils$1.walletClientToSmartAccountSigner(signer),
182
260
  });
183
- utils.wrapMethodWithCallback(this.kernelClientWithSponsorship, 'sendUserOperation', (original, ...args) => {
261
+ utils.wrapMethodWithCallback(kernelClientWithSponsorship, 'sendUserOperation', (original, ...args) => {
184
262
  this._walletUiUtils.disabledConfirmationOnce();
185
263
  return original(...args);
186
264
  });
187
- return this.kernelClientWithSponsorship;
265
+ return kernelClientWithSponsorship;
188
266
  });
189
267
  }
190
268
  getAddress() {
@@ -225,7 +303,10 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
225
303
  this._walletUiUtils.disabledConfirmationOnce();
226
304
  const effectiveProvider = this.isGasSponsorshipDisabled
227
305
  ? provider
228
- : yield this.getKernelClientWithSponsorshipValidation();
306
+ : this.kernelClientWithSponsorship;
307
+ if (!effectiveProvider) {
308
+ throw new utils.DynamicError('No provider');
309
+ }
229
310
  const response = yield effectiveProvider.sendTransaction(ethereumCore.unFormatTransaction(transaction));
230
311
  return response;
231
312
  }
@@ -263,7 +344,7 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
263
344
  var _a;
264
345
  const provider = this.kernelClient;
265
346
  if (!provider)
266
- throw new utils.DynamicError('No provider');
347
+ return undefined;
267
348
  const transport = this.getTransport(provider);
268
349
  const address = (_a = provider.account) === null || _a === void 0 ? void 0 : _a.address;
269
350
  const walletClient = viem.createWalletClient({
@@ -278,7 +359,7 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
278
359
  var _a;
279
360
  const provider = (_a = this.kernelClient) === null || _a === void 0 ? void 0 : _a.extend(viem.publicActions);
280
361
  if (!provider)
281
- throw new utils.DynamicError('No provider');
362
+ return undefined;
282
363
  return provider;
283
364
  });
284
365
  }
@@ -290,7 +371,10 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
290
371
  canSponsorTransactionGas(transaction) {
291
372
  return _tslib.__awaiter(this, void 0, void 0, function* () {
292
373
  try {
293
- const kernelClientWithSponsorship = yield this.getKernelClientWithSponsorshipValidation();
374
+ const { kernelClientWithSponsorship } = this;
375
+ if (!kernelClientWithSponsorship) {
376
+ throw new utils.DynamicError('No kernel client with sponsorship found');
377
+ }
294
378
  const userOperation = {
295
379
  callData: yield kernelClientWithSponsorship.account.encodeCallData({
296
380
  data: transaction.data ? transaction.data : '0x',
@@ -351,23 +435,18 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
351
435
  });
352
436
  }
353
437
  validateActiveWallet(expectedAddress) {
354
- const _super = Object.create(null, {
355
- validateActiveWallet: { get: () => super.validateActiveWallet }
356
- });
357
438
  return _tslib.__awaiter(this, void 0, void 0, function* () {
358
- var _a;
359
- const eoaConnector = this === null || this === void 0 ? void 0 : this.eoaConnector;
360
- if (eoaConnector && walletConnectorCore.isTurnkeyWalletConnector(eoaConnector)) {
361
- const verifiedCredentials = eoaConnector === null || eoaConnector === void 0 ? void 0 : eoaConnector.verifiedCredentials;
362
- const expectedEoaAddress = (_a = verifiedCredentials === null || verifiedCredentials === void 0 ? void 0 : verifiedCredentials.find((vc) => vc.smartWalletRefAddress === expectedAddress)) === null || _a === void 0 ? void 0 : _a.address;
363
- if (!expectedEoaAddress) {
364
- throw new utils.DynamicError('No EOA connector');
365
- }
366
- yield (eoaConnector === null || eoaConnector === void 0 ? void 0 : eoaConnector.validateActiveWallet(expectedEoaAddress));
367
- }
368
- else {
369
- yield _super.validateActiveWallet.call(this, expectedAddress);
439
+ const eoa = this.eoaConnectorMap[expectedAddress];
440
+ if (!eoa) {
441
+ throw new utils.DynamicError('No EOA connector');
370
442
  }
443
+ const { eoaAddress, eoaConnector, properties } = eoa;
444
+ yield eoaConnector.validateActiveWallet(eoaAddress);
445
+ yield this.setEoaConnector({
446
+ connector: eoaConnector,
447
+ eoaAddress,
448
+ properties,
449
+ });
371
450
  });
372
451
  }
373
452
  }