@pimlico/alto 0.0.0-staging.20240606T115633 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/lib/executor/executor.js +6 -0
- package/lib/executor/executor.js.map +1 -1
- package/lib/executor/executorManager.js +1 -0
- package/lib/executor/executorManager.js.map +1 -1
- package/lib/executor/utils.js +3 -1
- package/lib/executor/utils.js.map +1 -1
- package/lib/types/mempool.d.ts +2 -1
- package/package.json +10 -11
- package/esm/cli/alto.d.ts +0 -6
- package/esm/cli/alto.js +0 -92
- package/esm/cli/alto.js.map +0 -1
- package/esm/cli/config/bundler.d.ts +0 -391
- package/esm/cli/config/bundler.js +0 -132
- package/esm/cli/config/bundler.js.map +0 -1
- package/esm/cli/config/index.d.ts +0 -3
- package/esm/cli/config/index.js +0 -3
- package/esm/cli/config/index.js.map +0 -1
- package/esm/cli/config/options.d.ts +0 -11
- package/esm/cli/config/options.js +0 -336
- package/esm/cli/config/options.js.map +0 -1
- package/esm/cli/customTransport.d.ts +0 -14
- package/esm/cli/customTransport.js +0 -53
- package/esm/cli/customTransport.js.map +0 -1
- package/esm/cli/handler.d.ts +0 -3
- package/esm/cli/handler.js +0 -116
- package/esm/cli/handler.js.map +0 -1
- package/esm/cli/index.d.ts +0 -4
- package/esm/cli/index.js +0 -4
- package/esm/cli/index.js.map +0 -1
- package/esm/cli/instrumentation.d.ts +0 -2
- package/esm/cli/instrumentation.js +0 -39
- package/esm/cli/instrumentation.js.map +0 -1
- package/esm/cli/setupServer.d.ts +0 -17
- package/esm/cli/setupServer.js +0 -155
- package/esm/cli/setupServer.js.map +0 -1
- package/esm/cli/util.d.ts +0 -22
- package/esm/cli/util.js +0 -30
- package/esm/cli/util.js.map +0 -1
- package/esm/executor/executor.d.ts +0 -54
- package/esm/executor/executor.js +0 -637
- package/esm/executor/executor.js.map +0 -1
- package/esm/executor/executorManager.d.ts +0 -34
- package/esm/executor/executorManager.js +0 -401
- package/esm/executor/executorManager.js.map +0 -1
- package/esm/executor/index.d.ts +0 -5
- package/esm/executor/index.js +0 -5
- package/esm/executor/index.js.map +0 -1
- package/esm/executor/senderManager.d.ts +0 -17
- package/esm/executor/senderManager.js +0 -160
- package/esm/executor/senderManager.js.map +0 -1
- package/esm/executor/test/utils.d.ts +0 -13
- package/esm/executor/test/utils.js +0 -75
- package/esm/executor/test/utils.js.map +0 -1
- package/esm/executor/utils.d.ts +0 -32
- package/esm/executor/utils.js +0 -239
- package/esm/executor/utils.js.map +0 -1
- package/esm/index.d.ts +0 -2
- package/esm/index.js +0 -2
- package/esm/index.js.map +0 -1
- package/esm/mempool/index.d.ts +0 -5
- package/esm/mempool/index.js +0 -5
- package/esm/mempool/index.js.map +0 -1
- package/esm/mempool/mempool.d.ts +0 -64
- package/esm/mempool/mempool.js +0 -489
- package/esm/mempool/mempool.js.map +0 -1
- package/esm/mempool/monitoring.d.ts +0 -10
- package/esm/mempool/monitoring.js +0 -34
- package/esm/mempool/monitoring.js.map +0 -1
- package/esm/mempool/nullMempool.d.ts +0 -15
- package/esm/mempool/nullMempool.js +0 -36
- package/esm/mempool/nullMempool.js.map +0 -1
- package/esm/mempool/reputationManager.d.ts +0 -115
- package/esm/mempool/reputationManager.js +0 -397
- package/esm/mempool/reputationManager.js.map +0 -1
- package/esm/mempool/store.d.ts +0 -22
- package/esm/mempool/store.js +0 -123
- package/esm/mempool/store.js.map +0 -1
- package/esm/rpc/EntryPointSimulationsV07.d.ts +0 -58
- package/esm/rpc/EntryPointSimulationsV07.js +0 -407
- package/esm/rpc/EntryPointSimulationsV07.js.map +0 -1
- package/esm/rpc/ExecuteSimulator.d.ts +0 -37
- package/esm/rpc/ExecuteSimulator.js +0 -48
- package/esm/rpc/ExecuteSimulator.js.map +0 -1
- package/esm/rpc/gasEstimation.d.ts +0 -17
- package/esm/rpc/gasEstimation.js +0 -410
- package/esm/rpc/gasEstimation.js.map +0 -1
- package/esm/rpc/index.d.ts +0 -5
- package/esm/rpc/index.js +0 -5
- package/esm/rpc/index.js.map +0 -1
- package/esm/rpc/nonceQueuer.d.ts +0 -25
- package/esm/rpc/nonceQueuer.js +0 -135
- package/esm/rpc/nonceQueuer.js.map +0 -1
- package/esm/rpc/rpcHandler.d.ts +0 -64
- package/esm/rpc/rpcHandler.js +0 -727
- package/esm/rpc/rpcHandler.js.map +0 -1
- package/esm/rpc/server.d.ts +0 -31
- package/esm/rpc/server.js +0 -239
- package/esm/rpc/server.js.map +0 -1
- package/esm/rpc/validation/BundlerCollectorTracerV06.d.ts +0 -102
- package/esm/rpc/validation/BundlerCollectorTracerV06.js +0 -255
- package/esm/rpc/validation/BundlerCollectorTracerV06.js.map +0 -1
- package/esm/rpc/validation/BundlerCollectorTracerV07.d.ts +0 -102
- package/esm/rpc/validation/BundlerCollectorTracerV07.js +0 -254
- package/esm/rpc/validation/BundlerCollectorTracerV07.js.map +0 -1
- package/esm/rpc/validation/SafeValidator.d.ts +0 -35
- package/esm/rpc/validation/SafeValidator.js +0 -487
- package/esm/rpc/validation/SafeValidator.js.map +0 -1
- package/esm/rpc/validation/TracerResultParserV06.d.ts +0 -13
- package/esm/rpc/validation/TracerResultParserV06.js +0 -578
- package/esm/rpc/validation/TracerResultParserV06.js.map +0 -1
- package/esm/rpc/validation/TracerResultParserV07.d.ts +0 -33
- package/esm/rpc/validation/TracerResultParserV07.js +0 -557
- package/esm/rpc/validation/TracerResultParserV07.js.map +0 -1
- package/esm/rpc/validation/UnsafeValidator.d.ts +0 -63
- package/esm/rpc/validation/UnsafeValidator.js +0 -257
- package/esm/rpc/validation/UnsafeValidator.js.map +0 -1
- package/esm/rpc/validation/index.d.ts +0 -3
- package/esm/rpc/validation/index.js +0 -3
- package/esm/rpc/validation/index.js.map +0 -1
- package/esm/rpc/validation/tracer.d.ts +0 -122
- package/esm/rpc/validation/tracer.js +0 -82
- package/esm/rpc/validation/tracer.js.map +0 -1
- package/esm/types/contracts/BundleBulker.d.ts +0 -120
- package/esm/types/contracts/BundleBulker.js +0 -157
- package/esm/types/contracts/BundleBulker.js.map +0 -1
- package/esm/types/contracts/CallEngine.d.ts +0 -28
- package/esm/types/contracts/CallEngine.js +0 -37
- package/esm/types/contracts/CallEngine.js.map +0 -1
- package/esm/types/contracts/CodeHashGetter.d.ts +0 -37
- package/esm/types/contracts/CodeHashGetter.js +0 -45
- package/esm/types/contracts/CodeHashGetter.js.map +0 -1
- package/esm/types/contracts/EntryPoint.d.ts +0 -1789
- package/esm/types/contracts/EntryPoint.js +0 -2304
- package/esm/types/contracts/EntryPoint.js.map +0 -1
- package/esm/types/contracts/EntryPointSimulations.d.ts +0 -153
- package/esm/types/contracts/EntryPointSimulations.js +0 -15
- package/esm/types/contracts/EntryPointSimulations.js.map +0 -1
- package/esm/types/contracts/IOpInflator.d.ts +0 -61
- package/esm/types/contracts/IOpInflator.js +0 -80
- package/esm/types/contracts/IOpInflator.js.map +0 -1
- package/esm/types/contracts/IPaymaster.d.ts +0 -3
- package/esm/types/contracts/IPaymaster.js +0 -117
- package/esm/types/contracts/IPaymaster.js.map +0 -1
- package/esm/types/contracts/Inflator.d.ts +0 -65
- package/esm/types/contracts/Inflator.js +0 -84
- package/esm/types/contracts/Inflator.js.map +0 -1
- package/esm/types/contracts/PerOpInflator.d.ts +0 -176
- package/esm/types/contracts/PerOpInflator.js +0 -229
- package/esm/types/contracts/PerOpInflator.js.map +0 -1
- package/esm/types/contracts/PimlicoEntryPointSimulations.d.ts +0 -23
- package/esm/types/contracts/PimlicoEntryPointSimulations.js +0 -33
- package/esm/types/contracts/PimlicoEntryPointSimulations.js.map +0 -1
- package/esm/types/contracts/SenderCreator.d.ts +0 -4
- package/esm/types/contracts/SenderCreator.js +0 -23
- package/esm/types/contracts/SenderCreator.js.map +0 -1
- package/esm/types/contracts/SimpleAccountFactory.d.ts +0 -57
- package/esm/types/contracts/SimpleAccountFactory.js +0 -76
- package/esm/types/contracts/SimpleAccountFactory.js.map +0 -1
- package/esm/types/contracts/TestOpcodesAccount.d.ts +0 -4
- package/esm/types/contracts/TestOpcodesAccount.js +0 -281
- package/esm/types/contracts/TestOpcodesAccount.js.map +0 -1
- package/esm/types/contracts/TestOpcodesAccountFactory.d.ts +0 -4
- package/esm/types/contracts/TestOpcodesAccountFactory.js +0 -23
- package/esm/types/contracts/TestOpcodesAccountFactory.js.map +0 -1
- package/esm/types/contracts/TestStorageAccount.d.ts +0 -4
- package/esm/types/contracts/TestStorageAccount.js +0 -313
- package/esm/types/contracts/TestStorageAccount.js.map +0 -1
- package/esm/types/contracts/index.d.ts +0 -17
- package/esm/types/contracts/index.js +0 -17
- package/esm/types/contracts/index.js.map +0 -1
- package/esm/types/gasPrice.d.ts +0 -110
- package/esm/types/gasPrice.js +0 -52
- package/esm/types/gasPrice.js.map +0 -1
- package/esm/types/index.d.ts +0 -11
- package/esm/types/index.js +0 -11
- package/esm/types/index.js.map +0 -1
- package/esm/types/interfaces.d.ts +0 -26
- package/esm/types/interfaces.js +0 -2
- package/esm/types/interfaces.js.map +0 -1
- package/esm/types/mempool.d.ts +0 -78
- package/esm/types/mempool.js +0 -16
- package/esm/types/mempool.js.map +0 -1
- package/esm/types/schemas.d.ts +0 -4791
- package/esm/types/schemas.js +0 -497
- package/esm/types/schemas.js.map +0 -1
- package/esm/types/test/validationTestErrors.d.ts +0 -3
- package/esm/types/test/validationTestErrors.js +0 -229
- package/esm/types/test/validationTestErrors.js.map +0 -1
- package/esm/types/utils.d.ts +0 -24
- package/esm/types/utils.js +0 -30
- package/esm/types/utils.js.map +0 -1
- package/esm/types/validation.d.ts +0 -14327
- package/esm/types/validation.js +0 -304
- package/esm/types/validation.js.map +0 -1
- package/esm/utils/bigInt.d.ts +0 -3
- package/esm/utils/bigInt.js +0 -9
- package/esm/utils/bigInt.js.map +0 -1
- package/esm/utils/compressionHandler.d.ts +0 -11
- package/esm/utils/compressionHandler.js +0 -39
- package/esm/utils/compressionHandler.js.map +0 -1
- package/esm/utils/gasPriceManager.d.ts +0 -34
- package/esm/utils/gasPriceManager.js +0 -338
- package/esm/utils/gasPriceManager.js.map +0 -1
- package/esm/utils/helpers.d.ts +0 -4
- package/esm/utils/helpers.js +0 -13
- package/esm/utils/helpers.js.map +0 -1
- package/esm/utils/index.d.ts +0 -11
- package/esm/utils/index.js +0 -10
- package/esm/utils/index.js.map +0 -1
- package/esm/utils/logger.d.ts +0 -6
- package/esm/utils/logger.js +0 -76
- package/esm/utils/logger.js.map +0 -1
- package/esm/utils/metrics.d.ts +0 -22
- package/esm/utils/metrics.js +0 -150
- package/esm/utils/metrics.js.map +0 -1
- package/esm/utils/rpc-reply.d.ts +0 -17
- package/esm/utils/rpc-reply.js +0 -41
- package/esm/utils/rpc-reply.js.map +0 -1
- package/esm/utils/test.d.ts +0 -17
- package/esm/utils/test.js +0 -130
- package/esm/utils/test.js.map +0 -1
- package/esm/utils/userop.d.ts +0 -49
- package/esm/utils/userop.js +0 -408
- package/esm/utils/userop.js.map +0 -1
- package/esm/utils/validation.d.ts +0 -65
- package/esm/utils/validation.js +0 -461
- package/esm/utils/validation.js.map +0 -1
package/esm/rpc/rpcHandler.js
DELETED
|
@@ -1,727 +0,0 @@
|
|
|
1
|
-
import { EntryPointV06Abi, EntryPointV07Abi, IOpInflatorAbi, RpcError, ValidationErrors, bundlerGetStakeStatusResponseSchema, deriveUserOperation, logSchema, receiptSchema } from "../types/index.js";
|
|
2
|
-
import { calcPreVerificationGas, calcVerificationGasAndCallGasLimit, getNonceKeyAndValue, getUserOperationHash, isVersion06, isVersion07, maxBigInt, toUnpackedUserOperation } from "../utils/index.js";
|
|
3
|
-
import { TransactionNotFoundError, TransactionReceiptNotFoundError, decodeFunctionData, getAbiItem, getAddress, getContract, encodeEventTopics, zeroAddress, decodeEventLog, parseAbi } from "viem";
|
|
4
|
-
import * as chains from "viem/chains";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { fromZodError } from "zod-validation-error";
|
|
7
|
-
export class RpcHandler {
|
|
8
|
-
entryPoints;
|
|
9
|
-
publicClient;
|
|
10
|
-
validator;
|
|
11
|
-
mempool;
|
|
12
|
-
executor;
|
|
13
|
-
monitor;
|
|
14
|
-
nonceQueuer;
|
|
15
|
-
usingTenderly;
|
|
16
|
-
rpcMaxBlockRange;
|
|
17
|
-
logger;
|
|
18
|
-
metrics;
|
|
19
|
-
chainId;
|
|
20
|
-
chainType;
|
|
21
|
-
enableDebugEndpoints;
|
|
22
|
-
executorManager;
|
|
23
|
-
reputationManager;
|
|
24
|
-
compressionHandler;
|
|
25
|
-
legacyTransactions;
|
|
26
|
-
dangerousSkipUserOperationValidation;
|
|
27
|
-
gasPriceManager;
|
|
28
|
-
gasPriceMultipliers;
|
|
29
|
-
paymasterGasLimitMultiplier;
|
|
30
|
-
constructor(entryPoints, publicClient, validator, mempool, executor, monitor, nonceQueuer, executorManager, reputationManager, usingTenderly, rpcMaxBlockRange, logger, metrics, enableDebugEndpoints, compressionHandler, legacyTransactions, gasPriceManager, gasPriceMultipliers, chainType, paymasterGasLimitMultiplier, dangerousSkipUserOperationValidation = false) {
|
|
31
|
-
this.entryPoints = entryPoints;
|
|
32
|
-
this.publicClient = publicClient;
|
|
33
|
-
this.validator = validator;
|
|
34
|
-
this.mempool = mempool;
|
|
35
|
-
this.executor = executor;
|
|
36
|
-
this.monitor = monitor;
|
|
37
|
-
this.nonceQueuer = nonceQueuer;
|
|
38
|
-
this.usingTenderly = usingTenderly;
|
|
39
|
-
this.rpcMaxBlockRange = rpcMaxBlockRange;
|
|
40
|
-
this.logger = logger;
|
|
41
|
-
this.metrics = metrics;
|
|
42
|
-
this.enableDebugEndpoints = enableDebugEndpoints;
|
|
43
|
-
this.chainId = publicClient.chain.id;
|
|
44
|
-
this.executorManager = executorManager;
|
|
45
|
-
this.reputationManager = reputationManager;
|
|
46
|
-
this.compressionHandler = compressionHandler;
|
|
47
|
-
this.legacyTransactions = legacyTransactions;
|
|
48
|
-
this.dangerousSkipUserOperationValidation =
|
|
49
|
-
dangerousSkipUserOperationValidation;
|
|
50
|
-
this.gasPriceMultipliers = gasPriceMultipliers;
|
|
51
|
-
this.chainType = chainType;
|
|
52
|
-
this.gasPriceManager = gasPriceManager;
|
|
53
|
-
this.paymasterGasLimitMultiplier = paymasterGasLimitMultiplier;
|
|
54
|
-
}
|
|
55
|
-
async handleMethod(request, apiVersion) {
|
|
56
|
-
// call the method with the params
|
|
57
|
-
const method = request.method;
|
|
58
|
-
switch (method) {
|
|
59
|
-
case "eth_chainId":
|
|
60
|
-
return {
|
|
61
|
-
method,
|
|
62
|
-
result: this.eth_chainId(...request.params)
|
|
63
|
-
};
|
|
64
|
-
case "eth_supportedEntryPoints":
|
|
65
|
-
return {
|
|
66
|
-
method,
|
|
67
|
-
result: this.eth_supportedEntryPoints(...request.params)
|
|
68
|
-
};
|
|
69
|
-
case "eth_estimateUserOperationGas":
|
|
70
|
-
return {
|
|
71
|
-
method,
|
|
72
|
-
result: await this.eth_estimateUserOperationGas(apiVersion, request.params[0], request.params[1], request.params[2])
|
|
73
|
-
};
|
|
74
|
-
case "eth_sendUserOperation":
|
|
75
|
-
return {
|
|
76
|
-
method,
|
|
77
|
-
result: await this.eth_sendUserOperation(apiVersion, ...request.params)
|
|
78
|
-
};
|
|
79
|
-
case "eth_getUserOperationByHash":
|
|
80
|
-
return {
|
|
81
|
-
method,
|
|
82
|
-
result: await this.eth_getUserOperationByHash(...request.params)
|
|
83
|
-
};
|
|
84
|
-
case "eth_getUserOperationReceipt":
|
|
85
|
-
return {
|
|
86
|
-
method,
|
|
87
|
-
result: await this.eth_getUserOperationReceipt(...request.params)
|
|
88
|
-
};
|
|
89
|
-
case "debug_bundler_clearMempool":
|
|
90
|
-
return {
|
|
91
|
-
method,
|
|
92
|
-
result: this.debug_bundler_clearMempool(...request.params)
|
|
93
|
-
};
|
|
94
|
-
case "debug_bundler_clearState":
|
|
95
|
-
return {
|
|
96
|
-
method,
|
|
97
|
-
result: this.debug_bundler_clearState(...request.params)
|
|
98
|
-
};
|
|
99
|
-
case "debug_bundler_dumpMempool":
|
|
100
|
-
return {
|
|
101
|
-
method,
|
|
102
|
-
result: await this.debug_bundler_dumpMempool(...request.params)
|
|
103
|
-
};
|
|
104
|
-
case "debug_bundler_sendBundleNow":
|
|
105
|
-
return {
|
|
106
|
-
method,
|
|
107
|
-
result: await this.debug_bundler_sendBundleNow(...request.params)
|
|
108
|
-
};
|
|
109
|
-
case "debug_bundler_setBundlingMode":
|
|
110
|
-
return {
|
|
111
|
-
method,
|
|
112
|
-
result: this.debug_bundler_setBundlingMode(...request.params)
|
|
113
|
-
};
|
|
114
|
-
case "debug_bundler_setReputation":
|
|
115
|
-
return {
|
|
116
|
-
method,
|
|
117
|
-
result: this.debug_bundler_setReputation(request.params)
|
|
118
|
-
};
|
|
119
|
-
case "debug_bundler_dumpReputation":
|
|
120
|
-
return {
|
|
121
|
-
method,
|
|
122
|
-
result: this.debug_bundler_dumpReputation(...request.params)
|
|
123
|
-
};
|
|
124
|
-
case "debug_bundler_getStakeStatus":
|
|
125
|
-
return {
|
|
126
|
-
method,
|
|
127
|
-
result: await this.debug_bundler_getStakeStatus(...request.params)
|
|
128
|
-
};
|
|
129
|
-
case "pimlico_getUserOperationStatus":
|
|
130
|
-
return {
|
|
131
|
-
method,
|
|
132
|
-
result: this.pimlico_getUserOperationStatus(...request.params)
|
|
133
|
-
};
|
|
134
|
-
case "pimlico_getUserOperationGasPrice":
|
|
135
|
-
return {
|
|
136
|
-
method,
|
|
137
|
-
result: await this.pimlico_getUserOperationGasPrice(...request.params)
|
|
138
|
-
};
|
|
139
|
-
case "pimlico_sendCompressedUserOperation":
|
|
140
|
-
return {
|
|
141
|
-
method,
|
|
142
|
-
result: await this.pimlico_sendCompressedUserOperation(apiVersion, ...request.params)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
eth_chainId() {
|
|
147
|
-
return BigInt(this.chainId);
|
|
148
|
-
}
|
|
149
|
-
eth_supportedEntryPoints() {
|
|
150
|
-
return this.entryPoints;
|
|
151
|
-
}
|
|
152
|
-
async eth_estimateUserOperationGas(apiVersion, userOperation, entryPoint, stateOverrides) {
|
|
153
|
-
// check if entryPoint is supported, if not throw
|
|
154
|
-
if (!this.entryPoints.includes(entryPoint)) {
|
|
155
|
-
throw new Error(`EntryPoint ${entryPoint} not supported, supported EntryPoints: ${this.entryPoints.join(", ")}`);
|
|
156
|
-
}
|
|
157
|
-
if (userOperation.maxFeePerGas === 0n) {
|
|
158
|
-
throw new RpcError("user operation max fee per gas must be larger than 0 during gas estimation");
|
|
159
|
-
}
|
|
160
|
-
const preVerificationGas = ((await calcPreVerificationGas(this.publicClient, userOperation, entryPoint, this.chainId, this.chainType, this.gasPriceManager, false)) *
|
|
161
|
-
110n) /
|
|
162
|
-
100n;
|
|
163
|
-
userOperation.preVerificationGas = 1000000n;
|
|
164
|
-
userOperation.verificationGasLimit = 10000000n;
|
|
165
|
-
userOperation.callGasLimit = 10000000n;
|
|
166
|
-
if (this.chainId === chains.base.id) {
|
|
167
|
-
userOperation.verificationGasLimit = 5000000n;
|
|
168
|
-
}
|
|
169
|
-
if (this.chainId === chains.celoAlfajores.id ||
|
|
170
|
-
this.chainId === chains.celo.id) {
|
|
171
|
-
userOperation.verificationGasLimit = 1000000n;
|
|
172
|
-
userOperation.callGasLimit = 1000000n;
|
|
173
|
-
}
|
|
174
|
-
if (isVersion07(userOperation)) {
|
|
175
|
-
userOperation.paymasterPostOpGasLimit = 2000000n;
|
|
176
|
-
userOperation.paymasterVerificationGasLimit = 5000000n;
|
|
177
|
-
}
|
|
178
|
-
// This is necessary because entryPoint pays
|
|
179
|
-
// min(maxFeePerGas, baseFee + maxPriorityFeePerGas) for the verification
|
|
180
|
-
// Since we don't want our estimations to depend upon baseFee, we set
|
|
181
|
-
// maxFeePerGas to maxPriorityFeePerGas
|
|
182
|
-
userOperation.maxPriorityFeePerGas = userOperation.maxFeePerGas;
|
|
183
|
-
// Check if the nonce is valid
|
|
184
|
-
// If the nonce is less than the current nonce, the user operation has already been executed
|
|
185
|
-
// If the nonce is greater than the current nonce, we may have missing user operations in the mempool
|
|
186
|
-
const currentNonceValue = await this.getNonceValue(userOperation, entryPoint);
|
|
187
|
-
const [, userOperationNonceValue] = getNonceKeyAndValue(userOperation.nonce);
|
|
188
|
-
let queuedUserOperations = [];
|
|
189
|
-
if (userOperationNonceValue < currentNonceValue) {
|
|
190
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
191
|
-
}
|
|
192
|
-
if (userOperationNonceValue > currentNonceValue) {
|
|
193
|
-
// Nonce queues are supported only for v7 user operations
|
|
194
|
-
if (isVersion06(userOperation)) {
|
|
195
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
196
|
-
}
|
|
197
|
-
queuedUserOperations = await this.mempool.getQueuedUserOperations(userOperation, entryPoint, currentNonceValue);
|
|
198
|
-
if (userOperationNonceValue >
|
|
199
|
-
currentNonceValue + BigInt(queuedUserOperations.length)) {
|
|
200
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const executionResult = await this.validator.getExecutionResult(userOperation, entryPoint, queuedUserOperations, stateOverrides);
|
|
204
|
-
let { verificationGasLimit, callGasLimit } = calcVerificationGasAndCallGasLimit(userOperation, executionResult.data.executionResult, this.chainId, executionResult.data.callDataResult);
|
|
205
|
-
let paymasterVerificationGasLimit = 0n;
|
|
206
|
-
let paymasterPostOpGasLimit = 0n;
|
|
207
|
-
if (isVersion07(userOperation) &&
|
|
208
|
-
userOperation.paymaster !== null &&
|
|
209
|
-
"paymasterVerificationGasLimit" in
|
|
210
|
-
executionResult.data.executionResult &&
|
|
211
|
-
"paymasterPostOpGasLimit" in executionResult.data.executionResult) {
|
|
212
|
-
paymasterVerificationGasLimit =
|
|
213
|
-
executionResult.data.executionResult
|
|
214
|
-
.paymasterVerificationGasLimit || 1n;
|
|
215
|
-
paymasterPostOpGasLimit =
|
|
216
|
-
executionResult.data.executionResult.paymasterPostOpGasLimit ||
|
|
217
|
-
1n;
|
|
218
|
-
const multiplier = this.paymasterGasLimitMultiplier;
|
|
219
|
-
paymasterVerificationGasLimit =
|
|
220
|
-
(paymasterVerificationGasLimit * multiplier) / 100n;
|
|
221
|
-
paymasterPostOpGasLimit =
|
|
222
|
-
(paymasterPostOpGasLimit * multiplier) / 100n;
|
|
223
|
-
}
|
|
224
|
-
if (this.chainId === chains.base.id ||
|
|
225
|
-
this.chainId === chains.baseSepolia.id) {
|
|
226
|
-
callGasLimit += 10000n;
|
|
227
|
-
}
|
|
228
|
-
if (this.chainId === chains.base.id ||
|
|
229
|
-
this.chainId === chains.optimism.id) {
|
|
230
|
-
callGasLimit = maxBigInt(callGasLimit, 120000n);
|
|
231
|
-
}
|
|
232
|
-
if (userOperation.callData === "0x") {
|
|
233
|
-
callGasLimit = 0n;
|
|
234
|
-
}
|
|
235
|
-
if (isVersion07(userOperation)) {
|
|
236
|
-
return {
|
|
237
|
-
preVerificationGas,
|
|
238
|
-
verificationGasLimit,
|
|
239
|
-
callGasLimit,
|
|
240
|
-
paymasterVerificationGasLimit,
|
|
241
|
-
paymasterPostOpGasLimit
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
if (apiVersion === "v2") {
|
|
245
|
-
return {
|
|
246
|
-
preVerificationGas,
|
|
247
|
-
verificationGasLimit,
|
|
248
|
-
callGasLimit
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
preVerificationGas,
|
|
253
|
-
verificationGas: verificationGasLimit,
|
|
254
|
-
verificationGasLimit,
|
|
255
|
-
callGasLimit
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
async eth_sendUserOperation(apiVersion, userOperation, entryPoint) {
|
|
259
|
-
let status = "rejected";
|
|
260
|
-
try {
|
|
261
|
-
status = await this.addToMempoolIfValid(userOperation, entryPoint, apiVersion);
|
|
262
|
-
const hash = getUserOperationHash(userOperation, entryPoint, this.chainId);
|
|
263
|
-
return hash;
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
status = "rejected";
|
|
267
|
-
throw error;
|
|
268
|
-
}
|
|
269
|
-
finally {
|
|
270
|
-
this.metrics.userOperationsReceived
|
|
271
|
-
.labels({
|
|
272
|
-
status,
|
|
273
|
-
type: "regular"
|
|
274
|
-
})
|
|
275
|
-
.inc();
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
async eth_getUserOperationByHash(userOperationHash) {
|
|
279
|
-
const userOperationEventAbiItem = getAbiItem({
|
|
280
|
-
abi: EntryPointV06Abi,
|
|
281
|
-
name: "UserOperationEvent"
|
|
282
|
-
});
|
|
283
|
-
let fromBlock = undefined;
|
|
284
|
-
let toBlock = undefined;
|
|
285
|
-
if (this.rpcMaxBlockRange !== undefined) {
|
|
286
|
-
const latestBlock = await this.publicClient.getBlockNumber();
|
|
287
|
-
fromBlock = latestBlock - BigInt(this.rpcMaxBlockRange);
|
|
288
|
-
if (fromBlock < 0n) {
|
|
289
|
-
fromBlock = 0n;
|
|
290
|
-
}
|
|
291
|
-
toBlock = "latest";
|
|
292
|
-
}
|
|
293
|
-
const filterResult = await this.publicClient.getLogs({
|
|
294
|
-
address: this.entryPoints,
|
|
295
|
-
event: userOperationEventAbiItem,
|
|
296
|
-
fromBlock,
|
|
297
|
-
toBlock,
|
|
298
|
-
args: {
|
|
299
|
-
userOpHash: userOperationHash
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
if (filterResult.length === 0) {
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
const userOperationEvent = filterResult[0];
|
|
306
|
-
const txHash = userOperationEvent.transactionHash;
|
|
307
|
-
if (txHash === null) {
|
|
308
|
-
// transaction pending
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
const getTransaction = async (txHash) => {
|
|
312
|
-
try {
|
|
313
|
-
return await this.publicClient.getTransaction({ hash: txHash });
|
|
314
|
-
}
|
|
315
|
-
catch (e) {
|
|
316
|
-
if (e instanceof TransactionNotFoundError) {
|
|
317
|
-
return getTransaction(txHash);
|
|
318
|
-
}
|
|
319
|
-
throw e;
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
const tx = await getTransaction(txHash);
|
|
323
|
-
if (!tx.to) {
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
|
-
let op = undefined;
|
|
327
|
-
try {
|
|
328
|
-
const decoded = decodeFunctionData({
|
|
329
|
-
abi: EntryPointV06Abi,
|
|
330
|
-
data: tx.input
|
|
331
|
-
});
|
|
332
|
-
if (decoded.functionName !== "handleOps") {
|
|
333
|
-
return null;
|
|
334
|
-
}
|
|
335
|
-
const ops = decoded.args[0];
|
|
336
|
-
op = ops.find((op) => op.sender === userOperationEvent.args.sender &&
|
|
337
|
-
op.nonce === userOperationEvent.args.nonce);
|
|
338
|
-
}
|
|
339
|
-
catch {
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
|
-
if (op === undefined) {
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
const result = {
|
|
346
|
-
userOperation: isVersion06(op) ? op : toUnpackedUserOperation(op),
|
|
347
|
-
entryPoint: getAddress(tx.to),
|
|
348
|
-
transactionHash: txHash,
|
|
349
|
-
blockHash: tx.blockHash ?? "0x",
|
|
350
|
-
blockNumber: BigInt(tx.blockNumber ?? 0n)
|
|
351
|
-
};
|
|
352
|
-
return result;
|
|
353
|
-
}
|
|
354
|
-
async eth_getUserOperationReceipt(userOperationHash) {
|
|
355
|
-
const userOperationEventAbiItem = getAbiItem({
|
|
356
|
-
abi: EntryPointV06Abi,
|
|
357
|
-
name: "UserOperationEvent"
|
|
358
|
-
});
|
|
359
|
-
let fromBlock = undefined;
|
|
360
|
-
let toBlock = undefined;
|
|
361
|
-
if (this.rpcMaxBlockRange !== undefined) {
|
|
362
|
-
const latestBlock = await this.publicClient.getBlockNumber();
|
|
363
|
-
fromBlock = latestBlock - BigInt(this.rpcMaxBlockRange);
|
|
364
|
-
if (fromBlock < 0n) {
|
|
365
|
-
fromBlock = 0n;
|
|
366
|
-
}
|
|
367
|
-
toBlock = "latest";
|
|
368
|
-
}
|
|
369
|
-
const filterResult = await this.publicClient.getLogs({
|
|
370
|
-
address: this.entryPoints,
|
|
371
|
-
event: userOperationEventAbiItem,
|
|
372
|
-
fromBlock,
|
|
373
|
-
toBlock,
|
|
374
|
-
args: {
|
|
375
|
-
userOpHash: userOperationHash
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
if (filterResult.length === 0) {
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
|
-
const userOperationEvent = filterResult[0];
|
|
382
|
-
// throw if any of the members of userOperationEvent are undefined
|
|
383
|
-
if (userOperationEvent.args.actualGasCost === undefined ||
|
|
384
|
-
userOperationEvent.args.sender === undefined ||
|
|
385
|
-
userOperationEvent.args.nonce === undefined ||
|
|
386
|
-
userOperationEvent.args.userOpHash === undefined ||
|
|
387
|
-
userOperationEvent.args.success === undefined ||
|
|
388
|
-
userOperationEvent.args.paymaster === undefined ||
|
|
389
|
-
userOperationEvent.args.actualGasUsed === undefined) {
|
|
390
|
-
throw new Error("userOperationEvent has undefined members");
|
|
391
|
-
}
|
|
392
|
-
const txHash = userOperationEvent.transactionHash;
|
|
393
|
-
if (txHash === null) {
|
|
394
|
-
// transaction pending
|
|
395
|
-
return null;
|
|
396
|
-
}
|
|
397
|
-
const getTransactionReceipt = async (txHash) => {
|
|
398
|
-
while (true) {
|
|
399
|
-
try {
|
|
400
|
-
return await this.publicClient.getTransactionReceipt({
|
|
401
|
-
hash: txHash
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
catch (e) {
|
|
405
|
-
if (e instanceof TransactionReceiptNotFoundError) {
|
|
406
|
-
continue;
|
|
407
|
-
}
|
|
408
|
-
throw e;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
const receipt = await getTransactionReceipt(txHash);
|
|
413
|
-
const logs = receipt.logs;
|
|
414
|
-
if (logs.some((log) => log.blockHash === null ||
|
|
415
|
-
log.blockNumber === null ||
|
|
416
|
-
log.transactionIndex === null ||
|
|
417
|
-
log.transactionHash === null ||
|
|
418
|
-
log.logIndex === null ||
|
|
419
|
-
log.topics.length === 0)) {
|
|
420
|
-
// transaction pending
|
|
421
|
-
return null;
|
|
422
|
-
}
|
|
423
|
-
const userOperationRevertReasonAbi = parseAbi([
|
|
424
|
-
"event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason)"
|
|
425
|
-
]);
|
|
426
|
-
const userOperationRevertReasonTopicEvent = encodeEventTopics({
|
|
427
|
-
abi: userOperationRevertReasonAbi
|
|
428
|
-
})[0];
|
|
429
|
-
let entryPoint = zeroAddress;
|
|
430
|
-
let revertReason = undefined;
|
|
431
|
-
let startIndex = -1;
|
|
432
|
-
let endIndex = -1;
|
|
433
|
-
logs.forEach((log, index) => {
|
|
434
|
-
if (log?.topics[0] === userOperationEvent.topics[0]) {
|
|
435
|
-
// process UserOperationEvent
|
|
436
|
-
if (log.topics[1] === userOperationEvent.topics[1]) {
|
|
437
|
-
// it's our userOpHash. save as end of logs array
|
|
438
|
-
endIndex = index;
|
|
439
|
-
entryPoint = log.address;
|
|
440
|
-
}
|
|
441
|
-
else if (endIndex === -1) {
|
|
442
|
-
// it's a different hash. remember it as beginning index, but only if we didn't find our end index yet.
|
|
443
|
-
startIndex = index;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
if (log?.topics[0] === userOperationRevertReasonTopicEvent) {
|
|
447
|
-
// process UserOperationRevertReason
|
|
448
|
-
if (log.topics[1] === userOperationEvent.topics[1]) {
|
|
449
|
-
// it's our userOpHash. capture revert reason.
|
|
450
|
-
const decodedLog = decodeEventLog({
|
|
451
|
-
abi: userOperationRevertReasonAbi,
|
|
452
|
-
data: log.data,
|
|
453
|
-
topics: log.topics
|
|
454
|
-
});
|
|
455
|
-
revertReason = decodedLog.args.revertReason;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
});
|
|
459
|
-
if (endIndex === -1) {
|
|
460
|
-
throw new Error("fatal: no UserOperationEvent in logs");
|
|
461
|
-
}
|
|
462
|
-
const filteredLogs = logs.slice(startIndex + 1, endIndex);
|
|
463
|
-
const logsParsing = z.array(logSchema).safeParse(filteredLogs);
|
|
464
|
-
if (!logsParsing.success) {
|
|
465
|
-
const err = fromZodError(logsParsing.error);
|
|
466
|
-
throw err;
|
|
467
|
-
}
|
|
468
|
-
const receiptParsing = receiptSchema.safeParse({
|
|
469
|
-
...receipt,
|
|
470
|
-
status: receipt.status === "success" ? 1 : 0
|
|
471
|
-
});
|
|
472
|
-
if (!receiptParsing.success) {
|
|
473
|
-
const err = fromZodError(receiptParsing.error);
|
|
474
|
-
throw err;
|
|
475
|
-
}
|
|
476
|
-
let paymaster = userOperationEvent.args.paymaster;
|
|
477
|
-
paymaster = paymaster === zeroAddress ? undefined : paymaster;
|
|
478
|
-
const userOperationReceipt = {
|
|
479
|
-
userOpHash: userOperationHash,
|
|
480
|
-
entryPoint,
|
|
481
|
-
sender: userOperationEvent.args.sender,
|
|
482
|
-
nonce: userOperationEvent.args.nonce,
|
|
483
|
-
paymaster,
|
|
484
|
-
actualGasUsed: userOperationEvent.args.actualGasUsed,
|
|
485
|
-
actualGasCost: userOperationEvent.args.actualGasCost,
|
|
486
|
-
success: userOperationEvent.args.success,
|
|
487
|
-
reason: revertReason,
|
|
488
|
-
logs: logsParsing.data,
|
|
489
|
-
receipt: receiptParsing.data
|
|
490
|
-
};
|
|
491
|
-
return userOperationReceipt;
|
|
492
|
-
}
|
|
493
|
-
debug_bundler_clearState() {
|
|
494
|
-
if (!this.enableDebugEndpoints) {
|
|
495
|
-
throw new RpcError("debug_bundler_clearState is only available in development environment");
|
|
496
|
-
}
|
|
497
|
-
this.mempool.clear();
|
|
498
|
-
this.reputationManager.clear();
|
|
499
|
-
return "ok";
|
|
500
|
-
}
|
|
501
|
-
debug_bundler_clearMempool() {
|
|
502
|
-
if (!this.enableDebugEndpoints) {
|
|
503
|
-
throw new RpcError("debug_bundler_clearMempool is only available in development environment");
|
|
504
|
-
}
|
|
505
|
-
this.mempool.clear();
|
|
506
|
-
this.reputationManager.clearEntityCount();
|
|
507
|
-
return "ok";
|
|
508
|
-
}
|
|
509
|
-
async debug_bundler_dumpMempool(entryPoint) {
|
|
510
|
-
if (!this.enableDebugEndpoints) {
|
|
511
|
-
throw new RpcError("debug_bundler_dumpMempool is only available in development environment");
|
|
512
|
-
}
|
|
513
|
-
if (!this.entryPoints.includes(entryPoint)) {
|
|
514
|
-
throw new RpcError(`EntryPoint ${entryPoint} not supported, supported EntryPoints: ${this.entryPoints.join(", ")}`);
|
|
515
|
-
}
|
|
516
|
-
return this.mempool
|
|
517
|
-
.dumpOutstanding()
|
|
518
|
-
.map((userOpInfo) => deriveUserOperation(userOpInfo.mempoolUserOperation));
|
|
519
|
-
}
|
|
520
|
-
async debug_bundler_sendBundleNow() {
|
|
521
|
-
if (!this.enableDebugEndpoints) {
|
|
522
|
-
throw new RpcError("debug_bundler_sendBundleNow is only available in development environment");
|
|
523
|
-
}
|
|
524
|
-
const transactions = await this.executorManager.bundleNow();
|
|
525
|
-
return transactions[0];
|
|
526
|
-
}
|
|
527
|
-
debug_bundler_setBundlingMode(bundlingMode) {
|
|
528
|
-
if (!this.enableDebugEndpoints) {
|
|
529
|
-
throw new RpcError("debug_bundler_setBundlingMode is only available in development environment");
|
|
530
|
-
}
|
|
531
|
-
this.executorManager.setBundlingMode(bundlingMode);
|
|
532
|
-
return "ok";
|
|
533
|
-
}
|
|
534
|
-
debug_bundler_dumpReputation(entryPoint) {
|
|
535
|
-
if (!this.enableDebugEndpoints) {
|
|
536
|
-
throw new RpcError("debug_bundler_setRe is only available in development environment");
|
|
537
|
-
}
|
|
538
|
-
if (!this.entryPoints.includes(entryPoint)) {
|
|
539
|
-
throw new RpcError(`EntryPoint ${entryPoint} not supported, supported EntryPoints: ${this.entryPoints.join(", ")}`);
|
|
540
|
-
}
|
|
541
|
-
return this.reputationManager.dumpReputations(entryPoint);
|
|
542
|
-
}
|
|
543
|
-
async debug_bundler_getStakeStatus(address, entryPoint) {
|
|
544
|
-
if (!this.enableDebugEndpoints) {
|
|
545
|
-
throw new RpcError("debug_bundler_getStakeStatus is only available in development environment");
|
|
546
|
-
}
|
|
547
|
-
if (!this.entryPoints.includes(entryPoint)) {
|
|
548
|
-
throw new RpcError(`EntryPoint ${entryPoint} not supported, supported EntryPoints: ${this.entryPoints.join(", ")}`);
|
|
549
|
-
}
|
|
550
|
-
return bundlerGetStakeStatusResponseSchema.parse({
|
|
551
|
-
method: "debug_bundler_getStakeStatus",
|
|
552
|
-
result: await this.reputationManager.getStakeStatus(entryPoint, address)
|
|
553
|
-
}).result;
|
|
554
|
-
}
|
|
555
|
-
debug_bundler_setReputation(args) {
|
|
556
|
-
if (!this.enableDebugEndpoints) {
|
|
557
|
-
throw new RpcError("debug_bundler_setReputation is only available in development environment");
|
|
558
|
-
}
|
|
559
|
-
this.reputationManager.setReputation(args[1], args[0]);
|
|
560
|
-
return "ok";
|
|
561
|
-
}
|
|
562
|
-
pimlico_getUserOperationStatus(userOperationHash) {
|
|
563
|
-
return this.monitor.getUserOperationStatus(userOperationHash);
|
|
564
|
-
}
|
|
565
|
-
async pimlico_getUserOperationGasPrice() {
|
|
566
|
-
const gasPrice = await this.gasPriceManager.getGasPrice();
|
|
567
|
-
const { slow, standard, fast } = this.gasPriceMultipliers;
|
|
568
|
-
return {
|
|
569
|
-
slow: {
|
|
570
|
-
maxFeePerGas: (gasPrice.maxFeePerGas * slow) / 100n,
|
|
571
|
-
maxPriorityFeePerGas: (gasPrice.maxPriorityFeePerGas * slow) / 100n
|
|
572
|
-
},
|
|
573
|
-
standard: {
|
|
574
|
-
maxFeePerGas: (gasPrice.maxFeePerGas * standard) / 100n,
|
|
575
|
-
maxPriorityFeePerGas: (gasPrice.maxPriorityFeePerGas * standard) / 100n
|
|
576
|
-
},
|
|
577
|
-
fast: {
|
|
578
|
-
maxFeePerGas: (gasPrice.maxFeePerGas * fast) / 100n,
|
|
579
|
-
maxPriorityFeePerGas: (gasPrice.maxPriorityFeePerGas * fast) / 100n
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
// check if we want to bundle userOperation. If yes, add to mempool
|
|
584
|
-
async addToMempoolIfValid(op, entryPoint, apiVersion) {
|
|
585
|
-
const userOperation = deriveUserOperation(op);
|
|
586
|
-
if (!this.entryPoints.includes(entryPoint)) {
|
|
587
|
-
throw new RpcError(`EntryPoint ${entryPoint} not supported, supported EntryPoints: ${this.entryPoints.join(", ")}`);
|
|
588
|
-
}
|
|
589
|
-
if (this.chainId === chains.celoAlfajores.id ||
|
|
590
|
-
this.chainId === chains.celo.id) {
|
|
591
|
-
if (userOperation.maxFeePerGas !==
|
|
592
|
-
userOperation.maxPriorityFeePerGas) {
|
|
593
|
-
throw new RpcError("maxPriorityFeePerGas must equal maxFeePerGas on Celo chains");
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
if (apiVersion !== "v1") {
|
|
597
|
-
await this.gasPriceManager.validateGasPrice({
|
|
598
|
-
maxFeePerGas: userOperation.maxFeePerGas,
|
|
599
|
-
maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
if (userOperation.verificationGasLimit < 10000n) {
|
|
603
|
-
throw new RpcError("verificationGasLimit must be at least 10000");
|
|
604
|
-
}
|
|
605
|
-
this.logger.trace({ userOperation, entryPoint }, "beginning validation");
|
|
606
|
-
if (userOperation.preVerificationGas === 0n ||
|
|
607
|
-
userOperation.verificationGasLimit === 0n) {
|
|
608
|
-
throw new RpcError("user operation gas limits must be larger than 0");
|
|
609
|
-
}
|
|
610
|
-
const currentNonceValue = await this.getNonceValue(userOperation, entryPoint);
|
|
611
|
-
const [, userOperationNonceValue] = getNonceKeyAndValue(userOperation.nonce);
|
|
612
|
-
if (userOperationNonceValue < currentNonceValue) {
|
|
613
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
614
|
-
}
|
|
615
|
-
if (userOperationNonceValue > currentNonceValue + 10n) {
|
|
616
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
617
|
-
}
|
|
618
|
-
let queuedUserOperations = [];
|
|
619
|
-
if (userOperationNonceValue > currentNonceValue &&
|
|
620
|
-
isVersion07(userOperation)) {
|
|
621
|
-
queuedUserOperations = await this.mempool.getQueuedUserOperations(userOperation, entryPoint, currentNonceValue);
|
|
622
|
-
}
|
|
623
|
-
if (userOperationNonceValue ===
|
|
624
|
-
currentNonceValue + BigInt(queuedUserOperations.length)) {
|
|
625
|
-
if (this.dangerousSkipUserOperationValidation) {
|
|
626
|
-
const success = this.mempool.add(op, entryPoint);
|
|
627
|
-
if (!success) {
|
|
628
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
if (apiVersion !== "v1") {
|
|
633
|
-
await this.validator.validatePreVerificationGas(userOperation, entryPoint);
|
|
634
|
-
}
|
|
635
|
-
const validationResult = await this.validator.validateUserOperation(apiVersion !== "v1", userOperation, queuedUserOperations, entryPoint);
|
|
636
|
-
await this.reputationManager.checkReputation(userOperation, entryPoint, validationResult);
|
|
637
|
-
await this.mempool.checkEntityMultipleRoleViolation(userOperation);
|
|
638
|
-
const success = this.mempool.add(op, entryPoint, validationResult.referencedContracts);
|
|
639
|
-
if (!success) {
|
|
640
|
-
throw new RpcError("UserOperation reverted during simulation with reason: AA25 invalid account nonce", ValidationErrors.InvalidFields);
|
|
641
|
-
}
|
|
642
|
-
return "added";
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
this.nonceQueuer.add(op, entryPoint);
|
|
646
|
-
return "queued";
|
|
647
|
-
}
|
|
648
|
-
async pimlico_sendCompressedUserOperation(apiVersion, compressedCalldata, inflatorAddress, entryPoint) {
|
|
649
|
-
let status = "rejected";
|
|
650
|
-
try {
|
|
651
|
-
const { inflatedOp, inflatorId } = await this.validateAndInflateCompressedUserOperation(inflatorAddress, compressedCalldata);
|
|
652
|
-
const compressedUserOp = {
|
|
653
|
-
compressedCalldata,
|
|
654
|
-
inflatedOp,
|
|
655
|
-
inflatorAddress,
|
|
656
|
-
inflatorId
|
|
657
|
-
};
|
|
658
|
-
// check userOps inputs.
|
|
659
|
-
status = await this.addToMempoolIfValid(compressedUserOp, entryPoint, apiVersion);
|
|
660
|
-
const hash = getUserOperationHash(inflatedOp, entryPoint, this.chainId);
|
|
661
|
-
return hash;
|
|
662
|
-
}
|
|
663
|
-
catch (error) {
|
|
664
|
-
status = "rejected";
|
|
665
|
-
throw error;
|
|
666
|
-
}
|
|
667
|
-
finally {
|
|
668
|
-
this.metrics.userOperationsReceived
|
|
669
|
-
.labels({
|
|
670
|
-
status,
|
|
671
|
-
type: "compressed"
|
|
672
|
-
})
|
|
673
|
-
.inc();
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
async validateAndInflateCompressedUserOperation(inflatorAddress, compressedCalldata) {
|
|
677
|
-
// check if inflator is registered with our PerOpInflator.
|
|
678
|
-
if (this.compressionHandler === null) {
|
|
679
|
-
throw new RpcError("Endpoint not supported");
|
|
680
|
-
}
|
|
681
|
-
const inflatorId = await this.compressionHandler.getInflatorRegisteredId(inflatorAddress, this.publicClient);
|
|
682
|
-
if (inflatorId === 0) {
|
|
683
|
-
throw new RpcError(`Inflator ${inflatorAddress} is not registered`, ValidationErrors.InvalidFields);
|
|
684
|
-
}
|
|
685
|
-
// infalte + start to validate user op.
|
|
686
|
-
const inflatorContract = getContract({
|
|
687
|
-
address: inflatorAddress,
|
|
688
|
-
abi: IOpInflatorAbi,
|
|
689
|
-
client: {
|
|
690
|
-
public: this.publicClient
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
let inflatedOp;
|
|
694
|
-
try {
|
|
695
|
-
inflatedOp = await inflatorContract.read.inflate([
|
|
696
|
-
compressedCalldata
|
|
697
|
-
]);
|
|
698
|
-
}
|
|
699
|
-
catch (e) {
|
|
700
|
-
throw new RpcError(`Inflator ${inflatorAddress} failed to inflate calldata ${compressedCalldata}, due to ${e}`, ValidationErrors.InvalidFields);
|
|
701
|
-
}
|
|
702
|
-
// check if perUseropIsRegisterd to target BundleBulker
|
|
703
|
-
const perOpInflatorId = this.compressionHandler.perOpInflatorId;
|
|
704
|
-
if (perOpInflatorId === 0) {
|
|
705
|
-
throw new RpcError(`PerUserOp ${this.compressionHandler.perOpInflatorAddress} has not been registered with BundelBulker`, ValidationErrors.InvalidFields);
|
|
706
|
-
}
|
|
707
|
-
return { inflatedOp, inflatorId };
|
|
708
|
-
}
|
|
709
|
-
async getNonceValue(userOperation, entryPoint) {
|
|
710
|
-
const entryPointContract = getContract({
|
|
711
|
-
address: entryPoint,
|
|
712
|
-
abi: isVersion06(userOperation)
|
|
713
|
-
? EntryPointV06Abi
|
|
714
|
-
: EntryPointV07Abi,
|
|
715
|
-
client: {
|
|
716
|
-
public: this.publicClient
|
|
717
|
-
}
|
|
718
|
-
});
|
|
719
|
-
const [nonceKey] = getNonceKeyAndValue(userOperation.nonce);
|
|
720
|
-
const getNonceResult = await entryPointContract.read.getNonce([userOperation.sender, nonceKey], {
|
|
721
|
-
blockTag: "latest"
|
|
722
|
-
});
|
|
723
|
-
const [_, currentNonceValue] = getNonceKeyAndValue(getNonceResult);
|
|
724
|
-
return currentNonceValue;
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
//# sourceMappingURL=rpcHandler.js.map
|