@@ -20,13 +20,14 @@ import (
20
20
// Client controls the end to end process of adding incoming UserOperations to the mempool. It also
21
21
// implements the required RPC methods as specified in EIP-4337.
22
22
type Client struct {
23
- mempool * mempool.Mempool
24
- chainID * big.Int
25
- supportedEntryPoints []common.Address
26
- maxVerificationGas * big.Int
27
- userOpHandler modules.UserOpHandlerFunc
28
- logger logr.Logger
29
- getUserOpReceipt GetUserOpReceiptFunc
23
+ mempool * mempool.Mempool
24
+ chainID * big.Int
25
+ supportedEntryPoints []common.Address
26
+ userOpHandler modules.UserOpHandlerFunc
27
+ logger logr.Logger
28
+ getUserOpReceipt GetUserOpReceiptFunc
29
+ getSimulateValidation GetSimulateValidationFunc
30
+ getCallGasEstimate GetCallGasEstimateFunc
30
31
}
31
32
32
33
// New initializes a new ERC-4337 client which can be extended with modules for validating UserOperations
@@ -35,16 +36,16 @@ func New(
35
36
mempool * mempool.Mempool ,
36
37
chainID * big.Int ,
37
38
supportedEntryPoints []common.Address ,
38
- maxVerificationGas * big.Int ,
39
39
) * Client {
40
40
return & Client {
41
- mempool : mempool ,
42
- chainID : chainID ,
43
- supportedEntryPoints : supportedEntryPoints ,
44
- maxVerificationGas : maxVerificationGas ,
45
- userOpHandler : noop .UserOpHandler ,
46
- logger : logger .NewZeroLogr ().WithName ("client" ),
47
- getUserOpReceipt : getUserOpReceiptNoop (),
41
+ mempool : mempool ,
42
+ chainID : chainID ,
43
+ supportedEntryPoints : supportedEntryPoints ,
44
+ userOpHandler : noop .UserOpHandler ,
45
+ logger : logger .NewZeroLogr ().WithName ("client" ),
46
+ getUserOpReceipt : getUserOpReceiptNoop (),
47
+ getSimulateValidation : getSimulateValidationNoop (),
48
+ getCallGasEstimate : getCallGasEstimateNoop (),
48
49
}
49
50
}
50
51
@@ -74,6 +75,18 @@ func (i *Client) SetGetUserOpReceiptFunc(fn GetUserOpReceiptFunc) {
74
75
i .getUserOpReceipt = fn
75
76
}
76
77
78
+ // SetGetSimulateValidationFunc defines a general function for fetching simulateValidation results given a
79
+ // userOp and EntryPoint address. This function is called in *Client.EstimateUserOperationGas.
80
+ func (i * Client ) SetGetSimulateValidationFunc (fn GetSimulateValidationFunc ) {
81
+ i .getSimulateValidation = fn
82
+ }
83
+
84
+ // SetGetCallGasEstimateFunc defines a general function for fetching an estimate for callGasLimit given a
85
+ // userOp and EntryPoint address. This function is called in *Client.EstimateUserOperationGas.
86
+ func (i * Client ) SetGetCallGasEstimateFunc (fn GetCallGasEstimateFunc ) {
87
+ i .getCallGasEstimate = fn
88
+ }
89
+
77
90
// SendUserOperation implements the method call for eth_sendUserOperation.
78
91
// It returns true if userOp was accepted otherwise returns an error.
79
92
func (i * Client ) SendUserOperation (op map [string ]any , ep string ) (string , error ) {
@@ -148,12 +161,23 @@ func (i *Client) EstimateUserOperationGas(op map[string]any, ep string) (*gas.Ga
148
161
hash := userOp .GetUserOpHash (epAddr , i .chainID )
149
162
l = l .WithValues ("userop_hash" , hash )
150
163
164
+ sim , err := i .getSimulateValidation (epAddr , userOp )
165
+ if err != nil {
166
+ l .Error (err , "eth_estimateUserOperationGas error" )
167
+ return nil , err
168
+ }
169
+
170
+ cg , err := i .getCallGasEstimate (epAddr , userOp )
171
+ if err != nil {
172
+ l .Error (err , "eth_estimateUserOperationGas error" )
173
+ return nil , err
174
+ }
175
+
151
176
l .Info ("eth_estimateUserOperationGas ok" )
152
- // TODO: Return more reliable values
153
177
return & gas.GasEstimates {
154
178
PreVerificationGas : gas .NewDefaultOverhead ().CalcPreVerificationGas (userOp ),
155
- VerificationGas : i . maxVerificationGas ,
156
- CallGasLimit : gas . NewDefaultOverhead (). NonZeroValueCall ( ),
179
+ VerificationGas : sim . ReturnInfo . PreOpGas ,
180
+ CallGasLimit : big . NewInt ( int64 ( cg ) ),
157
181
}, nil
158
182
}
159
183
0 commit comments