@pimlico/alto 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/esm/cli/alto.d.ts +6 -0
  2. package/esm/cli/alto.js +92 -0
  3. package/esm/cli/alto.js.map +1 -0
  4. package/esm/cli/config/bundler.d.ts +403 -0
  5. package/esm/cli/config/bundler.js +134 -0
  6. package/esm/cli/config/bundler.js.map +1 -0
  7. package/esm/cli/config/index.d.ts +3 -0
  8. package/esm/cli/config/index.js +3 -0
  9. package/esm/cli/config/index.js.map +1 -0
  10. package/esm/cli/config/options.d.ts +11 -0
  11. package/esm/cli/config/options.js +348 -0
  12. package/esm/cli/config/options.js.map +1 -0
  13. package/esm/cli/customTransport.d.ts +14 -0
  14. package/esm/cli/customTransport.js +53 -0
  15. package/esm/cli/customTransport.js.map +1 -0
  16. package/esm/cli/handler.d.ts +3 -0
  17. package/esm/cli/handler.js +140 -0
  18. package/esm/cli/handler.js.map +1 -0
  19. package/esm/cli/index.d.ts +4 -0
  20. package/esm/cli/index.js +4 -0
  21. package/esm/cli/index.js.map +1 -0
  22. package/esm/cli/instrumentation.d.ts +2 -0
  23. package/esm/cli/instrumentation.js +39 -0
  24. package/esm/cli/instrumentation.js.map +1 -0
  25. package/esm/cli/setupServer.d.ts +17 -0
  26. package/esm/cli/setupServer.js +155 -0
  27. package/esm/cli/setupServer.js.map +1 -0
  28. package/esm/cli/util.d.ts +22 -0
  29. package/esm/cli/util.js +30 -0
  30. package/esm/cli/util.js.map +1 -0
  31. package/esm/executor/executor.d.ts +55 -0
  32. package/esm/executor/executor.js +645 -0
  33. package/esm/executor/executor.js.map +1 -0
  34. package/esm/executor/executorManager.d.ts +34 -0
  35. package/esm/executor/executorManager.js +402 -0
  36. package/esm/executor/executorManager.js.map +1 -0
  37. package/esm/executor/index.d.ts +5 -0
  38. package/esm/executor/index.js +5 -0
  39. package/esm/executor/index.js.map +1 -0
  40. package/esm/executor/senderManager.d.ts +17 -0
  41. package/esm/executor/senderManager.js +160 -0
  42. package/esm/executor/senderManager.js.map +1 -0
  43. package/esm/executor/test/utils.d.ts +13 -0
  44. package/esm/executor/test/utils.js +75 -0
  45. package/esm/executor/test/utils.js.map +1 -0
  46. package/esm/executor/utils.d.ts +32 -0
  47. package/esm/executor/utils.js +241 -0
  48. package/esm/executor/utils.js.map +1 -0
  49. package/esm/index.d.ts +2 -0
  50. package/esm/index.js +2 -0
  51. package/esm/index.js.map +1 -0
  52. package/esm/mempool/index.d.ts +5 -0
  53. package/esm/mempool/index.js +5 -0
  54. package/esm/mempool/index.js.map +1 -0
  55. package/esm/mempool/mempool.d.ts +64 -0
  56. package/esm/mempool/mempool.js +487 -0
  57. package/esm/mempool/mempool.js.map +1 -0
  58. package/esm/mempool/monitoring.d.ts +10 -0
  59. package/esm/mempool/monitoring.js +34 -0
  60. package/esm/mempool/monitoring.js.map +1 -0
  61. package/esm/mempool/nullMempool.d.ts +15 -0
  62. package/esm/mempool/nullMempool.js +36 -0
  63. package/esm/mempool/nullMempool.js.map +1 -0
  64. package/esm/mempool/reputationManager.d.ts +115 -0
  65. package/esm/mempool/reputationManager.js +401 -0
  66. package/esm/mempool/reputationManager.js.map +1 -0
  67. package/esm/mempool/store.d.ts +22 -0
  68. package/esm/mempool/store.js +123 -0
  69. package/esm/mempool/store.js.map +1 -0
  70. package/esm/rpc/EntryPointSimulationsV07.d.ts +62 -0
  71. package/esm/rpc/EntryPointSimulationsV07.js +407 -0
  72. package/esm/rpc/EntryPointSimulationsV07.js.map +1 -0
  73. package/esm/rpc/ExecuteSimulator.d.ts +37 -0
  74. package/esm/rpc/ExecuteSimulator.js +48 -0
  75. package/esm/rpc/ExecuteSimulator.js.map +1 -0
  76. package/esm/rpc/gasEstimation.d.ts +17 -0
  77. package/esm/rpc/gasEstimation.js +414 -0
  78. package/esm/rpc/gasEstimation.js.map +1 -0
  79. package/esm/rpc/index.d.ts +5 -0
  80. package/esm/rpc/index.js +5 -0
  81. package/esm/rpc/index.js.map +1 -0
  82. package/esm/rpc/nonceQueuer.d.ts +25 -0
  83. package/esm/rpc/nonceQueuer.js +135 -0
  84. package/esm/rpc/nonceQueuer.js.map +1 -0
  85. package/esm/rpc/rpcHandler.d.ts +64 -0
  86. package/esm/rpc/rpcHandler.js +738 -0
  87. package/esm/rpc/rpcHandler.js.map +1 -0
  88. package/esm/rpc/server.d.ts +31 -0
  89. package/esm/rpc/server.js +243 -0
  90. package/esm/rpc/server.js.map +1 -0
  91. package/esm/rpc/validation/BundlerCollectorTracerV06.d.ts +102 -0
  92. package/esm/rpc/validation/BundlerCollectorTracerV06.js +255 -0
  93. package/esm/rpc/validation/BundlerCollectorTracerV06.js.map +1 -0
  94. package/esm/rpc/validation/BundlerCollectorTracerV07.d.ts +102 -0
  95. package/esm/rpc/validation/BundlerCollectorTracerV07.js +254 -0
  96. package/esm/rpc/validation/BundlerCollectorTracerV07.js.map +1 -0
  97. package/esm/rpc/validation/SafeValidator.d.ts +31 -0
  98. package/esm/rpc/validation/SafeValidator.js +330 -0
  99. package/esm/rpc/validation/SafeValidator.js.map +1 -0
  100. package/esm/rpc/validation/TracerResultParserV06.d.ts +13 -0
  101. package/esm/rpc/validation/TracerResultParserV06.js +578 -0
  102. package/esm/rpc/validation/TracerResultParserV06.js.map +1 -0
  103. package/esm/rpc/validation/TracerResultParserV07.d.ts +33 -0
  104. package/esm/rpc/validation/TracerResultParserV07.js +561 -0
  105. package/esm/rpc/validation/TracerResultParserV07.js.map +1 -0
  106. package/esm/rpc/validation/UnsafeValidator.d.ts +64 -0
  107. package/esm/rpc/validation/UnsafeValidator.js +257 -0
  108. package/esm/rpc/validation/UnsafeValidator.js.map +1 -0
  109. package/esm/rpc/validation/index.d.ts +3 -0
  110. package/esm/rpc/validation/index.js +3 -0
  111. package/esm/rpc/validation/index.js.map +1 -0
  112. package/esm/rpc/validation/tracer.d.ts +122 -0
  113. package/esm/rpc/validation/tracer.js +82 -0
  114. package/esm/rpc/validation/tracer.js.map +1 -0
  115. package/esm/types/contracts/BundleBulker.d.ts +120 -0
  116. package/esm/types/contracts/BundleBulker.js +157 -0
  117. package/esm/types/contracts/BundleBulker.js.map +1 -0
  118. package/esm/types/contracts/CallEngine.d.ts +28 -0
  119. package/esm/types/contracts/CallEngine.js +37 -0
  120. package/esm/types/contracts/CallEngine.js.map +1 -0
  121. package/esm/types/contracts/CodeHashGetter.d.ts +37 -0
  122. package/esm/types/contracts/CodeHashGetter.js +45 -0
  123. package/esm/types/contracts/CodeHashGetter.js.map +1 -0
  124. package/esm/types/contracts/EntryPoint.d.ts +1789 -0
  125. package/esm/types/contracts/EntryPoint.js +2304 -0
  126. package/esm/types/contracts/EntryPoint.js.map +1 -0
  127. package/esm/types/contracts/EntryPointSimulations.d.ts +152 -0
  128. package/esm/types/contracts/EntryPointSimulations.js +1954 -0
  129. package/esm/types/contracts/EntryPointSimulations.js.map +1 -0
  130. package/esm/types/contracts/IOpInflator.d.ts +61 -0
  131. package/esm/types/contracts/IOpInflator.js +80 -0
  132. package/esm/types/contracts/IOpInflator.js.map +1 -0
  133. package/esm/types/contracts/IPaymaster.d.ts +3 -0
  134. package/esm/types/contracts/IPaymaster.js +117 -0
  135. package/esm/types/contracts/IPaymaster.js.map +1 -0
  136. package/esm/types/contracts/Inflator.d.ts +65 -0
  137. package/esm/types/contracts/Inflator.js +84 -0
  138. package/esm/types/contracts/Inflator.js.map +1 -0
  139. package/esm/types/contracts/PerOpInflator.d.ts +176 -0
  140. package/esm/types/contracts/PerOpInflator.js +229 -0
  141. package/esm/types/contracts/PerOpInflator.js.map +1 -0
  142. package/esm/types/contracts/PimlicoEntryPointSimulations.d.ts +23 -0
  143. package/esm/types/contracts/PimlicoEntryPointSimulations.js +33 -0
  144. package/esm/types/contracts/PimlicoEntryPointSimulations.js.map +1 -0
  145. package/esm/types/contracts/SenderCreator.d.ts +4 -0
  146. package/esm/types/contracts/SenderCreator.js +23 -0
  147. package/esm/types/contracts/SenderCreator.js.map +1 -0
  148. package/esm/types/contracts/SimpleAccountFactory.d.ts +57 -0
  149. package/esm/types/contracts/SimpleAccountFactory.js +76 -0
  150. package/esm/types/contracts/SimpleAccountFactory.js.map +1 -0
  151. package/esm/types/contracts/TestOpcodesAccount.d.ts +4 -0
  152. package/esm/types/contracts/TestOpcodesAccount.js +281 -0
  153. package/esm/types/contracts/TestOpcodesAccount.js.map +1 -0
  154. package/esm/types/contracts/TestOpcodesAccountFactory.d.ts +4 -0
  155. package/esm/types/contracts/TestOpcodesAccountFactory.js +23 -0
  156. package/esm/types/contracts/TestOpcodesAccountFactory.js.map +1 -0
  157. package/esm/types/contracts/TestStorageAccount.d.ts +4 -0
  158. package/esm/types/contracts/TestStorageAccount.js +313 -0
  159. package/esm/types/contracts/TestStorageAccount.js.map +1 -0
  160. package/esm/types/contracts/index.d.ts +17 -0
  161. package/esm/types/contracts/index.js +17 -0
  162. package/esm/types/contracts/index.js.map +1 -0
  163. package/esm/types/gasPrice.d.ts +110 -0
  164. package/esm/types/gasPrice.js +52 -0
  165. package/esm/types/gasPrice.js.map +1 -0
  166. package/esm/types/index.d.ts +11 -0
  167. package/esm/types/index.js +11 -0
  168. package/esm/types/index.js.map +1 -0
  169. package/esm/types/interfaces.d.ts +26 -0
  170. package/esm/types/interfaces.js +2 -0
  171. package/esm/types/interfaces.js.map +1 -0
  172. package/esm/types/mempool.d.ts +79 -0
  173. package/esm/types/mempool.js +16 -0
  174. package/esm/types/mempool.js.map +1 -0
  175. package/esm/types/schemas.d.ts +4791 -0
  176. package/esm/types/schemas.js +497 -0
  177. package/esm/types/schemas.js.map +1 -0
  178. package/esm/types/test/validationTestErrors.d.ts +3 -0
  179. package/esm/types/test/validationTestErrors.js +229 -0
  180. package/esm/types/test/validationTestErrors.js.map +1 -0
  181. package/esm/types/utils.d.ts +24 -0
  182. package/esm/types/utils.js +30 -0
  183. package/esm/types/utils.js.map +1 -0
  184. package/esm/types/validation.d.ts +14327 -0
  185. package/esm/types/validation.js +304 -0
  186. package/esm/types/validation.js.map +1 -0
  187. package/esm/utils/bigInt.d.ts +3 -0
  188. package/esm/utils/bigInt.js +9 -0
  189. package/esm/utils/bigInt.js.map +1 -0
  190. package/esm/utils/compressionHandler.d.ts +11 -0
  191. package/esm/utils/compressionHandler.js +39 -0
  192. package/esm/utils/compressionHandler.js.map +1 -0
  193. package/esm/utils/gasPriceManager.d.ts +34 -0
  194. package/esm/utils/gasPriceManager.js +338 -0
  195. package/esm/utils/gasPriceManager.js.map +1 -0
  196. package/esm/utils/helpers.d.ts +4 -0
  197. package/esm/utils/helpers.js +13 -0
  198. package/esm/utils/helpers.js.map +1 -0
  199. package/esm/utils/index.d.ts +11 -0
  200. package/esm/utils/index.js +10 -0
  201. package/esm/utils/index.js.map +1 -0
  202. package/esm/utils/logger.d.ts +6 -0
  203. package/esm/utils/logger.js +76 -0
  204. package/esm/utils/logger.js.map +1 -0
  205. package/esm/utils/metrics.d.ts +22 -0
  206. package/esm/utils/metrics.js +150 -0
  207. package/esm/utils/metrics.js.map +1 -0
  208. package/esm/utils/rpc-reply.d.ts +17 -0
  209. package/esm/utils/rpc-reply.js +41 -0
  210. package/esm/utils/rpc-reply.js.map +1 -0
  211. package/esm/utils/test.d.ts +17 -0
  212. package/esm/utils/test.js +130 -0
  213. package/esm/utils/test.js.map +1 -0
  214. package/esm/utils/userop.d.ts +49 -0
  215. package/esm/utils/userop.js +408 -0
  216. package/esm/utils/userop.js.map +1 -0
  217. package/esm/utils/validation.d.ts +65 -0
  218. package/esm/utils/validation.js +461 -0
  219. package/esm/utils/validation.js.map +1 -0
  220. package/lib/cli/config/bundler.d.ts +12 -0
  221. package/lib/cli/config/bundler.js +3 -1
  222. package/lib/cli/config/bundler.js.map +1 -1
  223. package/lib/cli/config/options.js +12 -0
  224. package/lib/cli/config/options.js.map +1 -1
  225. package/lib/cli/handler.js +25 -1
  226. package/lib/cli/handler.js.map +1 -1
  227. package/lib/cli/setupServer.js +1 -1
  228. package/lib/cli/setupServer.js.map +1 -1
  229. package/lib/executor/executor.d.ts +2 -1
  230. package/lib/executor/executor.js +6 -4
  231. package/lib/executor/executor.js.map +1 -1
  232. package/lib/executor/utils.d.ts +1 -1
  233. package/lib/executor/utils.js +4 -4
  234. package/lib/executor/utils.js.map +1 -1
  235. package/lib/mempool/mempool.js +5 -7
  236. package/lib/mempool/mempool.js.map +1 -1
  237. package/lib/mempool/reputationManager.js +7 -3
  238. package/lib/mempool/reputationManager.js.map +1 -1
  239. package/lib/rpc/EntryPointSimulationsV07.d.ts +5 -1
  240. package/lib/rpc/EntryPointSimulationsV07.js +3 -2
  241. package/lib/rpc/EntryPointSimulationsV07.js.map +1 -1
  242. package/lib/rpc/gasEstimation.js +7 -3
  243. package/lib/rpc/gasEstimation.js.map +1 -1
  244. package/lib/rpc/rpcHandler.js +18 -7
  245. package/lib/rpc/rpcHandler.js.map +1 -1
  246. package/lib/rpc/server.js +4 -0
  247. package/lib/rpc/server.js.map +1 -1
  248. package/lib/rpc/validation/SafeValidator.d.ts +2 -6
  249. package/lib/rpc/validation/SafeValidator.js +48 -205
  250. package/lib/rpc/validation/SafeValidator.js.map +1 -1
  251. package/lib/rpc/validation/TracerResultParserV07.js +6 -2
  252. package/lib/rpc/validation/TracerResultParserV07.js.map +1 -1
  253. package/lib/rpc/validation/UnsafeValidator.d.ts +2 -1
  254. package/lib/rpc/validation/UnsafeValidator.js +45 -68
  255. package/lib/rpc/validation/UnsafeValidator.js.map +1 -1
  256. package/lib/types/contracts/EntryPointSimulations.d.ts +0 -1
  257. package/lib/types/contracts/EntryPointSimulations.js +1942 -3
  258. package/lib/types/contracts/EntryPointSimulations.js.map +1 -1
  259. package/lib/types/contracts/PimlicoEntryPointSimulations.d.ts +1 -1
  260. package/lib/types/contracts/PimlicoEntryPointSimulations.js +2 -2
  261. package/lib/types/contracts/PimlicoEntryPointSimulations.js.map +1 -1
  262. package/lib/utils/userop.js +2 -25
  263. package/lib/utils/userop.js.map +1 -1
  264. package/package.json +2 -1
@@ -0,0 +1,645 @@
1
+ import { EntryPointV06Abi, EntryPointV07Abi, deriveUserOperation } from "../types/index.js";
2
+ import { getUserOperationHash, isVersion06, maxBigInt, parseViemError, toPackedUserOperation } from "../utils/index.js";
3
+ import * as sentry from "@sentry/node";
4
+ import { Mutex } from "async-mutex";
5
+ import { FeeCapTooLowError, InsufficientFundsError, IntrinsicGasTooLowError, NonceTooLowError, encodeFunctionData, getContract } from "viem";
6
+ import { createCompressedCalldata, filterOpsAndEstimateGas, flushStuckTransaction, simulatedOpsToResults } from "./utils.js";
7
+ export class NullExecutor {
8
+ bundle(_entryPoint, _ops) {
9
+ return Promise.resolve([]);
10
+ }
11
+ bundleCompressed(_entryPoint, _compressedOps) {
12
+ return Promise.resolve([]);
13
+ }
14
+ replaceTransaction(_entryPoint, _transactionInfo) {
15
+ return Promise.resolve({ status: "failed" });
16
+ }
17
+ replaceOps(_opHashes) {
18
+ return Promise.resolve();
19
+ }
20
+ cancelOps(_entryPoint, _ops) {
21
+ return Promise.resolve();
22
+ }
23
+ markWalletProcessed(_executor) {
24
+ return Promise.resolve();
25
+ }
26
+ flushStuckTransactions() {
27
+ return Promise.resolve();
28
+ }
29
+ }
30
+ export class Executor {
31
+ // private unWatch: WatchBlocksReturnType | undefined
32
+ publicClient;
33
+ walletClient;
34
+ entryPoints;
35
+ senderManager;
36
+ logger;
37
+ metrics;
38
+ simulateTransaction;
39
+ legacyTransactions;
40
+ fixedGasLimitForEstimation;
41
+ localGasLimitCalculation;
42
+ reputationManager;
43
+ compressionHandler;
44
+ gasPriceManager;
45
+ disableBlockTagSupport;
46
+ mutex;
47
+ constructor(publicClient, walletClient, senderManager, reputationManager, entryPoints, logger, metrics, compressionHandler, gasPriceManager, simulateTransaction = false, legacyTransactions = false, fixedGasLimitForEstimation, disableBlockTagSupport = false, localGasLimitCalculation = false) {
48
+ this.publicClient = publicClient;
49
+ this.walletClient = walletClient;
50
+ this.senderManager = senderManager;
51
+ this.reputationManager = reputationManager;
52
+ this.logger = logger;
53
+ this.metrics = metrics;
54
+ this.simulateTransaction = simulateTransaction;
55
+ this.legacyTransactions = legacyTransactions;
56
+ this.fixedGasLimitForEstimation = fixedGasLimitForEstimation;
57
+ this.localGasLimitCalculation = localGasLimitCalculation;
58
+ this.compressionHandler = compressionHandler;
59
+ this.gasPriceManager = gasPriceManager;
60
+ this.disableBlockTagSupport = disableBlockTagSupport;
61
+ this.entryPoints = entryPoints;
62
+ this.mutex = new Mutex();
63
+ }
64
+ getCompressionHandler() {
65
+ if (!this.compressionHandler) {
66
+ throw new Error("Support for compressed bundles has not initialized");
67
+ }
68
+ return this.compressionHandler;
69
+ }
70
+ cancelOps(_entryPoint, _ops) {
71
+ throw new Error("Method not implemented.");
72
+ }
73
+ markWalletProcessed(executor) {
74
+ if (!this.senderManager.availableWallets.includes(executor)) {
75
+ this.senderManager.pushWallet(executor);
76
+ }
77
+ return Promise.resolve();
78
+ }
79
+ async replaceTransaction(transactionInfo) {
80
+ const newRequest = { ...transactionInfo.transactionRequest };
81
+ const gasPriceParameters = await this.gasPriceManager.getGasPrice();
82
+ newRequest.maxFeePerGas = maxBigInt(gasPriceParameters.maxFeePerGas, (newRequest.maxFeePerGas * 11n + 9n) / 10n);
83
+ newRequest.maxPriorityFeePerGas = maxBigInt(gasPriceParameters.maxPriorityFeePerGas, (newRequest.maxPriorityFeePerGas * 11n + 9n) / 10n);
84
+ newRequest.account = transactionInfo.executor;
85
+ const opsWithHashes = transactionInfo.userOperationInfos.map((opInfo) => {
86
+ const op = deriveUserOperation(opInfo.mempoolUserOperation);
87
+ return {
88
+ mempoolUserOperation: opInfo.mempoolUserOperation,
89
+ userOperationHash: getUserOperationHash(op, transactionInfo.entryPoint, this.walletClient.chain.id),
90
+ entryPoint: opInfo.entryPoint
91
+ };
92
+ });
93
+ let callContext;
94
+ if (transactionInfo.transactionType === "default") {
95
+ const [isUserOpVersion06, entryPoint] = opsWithHashes.reduce((acc, op) => {
96
+ if (acc[0] !==
97
+ isVersion06(op.mempoolUserOperation) ||
98
+ acc[1] !== op.entryPoint) {
99
+ throw new Error("All user operations must be of the same version");
100
+ }
101
+ return acc;
102
+ }, [
103
+ isVersion06(opsWithHashes[0].mempoolUserOperation),
104
+ opsWithHashes[0].entryPoint
105
+ ]);
106
+ const ep = getContract({
107
+ abi: isUserOpVersion06 ? EntryPointV06Abi : EntryPointV07Abi,
108
+ address: entryPoint,
109
+ client: {
110
+ public: this.publicClient,
111
+ wallet: this.walletClient
112
+ }
113
+ });
114
+ callContext = {
115
+ ep,
116
+ type: "default"
117
+ };
118
+ }
119
+ else {
120
+ const compressionHandler = this.getCompressionHandler();
121
+ callContext = {
122
+ publicClient: this.publicClient,
123
+ bundleBulker: compressionHandler.bundleBulkerAddress,
124
+ perOpInflatorId: compressionHandler.perOpInflatorId,
125
+ type: "compressed"
126
+ };
127
+ }
128
+ const result = await filterOpsAndEstimateGas(transactionInfo.entryPoint, callContext, transactionInfo.executor, opsWithHashes, newRequest.nonce, newRequest.maxFeePerGas, newRequest.maxPriorityFeePerGas, this.disableBlockTagSupport ? undefined : "latest", this.legacyTransactions, this.fixedGasLimitForEstimation, this.reputationManager, this.logger);
129
+ const childLogger = this.logger.child({
130
+ transactionHash: transactionInfo.transactionHash,
131
+ executor: transactionInfo.executor.address
132
+ });
133
+ if (result.simulatedOps.length === 0) {
134
+ childLogger.warn("no ops to bundle");
135
+ this.markWalletProcessed(transactionInfo.executor);
136
+ return { status: "failed" };
137
+ }
138
+ if (result.simulatedOps.every((op) => op.reason === "AA25 invalid account nonce" ||
139
+ op.reason === "AA10 sender already constructed")) {
140
+ childLogger.trace({ reasons: result.simulatedOps.map((sop) => sop.reason) }, "all ops failed simulation with nonce error");
141
+ return { status: "potentially_already_included" };
142
+ }
143
+ if (result.simulatedOps.every((op) => op.reason !== undefined)) {
144
+ childLogger.warn("all ops failed simulation");
145
+ this.markWalletProcessed(transactionInfo.executor);
146
+ return { status: "failed" };
147
+ }
148
+ const opsToBundle = result.simulatedOps
149
+ .filter((op) => op.reason === undefined)
150
+ .map((op) => {
151
+ const opInfo = transactionInfo.userOperationInfos.find((info) => info.userOperationHash === op.owh.userOperationHash);
152
+ if (!opInfo) {
153
+ throw new Error("opInfo not found");
154
+ }
155
+ return opInfo;
156
+ });
157
+ newRequest.gas = this.localGasLimitCalculation
158
+ ? opsToBundle.reduce((acc, opInfo) => {
159
+ const userOperation = deriveUserOperation(opInfo.mempoolUserOperation);
160
+ return (acc +
161
+ userOperation.preVerificationGas +
162
+ 3n * userOperation.verificationGasLimit +
163
+ userOperation.callGasLimit);
164
+ }, 0n)
165
+ : result.gasLimit;
166
+ // update calldata to include only ops that pass simulation
167
+ if (transactionInfo.transactionType === "default") {
168
+ const isUserOpVersion06 = opsWithHashes.reduce((acc, op) => {
169
+ if (acc !==
170
+ isVersion06(op.mempoolUserOperation)) {
171
+ throw new Error("All user operations must be of the same version");
172
+ }
173
+ return acc;
174
+ }, isVersion06(opsWithHashes[0].mempoolUserOperation));
175
+ newRequest.data = isUserOpVersion06
176
+ ? encodeFunctionData({
177
+ abi: EntryPointV06Abi,
178
+ functionName: "handleOps",
179
+ args: [
180
+ opsToBundle.map((opInfo) => opInfo.mempoolUserOperation),
181
+ transactionInfo.executor.address
182
+ ]
183
+ })
184
+ : encodeFunctionData({
185
+ abi: EntryPointV07Abi,
186
+ functionName: "handleOps",
187
+ args: [
188
+ opsToBundle.map((opInfo) => toPackedUserOperation(opInfo.mempoolUserOperation)),
189
+ transactionInfo.executor.address
190
+ ]
191
+ });
192
+ }
193
+ else if (transactionInfo.transactionType === "compressed") {
194
+ const compressedOps = opsToBundle.map((opInfo) => opInfo.mempoolUserOperation);
195
+ newRequest.data = createCompressedCalldata(compressedOps, this.getCompressionHandler().perOpInflatorId);
196
+ }
197
+ try {
198
+ childLogger.info({
199
+ newRequest: {
200
+ ...newRequest,
201
+ abi: undefined,
202
+ chain: undefined
203
+ },
204
+ executor: newRequest.account.address,
205
+ opsToBundle: opsToBundle.map((opInfo) => opInfo.userOperationHash)
206
+ }, "replacing transaction");
207
+ const txHash = await this.walletClient.sendTransaction(this.legacyTransactions
208
+ ? {
209
+ ...newRequest,
210
+ gasPrice: newRequest.maxFeePerGas,
211
+ maxFeePerGas: undefined,
212
+ maxPriorityFeePerGas: undefined,
213
+ type: "legacy",
214
+ accessList: undefined
215
+ }
216
+ : newRequest);
217
+ const newTxInfo = {
218
+ ...transactionInfo,
219
+ transactionRequest: newRequest,
220
+ transactionHash: txHash,
221
+ previousTransactionHashes: [
222
+ transactionInfo.transactionHash,
223
+ ...transactionInfo.previousTransactionHashes
224
+ ],
225
+ lastReplaced: Date.now(),
226
+ userOperationInfos: opsToBundle.map((opInfo) => {
227
+ return {
228
+ entryPoint: opInfo.entryPoint,
229
+ mempoolUserOperation: opInfo.mempoolUserOperation,
230
+ userOperationHash: opInfo.userOperationHash,
231
+ lastReplaced: Date.now(),
232
+ firstSubmitted: opInfo.firstSubmitted
233
+ };
234
+ })
235
+ };
236
+ return {
237
+ status: "replaced",
238
+ transactionInfo: newTxInfo
239
+ };
240
+ }
241
+ catch (err) {
242
+ const e = parseViemError(err);
243
+ if (!e) {
244
+ sentry.captureException(err);
245
+ childLogger.error({ error: err }, "unknown error replacing transaction");
246
+ }
247
+ if (e instanceof NonceTooLowError) {
248
+ childLogger.trace({ error: e }, "nonce too low, potentially already included");
249
+ return { status: "potentially_already_included" };
250
+ }
251
+ if (e instanceof FeeCapTooLowError) {
252
+ childLogger.warn({ error: e }, "fee cap too low, not replacing");
253
+ }
254
+ if (e instanceof InsufficientFundsError) {
255
+ childLogger.warn({ error: e }, "insufficient funds, not replacing");
256
+ }
257
+ if (e instanceof IntrinsicGasTooLowError) {
258
+ childLogger.warn({ error: e }, "intrinsic gas too low, not replacing");
259
+ }
260
+ childLogger.warn({ error: e }, "error replacing transaction");
261
+ this.markWalletProcessed(transactionInfo.executor);
262
+ return { status: "failed" };
263
+ }
264
+ }
265
+ async flushStuckTransactions() {
266
+ const gasPrice = await this.gasPriceManager.getGasPrice();
267
+ const wallets = this.senderManager.utilityAccount
268
+ ? Array.from(new Set([
269
+ ...this.senderManager.wallets,
270
+ this.senderManager.utilityAccount
271
+ ]))
272
+ : Array.from(new Set(this.senderManager.wallets));
273
+ const promises = wallets.map(async (wallet) => {
274
+ for (const entryPoint of this.entryPoints) {
275
+ await flushStuckTransaction(this.publicClient, this.walletClient, wallet, gasPrice.maxFeePerGas * 5n, this.logger, entryPoint);
276
+ }
277
+ });
278
+ await Promise.all(promises);
279
+ }
280
+ async bundle(entryPoint, ops) {
281
+ const wallet = await this.senderManager.getWallet();
282
+ const opsWithHashes = ops.map((op) => {
283
+ return {
284
+ mempoolUserOperation: op,
285
+ userOperationHash: getUserOperationHash(op, entryPoint, this.walletClient.chain.id)
286
+ };
287
+ });
288
+ const isUserOpVersion06 = opsWithHashes.reduce((acc, op) => {
289
+ if (acc !==
290
+ isVersion06(op.mempoolUserOperation)) {
291
+ throw new Error("All user operations must be of the same version");
292
+ }
293
+ return acc;
294
+ }, isVersion06(opsWithHashes[0].mempoolUserOperation));
295
+ const ep = getContract({
296
+ abi: isUserOpVersion06 ? EntryPointV06Abi : EntryPointV07Abi,
297
+ address: entryPoint,
298
+ client: {
299
+ public: this.publicClient,
300
+ wallet: this.walletClient
301
+ }
302
+ });
303
+ let childLogger = this.logger.child({
304
+ userOperations: opsWithHashes.map((oh) => oh.userOperationHash),
305
+ entryPoint
306
+ });
307
+ childLogger.debug("bundling user operation");
308
+ const gasPriceParameters = await this.gasPriceManager.getGasPrice();
309
+ childLogger.debug({ gasPriceParameters }, "got gas price");
310
+ const nonce = await this.publicClient.getTransactionCount({
311
+ address: wallet.address,
312
+ blockTag: "pending"
313
+ });
314
+ childLogger.trace({ nonce }, "got nonce");
315
+ const callContext = {
316
+ ep,
317
+ type: "default"
318
+ };
319
+ let { gasLimit, simulatedOps, resubmitAllOps } = await filterOpsAndEstimateGas(entryPoint, callContext, wallet, opsWithHashes, nonce, gasPriceParameters.maxFeePerGas, gasPriceParameters.maxPriorityFeePerGas, this.disableBlockTagSupport ? undefined : "pending", this.legacyTransactions, this.fixedGasLimitForEstimation, this.reputationManager, childLogger);
320
+ gasLimit += 10000n;
321
+ if (resubmitAllOps) {
322
+ this.markWalletProcessed(wallet);
323
+ return opsWithHashes.map((owh) => {
324
+ const bundleResult = {
325
+ status: "resubmit",
326
+ info: {
327
+ entryPoint,
328
+ userOpHash: owh.userOperationHash,
329
+ userOperation: owh.mempoolUserOperation,
330
+ reason: FeeCapTooLowError.name
331
+ }
332
+ };
333
+ return bundleResult;
334
+ });
335
+ }
336
+ if (simulatedOps.length === 0) {
337
+ childLogger.error("gas limit simulation encountered unexpected failure");
338
+ this.markWalletProcessed(wallet);
339
+ return opsWithHashes.map((owh) => {
340
+ return {
341
+ status: "failure",
342
+ error: {
343
+ entryPoint,
344
+ userOpHash: owh.userOperationHash,
345
+ userOperation: owh.mempoolUserOperation,
346
+ reason: "INTERNAL FAILURE"
347
+ }
348
+ };
349
+ });
350
+ }
351
+ if (simulatedOps.every((op) => op.reason !== undefined)) {
352
+ childLogger.warn("all ops failed simulation");
353
+ this.markWalletProcessed(wallet);
354
+ return simulatedOps.map((op) => {
355
+ return {
356
+ status: "failure",
357
+ error: {
358
+ entryPoint,
359
+ userOpHash: op.owh.userOperationHash,
360
+ userOperation: op.owh.mempoolUserOperation,
361
+ reason: op.reason
362
+ }
363
+ };
364
+ });
365
+ }
366
+ const opsWithHashToBundle = simulatedOps
367
+ .filter((op) => op.reason === undefined)
368
+ .map((op) => op.owh);
369
+ childLogger = this.logger.child({
370
+ userOperations: opsWithHashToBundle.map((owh) => owh.userOperationHash),
371
+ entryPoint
372
+ });
373
+ childLogger.trace({ gasLimit }, "got gas limit");
374
+ let txHash;
375
+ try {
376
+ const gasOptions = this.legacyTransactions
377
+ ? {
378
+ gasPrice: gasPriceParameters.maxFeePerGas
379
+ }
380
+ : {
381
+ maxFeePerGas: gasPriceParameters.maxFeePerGas,
382
+ maxPriorityFeePerGas: gasPriceParameters.maxPriorityFeePerGas
383
+ };
384
+ txHash = isUserOpVersion06
385
+ ? await ep.write.handleOps([
386
+ opsWithHashToBundle.map((owh) => owh.mempoolUserOperation),
387
+ wallet.address
388
+ ], {
389
+ account: wallet,
390
+ gas: gasLimit,
391
+ nonce: nonce,
392
+ ...gasOptions
393
+ })
394
+ : await ep.write.handleOps([
395
+ opsWithHashToBundle.map((owh) => toPackedUserOperation(owh.mempoolUserOperation)),
396
+ wallet.address
397
+ ], {
398
+ account: wallet,
399
+ gas: gasLimit,
400
+ nonce: nonce,
401
+ ...gasOptions
402
+ });
403
+ }
404
+ catch (err) {
405
+ const e = parseViemError(err);
406
+ if (e instanceof InsufficientFundsError) {
407
+ childLogger.error({ error: e }, "insufficient funds, not submitting transaction");
408
+ this.markWalletProcessed(wallet);
409
+ return opsWithHashToBundle.map((owh) => {
410
+ return {
411
+ status: "resubmit",
412
+ info: {
413
+ entryPoint,
414
+ userOpHash: owh.userOperationHash,
415
+ userOperation: owh.mempoolUserOperation,
416
+ reason: InsufficientFundsError.name
417
+ }
418
+ };
419
+ });
420
+ }
421
+ sentry.captureException(err);
422
+ childLogger.error({ error: JSON.stringify(err) }, "error submitting bundle transaction");
423
+ this.markWalletProcessed(wallet);
424
+ return opsWithHashes.map((owh) => {
425
+ return {
426
+ status: "failure",
427
+ error: {
428
+ entryPoint,
429
+ userOpHash: owh.userOperationHash,
430
+ userOperation: owh.mempoolUserOperation,
431
+ reason: "INTERNAL FAILURE"
432
+ }
433
+ };
434
+ });
435
+ }
436
+ const userOperationInfos = opsWithHashToBundle.map((op) => {
437
+ return {
438
+ entryPoint,
439
+ mempoolUserOperation: op.mempoolUserOperation,
440
+ userOperationHash: op.userOperationHash,
441
+ lastReplaced: Date.now(),
442
+ firstSubmitted: Date.now()
443
+ };
444
+ });
445
+ const transactionInfo = {
446
+ entryPoint,
447
+ isVersion06: isUserOpVersion06,
448
+ transactionType: "default",
449
+ transactionHash: txHash,
450
+ previousTransactionHashes: [],
451
+ transactionRequest: {
452
+ account: wallet,
453
+ to: ep.address,
454
+ data: isUserOpVersion06
455
+ ? encodeFunctionData({
456
+ abi: ep.abi,
457
+ functionName: "handleOps",
458
+ args: [
459
+ opsWithHashToBundle.map((owh) => owh.mempoolUserOperation),
460
+ wallet.address
461
+ ]
462
+ })
463
+ : encodeFunctionData({
464
+ abi: ep.abi,
465
+ functionName: "handleOps",
466
+ args: [
467
+ opsWithHashToBundle.map((owh) => toPackedUserOperation(owh.mempoolUserOperation)),
468
+ wallet.address
469
+ ]
470
+ }),
471
+ gas: gasLimit,
472
+ chain: this.walletClient.chain,
473
+ maxFeePerGas: gasPriceParameters.maxFeePerGas,
474
+ maxPriorityFeePerGas: gasPriceParameters.maxPriorityFeePerGas,
475
+ nonce: nonce
476
+ },
477
+ executor: wallet,
478
+ userOperationInfos,
479
+ lastReplaced: Date.now(),
480
+ firstSubmitted: Date.now(),
481
+ timesPotentiallyIncluded: 0
482
+ };
483
+ const userOperationResults = simulatedOpsToResults(simulatedOps, transactionInfo);
484
+ childLogger.info({
485
+ transactionRequest: {
486
+ ...transactionInfo.transactionRequest,
487
+ abi: undefined
488
+ },
489
+ txHash,
490
+ opHashes: opsWithHashToBundle.map((owh) => owh.userOperationHash)
491
+ }, "submitted bundle transaction");
492
+ return userOperationResults;
493
+ }
494
+ async bundleCompressed(entryPoint, compressedOps) {
495
+ const compressionHandler = this.getCompressionHandler();
496
+ const wallet = await this.senderManager.getWallet();
497
+ const childLogger = this.logger.child({
498
+ compressedUserOperations: compressedOps,
499
+ entryPoint: entryPoint
500
+ });
501
+ childLogger.debug("bundling compressed user operation");
502
+ const gasPriceParameters = await this.gasPriceManager.getGasPrice();
503
+ childLogger.debug({ gasPriceParameters }, "got gas price");
504
+ const nonce = await this.publicClient.getTransactionCount({
505
+ address: wallet.address,
506
+ blockTag: "pending"
507
+ });
508
+ childLogger.trace({ nonce }, "got nonce");
509
+ const callContext = {
510
+ publicClient: this.publicClient,
511
+ bundleBulker: compressionHandler.bundleBulkerAddress,
512
+ perOpInflatorId: compressionHandler.perOpInflatorId,
513
+ type: "compressed"
514
+ };
515
+ let { gasLimit, simulatedOps, resubmitAllOps } = await filterOpsAndEstimateGas(entryPoint, callContext, wallet, compressedOps.map((compressedOp) => {
516
+ return {
517
+ mempoolUserOperation: compressedOp,
518
+ userOperationHash: getUserOperationHash(compressedOp.inflatedOp, entryPoint, this.walletClient.chain.id)
519
+ };
520
+ }), nonce, gasPriceParameters.maxFeePerGas, gasPriceParameters.maxPriorityFeePerGas, this.disableBlockTagSupport ? undefined : "pending", this.legacyTransactions, this.fixedGasLimitForEstimation, this.reputationManager, childLogger);
521
+ gasLimit += 10000n;
522
+ if (resubmitAllOps) {
523
+ this.markWalletProcessed(wallet);
524
+ return compressedOps.map((compressedOp) => {
525
+ return {
526
+ status: "resubmit",
527
+ info: {
528
+ entryPoint,
529
+ userOpHash: getUserOperationHash(compressedOp.inflatedOp, entryPoint, this.walletClient.chain.id),
530
+ userOperation: compressedOp,
531
+ reason: FeeCapTooLowError.name
532
+ }
533
+ };
534
+ });
535
+ }
536
+ if (simulatedOps.length === 0) {
537
+ childLogger.warn("no ops to bundle");
538
+ this.markWalletProcessed(wallet);
539
+ return compressedOps.map((compressedOp) => {
540
+ return {
541
+ status: "failure",
542
+ error: {
543
+ entryPoint,
544
+ userOpHash: getUserOperationHash(compressedOp.inflatedOp, entryPoint, this.walletClient.chain.id),
545
+ userOperation: compressedOp,
546
+ reason: "INTERNAL FAILURE"
547
+ }
548
+ };
549
+ });
550
+ }
551
+ // if not all succeeded, return error
552
+ if (simulatedOps.some((simulatedOp) => simulatedOp.reason !== undefined)) {
553
+ childLogger.warn("some ops failed simulation");
554
+ this.markWalletProcessed(wallet);
555
+ return simulatedOps.map((simulatedOp) => {
556
+ return {
557
+ status: "failure",
558
+ error: {
559
+ entryPoint,
560
+ userOpHash: simulatedOp.owh.userOperationHash,
561
+ userOperation: simulatedOp.owh.mempoolUserOperation,
562
+ reason: simulatedOp.reason
563
+ }
564
+ };
565
+ });
566
+ }
567
+ const opsToBundle = simulatedOps
568
+ .filter((simulatedOp) => simulatedOp.reason === undefined)
569
+ .map((simulatedOp) => simulatedOp.owh);
570
+ let txHash;
571
+ try {
572
+ const gasOptions = this.legacyTransactions
573
+ ? {
574
+ gasPrice: gasPriceParameters.maxFeePerGas
575
+ }
576
+ : {
577
+ maxFeePerGas: gasPriceParameters.maxFeePerGas,
578
+ maxPriorityFeePerGas: gasPriceParameters.maxPriorityFeePerGas
579
+ };
580
+ // need to use sendTransaction to target BundleBulker's fallback
581
+ txHash = await this.walletClient.sendTransaction({
582
+ account: wallet,
583
+ to: compressionHandler.bundleBulkerAddress,
584
+ data: createCompressedCalldata(compressedOps, compressionHandler.perOpInflatorId),
585
+ gas: gasLimit,
586
+ nonce: nonce,
587
+ ...gasOptions
588
+ });
589
+ }
590
+ catch (err) {
591
+ sentry.captureException(err);
592
+ childLogger.error({ error: JSON.stringify(err) }, "error submitting bundle transaction");
593
+ this.markWalletProcessed(wallet);
594
+ return opsToBundle.map((op) => {
595
+ return {
596
+ status: "failure",
597
+ error: {
598
+ entryPoint,
599
+ userOpHash: op.userOperationHash,
600
+ userOperation: op.mempoolUserOperation,
601
+ reason: "INTERNAL FAILURE"
602
+ }
603
+ };
604
+ });
605
+ }
606
+ const userOperationInfos = opsToBundle.map((owh) => {
607
+ return {
608
+ entryPoint,
609
+ mempoolUserOperation: owh.mempoolUserOperation,
610
+ userOperationHash: owh.userOperationHash,
611
+ lastReplaced: Date.now(),
612
+ firstSubmitted: Date.now()
613
+ };
614
+ });
615
+ const transactionInfo = {
616
+ entryPoint,
617
+ isVersion06: true, //TODO: compressed bundles are always v06
618
+ transactionType: "compressed",
619
+ transactionHash: txHash,
620
+ previousTransactionHashes: [],
621
+ transactionRequest: {
622
+ to: compressionHandler.bundleBulkerAddress,
623
+ data: createCompressedCalldata(compressedOps, compressionHandler.perOpInflatorId),
624
+ gas: gasLimit,
625
+ account: wallet,
626
+ chain: this.walletClient.chain,
627
+ maxFeePerGas: gasPriceParameters.maxFeePerGas,
628
+ maxPriorityFeePerGas: gasPriceParameters.maxPriorityFeePerGas,
629
+ nonce: nonce
630
+ },
631
+ executor: wallet,
632
+ userOperationInfos,
633
+ lastReplaced: Date.now(),
634
+ firstSubmitted: Date.now(),
635
+ timesPotentiallyIncluded: 0
636
+ };
637
+ const userOperationResults = simulatedOpsToResults(simulatedOps, transactionInfo);
638
+ childLogger.info({
639
+ txHash,
640
+ opHashes: opsToBundle.map((owh) => owh.userOperationHash)
641
+ }, "submitted bundle transaction");
642
+ return userOperationResults;
643
+ }
644
+ }
645
+ //# sourceMappingURL=executor.js.map