Skip to content

Commit 5f04d34

Browse files
authored
Use Etherscan API V2 (#273)
1 parent ff09aec commit 5f04d34

File tree

12 files changed

+144
-129
lines changed

12 files changed

+144
-129
lines changed

README.md

Lines changed: 63 additions & 61 deletions
Large diffs are not rendered by default.

docs/advanced.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Some example gas reporter option settings for different use-cases
1919
```ts
2020
const config: HardhatUserConfig = {
2121
gasReporter: {
22-
L1Etherscan: "ABC...", // Etherscan api key
22+
etherscan: "ABC...", // Etherscan api key
2323
coinmarketcap: "abc...", // Coinmarketcap api key
2424
}
2525
}
@@ -45,9 +45,8 @@ const config: HardhatUserConfig = {
4545
const config: HardhatUserConfig = {
4646
gasReporter: {
4747
L2: "optimism",
48-
L1Etherscan: "ABC...", // Requires api keys for both Ethereum Mainnet and Optimism
49-
L2Etherscan: "ABC...",
5048
currency: "EUR",
49+
etherscan: "ABC...",
5150
coinmarketcap: "abc...",
5251
}
5352
}

scripts/gen-options-md.ts

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ const advancedSubtitle = [
2525
":mag: **LOW-LEVEL CONFIG**", "", "", ""
2626
];
2727

28+
const deprecatedSubtitle = [
29+
":hourglass_flowing_sand: **DEPRECATED**", "", "", ""
30+
];
31+
2832
const optionsTable = [
2933
title,
3034
// currency
@@ -49,6 +53,14 @@ title,
4953
"`true`",
5054
"Produce gas reports with `hardhat test`"
5155
],
56+
// etherscan
57+
[
58+
"etherscan",
59+
"_string_",
60+
"-",
61+
"[API key][4] to use when fetching live gas price and fee data from both L1 & L2 networks. " +
62+
"(Optional, see [Supported Networks][6])"
63+
],
5264
// excludeAutoGeneratedGetters
5365
[
5466
"excludeAutoGeneratedGetters",
@@ -86,22 +98,6 @@ title,
8698
"-",
8799
"Auto-configure reporter to emulate an L2 network (See [supported networks][6])"
88100
],
89-
// L1Etherscan
90-
[
91-
"L1Etherscan",
92-
"_string_",
93-
"-",
94-
"[API key][4] to use when fetching live gasPrice and baseFee data " +
95-
"from an L1 network. (Optional, see [Supported Networks][6])"
96-
],
97-
// L1Etherscan
98-
[
99-
"L2Etherscan",
100-
"_string_",
101-
"-",
102-
"[API key][4] to use when fetching live gasPrice and blobBaseFee data from an L2 network " +
103-
"(Optional, see [Supported Networks][6])"
104-
],
105101
// offline
106102
[
107103
"offline",
@@ -342,6 +338,21 @@ advancedSubtitle,
342338
"-",
343339
"Network token price per nation state currency unit. (To denominate costs *in network token* " +
344340
"set this to `\"1\"`)"
341+
],
342+
deprecatedSubtitle,
343+
// L1Etherscan
344+
[
345+
"L1Etherscan",
346+
"_string_",
347+
"-",
348+
"Etherscan V1 API key. (Use the newer `etherscan` option instead)"
349+
],
350+
// L2Etherscan
351+
[
352+
"L2Etherscan",
353+
"_string_",
354+
"-",
355+
"Etherscan V1 API key. (Use the newer `etherscan` option instead)"
345356
]];
346357

347358
// Run

src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ extendConfig(
3636
// Deep clone userConfig otherwise HH will throw unauthorized modification error
3737
if (userConfig.gasReporter !== undefined) {
3838
options = Object.assign(options, cloneDeep(userConfig.gasReporter));
39+
40+
// Use legacy Etherscan API Key if user did not migrate from deprecated options
41+
if (options.L1Etherscan && !options.etherscan) {
42+
options.etherscan = options.L1Etherscan
43+
}
3944
}
45+
4046
(config as any).gasReporter = options;
4147
}
4248
);

src/lib/render/json.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ function _sanitizeGasData(data: GasData, options: GasReporterOptions) {
6262
options.coinmarketcap = "[REDACTED]";
6363
}
6464

65+
if (options.etherscan) {
66+
options.etherscan = "[REDACTED]";
67+
}
68+
69+
// Options deprecated in 2.3.0
6570
if (options.L1Etherscan){
6671
options.L1Etherscan = "[REDACTED]";
6772
}

src/types.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ export interface GasReporterOptions {
5151
/** @property Enable plugin */
5252
enabled?: boolean;
5353

54+
/** @property Etherscan V2 API key */
55+
etherscan?: string;
56+
5457
/** @property Filters out gas reporting for solc generated public state & storage vars */
5558
excludeAutoGeneratedGetters?: boolean;
5659

@@ -84,12 +87,6 @@ export interface GasReporterOptions {
8487
/** @property L2 Network to calculate execution costs for */
8588
L2?: "optimism" | "base" | "arbitrum"
8689

87-
/** @property Etherscan API key for L1 networks */
88-
L1Etherscan?: string;
89-
90-
/** @property Etherscan API key for L2 networks */
91-
L2Etherscan?: string;
92-
9390
/** @property Omit terminal color in output */
9491
noColors?: boolean;
9592

@@ -161,6 +158,16 @@ export interface GasReporterOptions {
161158

162159
/** @ignore */
163160
cachePath?: string;
161+
162+
// ====================================
163+
// DEPRECATED:
164+
// =====================================
165+
166+
/** @deprecated Etherscan V1 API key for L1 networks. (Use newer `etherscan` option instead) */
167+
L1Etherscan?: string;
168+
169+
/** @deprecated Etherscan V1 API key for L2 networks. (Use newer `etherscan` option instead) */
170+
L2Etherscan?: string;
164171
}
165172

166173
export interface GasReporterExecutionContext {

src/utils/chains.ts

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,16 @@ export function getTokenForChain(options: GasReporterOptions): string {
2828
* @returns
2929
*/
3030
export function getGasPriceUrlForChain(options: GasReporterOptions): string {
31-
let apiKey: string;
32-
3331
if (options.gasPriceApi) return options.gasPriceApi;
3432

33+
const apiKey = (options.etherscan) ? `${DEFAULT_API_KEY_ARGS}${options.etherscan}` : "";
34+
3535
if (options.L2) {
3636
if (!L2[options.L2]) throw new Error;
37-
38-
apiKey = (options.L2Etherscan)
39-
? `${DEFAULT_API_KEY_ARGS}${options.L2Etherscan}`
40-
: "";
41-
4237
return `${L2[options.L2!].baseUrl}${DEFAULT_GAS_PRICE_API_ARGS}${apiKey}`;
4338
}
4439

4540
if (!L1[options.L1!]) throw new Error();
46-
47-
apiKey = (options.L1Etherscan)
48-
? `${DEFAULT_API_KEY_ARGS}${options.L1Etherscan}`
49-
: "";
50-
5141
return `${L1[options.L1!].baseUrl}${DEFAULT_GAS_PRICE_API_ARGS}${apiKey}`;
5242
}
5343

@@ -61,9 +51,7 @@ export function getBlockUrlForChain(options: GasReporterOptions): string {
6151
if (!options.L2) return "";
6252
if (options.getBlockApi) return options.getBlockApi;
6353

64-
const apiKey = (options.L1Etherscan)
65-
? `${DEFAULT_API_KEY_ARGS}${options.L1Etherscan}`
66-
: "";
54+
const apiKey = (options.etherscan) ? `${DEFAULT_API_KEY_ARGS}${options.etherscan}` : "";
6755

6856
if (!L1[options.L1!]) throw new Error();
6957

@@ -72,7 +60,7 @@ export function getBlockUrlForChain(options: GasReporterOptions): string {
7260

7361
/**
7462
* Gets Etherscan eth_call api url to read OP Stack GasPriceOracle for blobBaseFee.
75-
* Attaches L2 apikey if configured. (This fee fetched from L2 contract b/c its the only available place at
63+
* Attaches apikey if configured. (This fee fetched from L2 contract b/c its the only available place at
7664
* time of PR - eth_blobBaseFee hasn't been implemented in geth yet)
7765
* @param {GasReporterOptions} options
7866
* @returns
@@ -81,26 +69,22 @@ export function getBlobBaseFeeUrlForChain(options: GasReporterOptions): string {
8169
if (!options.L2) return "";
8270
if (options.blobBaseFeeApi) return options.blobBaseFeeApi;
8371

84-
const apiKey = (options.L2Etherscan)
85-
? `${DEFAULT_API_KEY_ARGS}${options.L2Etherscan}`
86-
: "";
72+
const apiKey = (options.etherscan) ? `${DEFAULT_API_KEY_ARGS}${options.etherscan}` : "";
8773

8874
return `${L2[options.L2!].baseUrl}${DEFAULT_BLOB_BASE_FEE_API_ARGS}${L2[options.L2!].gasPriceOracle}${apiKey}`;
8975
}
9076

9177
/**
9278
* Gets Etherscan eth_call api url to read OP Stack GasPriceOracle for blobBaseFee.
93-
* Attaches L2 apikey if configured. (This fee fetched from L2 contract b/c its the only available place at
79+
* Attaches apikey if configured. (This fee fetched from L2 contract b/c its the only available place at
9480
* time of PR - eth_blobBaseFee hasn't been implemented in geth yet)
9581
* @param {GasReporterOptions} options
9682
* @returns
9783
*/
9884
export function getBaseFeePerByteUrlForChain(options: GasReporterOptions): string {
9985
if (options.L2 !== "arbitrum") return "";
10086

101-
const apiKey = (options.L2Etherscan)
102-
? `${DEFAULT_API_KEY_ARGS}${options.L2Etherscan}`
103-
: "";
87+
const apiKey = (options.etherscan) ? `${DEFAULT_API_KEY_ARGS}${options.etherscan}` : "";
10488

10589
return `${L2[options.L2!].baseUrl}${DEFAULT_BASE_FEE_PER_BYTE_API_ARGS}${apiKey}`;
10690
}
@@ -111,52 +95,52 @@ export function getBaseFeePerByteUrlForChain(options: GasReporterOptions): strin
11195
*/
11296
export const L1 = {
11397
ethereum: {
114-
baseUrl: "https://api.etherscan.io/api?module=proxy&",
98+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=1&",
11599
token: "ETH"
116100
},
117101
polygon: {
118-
baseUrl: "https://api.polygonscan.com/api?module=proxy&",
102+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=137&",
119103
token: "POL"
120104
},
121105
binance: {
122-
baseUrl: "https://api.bscscan.com/api?module=proxy&",
106+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=56&",
123107
token: "BNB"
124108
},
125109
fantom: {
126-
baseUrl: "https://api.ftmscan.com/api?module=proxy&",
110+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=250&",
127111
token: "FTM"
128112
},
129113
moonbeam: {
130-
baseUrl: "https://api-moonbeam.moonscan.io/api?module=proxy&",
114+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=1284&",
131115
token: "GLMR"
132116
},
133117
moonriver: {
134-
baseUrl: "https://api-moonriver.moonscan.io//api?module=proxy&",
118+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=1285&",
135119
token: "MOVR"
136120
},
137121
gnosis: {
138-
baseUrl: "https://api.gnosisscan.io/api?module=proxy&",
122+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=100&",
139123
token: "XDAI"
140124
},
141125
avalanche: {
142-
baseUrl: "https://api.snowtrace.io/api?module=proxy&",
126+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=43114&",
143127
token: "AVAX"
144128
}
145129
}
146130

147131
export const L2 = {
148132
optimism: {
149-
baseUrl: "https://api-optimistic.etherscan.io/api?module=proxy&",
133+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=10&",
150134
gasPriceOracle: "0x420000000000000000000000000000000000000F",
151135
token: "ETH"
152136
},
153137
base: {
154-
baseUrl: "https://api.basescan.org/api?module=proxy&",
138+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=8453&",
155139
gasPriceOracle: "0x420000000000000000000000000000000000000F",
156140
token: "ETH"
157141
},
158142
arbitrum: {
159-
baseUrl: "https://api.arbiscan.io/api?module=proxy&",
143+
baseUrl: "https://api.etherscan.io/v2/api?module=proxy&chainid=42161&",
160144
gasPriceOracle: "",
161145
token: "ETH"
162146
}

test/projects/options/hardhat.options.a.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const config: HardhatUserConfig = {
3535
gasReporter: {
3636
currency: "CHF",
3737
L1: "ethereum",
38-
L1Etherscan: process.env.ETHERSCAN_API_KEY,
38+
etherscan: process.env.ETHERSCAN_API_KEY,
3939
coinmarketcap: process.env.CMC_API_KEY,
4040
rst: true,
4141
rstTitle: "Ethereum Report",

test/projects/options/hardhat.options.e.config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ const config: HardhatUserConfig = {
2020
gasReporter: {
2121
coinmarketcap: process.env.CMC_API_KEY,
2222
L2: "optimism",
23-
L1Etherscan: process.env.ETHERSCAN_API_KEY,
24-
L2Etherscan: process.env.OPTIMISTIC_API_KEY,
23+
etherscan: process.env.ETHERSCAN_API_KEY,
2524
enabled: true,
2625
reportPureAndViewMethods: true,
2726
excludeAutoGeneratedGetters: true,

test/projects/options/hardhat.options.f.config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ const config: HardhatUserConfig = {
2020
gasReporter: {
2121
coinmarketcap: process.env.CMC_API_KEY,
2222
L2: "base",
23-
L1Etherscan: process.env.ETHERSCAN_API_KEY,
24-
L2Etherscan: process.env.BASE_API_KEY,
23+
etherscan: process.env.ETHERSCAN_API_KEY,
2524
enabled: true,
2625
reportPureAndViewMethods: true,
2726
excludeAutoGeneratedGetters: true,

test/projects/options/hardhat.options.g.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ const config: HardhatUserConfig = {
2626
coinmarketcap: process.env.CMC_API_KEY,
2727
currencyDisplayPrecision: 4,
2828
L2: "arbitrum",
29+
30+
// DEPRECATED ETHERSCAN V1
2931
L1Etherscan: process.env.ETHERSCAN_API_KEY,
3032
L2Etherscan: process.env.ARBITRUM_API_KEY,
33+
3134
enabled: true,
3235
reportPureAndViewMethods: true,
3336
excludeAutoGeneratedGetters: true

test/unit/prices.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe("setGasAndPriceRates", function(){
5353

5454
options.tokenPrice = initialTokenPrice;
5555
options.coinmarketcap = process.env.CMC_API_KEY;
56-
options.L1Etherscan = process.env.ETHERSCAN_API_KEY;
56+
options.etherscan = process.env.ETHERSCAN_API_KEY;
5757

5858
assert.isUndefined(options.gasPrice);
5959

@@ -82,7 +82,7 @@ describe("setGasAndPriceRates", function(){
8282
options.gasPrice = 1;
8383
options.L2 = 'arbitrum';
8484
options.coinmarketcap = process.env.CMC_API_KEY;
85-
options.L2Etherscan = process.env.ARBITRUM_API_KEY;
85+
options.etherscan = process.env.ETHERSCAN_API_KEY;
8686

8787
assert.isUndefined(options.baseFeePerByte);
8888

@@ -97,7 +97,7 @@ describe("setGasAndPriceRates", function(){
9797
options.gasPrice = 1;
9898
options.L2 = 'optimism';
9999
options.coinmarketcap = process.env.CMC_API_KEY;
100-
options.L2Etherscan = process.env.OPTIMISTIC_API_KEY;
100+
options.etherscan = process.env.ETHERSCAN_API_KEY;
101101

102102
assert.isUndefined(options.baseFee);
103103

@@ -114,7 +114,7 @@ describe("setGasAndPriceRates", function(){
114114
options.L2 = 'optimism';
115115
options.optimismHardfork = "ecotone";
116116
options.coinmarketcap = process.env.CMC_API_KEY;
117-
options.L2Etherscan = process.env.OPTIMISTIC_API_KEY;
117+
options.etherscan = process.env.ETHERSCAN_API_KEY;
118118

119119
assert.isUndefined(options.blobBaseFee);
120120

0 commit comments

Comments
 (0)