Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Enhancement: Add even more networks to source-fetcher #5076

Merged
merged 2 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/fetch-and-compile/test/fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ describe("Supported networks", function () {
it("Lists supported networks for specified fetchers only", function () {
const networks = getSupportedNetworks(["etherscan"]);
assert.property(networks, "mainnet");
assert.notProperty(networks, "sokol"); //suported by sourcify but not etherscan
assert.notProperty(networks, "sokol-poa"); //suported by sourcify but not etherscan
assert.deepEqual(networks.mainnet, {
name: "mainnet",
networkId: 1,
Expand Down
102 changes: 39 additions & 63 deletions packages/source-fetcher/lib/etherscan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,35 +49,46 @@ const EtherscanFetcher: FetcherConstructor = class EtherscanFetcher
private ready: Promise<void>; //always await this timer before making a request.
//then, afterwards, start a new timer.

private static readonly supportedNetworks = new Set([
"mainnet",
"ropsten",
"kovan",
"rinkeby",
"goerli",
"optimistic",
"kovan-optimistic",
"arbitrum",
"rinkeby-arbitrum",
"polygon",
"mumbai-polygon",
"binance",
"testnet-binance",
"fantom",
"testnet-fantom",
//we don't support avalanche, even though etherscan has snowtrace.io
"heco",
"testnet-heco",
"moonbeam",
"moonriver",
"moonbase-alpha"
]);
private static readonly apiDomainsByNetworkName: { [name: string]: string } =
{
"mainnet": "api.etherscan.io",
"ropsten": "api-ropsten.etherscan.io",
"kovan": "api-kovan.etherscan.io",
"rinkeby": "api-rinkeby.etherscan.io",
"goerli": "api-goerli.etherscan.io",
"optimistic": "api-optimistic.etherscan.io",
"kovan-optimistic": "api-kovan-optimistic.etherscan.io",
"arbitrum": "api.arbiscan.io",
"rinkeby-arbitrum": "api-testnet.arbiscan.io",
"polygon": "api.polygonscan.com",
"mumbai-polygon": "api-mumbai.polygonscan.com",
"binance": "api.bscscan.com",
"testnet-binance": "api-testnet.bscscan.com",
"fantom": "api.ftmscan.com",
"testnet-fantom": "api-testnet.ftmscan.com",
"avalanche": "api.snowtrace.io",
"fuji-avalanche": "api-testnet.snowtrace.io",
"heco": "api.hecoinfo.com",
"testnet-heco": "api-testnet.hecoinfo.com",
"moonbeam": "api-moonbeam.moonscan.io",
"moonriver": "api-moonriver.moonscan.io",
"moonbase-alpha": "api-moonbase.moonscan.io",
"hoo": "api.hooscan.com",
"cronos": "api.cronoscan.com",
"bttc": "api.bttcscan.com",
"donau-bttc": "api-testnet.bttcscan.com",
"aurora": "api.aurorascan.dev",
"testnet-aurora": "api-testnet.aurorascan.dev",
"celo": "api.celoscan.xyz",
"alfajores-celo": "api-alfajores.celoscan.xyz",
"clover": "api.clvscan.com"
};

constructor(networkId: number, apiKey: string = "") {
const networkName = networkNamesById[networkId];
if (
networkName === undefined ||
!EtherscanFetcher.supportedNetworks.has(networkName)
!(networkName in EtherscanFetcher.apiDomainsByNetworkName)
) {
throw new InvalidNetworkError(networkId, "etherscan");
}
Expand All @@ -92,8 +103,8 @@ const EtherscanFetcher: FetcherConstructor = class EtherscanFetcher

static getSupportedNetworks(): Types.SupportedNetworks {
return Object.fromEntries(
Object.entries(networksByName).filter(([name, _]) =>
EtherscanFetcher.supportedNetworks.has(name)
Object.entries(networksByName).filter(
([name, _]) => name in EtherscanFetcher.apiDomainsByNetworkName
)
);
}
Expand All @@ -116,43 +127,8 @@ const EtherscanFetcher: FetcherConstructor = class EtherscanFetcher
}

private determineUrl() {
const scanners: { [network: string]: string } = {
//etherscan.io is treated separately
polygon: "polygonscan.com",
arbitrum: "arbiscan.io",
binance: "bscscan.com",
fantom: "ftmscan.com",
//we don't support avalanche's snowtrace.io
heco: "hecoinfo.com"
//moonscan.io is treated separately
};
const [part1, part2] = this.networkName.split("-");
if (part2 === undefined && this.networkName in scanners) {
//mainnet for one of the above scanners
return `https://api.${scanners[this.networkName]}/api`;
} else if (part2 in scanners) {
//a testnet for one of the above scanners;
//part1 is the testnet name, part2 is the broader mainnet name
let [testnet, network] = [part1, part2];
if (network === "arbitrum" && testnet === "rinkeby") {
//special case: arbitrum rinkeby is testnet.arbiscan.io,
//not rinkeby.arbiscan.io
//note: if we supported avalanche, it would have a similar special case
testnet = "testnet";
}
return `https://api-${testnet}.${scanners[network]}/api`;
} else if (part1.startsWith("moon")) {
//one of the moonbeam networks; here even the moonbeam mainnet
//gets a prefix (we use part1 to get moonbase, not moonbase-alpha)
const shortName = part1;
return `https://api-${shortName}.moonscan.io/api`;
} else if (this.networkName === "mainnet") {
//ethereum mainnet
return "https://api.etherscan.io/api";
} else {
//default case: an ethereum testnet, or an optimistic network (main or test)
return `https://api-${this.networkName}.etherscan.io/api`;
}
const domain = EtherscanFetcher.apiDomainsByNetworkName[this.networkName];
return `https://${domain}/api`;
}

private async makeRequest(address: string): Promise<EtherscanSuccess> {
Expand Down
17 changes: 14 additions & 3 deletions packages/source-fetcher/lib/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@ export const networkNamesById: { [id: number]: string } = {
4: "rinkeby",
5: "goerli",
42: "kovan",
11155111: "sepolia",
10: "optimistic",
69: "kovan-optimistic",
42161: "arbitrum",
421611: "rinkeby-arbitrum",
137: "polygon",
80001: "mumbai-polygon",
100: "xdai",
77: "sokol",
99: "poa", //not presently supported by either fetcher, but...
77: "sokol-poa",
56: "binance",
97: "testnet-binance",
42220: "celo",
44787: "alfajores-celo",
62320: "baklava-celo",
//we don't support avalanche, so it's excluded
43114: "avalanche",
43113: "fuji-avalanche",
40: "telos",
41: "testnet-telos",
8: "ubiq",
Expand All @@ -40,7 +43,15 @@ export const networkNamesById: { [id: number]: string } = {
256: "testnet-heco",
1284: "moonbeam",
1285: "moonriver",
1287: "moonbase-alpha"
1287: "moonbase-alpha",
122: "fuse",
11297108109: "palm",
11297108099: "testnet-palm",
70: "hoo",
25: "cronos",
199: "bttc",
1029: "donau-bttc",
1024: "clover"
};

export const networksByName: Types.SupportedNetworks = Object.fromEntries(
Expand Down
15 changes: 12 additions & 3 deletions packages/source-fetcher/lib/sourcify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,23 @@ const SourcifyFetcher: FetcherConstructor = class SourcifyFetcher
"rinkeby",
"goerli",
"kovan",
"sepolia",
"optimistic",
"kovan-optimistic",
"arbitrum",
"rinkeby-arbitrum",
"polygon",
"mumbai-polygon",
"xdai",
"sokol",
//sourcify does *not* support poa core...?
"sokol-poa",
"binance",
"testnet-binance",
"celo",
"alfajores-celo",
"baklava-celo",
//again, we don't support avalanche, even though sourcify does
"avalanche",
"fuji-avalanche",
"telos",
"testnet-telos",
"ubiq",
Expand All @@ -68,7 +71,13 @@ const SourcifyFetcher: FetcherConstructor = class SourcifyFetcher
"meter",
"testnet-meter",
"aurora",
"testnet-aurora"
"testnet-aurora",
"fuse",
"moonbeam",
"moonriver",
"moonbase-alpha",
"palm",
"testnet-palm"
]);

constructor(networkId: number) {
Expand Down