@@ -11,33 +11,33 @@ export const fetchContractFromEtherscan = async (plugin, endpoint: string | Netw
11
11
if ( ! etherscanKey ) etherscanKey = '2HKUX5ZVASZIKWJM8MIQVCRUVZ6JAWT531'
12
12
13
13
if ( etherscanKey ) {
14
- // Extract chain ID from Network object before converting to string
14
+ // Extract chain ID and build endpoint string once
15
15
let chainId = 1 // Default to Ethereum mainnet
16
+ let endpointStr : string
16
17
if ( typeof endpoint === 'object' && endpoint !== null && 'id' in endpoint && 'name' in endpoint ) {
17
18
chainId = endpoint . id
18
- endpoint = endpoint . id == 1 ? 'api.etherscan.io' : 'api-' + endpoint . name + '.etherscan.io'
19
+ const normalized = String ( ( endpoint as any ) . name || '' ) . toLowerCase ( )
20
+ endpointStr = endpoint . id == 1 ? 'api.etherscan.io' : 'api-' + normalized + '.etherscan.io'
21
+ } else {
22
+ endpointStr = endpoint as string
19
23
}
20
24
try {
21
- // Try V2 API first with chainid parameter
22
- let apiUrl = 'https://' + endpoint + '/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
23
- data = await fetch ( apiUrl )
24
-
25
- // If V2 API fails (404 or other error), fallback to V1 API
26
- if ( ! data . ok ) {
27
- apiUrl = 'https://' + endpoint + '/api?module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
28
- data = await fetch ( apiUrl )
29
- }
30
-
31
- data = await data . json ( )
32
-
33
- // Handle deprecated V1 endpoint response
34
- if ( data . message === 'NOTOK' && data . result && data . result . includes ( 'deprecated V1 endpoint' ) ) {
35
- // Force V2 API usage even if it initially failed
36
- apiUrl = 'https://' + endpoint + '/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
37
- data = await fetch ( apiUrl )
38
- data = await data . json ( )
25
+ // Prefer central V2 API host with chainid param (works across Etherscan-supported networks)
26
+ const v2CentralUrl = 'https://api.etherscan.io/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
27
+ let response = await fetch ( v2CentralUrl )
28
+
29
+ // If central V2 not OK, try per-network V2, then per-network V1
30
+ if ( ! response . ok ) {
31
+ const v2PerNetworkUrl = 'https://' + endpointStr + '/v2/api?chainid=' + chainId + '&module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
32
+ response = await fetch ( v2PerNetworkUrl )
33
+ if ( ! response . ok ) {
34
+ const v1Url = 'https://' + endpointStr + '/api?module=contract&action=getsourcecode&address=' + contractAddress + '&apikey=' + etherscanKey
35
+ response = await fetch ( v1Url )
36
+ }
39
37
}
40
-
38
+
39
+ data = await response . json ( )
40
+
41
41
// etherscan api doc https://docs.etherscan.io/api-endpoints/contracts
42
42
if ( data . message === 'OK' && data . status === "1" ) {
43
43
if ( data . result . length ) {
0 commit comments