Skip to content

Commit fd2384c

Browse files
author
ci-bot
committed
Etherscan: use V2 with chainId; add per-network V2 then V1 fallback; normalize endpoint casing; remove redundant retry
1 parent 40cc35a commit fd2384c

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

libs/remix-core-plugin/src/lib/helpers/fetch-etherscan.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@ export const fetchContractFromEtherscan = async (plugin, endpoint: string | Netw
1111
if (!etherscanKey) etherscanKey = '2HKUX5ZVASZIKWJM8MIQVCRUVZ6JAWT531'
1212

1313
if (etherscanKey) {
14-
// Extract chain ID from Network object before converting to string
14+
// Extract chain ID and build endpoint string once
1515
let chainId = 1 // Default to Ethereum mainnet
16+
let endpointStr: string
1617
if (typeof endpoint === 'object' && endpoint !== null && 'id' in endpoint && 'name' in endpoint) {
1718
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
1923
}
2024
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+
}
3937
}
40-
38+
39+
data = await response.json()
40+
4141
// etherscan api doc https://docs.etherscan.io/api-endpoints/contracts
4242
if (data.message === 'OK' && data.status === "1") {
4343
if (data.result.length) {

0 commit comments

Comments
 (0)