@aastar/sdk 0.20.7 → 0.20.9

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 (94) hide show
  1. package/dist/BaseClient-CkBhQ1ou.d.cts +88 -0
  2. package/dist/UserClient-2J6XMTNV.cjs +15 -0
  3. package/dist/UserClient-2J6XMTNV.cjs.map +1 -0
  4. package/dist/account.cjs +31 -0
  5. package/dist/account.cjs.map +1 -0
  6. package/dist/account.d.cts +48 -0
  7. package/dist/admin.cjs +15 -0
  8. package/dist/admin.cjs.map +1 -0
  9. package/dist/admin.d.cts +62 -0
  10. package/dist/airaccount.cjs +452 -0
  11. package/dist/airaccount.cjs.map +1 -0
  12. package/dist/airaccount.d.cts +4 -0
  13. package/dist/airaccount.js +3 -1
  14. package/dist/channel-CkRRbzT8.d.cts +77 -0
  15. package/dist/channel.cjs +27 -0
  16. package/dist/channel.cjs.map +1 -0
  17. package/dist/channel.d.cts +64 -0
  18. package/dist/chunk-2RCJBWPO.cjs +1168 -0
  19. package/dist/chunk-2RCJBWPO.cjs.map +1 -0
  20. package/dist/chunk-FTJD2DWE.cjs +42472 -0
  21. package/dist/chunk-FTJD2DWE.cjs.map +1 -0
  22. package/dist/chunk-GRDC6ZRA.cjs +118 -0
  23. package/dist/chunk-GRDC6ZRA.cjs.map +1 -0
  24. package/dist/chunk-GX7NROST.cjs +421 -0
  25. package/dist/chunk-GX7NROST.cjs.map +1 -0
  26. package/dist/chunk-HSVQIFIK.cjs +128 -0
  27. package/dist/chunk-HSVQIFIK.cjs.map +1 -0
  28. package/dist/{chunk-UIFMIVDK.js → chunk-IC3G6YM2.js} +24 -26
  29. package/dist/chunk-IC3G6YM2.js.map +1 -0
  30. package/dist/chunk-JTWY2XEG.cjs +115 -0
  31. package/dist/chunk-JTWY2XEG.cjs.map +1 -0
  32. package/dist/chunk-MRREGCWN.cjs +585 -0
  33. package/dist/chunk-MRREGCWN.cjs.map +1 -0
  34. package/dist/chunk-NT26BDGN.cjs +228 -0
  35. package/dist/chunk-NT26BDGN.cjs.map +1 -0
  36. package/dist/chunk-Q7SFCCGT.cjs +11 -0
  37. package/dist/chunk-Q7SFCCGT.cjs.map +1 -0
  38. package/dist/chunk-QLF7N6H7.cjs +448 -0
  39. package/dist/chunk-QLF7N6H7.cjs.map +1 -0
  40. package/dist/chunk-RNHSA3LO.cjs +108 -0
  41. package/dist/chunk-RNHSA3LO.cjs.map +1 -0
  42. package/dist/chunk-S5IKOOUR.cjs +393 -0
  43. package/dist/chunk-S5IKOOUR.cjs.map +1 -0
  44. package/dist/chunk-TFLZETWB.cjs +4693 -0
  45. package/dist/chunk-TFLZETWB.cjs.map +1 -0
  46. package/dist/chunk-WQREDGUF.cjs +435 -0
  47. package/dist/chunk-WQREDGUF.cjs.map +1 -0
  48. package/dist/chunk-XQROKLZI.cjs +4521 -0
  49. package/dist/chunk-XQROKLZI.cjs.map +1 -0
  50. package/dist/contract-addresses-TANQ5DLX.cjs +49 -0
  51. package/dist/contract-addresses-TANQ5DLX.cjs.map +1 -0
  52. package/dist/core.cjs +894 -0
  53. package/dist/core.cjs.map +1 -0
  54. package/dist/core.d.cts +6930 -0
  55. package/dist/dapp.cjs +289 -0
  56. package/dist/dapp.cjs.map +1 -0
  57. package/dist/dapp.d.cts +127 -0
  58. package/dist/doc-types-471vSmPO.d.cts +16 -0
  59. package/dist/enduser.cjs +24 -0
  60. package/dist/enduser.cjs.map +1 -0
  61. package/dist/enduser.d.cts +261 -0
  62. package/dist/identity.cjs +23 -0
  63. package/dist/identity.cjs.map +1 -0
  64. package/dist/identity.d.cts +81 -0
  65. package/dist/index-B6SfEQxo.d.cts +47 -0
  66. package/dist/index.cjs +2814 -0
  67. package/dist/index.cjs.map +1 -0
  68. package/dist/index.d.cts +656 -0
  69. package/dist/kms.cjs +452 -0
  70. package/dist/kms.cjs.map +1 -0
  71. package/dist/kms.d.cts +3054 -0
  72. package/dist/kms.d.ts +13 -13
  73. package/dist/kms.js +3 -1
  74. package/dist/lib-FE4GR7TO.cjs +1865 -0
  75. package/dist/lib-FE4GR7TO.cjs.map +1 -0
  76. package/dist/operator.cjs +27 -0
  77. package/dist/operator.cjs.map +1 -0
  78. package/dist/operator.d.cts +164 -0
  79. package/dist/paymaster.cjs +63 -0
  80. package/dist/paymaster.cjs.map +1 -0
  81. package/dist/paymaster.d.cts +312 -0
  82. package/dist/src-ENPA7D2S.cjs +63 -0
  83. package/dist/src-ENPA7D2S.cjs.map +1 -0
  84. package/dist/src-TQKEO2I4.cjs +894 -0
  85. package/dist/src-TQKEO2I4.cjs.map +1 -0
  86. package/dist/tier-router-DeeVg69O.d.cts +370 -0
  87. package/dist/tokens.cjs +15 -0
  88. package/dist/tokens.cjs.map +1 -0
  89. package/dist/tokens.d.cts +64 -0
  90. package/dist/x402.cjs +103 -0
  91. package/dist/x402.cjs.map +1 -0
  92. package/dist/x402.d.cts +373 -0
  93. package/package.json +32 -32
  94. package/dist/chunk-UIFMIVDK.js.map +0 -1
@@ -0,0 +1,1168 @@
1
+ 'use strict';
2
+
3
+ var chunkFTJD2DWE_cjs = require('./chunk-FTJD2DWE.cjs');
4
+ var viem = require('viem');
5
+
6
+ var DEFAULT_VERIFICATION_GAS = 160000n;
7
+ var DEFAULT_POSTOP_GAS = 10000n;
8
+ function getSuperPaymasterMiddleware(config) {
9
+ return {
10
+ sponsorUserOperation: async (args) => {
11
+ const verGas = config.verificationGasLimit ?? DEFAULT_VERIFICATION_GAS;
12
+ const postGas = config.postOpGasLimit ?? DEFAULT_POSTOP_GAS;
13
+ const maxRate = config.maxRate ?? 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn;
14
+ const paymasterAndData = viem.concat([
15
+ config.paymasterAddress,
16
+ viem.pad(viem.toHex(verGas), { size: 16 }),
17
+ viem.pad(viem.toHex(postGas), { size: 16 }),
18
+ config.operator,
19
+ viem.pad(viem.toHex(maxRate), { size: 32 })
20
+ ]);
21
+ return {
22
+ paymasterAndData,
23
+ verificationGasLimit: verGas,
24
+ preVerificationGas: args.userOperation.preVerificationGas
25
+ };
26
+ }
27
+ };
28
+ }
29
+ async function checkEligibility(client, paymaster, user, operator) {
30
+ try {
31
+ const operatorData = await client.readContract({
32
+ address: paymaster,
33
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
34
+ functionName: "operators",
35
+ args: [operator]
36
+ });
37
+ const token = operatorData[0];
38
+ const isConfigured = operatorData[2];
39
+ const isPaused = operatorData[3];
40
+ if (!isConfigured || isPaused) {
41
+ return { eligible: false };
42
+ }
43
+ const credit = await client.readContract({
44
+ address: paymaster,
45
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
46
+ functionName: "getAvailableCredit",
47
+ args: [user, token]
48
+ });
49
+ return {
50
+ eligible: credit > 0n,
51
+ credit,
52
+ token
53
+ };
54
+ } catch (e) {
55
+ console.warn("Eligibility check failed:", e);
56
+ return { eligible: false };
57
+ }
58
+ }
59
+ var SuperPaymasterAdminClient = class {
60
+ client;
61
+ paymasterAddress;
62
+ constructor(client, paymasterAddress) {
63
+ this.client = client;
64
+ this.paymasterAddress = paymasterAddress;
65
+ }
66
+ async getOperator(operator) {
67
+ return this.client.readContract({
68
+ address: this.paymasterAddress,
69
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
70
+ functionName: "operators",
71
+ args: [operator]
72
+ });
73
+ }
74
+ static async configureOperator(wallet, paymaster, token, treasury) {
75
+ return wallet.writeContract({
76
+ address: paymaster,
77
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
78
+ functionName: "configureOperator",
79
+ args: [token, treasury],
80
+ chain: wallet.chain
81
+ });
82
+ }
83
+ static async setOperatorPaused(wallet, paymaster, operator, paused) {
84
+ return wallet.writeContract({
85
+ address: paymaster,
86
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
87
+ functionName: "setOperatorPaused",
88
+ args: [operator, paused],
89
+ chain: wallet.chain
90
+ });
91
+ }
92
+ static async updateReputation(wallet, paymaster, operator, score) {
93
+ return wallet.writeContract({
94
+ address: paymaster,
95
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
96
+ functionName: "updateReputation",
97
+ args: [operator, score],
98
+ chain: wallet.chain
99
+ });
100
+ }
101
+ static async setAPNTsToken(wallet, paymaster, token) {
102
+ return wallet.writeContract({
103
+ address: paymaster,
104
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
105
+ functionName: "setAPNTsToken",
106
+ args: [token],
107
+ chain: wallet.chain
108
+ });
109
+ }
110
+ static async setXPNTsFactory(wallet, paymaster, factory) {
111
+ return wallet.writeContract({
112
+ address: paymaster,
113
+ abi: chunkFTJD2DWE_cjs.SuperPaymasterABI,
114
+ functionName: "setXPNTsFactory",
115
+ args: [factory],
116
+ chain: wallet.chain
117
+ });
118
+ }
119
+ };
120
+ var DEFAULT_VERIFICATION_GAS_V4 = 1500000n;
121
+ var DEFAULT_POSTOP_GAS_V4 = 300000n;
122
+ function getPaymasterV4Middleware(config) {
123
+ return {
124
+ sponsorUserOperation: async (args) => {
125
+ const verGas = config.verificationGasLimit ?? DEFAULT_VERIFICATION_GAS_V4;
126
+ const postGas = config.postOpGasLimit ?? DEFAULT_POSTOP_GAS_V4;
127
+ const paymasterAndData = viem.concat([
128
+ config.paymasterAddress,
129
+ viem.pad(viem.toHex(verGas), { size: 16 }),
130
+ viem.pad(viem.toHex(postGas), { size: 16 }),
131
+ config.gasToken
132
+ ]);
133
+ return {
134
+ paymasterAndData,
135
+ verificationGasLimit: verGas,
136
+ preVerificationGas: args.userOperation.preVerificationGas
137
+ };
138
+ }
139
+ };
140
+ }
141
+ function buildPaymasterData(paymasterAddress, token, options) {
142
+ const validityWindow = options?.validityWindow ?? 3600;
143
+ const verGas = options?.verificationGasLimit ?? 200000n;
144
+ const postGas = options?.postOpGasLimit ?? 100000n;
145
+ const now = Math.floor(Date.now() / 1e3);
146
+ const validUntil = now + validityWindow;
147
+ const validAfter = now - 100;
148
+ return viem.concat([
149
+ paymasterAddress,
150
+ viem.pad(viem.toHex(verGas), { size: 16 }),
151
+ viem.pad(viem.toHex(postGas), { size: 16 }),
152
+ token,
153
+ viem.pad(viem.toHex(validUntil), { size: 6 }),
154
+ viem.pad(viem.toHex(validAfter), { size: 6 })
155
+ ]);
156
+ }
157
+ function buildSuperPaymasterData(paymasterAddress, operator, options) {
158
+ const verGas = options?.verificationGasLimit ?? 80000n;
159
+ const postGas = options?.postOpGasLimit ?? 100000n;
160
+ const maxRate = options?.maxRate ?? (1n << 256n) - 1n;
161
+ return viem.concat([
162
+ paymasterAddress,
163
+ viem.pad(viem.toHex(verGas), { size: 16 }),
164
+ viem.pad(viem.toHex(postGas), { size: 16 }),
165
+ operator,
166
+ viem.pad(viem.toHex(maxRate), { size: 32 })
167
+ // Optional rate commitment (rug pull protection)
168
+ ]);
169
+ }
170
+ function formatUserOpV07(userOp) {
171
+ const result = {
172
+ sender: userOp.sender,
173
+ nonce: viem.toHex(userOp.nonce),
174
+ callData: userOp.callData,
175
+ preVerificationGas: viem.toHex(userOp.preVerificationGas),
176
+ signature: userOp.signature
177
+ };
178
+ if (userOp.initCode && userOp.initCode !== "0x" && userOp.initCode.length > 2) {
179
+ result.initCode = userOp.initCode;
180
+ if (userOp.initCode.length > 42) {
181
+ result.factory = userOp.initCode.slice(0, 42);
182
+ result.factoryData = "0x" + userOp.initCode.slice(42);
183
+ } else {
184
+ result.factory = "0x0000000000000000000000000000000000000000";
185
+ result.factoryData = "0x";
186
+ }
187
+ }
188
+ if (userOp.accountGasLimits && userOp.accountGasLimits !== "0x") {
189
+ const packed = userOp.accountGasLimits.replace("0x", "").padStart(64, "0");
190
+ result.verificationGasLimit = "0x" + BigInt("0x" + packed.slice(0, 32)).toString(16);
191
+ result.callGasLimit = "0x" + BigInt("0x" + packed.slice(32, 64)).toString(16);
192
+ }
193
+ if (userOp.gasFees && userOp.gasFees !== "0x") {
194
+ const packed = userOp.gasFees.replace("0x", "").padStart(64, "0");
195
+ result.maxPriorityFeePerGas = "0x" + BigInt("0x" + packed.slice(0, 32)).toString(16);
196
+ result.maxFeePerGas = "0x" + BigInt("0x" + packed.slice(32, 64)).toString(16);
197
+ }
198
+ if (userOp.paymasterAndData && userOp.paymasterAndData !== "0x") {
199
+ const packed = userOp.paymasterAndData.replace("0x", "");
200
+ if (packed.length >= 104) {
201
+ result.paymaster = "0x" + packed.slice(0, 40);
202
+ result.paymasterVerificationGasLimit = "0x" + BigInt("0x" + packed.slice(40, 72)).toString(16);
203
+ result.paymasterPostOpGasLimit = "0x" + BigInt("0x" + packed.slice(72, 104)).toString(16);
204
+ result.paymasterData = "0x" + packed.slice(104);
205
+ }
206
+ }
207
+ return result;
208
+ }
209
+ function getUserOpHashV07(userOp, entryPoint, chainId) {
210
+ const hashedUserOp = viem.keccak256(viem.encodeAbiParameters(
211
+ ["address", "uint256", "bytes32", "bytes32", "bytes32", "uint256", "bytes32", "bytes32"].map((t) => ({ type: t })),
212
+ [
213
+ userOp.sender,
214
+ userOp.nonce,
215
+ viem.keccak256(viem.toBytes(userOp.initCode)),
216
+ viem.keccak256(viem.toBytes(userOp.callData)),
217
+ userOp.accountGasLimits,
218
+ viem.toHex(userOp.preVerificationGas),
219
+ userOp.gasFees,
220
+ viem.keccak256(viem.toBytes(userOp.paymasterAndData))
221
+ ]
222
+ ));
223
+ return viem.keccak256(viem.encodeAbiParameters(
224
+ ["bytes32", "address", "uint256"].map((t) => ({ type: t })),
225
+ [hashedUserOp, entryPoint, chainId]
226
+ ));
227
+ }
228
+ function tuneGasLimit(estimate, nominalActual, targetEfficiency = 0.45) {
229
+ if (estimate === 0n) return 0n;
230
+ const ceiling = nominalActual * 100n / BigInt(Math.floor(targetEfficiency * 100));
231
+ return estimate < ceiling ? estimate : ceiling;
232
+ }
233
+
234
+ // ../paymaster/src/V4/BundlerCompat.ts
235
+ function detectBundlerType(bundlerUrl) {
236
+ const url = bundlerUrl.toLowerCase();
237
+ if (url.includes("alchemy.com")) return "alchemy" /* ALCHEMY */;
238
+ if (url.includes("pimlico.io")) return "pimlico" /* PIMLICO */;
239
+ if (url.includes("stackup")) return "stackup" /* STACKUP */;
240
+ if (url.includes("candide.dev")) return "candide" /* CANDIDE */;
241
+ return "unknown" /* UNKNOWN */;
242
+ }
243
+
244
+ // ../paymaster/src/V4/PaymasterClient.ts
245
+ var PaymasterClient = class _PaymasterClient {
246
+ /**
247
+ * @private
248
+ * Static utility class, should not be instantiated.
249
+ */
250
+ constructor() {
251
+ }
252
+ static makePlaceholderSignature(byteLength) {
253
+ const clamped = Math.max(0, Math.min(byteLength, 1e4));
254
+ return `0x${"11".repeat(clamped)}`;
255
+ }
256
+ static estimatePreVerificationGasV07(userOp) {
257
+ const encoded = viem.encodeAbiParameters(
258
+ viem.parseAbiParameters("(address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes)"),
259
+ [
260
+ [
261
+ userOp.sender,
262
+ userOp.nonce,
263
+ userOp.initCode,
264
+ userOp.callData,
265
+ userOp.accountGasLimits,
266
+ userOp.preVerificationGas,
267
+ userOp.gasFees,
268
+ userOp.paymasterAndData,
269
+ userOp.signature
270
+ ]
271
+ ]
272
+ );
273
+ const bytes = viem.toBytes(encoded);
274
+ let calldataCost = 0n;
275
+ for (const b of bytes) calldataCost += b === 0 ? 4n : 16n;
276
+ return calldataCost + 26000n;
277
+ }
278
+ /**
279
+ * Get user's deposited balance on the Paymaster.
280
+ */
281
+ static async getDepositedBalance(publicClient, address, user, token) {
282
+ return publicClient.readContract({
283
+ address,
284
+ abi: [{
285
+ name: "balances",
286
+ type: "function",
287
+ inputs: [
288
+ { name: "user", type: "address" },
289
+ { name: "token", type: "address" }
290
+ ],
291
+ outputs: [{ name: "", type: "uint256" }],
292
+ stateMutability: "view"
293
+ }],
294
+ functionName: "balances",
295
+ args: [user, token]
296
+ });
297
+ }
298
+ /**
299
+ * Deposit tokens to Paymaster for a user (enables gasless transactions).
300
+ */
301
+ static async depositFor(wallet, address, user, token, amount) {
302
+ return wallet.writeContract({
303
+ address,
304
+ abi: viem.parseAbi(["function depositFor(address user, address token, uint256 amount) external"]),
305
+ functionName: "depositFor",
306
+ args: [user, token, amount],
307
+ chain: wallet.chain
308
+ });
309
+ }
310
+ /**
311
+ * Approve the Paymaster (or any spender) to spend gas tokens.
312
+ */
313
+ static async approveGasToken(wallet, token, spender, amount) {
314
+ return wallet.writeContract({
315
+ address: token,
316
+ abi: viem.parseAbi(["function approve(address spender, uint256 amount) external returns (bool)"]),
317
+ functionName: "approve",
318
+ args: [spender, amount],
319
+ chain: wallet.chain
320
+ });
321
+ }
322
+ /**
323
+ * Estimate Gas for a UserOperation.
324
+ */
325
+ static async estimateUserOperationGas(client, wallet, aaAddress, entryPoint, paymasterAddress, token, bundlerUrl, callData, options) {
326
+ if (!options?.operator) {
327
+ try {
328
+ const cache = await client.readContract({
329
+ address: paymasterAddress,
330
+ abi: viem.parseAbi(["function cachedPrice() view returns (uint208 price, uint48 updatedAt)"]),
331
+ functionName: "cachedPrice"
332
+ });
333
+ const cachedPrice = BigInt(cache?.price ?? cache?.[0] ?? 0);
334
+ const cachedUpdatedAt = BigInt(cache?.updatedAt ?? cache?.[1] ?? 0);
335
+ const now = BigInt(Math.floor(Date.now() / 1e3));
336
+ let stalenessThreshold = 0n;
337
+ try {
338
+ stalenessThreshold = await client.readContract({
339
+ address: paymasterAddress,
340
+ abi: viem.parseAbi(["function priceStalenessThreshold() view returns (uint256)"]),
341
+ functionName: "priceStalenessThreshold"
342
+ });
343
+ } catch {
344
+ }
345
+ const isStale = cachedPrice === 0n || cachedUpdatedAt === 0n || stalenessThreshold > 0n && cachedUpdatedAt + stalenessThreshold < now;
346
+ if (isStale) {
347
+ const chainId2 = client.chain?.id || await client.getChainId();
348
+ const isTestnet2 = [11155111, 11155420, 31337].includes(chainId2);
349
+ if (isTestnet2) {
350
+ const updateHash = await wallet.writeContract({
351
+ address: paymasterAddress,
352
+ abi: viem.parseAbi(["function updatePrice() external"]),
353
+ functionName: "updatePrice"
354
+ });
355
+ await client.waitForTransactionReceipt({ hash: updateHash });
356
+ console.log("[PaymasterClient] \u2705 cachedPrice refreshed via updatePrice()");
357
+ } else {
358
+ throw new Error(
359
+ `Paymaster cachedPrice is stale on Mainnet (chainId: ${chainId2}). This requires Keeper to call updatePrice(). Please ensure Keeper is running.`
360
+ );
361
+ }
362
+ }
363
+ } catch (e) {
364
+ if (e.message?.includes("requires Keeper")) throw e;
365
+ console.log("[PaymasterClient] \u26A0\uFE0F Failed to check cachedPrice:", e.message?.slice(0, 50));
366
+ }
367
+ }
368
+ let paymasterAndData;
369
+ if (options?.operator) {
370
+ paymasterAndData = buildSuperPaymasterData(paymasterAddress, options.operator, {
371
+ verificationGasLimit: 300000n,
372
+ postOpGasLimit: 300000n
373
+ });
374
+ } else {
375
+ paymasterAndData = buildPaymasterData(paymasterAddress, token, {
376
+ validityWindow: options?.validityWindow,
377
+ verificationGasLimit: 250000n,
378
+ postOpGasLimit: 150000n
379
+ });
380
+ }
381
+ const chainId = client.chain?.id || await client.getChainId();
382
+ const isTestnet = [11155111, 11155420, 31337].includes(chainId);
383
+ const TESTNET_PRIORITY_FLOOR = 500000000n;
384
+ let maxFeePerGas = 0n;
385
+ let maxPriorityFeePerGas = 0n;
386
+ try {
387
+ const feeData = await client.estimateFeesPerGas();
388
+ maxFeePerGas = (feeData.maxFeePerGas ?? 0n) * 115n / 100n;
389
+ maxPriorityFeePerGas = (feeData.maxPriorityFeePerGas ?? 0n) * 115n / 100n;
390
+ } catch {
391
+ }
392
+ if (!maxFeePerGas) {
393
+ try {
394
+ const gasPrice = await client.getGasPrice();
395
+ maxFeePerGas = gasPrice * 120n / 100n;
396
+ } catch {
397
+ }
398
+ }
399
+ if (isTestnet) {
400
+ if (maxPriorityFeePerGas < TESTNET_PRIORITY_FLOOR) maxPriorityFeePerGas = TESTNET_PRIORITY_FLOOR;
401
+ if (maxFeePerGas < TESTNET_PRIORITY_FLOOR * 2n) maxFeePerGas = TESTNET_PRIORITY_FLOOR * 2n;
402
+ }
403
+ if (!maxFeePerGas) maxFeePerGas = 1n;
404
+ if (maxFeePerGas < maxPriorityFeePerGas) maxFeePerGas = maxPriorityFeePerGas + 1n;
405
+ const partialUserOp = {
406
+ sender: aaAddress,
407
+ nonce: 0n,
408
+ initCode: options?.factory && options?.factoryData ? viem.concat([options.factory, options.factoryData]) : "0x",
409
+ callData,
410
+ accountGasLimits: viem.concat([viem.pad(viem.toHex(250000n), { size: 16 }), viem.pad(viem.toHex(500000n), { size: 16 })]),
411
+ preVerificationGas: 0n,
412
+ gasFees: viem.concat([viem.pad(viem.toHex(maxPriorityFeePerGas), { size: 16 }), viem.pad(viem.toHex(maxFeePerGas), { size: 16 })]),
413
+ paymasterAndData,
414
+ signature: _PaymasterClient.makePlaceholderSignature(65)
415
+ };
416
+ try {
417
+ const nonce = await client.readContract({
418
+ address: aaAddress,
419
+ abi: viem.parseAbi(["function getNonce() view returns (uint256)"]),
420
+ functionName: "getNonce"
421
+ });
422
+ partialUserOp.nonce = BigInt(nonce);
423
+ } catch (e) {
424
+ }
425
+ partialUserOp.preVerificationGas = _PaymasterClient.estimatePreVerificationGasV07(partialUserOp) * 120n / 100n + 5000n;
426
+ const userOpHash = getUserOpHashV07(partialUserOp, entryPoint, BigInt(client.chain.id));
427
+ partialUserOp.signature = await wallet.account.signMessage({ message: { raw: userOpHash } });
428
+ const payload = {
429
+ jsonrpc: "2.0",
430
+ id: 1,
431
+ method: "eth_estimateUserOperationGas",
432
+ params: [formatUserOpV07(partialUserOp), entryPoint]
433
+ };
434
+ const response = await fetch(bundlerUrl, {
435
+ method: "POST",
436
+ headers: { "Content-Type": "application/json" },
437
+ body: JSON.stringify(payload, (_, v) => typeof v === "bigint" ? "0x" + v.toString(16) : v)
438
+ });
439
+ const result = await response.json();
440
+ if (bundlerUrl.includes("candide")) {
441
+ console.log("[PaymasterClient] Candide Request:", JSON.stringify(payload.params[0], null, 2));
442
+ console.log("[PaymasterClient] Candide Response:", JSON.stringify(result, null, 2));
443
+ }
444
+ const data = result.result;
445
+ console.log("[PaymasterClient] Gas Estimation Result:", JSON.stringify(data, null, 2));
446
+ if (result.error && (result.error.code === -32601 || result.error.message?.includes("Method not found"))) {
447
+ console.log("[PaymasterClient] EstimateUserOp failed (Method not found). Using Anvil defaults.");
448
+ return {
449
+ preVerificationGas: partialUserOp.preVerificationGas,
450
+ verificationGasLimit: 1000000n,
451
+ callGasLimit: 2000000n,
452
+ paymasterVerificationGasLimit: 100000n,
453
+ paymasterPostOpGasLimit: 100000n
454
+ };
455
+ }
456
+ if (result.error) throw new Error(`Estimation Error: ${JSON.stringify(result.error)}`);
457
+ const estVGL = BigInt(data.verificationGasLimit);
458
+ const estPMVGL = data.paymasterVerificationGasLimit ? BigInt(data.paymasterVerificationGasLimit) : 100000n;
459
+ return {
460
+ preVerificationGas: BigInt(data.preVerificationGas) * 120n / 100n + 5000n,
461
+ verificationGasLimit: tuneGasLimit(estVGL, 35000n, 0.45),
462
+ callGasLimit: BigInt(data.callGasLimit) * 110n / 100n,
463
+ // Small 1.1x buffer
464
+ paymasterVerificationGasLimit: tuneGasLimit(estPMVGL, 35000n, 0.45),
465
+ paymasterPostOpGasLimit: data.paymasterPostOpGasLimit ? BigInt(data.paymasterPostOpGasLimit) : 100000n
466
+ };
467
+ }
468
+ /**
469
+ * High-level API to submit a gasless UserOperation.
470
+ * Automatically handles nonce fetching, gas estimation (if not provided), signing, and submission.
471
+ */
472
+ static async submitGaslessUserOperation(client, wallet, aaAddress, entryPoint, paymasterAddress, token, bundlerUrl, callData, options) {
473
+ let gasLimits = {
474
+ preVerificationGas: options?.preVerificationGas,
475
+ verificationGasLimit: options?.verificationGasLimit,
476
+ callGasLimit: options?.callGasLimit,
477
+ paymasterVerificationGasLimit: options?.paymasterVerificationGasLimit,
478
+ paymasterPostOpGasLimit: options?.paymasterPostOpGasLimit ?? 200000n
479
+ };
480
+ if (options?.autoEstimate !== false && (!gasLimits.verificationGasLimit || !gasLimits.callGasLimit)) {
481
+ const est = await this.estimateUserOperationGas(
482
+ client,
483
+ wallet,
484
+ aaAddress,
485
+ entryPoint,
486
+ paymasterAddress,
487
+ token,
488
+ bundlerUrl,
489
+ callData,
490
+ {
491
+ validityWindow: options?.validityWindow,
492
+ operator: options?.operator,
493
+ factory: options?.factory,
494
+ factoryData: options?.factoryData
495
+ }
496
+ );
497
+ gasLimits.preVerificationGas = options?.preVerificationGas ?? est.preVerificationGas;
498
+ gasLimits.verificationGasLimit = options?.verificationGasLimit ?? est.verificationGasLimit;
499
+ gasLimits.callGasLimit = options?.callGasLimit ?? est.callGasLimit;
500
+ gasLimits.paymasterVerificationGasLimit = options?.paymasterVerificationGasLimit ?? est.paymasterVerificationGasLimit;
501
+ if (!options?.paymasterPostOpGasLimit) {
502
+ const _base = est.paymasterPostOpGasLimit + 100000n;
503
+ gasLimits.paymasterPostOpGasLimit = _base > 200000n ? _base : 200000n;
504
+ }
505
+ }
506
+ const nonce = await client.readContract({
507
+ address: aaAddress,
508
+ abi: viem.parseAbi(["function getNonce() view returns (uint256)"]),
509
+ functionName: "getNonce"
510
+ });
511
+ const chainId = client.chain?.id || await client.getChainId();
512
+ const isTestnet = [11155111, 11155420, 31337].includes(chainId);
513
+ const TESTNET_PRIORITY_FLOOR = 500000000n;
514
+ let maxFeePerGas = options?.maxFeePerGas;
515
+ let maxPriorityFeePerGas = options?.maxPriorityFeePerGas;
516
+ if (!maxFeePerGas || !maxPriorityFeePerGas) {
517
+ try {
518
+ const feeData = await client.estimateFeesPerGas();
519
+ maxFeePerGas = maxFeePerGas ?? (feeData.maxFeePerGas ?? 0n) * 115n / 100n;
520
+ maxPriorityFeePerGas = maxPriorityFeePerGas ?? (feeData.maxPriorityFeePerGas ?? 0n) * 115n / 100n;
521
+ } catch (e) {
522
+ maxFeePerGas = maxFeePerGas ?? void 0;
523
+ maxPriorityFeePerGas = maxPriorityFeePerGas ?? void 0;
524
+ }
525
+ }
526
+ if (!maxFeePerGas) {
527
+ try {
528
+ maxFeePerGas = await client.getGasPrice() * 150n / 100n;
529
+ } catch {
530
+ }
531
+ }
532
+ if (isTestnet) {
533
+ maxPriorityFeePerGas = maxPriorityFeePerGas ?? TESTNET_PRIORITY_FLOOR;
534
+ if (maxPriorityFeePerGas < TESTNET_PRIORITY_FLOOR) maxPriorityFeePerGas = TESTNET_PRIORITY_FLOOR;
535
+ if (!maxFeePerGas || maxFeePerGas < TESTNET_PRIORITY_FLOOR * 2n) maxFeePerGas = TESTNET_PRIORITY_FLOOR * 2n;
536
+ }
537
+ maxFeePerGas = maxFeePerGas ?? 1n;
538
+ maxPriorityFeePerGas = maxPriorityFeePerGas ?? 0n;
539
+ if (maxFeePerGas < maxPriorityFeePerGas) maxFeePerGas = maxPriorityFeePerGas + 1n;
540
+ console.log(`[PaymasterClient] Gas Pricing: ${isTestnet ? "TESTNET (0.5 Gwei floor)" : "MAINNET (dynamic)"} | priority=${maxPriorityFeePerGas} maxFee=${maxFeePerGas}`);
541
+ let paymasterAndData;
542
+ if (options?.operator) {
543
+ paymasterAndData = buildSuperPaymasterData(paymasterAddress, options.operator, {
544
+ verificationGasLimit: gasLimits.paymasterVerificationGasLimit ?? gasLimits.verificationGasLimit ?? 150000n,
545
+ postOpGasLimit: gasLimits.paymasterPostOpGasLimit ?? 100000n
546
+ });
547
+ } else {
548
+ const pmVerGas = gasLimits.paymasterVerificationGasLimit ?? 75000n;
549
+ paymasterAndData = buildPaymasterData(paymasterAddress, token, {
550
+ validityWindow: options?.validityWindow,
551
+ verificationGasLimit: pmVerGas,
552
+ postOpGasLimit: gasLimits.paymasterPostOpGasLimit ?? 100000n
553
+ });
554
+ }
555
+ const initCode = options?.factory && options?.factoryData ? viem.concat([options.factory, options.factoryData]) : "0x";
556
+ const accountGasLimits = viem.concat([
557
+ viem.pad(viem.toHex(gasLimits.verificationGasLimit ?? 75000n), { size: 16 }),
558
+ viem.pad(viem.toHex(gasLimits.callGasLimit ?? 500000n), { size: 16 })
559
+ ]);
560
+ const gasFees = viem.concat([
561
+ viem.pad(viem.toHex(maxPriorityFeePerGas), { size: 16 }),
562
+ viem.pad(viem.toHex(maxFeePerGas), { size: 16 })
563
+ ]);
564
+ const preVerificationGas = gasLimits.preVerificationGas ?? _PaymasterClient.estimatePreVerificationGasV07({
565
+ sender: aaAddress,
566
+ nonce: BigInt(nonce),
567
+ initCode,
568
+ callData,
569
+ accountGasLimits,
570
+ preVerificationGas: 0n,
571
+ gasFees,
572
+ paymasterAndData,
573
+ signature: _PaymasterClient.makePlaceholderSignature(65)
574
+ }) * 120n / 100n + 5000n;
575
+ const userOp = {
576
+ sender: aaAddress,
577
+ nonce: BigInt(nonce),
578
+ initCode,
579
+ callData,
580
+ accountGasLimits,
581
+ preVerificationGas,
582
+ gasFees,
583
+ paymasterAndData,
584
+ signature: "0x"
585
+ };
586
+ const userOpHash = getUserOpHashV07(userOp, entryPoint, BigInt(client.chain.id));
587
+ const signature = await wallet.account.signMessage({ message: { raw: userOpHash } });
588
+ userOp.signature = signature;
589
+ const bundlerType = detectBundlerType(bundlerUrl);
590
+ console.log(`[PaymasterClient] Using ${bundlerType} Bundler`);
591
+ for (let attempt = 0; attempt < 5; attempt++) {
592
+ const response = await fetch(bundlerUrl, {
593
+ method: "POST",
594
+ headers: { "Content-Type": "application/json" },
595
+ body: JSON.stringify({
596
+ jsonrpc: "2.0",
597
+ id: 1,
598
+ method: "eth_sendUserOperation",
599
+ params: [formatUserOpV07(userOp), entryPoint]
600
+ }, (_, v) => typeof v === "bigint" ? "0x" + v.toString(16) : v)
601
+ });
602
+ const result = await response.json();
603
+ if (result.error && attempt < 4) {
604
+ const msg = result.error.message || "";
605
+ const errData = result.error.data || {};
606
+ if (result.error.code === -32602 || msg.includes("replacement underpriced")) {
607
+ console.log(`[PaymasterClient] \u26A0\uFE0F Replacement Underpriced. Bumping fees to replace pending UserOp...`);
608
+ let newMaxPriority = userOp.gasFees ? BigInt("0x" + userOp.gasFees.slice(2, 34)) : 0n;
609
+ let newMaxFee = userOp.gasFees ? BigInt("0x" + userOp.gasFees.slice(34)) : 0n;
610
+ if (errData.currentMaxPriorityFee && errData.currentMaxFee) {
611
+ const currentPriority = BigInt(errData.currentMaxPriorityFee);
612
+ const currentMax = BigInt(errData.currentMaxFee);
613
+ newMaxPriority = currentPriority * 110n / 100n;
614
+ newMaxFee = currentMax * 110n / 100n;
615
+ } else {
616
+ newMaxPriority = newMaxPriority * 115n / 100n;
617
+ newMaxFee = newMaxFee * 115n / 100n;
618
+ }
619
+ console.log(` -> New Priority: ${newMaxPriority}, New MaxFee: ${newMaxFee}`);
620
+ userOp.gasFees = viem.concat([
621
+ viem.pad(viem.toHex(newMaxPriority), { size: 16 }),
622
+ viem.pad(viem.toHex(newMaxFee), { size: 16 })
623
+ ]);
624
+ const newHash = getUserOpHashV07(userOp, entryPoint, BigInt(client.chain.id));
625
+ userOp.signature = await wallet.account.signMessage({ message: { raw: newHash } });
626
+ continue;
627
+ }
628
+ const matchPriority = msg.match(/maxPriorityFeePerGas.*(?:at least|expected) (\d+)/i) || msg.match(/priority fee.*(?:at least|expected) (\d+)/i);
629
+ const matchMaxFee = msg.match(/maxFeePerGas.*(?:at least|expected) (\d+)/i);
630
+ if (matchPriority || matchMaxFee) {
631
+ console.log(`[PaymasterClient] \u26A0\uFE0F Fee Error: ${msg}. Retrying with higher fees...`);
632
+ let newMaxPriority = userOp.gasFees ? BigInt("0x" + userOp.gasFees.slice(2, 34)) : 0n;
633
+ let newMaxFee = userOp.gasFees ? BigInt("0x" + userOp.gasFees.slice(34)) : 0n;
634
+ if (matchPriority && matchPriority[1]) {
635
+ const required = BigInt(matchPriority[1]);
636
+ if (required > newMaxPriority) {
637
+ console.log(` -> Bumping Priority Fee to ${required}`);
638
+ const delta = required - newMaxPriority;
639
+ newMaxPriority = required;
640
+ newMaxFee += delta;
641
+ }
642
+ }
643
+ if (matchMaxFee && matchMaxFee[1]) {
644
+ const required = BigInt(matchMaxFee[1]);
645
+ if (required > newMaxFee) {
646
+ console.log(` -> Bumping Max Fee to ${required}`);
647
+ newMaxFee = required;
648
+ }
649
+ }
650
+ if (newMaxFee < newMaxPriority) newMaxFee = newMaxPriority + 1n;
651
+ userOp.gasFees = viem.concat([
652
+ viem.pad(viem.toHex(newMaxPriority), { size: 16 }),
653
+ viem.pad(viem.toHex(newMaxFee), { size: 16 })
654
+ ]);
655
+ const newHash = getUserOpHashV07(userOp, entryPoint, BigInt(client.chain.id));
656
+ userOp.signature = await wallet.account.signMessage({ message: { raw: newHash } });
657
+ continue;
658
+ }
659
+ const matchPVG = msg.match(/preVerificationGas.*(?:at least|expected) (\d+)/i);
660
+ if (matchPVG && matchPVG[1]) {
661
+ const requiredPVG = BigInt(matchPVG[1]);
662
+ const currentPVG = BigInt(userOp.preVerificationGas);
663
+ if (requiredPVG > currentPVG) {
664
+ console.log(`[PaymasterClient] \u26A0\uFE0F PVG Error: ${msg}. Updating preVerificationGas...`);
665
+ const bufferedPVG = requiredPVG * 105n / 100n;
666
+ console.log(` -> Updating PVG from ${currentPVG} to ${bufferedPVG} (inc. buffer)`);
667
+ userOp.preVerificationGas = bufferedPVG;
668
+ const newHash = getUserOpHashV07(userOp, entryPoint, BigInt(client.chain.id));
669
+ userOp.signature = await wallet.account.signMessage({ message: { raw: newHash } });
670
+ continue;
671
+ }
672
+ }
673
+ }
674
+ if (result.error && (result.error.code === -32601 || result.error.message?.includes("Method not found"))) {
675
+ console.log("[PaymasterClient] SendUserOp failed (Method not found). Falling back to direct handleOps...");
676
+ const caller = wallet.account?.address ? wallet.account.address : wallet.account;
677
+ return await wallet.writeContract({
678
+ address: entryPoint,
679
+ abi: viem.parseAbi(["function handleOps((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes)[], address) external"]),
680
+ functionName: "handleOps",
681
+ args: [[userOp], caller],
682
+ chain: wallet.chain,
683
+ account: wallet.account
684
+ });
685
+ }
686
+ if (result.error) throw new Error(`Bundler Error: ${JSON.stringify(result.error)}`);
687
+ console.log("[PaymasterClient] \u2705 Submitted via", bundlerType, "hash:", result.result);
688
+ return result.result;
689
+ }
690
+ throw new Error("Failed to submit UserOp after retries");
691
+ }
692
+ /**
693
+ * Helper to extract the actual Gas Token fee from a UserOperation receipt.
694
+ * Looks for the 'PostOpProcessed' event emitted by the Paymaster.
695
+ */
696
+ static getFeeFromReceipt(receipt, paymasterAddress) {
697
+ const TOPIC_POST_OP = "0x62544d7f48b11c32334310ebd306b47224fca220163218d4a7264322c52ae073";
698
+ for (const log of receipt.logs) {
699
+ if (log.address.toLowerCase() === paymasterAddress.toLowerCase() && log.topics[0] === TOPIC_POST_OP) {
700
+ const data = log.data.replace("0x", "");
701
+ if (data.length >= 192) {
702
+ const actualGasCostWei = BigInt("0x" + data.slice(0, 64));
703
+ const tokenCost = BigInt("0x" + data.slice(64, 128));
704
+ return { tokenCost, actualGasCostWei };
705
+ }
706
+ }
707
+ }
708
+ return null;
709
+ }
710
+ /**
711
+ * Get the fee for a specific transaction hash.
712
+ * Fetches the receipt (no scanning required) and decodes the log.
713
+ */
714
+ static async getTransactionFee(publicClient, txHash, paymasterAddress) {
715
+ const receipt = await publicClient.getTransactionReceipt({ hash: txHash });
716
+ return this.getFeeFromReceipt(receipt, paymasterAddress);
717
+ }
718
+ // ===========================================
719
+ // 🛠️ Semantic CallData Builders (For DX)
720
+ // ===========================================
721
+ /**
722
+ * Helper: Encode a standardized ERC-20 Transfer.
723
+ * Returns the raw function data: `transfer(to, amount)`
724
+ */
725
+ static encodeTokenTransfer(recipient, amount) {
726
+ return viem.encodeFunctionData({
727
+ abi: viem.parseAbi(["function transfer(address to, uint256 amount) external returns (bool)"]),
728
+ functionName: "transfer",
729
+ args: [recipient, amount]
730
+ });
731
+ }
732
+ /**
733
+ * Helper: Encode a SimpleAccount execution.
734
+ * Wraps the inner call into: `execute(target, value, data)`
735
+ * This is the payload signed by the user.
736
+ */
737
+ static encodeExecution(target, value, data) {
738
+ return viem.encodeFunctionData({
739
+ abi: viem.parseAbi(["function execute(address dest, uint256 value, bytes func) external"]),
740
+ functionName: "execute",
741
+ args: [target, value, data]
742
+ });
743
+ }
744
+ /**
745
+ * More robust version of waitForUserOperationReceipt.
746
+ * Catches timeouts and returns a cleaner result.
747
+ */
748
+ static async waitForUserOperation(bundlerClient, hash, timeout = 18e4) {
749
+ try {
750
+ return await bundlerClient.waitForUserOperationReceipt({ hash, timeout });
751
+ } catch (error) {
752
+ const errName = error.name || "";
753
+ const errMsg = error.message || "";
754
+ if (errName === "TimeoutError" || errName === "WaitForUserOperationReceiptTimeoutError" || /timed? out/i.test(errMsg)) {
755
+ return { timeout: true, hash };
756
+ }
757
+ throw error;
758
+ }
759
+ }
760
+ };
761
+ var PaymasterOperator = class {
762
+ /**
763
+ * Update the cached ETH/USD price from Chainlink Oracle.
764
+ * Must be called if cachedPrice is 0 (uninitialized).
765
+ */
766
+ static async updatePrice(wallet, address) {
767
+ return wallet.writeContract({
768
+ address,
769
+ abi: viem.parseAbi(["function updatePrice() external"]),
770
+ functionName: "updatePrice",
771
+ chain: wallet.chain
772
+ });
773
+ }
774
+ /**
775
+ * Set the token price (in 8 decimals, e.g., 1e8 = $1 USD).
776
+ */
777
+ static async setTokenPrice(wallet, address, token, priceUSD) {
778
+ return wallet.writeContract({
779
+ address,
780
+ abi: viem.parseAbi(["function setTokenPrice(address token, uint256 price) external"]),
781
+ functionName: "setTokenPrice",
782
+ args: [token, priceUSD],
783
+ chain: wallet.chain
784
+ });
785
+ }
786
+ static async getCachedPrice(publicClient, address) {
787
+ const result = await publicClient.readContract({
788
+ address,
789
+ abi: [{
790
+ name: "cachedPrice",
791
+ type: "function",
792
+ inputs: [],
793
+ outputs: [
794
+ { name: "price", type: "uint208" },
795
+ { name: "updatedAt", type: "uint48" }
796
+ ],
797
+ stateMutability: "view"
798
+ }],
799
+ functionName: "cachedPrice"
800
+ });
801
+ return { price: result[0], updatedAt: result[1] };
802
+ }
803
+ static async getTokenPrice(publicClient, address, token) {
804
+ return publicClient.readContract({
805
+ address,
806
+ abi: [{
807
+ name: "tokenPrices",
808
+ type: "function",
809
+ inputs: [{ name: "token", type: "address" }],
810
+ outputs: [{ name: "", type: "uint256" }],
811
+ stateMutability: "view"
812
+ }],
813
+ functionName: "tokenPrices",
814
+ args: [token]
815
+ });
816
+ }
817
+ static async getDepositedBalance(publicClient, address, user, token) {
818
+ return publicClient.readContract({
819
+ address,
820
+ abi: [{
821
+ name: "balances",
822
+ type: "function",
823
+ inputs: [
824
+ { name: "user", type: "address" },
825
+ { name: "token", type: "address" }
826
+ ],
827
+ outputs: [{ name: "", type: "uint256" }],
828
+ stateMutability: "view"
829
+ }],
830
+ functionName: "balances",
831
+ args: [user, token]
832
+ });
833
+ }
834
+ static async ensurePriceInitialized(wallet, publicClient, address) {
835
+ const { price } = await this.getCachedPrice(publicClient, address);
836
+ if (price === 0n) {
837
+ await this.updatePrice(wallet, address);
838
+ return true;
839
+ }
840
+ return false;
841
+ }
842
+ static async addStake(wallet, address, amount, unstakeDelaySec) {
843
+ return wallet.writeContract({
844
+ address,
845
+ abi: viem.parseAbi(["function addStake(uint32 unstakeDelaySec) external payable"]),
846
+ functionName: "addStake",
847
+ args: [unstakeDelaySec],
848
+ value: amount,
849
+ chain: wallet.chain
850
+ });
851
+ }
852
+ static async addDeposit(wallet, address, amount) {
853
+ return wallet.writeContract({
854
+ address,
855
+ abi: viem.parseAbi(["function addDeposit() external payable"]),
856
+ functionName: "addDeposit",
857
+ value: amount,
858
+ chain: wallet.chain
859
+ });
860
+ }
861
+ static async addGasToken(wallet, address, token) {
862
+ return wallet.writeContract({
863
+ address,
864
+ abi: ["function addGasToken(address token)"],
865
+ functionName: "addGasToken",
866
+ args: [token],
867
+ chain: wallet.chain
868
+ });
869
+ }
870
+ static async removeGasToken(wallet, address, token) {
871
+ return wallet.writeContract({
872
+ address,
873
+ abi: ["function removeGasToken(address token)"],
874
+ functionName: "removeGasToken",
875
+ args: [token],
876
+ chain: wallet.chain
877
+ });
878
+ }
879
+ static async setServiceFeeRate(wallet, address, rate) {
880
+ return wallet.writeContract({
881
+ address,
882
+ abi: ["function setServiceFeeRate(uint256 rate)"],
883
+ functionName: "setServiceFeeRate",
884
+ args: [rate],
885
+ chain: wallet.chain
886
+ });
887
+ }
888
+ static async setMaxGasCostCap(wallet, address, cap) {
889
+ return wallet.writeContract({
890
+ address,
891
+ abi: ["function setMaxGasCostCap(uint256 cap)"],
892
+ functionName: "setMaxGasCostCap",
893
+ args: [cap],
894
+ chain: wallet.chain
895
+ });
896
+ }
897
+ static async withdrawPNT(wallet, address, to, token, amount) {
898
+ return wallet.writeContract({
899
+ address,
900
+ abi: ["function withdrawPNT(address to, address token, uint256 amount)"],
901
+ functionName: "withdrawPNT",
902
+ args: [to, token, amount],
903
+ chain: wallet.chain
904
+ });
905
+ }
906
+ // --- Diagnostics & Automation ---
907
+ static async checkGaslessReadiness(publicClient, entryPoint, paymasterAddress, user, token) {
908
+ const issues = [];
909
+ const depositInfo = await publicClient.readContract({
910
+ address: entryPoint,
911
+ abi: viem.parseAbi(["function getDepositInfo(address account) external view returns (uint256 deposit, bool staked, uint256 stake, uint32 unstakeDelaySec, uint48 withdrawTime)"]),
912
+ functionName: "getDepositInfo",
913
+ args: [paymasterAddress]
914
+ });
915
+ if (depositInfo[2] < 50000000000000000n) issues.push("Paymaster stake in EntryPoint is less than 0.05 ETH");
916
+ if (depositInfo[3] < 86400) issues.push("Paymaster unstake delay is less than 1 day");
917
+ if (depositInfo[0] < 100000000000000000n) issues.push("Paymaster deposit in EntryPoint is less than 0.1 ETH");
918
+ const ethPrice = await publicClient.readContract({
919
+ address: paymasterAddress,
920
+ abi: viem.parseAbi(["function cachedPrice() external view returns (uint208 price, uint48 updatedAt)"]),
921
+ functionName: "cachedPrice"
922
+ }).catch(() => [0n, 0n]);
923
+ if (ethPrice[0] === 0n) issues.push("Paymaster ETH/USD price not initialized");
924
+ const [tokenPrice, userTokenBal, userPMDeposit] = await Promise.all([
925
+ this.getTokenPrice(publicClient, paymasterAddress, token),
926
+ publicClient.readContract({
927
+ address: token,
928
+ abi: viem.parseAbi(["function balanceOf(address account) external view returns (uint256)"]),
929
+ functionName: "balanceOf",
930
+ args: [user]
931
+ }),
932
+ this.getDepositedBalance(publicClient, paymasterAddress, user, token)
933
+ ]);
934
+ if (tokenPrice === 0n) issues.push("Token price not set in Paymaster");
935
+ if (userPMDeposit === 0n) issues.push("User has no deposit in Paymaster");
936
+ return {
937
+ isReady: issues.length === 0,
938
+ issues,
939
+ details: {
940
+ paymasterStake: depositInfo[2],
941
+ paymasterDeposit: depositInfo[0],
942
+ ethUsdPrice: ethPrice.price,
943
+ tokenSupported: true,
944
+ tokenPrice,
945
+ userTokenBalance: userTokenBal,
946
+ userPaymasterDeposit: userPMDeposit
947
+ }
948
+ };
949
+ }
950
+ static async prepareGaslessEnvironment(operatorWallet, publicClient, entryPoint, paymasterAddress, token, options = {}) {
951
+ const report = await this.checkGaslessReadiness(publicClient, entryPoint, paymasterAddress, operatorWallet.account.address, token);
952
+ const results = [];
953
+ if (report.details.paymasterStake < (options.minStake || 50000000000000000n)) {
954
+ const hash = await this.addStake(operatorWallet, paymasterAddress, options.minStake || 50000000000000000n, 86400);
955
+ await publicClient.waitForTransactionReceipt({ hash });
956
+ results.push({ step: "Stake", hash, status: "Confirmed" });
957
+ }
958
+ if (report.details.paymasterDeposit < (options.minDeposit || 100000000000000000n)) {
959
+ const hash = await this.addDeposit(operatorWallet, paymasterAddress, options.minDeposit || 300000000000000000n);
960
+ await publicClient.waitForTransactionReceipt({ hash });
961
+ results.push({ step: "Deposit", hash, status: "Confirmed" });
962
+ }
963
+ if (report.details.ethUsdPrice === 0n) {
964
+ const hash = await this.updatePrice(operatorWallet, paymasterAddress);
965
+ await publicClient.waitForTransactionReceipt({ hash });
966
+ results.push({ step: "OraclePrice", hash, status: "Confirmed" });
967
+ }
968
+ if (report.details.tokenPrice === 0n) {
969
+ try {
970
+ const hash = await this.addGasToken(operatorWallet, paymasterAddress, token);
971
+ await publicClient.waitForTransactionReceipt({ hash });
972
+ results.push({ step: "AddGasToken", hash, status: "Confirmed" });
973
+ } catch (e) {
974
+ }
975
+ if (options.tokenPriceUSD) {
976
+ const hash = await this.setTokenPrice(operatorWallet, paymasterAddress, token, options.tokenPriceUSD);
977
+ await publicClient.waitForTransactionReceipt({ hash });
978
+ results.push({ step: "TokenPrice", hash, status: "Confirmed" });
979
+ }
980
+ }
981
+ return results;
982
+ }
983
+ };
984
+ var SuperPaymasterClient = class {
985
+ /**
986
+ * @private
987
+ * Static utility class, should not be instantiated.
988
+ */
989
+ constructor() {
990
+ }
991
+ /**
992
+ * Submit a gasless transaction using SuperPaymaster.
993
+ * Automatically handles gas estimation with a smart efficiency buffer.
994
+ */
995
+ static async submitGaslessTransaction(client, wallet, aaAddress, entryPoint, bundlerUrl, config) {
996
+ const callData = viem.encodeFunctionData({
997
+ abi: viem.parseAbi(["function execute(address dest, uint256 value, bytes func) external"]),
998
+ functionName: "execute",
999
+ args: [
1000
+ config.token,
1001
+ 0n,
1002
+ viem.encodeFunctionData({
1003
+ abi: viem.parseAbi(["function transfer(address to, uint256 amount) external returns (bool)"]),
1004
+ functionName: "transfer",
1005
+ args: [config.recipient, config.amount]
1006
+ })
1007
+ ]
1008
+ });
1009
+ console.log(`[SuperPaymasterClient] \u{1F3AF} Target Info:`);
1010
+ console.log(` - Paymaster: ${config.paymasterAddress}`);
1011
+ console.log(` - Token: ${config.token}`);
1012
+ console.log(` - Operator: ${config.operator}`);
1013
+ console.log("[SuperPaymasterClient] \u2601\uFE0F Estimating Gas usage...");
1014
+ const est = await PaymasterClient.estimateUserOperationGas(
1015
+ client,
1016
+ wallet,
1017
+ aaAddress,
1018
+ entryPoint,
1019
+ config.paymasterAddress,
1020
+ config.token,
1021
+ bundlerUrl,
1022
+ callData,
1023
+ {
1024
+ operator: config.operator,
1025
+ factory: config.factory,
1026
+ factoryData: config.factoryData
1027
+ }
1028
+ );
1029
+ console.log("[SuperPaymasterClient] \u2601\uFE0F Bundler Estimates:", est);
1030
+ const tunedVGL = tuneGasLimit(est.verificationGasLimit, 35000n, 0.45);
1031
+ const bundlerEstimateVGL = est.paymasterVerificationGasLimit || 100000n;
1032
+ const tunedPMVerificationGas = tuneGasLimit(bundlerEstimateVGL, 60000n, 0.45);
1033
+ const _postOpBase = est.paymasterPostOpGasLimit + 100000n;
1034
+ const tunedPostOp = _postOpBase > 200000n ? _postOpBase : 200000n;
1035
+ console.log(`[SuperPaymasterClient] \u{1F527} Tuned Limits: VGL=${tunedVGL}, PMVGL=${tunedPMVerificationGas}, PostOp=${tunedPostOp}`);
1036
+ return PaymasterClient.submitGaslessUserOperation(
1037
+ client,
1038
+ wallet,
1039
+ aaAddress,
1040
+ entryPoint,
1041
+ config.paymasterAddress,
1042
+ config.token,
1043
+ bundlerUrl,
1044
+ callData,
1045
+ {
1046
+ operator: config.operator,
1047
+ verificationGasLimit: tunedVGL,
1048
+ callGasLimit: est.callGasLimit,
1049
+ preVerificationGas: est.preVerificationGas,
1050
+ paymasterVerificationGasLimit: tunedPMVerificationGas,
1051
+ // EXPLICIT PM LIMIT
1052
+ paymasterPostOpGasLimit: tunedPostOp,
1053
+ autoEstimate: false,
1054
+ // We did it ourselves
1055
+ factory: config.factory,
1056
+ factoryData: config.factoryData
1057
+ }
1058
+ );
1059
+ }
1060
+ };
1061
+
1062
+ // ../paymaster/src/PaymasterManager.ts
1063
+ var PaymasterManager = class _PaymasterManager {
1064
+ knownPaymasters;
1065
+ constructor(opts) {
1066
+ this.knownPaymasters = /* @__PURE__ */ new Map();
1067
+ if (opts?.knownPaymasters) {
1068
+ for (const [address, type] of Object.entries(opts.knownPaymasters)) {
1069
+ this.setKnownPaymaster(address, type);
1070
+ }
1071
+ }
1072
+ }
1073
+ /**
1074
+ * Register a known paymaster address → type mapping so that callers can
1075
+ * omit the explicit `type` and have it resolved from the address.
1076
+ */
1077
+ registerPaymaster(address, type) {
1078
+ this.setKnownPaymaster(address, type);
1079
+ }
1080
+ /**
1081
+ * Record an address → type mapping, throwing on a CONFLICTING re-registration.
1082
+ * Silently overwriting a v4 address with `super` (or vice-versa) would later
1083
+ * pack the wrong-length paymasterData for a `type`-less call, so a conflicting
1084
+ * re-registration is treated as a programmer error. Re-registering the SAME
1085
+ * type (including a case-variant of the address) is an idempotent no-op.
1086
+ */
1087
+ setKnownPaymaster(address, type) {
1088
+ const normalized = address.toLowerCase();
1089
+ const existing = this.knownPaymasters.get(normalized);
1090
+ if (existing && existing !== type) {
1091
+ throw new Error(
1092
+ `Paymaster ${address} is already registered as '${existing}'; refusing to re-register as '${type}'`
1093
+ );
1094
+ }
1095
+ this.knownPaymasters.set(normalized, type);
1096
+ }
1097
+ /**
1098
+ * Resolve a paymaster's type from a registered address. Returns undefined
1099
+ * if the address is not registered.
1100
+ */
1101
+ resolveType(address) {
1102
+ return this.knownPaymasters.get(address.toLowerCase());
1103
+ }
1104
+ /**
1105
+ * Build `paymasterAndData`, auto-selecting the correct byte layout for the
1106
+ * paymaster type. Dispatches to the existing per-type packers.
1107
+ */
1108
+ buildPaymasterData(params) {
1109
+ const type = params.type ?? this.resolveType(params.paymasterAddress);
1110
+ if (!type) {
1111
+ throw new Error(
1112
+ `PaymasterManager: cannot resolve paymaster type for ${params.paymasterAddress}. Pass an explicit \`type\` ('v4' | 'super') or register the address via registerPaymaster().`
1113
+ );
1114
+ }
1115
+ return _PaymasterManager.dispatch(type, params);
1116
+ }
1117
+ /**
1118
+ * Static helper: build `paymasterAndData` for an explicit type without an
1119
+ * instance. Useful when the caller already knows the type.
1120
+ */
1121
+ static buildPaymasterData(type, params) {
1122
+ return _PaymasterManager.dispatch(type, params);
1123
+ }
1124
+ static dispatch(type, params) {
1125
+ switch (type) {
1126
+ case "v4": {
1127
+ if (!params.token) {
1128
+ throw new Error("PaymasterManager: type 'v4' requires `token`.");
1129
+ }
1130
+ return buildPaymasterData(params.paymasterAddress, params.token, {
1131
+ validityWindow: params.validityWindow,
1132
+ verificationGasLimit: params.verificationGasLimit,
1133
+ postOpGasLimit: params.postOpGasLimit
1134
+ });
1135
+ }
1136
+ case "super": {
1137
+ if (!params.operator) {
1138
+ throw new Error("PaymasterManager: type 'super' requires `operator`.");
1139
+ }
1140
+ return buildSuperPaymasterData(params.paymasterAddress, params.operator, {
1141
+ verificationGasLimit: params.verificationGasLimit,
1142
+ postOpGasLimit: params.postOpGasLimit,
1143
+ maxRate: params.maxRate
1144
+ });
1145
+ }
1146
+ default: {
1147
+ const _never = type;
1148
+ throw new Error(`PaymasterManager: unsupported paymaster type '${_never}'.`);
1149
+ }
1150
+ }
1151
+ }
1152
+ };
1153
+
1154
+ exports.PaymasterClient = PaymasterClient;
1155
+ exports.PaymasterManager = PaymasterManager;
1156
+ exports.PaymasterOperator = PaymasterOperator;
1157
+ exports.SuperPaymasterAdminClient = SuperPaymasterAdminClient;
1158
+ exports.SuperPaymasterClient = SuperPaymasterClient;
1159
+ exports.buildPaymasterData = buildPaymasterData;
1160
+ exports.buildSuperPaymasterData = buildSuperPaymasterData;
1161
+ exports.checkEligibility = checkEligibility;
1162
+ exports.formatUserOpV07 = formatUserOpV07;
1163
+ exports.getPaymasterV4Middleware = getPaymasterV4Middleware;
1164
+ exports.getSuperPaymasterMiddleware = getSuperPaymasterMiddleware;
1165
+ exports.getUserOpHashV07 = getUserOpHashV07;
1166
+ exports.tuneGasLimit = tuneGasLimit;
1167
+ //# sourceMappingURL=chunk-2RCJBWPO.cjs.map
1168
+ //# sourceMappingURL=chunk-2RCJBWPO.cjs.map