11use alloy:: hex;
2+ use alloy:: json_abi:: Param ;
23use alloy:: {
34 dyn_abi:: { DynSolType , DynSolValue , JsonAbiExt } ,
45 json_abi:: { Function , JsonAbi } ,
@@ -213,6 +214,54 @@ impl ContractCall {
213214 } )
214215 }
215216
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+
216265 /// Encodes parameters using serde to directly deserialize into DynSolValue
217266 pub fn encode_parameters (
218267 & self ,
@@ -231,39 +280,9 @@ impl ContractCall {
231280 ) ) ;
232281 }
233282
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+ } ) ?;
267286
268287 function. abi_encode_input ( & parsed_params) . map_err ( |e| {
269288 EngineError :: contract_preparation_error (
0 commit comments