1
1
use alloy:: hex;
2
+ use alloy:: json_abi:: Param ;
2
3
use alloy:: {
3
4
dyn_abi:: { DynSolType , DynSolValue , JsonAbiExt } ,
4
5
json_abi:: { Function , JsonAbi } ,
@@ -213,6 +214,54 @@ impl ContractCall {
213
214
} )
214
215
}
215
216
217
+ fn json_to_sol (
218
+ json_values : & [ JsonValue ] ,
219
+ json_abi_params : & [ Param ] ,
220
+ ) -> Result < Vec < DynSolValue > , String > {
221
+ if json_values. len ( ) != json_abi_params. len ( ) {
222
+ return Err ( format ! (
223
+ "Parameter count mismatch: expected {}, got {}" ,
224
+ json_abi_params. len( ) ,
225
+ json_values. len( )
226
+ ) ) ;
227
+ }
228
+
229
+ let mut parsed_params = Vec :: new ( ) ;
230
+
231
+ for ( json_value, json_abi_param) in json_values. iter ( ) . zip ( json_abi_params. iter ( ) ) {
232
+ if json_abi_param. is_complex_type ( ) {
233
+ let json_value = json_value
234
+ . as_array ( )
235
+ . ok_or_else ( || "Expected array for complex type" . to_string ( ) ) ?;
236
+
237
+ let dyn_sol_value = Self :: json_to_sol ( json_value, & json_abi_param. components ) ?;
238
+
239
+ parsed_params. push ( DynSolValue :: Tuple ( dyn_sol_value) ) ;
240
+ } else {
241
+ let sol_type: DynSolType = json_abi_param
242
+ . ty
243
+ . parse ( )
244
+ . map_err ( |e| format ! ( "Invalid Solidity type '{}': {}" , json_abi_param. ty, e) ) ?;
245
+
246
+ let parsed_value: DynSolValue = sol_type
247
+ . coerce_json ( json_value)
248
+ . map_err ( |e| format ! ( "Failed to parse parameter as DynSolValue: {}" , e) ) ?;
249
+
250
+ if !parsed_value. matches ( & sol_type) {
251
+ return Err ( format ! (
252
+ "Parameter type mismatch: expected {}, got {:?}" ,
253
+ json_abi_param. ty,
254
+ parsed_value. as_type( )
255
+ ) ) ;
256
+ }
257
+
258
+ parsed_params. push ( parsed_value) ;
259
+ }
260
+ }
261
+
262
+ Ok ( parsed_params)
263
+ }
264
+
216
265
/// Encodes parameters using serde to directly deserialize into DynSolValue
217
266
pub fn encode_parameters (
218
267
& self ,
@@ -231,39 +280,9 @@ impl ContractCall {
231
280
) ) ;
232
281
}
233
282
234
- let mut parsed_params = Vec :: new ( ) ;
235
-
236
- for ( param, input) in self . params . iter ( ) . zip ( function. inputs . iter ( ) ) {
237
- let sol_type: DynSolType = input. ty . parse ( ) . map_err ( |e| {
238
- EngineError :: contract_preparation_error (
239
- Some ( self . contract_address ) ,
240
- chain_id,
241
- format ! ( "Invalid Solidity type '{}': {}" , input. ty, e) ,
242
- )
243
- } ) ?;
244
-
245
- let parsed_value: DynSolValue = sol_type. coerce_json ( param) . map_err ( |e| {
246
- EngineError :: contract_preparation_error (
247
- Some ( self . contract_address ) ,
248
- chain_id,
249
- format ! ( "Failed to parse parameter as DynSolValue: {}" , e) ,
250
- )
251
- } ) ?;
252
-
253
- if !parsed_value. matches ( & sol_type) {
254
- return Err ( EngineError :: contract_preparation_error (
255
- Some ( self . contract_address ) ,
256
- chain_id,
257
- format ! (
258
- "Parameter type mismatch: expected {}, got {:?}" ,
259
- input. ty,
260
- parsed_value. as_type( )
261
- ) ,
262
- ) ) ;
263
- }
264
-
265
- parsed_params. push ( parsed_value) ;
266
- }
283
+ let parsed_params = Self :: json_to_sol ( & self . params , & function. inputs ) . map_err ( |e| {
284
+ EngineError :: contract_preparation_error ( Some ( self . contract_address ) , chain_id, e)
285
+ } ) ?;
267
286
268
287
function. abi_encode_input ( & parsed_params) . map_err ( |e| {
269
288
EngineError :: contract_preparation_error (
0 commit comments