@@ -241,7 +241,7 @@ impl Client {
241
241
} ) ?;
242
242
243
243
match res {
244
- ResponseData :: Error { result , message, status } => {
244
+ ResponseData :: Error { message, result } => {
245
245
if let Some ( ref result) = result {
246
246
if result. starts_with ( "Max rate limit reached" ) {
247
247
return Err ( EtherscanError :: RateLimitExceeded ) ;
@@ -250,9 +250,11 @@ impl Client {
250
250
return Err ( EtherscanError :: InvalidApiKey ) ;
251
251
}
252
252
}
253
- Err ( EtherscanError :: ErrorResponse { status, message, result } )
253
+ Err ( EtherscanError :: ErrorResponse { status : "0" . to_string ( ) , message, result } )
254
+ }
255
+ ResponseData :: Success { message, result } => {
256
+ Ok ( Response { status : "1" . to_string ( ) , message, result } )
254
257
}
255
- ResponseData :: Success ( res) => Ok ( res) ,
256
258
}
257
259
}
258
260
@@ -496,11 +498,13 @@ pub struct Response<T> {
496
498
pub result : T ,
497
499
}
498
500
499
- #[ derive( Deserialize , Debug , Clone ) ]
500
- #[ serde( untagged ) ]
501
+ #[ derive( Debug , Clone , Deserialize ) ]
502
+ #[ serde( tag = "status" ) ]
501
503
pub enum ResponseData < T > {
502
- Success ( Response < T > ) ,
503
- Error { status : String , message : String , result : Option < String > } ,
504
+ #[ serde( rename = "1" ) ]
505
+ Success { message : String , result : T } ,
506
+ #[ serde( rename = "0" ) ]
507
+ Error { message : String , result : Option < String > } ,
504
508
}
505
509
506
510
/// The type that gets serialized as query
@@ -528,6 +532,7 @@ mod tests {
528
532
use crate :: { Client , EtherscanError , ResponseData } ;
529
533
use alloy_chains:: Chain ;
530
534
use alloy_primitives:: { Address , B256 } ;
535
+ use serde_json:: json;
531
536
532
537
// <https://github.com/foundry-rs/foundry/issues/4406>
533
538
#[ test]
@@ -537,6 +542,17 @@ mod tests {
537
542
assert ! ( matches!( resp, ResponseData :: Error { .. } ) ) ;
538
543
}
539
544
545
+ #[ test]
546
+ fn can_parse_etherscan_mainnet_invalid_api_key ( ) {
547
+ let err = json ! ( {
548
+ "status" : "0" ,
549
+ "message" : "NOTOK" ,
550
+ "result" : "Missing/Invalid API Key"
551
+ } ) ;
552
+ let resp: ResponseData < String > = serde_json:: from_value ( err) . unwrap ( ) ;
553
+ assert ! ( matches!( resp, ResponseData :: Error { .. } ) ) ;
554
+ }
555
+
540
556
#[ test]
541
557
fn test_api_paths ( ) {
542
558
let client = Client :: new ( Chain :: goerli ( ) , "" ) . unwrap ( ) ;
0 commit comments