@1llet.xyz/erc4337-gasless-sdk 0.1.1 → 0.1.4

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/dist/index.js DELETED
@@ -1,610 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- AccountAbstraction: () => AccountAbstraction,
24
- DEFAULT_ENTRYPOINT: () => DEFAULT_ENTRYPOINT,
25
- DEFAULT_FACTORY: () => DEFAULT_FACTORY,
26
- entryPointAbi: () => entryPointAbi,
27
- erc20Abi: () => erc20Abi,
28
- factoryAbi: () => factoryAbi,
29
- smartAccountAbi: () => smartAccountAbi
30
- });
31
- module.exports = __toCommonJS(index_exports);
32
-
33
- // src/AccountAbstraction.ts
34
- var import_viem = require("viem");
35
-
36
- // src/constants.ts
37
- var DEFAULT_ENTRYPOINT = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";
38
- var DEFAULT_FACTORY = "0x9406Cc6185a346906296840746125a0E44976454";
39
- var factoryAbi = [
40
- {
41
- inputs: [
42
- { name: "owner", type: "address" },
43
- { name: "salt", type: "uint256" }
44
- ],
45
- name: "getAccountAddress",
46
- outputs: [{ name: "", type: "address" }],
47
- stateMutability: "view",
48
- type: "function"
49
- },
50
- {
51
- inputs: [
52
- { name: "owner", type: "address" },
53
- { name: "salt", type: "uint256" }
54
- ],
55
- name: "isAccountDeployed",
56
- outputs: [{ name: "", type: "bool" }],
57
- stateMutability: "view",
58
- type: "function"
59
- },
60
- {
61
- inputs: [
62
- { name: "owner", type: "address" },
63
- { name: "salt", type: "uint256" }
64
- ],
65
- name: "createAccount",
66
- outputs: [{ name: "account", type: "address" }],
67
- stateMutability: "nonpayable",
68
- type: "function"
69
- }
70
- ];
71
- var entryPointAbi = [
72
- {
73
- inputs: [
74
- { name: "sender", type: "address" },
75
- { name: "key", type: "uint192" }
76
- ],
77
- name: "getNonce",
78
- outputs: [{ name: "nonce", type: "uint256" }],
79
- stateMutability: "view",
80
- type: "function"
81
- }
82
- ];
83
- var smartAccountAbi = [
84
- {
85
- inputs: [
86
- { name: "target", type: "address" },
87
- { name: "value", type: "uint256" },
88
- { name: "data", type: "bytes" }
89
- ],
90
- name: "execute",
91
- outputs: [],
92
- stateMutability: "nonpayable",
93
- type: "function"
94
- },
95
- {
96
- inputs: [
97
- { name: "targets", type: "address[]" },
98
- { name: "values", type: "uint256[]" },
99
- { name: "datas", type: "bytes[]" }
100
- ],
101
- name: "executeBatch",
102
- outputs: [],
103
- stateMutability: "nonpayable",
104
- type: "function"
105
- }
106
- ];
107
- var erc20Abi = [
108
- {
109
- inputs: [{ name: "account", type: "address" }],
110
- name: "balanceOf",
111
- outputs: [{ name: "", type: "uint256" }],
112
- stateMutability: "view",
113
- type: "function"
114
- },
115
- {
116
- inputs: [
117
- { name: "to", type: "address" },
118
- { name: "amount", type: "uint256" }
119
- ],
120
- name: "transfer",
121
- outputs: [{ name: "", type: "bool" }],
122
- stateMutability: "nonpayable",
123
- type: "function"
124
- },
125
- {
126
- inputs: [
127
- { name: "spender", type: "address" },
128
- { name: "amount", type: "uint256" }
129
- ],
130
- name: "approve",
131
- outputs: [{ name: "", type: "bool" }],
132
- stateMutability: "nonpayable",
133
- type: "function"
134
- },
135
- {
136
- inputs: [
137
- { name: "owner", type: "address" },
138
- { name: "spender", type: "address" }
139
- ],
140
- name: "allowance",
141
- outputs: [{ name: "", type: "uint256" }],
142
- stateMutability: "view",
143
- type: "function"
144
- },
145
- {
146
- inputs: [
147
- { name: "from", type: "address" },
148
- { name: "to", type: "address" },
149
- { name: "amount", type: "uint256" }
150
- ],
151
- name: "transferFrom",
152
- outputs: [{ name: "", type: "bool" }],
153
- stateMutability: "nonpayable",
154
- type: "function"
155
- },
156
- {
157
- inputs: [],
158
- name: "decimals",
159
- outputs: [{ name: "", type: "uint8" }],
160
- stateMutability: "view",
161
- type: "function"
162
- }
163
- ];
164
-
165
- // src/deployments.ts
166
- var DEPLOYMENTS = {
167
- // Base Mainnet
168
- 8453: {
169
- entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
170
- factory: "0xe2584152891E4769025807DEa0cD611F135aDC68",
171
- paymaster: "0x1e13Eb16C565E3f3FDe49A011755e50410bb1F95",
172
- usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
173
- },
174
- // Base Sepolia
175
- 84532: {
176
- entryPoint: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
177
- factory: "0x9406Cc6185a346906296840746125a0E44976454",
178
- usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
179
- }
180
- };
181
-
182
- // src/AccountAbstraction.ts
183
- var AccountAbstraction = class {
184
- constructor(chainConfig) {
185
- this.owner = null;
186
- this.smartAccountAddress = null;
187
- this.chainConfig = chainConfig;
188
- const chainId = chainConfig.chain.id;
189
- const defaults = DEPLOYMENTS[chainId];
190
- const entryPoint = chainConfig.entryPointAddress || defaults?.entryPoint;
191
- if (!entryPoint) throw new Error(`EntryPoint address not found for chain ${chainId}`);
192
- this.entryPointAddress = entryPoint;
193
- const factory = chainConfig.factoryAddress || defaults?.factory;
194
- if (!factory) throw new Error(`Factory address not found for chain ${chainId}`);
195
- this.factoryAddress = factory;
196
- const usdc = chainConfig.usdcAddress || defaults?.usdc;
197
- if (!usdc) throw new Error(`USDC address not found for chain ${chainId}`);
198
- this.usdcAddress = usdc;
199
- this.paymasterAddress = chainConfig.paymasterAddress || defaults?.paymaster;
200
- const rpcUrl = chainConfig.rpcUrl || chainConfig.chain.rpcUrls.default.http[0];
201
- this.publicClient = (0, import_viem.createPublicClient)({
202
- chain: chainConfig.chain,
203
- transport: (0, import_viem.http)(rpcUrl)
204
- });
205
- }
206
- /**
207
- * Connect to MetaMask and get the owner address
208
- */
209
- async connect() {
210
- if (typeof window === "undefined" || !window.ethereum) {
211
- throw new Error("MetaMask is not installed");
212
- }
213
- const accounts = await window.ethereum.request({
214
- method: "eth_requestAccounts"
215
- });
216
- if (!accounts || accounts.length === 0) {
217
- throw new Error("No accounts found");
218
- }
219
- const chainId = await window.ethereum.request({
220
- method: "eth_chainId"
221
- });
222
- const targetChainId = this.chainConfig.chain.id;
223
- if (parseInt(chainId, 16) !== targetChainId) {
224
- try {
225
- await window.ethereum.request({
226
- method: "wallet_switchEthereumChain",
227
- params: [{ chainId: "0x" + targetChainId.toString(16) }]
228
- });
229
- } catch (switchError) {
230
- const error = switchError;
231
- if (error.code === 4902) {
232
- await window.ethereum.request({
233
- method: "wallet_addEthereumChain",
234
- params: [
235
- {
236
- chainId: "0x" + targetChainId.toString(16),
237
- chainName: this.chainConfig.chain.name,
238
- nativeCurrency: this.chainConfig.chain.nativeCurrency,
239
- rpcUrls: [this.chainConfig.rpcUrl],
240
- blockExplorerUrls: this.chainConfig.chain.blockExplorers?.default?.url ? [this.chainConfig.chain.blockExplorers.default.url] : []
241
- }
242
- ]
243
- });
244
- } else {
245
- throw switchError;
246
- }
247
- }
248
- }
249
- this.owner = accounts[0];
250
- this.smartAccountAddress = await this.getSmartAccountAddress(this.owner);
251
- return {
252
- owner: this.owner,
253
- smartAccount: this.smartAccountAddress
254
- };
255
- }
256
- /**
257
- * Get the Smart Account address for an owner (counterfactual)
258
- */
259
- async getSmartAccountAddress(owner) {
260
- const address = await this.publicClient.readContract({
261
- address: this.factoryAddress,
262
- abi: factoryAbi,
263
- functionName: "getAccountAddress",
264
- args: [owner, 0n]
265
- // salt = 0
266
- });
267
- return address;
268
- }
269
- /**
270
- * Check if the Smart Account is deployed
271
- */
272
- async isAccountDeployed() {
273
- if (!this.smartAccountAddress) {
274
- throw new Error("Not connected");
275
- }
276
- const code = await this.publicClient.getCode({
277
- address: this.smartAccountAddress
278
- });
279
- return code !== void 0 && code !== "0x";
280
- }
281
- /**
282
- * Get the USDC balance of the Smart Account
283
- */
284
- async getUsdcBalance() {
285
- if (!this.smartAccountAddress) {
286
- throw new Error("Not connected");
287
- }
288
- return await this.publicClient.readContract({
289
- address: this.usdcAddress,
290
- abi: erc20Abi,
291
- functionName: "balanceOf",
292
- args: [this.smartAccountAddress]
293
- });
294
- }
295
- /**
296
- * Get the EOA's USDC balance
297
- */
298
- async getEoaUsdcBalance() {
299
- if (!this.owner) {
300
- throw new Error("Not connected");
301
- }
302
- return await this.publicClient.readContract({
303
- address: this.usdcAddress,
304
- abi: erc20Abi,
305
- functionName: "balanceOf",
306
- args: [this.owner]
307
- });
308
- }
309
- /**
310
- * Get the allowance of the Smart Account to spend the EOA's USDC
311
- */
312
- async getAllowance() {
313
- if (!this.owner || !this.smartAccountAddress) {
314
- throw new Error("Not connected");
315
- }
316
- return await this.publicClient.readContract({
317
- address: this.usdcAddress,
318
- abi: erc20Abi,
319
- functionName: "allowance",
320
- args: [this.owner, this.smartAccountAddress]
321
- });
322
- }
323
- /**
324
- * Get the nonce for the Smart Account
325
- */
326
- async getNonce() {
327
- if (!this.smartAccountAddress) {
328
- throw new Error("Not connected");
329
- }
330
- return await this.publicClient.readContract({
331
- address: this.entryPointAddress,
332
- abi: entryPointAbi,
333
- functionName: "getNonce",
334
- args: [this.smartAccountAddress, 0n]
335
- });
336
- }
337
- /**
338
- * Build initCode for account deployment
339
- */
340
- buildInitCode() {
341
- if (!this.owner) {
342
- throw new Error("Not connected");
343
- }
344
- const createAccountData = (0, import_viem.encodeFunctionData)({
345
- abi: factoryAbi,
346
- functionName: "createAccount",
347
- args: [this.owner, 0n]
348
- });
349
- return `${this.factoryAddress}${createAccountData.slice(2)}`;
350
- }
351
- /**
352
- * Estimate gas for a UserOperation
353
- */
354
- async estimateGas(userOp) {
355
- const response = await fetch(this.chainConfig.bundlerUrl, {
356
- method: "POST",
357
- headers: { "Content-Type": "application/json" },
358
- body: JSON.stringify({
359
- jsonrpc: "2.0",
360
- id: 1,
361
- method: "eth_estimateUserOperationGas",
362
- params: [
363
- {
364
- sender: userOp.sender,
365
- nonce: userOp.nonce ? "0x" + userOp.nonce.toString(16) : "0x0",
366
- initCode: userOp.initCode || "0x",
367
- callData: userOp.callData || "0x",
368
- paymasterAndData: userOp.paymasterAndData || "0x",
369
- signature: "0x"
370
- },
371
- this.entryPointAddress
372
- ]
373
- })
374
- });
375
- const result = await response.json();
376
- if (result.error) {
377
- throw new Error(result.error.message);
378
- }
379
- return result.result;
380
- }
381
- /**
382
- * Build a UserOperation for Batched Execution (e.g. USDC Transfer + Fee)
383
- */
384
- async buildUserOperationBatch(transactions) {
385
- if (!this.owner || !this.smartAccountAddress) {
386
- throw new Error("Not connected");
387
- }
388
- const isDeployed = await this.isAccountDeployed();
389
- const initCode = isDeployed ? "0x" : this.buildInitCode();
390
- const targets = transactions.map((tx) => tx.target);
391
- const values = transactions.map((tx) => tx.value);
392
- const datas = transactions.map((tx) => tx.data);
393
- const callData = (0, import_viem.encodeFunctionData)({
394
- abi: smartAccountAbi,
395
- functionName: "executeBatch",
396
- args: [targets, values, datas]
397
- });
398
- const nonce = await this.getNonce();
399
- const gasEstimate = await this.estimateGas({
400
- sender: this.smartAccountAddress,
401
- nonce,
402
- initCode,
403
- callData,
404
- paymasterAndData: this.paymasterAddress
405
- });
406
- return {
407
- sender: this.smartAccountAddress,
408
- nonce,
409
- initCode,
410
- callData,
411
- callGasLimit: BigInt(gasEstimate.callGasLimit),
412
- verificationGasLimit: BigInt(gasEstimate.verificationGasLimit),
413
- preVerificationGas: BigInt(gasEstimate.preVerificationGas),
414
- maxFeePerGas: BigInt(gasEstimate.maxFeePerGas),
415
- maxPriorityFeePerGas: BigInt(gasEstimate.maxPriorityFeePerGas),
416
- paymasterAndData: this.paymasterAddress,
417
- signature: "0x"
418
- };
419
- }
420
- /**
421
- * Build a UserOperation to ONLY deploy the account (empty callData)
422
- */
423
- async buildDeployUserOperation() {
424
- if (!this.owner || !this.smartAccountAddress) {
425
- throw new Error("Not connected");
426
- }
427
- const isDeployed = await this.isAccountDeployed();
428
- if (isDeployed) {
429
- throw new Error("Account is already deployed");
430
- }
431
- const initCode = this.buildInitCode();
432
- const callData = "0x";
433
- const nonce = await this.getNonce();
434
- const gasEstimate = await this.estimateGas({
435
- sender: this.smartAccountAddress,
436
- nonce,
437
- initCode,
438
- callData,
439
- paymasterAndData: this.paymasterAddress
440
- });
441
- return {
442
- sender: this.smartAccountAddress,
443
- nonce,
444
- initCode,
445
- callData,
446
- callGasLimit: BigInt(gasEstimate.callGasLimit),
447
- verificationGasLimit: BigInt(gasEstimate.verificationGasLimit),
448
- preVerificationGas: BigInt(gasEstimate.preVerificationGas),
449
- maxFeePerGas: BigInt(gasEstimate.maxFeePerGas),
450
- maxPriorityFeePerGas: BigInt(gasEstimate.maxPriorityFeePerGas),
451
- paymasterAndData: this.paymasterAddress,
452
- signature: "0x"
453
- };
454
- }
455
- /**
456
- * Calculate the UserOperation hash
457
- */
458
- getUserOpHash(userOp) {
459
- const packed = (0, import_viem.encodeAbiParameters)(
460
- [
461
- { type: "address" },
462
- { type: "uint256" },
463
- { type: "bytes32" },
464
- { type: "bytes32" },
465
- { type: "uint256" },
466
- { type: "uint256" },
467
- { type: "uint256" },
468
- { type: "uint256" },
469
- { type: "uint256" },
470
- { type: "bytes32" }
471
- ],
472
- [
473
- userOp.sender,
474
- userOp.nonce,
475
- (0, import_viem.keccak256)(userOp.initCode),
476
- (0, import_viem.keccak256)(userOp.callData),
477
- userOp.callGasLimit,
478
- userOp.verificationGasLimit,
479
- userOp.preVerificationGas,
480
- userOp.maxFeePerGas,
481
- userOp.maxPriorityFeePerGas,
482
- (0, import_viem.keccak256)(userOp.paymasterAndData)
483
- ]
484
- );
485
- const packedHash = (0, import_viem.keccak256)(packed);
486
- return (0, import_viem.keccak256)(
487
- (0, import_viem.encodeAbiParameters)(
488
- [{ type: "bytes32" }, { type: "address" }, { type: "uint256" }],
489
- [packedHash, this.entryPointAddress, BigInt(this.chainConfig.chain.id)]
490
- )
491
- );
492
- }
493
- /**
494
- * Sign a UserOperation with MetaMask
495
- */
496
- async signUserOperation(userOp) {
497
- if (!this.owner) {
498
- throw new Error("Not connected");
499
- }
500
- const userOpHash = this.getUserOpHash(userOp);
501
- const signature = await window.ethereum.request({
502
- method: "personal_sign",
503
- params: [userOpHash, this.owner]
504
- });
505
- return {
506
- ...userOp,
507
- signature
508
- };
509
- }
510
- /**
511
- * Send a signed UserOperation to the bundler
512
- */
513
- async sendUserOperation(userOp) {
514
- const response = await fetch(this.chainConfig.bundlerUrl, {
515
- method: "POST",
516
- headers: { "Content-Type": "application/json" },
517
- body: JSON.stringify({
518
- jsonrpc: "2.0",
519
- id: 1,
520
- method: "eth_sendUserOperation",
521
- params: [
522
- {
523
- sender: userOp.sender,
524
- nonce: "0x" + userOp.nonce.toString(16),
525
- initCode: userOp.initCode,
526
- callData: userOp.callData,
527
- callGasLimit: "0x" + userOp.callGasLimit.toString(16),
528
- verificationGasLimit: "0x" + userOp.verificationGasLimit.toString(16),
529
- preVerificationGas: "0x" + userOp.preVerificationGas.toString(16),
530
- maxFeePerGas: "0x" + userOp.maxFeePerGas.toString(16),
531
- maxPriorityFeePerGas: "0x" + userOp.maxPriorityFeePerGas.toString(16),
532
- paymasterAndData: userOp.paymasterAndData,
533
- signature: userOp.signature
534
- },
535
- this.entryPointAddress
536
- ]
537
- })
538
- });
539
- const result = await response.json();
540
- if (result.error) {
541
- throw new Error(result.error.message);
542
- }
543
- return result.result;
544
- }
545
- /**
546
- * Wait for a UserOperation to be confirmed
547
- */
548
- async waitForUserOperation(userOpHash, timeout = 6e4) {
549
- const startTime = Date.now();
550
- while (Date.now() - startTime < timeout) {
551
- const response = await fetch(this.chainConfig.bundlerUrl, {
552
- method: "POST",
553
- headers: { "Content-Type": "application/json" },
554
- body: JSON.stringify({
555
- jsonrpc: "2.0",
556
- id: 1,
557
- method: "eth_getUserOperationReceipt",
558
- params: [userOpHash]
559
- })
560
- });
561
- const result = await response.json();
562
- if (result.result) {
563
- return result.result;
564
- }
565
- await new Promise((resolve) => setTimeout(resolve, 2e3));
566
- }
567
- throw new Error("Timeout waiting for UserOperation");
568
- }
569
- /**
570
- * Request support for token approval (fund if needed)
571
- */
572
- async requestApprovalSupport(token, spender, amount) {
573
- if (!this.owner) {
574
- throw new Error("Not connected");
575
- }
576
- const response = await fetch(this.chainConfig.bundlerUrl, {
577
- method: "POST",
578
- headers: { "Content-Type": "application/json" },
579
- body: JSON.stringify({
580
- jsonrpc: "2.0",
581
- id: 1,
582
- method: "pm_requestApprovalSupport",
583
- params: [token, this.owner, spender, amount.toString()]
584
- })
585
- });
586
- const result = await response.json();
587
- if (result.error) {
588
- throw new Error(result.error.message);
589
- }
590
- return result.result;
591
- }
592
- // Getters
593
- getOwner() {
594
- return this.owner;
595
- }
596
- getSmartAccount() {
597
- return this.smartAccountAddress;
598
- }
599
- };
600
- // Annotate the CommonJS export names for ESM import in node:
601
- 0 && (module.exports = {
602
- AccountAbstraction,
603
- DEFAULT_ENTRYPOINT,
604
- DEFAULT_FACTORY,
605
- entryPointAbi,
606
- erc20Abi,
607
- factoryAbi,
608
- smartAccountAbi
609
- });
610
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AccountAbstraction.ts","../src/constants.ts","../src/deployments.ts"],"sourcesContent":["export * from \"./AccountAbstraction\";\nexport * from \"./types\";\nexport * from \"./constants\";\n","import {\n createPublicClient,\n http,\n encodeFunctionData,\n encodeAbiParameters,\n keccak256,\n type Address,\n type Hash,\n type Hex,\n type PublicClient\n} from \"viem\";\nimport {\n factoryAbi,\n entryPointAbi,\n smartAccountAbi,\n erc20Abi,\n} from \"./constants\";\nimport {\n type ChainConfig,\n type UserOperation,\n type GasEstimate,\n type UserOpReceipt,\n type ApprovalSupportResult\n} from \"./types\";\nimport { DEPLOYMENTS } from \"./deployments\";\n\n/**\n * ERC-4337 Account Abstraction Client\n */\nexport class AccountAbstraction {\n private owner: Address | null = null;\n private smartAccountAddress: Address | null = null;\n private chainConfig: ChainConfig;\n private publicClient: PublicClient;\n\n // Resolved addresses\n private entryPointAddress: Address;\n private factoryAddress: Address;\n private paymasterAddress?: Address;\n private usdcAddress: Address;\n\n constructor(chainConfig: ChainConfig) {\n this.chainConfig = chainConfig;\n const chainId = chainConfig.chain.id;\n const defaults = DEPLOYMENTS[chainId];\n\n // Resolve addresses (Config > Defaults > Error)\n const entryPoint = chainConfig.entryPointAddress || defaults?.entryPoint;\n if (!entryPoint) throw new Error(`EntryPoint address not found for chain ${chainId}`);\n this.entryPointAddress = entryPoint;\n\n const factory = chainConfig.factoryAddress || defaults?.factory;\n if (!factory) throw new Error(`Factory address not found for chain ${chainId}`);\n this.factoryAddress = factory;\n\n const usdc = chainConfig.usdcAddress || defaults?.usdc;\n if (!usdc) throw new Error(`USDC address not found for chain ${chainId}`);\n this.usdcAddress = usdc;\n\n this.paymasterAddress = chainConfig.paymasterAddress || defaults?.paymaster;\n\n // Use provided RPC or default from chain\n const rpcUrl = chainConfig.rpcUrl || chainConfig.chain.rpcUrls.default.http[0];\n\n this.publicClient = createPublicClient({\n chain: chainConfig.chain,\n transport: http(rpcUrl),\n });\n }\n\n /**\n * Connect to MetaMask and get the owner address\n */\n async connect(): Promise<{ owner: Address; smartAccount: Address }> {\n if (typeof window === \"undefined\" || !window.ethereum) {\n throw new Error(\"MetaMask is not installed\");\n }\n\n // Request account access\n const accounts = (await window.ethereum.request({\n method: \"eth_requestAccounts\",\n })) as string[];\n\n if (!accounts || accounts.length === 0) {\n throw new Error(\"No accounts found\");\n }\n\n // Check network\n const chainId = (await window.ethereum.request({\n method: \"eth_chainId\",\n })) as string;\n\n const targetChainId = this.chainConfig.chain.id;\n\n if (parseInt(chainId, 16) !== targetChainId) {\n // Switch to configured chain\n try {\n await window.ethereum.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: \"0x\" + targetChainId.toString(16) }],\n });\n } catch (switchError: unknown) {\n const error = switchError as { code?: number };\n // Chain not added, add it\n if (error.code === 4902) {\n await window.ethereum.request({\n method: \"wallet_addEthereumChain\",\n params: [\n {\n chainId: \"0x\" + targetChainId.toString(16),\n chainName: this.chainConfig.chain.name,\n nativeCurrency: this.chainConfig.chain.nativeCurrency,\n rpcUrls: [this.chainConfig.rpcUrl],\n blockExplorerUrls: this.chainConfig.chain.blockExplorers?.default?.url\n ? [this.chainConfig.chain.blockExplorers.default.url]\n : [],\n },\n ],\n });\n } else {\n throw switchError;\n }\n }\n }\n\n this.owner = accounts[0] as Address;\n this.smartAccountAddress = await this.getSmartAccountAddress(this.owner);\n\n return {\n owner: this.owner,\n smartAccount: this.smartAccountAddress,\n };\n }\n\n /**\n * Get the Smart Account address for an owner (counterfactual)\n */\n async getSmartAccountAddress(owner: Address): Promise<Address> {\n const address = await this.publicClient.readContract({\n address: this.factoryAddress,\n abi: factoryAbi,\n functionName: \"getAccountAddress\",\n args: [owner, 0n], // salt = 0\n }) as Address;\n return address;\n }\n\n /**\n * Check if the Smart Account is deployed\n */\n async isAccountDeployed(): Promise<boolean> {\n if (!this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n const code = await this.publicClient.getCode({\n address: this.smartAccountAddress,\n });\n return code !== undefined && code !== \"0x\";\n }\n\n\n /**\n * Get the USDC balance of the Smart Account\n */\n async getUsdcBalance(): Promise<bigint> {\n if (!this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n return await this.publicClient.readContract({\n address: this.usdcAddress,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [this.smartAccountAddress],\n }) as bigint;\n }\n\n\n /**\n * Get the EOA's USDC balance\n */\n async getEoaUsdcBalance(): Promise<bigint> {\n if (!this.owner) {\n throw new Error(\"Not connected\");\n }\n\n return await this.publicClient.readContract({\n address: this.usdcAddress,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [this.owner],\n }) as bigint;\n }\n\n /**\n * Get the allowance of the Smart Account to spend the EOA's USDC\n */\n async getAllowance(): Promise<bigint> {\n if (!this.owner || !this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n return await this.publicClient.readContract({\n address: this.usdcAddress,\n abi: erc20Abi,\n functionName: \"allowance\",\n args: [this.owner, this.smartAccountAddress],\n }) as bigint;\n }\n\n /**\n * Get the nonce for the Smart Account\n */\n async getNonce(): Promise<bigint> {\n if (!this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n return await this.publicClient.readContract({\n address: this.entryPointAddress,\n abi: entryPointAbi,\n functionName: \"getNonce\",\n args: [this.smartAccountAddress, 0n],\n }) as bigint;\n }\n\n /**\n * Build initCode for account deployment\n */\n buildInitCode(): Hex {\n if (!this.owner) {\n throw new Error(\"Not connected\");\n }\n\n const createAccountData = encodeFunctionData({\n abi: factoryAbi,\n functionName: \"createAccount\",\n args: [this.owner, 0n],\n });\n\n return `${this.factoryAddress}${createAccountData.slice(2)}` as Hex;\n }\n\n\n /**\n * Estimate gas for a UserOperation\n */\n async estimateGas(userOp: Partial<UserOperation>): Promise<GasEstimate> {\n const response = await fetch(this.chainConfig.bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_estimateUserOperationGas\",\n params: [\n {\n sender: userOp.sender,\n nonce: userOp.nonce ? \"0x\" + userOp.nonce.toString(16) : \"0x0\",\n initCode: userOp.initCode || \"0x\",\n callData: userOp.callData || \"0x\",\n paymasterAndData: userOp.paymasterAndData || \"0x\",\n signature: \"0x\",\n },\n this.entryPointAddress,\n ],\n }),\n });\n\n const result = await response.json();\n if (result.error) {\n throw new Error(result.error.message);\n }\n\n return result.result;\n }\n\n\n /**\n * Build a UserOperation for Batched Execution (e.g. USDC Transfer + Fee)\n */\n async buildUserOperationBatch(\n transactions: { target: Address; value: bigint; data: Hex }[]\n ): Promise<UserOperation> {\n if (!this.owner || !this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n const isDeployed = await this.isAccountDeployed();\n const initCode = isDeployed ? \"0x\" : this.buildInitCode();\n\n // Prepare arrays for executeBatch\n const targets = transactions.map((tx) => tx.target);\n const values = transactions.map((tx) => tx.value);\n const datas = transactions.map((tx) => tx.data);\n\n // Encode callData for executeBatch\n const callData = encodeFunctionData({\n abi: smartAccountAbi,\n functionName: \"executeBatch\",\n args: [targets, values, datas],\n });\n\n const nonce = await this.getNonce();\n\n // Estimate gas\n const gasEstimate = await this.estimateGas({\n sender: this.smartAccountAddress,\n nonce,\n initCode: initCode as Hex,\n callData,\n paymasterAndData: this.paymasterAddress as Hex,\n });\n\n return {\n sender: this.smartAccountAddress,\n nonce,\n initCode: initCode as Hex,\n callData,\n callGasLimit: BigInt(gasEstimate.callGasLimit),\n verificationGasLimit: BigInt(gasEstimate.verificationGasLimit),\n preVerificationGas: BigInt(gasEstimate.preVerificationGas),\n maxFeePerGas: BigInt(gasEstimate.maxFeePerGas),\n maxPriorityFeePerGas: BigInt(gasEstimate.maxPriorityFeePerGas),\n paymasterAndData: this.paymasterAddress as Hex,\n signature: \"0x\",\n };\n }\n\n /**\n * Build a UserOperation to ONLY deploy the account (empty callData)\n */\n async buildDeployUserOperation(): Promise<UserOperation> {\n if (!this.owner || !this.smartAccountAddress) {\n throw new Error(\"Not connected\");\n }\n\n const isDeployed = await this.isAccountDeployed();\n if (isDeployed) {\n throw new Error(\"Account is already deployed\");\n }\n\n const initCode = this.buildInitCode();\n const callData = \"0x\"; // Empty callData for deployment only\n const nonce = await this.getNonce();\n\n // Estimate gas\n const gasEstimate = await this.estimateGas({\n sender: this.smartAccountAddress,\n nonce,\n initCode: initCode as Hex,\n callData,\n paymasterAndData: this.paymasterAddress as Hex,\n });\n\n return {\n sender: this.smartAccountAddress,\n nonce,\n initCode: initCode as Hex,\n callData,\n callGasLimit: BigInt(gasEstimate.callGasLimit),\n verificationGasLimit: BigInt(gasEstimate.verificationGasLimit),\n preVerificationGas: BigInt(gasEstimate.preVerificationGas),\n maxFeePerGas: BigInt(gasEstimate.maxFeePerGas),\n maxPriorityFeePerGas: BigInt(gasEstimate.maxPriorityFeePerGas),\n paymasterAndData: this.paymasterAddress as Hex,\n signature: \"0x\",\n };\n }\n\n /**\n * Calculate the UserOperation hash\n */\n getUserOpHash(userOp: UserOperation): Hex {\n const packed = encodeAbiParameters(\n [\n { type: \"address\" },\n { type: \"uint256\" },\n { type: \"bytes32\" },\n { type: \"bytes32\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"uint256\" },\n { type: \"bytes32\" },\n ],\n [\n userOp.sender,\n userOp.nonce,\n keccak256(userOp.initCode),\n keccak256(userOp.callData),\n userOp.callGasLimit,\n userOp.verificationGasLimit,\n userOp.preVerificationGas,\n userOp.maxFeePerGas,\n userOp.maxPriorityFeePerGas,\n keccak256(userOp.paymasterAndData),\n ]\n );\n\n const packedHash = keccak256(packed);\n\n return keccak256(\n encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"address\" }, { type: \"uint256\" }],\n [packedHash, this.entryPointAddress, BigInt(this.chainConfig.chain.id)]\n )\n );\n }\n\n /**\n * Sign a UserOperation with MetaMask\n */\n async signUserOperation(userOp: UserOperation): Promise<UserOperation> {\n if (!this.owner) {\n throw new Error(\"Not connected\");\n }\n\n const userOpHash = this.getUserOpHash(userOp);\n\n // Sign with MetaMask using personal_sign (EIP-191)\n const signature = (await window.ethereum!.request({\n method: \"personal_sign\",\n params: [userOpHash, this.owner],\n })) as Hex;\n\n return {\n ...userOp,\n signature,\n };\n }\n\n /**\n * Send a signed UserOperation to the bundler\n */\n async sendUserOperation(userOp: UserOperation): Promise<Hash> {\n const response = await fetch(this.chainConfig.bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_sendUserOperation\",\n params: [\n {\n sender: userOp.sender,\n nonce: \"0x\" + userOp.nonce.toString(16),\n initCode: userOp.initCode,\n callData: userOp.callData,\n callGasLimit: \"0x\" + userOp.callGasLimit.toString(16),\n verificationGasLimit: \"0x\" + userOp.verificationGasLimit.toString(16),\n preVerificationGas: \"0x\" + userOp.preVerificationGas.toString(16),\n maxFeePerGas: \"0x\" + userOp.maxFeePerGas.toString(16),\n maxPriorityFeePerGas: \"0x\" + userOp.maxPriorityFeePerGas.toString(16),\n paymasterAndData: userOp.paymasterAndData,\n signature: userOp.signature,\n },\n this.entryPointAddress,\n ],\n }),\n });\n\n const result = await response.json();\n if (result.error) {\n throw new Error(result.error.message);\n }\n\n return result.result as Hash;\n }\n\n /**\n * Wait for a UserOperation to be confirmed\n */\n async waitForUserOperation(\n userOpHash: Hash,\n timeout = 60000\n ): Promise<UserOpReceipt> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n const response = await fetch(this.chainConfig.bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_getUserOperationReceipt\",\n params: [userOpHash],\n }),\n });\n\n const result = await response.json();\n if (result.result) {\n return result.result as UserOpReceipt;\n }\n\n // Wait 2 seconds before polling again\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n throw new Error(\"Timeout waiting for UserOperation\");\n }\n\n\n /**\n * Request support for token approval (fund if needed)\n */\n async requestApprovalSupport(\n token: Address,\n spender: Address,\n amount: bigint\n ): Promise<ApprovalSupportResult> {\n if (!this.owner) {\n throw new Error(\"Not connected\");\n }\n\n const response = await fetch(this.chainConfig.bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"pm_requestApprovalSupport\",\n params: [token, this.owner, spender, amount.toString()],\n }),\n });\n\n const result = await response.json();\n if (result.error) {\n throw new Error(result.error.message);\n }\n\n return result.result;\n }\n\n // Getters\n getOwner(): Address | null {\n return this.owner;\n }\n\n getSmartAccount(): Address | null {\n return this.smartAccountAddress;\n }\n}\n\n// Global window types for MetaMask\ndeclare global {\n interface Window {\n ethereum?: {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n on: (event: string, callback: (args: unknown) => void) => void;\n removeListener: (event: string, callback: (args: unknown) => void) => void;\n };\n }\n}\n","export const DEFAULT_ENTRYPOINT = \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\";\nexport const DEFAULT_FACTORY = \"0x9406Cc6185a346906296840746125a0E44976454\"; // SimpleAccountFactory v0.6\n\nexport const factoryAbi = [\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"salt\", type: \"uint256\" },\n ],\n name: \"getAccountAddress\",\n outputs: [{ name: \"\", type: \"address\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"salt\", type: \"uint256\" },\n ],\n name: \"isAccountDeployed\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"salt\", type: \"uint256\" },\n ],\n name: \"createAccount\",\n outputs: [{ name: \"account\", type: \"address\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const entryPointAbi = [\n {\n inputs: [\n { name: \"sender\", type: \"address\" },\n { name: \"key\", type: \"uint192\" },\n ],\n name: \"getNonce\",\n outputs: [{ name: \"nonce\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\nexport const smartAccountAbi = [\n {\n inputs: [\n { name: \"target\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"data\", type: \"bytes\" },\n ],\n name: \"execute\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"targets\", type: \"address[]\" },\n { name: \"values\", type: \"uint256[]\" },\n { name: \"datas\", type: \"bytes[]\" },\n ],\n name: \"executeBatch\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n] as const;\n\nexport const erc20Abi = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transfer\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"approve\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n name: \"allowance\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"transferFrom\",\n outputs: [{ name: \"\", type: \"bool\" }],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [],\n name: \"decimals\",\n outputs: [{ name: \"\", type: \"uint8\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n","import { type Address } from \"viem\";\n\nexport const DEPLOYMENTS: Record<number, {\n entryPoint: Address;\n factory: Address;\n paymaster?: Address;\n usdc: Address;\n}> = {\n // Base Mainnet\n 8453: {\n entryPoint: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n factory: \"0xe2584152891E4769025807DEa0cD611F135aDC68\",\n paymaster: \"0x1e13Eb16C565E3f3FDe49A011755e50410bb1F95\",\n usdc: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\"\n },\n // Base Sepolia\n 84532: {\n entryPoint: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n factory: \"0x9406Cc6185a346906296840746125a0E44976454\",\n usdc: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\"\n }\n};\n"],"mappings":"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","names":[]}