@@ -7,6 +7,31 @@ import { withSpinner } from './spinner';
77
88const  logger  =  debugFactory ( 'graph-cli:abi-helpers' ) ; 
99
10+ const  fetchFromEtherscan  =  async  ( url : string ) : Promise < any  |  null >  =>  { 
11+   const  result  =  await  fetch ( url ) ; 
12+   let  json : any  =  { } ; 
13+ 
14+   if  ( result . ok )  { 
15+     json  =  await  result . json ( ) . catch ( error  =>  { 
16+       throw  new  Error ( `Failed to read JSON response from Etherscan: ${ error }  ` ) ; 
17+     } ) ; 
18+ 
19+     // Etherscan returns a JSON object that has a `status`, a `message` and 
20+     // a `result` field. The `status` is '0' in case of errors and '1' in 
21+     // case of success 
22+     if  ( json . status  ===  '1' )  return  json ; 
23+   } 
24+ 
25+   logger ( 
26+     'Failed to fetchFromEtherscan: [%s] %s (%s)\n%O' , 
27+     result . status , 
28+     result . statusText , 
29+     result . url , 
30+     json , 
31+   ) ; 
32+   return  null ; 
33+ } ; 
34+ 
1035export  const  loadAbiFromEtherscan  =  async  ( 
1136  ABICtor : typeof  ABI , 
1237  network : string , 
@@ -18,16 +43,14 @@ export const loadAbiFromEtherscan = async (
1843    `Warnings while fetching ABI from Etherscan` , 
1944    async  ( )  =>  { 
2045      const  scanApiUrl  =  getEtherscanLikeAPIUrl ( network ) ; 
21-       const  result  =  await  fetch ( `${ scanApiUrl }  ?module=contract&action=getabi&address=${ address }  ` ) ; 
22-       const  json  =  await  result . json ( ) ; 
46+       const  json  =  await  fetchFromEtherscan ( 
47+         `${ scanApiUrl }  ?module=contract&action=getabi&address=${ address }  ` , 
48+       ) ; 
2349
24-       // Etherscan returns a JSON object that has a `status`, a `message` and 
25-       // a `result` field. The `status` is '0' in case of errors and '1' in 
26-       // case of success 
27-       if  ( json . status  ===  '1' )  { 
50+       if  ( json ) 
2851        return  new  ABICtor ( 'Contract' ,  undefined ,  immutable . fromJS ( JSON . parse ( json . result ) ) ) ; 
29-        } 
30-       throw  new  Error ( 'ABI not found, try  loading it from a local file' ) ; 
52+ 
53+       throw  new  Error ( 'Try  loading it from a local file' ) ; 
3154    } , 
3255  ) ; 
3356
@@ -62,11 +85,11 @@ export const fetchDeployContractTransactionFromEtherscan = async (
6285  address : string , 
6386) : Promise < string >  =>  { 
6487  const  scanApiUrl  =  getEtherscanLikeAPIUrl ( network ) ; 
65-   const  json  =  await  fetchContractCreationHashWithRetry ( 
88+   const  json  =  await  fetchFromEtherscan ( 
6689    `${ scanApiUrl }  ?module=contract&action=getcontractcreation&contractaddresses=${ address }  ` , 
67-     5 , 
6890  ) ; 
69-   if  ( json . status  ===  '1' )  { 
91+ 
92+   if  ( json )  { 
7093    const  hash  =  json . result [ 0 ] . txHash ; 
7194    logger ( 'Successfully fetchDeployContractTransactionFromEtherscan. txHash: %s' ,  hash ) ; 
7295    return  hash ; 
@@ -75,26 +98,6 @@ export const fetchDeployContractTransactionFromEtherscan = async (
7598  throw  new  Error ( `Failed to fetch deploy contract transaction` ) ; 
7699} ; 
77100
78- export  const  fetchContractCreationHashWithRetry  =  async  ( 
79-   url : string , 
80-   retryCount : number , 
81- ) : Promise < any >  =>  { 
82-   let  json ; 
83-   for  ( let  i  =  0 ;  i  <  retryCount ;  i ++ )  { 
84-     try  { 
85-       const  result  =  await  fetch ( url ) ; 
86-       json  =  await  result . json ( ) ; 
87-       if  ( json . status  !==  '0' )  { 
88-         return  json ; 
89-       } 
90-     }  catch  ( error )  { 
91-       logger ( 'Failed to fetchContractCreationHashWithRetry: %O' ,  error ) ; 
92-       /* empty */ 
93-     } 
94-   } 
95-   throw  new  Error ( `Failed to fetch contract creation transaction hash` ) ; 
96- } ; 
97- 
98101export  const  fetchTransactionByHashFromRPC  =  async  ( 
99102  network : string , 
100103  transactionHash : string , 
@@ -131,14 +134,15 @@ export const fetchSourceCodeFromEtherscan = async (
131134  address : string , 
132135) : Promise < any >  =>  { 
133136  const  scanApiUrl  =  getEtherscanLikeAPIUrl ( network ) ; 
134-   const  result  =  await  fetch ( 
137+   const  json  =  await  fetchFromEtherscan ( 
135138    `${ scanApiUrl }  ?module=contract&action=getsourcecode&address=${ address }  ` , 
136139  ) ; 
137-   const  json  =  await  result . json ( ) ; 
138-   if  ( json . status  ===  '1' )  { 
139-     return  json ; 
140-   } 
141-   throw  new  Error ( 'Failed to fetch contract source code' ) ; 
140+ 
141+   // Have to check that the SourceCode response is not empty due to Etherscan API bug responding with 
142+   // 1 - OK on non-valid contracts. 
143+   if  ( json . result [ 0 ] . SourceCode )  return  json ; 
144+ 
145+   throw  new  Error ( `Failed to fetch contract source code: ${ json . result [ 0 ] . ABI }  ` ) ; 
142146} ; 
143147
144148export  const  getContractNameForAddress  =  async  ( 
0 commit comments