@pimlico/alto 0.0.0-main.20250626T085447 → 0.0.0-main.20250627T140102

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 (150) hide show
  1. package/contracts/EIP712.sol/EIP712.json +1 -1
  2. package/contracts/Eip7702Support.sol/Eip7702Support.json +1 -1
  3. package/contracts/EntryPoint.sol/EntryPoint.json +1 -1
  4. package/contracts/EntryPointSimulations.sol/EntryPointSimulations07.json +1 -1
  5. package/contracts/EntryPointSimulations.sol/EntryPointSimulations08.json +1 -1
  6. package/contracts/Exec.sol/Exec.json +1 -1
  7. package/contracts/IAccount.sol/IAccount.json +1 -1
  8. package/contracts/IAccountExecute.sol/IAccountExecute.json +1 -1
  9. package/contracts/IAggregator.sol/IAggregator.json +1 -1
  10. package/contracts/IERC5267.sol/IERC5267.json +1 -1
  11. package/contracts/IEntryPoint.sol/IEntryPoint.json +1 -1
  12. package/contracts/IEntryPointSimulations.sol/IEntryPointSimulations.json +1 -1
  13. package/contracts/INonceManager.sol/INonceManager.json +1 -1
  14. package/contracts/IPaymaster.sol/IPaymaster.json +1 -1
  15. package/contracts/ISenderCreator.sol/ISenderCreator.json +1 -1
  16. package/contracts/IStakeManager.sol/IStakeManager.json +1 -1
  17. package/contracts/Math.sol/Math.json +1 -1
  18. package/contracts/MessageHashUtils.sol/MessageHashUtils.json +1 -1
  19. package/contracts/NonceManager.sol/NonceManager.json +1 -1
  20. package/contracts/Panic.sol/Panic.json +1 -1
  21. package/contracts/PimlicoSimulations.sol/PimlicoSimulations.json +1 -1
  22. package/contracts/ReentrancyGuardTransient.sol/ReentrancyGuardTransient.json +1 -1
  23. package/contracts/SafeCast.sol/SafeCast.json +1 -1
  24. package/contracts/SenderCreator.sol/SenderCreator.json +1 -1
  25. package/contracts/ShortStrings.sol/ShortStrings.json +1 -1
  26. package/contracts/SignedMath.sol/SignedMath.json +1 -1
  27. package/contracts/StakeManager.sol/StakeManager.json +1 -1
  28. package/contracts/StorageSlot.sol/StorageSlot.json +1 -1
  29. package/contracts/Strings.sol/Strings.json +1 -1
  30. package/contracts/TransientSlot.sol/TransientSlot.json +1 -1
  31. package/contracts/UserOperationLib.sol/UserOperationLib.json +1 -1
  32. package/contracts/build-info/004071c167bc55de.json +1 -0
  33. package/contracts/build-info/{257ff8e2b1124ead.json → 2f5dec90e180c3a0.json} +1 -1
  34. package/contracts/interfaces/IEntryPoint.sol/IEntryPoint.json +1 -1
  35. package/esm/cli/customTransport.js +3 -2
  36. package/esm/cli/customTransport.js.map +1 -1
  37. package/esm/contracts/EntryPointSimulations.sol/EntryPointSimulations07.json +1 -1
  38. package/esm/contracts/EntryPointSimulations.sol/EntryPointSimulations08.json +1 -1
  39. package/esm/contracts/PimlicoSimulations.sol/PimlicoSimulations.json +1 -1
  40. package/esm/executor/executorManager.js +1 -1
  41. package/esm/executor/executorManager.js.map +1 -1
  42. package/esm/executor/filterOpsAndEstimateGas.js +7 -7
  43. package/esm/executor/filterOpsAndEstimateGas.js.map +1 -1
  44. package/esm/executor/getBundleStatus.js +2 -2
  45. package/esm/executor/getBundleStatus.js.map +1 -1
  46. package/esm/executor/userOpMonitor.d.ts +1 -1
  47. package/esm/executor/userOpMonitor.js +17 -17
  48. package/esm/executor/userOpMonitor.js.map +1 -1
  49. package/esm/executor/utils.js +5 -2
  50. package/esm/executor/utils.js.map +1 -1
  51. package/esm/handlers/eventManager.d.ts +9 -9
  52. package/esm/handlers/eventManager.js +22 -22
  53. package/esm/handlers/eventManager.js.map +1 -1
  54. package/esm/mempool/mempool.js +17 -17
  55. package/esm/mempool/mempool.js.map +1 -1
  56. package/esm/mempool/monitoring.d.ts +3 -3
  57. package/esm/mempool/monitoring.js +11 -11
  58. package/esm/mempool/monitoring.js.map +1 -1
  59. package/esm/mempool/reputationManager.d.ts +26 -26
  60. package/esm/mempool/reputationManager.js +65 -65
  61. package/esm/mempool/reputationManager.js.map +1 -1
  62. package/esm/rpc/estimation/gasEstimationHandler.d.ts +8 -8
  63. package/esm/rpc/estimation/gasEstimationHandler.js +16 -16
  64. package/esm/rpc/estimation/gasEstimationHandler.js.map +1 -1
  65. package/esm/rpc/estimation/{gasEstimationsV06.d.ts → gasEstimations06.d.ts} +5 -5
  66. package/esm/rpc/estimation/gasEstimations06.js +68 -0
  67. package/esm/rpc/estimation/gasEstimations06.js.map +1 -0
  68. package/esm/rpc/estimation/gasEstimations07.d.ts +89 -0
  69. package/esm/rpc/estimation/gasEstimations07.js +386 -0
  70. package/esm/rpc/estimation/gasEstimations07.js.map +1 -0
  71. package/esm/rpc/estimation/types.d.ts +23 -111
  72. package/esm/rpc/estimation/types.js +5 -121
  73. package/esm/rpc/estimation/types.js.map +1 -1
  74. package/esm/rpc/estimation/utils.d.ts +51 -0
  75. package/esm/rpc/estimation/utils.js +182 -0
  76. package/esm/rpc/estimation/utils.js.map +1 -0
  77. package/esm/rpc/methods/boost_sendUserOperation.js +14 -15
  78. package/esm/rpc/methods/boost_sendUserOperation.js.map +1 -1
  79. package/esm/rpc/methods/eth_estimateUserOperationGas.js +29 -32
  80. package/esm/rpc/methods/eth_estimateUserOperationGas.js.map +1 -1
  81. package/esm/rpc/methods/eth_getUserOperationByHash.js +6 -6
  82. package/esm/rpc/methods/eth_getUserOperationByHash.js.map +1 -1
  83. package/esm/rpc/methods/eth_getUserOperationReceipt.js +3 -3
  84. package/esm/rpc/methods/eth_getUserOperationReceipt.js.map +1 -1
  85. package/esm/rpc/methods/eth_sendUserOperation.d.ts +2 -2
  86. package/esm/rpc/methods/eth_sendUserOperation.js +33 -34
  87. package/esm/rpc/methods/eth_sendUserOperation.js.map +1 -1
  88. package/esm/rpc/methods/pimlico_getUserOperationStatus.js +2 -2
  89. package/esm/rpc/methods/pimlico_getUserOperationStatus.js.map +1 -1
  90. package/esm/rpc/methods/pimlico_sendUserOperationNow.js +11 -11
  91. package/esm/rpc/methods/pimlico_sendUserOperationNow.js.map +1 -1
  92. package/esm/rpc/rpcHandler.d.ts +4 -4
  93. package/esm/rpc/rpcHandler.js +34 -36
  94. package/esm/rpc/rpcHandler.js.map +1 -1
  95. package/esm/rpc/validation/SafeValidator.d.ts +13 -13
  96. package/esm/rpc/validation/SafeValidator.js +59 -57
  97. package/esm/rpc/validation/SafeValidator.js.map +1 -1
  98. package/esm/rpc/validation/TracerResultParserV06.d.ts +2 -2
  99. package/esm/rpc/validation/TracerResultParserV06.js +4 -4
  100. package/esm/rpc/validation/TracerResultParserV06.js.map +1 -1
  101. package/esm/rpc/validation/TracerResultParserV07.d.ts +2 -2
  102. package/esm/rpc/validation/TracerResultParserV07.js +8 -8
  103. package/esm/rpc/validation/TracerResultParserV07.js.map +1 -1
  104. package/esm/rpc/validation/UnsafeValidator.d.ts +19 -19
  105. package/esm/rpc/validation/UnsafeValidator.js +39 -33
  106. package/esm/rpc/validation/UnsafeValidator.js.map +1 -1
  107. package/esm/store/createMemoryOutstandingStore.js +4 -4
  108. package/esm/store/createMemoryOutstandingStore.js.map +1 -1
  109. package/esm/store/createMempoolStore.js +2 -2
  110. package/esm/store/createMempoolStore.js.map +1 -1
  111. package/esm/store/createRedisOutstandingStore.js +4 -4
  112. package/esm/store/createRedisOutstandingStore.js.map +1 -1
  113. package/esm/types/contracts/PimlicoSimulations.d.ts +1083 -96
  114. package/esm/types/contracts/PimlicoSimulations.js +1357 -88
  115. package/esm/types/contracts/PimlicoSimulations.js.map +1 -1
  116. package/esm/types/contracts/index.d.ts +0 -2
  117. package/esm/types/contracts/index.js +0 -2
  118. package/esm/types/contracts/index.js.map +1 -1
  119. package/esm/types/interfaces.d.ts +14 -14
  120. package/esm/types/validation.d.ts +208 -222
  121. package/esm/types/validation.js +0 -8
  122. package/esm/types/validation.js.map +1 -1
  123. package/esm/utils/helpers.d.ts +2 -2
  124. package/esm/utils/helpers.js +2 -2
  125. package/esm/utils/helpers.js.map +1 -1
  126. package/esm/utils/metrics.d.ts +9 -9
  127. package/esm/utils/metrics.js +18 -18
  128. package/esm/utils/metrics.js.map +1 -1
  129. package/esm/utils/preVerificationGasCalulator.d.ts +3 -3
  130. package/esm/utils/preVerificationGasCalulator.js +13 -13
  131. package/esm/utils/preVerificationGasCalulator.js.map +1 -1
  132. package/esm/utils/toViemStateOverrides.d.ts +4 -0
  133. package/esm/utils/toViemStateOverrides.js +44 -0
  134. package/esm/utils/toViemStateOverrides.js.map +1 -0
  135. package/esm/utils/userop.d.ts +15 -15
  136. package/esm/utils/userop.js +77 -77
  137. package/esm/utils/userop.js.map +1 -1
  138. package/package.json +1 -1
  139. package/contracts/build-info/10cf9b18fcc1598e.json +0 -1
  140. package/esm/rpc/estimation/gasEstimationsV06.js +0 -156
  141. package/esm/rpc/estimation/gasEstimationsV06.js.map +0 -1
  142. package/esm/rpc/estimation/gasEstimationsV07.d.ts +0 -101
  143. package/esm/rpc/estimation/gasEstimationsV07.js +0 -724
  144. package/esm/rpc/estimation/gasEstimationsV07.js.map +0 -1
  145. package/esm/types/contracts/EntryPointSimulationsV6.d.ts +0 -33
  146. package/esm/types/contracts/EntryPointSimulationsV6.js +0 -46
  147. package/esm/types/contracts/EntryPointSimulationsV6.js.map +0 -1
  148. package/esm/types/contracts/EntryPointSimulationsV7.d.ts +0 -2076
  149. package/esm/types/contracts/EntryPointSimulationsV7.js +0 -2675
  150. package/esm/types/contracts/EntryPointSimulationsV7.js.map +0 -1
@@ -1,724 +0,0 @@
1
- import { EntryPointV07Abi, EntryPointV07SimulationsAbi, ExecutionErrors, PimlicoSimulationsAbi, RpcError, ValidationErrors, binarySearchCallResultSchema } from "../../types/index.js";
2
- import { getAuthorizationStateOverrides, getUserOperationHash, isVersion08, toPackedUserOperation } from "../../utils/index.js";
3
- import { decodeAbiParameters, decodeErrorResult, decodeFunctionResult, encodeFunctionData, slice, toFunctionSelector, toHex, zeroAddress } from "viem";
4
- import { AccountExecuteAbi } from "../../types/contracts/IAccountExecute.js";
5
- import { simulationValidationResultStruct } from "./types.js";
6
- export class GasEstimatorV07 {
7
- config;
8
- logger;
9
- constructor(config) {
10
- this.config = config;
11
- this.logger = config.getLogger({
12
- module: "gas-estimator-v07"
13
- }, {
14
- level: config.logLevel
15
- });
16
- }
17
- async simulateValidation({ entryPoint, userOperation, queuedUserOperations }) {
18
- const userOperations = [...queuedUserOperations, userOperation];
19
- const packedUserOperations = userOperations.map((uo) => toPackedUserOperation(uo));
20
- const simulateValidationLast = encodeFunctionData({
21
- abi: EntryPointV07SimulationsAbi,
22
- functionName: "simulateValidationLast",
23
- args: [packedUserOperations]
24
- });
25
- const stateOverrides = getAuthorizationStateOverrides({
26
- userOperations: [...queuedUserOperations, userOperation]
27
- });
28
- const isV8 = isVersion08(userOperation, entryPoint);
29
- const entryPointSimulationsAddress = isV8
30
- ? this.config.entrypointSimulationContractV8
31
- : this.config.entrypointSimulationContractV7;
32
- if (!entryPointSimulationsAddress) {
33
- throw new Error(`Cannot find entryPointSimulationsAddress for version ${isV8 ? "08" : "07"}`);
34
- }
35
- const errorResult = await this.callPimlicoSimulations({
36
- entryPoint,
37
- entryPointSimulationsCallData: [simulateValidationLast],
38
- stateOverrides,
39
- entryPointSimulationsAddress
40
- });
41
- return {
42
- simulateValidationResult: getSimulateValidationResult(errorResult[0])
43
- };
44
- }
45
- async encodeUserOperationCalldata({ op, entryPoint }) {
46
- const packedOp = toPackedUserOperation(op);
47
- const executeUserOpMethodSig = toFunctionSelector(AccountExecuteAbi[0]);
48
- const callDataMethodSig = slice(packedOp.callData, 0, 4);
49
- if (executeUserOpMethodSig === callDataMethodSig) {
50
- return encodeFunctionData({
51
- abi: AccountExecuteAbi,
52
- functionName: "executeUserOp",
53
- args: [
54
- packedOp,
55
- await getUserOperationHash({
56
- userOperation: op,
57
- entryPointAddress: entryPoint,
58
- chainId: this.config.chainId,
59
- publicClient: this.config.publicClient
60
- })
61
- ]
62
- });
63
- }
64
- return packedOp.callData;
65
- }
66
- async encodeSimulateHandleOpLast({ userOperation, queuedUserOperations, entryPoint }) {
67
- const userOperations = [...queuedUserOperations, userOperation];
68
- const packedUserOperations = await Promise.all(userOperations.map(async (uop) => ({
69
- packedUserOperation: toPackedUserOperation(uop),
70
- userOperation: uop,
71
- userOperationHash: await getUserOperationHash({
72
- userOperation: uop,
73
- entryPointAddress: entryPoint,
74
- chainId: this.config.chainId,
75
- publicClient: this.config.publicClient
76
- })
77
- })));
78
- const simulateHandleOpCallData = encodeFunctionData({
79
- abi: EntryPointV07SimulationsAbi,
80
- functionName: "simulateHandleOpLast",
81
- args: [packedUserOperations.map((uop) => uop.packedUserOperation)]
82
- });
83
- return simulateHandleOpCallData;
84
- }
85
- async encodeBinarySearchGasLimit({ entryPoint, userOperation, queuedUserOperations, target, targetCallData, gasAllowance = this.config.binarySearchGasAllowance, initialMinGas = 0n, functionName }) {
86
- const queuedOps = await Promise.all(queuedUserOperations.map(async (op) => ({
87
- op: toPackedUserOperation(op),
88
- target: op.sender,
89
- targetCallData: await this.encodeUserOperationCalldata({
90
- op,
91
- entryPoint
92
- })
93
- })));
94
- const targetOp = {
95
- op: toPackedUserOperation(userOperation),
96
- target,
97
- targetCallData
98
- };
99
- const binarySearchVerificationGasLimit = encodeFunctionData({
100
- abi: EntryPointV07SimulationsAbi,
101
- functionName,
102
- args: [
103
- queuedOps,
104
- targetOp,
105
- entryPoint,
106
- initialMinGas,
107
- this.config.binarySearchToleranceDelta,
108
- gasAllowance
109
- ]
110
- });
111
- return binarySearchVerificationGasLimit;
112
- }
113
- // Try to get the calldata gas again if the initial simulation reverted due to hitting the eth_call gasLimit.
114
- async retryBinarySearch({ entryPoint, optimalGas, minGas, targetOp, target, targetCallData, functionName, queuedOps, stateOverrides = {} }) {
115
- const maxRetries = this.config.binarySearchMaxRetries;
116
- let retryCount = 0;
117
- let currentOptimalGas = optimalGas;
118
- let currentMinGas = minGas;
119
- while (retryCount < maxRetries) {
120
- // OptimalGas represents the current lowest gasLimit, so we set the gasAllowance to search range minGas <-> optimalGas
121
- const gasAllowance = currentOptimalGas - currentMinGas;
122
- const binarySearchCallGasLimit = await this.encodeBinarySearchGasLimit({
123
- entryPoint,
124
- userOperation: targetOp,
125
- target,
126
- targetCallData,
127
- queuedUserOperations: queuedOps,
128
- initialMinGas: currentMinGas,
129
- gasAllowance,
130
- functionName
131
- });
132
- stateOverrides = getAuthorizationStateOverrides({
133
- userOperations: [...queuedOps, targetOp],
134
- stateOverrides
135
- });
136
- const isV8 = isVersion08(targetOp, entryPoint);
137
- const entryPointSimulationsAddress = isV8
138
- ? this.config.entrypointSimulationContractV8
139
- : this.config.entrypointSimulationContractV7;
140
- if (!entryPointSimulationsAddress) {
141
- throw new Error(`Cannot find entryPointSimulationsAddress for version ${isV8 ? "08" : "07"}`);
142
- }
143
- let cause = await this.callPimlicoSimulations({
144
- entryPoint,
145
- entryPointSimulationsCallData: [binarySearchCallGasLimit],
146
- stateOverrides,
147
- entryPointSimulationsAddress
148
- });
149
- cause = cause.map((data) => {
150
- const decodedDelegateAndError = decodeErrorResult({
151
- abi: EntryPointV07Abi,
152
- data: data
153
- });
154
- if (!decodedDelegateAndError?.args?.[1]) {
155
- throw new Error("Unexpected error");
156
- }
157
- return decodedDelegateAndError.args[1];
158
- });
159
- const callGasLimitResult = validateBinarySearchDataResult(cause[0], functionName);
160
- if (callGasLimitResult.result === "failed") {
161
- return callGasLimitResult;
162
- }
163
- if (callGasLimitResult.result === "retry") {
164
- currentOptimalGas = callGasLimitResult.optimalGas;
165
- currentMinGas = callGasLimitResult.minGas;
166
- retryCount++;
167
- continue;
168
- }
169
- // If we reach here, it means we have a successful result
170
- return {
171
- result: "success",
172
- data: callGasLimitResult.data
173
- };
174
- }
175
- // If we've exhausted all retries, return a failure result
176
- return {
177
- result: "failed",
178
- data: "Max retries reached for getting call data gas",
179
- code: ValidationErrors.SimulateValidation
180
- };
181
- }
182
- async validateHandleOpV07({ entryPoint, userOperation, queuedUserOperations, stateOverrides = {} }) {
183
- const simulateHandleOpLast = await this.encodeSimulateHandleOpLast({
184
- entryPoint,
185
- userOperation,
186
- queuedUserOperations
187
- });
188
- stateOverrides = getAuthorizationStateOverrides({
189
- userOperations: [...queuedUserOperations, userOperation],
190
- stateOverrides
191
- });
192
- const isV8 = isVersion08(userOperation, entryPoint);
193
- const entryPointSimulationsAddress = isV8
194
- ? this.config.entrypointSimulationContractV8
195
- : this.config.entrypointSimulationContractV7;
196
- if (!entryPointSimulationsAddress) {
197
- throw new Error(`Cannot find entryPointSimulationsAddress for version ${isV8 ? "08" : "07"}`);
198
- }
199
- let cause = [
200
- (await this.callPimlicoSimulations({
201
- entryPoint,
202
- entryPointSimulationsCallData: [simulateHandleOpLast],
203
- stateOverrides,
204
- entryPointSimulationsAddress
205
- }))[0]
206
- ];
207
- cause = cause.map((data) => {
208
- const decodedDelegateAndError = decodeErrorResult({
209
- abi: EntryPointV07Abi,
210
- data: data
211
- });
212
- const delegateAndRevertResponseBytes = decodedDelegateAndError?.args?.[1];
213
- if (!delegateAndRevertResponseBytes) {
214
- throw new Error("Unexpected error");
215
- }
216
- return delegateAndRevertResponseBytes;
217
- });
218
- const [simulateHandleOpLastCause] = cause;
219
- try {
220
- const simulateHandleOpLastResult = getSimulateHandleOpResult(simulateHandleOpLastCause);
221
- if (simulateHandleOpLastResult.result === "failed") {
222
- return simulateHandleOpLastResult;
223
- }
224
- return {
225
- result: "execution",
226
- data: {
227
- callGasLimit: 0n,
228
- verificationGasLimit: 0n,
229
- paymasterVerificationGasLimit: 0n,
230
- executionResult: simulateHandleOpLastResult.data.executionResult
231
- }
232
- };
233
- }
234
- catch (_e) {
235
- return {
236
- result: "failed",
237
- data: "Unknown error, could not parse simulate handle op result.",
238
- code: ValidationErrors.SimulateValidation
239
- };
240
- }
241
- }
242
- async simulateHandleOpV07({ entryPoint, userOperation, queuedUserOperations, stateOverrides = {} }) {
243
- const simulateHandleOpLast = await this.encodeSimulateHandleOpLast({
244
- entryPoint,
245
- userOperation,
246
- queuedUserOperations
247
- });
248
- const binarySearchVerificationGasLimit = await this.encodeBinarySearchGasLimit({
249
- initialMinGas: 9000n,
250
- entryPoint,
251
- userOperation,
252
- queuedUserOperations,
253
- target: zeroAddress,
254
- targetCallData: "0x",
255
- functionName: "binarySearchVerificationGasLimit"
256
- });
257
- const binarySearchPaymasterVerificationGasLimit = userOperation.paymaster
258
- ? await this.encodeBinarySearchGasLimit({
259
- initialMinGas: 9000n,
260
- entryPoint,
261
- userOperation,
262
- queuedUserOperations,
263
- target: zeroAddress,
264
- targetCallData: "0x",
265
- functionName: "binarySearchPaymasterVerificationGasLimit"
266
- })
267
- : null;
268
- const binarySearchCallGasLimit = await this.encodeBinarySearchGasLimit({
269
- initialMinGas: 9000n,
270
- entryPoint,
271
- userOperation,
272
- queuedUserOperations,
273
- target: userOperation.sender,
274
- targetCallData: await this.encodeUserOperationCalldata({
275
- op: userOperation,
276
- entryPoint
277
- }),
278
- functionName: "binarySearchCallGasLimit"
279
- });
280
- stateOverrides = getAuthorizationStateOverrides({
281
- userOperations: [...queuedUserOperations, userOperation],
282
- stateOverrides
283
- });
284
- let cause;
285
- const isV8 = isVersion08(userOperation, entryPoint);
286
- const entryPointSimulationsAddress = isV8
287
- ? this.config.entrypointSimulationContractV8
288
- : this.config.entrypointSimulationContractV7;
289
- if (!entryPointSimulationsAddress) {
290
- throw new Error(`Cannot find entryPointSimulationsAddress for version ${isV8 ? "08" : "07"}`);
291
- }
292
- if (this.config.splitSimulationCalls) {
293
- // due to Hedera specific restrictions, we can't combine these two calls.
294
- const [simulateHandleOpLastCause, binarySearchVerificationGasLimitCause, binarySearchPaymasterVerificationGasLimitCause, binarySearchCallGasLimitCause] = await Promise.all([
295
- this.callPimlicoSimulations({
296
- entryPoint,
297
- entryPointSimulationsCallData: [simulateHandleOpLast],
298
- stateOverrides,
299
- entryPointSimulationsAddress
300
- }),
301
- this.callPimlicoSimulations({
302
- entryPoint,
303
- entryPointSimulationsCallData: [
304
- binarySearchVerificationGasLimit
305
- ],
306
- stateOverrides,
307
- entryPointSimulationsAddress
308
- }),
309
- binarySearchPaymasterVerificationGasLimit
310
- ? this.callPimlicoSimulations({
311
- entryPoint,
312
- entryPointSimulationsCallData: [
313
- binarySearchPaymasterVerificationGasLimit
314
- ],
315
- stateOverrides,
316
- entryPointSimulationsAddress
317
- })
318
- : null,
319
- this.callPimlicoSimulations({
320
- entryPoint,
321
- entryPointSimulationsCallData: [binarySearchCallGasLimit],
322
- stateOverrides,
323
- entryPointSimulationsAddress
324
- })
325
- ]);
326
- cause = [
327
- simulateHandleOpLastCause[0],
328
- binarySearchVerificationGasLimitCause[0],
329
- binarySearchPaymasterVerificationGasLimitCause?.[0] ?? null,
330
- binarySearchCallGasLimitCause[0]
331
- ];
332
- }
333
- else {
334
- const [handleOpAndBinarySearchVerificationGasLimits, binarySearchCallDataGasLimits] = await Promise.all([
335
- binarySearchPaymasterVerificationGasLimit
336
- ? await this.callPimlicoSimulations({
337
- entryPoint,
338
- entryPointSimulationsCallData: [
339
- simulateHandleOpLast,
340
- binarySearchVerificationGasLimit,
341
- binarySearchPaymasterVerificationGasLimit
342
- ],
343
- stateOverrides,
344
- entryPointSimulationsAddress
345
- })
346
- : await this.callPimlicoSimulations({
347
- entryPoint,
348
- entryPointSimulationsCallData: [
349
- simulateHandleOpLast,
350
- binarySearchVerificationGasLimit
351
- ],
352
- stateOverrides,
353
- entryPointSimulationsAddress
354
- }),
355
- await this.callPimlicoSimulations({
356
- entryPoint,
357
- entryPointSimulationsCallData: [binarySearchCallGasLimit],
358
- stateOverrides,
359
- entryPointSimulationsAddress
360
- })
361
- ]);
362
- cause = [
363
- handleOpAndBinarySearchVerificationGasLimits[0],
364
- handleOpAndBinarySearchVerificationGasLimits[1],
365
- binarySearchPaymasterVerificationGasLimit
366
- ? handleOpAndBinarySearchVerificationGasLimits[2]
367
- : null,
368
- binarySearchCallDataGasLimits[0]
369
- ];
370
- }
371
- cause = cause.map((data) => {
372
- if (!data) {
373
- return null;
374
- }
375
- const decodedDelegateAndError = decodeErrorResult({
376
- abi: EntryPointV07Abi,
377
- data: data
378
- });
379
- const delegateAndRevertResponseBytes = decodedDelegateAndError?.args?.[1];
380
- if (!delegateAndRevertResponseBytes) {
381
- throw new Error("Unexpected error");
382
- }
383
- return delegateAndRevertResponseBytes;
384
- });
385
- const [simulateHandleOpLastCause, binarySearchVerificationGasLimitCause, binarySearchPaymasterVerificationGasLimitCause, binarySearchCallGasLimitCause] = cause;
386
- try {
387
- const simulateHandleOpLastResult = getSimulateHandleOpResult(simulateHandleOpLastCause);
388
- if (simulateHandleOpLastResult.result === "failed") {
389
- return simulateHandleOpLastResult;
390
- }
391
- const verificationGasLimitResult = validateBinarySearchDataResult(binarySearchVerificationGasLimitCause, "binarySearchVerificationGasLimit");
392
- let verificationGasLimit = 0n;
393
- if (verificationGasLimitResult.result === "success") {
394
- verificationGasLimit = verificationGasLimitResult.data.gasUsed;
395
- }
396
- if (verificationGasLimitResult.result === "failed") {
397
- return verificationGasLimitResult;
398
- }
399
- if (verificationGasLimitResult.result === "retry") {
400
- const { optimalGas, minGas } = verificationGasLimitResult;
401
- const binarySearchResult = await this.retryBinarySearch({
402
- entryPoint,
403
- optimalGas,
404
- minGas,
405
- targetOp: userOperation,
406
- target: zeroAddress,
407
- targetCallData: "0x",
408
- functionName: "binarySearchVerificationGasLimit",
409
- queuedOps: queuedUserOperations,
410
- stateOverrides
411
- });
412
- if (binarySearchResult.result === "failed") {
413
- return binarySearchResult;
414
- }
415
- verificationGasLimit = binarySearchResult.data.gasUsed;
416
- }
417
- const paymasterVerificationGasLimitResult = binarySearchPaymasterVerificationGasLimitCause
418
- ? validateBinarySearchDataResult(binarySearchPaymasterVerificationGasLimitCause, "binarySearchPaymasterVerificationGasLimit")
419
- : {
420
- result: "success",
421
- data: {
422
- gasUsed: 0n,
423
- success: true,
424
- returnData: "0x"
425
- }
426
- };
427
- let paymasterVerificationGasLimit = 0n;
428
- if (paymasterVerificationGasLimitResult.result === "success") {
429
- paymasterVerificationGasLimit =
430
- paymasterVerificationGasLimitResult.data.gasUsed;
431
- }
432
- if (paymasterVerificationGasLimitResult.result === "failed") {
433
- return paymasterVerificationGasLimitResult;
434
- }
435
- if (paymasterVerificationGasLimitResult.result === "retry") {
436
- const { optimalGas, minGas } = paymasterVerificationGasLimitResult;
437
- const binarySearchResult = await this.retryBinarySearch({
438
- entryPoint,
439
- optimalGas,
440
- minGas,
441
- targetOp: userOperation,
442
- target: zeroAddress,
443
- targetCallData: "0x",
444
- functionName: "binarySearchPaymasterVerificationGasLimit",
445
- queuedOps: queuedUserOperations,
446
- stateOverrides
447
- });
448
- if (binarySearchResult.result === "failed") {
449
- return binarySearchResult;
450
- }
451
- paymasterVerificationGasLimit = binarySearchResult.data.gasUsed;
452
- }
453
- const callGasLimitResult = validateBinarySearchDataResult(binarySearchCallGasLimitCause, "binarySearchCallGasLimit");
454
- let callGasLimit = 0n;
455
- if (callGasLimitResult.result === "success") {
456
- callGasLimit = callGasLimitResult.data.gasUsed;
457
- }
458
- if (callGasLimitResult.result === "failed") {
459
- return callGasLimitResult;
460
- }
461
- if (callGasLimitResult.result === "retry") {
462
- const { optimalGas, minGas } = callGasLimitResult;
463
- const binarySearchResult = await this.retryBinarySearch({
464
- entryPoint,
465
- optimalGas,
466
- minGas,
467
- targetOp: userOperation,
468
- target: userOperation.sender,
469
- targetCallData: await this.encodeUserOperationCalldata({
470
- op: userOperation,
471
- entryPoint
472
- }),
473
- functionName: "binarySearchCallGasLimit",
474
- queuedOps: queuedUserOperations,
475
- stateOverrides
476
- });
477
- if (binarySearchResult.result === "failed") {
478
- return binarySearchResult;
479
- }
480
- callGasLimit = binarySearchResult.data.gasUsed;
481
- }
482
- return {
483
- result: "execution",
484
- data: {
485
- callGasLimit,
486
- verificationGasLimit,
487
- paymasterVerificationGasLimit,
488
- executionResult: simulateHandleOpLastResult.data.executionResult
489
- }
490
- };
491
- }
492
- catch (_e) {
493
- return {
494
- result: "failed",
495
- data: "Unknown error, could not parse simulate handle op result.",
496
- code: ValidationErrors.SimulateValidation
497
- };
498
- }
499
- }
500
- async callPimlicoSimulations({ entryPoint, entryPointSimulationsCallData, stateOverrides, entryPointSimulationsAddress }) {
501
- const { publicClient, blockTagSupport, utilityWalletAddress, fixedGasLimitForEstimation, balanceOverride: balanceOverrideSupport, codeOverrideSupport, pimlicoSimulationContract } = this.config;
502
- if (!entryPointSimulationsAddress) {
503
- throw new RpcError("entryPointSimulationsAddress must be provided", ValidationErrors.InvalidFields);
504
- }
505
- if (!pimlicoSimulationContract) {
506
- throw new RpcError("pimlicoSimulationContract must be provided", ValidationErrors.InvalidFields);
507
- }
508
- const callData = encodeFunctionData({
509
- abi: PimlicoSimulationsAbi,
510
- functionName: "simulateEntryPoint",
511
- args: [
512
- entryPointSimulationsAddress,
513
- entryPoint,
514
- entryPointSimulationsCallData
515
- ]
516
- });
517
- // Remove state override if not supported by network.
518
- if (!balanceOverrideSupport && !codeOverrideSupport) {
519
- stateOverrides = undefined;
520
- }
521
- const result = (await publicClient.request({
522
- method: "eth_call",
523
- params: [
524
- {
525
- to: pimlicoSimulationContract,
526
- from: utilityWalletAddress,
527
- data: callData,
528
- ...(fixedGasLimitForEstimation !== undefined && {
529
- gas: `0x${fixedGasLimitForEstimation.toString(16)}`
530
- })
531
- },
532
- blockTagSupport
533
- ? "latest"
534
- : toHex(await publicClient.getBlockNumber()),
535
- // @ts-ignore
536
- ...(stateOverrides ? [stateOverrides] : [])
537
- ]
538
- }));
539
- try {
540
- const returnBytes = decodeAbiParameters([{ name: "ret", type: "bytes[]" }], result);
541
- return returnBytes[0];
542
- }
543
- catch (err) {
544
- this.logger.error({ err, result }, "Failed to decode simulation result");
545
- throw new RpcError("Failed to decode simulation result", ValidationErrors.SimulateValidation);
546
- }
547
- }
548
- }
549
- const panicCodes = {
550
- // from https://docs.soliditylang.org/en/v0.8.0/control-structures.html
551
- 1: "assert(false)",
552
- 17: "arithmetic overflow/underflow",
553
- 18: "divide by zero",
554
- 33: "invalid enum value",
555
- 34: "storage byte array that is incorrectly encoded",
556
- 49: ".pop() on an empty array.",
557
- 50: "array sout-of-bounds or negative index",
558
- 65: "memory overflow",
559
- 81: "zero-initialized variable of internal function type"
560
- };
561
- export function parseFailedOpWithRevert(data) {
562
- const methodSig = data.slice(0, 10);
563
- const dataParams = `0x${data.slice(10)}`;
564
- if (methodSig === "0x08c379a0") {
565
- const [err] = decodeAbiParameters([
566
- {
567
- name: "err",
568
- type: "string"
569
- }
570
- ], dataParams);
571
- return err;
572
- }
573
- if (methodSig === "0x4e487b71") {
574
- const [code] = decodeAbiParameters([
575
- {
576
- name: "err",
577
- type: "uint256"
578
- }
579
- ], dataParams);
580
- return panicCodes[Number(code)] ?? `${code}`;
581
- }
582
- return data;
583
- }
584
- export function getSimulateValidationResult(errorData) {
585
- const decodedDelegateAndError = decodeErrorResult({
586
- abi: EntryPointV07Abi,
587
- data: errorData
588
- });
589
- if (!decodedDelegateAndError?.args?.[1]) {
590
- throw new Error("Unexpected error");
591
- }
592
- try {
593
- const decodedError = decodeErrorResult({
594
- abi: EntryPointV07SimulationsAbi,
595
- data: decodedDelegateAndError.args[1]
596
- });
597
- if (decodedError &&
598
- decodedError.errorName === "FailedOp" &&
599
- decodedError.args) {
600
- return {
601
- status: "failed",
602
- data: decodedError.args[1]
603
- };
604
- }
605
- if (decodedError &&
606
- decodedError.errorName === "FailedOpWithRevert" &&
607
- decodedError.args) {
608
- return {
609
- status: "failed",
610
- data: `${decodedError.args?.[1]} - ${parseFailedOpWithRevert(decodedError.args?.[2])}`
611
- };
612
- }
613
- }
614
- catch {
615
- const decodedResult = decodeAbiParameters(simulationValidationResultStruct, decodedDelegateAndError.args[1])[0];
616
- return {
617
- status: "validation",
618
- data: decodedResult
619
- };
620
- }
621
- throw new Error("Unexpected error - errorName is not ValidationResult or ValidationResultWithAggregation");
622
- }
623
- function validateBinarySearchDataResult(data, fnName) {
624
- try {
625
- const targetCallResult = decodeFunctionResult({
626
- abi: EntryPointV07SimulationsAbi,
627
- functionName: fnName,
628
- data: data
629
- });
630
- const parsedTargetCallResult = binarySearchCallResultSchema.parse(targetCallResult);
631
- if (parsedTargetCallResult.success) {
632
- return {
633
- result: "success",
634
- data: parsedTargetCallResult
635
- };
636
- }
637
- return {
638
- result: "failed",
639
- data: parsedTargetCallResult.returnData,
640
- code: ExecutionErrors.UserOperationReverted
641
- };
642
- }
643
- catch (_e) {
644
- try {
645
- const res = decodeErrorResult({
646
- abi: EntryPointV07SimulationsAbi,
647
- data: data
648
- });
649
- if (res.errorName === "SimulationOutOfGas") {
650
- const [optimalGas, minGas, maxGas] = res.args;
651
- return {
652
- result: "retry",
653
- optimalGas,
654
- minGas,
655
- maxGas
656
- };
657
- }
658
- return {
659
- result: "failed",
660
- data,
661
- code: ExecutionErrors.UserOperationReverted
662
- };
663
- }
664
- catch {
665
- // no error we go the result
666
- return {
667
- result: "failed",
668
- data: "Unknown error, could not parse target call data result.",
669
- code: ExecutionErrors.UserOperationReverted
670
- };
671
- }
672
- }
673
- }
674
- function getSimulateHandleOpResult(data) {
675
- try {
676
- const decodedError = decodeErrorResult({
677
- abi: EntryPointV07SimulationsAbi,
678
- data: data
679
- });
680
- if (decodedError &&
681
- decodedError.errorName === "FailedOp" &&
682
- decodedError.args) {
683
- return {
684
- result: "failed",
685
- data: decodedError.args[1],
686
- code: ValidationErrors.SimulateValidation
687
- };
688
- }
689
- if (decodedError &&
690
- decodedError.errorName === "FailedOpWithRevert" &&
691
- decodedError.args) {
692
- return {
693
- result: "failed",
694
- data: `${decodedError.args[1]} ${parseFailedOpWithRevert(decodedError.args?.[2])}`,
695
- code: ValidationErrors.SimulateValidation
696
- };
697
- }
698
- if (decodedError &&
699
- decodedError.errorName === "CallPhaseReverted" &&
700
- decodedError.args) {
701
- return {
702
- result: "failed",
703
- data: decodedError.args[0],
704
- code: ValidationErrors.SimulateValidation
705
- };
706
- }
707
- }
708
- catch {
709
- // no error we go the result
710
- const decodedResult = decodeFunctionResult({
711
- abi: EntryPointV07SimulationsAbi,
712
- functionName: "simulateHandleOp",
713
- data
714
- });
715
- return {
716
- result: "execution",
717
- data: {
718
- executionResult: decodedResult
719
- }
720
- };
721
- }
722
- throw new Error("Unexpected error");
723
- }
724
- //# sourceMappingURL=gasEstimationsV07.js.map