@@ -12,6 +12,10 @@ import (
12
12
)
13
13
14
14
var (
15
+ address , _ = abi .NewType ("address" , "" , nil )
16
+ uint256 , _ = abi .NewType ("uint256" , "" , nil )
17
+ bytes32 , _ = abi .NewType ("bytes32" , "" , nil )
18
+
15
19
// UserOpPrimitives is the primitive ABI types for each UserOperation field.
16
20
UserOpPrimitives = []abi.ArgumentMarshaling {
17
21
{Name : "sender" , InternalType : "Sender" , Type : "address" },
34
38
UserOpArr , _ = abi .NewType ("tuple[]" , "ops" , UserOpPrimitives )
35
39
)
36
40
37
- func getAbiArgs () abi.Arguments {
38
- return abi.Arguments {
39
- {Name : "UserOp" , Type : UserOpType },
40
- }
41
- }
42
-
43
41
// UserOperation represents an EIP-4337 style transaction for a smart contract account.
44
42
type UserOperation struct {
45
43
Sender common.Address `json:"sender" mapstructure:"sender" validate:"required"`
@@ -92,7 +90,9 @@ func (op *UserOperation) GetMaxPrefund() *big.Int {
92
90
93
91
// Pack returns a standard message of the userOp. This cannot be used to generate a userOpHash.
94
92
func (op * UserOperation ) Pack () []byte {
95
- args := getAbiArgs ()
93
+ args := abi.Arguments {
94
+ {Name : "UserOp" , Type : UserOpType },
95
+ }
96
96
packed , _ := args .Pack (& struct {
97
97
Sender common.Address
98
98
Nonce * big.Int
@@ -126,37 +126,32 @@ func (op *UserOperation) Pack() []byte {
126
126
127
127
// PackForSignature returns a minimal message of the userOp. This can be used to generate a userOpHash.
128
128
func (op * UserOperation ) PackForSignature () []byte {
129
- args := getAbiArgs ()
130
- packed , _ := args .Pack (& struct {
131
- Sender common.Address
132
- Nonce * big.Int
133
- InitCode []byte
134
- CallData []byte
135
- CallGasLimit * big.Int
136
- VerificationGasLimit * big.Int
137
- PreVerificationGas * big.Int
138
- MaxFeePerGas * big.Int
139
- MaxPriorityFeePerGas * big.Int
140
- PaymasterAndData []byte
141
- Signature []byte
142
- }{
129
+ args := abi.Arguments {
130
+ {Name : "sender" , Type : address },
131
+ {Name : "nonce" , Type : uint256 },
132
+ {Name : "hashInitCode" , Type : bytes32 },
133
+ {Name : "hashCallData" , Type : bytes32 },
134
+ {Name : "callGasLimit" , Type : uint256 },
135
+ {Name : "verificationGasLimit" , Type : uint256 },
136
+ {Name : "preVerificationGas" , Type : uint256 },
137
+ {Name : "maxFeePerGas" , Type : uint256 },
138
+ {Name : "maxPriorityFeePerGas" , Type : uint256 },
139
+ {Name : "hashPaymasterAndData" , Type : bytes32 },
140
+ }
141
+ packed , _ := args .Pack (
143
142
op .Sender ,
144
143
op .Nonce ,
145
- op .InitCode ,
146
- op .CallData ,
144
+ crypto . Keccak256Hash ( op .InitCode ) ,
145
+ crypto . Keccak256Hash ( op .CallData ) ,
147
146
op .CallGasLimit ,
148
147
op .VerificationGasLimit ,
149
148
op .PreVerificationGas ,
150
149
op .MaxFeePerGas ,
151
150
op .MaxPriorityFeePerGas ,
152
- op .PaymasterAndData ,
153
- []byte {},
154
- })
151
+ crypto .Keccak256Hash (op .PaymasterAndData ),
152
+ )
155
153
156
- // Return with stripped leading word (total length) and trailing word (zero-length signature).
157
- enc := hexutil .Encode (packed )
158
- enc = "0x" + enc [66 :len (enc )- 64 ]
159
- return (hexutil .MustDecode (enc ))
154
+ return packed
160
155
}
161
156
162
157
// GetUserOpHash returns the hash of the userOp + entryPoint address + chainID.
@@ -196,3 +191,17 @@ func (op *UserOperation) MarshalJSON() ([]byte, error) {
196
191
Signature : hexutil .Encode (op .Signature ),
197
192
})
198
193
}
194
+
195
+ // ToMap returns the current UserOp struct as a map type.
196
+ func (op * UserOperation ) ToMap () (map [string ]any , error ) {
197
+ data , err := op .MarshalJSON ()
198
+ if err != nil {
199
+ return nil , err
200
+ }
201
+
202
+ var opData map [string ]any
203
+ if err := json .Unmarshal (data , & opData ); err != nil {
204
+ return nil , err
205
+ }
206
+ return opData , nil
207
+ }
0 commit comments