@deserialize/multi-vm-wallet 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude/settings.local.json +8 -1
  2. package/dist/IChainWallet.d.ts +3 -3
  3. package/dist/evm/aa-service/index.d.ts +1 -1
  4. package/dist/evm/aa-service/index.js +1 -2
  5. package/dist/evm/aa-service/index.js.map +1 -1
  6. package/dist/evm/aa-service/lib/kernel-account.d.ts +1 -43
  7. package/dist/evm/aa-service/lib/kernel-account.js +21 -88
  8. package/dist/evm/aa-service/lib/kernel-account.js.map +1 -1
  9. package/dist/evm/aa-service/lib/type.d.ts +16 -0
  10. package/dist/evm/aa-service/lib/type.js.map +1 -1
  11. package/dist/evm/aa-service/services/account-abstraction.d.ts +4 -0
  12. package/dist/evm/aa-service/services/account-abstraction.js +12 -4
  13. package/dist/evm/aa-service/services/account-abstraction.js.map +1 -1
  14. package/dist/evm/aa-service/services/bundler.d.ts +4 -1
  15. package/dist/evm/aa-service/services/bundler.js +40 -7
  16. package/dist/evm/aa-service/services/bundler.js.map +1 -1
  17. package/dist/evm/evm.d.ts +3 -13
  18. package/dist/evm/evm.js +12 -80
  19. package/dist/evm/evm.js.map +1 -1
  20. package/dist/evm/smartWallet.d.ts +2 -19
  21. package/dist/evm/smartWallet.js +8 -68
  22. package/dist/evm/smartWallet.js.map +1 -1
  23. package/dist/evm/utils.js +2 -1
  24. package/dist/evm/utils.js.map +1 -1
  25. package/dist/helpers/index.d.ts +6 -1
  26. package/dist/helpers/index.js +116 -0
  27. package/dist/helpers/index.js.map +1 -1
  28. package/dist/svm/svm.d.ts +3 -3
  29. package/dist/svm/svm.js +6 -17
  30. package/dist/svm/svm.js.map +1 -1
  31. package/dist/svm/utils.d.ts +2 -2
  32. package/dist/svm/utils.js +4 -4
  33. package/dist/svm/utils.js.map +1 -1
  34. package/dist/test.d.ts +4 -0
  35. package/dist/test.js +66 -21
  36. package/dist/test.js.map +1 -1
  37. package/dist/types.d.ts +14 -16
  38. package/dist/types.js.map +1 -1
  39. package/package.json +7 -1
  40. package/utils/IChainWallet.ts +3 -3
  41. package/utils/evm/aa-service/index.ts +1 -2
  42. package/utils/evm/aa-service/lib/kernel-account.ts +22 -128
  43. package/utils/evm/aa-service/lib/type.ts +17 -0
  44. package/utils/evm/aa-service/services/account-abstraction.ts +18 -4
  45. package/utils/evm/aa-service/services/bundler.ts +53 -11
  46. package/utils/evm/evm.ts +13 -110
  47. package/utils/evm/smartWallet.ts +10 -88
  48. package/utils/evm/utils.ts +2 -1
  49. package/utils/helpers/index.ts +138 -1
  50. package/utils/svm/svm.ts +7 -25
  51. package/utils/svm/utils.ts +4 -10
  52. package/utils/test.ts +85 -21
  53. package/utils/types.ts +15 -17
  54. package/utils/evm/SMART_WALLET_EXAMPLES.ts.bak +0 -591
package/dist/types.d.ts CHANGED
@@ -16,19 +16,20 @@ export interface ChainWalletConfig {
16
16
  confirmationNo?: number;
17
17
  testnet?: boolean;
18
18
  vmType: vmTypes;
19
- aaSupport?: {
20
- enabled: boolean;
21
- entryPoints: {
22
- address: string;
23
- version: EntryPointVersion;
24
- }[];
25
- bundlerUrl: string;
26
- paymasterUrl: string;
27
- kernelImplementations: {
28
- address: string;
29
- version: number;
30
- }[];
31
- };
19
+ aaSupport?: AA_SupportConfig;
20
+ }
21
+ export interface AA_SupportConfig {
22
+ enabled: boolean;
23
+ entryPoints: {
24
+ address: string;
25
+ version: EntryPointVersion;
26
+ }[];
27
+ bundlerUrl: string;
28
+ paymasterUrl: string;
29
+ kernelImplementations: {
30
+ address: string;
31
+ version: number;
32
+ }[];
32
33
  }
33
34
  export interface TokenInfo {
34
35
  address: string;
@@ -202,9 +203,6 @@ export interface TransactionResult {
202
203
  success: boolean;
203
204
  error?: string;
204
205
  }
205
- export interface FeePayerOptions {
206
- privateKey: string;
207
- }
208
206
  export interface Balance {
209
207
  balance: BN;
210
208
  formatted: number;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../utils/types.ts"],"names":[],"mappings":";;;AACA,+BAA8B;AAC9B,+BAA8B;AAiRjB,QAAA,YAAY,GAAG;IACxB,KAAK,EAAE,WAAK;IACZ,KAAK,EAAE,WAAK;CACN,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../utils/types.ts"],"names":[],"mappings":";;;AACA,+BAA8B;AAC9B,+BAA8B;AA+QjB,QAAA,YAAY,GAAG;IACxB,KAAK,EAAE,WAAK;IACZ,KAAK,EAAE,WAAK;CACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deserialize/multi-vm-wallet",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "devDependencies": {
5
5
  "@types/bn.js": "^5.2.0",
6
6
  "@types/crypto-js": "^4.2.2",
@@ -16,15 +16,21 @@
16
16
  "@noble/hashes": "^1.3.3",
17
17
  "@scure/bip32": "^2.0.1",
18
18
  "@scure/bip39": "^2.0.1",
19
+ "@simplewebauthn/typescript-types": "^8.3.4",
19
20
  "@solana/spl-token": "^0.4.13",
20
21
  "@solana/web3.js": "^1.98.4",
22
+ "@zerodev/permissions": "^5.6.3",
23
+ "@zerodev/sdk": "^5.5.7",
24
+ "@zerodev/webauthn-key": "^5.5.0",
21
25
  "bignumber.js": "^9.3.1",
22
26
  "bn.js": "^5.2.2",
23
27
  "bs58": "^6.0.0",
24
28
  "crypto-js": "^4.2.0",
25
29
  "debonk-evm-sever-sdk": "^1.4.0",
26
30
  "ethers": "^6.15.0",
31
+ "permissionless": "^0.3.2",
27
32
  "promise-retry": "^2.0.1",
33
+ "tslib": "^2.8.1",
28
34
  "tweetnacl": "^1.0.3",
29
35
  "viem": "^2.43.4"
30
36
  },
@@ -1,6 +1,6 @@
1
1
  import { EVMTransactionHistoryItem } from "./evm/transactionParsing";
2
2
  import { SVMTransactionHistoryItem } from "./svm/transactionParsing";
3
- import { Balance, ChainWalletConfig, NFTInfo, TokenInfo, TransactionResult, UserTokenBalance, NFT, FeePayerOptions } from "./types";
3
+ import { Balance, ChainWalletConfig, NFTInfo, TokenInfo, TransactionResult, UserTokenBalance, NFT } from "./types";
4
4
 
5
5
  export abstract class ChainWallet<AddressType, PrivateKeyType, ConnectionType> {
6
6
  protected privateKey: PrivateKeyType;
@@ -20,8 +20,8 @@ export abstract class ChainWallet<AddressType, PrivateKeyType, ConnectionType> {
20
20
  abstract generateAddress(privateKey: PrivateKeyType): AddressType;
21
21
  abstract getNativeBalance(): Promise<Balance>;
22
22
  abstract getTokenBalance(tokenAddress: AddressType): Promise<Balance>;
23
- abstract transferNative(to: AddressType, amount: number, feePayerOptions?: FeePayerOptions): Promise<TransactionResult>;
24
- abstract transferToken(tokenAddress: TokenInfo, to: AddressType, amount: number, feePayerOptions?: FeePayerOptions): Promise<TransactionResult>;
23
+ abstract transferNative(to: AddressType, amount: number): Promise<TransactionResult>;
24
+ abstract transferToken(tokenAddress: TokenInfo, to: AddressType, amount: number): Promise<TransactionResult>;
25
25
  abstract swap(tokenAddress: TokenInfo, to: AddressType, amount: number, slippage?: number): Promise<TransactionResult>;
26
26
  abstract discoverToken(): Promise<UserTokenBalance<AddressType>[]>;
27
27
  abstract discoverNFT(): Promise<NFT[]>;
@@ -30,8 +30,7 @@ export {
30
30
  createKernelAuthorization,
31
31
  sendKernelTransaction,
32
32
  sendBatchTransaction,
33
- waitForKernelReceipt,
34
- sendSponsoredBatchTransaction
33
+ waitForKernelReceipt
35
34
  } from './lib/kernel-account';
36
35
 
37
36
 
@@ -9,7 +9,7 @@ import { Chain, Hex, parseEther, PublicClient, SignAuthorizationReturnType, crea
9
9
  import { PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts';
10
10
  import { createKernelAccount } from '@zerodev/sdk';
11
11
  import { KERNEL_V3_3, KernelVersionToAddressesMap } from '@zerodev/sdk/constants';
12
- import { entryPoint07Address, entryPoint08Address } from 'viem/account-abstraction';
12
+ import { createBundlerClient, entryPoint07Address, entryPoint08Address } from 'viem/account-abstraction';
13
13
  import { BundlerManager, createBundlerService } from '../services/bundler';
14
14
  import { BatchTransactionConfig, EntryPointVersion, KernelAccountConfig, KernelAccountInstance, KernelVersion, SingleTransactionConfig, Call } from './type';
15
15
 
@@ -47,7 +47,8 @@ export async function createKernel7702Account(
47
47
  owner,
48
48
  bundlerManager,
49
49
  entryPointVersion = '0.7',
50
- kernelVersion = '0.3.3'
50
+ kernelVersion = '0.3.3',
51
+ aaConfig
51
52
  } = config;
52
53
 
53
54
  // Create public client for standard RPC calls
@@ -57,11 +58,25 @@ export async function createKernel7702Account(
57
58
  transport: http()
58
59
  });
59
60
 
60
- // Get EntryPoint address
61
- const entryPointAddress = ENTRYPOINT_MAP[entryPointVersion];
62
-
63
- if (!entryPointAddress) {
64
- throw new Error(`Unsupported EntryPoint version: ${entryPointVersion}`);
61
+ // Get EntryPoint address from aaConfig or fallback to default
62
+ let entryPointAddress: Hex;
63
+
64
+ if (aaConfig && aaConfig.entryPoints.length > 0) {
65
+ // Find matching entry point from config
66
+ const entryPoint = aaConfig.entryPoints.find(ep => ep.version === entryPointVersion);
67
+ if (entryPoint) {
68
+ entryPointAddress = entryPoint.address as Hex;
69
+ } else {
70
+ // Fallback to first entry point if version not found
71
+ console.warn(`EntryPoint version ${entryPointVersion} not found in aaConfig, using first available`);
72
+ entryPointAddress = aaConfig.entryPoints[0].address as Hex;
73
+ }
74
+ } else {
75
+ // Fallback to hardcoded map if no config
76
+ entryPointAddress = ENTRYPOINT_MAP[entryPointVersion];
77
+ if (!entryPointAddress) {
78
+ throw new Error(`Unsupported EntryPoint version: ${entryPointVersion}`);
79
+ }
65
80
  }
66
81
 
67
82
  // Create Kernel account with EIP-7702
@@ -244,124 +259,3 @@ export async function waitForKernelReceipt(config: {
244
259
  return receipt;
245
260
  }
246
261
 
247
- // ============================================
248
- // Sponsored Transactions (EIP-7702)
249
- // ============================================
250
-
251
- /**
252
- * Configuration for sponsored batch transaction
253
- */
254
- export interface SponsoredBatchTransactionConfig {
255
- ownerAuthorization: SignAuthorizationReturnType;
256
- calls: Call[];
257
- feePayerPrivateKey: Hex;
258
- bundlerUrl: string;
259
- paymasterUrl?: string;
260
- chain: Chain;
261
- entryPointVersion?: EntryPointVersion;
262
- }
263
-
264
- /**
265
- * Send sponsored batch transaction using EIP-7702
266
- *
267
- * Allows a feePayer wallet to pay gas fees for another wallet's transaction.
268
- * The transaction executes from the owner's address, but gas is paid by the feePayer.
269
- *
270
- * @param config - Sponsored transaction configuration
271
- * @returns UserOperation hash and transaction hash
272
- *
273
- * @example
274
- * // Owner creates authorization
275
- * const authorization = await createKernelAuthorization({
276
- * owner: ownerAccount,
277
- * chain,
278
- * bundlerManager
279
- * });
280
- *
281
- * // FeePayer sends transaction
282
- * const result = await sendSponsoredBatchTransaction({
283
- * ownerAuthorization: authorization,
284
- * calls: [{ to: recipient, value: parseEther('0.1') }],
285
- * feePayerPrivateKey: sponsorPrivateKey,
286
- * bundlerUrl,
287
- * chain
288
- * });
289
- */
290
- export async function sendSponsoredBatchTransaction(
291
- config: SponsoredBatchTransactionConfig
292
- ): Promise<{ userOpHash: Hex; transactionHash?: string }> {
293
- const {
294
- ownerAuthorization,
295
- calls,
296
- feePayerPrivateKey,
297
- bundlerUrl,
298
- paymasterUrl,
299
- chain,
300
- entryPointVersion = '0.7'
301
- } = config;
302
-
303
- if (calls.length === 0) {
304
- throw new Error('Sponsored transaction must have at least one call');
305
- }
306
-
307
- // Create feePayer account
308
- const feePayerAccount = privateKeyToAccount(feePayerPrivateKey);
309
-
310
- // Create bundler service for feePayer
311
- const feePayerBundlerService = createBundlerService({
312
- provider: "custom",
313
- customUrl: bundlerUrl,
314
- chain
315
- });
316
-
317
- // Get bundler client (uses feePayer account internally)
318
- const bundlerClient = feePayerBundlerService.getClient(chain);
319
-
320
- // Create kernel account for feePayer (needed for sendUserOperation)
321
- const publicClient = createPublicClient({
322
- chain,
323
- transport: http(chain.rpcUrls.default.http[0])
324
- });
325
-
326
- const entryPointAddress = ENTRYPOINT_MAP[entryPointVersion];
327
- if (!entryPointAddress) {
328
- throw new Error(`Unsupported EntryPoint version: ${entryPointVersion}`);
329
- }
330
-
331
- const feePayerKernelAccount = await createKernelAccount(
332
- publicClient as any,
333
- {
334
- entryPoint: {
335
- address: entryPointAddress,
336
- version: entryPointVersion
337
- },
338
- kernelVersion: KERNEL_V3_3,
339
- eip7702Account: feePayerAccount as any
340
- }
341
- );
342
-
343
- // Normalize calls
344
- const normalizedCalls = calls.map(call => ({
345
- to: call.to,
346
- value: call.value ?? 0n,
347
- data: call.data ?? '0x' as Hex
348
- }));
349
-
350
- // Send UserOperation with owner's authorization
351
- // The transaction executes from owner's address, but feePayer pays gas
352
- const userOpHash = await bundlerClient.sendUserOperation({
353
- account: feePayerKernelAccount,
354
- authorization: ownerAuthorization,
355
- calls: normalizedCalls
356
- });
357
-
358
- // Wait for receipt
359
- const receipt = await bundlerClient.waitForUserOperationReceipt({
360
- hash: userOpHash
361
- });
362
-
363
- return {
364
- userOpHash: userOpHash as Hex,
365
- transactionHash: receipt?.receipt?.transactionHash
366
- };
367
- }
@@ -59,6 +59,7 @@ export interface KernelAccountConfig {
59
59
  bundlerManager: BundlerManager;
60
60
  entryPointVersion?: EntryPointVersion;
61
61
  kernelVersion?: KernelVersion;
62
+ aaConfig?: AA_SupportConfig;
62
63
  }
63
64
 
64
65
  export interface KernelAccountInstance {
@@ -79,7 +80,23 @@ export interface KernelAccountInstance {
79
80
 
80
81
 
81
82
 
83
+ export interface AA_SupportConfig {
84
+ enabled: boolean;
85
+ entryPoints: {
86
+ address: string;
87
+ version: EntryPointVersion;
88
+ }[]
89
+ bundlerUrl: string;
90
+ paymasterUrl: string;
91
+ kernelImplementations: {
92
+ address: string;
93
+ version: number;
94
+ }[];
95
+ }
96
+
82
97
  export interface SmartWalletOptions {
98
+ /** Full AA support configuration from chain config */
99
+ aaConfig?: AA_SupportConfig;
83
100
  /** Bundler URL for submitting UserOperations */
84
101
  bundlerUrl?: string;
85
102
  /** Paymaster URL for gas sponsorship (optional) */
@@ -60,16 +60,20 @@ import { ModularSigner } from '@zerodev/permissions';
60
60
  // Types
61
61
  // ============================================
62
62
 
63
+ import { AA_SupportConfig } from '../lib/type';
64
+
63
65
  export interface AAServiceConfig {
64
66
  bundlerProvider: 'pimlico' | 'etherspot' | 'custom';
65
67
  apiKey?: string;
66
68
  customBundlerUrl?: string;
69
+ aaConfig?: AA_SupportConfig;
67
70
  }
68
71
 
69
72
  export interface CreateAccountOptions {
70
73
  chain: Chain;
71
74
  owner: PrivateKeyAccount;
72
75
  entryPointVersion?: EntryPointVersion;
76
+ aaConfig?: AA_SupportConfig;
73
77
  }
74
78
 
75
79
  export interface SendTransactionOptions {
@@ -98,6 +102,7 @@ export interface WaitForReceiptOptions {
98
102
  export class AccountAbstractionService {
99
103
  private static instance: AccountAbstractionService | null = null;
100
104
  private bundlerManager: BundlerManager;
105
+ private aaConfig: AA_SupportConfig | undefined;
101
106
  private accountCache: Map<string, KernelAccountInstance> = new Map();
102
107
  private authorizationCache: Map<string, SignAuthorizationReturnType> = new Map();
103
108
  private publicClientCache: Map<number, PublicClient> = new Map();
@@ -109,9 +114,11 @@ export class AccountAbstractionService {
109
114
  const bundlerConfig: BundlerConfig = {
110
115
  provider: config.bundlerProvider,
111
116
  apiKey: config.apiKey,
112
- customUrl: config.customBundlerUrl
117
+ customUrl: config.customBundlerUrl,
118
+ aaConfig: config.aaConfig
113
119
  };
114
120
  this.bundlerManager = createBundlerManager(bundlerConfig);
121
+ this.aaConfig = config.aaConfig;
115
122
  }
116
123
 
117
124
  /**
@@ -142,10 +149,12 @@ export class AccountAbstractionService {
142
149
  const bundlerConfig: BundlerConfig = {
143
150
  provider: config.bundlerProvider,
144
151
  apiKey: config.apiKey,
145
- customUrl: config.customBundlerUrl
152
+ customUrl: config.customBundlerUrl,
153
+ aaConfig: config.aaConfig
146
154
  };
147
155
 
148
156
  this.bundlerManager = createBundlerManager(bundlerConfig);
157
+ this.aaConfig = config.aaConfig;
149
158
  this.clearCache();
150
159
  }
151
160
 
@@ -160,7 +169,8 @@ export class AccountAbstractionService {
160
169
  const {
161
170
  chain,
162
171
  owner,
163
- entryPointVersion = '0.7'
172
+ entryPointVersion = '0.7',
173
+ aaConfig
164
174
  } = options;
165
175
 
166
176
  const cacheKey = this.getAccountCacheKey(chain, owner, entryPointVersion);
@@ -170,12 +180,16 @@ export class AccountAbstractionService {
170
180
  return this.accountCache.get(cacheKey)!;
171
181
  }
172
182
 
183
+ // Use aaConfig from options or fallback to service-level config
184
+ const config = aaConfig || this.aaConfig;
185
+
173
186
  // Create new account
174
187
  const account = await createKernel7702Account({
175
188
  chain,
176
189
  owner,
177
190
  bundlerManager: this.bundlerManager,
178
- entryPointVersion
191
+ entryPointVersion,
192
+ aaConfig: config
179
193
  });
180
194
 
181
195
  // Cache and return
@@ -6,23 +6,26 @@
6
6
  */
7
7
 
8
8
  import { Chain, createPublicClient, http, publicActions, walletActions } from 'viem';
9
- import { createBundlerClient, entryPoint07Address, entryPoint08Address } from 'viem/account-abstraction';
10
-
9
+ import { BundlerClient, createBundlerClient, entryPoint07Address, entryPoint08Address } from 'viem/account-abstraction';
10
+ import { createPimlicoClient } from 'permissionless/clients/pimlico';
11
11
  // ============================================
12
12
  // Types
13
13
  // ============================================
14
14
 
15
15
  export type BundlerProvider = 'pimlico' | 'etherspot' | 'custom';
16
16
 
17
+ import type { AA_SupportConfig } from '../lib/type';
18
+
17
19
  export interface BundlerConfig {
18
20
  provider: BundlerProvider;
19
21
  apiKey?: string;
20
22
  customUrl?: string;
21
23
  chain?: Chain;
24
+ aaConfig?: AA_SupportConfig;
22
25
  }
23
26
 
24
27
  export interface BundlerService {
25
- getClient(chain: Chain): any;
28
+ getClient(chain: Chain): BundlerClient;
26
29
  getBundlerUrl(chain: Chain): string;
27
30
  getProvider(): string;
28
31
  }
@@ -34,26 +37,61 @@ export interface BundlerService {
34
37
  class PimlicoBundler implements BundlerService {
35
38
  private apiKey: string;
36
39
  private clientCache: Map<number, any> = new Map();
40
+ private url: string;
41
+ private aaConfig?: AA_SupportConfig;
37
42
 
38
- constructor(apiKey: string) {
39
- if (!apiKey) {
40
- throw new Error('Pimlico API key is required');
41
- }
43
+ constructor(apiKey: string, url: string, aaConfig?: AA_SupportConfig) {
44
+ this.url = url;
42
45
  this.apiKey = apiKey;
46
+ this.aaConfig = aaConfig;
43
47
  }
44
48
 
45
49
  getBundlerUrl(chain: Chain): string {
50
+ if (!this.apiKey) {
51
+ return this.url
52
+ }
46
53
  return `https://api.pimlico.io/v2/${chain.id}/rpc?apikey=${this.apiKey}`;
47
54
  }
48
55
 
49
- getClient(chain: Chain): any {
56
+ getClient(chain: Chain): BundlerClient {
50
57
  if (this.clientCache.has(chain.id)) {
51
58
  return this.clientCache.get(chain.id);
52
59
  }
60
+ const bundlerUrl = this.getBundlerUrl(chain);
61
+
62
+ // Get entryPoint from aaConfig or fallback to default
63
+ let entryPointAddress: `0x${string}`;
64
+ let entryPointVersion: '0.6' | '0.7' = '0.7';
65
+
66
+ if (this.aaConfig && this.aaConfig.entryPoints.length > 0) {
67
+ // Use first entry point from config (could be enhanced to select by version)
68
+ const ep = this.aaConfig.entryPoints[0];
69
+ entryPointAddress = ep.address as `0x${string}`;
70
+ entryPointVersion = ep.version;
71
+ } else {
72
+ // Fallback to hardcoded default
73
+ entryPointAddress = entryPoint07Address;
74
+ entryPointVersion = '0.7';
75
+ }
53
76
 
77
+ // Create Pimlico client for Pimlico-specific features (gas estimation)
78
+ const entryPoint = {
79
+ address: entryPointAddress,
80
+ version: entryPointVersion
81
+ };
82
+
83
+ const paymasterClient = createPimlicoClient({
84
+ transport: http(bundlerUrl),
85
+ entryPoint
86
+ });
87
+
88
+ // Create bundler client with Pimlico gas estimation
54
89
  const client = createBundlerClient({
55
- transport: http(this.getBundlerUrl(chain)),
56
- chain
90
+ transport: http(bundlerUrl),
91
+ chain,
92
+ userOperation: {
93
+ estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast,
94
+ }
57
95
  });
58
96
 
59
97
  this.clientCache.set(chain.id, client);
@@ -155,7 +193,11 @@ export class BundlerManager {
155
193
  constructor(config: BundlerConfig) {
156
194
  switch (config.provider) {
157
195
  case 'pimlico':
158
- this.bundlerService = new PimlicoBundler(config.apiKey!);
196
+ this.bundlerService = new PimlicoBundler(
197
+ config.apiKey ? config.apiKey : '',
198
+ config.customUrl ? config.customUrl : '',
199
+ config.aaConfig
200
+ );
159
201
  break;
160
202
  // case 'etherspot':
161
203
  // this.bundlerService = new EtherspotBundler();
package/utils/evm/evm.ts CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { EVMDeriveChildPrivateKey } from "../walletBip32";
8
8
  import { ChainWallet } from "../IChainWallet";
9
- import { Balance, ChainWalletConfig, NFTInfo, UserTokenBalance, TokenInfo, TransactionResult, NFT, FeePayerOptions } from "../types";
9
+ import { Balance, ChainWalletConfig, NFTInfo, UserTokenBalance, TokenInfo, TransactionResult, NFT } from "../types";
10
10
  import { VM } from "../vm";
11
11
  import { ethers, JsonRpcProvider, Wallet, formatUnits, Interface } from "ethers";
12
12
  import BN from "bn.js";
@@ -225,25 +225,17 @@ export class EVMChainWallet extends ChainWallet<string, string, JsonRpcProvider>
225
225
  */
226
226
  async extend(options: SmartWalletOptions = {}): Promise<EVMSmartWallet> {
227
227
  if (!this.smartWallet) {
228
- // Priority 1: Use bundlerUrl from options if provided (manual override)
229
- let bundlerUrl = options.bundlerUrl;
230
- let paymasterUrl = options.paymasterUrl;
231
- let entryPointVersion = options.entryPointVersion;
232
-
233
- // Priority 2: Use aaSupport config if available and no manual override
234
- if (!bundlerUrl && this.config.aaSupport?.enabled) {
235
- bundlerUrl = this.config.aaSupport.bundlerUrl;
236
- paymasterUrl = paymasterUrl || this.config.aaSupport.paymasterUrl;
237
-
238
- // Use the first entry point version if not specified
239
- if (!entryPointVersion && this.config.aaSupport.entryPoints.length > 0) {
240
- const version = this.config.aaSupport.entryPoints[0].version;
241
- entryPointVersion = version
242
- }
243
- }
228
+ // Merge options with aaSupport config (options take priority)
229
+ const mergedOptions: SmartWalletOptions = {
230
+ ...options,
231
+ aaConfig: this.config.aaSupport,
232
+ bundlerUrl: options.bundlerUrl || this.config.aaSupport?.bundlerUrl,
233
+ paymasterUrl: options.paymasterUrl || this.config.aaSupport?.paymasterUrl,
234
+ entryPointVersion: options.entryPointVersion || this.config.aaSupport?.entryPoints?.[0]?.version
235
+ };
244
236
 
245
237
  // Validate bundlerUrl is available
246
- if (!bundlerUrl) {
238
+ if (!mergedOptions.bundlerUrl) {
247
239
  throw new Error(
248
240
  'bundlerUrl is required to enable smart wallet features.\n' +
249
241
  'Provide it via:\n' +
@@ -278,12 +270,7 @@ export class EVMChainWallet extends ChainWallet<string, string, JsonRpcProvider>
278
270
  this.smartWallet = new EVMSmartWallet(
279
271
  this.privateKey,
280
272
  chain,
281
- bundlerUrl,
282
- {
283
- paymasterUrl,
284
- entryPointVersion,
285
- autoInitialize: options.autoInitialize
286
- }
273
+ mergedOptions
287
274
  );
288
275
 
289
276
  // Auto-initialize if option is set (default: true)
@@ -329,76 +316,6 @@ export class EVMChainWallet extends ChainWallet<string, string, JsonRpcProvider>
329
316
  }
330
317
  }
331
318
 
332
- // ============================================
333
- // Sponsored Transaction Helpers (EIP-7702)
334
- // ============================================
335
-
336
- /**
337
- * Transfer native tokens with sponsored gas (internal method)
338
- * Requires smart wallet to be initialized via extend()
339
- */
340
- private async transferNativeSponsored(
341
- to: string,
342
- amount: number,
343
- feePayerOptions: FeePayerOptions
344
- ): Promise<TransactionResult> {
345
- // Smart wallet is guaranteed to exist because validateAAAvailability() was called
346
- const call: Call = {
347
- to: to as Hex,
348
- value: parseEther(amount.toString()),
349
- data: '0x' as Hex
350
- };
351
-
352
- const result = await this.smartWallet!.sendSponsoredBatchTransaction(
353
- [call],
354
- feePayerOptions.privateKey as Hex
355
- );
356
-
357
- return {
358
- success: result.success,
359
- hash: result.transactionHash || '',
360
- error: result.error
361
- };
362
- }
363
-
364
- /**
365
- * Transfer tokens with sponsored gas (internal method)
366
- * Requires smart wallet to be initialized via extend()
367
- */
368
- private async transferTokenSponsored(
369
- tokenAddress: TokenInfo,
370
- to: string,
371
- amount: number,
372
- feePayerOptions: FeePayerOptions
373
- ): Promise<TransactionResult> {
374
- // Create ERC20 transfer call data
375
- const erc20Interface = new Interface([
376
- 'function transfer(address to, uint256 amount) returns (bool)'
377
- ]);
378
-
379
- const data = erc20Interface.encodeFunctionData('transfer', [
380
- to,
381
- parseUnits(amount.toString(), tokenAddress.decimals)
382
- ]);
383
-
384
- const call: Call = {
385
- to: tokenAddress.address as Hex,
386
- value: 0n,
387
- data: data as Hex
388
- };
389
-
390
- const result = await this.smartWallet!.sendSponsoredBatchTransaction(
391
- [call],
392
- feePayerOptions.privateKey as Hex
393
- );
394
-
395
- return {
396
- success: result.success,
397
- hash: result.transactionHash || '',
398
- error: result.error
399
- };
400
- }
401
-
402
319
  // ============================================
403
320
  // Existing Wallet Methods
404
321
  // ============================================
@@ -435,26 +352,12 @@ export class EVMChainWallet extends ChainWallet<string, string, JsonRpcProvider>
435
352
  return await discoverNFTs(this.address, this.config)
436
353
  }
437
354
 
438
- async transferNative(to: string, amount: number, feePayerOptions?: FeePayerOptions): Promise<TransactionResult> {
439
- // If feePayer is provided, use sponsored transaction (requires AA)
440
- if (feePayerOptions) {
441
- this.validateAAAvailability();
442
- return await this.transferNativeSponsored(to, amount, feePayerOptions);
443
- }
444
-
445
- // Regular transfer (existing implementation)
355
+ async transferNative(to: string, amount: number): Promise<TransactionResult> {
446
356
  const wallet = this.getWallet();
447
357
  return await sendNativeToken(wallet, to, amount.toString(), undefined, this.config.confirmationNo || 5);
448
358
  }
449
359
 
450
- async transferToken(tokenAddress: TokenInfo, to: string, amount: number, feePayerOptions?: FeePayerOptions): Promise<TransactionResult> {
451
- // If feePayer is provided, use sponsored transaction (requires AA)
452
- if (feePayerOptions) {
453
- this.validateAAAvailability();
454
- return await this.transferTokenSponsored(tokenAddress, to, amount, feePayerOptions);
455
- }
456
-
457
- // Regular transfer (existing implementation)
360
+ async transferToken(tokenAddress: TokenInfo, to: string, amount: number): Promise<TransactionResult> {
458
361
  const wallet = this.getWallet();
459
362
  return await sendERC20Token(wallet, tokenAddress.address, to, amount.toString(), undefined, this.config.confirmationNo || 5);
460
363
  }