@dynamic-labs/ethereum-aa 4.0.0-alpha.8 → 4.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.
@@ -5,7 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var _tslib = require('../_virtual/_tslib.cjs');
7
7
  var viem = require('viem');
8
- var utils$1 = require('permissionless/utils');
8
+ var accounts = require('viem/accounts');
9
+ var constants$1 = require('@zerodev/sdk/constants');
9
10
  var ethereumCore = require('@dynamic-labs/ethereum-core');
10
11
  var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
11
12
  var utils = require('@dynamic-labs/utils');
@@ -20,7 +21,10 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
20
21
  constructor(opts) {
21
22
  var _a, _b, _c, _d;
22
23
  super(opts);
24
+ // provider map maintains the kernel clients per chain
23
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'];
@@ -113,23 +117,54 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
113
117
  utils.StorageService.removeItem(constants.ZERO_DEV_LAST_USED_CHAIN_ID_KEY);
114
118
  });
115
119
  }
116
- setEoaConnector(connector) {
117
- 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;
118
145
  if (!connector) {
119
146
  logger.logger.error('No EOA connector provided');
120
147
  return;
121
148
  }
122
149
  this.kernelClientDeferredPromise = new utils.DeferredPromise();
123
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
+ }
124
162
  if (ethereumCore.isEthWalletConnector(this.eoaConnector) &&
125
163
  !this.eoaConnector.getActiveAccount()) {
126
164
  yield this.eoaConnector.getConnectedAccounts();
127
165
  }
128
166
  const signer = yield this.eoaConnector.getSigner();
129
- if (!(signer === null || signer === void 0 ? void 0 : signer.account)) {
130
- logger.logger.error('No signer account found');
131
- return;
132
- }
167
+ signer.account = accounts.toAccount(eoaAddress);
133
168
  yield this.generateProviderMap(signer);
134
169
  this.evmNetworks = this.evmNetworks.filter((network) => Boolean(this.providerMap[network.chainId]));
135
170
  this.kernelClientDeferredPromise.resolve();
@@ -151,23 +186,29 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
151
186
  }
152
187
  generateProviderMap(signer) {
153
188
  return _tslib.__awaiter(this, void 0, void 0, function* () {
154
- for (const provider of this.providersFromApi) {
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* () {
155
192
  if (!this.providerMap[provider.chain]) {
156
- this.providerMap[provider.chain] = {
157
- kernelClient: yield this.getKernelClientWithoutSponsorshipValidation({
193
+ const [kernelClient, kernelClientWithSponsorship] = yield Promise.all([
194
+ this.getKernelClientWithoutSponsorshipValidation({
158
195
  chainId: provider.chain,
159
196
  projectId: provider.clientId,
160
197
  signer,
161
198
  }),
162
- kernelClientWithSponsorship: yield this.getKernelClientWithSponsorshipValidation({
199
+ this.getKernelClientWithSponsorshipValidation({
163
200
  chainId: provider.chain,
164
201
  projectId: provider.clientId,
165
202
  signer,
166
203
  }),
204
+ ]);
205
+ this.providerMap[provider.chain] = {
206
+ kernelClient,
207
+ kernelClientWithSponsorship,
167
208
  };
168
209
  }
169
210
  yield this.warnIfProjectChainNotEnabled(utils.parseChainId(provider.chain));
170
- }
211
+ })));
171
212
  });
172
213
  }
173
214
  getKernelClientWithoutSponsorshipValidation(_a) {
@@ -182,13 +223,13 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
182
223
  bundlerRpc: ZeroDevConnector.bundlerRpc,
183
224
  chain: ethereumCore.chainsMap[chainId],
184
225
  ecdsaValidator: getEcdsaValidator.getEcdsaValidator(this.ecdsaProviderType),
185
- entryPointAddress: this.entryPoint,
226
+ entryPoint: this.entryPoint,
186
227
  kernelVersion: this.kernelVersion,
187
228
  paymaster: 'NONE',
188
229
  paymasterRpc: ZeroDevConnector.paymasterRpc,
189
230
  projectId,
190
231
  provider: ZeroDevConnector.bundlerProvider,
191
- signer: utils$1.walletClientToSmartAccountSigner(signer),
232
+ signer,
192
233
  });
193
234
  utils.wrapMethodWithCallback(kernelClient, 'sendUserOperation', (original, ...args) => {
194
235
  this._walletUiUtils.disabledConfirmationOnce();
@@ -209,13 +250,13 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
209
250
  bundlerRpc: ZeroDevConnector.bundlerRpc,
210
251
  chain: ethereumCore.chainsMap[chainId],
211
252
  ecdsaValidator: getEcdsaValidator.getEcdsaValidator(this.ecdsaProviderType),
212
- entryPointAddress: this.entryPoint,
253
+ entryPoint: this.entryPoint,
213
254
  kernelVersion: this.kernelVersion,
214
255
  paymaster: 'SPONSOR',
215
256
  paymasterRpc: ZeroDevConnector.paymasterRpc,
216
257
  projectId,
217
258
  provider: ZeroDevConnector.bundlerProvider,
218
- signer: utils$1.walletClientToSmartAccountSigner(signer),
259
+ signer,
219
260
  });
220
261
  utils.wrapMethodWithCallback(kernelClientWithSponsorship, 'sendUserOperation', (original, ...args) => {
221
262
  this._walletUiUtils.disabledConfirmationOnce();
@@ -253,7 +294,6 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
253
294
  onPersonalSign: (_a) => _tslib.__awaiter(this, [_a], void 0, function* ({ message }) {
254
295
  this._walletUiUtils.disabledConfirmationOnce();
255
296
  return provider.signMessage({
256
- account: provider.account,
257
297
  message,
258
298
  });
259
299
  }),
@@ -284,7 +324,6 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
284
324
  this._walletUiUtils.disabledConfirmationOnce();
285
325
  const signTypedData = JSON.parse(message);
286
326
  return provider.signTypedData({
287
- account: provider.account,
288
327
  domain: signTypedData.domain,
289
328
  message: signTypedData.message,
290
329
  primaryType: signTypedData.primaryType,
@@ -300,14 +339,12 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
300
339
  return transport;
301
340
  }
302
341
  getWalletClient(chainId) {
303
- var _a;
304
342
  const provider = this.kernelClient;
305
343
  if (!provider)
306
344
  return undefined;
307
345
  const transport = this.getTransport(provider);
308
- const address = (_a = provider.account) === null || _a === void 0 ? void 0 : _a.address;
309
346
  const walletClient = viem.createWalletClient({
310
- account: address,
347
+ account: accounts.toAccount(provider.account.address),
311
348
  chain: chainId ? ethereumCore.chainsMap[chainId] : provider.chain,
312
349
  transport,
313
350
  });
@@ -327,38 +364,109 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
327
364
  return this.getWalletClient();
328
365
  });
329
366
  }
330
- canSponsorTransactionGas(transaction) {
367
+ formatUserOperation(params) {
368
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
369
+ var _a;
370
+ const kernelAccount = (_a = this.getAccountAbstractionProvider()) === null || _a === void 0 ? void 0 : _a.account;
371
+ const entryPoint = kernelAccount === null || kernelAccount === void 0 ? void 0 : kernelAccount.entryPoint;
372
+ const isV6 = (entryPoint === null || entryPoint === void 0 ? void 0 : entryPoint.address.toLowerCase()) ===
373
+ constants$1.getEntryPoint('0.6').address.toLowerCase();
374
+ if (isV6) {
375
+ return {
376
+ callData: params.callData,
377
+ callGasLimit: viem.toHex(params.callGasLimit),
378
+ // setting initCode to 0x since it is only used for transaction simulation
379
+ initCode: '0x',
380
+ maxFeePerGas: viem.toHex(params.maxFeePerGas),
381
+ maxPriorityFeePerGas: viem.toHex(params.maxPriorityFeePerGas),
382
+ nonce: viem.toHex(params.nonce),
383
+ paymasterAndData: params.paymasterAndData.toLowerCase(),
384
+ preVerificationGas: viem.toHex(params.preVerificationGas),
385
+ sender: params.sender,
386
+ signature: '0x',
387
+ verificationGasLimit: viem.toHex(params.verificationGasLimit),
388
+ };
389
+ }
390
+ const accountGasLimits = '0x' +
391
+ '000000000000000000000000000' + // 27 zeros
392
+ viem.toHex(params.verificationGasLimit).slice(2) +
393
+ '000000000000000000000000000' + // 27 zeros
394
+ viem.toHex(params.callGasLimit).slice(2);
395
+ const preVerificationGas = viem.toHex(params.preVerificationGas);
396
+ const gasFees = '0x' +
397
+ '00000000000000000000000000' + // 26 zeros
398
+ viem.toHex(params.maxPriorityFeePerGas).slice(2).padStart(6, '0') +
399
+ '0000000000000000000000' + // 22 zeros
400
+ viem.toHex(params.maxFeePerGas).slice(2).padStart(10, '0');
401
+ const paymasterAndData = params.paymaster
402
+ ? '0x' +
403
+ params.paymaster.slice(2).toLowerCase() +
404
+ viem.toHex(params.paymasterVerificationGasLimit).slice(2).padStart(32, '0') + // Make sure it's 32 chars
405
+ viem.toHex(params.paymasterPostOpGasLimit).slice(2).padStart(32, '0') + // Make sure it's 32 chars
406
+ params.paymasterData.slice(2) // Include full paymaster data
407
+ : '0x';
408
+ return {
409
+ accountGasLimits: accountGasLimits,
410
+ callData: params.callData,
411
+ gasFees: gasFees,
412
+ // setting initCode to 0x since it is only used for transaction simulation
413
+ initCode: '0x',
414
+ nonce: viem.toHex(params.nonce),
415
+ paymasterAndData: paymasterAndData.toLowerCase(),
416
+ preVerificationGas: preVerificationGas,
417
+ sender: params.sender,
418
+ signature: '0x',
419
+ };
420
+ });
421
+ }
422
+ getCurrentUserOperation(transaction) {
331
423
  return _tslib.__awaiter(this, void 0, void 0, function* () {
424
+ var _a, _b;
332
425
  try {
333
426
  const { kernelClientWithSponsorship } = this;
334
427
  if (!kernelClientWithSponsorship) {
335
428
  throw new utils.DynamicError('No kernel client with sponsorship found');
336
429
  }
337
- const userOperation = {
338
- callData: yield kernelClientWithSponsorship.account.encodeCallData({
430
+ const value = BigInt((_a = transaction.value) !== null && _a !== void 0 ? _a : 0);
431
+ const callData = yield kernelClientWithSponsorship.account.encodeCalls([
432
+ {
339
433
  data: transaction.data ? transaction.data : '0x',
340
434
  to: transaction.to,
341
- /**
342
- * if value is undefined, it will be set to 0x0 so the sponsorship
343
- * check does not fail
344
- */
345
- value: transaction.value && viem.isHex(transaction.value)
346
- ? viem.fromHex(transaction.value, 'bigint')
347
- : viem.fromHex('0x0', 'bigint'),
348
- }),
349
- };
350
- const result = yield kernelClientWithSponsorship.prepareUserOperationRequest({
351
- account: kernelClientWithSponsorship.account,
352
- userOperation,
353
- });
354
- if (!result)
355
- return false;
356
- return result.paymasterAndData !== '0x';
435
+ value,
436
+ },
437
+ ]);
438
+ let sponsorResult;
439
+ let unsponsoredResult;
440
+ try {
441
+ sponsorResult = yield kernelClientWithSponsorship.prepareUserOperation({
442
+ callData,
443
+ });
444
+ }
445
+ catch (err) {
446
+ logger.logger.debug('[ZeroDevConnector] Sponsored UserOp Attempt Failed:', err);
447
+ unsponsoredResult = yield ((_b = this.kernelClient) === null || _b === void 0 ? void 0 : _b.prepareUserOperation({
448
+ callData,
449
+ }));
450
+ }
451
+ if ((sponsorResult === null || sponsorResult === void 0 ? void 0 : sponsorResult.paymasterAndData) === '0x')
452
+ return { sponsored: false, userOperation: sponsorResult };
453
+ return sponsorResult
454
+ ? { sponsored: true, userOperation: sponsorResult }
455
+ : { sponsored: false, userOperation: unsponsoredResult };
357
456
  }
358
457
  catch (err) {
359
- logger.logger.debug(err);
458
+ logger.logger.debug('[ZeroDevConnector] Error in getCurrentUserOperation:', err);
459
+ return { sponsored: false, userOperation: undefined };
460
+ }
461
+ });
462
+ }
463
+ canSponsorTransactionGas(transaction) {
464
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
465
+ const { sponsored } = yield this.getCurrentUserOperation(transaction);
466
+ if (!sponsored) {
360
467
  return false;
361
468
  }
469
+ return sponsored;
362
470
  });
363
471
  }
364
472
  disableGasSponsorshipOnce() {
@@ -394,23 +502,18 @@ class ZeroDevConnector extends walletConnectorCore.WalletConnectorBase {
394
502
  });
395
503
  }
396
504
  validateActiveWallet(expectedAddress) {
397
- const _super = Object.create(null, {
398
- validateActiveWallet: { get: () => super.validateActiveWallet }
399
- });
400
505
  return _tslib.__awaiter(this, void 0, void 0, function* () {
401
- var _a;
402
- const eoaConnector = this === null || this === void 0 ? void 0 : this.eoaConnector;
403
- if (eoaConnector && walletConnectorCore.isTurnkeyWalletConnector(eoaConnector)) {
404
- const verifiedCredentials = eoaConnector === null || eoaConnector === void 0 ? void 0 : eoaConnector.verifiedCredentials;
405
- const expectedEoaAddress = (_a = verifiedCredentials === null || verifiedCredentials === void 0 ? void 0 : verifiedCredentials.find((vc) => vc.smartWalletRefAddress === expectedAddress)) === null || _a === void 0 ? void 0 : _a.address;
406
- if (!expectedEoaAddress) {
407
- throw new utils.DynamicError('No EOA connector');
408
- }
409
- yield (eoaConnector === null || eoaConnector === void 0 ? void 0 : eoaConnector.validateActiveWallet(expectedEoaAddress));
410
- }
411
- else {
412
- yield _super.validateActiveWallet.call(this, expectedAddress);
506
+ const eoa = this.eoaConnectorMap[expectedAddress];
507
+ if (!eoa) {
508
+ throw new utils.DynamicError('No EOA connector');
413
509
  }
510
+ const { eoaAddress, eoaConnector, properties } = eoa;
511
+ yield eoaConnector.validateActiveWallet(eoaAddress);
512
+ yield this.setEoaConnector({
513
+ connector: eoaConnector,
514
+ eoaAddress,
515
+ properties,
516
+ });
414
517
  });
415
518
  }
416
519
  }