@t402/wdk-gasless 1.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.
@@ -0,0 +1,727 @@
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
+ CHAIN_IDS: () => CHAIN_IDS,
24
+ DEFAULT_BUNDLER_URLS: () => DEFAULT_BUNDLER_URLS,
25
+ SAFE_4337_ADDRESSES: () => SAFE_4337_ADDRESSES,
26
+ USDC_ADDRESSES: () => USDC_ADDRESSES,
27
+ USDT0_ADDRESSES: () => USDT0_ADDRESSES,
28
+ WdkGaslessClient: () => WdkGaslessClient,
29
+ WdkSmartAccount: () => WdkSmartAccount,
30
+ createWdkGaslessClient: () => createWdkGaslessClient,
31
+ createWdkSmartAccount: () => createWdkSmartAccount,
32
+ getChainName: () => getChainName,
33
+ getTokenAddress: () => getTokenAddress
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/client.ts
38
+ var import_viem2 = require("viem");
39
+ var import_evm = require("@t402/evm");
40
+
41
+ // src/account.ts
42
+ var import_viem = require("viem");
43
+ var SAFE_4337_ADDRESSES = {
44
+ /** Safe 4337 Module */
45
+ module: "0xa581c4A4DB7175302464fF3C06380BC3270b4037",
46
+ /** Safe Module Setup */
47
+ moduleSetup: "0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47",
48
+ /** Safe Singleton */
49
+ singleton: "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762",
50
+ /** Safe Proxy Factory */
51
+ proxyFactory: "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67",
52
+ /** Safe Fallback Handler */
53
+ fallbackHandler: "0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99",
54
+ /** Add Modules Lib */
55
+ addModulesLib: "0x8EcD4ec46D4D2a6B64fE960B3D64e8B94B2234eb"
56
+ };
57
+ var PROXY_FACTORY_ABI = [
58
+ {
59
+ inputs: [
60
+ { name: "singleton", type: "address" },
61
+ { name: "initializer", type: "bytes" },
62
+ { name: "saltNonce", type: "uint256" }
63
+ ],
64
+ name: "createProxyWithNonce",
65
+ outputs: [{ name: "proxy", type: "address" }],
66
+ stateMutability: "nonpayable",
67
+ type: "function"
68
+ },
69
+ {
70
+ inputs: [
71
+ { name: "singleton", type: "address" },
72
+ { name: "initializer", type: "bytes" },
73
+ { name: "saltNonce", type: "uint256" }
74
+ ],
75
+ name: "proxyCreationCode",
76
+ outputs: [{ name: "", type: "bytes" }],
77
+ stateMutability: "view",
78
+ type: "function"
79
+ }
80
+ ];
81
+ var SAFE_ABI = [
82
+ {
83
+ inputs: [
84
+ { name: "owners", type: "address[]" },
85
+ { name: "threshold", type: "uint256" },
86
+ { name: "to", type: "address" },
87
+ { name: "data", type: "bytes" },
88
+ { name: "fallbackHandler", type: "address" },
89
+ { name: "paymentToken", type: "address" },
90
+ { name: "payment", type: "uint256" },
91
+ { name: "paymentReceiver", type: "address" }
92
+ ],
93
+ name: "setup",
94
+ outputs: [],
95
+ stateMutability: "nonpayable",
96
+ type: "function"
97
+ }
98
+ ];
99
+ var ADD_MODULES_LIB_ABI = [
100
+ {
101
+ inputs: [{ name: "modules", type: "address[]" }],
102
+ name: "enableModules",
103
+ outputs: [],
104
+ stateMutability: "nonpayable",
105
+ type: "function"
106
+ }
107
+ ];
108
+ var SAFE_4337_MODULE_ABI = [
109
+ {
110
+ inputs: [
111
+ { name: "to", type: "address" },
112
+ { name: "value", type: "uint256" },
113
+ { name: "data", type: "bytes" },
114
+ { name: "operation", type: "uint8" }
115
+ ],
116
+ name: "executeUserOp",
117
+ outputs: [],
118
+ stateMutability: "nonpayable",
119
+ type: "function"
120
+ },
121
+ {
122
+ inputs: [
123
+ { name: "tos", type: "address[]" },
124
+ { name: "values", type: "uint256[]" },
125
+ { name: "datas", type: "bytes[]" },
126
+ { name: "operations", type: "uint8[]" }
127
+ ],
128
+ name: "executeUserOpBatch",
129
+ outputs: [],
130
+ stateMutability: "nonpayable",
131
+ type: "function"
132
+ }
133
+ ];
134
+ var WdkSmartAccount = class {
135
+ wdkAccount;
136
+ publicClient;
137
+ chainId;
138
+ owners;
139
+ threshold;
140
+ saltNonce;
141
+ cachedAddress;
142
+ cachedInitCode;
143
+ cachedOwnerAddress;
144
+ deploymentChecked = false;
145
+ isAccountDeployed = false;
146
+ constructor(config) {
147
+ this.wdkAccount = config.wdkAccount;
148
+ this.publicClient = config.publicClient;
149
+ this.chainId = config.chainId;
150
+ this.threshold = config.threshold ?? 1;
151
+ this.saltNonce = config.saltNonce ?? 0n;
152
+ this.owners = config.additionalOwners ?? [];
153
+ }
154
+ /**
155
+ * Initialize the account (fetch WDK address)
156
+ * Call this before using the account
157
+ */
158
+ async initialize() {
159
+ if (!this.cachedOwnerAddress) {
160
+ const address = await this.wdkAccount.getAddress();
161
+ this.cachedOwnerAddress = address;
162
+ if (!this.owners.includes(this.cachedOwnerAddress)) {
163
+ this.owners.unshift(this.cachedOwnerAddress);
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Get the WDK account's EOA address
169
+ */
170
+ async getOwnerAddress() {
171
+ await this.initialize();
172
+ return this.cachedOwnerAddress;
173
+ }
174
+ /**
175
+ * Get the smart account address (counterfactual)
176
+ */
177
+ async getAddress() {
178
+ await this.initialize();
179
+ if (this.cachedAddress) {
180
+ return this.cachedAddress;
181
+ }
182
+ const initCode = await this.getInitCode();
183
+ if (initCode === "0x") {
184
+ const initializerData = await this.buildInitializer();
185
+ const salt = (0, import_viem.keccak256)(
186
+ (0, import_viem.encodeAbiParameters)(
187
+ [{ type: "bytes32" }, { type: "uint256" }],
188
+ [(0, import_viem.keccak256)(initializerData), this.saltNonce]
189
+ )
190
+ );
191
+ const proxyCreationCode = await this.publicClient.readContract({
192
+ address: SAFE_4337_ADDRESSES.proxyFactory,
193
+ abi: PROXY_FACTORY_ABI,
194
+ functionName: "proxyCreationCode",
195
+ args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce]
196
+ });
197
+ this.cachedAddress = (0, import_viem.getContractAddress)({
198
+ bytecode: proxyCreationCode,
199
+ from: SAFE_4337_ADDRESSES.proxyFactory,
200
+ opcode: "CREATE2",
201
+ salt
202
+ });
203
+ } else {
204
+ const initializerData = `0x${initCode.slice(2 + 40 * 2)}`;
205
+ const salt = (0, import_viem.keccak256)(
206
+ (0, import_viem.encodeAbiParameters)(
207
+ [{ type: "bytes32" }, { type: "uint256" }],
208
+ [(0, import_viem.keccak256)(initializerData), this.saltNonce]
209
+ )
210
+ );
211
+ const proxyCreationCode = await this.publicClient.readContract({
212
+ address: SAFE_4337_ADDRESSES.proxyFactory,
213
+ abi: PROXY_FACTORY_ABI,
214
+ functionName: "proxyCreationCode",
215
+ args: [SAFE_4337_ADDRESSES.singleton, initializerData, this.saltNonce]
216
+ });
217
+ this.cachedAddress = (0, import_viem.getContractAddress)({
218
+ bytecode: proxyCreationCode,
219
+ from: SAFE_4337_ADDRESSES.proxyFactory,
220
+ opcode: "CREATE2",
221
+ salt
222
+ });
223
+ }
224
+ return this.cachedAddress;
225
+ }
226
+ /**
227
+ * Sign a UserOperation hash using the WDK account
228
+ */
229
+ async signUserOpHash(userOpHash) {
230
+ await this.initialize();
231
+ const signature = await this.wdkAccount.signMessage(userOpHash);
232
+ return (0, import_viem.concat)([signature, "0x00"]);
233
+ }
234
+ /**
235
+ * Get the account's init code for deployment
236
+ */
237
+ async getInitCode() {
238
+ await this.initialize();
239
+ if (await this.isDeployed()) {
240
+ return "0x";
241
+ }
242
+ if (this.cachedInitCode) {
243
+ return this.cachedInitCode;
244
+ }
245
+ const safeSetupData = await this.buildInitializer();
246
+ const createProxyData = (0, import_viem.encodeFunctionData)({
247
+ abi: PROXY_FACTORY_ABI,
248
+ functionName: "createProxyWithNonce",
249
+ args: [SAFE_4337_ADDRESSES.singleton, safeSetupData, this.saltNonce]
250
+ });
251
+ this.cachedInitCode = (0, import_viem.concat)([
252
+ SAFE_4337_ADDRESSES.proxyFactory,
253
+ createProxyData
254
+ ]);
255
+ return this.cachedInitCode;
256
+ }
257
+ /**
258
+ * Check if the account is deployed
259
+ */
260
+ async isDeployed() {
261
+ if (this.deploymentChecked) {
262
+ return this.isAccountDeployed;
263
+ }
264
+ await this.initialize();
265
+ const address = this.cachedAddress ?? await this.getAddress();
266
+ const code = await this.publicClient.getCode({ address });
267
+ this.deploymentChecked = true;
268
+ this.isAccountDeployed = code !== void 0 && code !== "0x";
269
+ return this.isAccountDeployed;
270
+ }
271
+ /**
272
+ * Encode a call to the account's execute function
273
+ */
274
+ encodeExecute(target, value, data) {
275
+ return (0, import_viem.encodeFunctionData)({
276
+ abi: SAFE_4337_MODULE_ABI,
277
+ functionName: "executeUserOp",
278
+ args: [target, value, data, 0]
279
+ // operation: CALL
280
+ });
281
+ }
282
+ /**
283
+ * Encode a batch call to the account's executeBatch function
284
+ */
285
+ encodeExecuteBatch(targets, values, datas) {
286
+ if (targets.length !== values.length || targets.length !== datas.length) {
287
+ throw new Error("Array lengths must match");
288
+ }
289
+ const operations = targets.map(() => 0);
290
+ return (0, import_viem.encodeFunctionData)({
291
+ abi: SAFE_4337_MODULE_ABI,
292
+ functionName: "executeUserOpBatch",
293
+ args: [targets, values, datas, operations]
294
+ });
295
+ }
296
+ /**
297
+ * Build the Safe setup initializer data
298
+ */
299
+ async buildInitializer() {
300
+ await this.initialize();
301
+ const setupModulesData = (0, import_viem.encodeFunctionData)({
302
+ abi: ADD_MODULES_LIB_ABI,
303
+ functionName: "enableModules",
304
+ args: [[SAFE_4337_ADDRESSES.module]]
305
+ });
306
+ return (0, import_viem.encodeFunctionData)({
307
+ abi: SAFE_ABI,
308
+ functionName: "setup",
309
+ args: [
310
+ this.owners,
311
+ BigInt(this.threshold),
312
+ SAFE_4337_ADDRESSES.addModulesLib,
313
+ // to: AddModulesLib
314
+ setupModulesData,
315
+ // data: enableModules([module])
316
+ SAFE_4337_ADDRESSES.fallbackHandler,
317
+ "0x0000000000000000000000000000000000000000",
318
+ // paymentToken
319
+ 0n,
320
+ // payment
321
+ "0x0000000000000000000000000000000000000000"
322
+ // paymentReceiver
323
+ ]
324
+ });
325
+ }
326
+ /**
327
+ * Get the Safe's owners
328
+ */
329
+ getOwners() {
330
+ return [...this.owners];
331
+ }
332
+ /**
333
+ * Get the Safe's threshold
334
+ */
335
+ getThreshold() {
336
+ return this.threshold;
337
+ }
338
+ /**
339
+ * Clear cached values (useful after deployment)
340
+ */
341
+ clearCache() {
342
+ this.cachedAddress = void 0;
343
+ this.cachedInitCode = void 0;
344
+ this.deploymentChecked = false;
345
+ this.isAccountDeployed = false;
346
+ }
347
+ };
348
+ async function createWdkSmartAccount(config) {
349
+ const account = new WdkSmartAccount(config);
350
+ await account.initialize();
351
+ return account;
352
+ }
353
+
354
+ // src/constants.ts
355
+ var USDT0_ADDRESSES = {
356
+ ethereum: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee",
357
+ arbitrum: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
358
+ ink: "0x0200C29006150606B650577BBE7B6248F58470c1",
359
+ berachain: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
360
+ unichain: "0x588ce4F028D8e7B53B687865d6A67b3A54C75518",
361
+ base: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee",
362
+ optimism: "0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee"
363
+ };
364
+ var USDC_ADDRESSES = {
365
+ ethereum: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
366
+ arbitrum: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
367
+ base: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
368
+ optimism: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
369
+ polygon: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
370
+ };
371
+ var CHAIN_IDS = {
372
+ ethereum: 1,
373
+ arbitrum: 42161,
374
+ base: 8453,
375
+ optimism: 10,
376
+ polygon: 137,
377
+ ink: 57073,
378
+ berachain: 80084,
379
+ unichain: 130
380
+ };
381
+ var DEFAULT_BUNDLER_URLS = {
382
+ 1: "https://api.pimlico.io/v2/ethereum/rpc",
383
+ 42161: "https://api.pimlico.io/v2/arbitrum/rpc",
384
+ 8453: "https://api.pimlico.io/v2/base/rpc",
385
+ 10: "https://api.pimlico.io/v2/optimism/rpc",
386
+ 137: "https://api.pimlico.io/v2/polygon/rpc"
387
+ };
388
+ function getTokenAddress(token, chainName) {
389
+ if (token.startsWith("0x")) {
390
+ return token;
391
+ }
392
+ const addresses = token === "USDT0" ? USDT0_ADDRESSES : USDC_ADDRESSES;
393
+ const address = addresses[chainName.toLowerCase()];
394
+ if (!address) {
395
+ throw new Error(`Token ${token} not available on ${chainName}`);
396
+ }
397
+ return address;
398
+ }
399
+ function getChainName(chainId) {
400
+ const entry = Object.entries(CHAIN_IDS).find(([, id]) => id === chainId);
401
+ if (!entry) {
402
+ throw new Error(`Unsupported chain ID: ${chainId}`);
403
+ }
404
+ return entry[0];
405
+ }
406
+
407
+ // src/client.ts
408
+ var ERC20_TRANSFER_ABI = [
409
+ {
410
+ inputs: [
411
+ { name: "to", type: "address" },
412
+ { name: "amount", type: "uint256" }
413
+ ],
414
+ name: "transfer",
415
+ outputs: [{ name: "", type: "bool" }],
416
+ stateMutability: "nonpayable",
417
+ type: "function"
418
+ }
419
+ ];
420
+ var ERC20_BALANCE_ABI = [
421
+ {
422
+ inputs: [{ name: "account", type: "address" }],
423
+ name: "balanceOf",
424
+ outputs: [{ name: "", type: "uint256" }],
425
+ stateMutability: "view",
426
+ type: "function"
427
+ }
428
+ ];
429
+ var WdkGaslessClient = class {
430
+ signer;
431
+ builder;
432
+ bundler;
433
+ paymaster;
434
+ chainId;
435
+ publicClient;
436
+ chainName;
437
+ constructor(config) {
438
+ this.signer = config.signer;
439
+ this.builder = new import_evm.UserOpBuilder();
440
+ this.bundler = new import_evm.BundlerClient(config.bundler);
441
+ this.paymaster = config.paymaster ? new import_evm.PaymasterClient(config.paymaster) : void 0;
442
+ this.chainId = config.chainId;
443
+ this.publicClient = config.publicClient;
444
+ this.chainName = getChainName(config.chainId);
445
+ }
446
+ /**
447
+ * Execute a gasless payment
448
+ *
449
+ * Sends USDT0 (or other tokens) without the user paying gas fees.
450
+ * Gas is sponsored by a paymaster if configured.
451
+ */
452
+ async pay(params) {
453
+ const token = params.token ?? "USDT0";
454
+ const tokenAddress = getTokenAddress(token, this.chainName);
455
+ const callData = (0, import_viem2.encodeFunctionData)({
456
+ abi: ERC20_TRANSFER_ABI,
457
+ functionName: "transfer",
458
+ args: [params.to, params.amount]
459
+ });
460
+ const intent = {
461
+ to: tokenAddress,
462
+ value: 0n,
463
+ data: callData
464
+ };
465
+ const gasEstimate = await this.estimateGas(intent);
466
+ const paymasterData = await this.getPaymasterData(gasEstimate);
467
+ const sponsored = paymasterData !== void 0;
468
+ const userOp = await this.builder.buildUserOp(
469
+ this.signer,
470
+ intent,
471
+ this.publicClient,
472
+ gasEstimate,
473
+ paymasterData
474
+ );
475
+ const signedUserOp = await this.builder.signUserOp(
476
+ userOp,
477
+ this.signer,
478
+ this.publicClient,
479
+ this.chainId
480
+ );
481
+ const result = await this.bundler.sendUserOperation(signedUserOp);
482
+ const sender = await this.signer.getAddress();
483
+ return {
484
+ userOpHash: result.userOpHash,
485
+ sender,
486
+ sponsored,
487
+ wait: async () => {
488
+ const receipt = await result.wait();
489
+ return {
490
+ userOpHash: receipt.userOpHash,
491
+ txHash: receipt.receipt.transactionHash,
492
+ blockNumber: receipt.receipt.blockNumber,
493
+ success: receipt.success,
494
+ gasUsed: receipt.actualGasUsed,
495
+ gasCost: receipt.actualGasCost,
496
+ reason: receipt.reason
497
+ };
498
+ }
499
+ };
500
+ }
501
+ /**
502
+ * Execute multiple payments in a single transaction
503
+ *
504
+ * More gas efficient than individual payments.
505
+ * All payments are executed atomically.
506
+ */
507
+ async payBatch(params) {
508
+ const intents = params.payments.map((payment) => {
509
+ const token = payment.token ?? "USDT0";
510
+ const tokenAddress = getTokenAddress(token, this.chainName);
511
+ return {
512
+ to: tokenAddress,
513
+ value: 0n,
514
+ data: (0, import_viem2.encodeFunctionData)({
515
+ abi: ERC20_TRANSFER_ABI,
516
+ functionName: "transfer",
517
+ args: [payment.to, payment.amount]
518
+ })
519
+ };
520
+ });
521
+ const gasEstimate = await this.estimateBatchGas(intents);
522
+ const paymasterData = await this.getPaymasterData(gasEstimate);
523
+ const sponsored = paymasterData !== void 0;
524
+ const userOp = await this.builder.buildBatchUserOp(
525
+ this.signer,
526
+ intents,
527
+ this.publicClient,
528
+ gasEstimate,
529
+ paymasterData
530
+ );
531
+ const signedUserOp = await this.builder.signUserOp(
532
+ userOp,
533
+ this.signer,
534
+ this.publicClient,
535
+ this.chainId
536
+ );
537
+ const result = await this.bundler.sendUserOperation(signedUserOp);
538
+ const sender = await this.signer.getAddress();
539
+ return {
540
+ userOpHash: result.userOpHash,
541
+ sender,
542
+ sponsored,
543
+ wait: async () => {
544
+ const receipt = await result.wait();
545
+ return {
546
+ userOpHash: receipt.userOpHash,
547
+ txHash: receipt.receipt.transactionHash,
548
+ blockNumber: receipt.receipt.blockNumber,
549
+ success: receipt.success,
550
+ gasUsed: receipt.actualGasUsed,
551
+ gasCost: receipt.actualGasCost,
552
+ reason: receipt.reason
553
+ };
554
+ }
555
+ };
556
+ }
557
+ /**
558
+ * Check if a payment can be sponsored (free gas)
559
+ */
560
+ async canSponsor(params) {
561
+ if (!this.paymaster) {
562
+ return {
563
+ canSponsor: false,
564
+ reason: "No paymaster configured"
565
+ };
566
+ }
567
+ const token = params.token ?? "USDT0";
568
+ const tokenAddress = getTokenAddress(token, this.chainName);
569
+ const callData = (0, import_viem2.encodeFunctionData)({
570
+ abi: ERC20_TRANSFER_ABI,
571
+ functionName: "transfer",
572
+ args: [params.to, params.amount]
573
+ });
574
+ const sender = await this.signer.getAddress();
575
+ const encodedCallData = this.signer.encodeExecute(tokenAddress, 0n, callData);
576
+ try {
577
+ const canSponsor = await this.paymaster.willSponsor(
578
+ { sender, callData: encodedCallData },
579
+ this.chainId,
580
+ import_evm.ENTRYPOINT_V07_ADDRESS
581
+ );
582
+ if (canSponsor) {
583
+ return { canSponsor: true };
584
+ } else {
585
+ const intent = {
586
+ to: tokenAddress,
587
+ value: 0n,
588
+ data: callData
589
+ };
590
+ const gasEstimate = await this.estimateGas(intent);
591
+ const gasPrice = await this.publicClient.getGasPrice();
592
+ const estimatedGasCost = (gasEstimate.verificationGasLimit + gasEstimate.callGasLimit + gasEstimate.preVerificationGas) * gasPrice;
593
+ return {
594
+ canSponsor: false,
595
+ reason: "Payment not eligible for sponsorship",
596
+ estimatedGasCost
597
+ };
598
+ }
599
+ } catch (error) {
600
+ return {
601
+ canSponsor: false,
602
+ reason: error instanceof Error ? error.message : "Unknown error"
603
+ };
604
+ }
605
+ }
606
+ /**
607
+ * Get the smart account address
608
+ */
609
+ async getAccountAddress() {
610
+ return this.signer.getAddress();
611
+ }
612
+ /**
613
+ * Check if the smart account is deployed
614
+ */
615
+ async isAccountDeployed() {
616
+ return this.signer.isDeployed();
617
+ }
618
+ /**
619
+ * Get the token balance of the smart account
620
+ */
621
+ async getBalance(token = "USDT0") {
622
+ const tokenAddress = getTokenAddress(token, this.chainName);
623
+ const accountAddress = await this.signer.getAddress();
624
+ const balance = await this.publicClient.readContract({
625
+ address: tokenAddress,
626
+ abi: ERC20_BALANCE_ABI,
627
+ functionName: "balanceOf",
628
+ args: [accountAddress]
629
+ });
630
+ return balance;
631
+ }
632
+ /**
633
+ * Get the formatted token balance
634
+ */
635
+ async getFormattedBalance(token = "USDT0", decimals = 6) {
636
+ const balance = await this.getBalance(token);
637
+ return (0, import_viem2.formatUnits)(balance, decimals);
638
+ }
639
+ /**
640
+ * Estimate gas for a single transaction
641
+ */
642
+ async estimateGas(intent) {
643
+ const sender = await this.signer.getAddress();
644
+ const callData = this.signer.encodeExecute(
645
+ intent.to,
646
+ intent.value ?? 0n,
647
+ intent.data ?? "0x"
648
+ );
649
+ try {
650
+ return await this.bundler.estimateUserOperationGas({
651
+ sender,
652
+ callData
653
+ });
654
+ } catch {
655
+ return {
656
+ verificationGasLimit: 150000n,
657
+ callGasLimit: 100000n,
658
+ preVerificationGas: 50000n
659
+ };
660
+ }
661
+ }
662
+ /**
663
+ * Estimate gas for a batch transaction
664
+ */
665
+ async estimateBatchGas(intents) {
666
+ const sender = await this.signer.getAddress();
667
+ const callData = this.signer.encodeExecuteBatch(
668
+ intents.map((i) => i.to),
669
+ intents.map((i) => i.value ?? 0n),
670
+ intents.map((i) => i.data ?? "0x")
671
+ );
672
+ try {
673
+ return await this.bundler.estimateUserOperationGas({
674
+ sender,
675
+ callData
676
+ });
677
+ } catch {
678
+ return {
679
+ verificationGasLimit: 150000n,
680
+ callGasLimit: 100000n * BigInt(intents.length),
681
+ preVerificationGas: 50000n
682
+ };
683
+ }
684
+ }
685
+ /**
686
+ * Get paymaster data if configured
687
+ */
688
+ async getPaymasterData(_gasEstimate) {
689
+ if (!this.paymaster) return void 0;
690
+ const sender = await this.signer.getAddress();
691
+ return this.paymaster.getPaymasterData(
692
+ { sender },
693
+ this.chainId,
694
+ import_evm.ENTRYPOINT_V07_ADDRESS
695
+ );
696
+ }
697
+ };
698
+ async function createWdkGaslessClient(config) {
699
+ const smartAccount = await createWdkSmartAccount({
700
+ wdkAccount: config.wdkAccount,
701
+ publicClient: config.publicClient,
702
+ chainId: config.chainId,
703
+ saltNonce: config.saltNonce
704
+ });
705
+ return new WdkGaslessClient({
706
+ signer: smartAccount,
707
+ bundler: config.bundler,
708
+ paymaster: config.paymaster,
709
+ chainId: config.chainId,
710
+ publicClient: config.publicClient
711
+ });
712
+ }
713
+ // Annotate the CommonJS export names for ESM import in node:
714
+ 0 && (module.exports = {
715
+ CHAIN_IDS,
716
+ DEFAULT_BUNDLER_URLS,
717
+ SAFE_4337_ADDRESSES,
718
+ USDC_ADDRESSES,
719
+ USDT0_ADDRESSES,
720
+ WdkGaslessClient,
721
+ WdkSmartAccount,
722
+ createWdkGaslessClient,
723
+ createWdkSmartAccount,
724
+ getChainName,
725
+ getTokenAddress
726
+ });
727
+ //# sourceMappingURL=index.js.map