@skalenetwork/upgrade-tools 4.0.0-update-verify.6 → 4.0.0-verification.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,25 @@
1
- import { VerificationTarget } from "./verification";
2
- export declare class ContractVerifier {
3
- private readonly contractName;
4
- private readonly contractAddress;
5
- private readonly apiURL;
6
- private readonly browserURL;
7
- private readonly isEtherscan;
8
- private readonly etherscan;
9
- constructor(target: VerificationTarget);
10
- private isAlreadyVerified;
11
- private submitVerification;
1
+ import { ValidationResponse } from "@nomicfoundation/hardhat-verify/internal/utilities";
2
+ export interface VerificationTarget {
3
+ contractName: string;
4
+ contractAddress: string;
5
+ }
6
+ export interface VerificationRequestParameters {
7
+ solcInputJson: string;
8
+ fullContractName: string;
9
+ compilerVersion: string;
10
+ }
11
+ export declare abstract class ContractVerifier {
12
+ abstract name: string;
13
+ private readonly PROXY_CONTRACT_NAME;
14
+ verify: (verificationTarget: VerificationTarget, attempts?: number) => Promise<void>;
15
+ attemptVerification(verificationTarget: VerificationTarget): Promise<boolean>;
16
+ protected abstract isAlreadyVerified(verificationTarget: VerificationTarget): Promise<boolean>;
17
+ protected abstract submitVerificationRequest(target: VerificationTarget, params: VerificationRequestParameters): Promise<ValidationResponse>;
18
+ protected abstract getContractUrl(verificationTarget: VerificationTarget): string;
19
+ protected getVerifyParameters(contractName: string): Promise<{
20
+ compilerVersion: string;
21
+ fullContractName: string;
22
+ solcInputJson: string;
23
+ }>;
12
24
  private checkVerificationStatus;
13
- attempt(): Promise<boolean>;
14
25
  }
@@ -4,63 +4,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ContractVerifier = void 0;
7
- const verification_1 = require("./verification");
8
- const etherscan_1 = require("@nomicfoundation/hardhat-verify/etherscan");
7
+ const hardhat_1 = require("hardhat");
9
8
  const chalk_1 = __importDefault(require("chalk"));
9
+ const TransparentUpgradeableProxy_json_1 = __importDefault(require("@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts-v5/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"));
10
+ const build_info_v5_json_1 = __importDefault(require("@openzeppelin/upgrades-core/artifacts/build-info-v5.json"));
11
+ const DEFAULT_RETRIES_AMOUNT = 5;
10
12
  class ContractVerifier {
11
- constructor(target) {
12
- this.contractName = target.contractName;
13
- this.contractAddress = target.contractAddress;
14
- this.apiURL = target.explorerUrls.apiURL;
15
- this.browserURL = target.explorerUrls.browserURL;
16
- this.isEtherscan = Boolean(target.isEtherscan);
17
- this.etherscan = new etherscan_1.Etherscan(process.env.ETHERSCAN ?? "", this.apiURL, this.browserURL, target.chainId);
13
+ constructor() {
14
+ this.PROXY_CONTRACT_NAME = "TransparentUpgradeableProxy";
15
+ this.verify = async (verificationTarget, attempts = DEFAULT_RETRIES_AMOUNT) => {
16
+ const limit = 0;
17
+ if (attempts > limit) {
18
+ if (!await this.attemptVerification(verificationTarget)) {
19
+ const failedAttempts = 1;
20
+ await this.verify(verificationTarget, attempts - failedAttempts);
21
+ }
22
+ }
23
+ };
18
24
  }
19
- async isAlreadyVerified() {
20
- let verified = false;
21
- if (this.isEtherscan) {
22
- verified = await this.etherscan.isVerified(this.contractAddress);
23
- }
24
- if (!verified) {
25
- verified = await (0, verification_1.isVerifiedOnBlockscout)(this.apiURL, this.contractAddress);
26
- }
27
- if (verified) {
28
- console.log(`${this.contractName} is already verified on: ${this.etherscan.getContractUrl(this.contractAddress)}`);
25
+ async attemptVerification(verificationTarget) {
26
+ if (await this.isAlreadyVerified(verificationTarget)) {
27
+ console.log(chalk_1.default.cyan(`${verificationTarget.contractName} is already verified on ${this.name}:\n${this.getContractUrl(verificationTarget)}`));
28
+ return true;
29
29
  }
30
- return verified;
31
- }
32
- async submitVerification(params) {
30
+ const params = await this.getVerifyParameters(verificationTarget.contractName);
33
31
  try {
34
- const res = await this.etherscan.verify(this.contractAddress, params.solcInputJson, params.fullContractName, params.compilerVersion, "");
35
- return res.message;
32
+ const response = await this.submitVerificationRequest(verificationTarget, params);
33
+ return this.checkVerificationStatus(verificationTarget, response);
36
34
  }
37
35
  catch (error) {
38
- console.log(chalk_1.default.yellow(`Verification attempt for ${this.contractName} failed with error: ${error}`));
39
- return null;
40
- }
41
- }
42
- async checkVerificationStatus(guid) {
43
- const status = await this.etherscan.getVerificationStatus(guid);
44
- if (status.isFailure()) {
45
- console.log(chalk_1.default.red(`Failed to verify contract ${this.contractName}`));
36
+ console.log(chalk_1.default.yellow(`Verification attempt for ${verificationTarget.contractName} failed on ${this.name} with error: ${error}`));
46
37
  return false;
47
38
  }
48
- console.log(`${this.contractName} is successfully verified on: ${this.etherscan.getContractUrl(this.contractAddress)}`);
49
- return true;
50
39
  }
51
- async attempt() {
52
- if (await this.isAlreadyVerified()) {
53
- return true;
40
+ async getVerifyParameters(contractName) {
41
+ if (contractName === this.PROXY_CONTRACT_NAME) {
42
+ return {
43
+ compilerVersion: build_info_v5_json_1.default.solcLongVersion,
44
+ fullContractName: `${TransparentUpgradeableProxy_json_1.default.sourceName}:${contractName}`,
45
+ solcInputJson: JSON.stringify(build_info_v5_json_1.default.input)
46
+ };
54
47
  }
55
- const params = await (0, verification_1.getVerifyParameters)(this.contractName);
56
- if (this.isEtherscan) {
57
- params.compilerVersion = `v${params.compilerVersion}`;
48
+ const artifact = await hardhat_1.artifacts.readArtifact(contractName);
49
+ const fullContractName = `${artifact.sourceName}:${contractName}`;
50
+ const buildInfo = await hardhat_1.artifacts.getBuildInfo(fullContractName);
51
+ if (!buildInfo) {
52
+ throw new Error(`No build-info for ${contractName}`);
58
53
  }
59
- const guid = await this.submitVerification(params);
60
- if (!guid) {
54
+ return {
55
+ compilerVersion: buildInfo.solcLongVersion,
56
+ fullContractName,
57
+ solcInputJson: JSON.stringify(buildInfo.input)
58
+ };
59
+ }
60
+ // Private
61
+ checkVerificationStatus(verificationTarget, response) {
62
+ if (response.isFailure()) {
63
+ console.log(chalk_1.default.red(`Failed to verify contract ${verificationTarget.contractName}`));
61
64
  return false;
62
65
  }
63
- return this.checkVerificationStatus(guid);
66
+ console.log(chalk_1.default.cyan(`${verificationTarget.contractName} is successfully verified on ${this.name}:\n${this.getContractUrl(verificationTarget)}`));
67
+ return true;
64
68
  }
65
69
  }
66
70
  exports.ContractVerifier = ContractVerifier;
@@ -1 +1 @@
1
- {"version":3,"file":"contractVerifier.js","sourceRoot":"","sources":["../../src/contractVerifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contractVerifier.js","sourceRoot":"","sources":["../../src/contractVerifier.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,2 @@
1
- export interface VerificationTarget {
2
- contractName: string;
3
- contractAddress: string;
4
- explorerUrls: {
5
- browserURL: string;
6
- apiURL: string;
7
- };
8
- isEtherscan?: boolean;
9
- chainId?: number;
10
- }
11
- export declare const isVerifiedOnBlockscout: (apiURL: string, address: string) => Promise<boolean>;
12
- export declare const getVerifyParameters: (contractName: string) => Promise<{
13
- compilerVersion: string;
14
- fullContractName: string;
15
- solcInputJson: string;
16
- }>;
17
1
  export declare const verify: (contractName: string, contractAddress: string) => Promise<void>;
18
2
  export declare const verifyProxy: (contractName: string, proxyAddress: string) => Promise<void>;
@@ -3,228 +3,76 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.verifyProxy = exports.verify = exports.getVerifyParameters = exports.isVerifiedOnBlockscout = void 0;
6
+ exports.verifyProxy = exports.verify = void 0;
7
7
  const hardhat_1 = require("hardhat");
8
- const contractVerifier_1 = require("./contractVerifier");
9
- const semaphore_async_await_1 = __importDefault(require("semaphore-async-await"));
8
+ const blockscoutVerifier_1 = require("./verifiers/blockscoutVerifier");
9
+ const etherscanVerifier_1 = require("./verifiers/etherscanVerifier");
10
+ const skaleBlockscoutVerifier_1 = require("./verifiers/skaleBlockscoutVerifier");
10
11
  const chalk_1 = __importDefault(require("chalk"));
11
12
  const upgrades_core_1 = require("@openzeppelin/upgrades-core");
12
- const TransparentUpgradeableProxy_json_1 = __importDefault(require("@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts-v5/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json"));
13
- const build_info_v5_json_1 = __importDefault(require("@openzeppelin/upgrades-core/artifacts/build-info-v5.json"));
14
- // Cspell:words skalenodes holesky hoodi chainname blockexplorer apiurl
15
- const RETRIES_AMOUNT = 5;
16
- const MAX_CONCURRENCY = 1;
17
- const BASE_EXPLORER_URLS = {
18
- legacy: "legacy-explorer.skalenodes.com",
19
- mainnet: "explorer.mainnet.skalenodes.com",
20
- testnet: "explorer.testnet.skalenodes.com"
21
- };
22
- const etherscanChains = [];
23
- const lock = new semaphore_async_await_1.default(MAX_CONCURRENCY);
24
- const loadEtherscanSupportedChains = async () => {
25
- const resp = await fetch("https://api.etherscan.io/v2/chainlist");
26
- if (!resp.ok) {
27
- throw new Error(`Etherscan API error: ${resp.status} ${resp.statusText}`);
28
- }
29
- const data = await resp.json();
30
- data.result.forEach((element) => {
31
- etherscanChains.push({
32
- chainId: parseInt(element.chainid, 10),
33
- network: element.chainname,
34
- urls: {
35
- apiURL: element.apiurl,
36
- browserURL: element.blockexplorer
37
- }
38
- });
39
- });
40
- };
41
- const safeLoadSupportedChains = async () => {
42
- await lock.acquire();
43
- try {
44
- if (!etherscanChains.length) {
45
- await loadEtherscanSupportedChains();
46
- }
47
- }
48
- finally {
49
- lock.release();
50
- }
51
- };
52
- const blockscoutChains = [
53
- {
54
- chainId: 1,
55
- network: "mainnet",
56
- urls: {
57
- apiURL: "https://eth.blockscout.com/api",
58
- browserURL: "https://eth.blockscout.com",
59
- }
60
- },
61
- {
62
- chainId: 11155111,
63
- network: "sepolia",
64
- urls: {
65
- apiURL: "https://eth-sepolia.blockscout.com/api",
66
- browserURL: "https://eth-sepolia.blockscout.com",
67
- }
68
- },
69
- {
70
- chainId: 17000,
71
- network: "holesky",
72
- urls: {
73
- apiURL: "https://eth-holesky.blockscout.com/api",
74
- browserURL: "https://eth-holesky.blockscout.com",
75
- }
76
- },
77
- {
78
- chainId: 560048,
79
- network: "hoodi",
80
- urls: {
81
- apiURL: "https://eth-hoodi.blockscout.com/api",
82
- browserURL: "https://eth-hoodi.blockscout.com",
13
+ const setupEtherscan = async (chainId) => {
14
+ if (process.env.ETHERSCAN) {
15
+ if (await etherscanVerifier_1.EtherscanVerifier.isChainSupported(chainId)) {
16
+ return new etherscanVerifier_1.EtherscanVerifier(process.env.ETHERSCAN, chainId);
83
17
  }
84
- }
85
- ];
86
- const pingExplorer = async (baseUrl) => {
87
- const url = `${baseUrl}/api/health`;
88
- try {
89
- const res = await fetch(url);
90
- if (!res.ok) {
91
- return false;
92
- }
93
- const jsonResponse = await res.json();
94
- return jsonResponse.healthy;
95
- }
96
- catch {
97
- return false;
98
- }
99
- };
100
- const parseEndpoint = (endpoint) => {
101
- const { host, pathname } = new URL(endpoint);
102
- const schainName = pathname.split("/").filter(Boolean).pop();
103
- let networkType = "mainnet";
104
- if (host.includes("mainnet.")) {
105
- networkType = "mainnet";
106
- }
107
- else if (host.includes("testnet.")) {
108
- networkType = "testnet";
109
- }
110
- else if (host.includes("legacy-proxy.")) {
111
- networkType = "legacy";
18
+ console.log(chalk_1.default.gray(`Etherscan does not support chainId ${chainId}. Skipping verification on Etherscan.`));
112
19
  }
113
20
  else {
114
- throw new Error(`Unknown network in ENDPOINT: ${endpoint}`);
21
+ console.log(chalk_1.default.yellow(`No etherscan API key provided. Skipping verification on Etherscan.`));
115
22
  }
116
- return { networkType, schainName };
23
+ return null;
117
24
  };
118
- const getSchainExplorerUrls = async () => {
119
- if (!process.env.ENDPOINT) {
120
- throw new Error("ENDPOINT is not set");
121
- }
122
- const { schainName, networkType } = parseEndpoint(process.env.ENDPOINT);
123
- const browserURL = `https://${schainName}.${BASE_EXPLORER_URLS[networkType]}`;
124
- const apiURL = `${browserURL}/api`;
125
- if (!await pingExplorer(browserURL)) {
126
- throw new Error(`Explorer is not reachable, set EXPLORER_URL`);
25
+ const setupBlockscout = (chainId) => {
26
+ const verifier = blockscoutVerifier_1.BlockscoutVerifier.createFromChainId(chainId);
27
+ if (verifier) {
28
+ return verifier;
127
29
  }
128
- return { apiURL, browserURL };
129
- };
130
- const getExplorerUrls = async (chainConfig) => {
30
+ console.log(chalk_1.default.gray(`Blockscout API url is not known for chainId ${chainId}.`));
131
31
  if (process.env.EXPLORER_URL) {
132
- return {
133
- apiURL: `${process.env.EXPLORER_URL}/api`,
134
- browserURL: process.env.EXPLORER_URL
135
- };
136
- }
137
- if (chainConfig) {
138
- return chainConfig.urls;
139
- }
140
- return await getSchainExplorerUrls();
141
- };
142
- const isVerifiedOnBlockscout = async (apiURL, address) => {
143
- const url = `${apiURL}/v2/smart-contracts/${address}`;
144
- try {
145
- const response = await fetch(url);
146
- const data = await response.json();
147
- return data?.is_verified;
148
- }
149
- catch {
150
- return false;
151
- }
152
- };
153
- exports.isVerifiedOnBlockscout = isVerifiedOnBlockscout;
154
- const getVerifyParameters = async (contractName) => {
155
- if (contractName === "TransparentUpgradeableProxy") {
156
- return {
157
- compilerVersion: build_info_v5_json_1.default.solcLongVersion,
158
- fullContractName: `${TransparentUpgradeableProxy_json_1.default.sourceName}:${contractName}`,
159
- solcInputJson: JSON.stringify(build_info_v5_json_1.default.input)
160
- };
161
- }
162
- const artifact = await hardhat_1.artifacts.readArtifact(contractName);
163
- const fullContractName = `${artifact.sourceName}:${contractName}`;
164
- const buildInfo = await hardhat_1.artifacts.getBuildInfo(fullContractName);
165
- if (!buildInfo) {
166
- throw new Error(`No build-info for ${contractName}`);
167
- }
168
- return {
169
- compilerVersion: buildInfo.solcLongVersion,
170
- fullContractName,
171
- solcInputJson: JSON.stringify(buildInfo.input)
172
- };
173
- };
174
- exports.getVerifyParameters = getVerifyParameters;
175
- const verifyWithRetry = async (verificationTarget, attempts) => {
176
- if (attempts) {
177
- const verifier = new contractVerifier_1.ContractVerifier(verificationTarget);
178
- if (!await verifier.attempt()) {
179
- const failedAttempts = 1;
180
- await verifyWithRetry(verificationTarget, attempts - failedAttempts);
32
+ console.log(chalk_1.default.gray("Using EXPLORER_URL to setup verification."));
33
+ return new blockscoutVerifier_1.BlockscoutVerifier(`${process.env.EXPLORER_URL}/api`, process.env.EXPLORER_URL);
34
+ }
35
+ console.log(chalk_1.default.gray("Skipping verification on Blockscout."));
36
+ return null;
37
+ };
38
+ const setupSkale = async () => {
39
+ if (process.env.ENDPOINT) {
40
+ try {
41
+ const verifier = await skaleBlockscoutVerifier_1.SkaleBlockscoutVerifier.createFromEndpoint(process.env.ENDPOINT);
42
+ if (verifier) {
43
+ return verifier;
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.log(chalk_1.default.yellow(error));
181
48
  }
182
49
  }
183
- };
184
- const verifyOnEtherscan = async (contractName, contractAddress, chainConfig) => {
185
- if (!process.env.ETHERSCAN) {
186
- console.log(chalk_1.default.yellow(`No etherscan API key provided. Skipping verification for ${contractName}.`));
187
- return;
50
+ else {
51
+ console.log(chalk_1.default.gray("ENDPOINT is not provided. Can't determine SKALE block explorer API url."));
188
52
  }
189
- const explorerUrls = await getExplorerUrls(chainConfig);
190
- await verifyWithRetry({
191
- chainId: chainConfig.chainId,
192
- contractAddress,
193
- contractName,
194
- explorerUrls,
195
- isEtherscan: true,
196
- }, RETRIES_AMOUNT);
53
+ console.log(chalk_1.default.gray("Skipping verification on SKALE block explorer."));
54
+ return null;
197
55
  };
198
- const verifyOnBlockscout = async (contractName, contractAddress, chainConfig) => {
199
- const explorerUrls = await getExplorerUrls(chainConfig);
200
- await verifyWithRetry({
201
- contractAddress,
202
- contractName,
203
- explorerUrls
204
- }, RETRIES_AMOUNT);
205
- };
206
- const verifyOnSkale = async (contractName, contractAddress) => {
207
- const explorerUrls = await getExplorerUrls();
208
- await verifyWithRetry({
209
- contractAddress,
210
- contractName,
211
- explorerUrls
212
- }, RETRIES_AMOUNT);
56
+ const verifiers = [];
57
+ let verifiersSetup = false;
58
+ const setupVerifiers = async () => {
59
+ if (!verifiersSetup) {
60
+ verifiersSetup = true;
61
+ const { chainId } = await hardhat_1.ethers.provider.getNetwork();
62
+ const candidates = [
63
+ await setupEtherscan(chainId),
64
+ setupBlockscout(chainId),
65
+ await setupSkale()
66
+ ];
67
+ verifiers.push(...candidates.filter(item => item !== null));
68
+ }
213
69
  };
214
70
  const verify = async (contractName, contractAddress) => {
215
- await safeLoadSupportedChains();
216
- const { chainId } = await hardhat_1.ethers.provider.getNetwork();
217
- const etherscanConfig = etherscanChains.find(config => config.chainId === Number(chainId));
218
- const blockscoutConfig = blockscoutChains.find(config => config.chainId === Number(chainId));
219
- if (blockscoutConfig) {
220
- await verifyOnBlockscout(contractName, contractAddress, blockscoutConfig);
221
- }
222
- if (etherscanConfig) {
223
- await verifyOnEtherscan(contractName, contractAddress, etherscanConfig);
224
- }
225
- if (!etherscanConfig && !blockscoutConfig) {
226
- await verifyOnSkale(contractName, contractAddress);
227
- }
71
+ await setupVerifiers();
72
+ await Promise.all(verifiers.map(verifier => verifier.verify({
73
+ contractAddress,
74
+ contractName
75
+ })));
228
76
  };
229
77
  exports.verify = verify;
230
78
  const verifyProxy = async (contractName, proxyAddress) => {
@@ -1 +1 @@
1
- {"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/verification.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/verification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ContractVerifier, VerificationRequestParameters, VerificationTarget } from "../contractVerifier";
2
+ import { ValidationResponse } from "@nomicfoundation/hardhat-verify/internal/utilities";
3
+ export declare class BlockscoutVerifier extends ContractVerifier {
4
+ name: string;
5
+ private readonly blockscout;
6
+ constructor(apiURL: string, browserURL: string);
7
+ static createFromChainId(chainId: bigint): BlockscoutVerifier | null;
8
+ protected isAlreadyVerified(verificationTarget: VerificationTarget): Promise<boolean>;
9
+ protected submitVerificationRequest(target: VerificationTarget, params: VerificationRequestParameters): Promise<ValidationResponse>;
10
+ protected getContractUrl(verificationTarget: VerificationTarget): string;
11
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ // Cspell:words holesky hoodi
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.BlockscoutVerifier = void 0;
5
+ const contractVerifier_1 = require("../contractVerifier");
6
+ const blockscout_1 = require("@nomicfoundation/hardhat-verify/blockscout");
7
+ const BLOCKSCOUT_CHAINS = [
8
+ {
9
+ chainId: 1,
10
+ network: "mainnet",
11
+ urls: {
12
+ apiURL: "https://eth.blockscout.com/api",
13
+ browserURL: "https://eth.blockscout.com",
14
+ }
15
+ },
16
+ {
17
+ chainId: 11155111,
18
+ network: "sepolia",
19
+ urls: {
20
+ apiURL: "https://eth-sepolia.blockscout.com/api",
21
+ browserURL: "https://eth-sepolia.blockscout.com",
22
+ }
23
+ },
24
+ {
25
+ chainId: 17000,
26
+ network: "holesky",
27
+ urls: {
28
+ apiURL: "https://eth-holesky.blockscout.com/api",
29
+ browserURL: "https://eth-holesky.blockscout.com",
30
+ }
31
+ },
32
+ {
33
+ chainId: 560048,
34
+ network: "hoodi",
35
+ urls: {
36
+ apiURL: "https://eth-hoodi.blockscout.com/api",
37
+ browserURL: "https://eth-hoodi.blockscout.com",
38
+ }
39
+ }
40
+ ];
41
+ class BlockscoutVerifier extends contractVerifier_1.ContractVerifier {
42
+ constructor(apiURL, browserURL) {
43
+ super();
44
+ this.name = "Blockscout";
45
+ this.blockscout = new blockscout_1.Blockscout(apiURL, browserURL);
46
+ }
47
+ static createFromChainId(chainId) {
48
+ const config = BLOCKSCOUT_CHAINS.find(chain => chain.chainId === Number(chainId));
49
+ if (config) {
50
+ return new BlockscoutVerifier(config.urls.apiURL, config.urls.browserURL);
51
+ }
52
+ return null;
53
+ }
54
+ async isAlreadyVerified(verificationTarget) {
55
+ return await this.blockscout.isVerified(verificationTarget.contractAddress);
56
+ }
57
+ async submitVerificationRequest(target, params) {
58
+ return await this.blockscout.verify(target.contractAddress, params.solcInputJson, params.fullContractName, params.compilerVersion);
59
+ }
60
+ getContractUrl(verificationTarget) {
61
+ return this.blockscout.getContractUrl(verificationTarget.contractAddress);
62
+ }
63
+ }
64
+ exports.BlockscoutVerifier = BlockscoutVerifier;
65
+ //# sourceMappingURL=blockscoutVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blockscoutVerifier.js","sourceRoot":"","sources":["../../../src/verifiers/blockscoutVerifier.ts"],"names":[],"mappings":";AAAA,6BAA6B;;;AAE7B,0DAAwG;AACxG,2EAAsE;AAItE,MAAM,iBAAiB,GAAkB;IACrC;QACI,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE;YACF,MAAM,EAAE,gCAAgC;YACxC,UAAU,EAAE,4BAA4B;SAC3C;KACJ;IACD;QACI,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE;YACF,MAAM,EAAE,wCAAwC;YAChD,UAAU,EAAE,oCAAoC;SACnD;KACJ;IACD;QACI,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE;YACF,MAAM,EAAE,wCAAwC;YAChD,UAAU,EAAE,oCAAoC;SACnD;KACJ;IACD;QACI,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACF,MAAM,EAAE,sCAAsC;YAC9C,UAAU,EAAE,kCAAkC;SACjD;KACJ;CACJ,CAAA;AAED,MAAa,kBAAmB,SAAQ,mCAAgB;IAIpD,YAAY,MAAc,EAAE,UAAkB;QAC1C,KAAK,EAAE,CAAC;QAJL,SAAI,GAAG,YAAY,CAAC;QAKvB,IAAI,CAAC,UAAU,GAAG,IAAI,uBAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAAC,OAAe;QAC3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAClF,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAES,KAAK,CAAC,iBAAiB,CAAC,kBAAsC;QACpE,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAChF,CAAC;IAES,KAAK,CAAC,yBAAyB,CAAC,MAA0B,EAAE,MAAqC;QACvG,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAC/B,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,aAAa,EACpB,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,eAAe,CACzB,CAAC;IACN,CAAC;IAES,cAAc,CAAC,kBAAsC;QAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9E,CAAC;CACJ;AAjCD,gDAiCC"}
@@ -0,0 +1,19 @@
1
+ import { ContractVerifier, VerificationRequestParameters, VerificationTarget } from '../contractVerifier';
2
+ import { ValidationResponse } from '@nomicfoundation/hardhat-verify/internal/utilities';
3
+ export declare class EtherscanVerifier extends ContractVerifier {
4
+ readonly name = "Etherscan";
5
+ private readonly etherscan;
6
+ constructor(apiKey: string, chainId: bigint);
7
+ static isChainSupported(chainId: bigint): Promise<boolean>;
8
+ protected isAlreadyVerified(verificationTarget: VerificationTarget): Promise<boolean>;
9
+ protected submitVerificationRequest(target: VerificationTarget, params: VerificationRequestParameters, retries?: number): Promise<ValidationResponse>;
10
+ protected getContractUrl(verificationTarget: VerificationTarget): string;
11
+ protected getVerifyParameters(contractName: string): Promise<{
12
+ compilerVersion: string;
13
+ fullContractName: string;
14
+ solcInputJson: string;
15
+ }>;
16
+ private static loadEtherscanSupportedChains;
17
+ private processContractVerificationMissingBytecodeError;
18
+ private static waitForBlocks;
19
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ // Cspell:words apiurl blockexplorer chainname
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EtherscanVerifier = void 0;
8
+ const contractVerifier_1 = require("../contractVerifier");
9
+ const etherscan_1 = require("@nomicfoundation/hardhat-verify/etherscan");
10
+ const semaphore_async_await_1 = __importDefault(require("semaphore-async-await"));
11
+ const chalk_1 = __importDefault(require("chalk"));
12
+ const hardhat_1 = require("hardhat");
13
+ const MAX_CONCURRENCY = 1;
14
+ const DEFAULT_RETRIES_AMOUNT = 5;
15
+ const BLOCKS_TO_WAIT = 5;
16
+ const ZERO_ATTEMPTS = 0;
17
+ const ONE_ATTEMPT = 1;
18
+ const lock = new semaphore_async_await_1.default(MAX_CONCURRENCY);
19
+ class EtherscanVerifier extends contractVerifier_1.ContractVerifier {
20
+ constructor(apiKey, chainId) {
21
+ super();
22
+ this.name = "Etherscan";
23
+ this.etherscan = new etherscan_1.Etherscan(apiKey,
24
+ // API url is set automatically because chainId is provided
25
+ "", "https://etherscan.io", Number(chainId));
26
+ }
27
+ static async isChainSupported(chainId) {
28
+ const supportedChains = await EtherscanVerifier.loadEtherscanSupportedChains();
29
+ return supportedChains.some(config => config.chainId === Number(chainId));
30
+ }
31
+ // Protected
32
+ async isAlreadyVerified(verificationTarget) {
33
+ return await this.etherscan.isVerified(verificationTarget.contractAddress);
34
+ }
35
+ async submitVerificationRequest(target, params, retries = DEFAULT_RETRIES_AMOUNT) {
36
+ try {
37
+ await lock.acquire();
38
+ return await this.etherscan.verify(target.contractAddress, params.solcInputJson, params.fullContractName, params.compilerVersion, "");
39
+ }
40
+ catch (error) {
41
+ if (error instanceof Error && error.name === 'ContractVerificationMissingBytecodeError') {
42
+ lock.release();
43
+ return await this.processContractVerificationMissingBytecodeError(error, { params, target }, retries);
44
+ }
45
+ throw error;
46
+ }
47
+ finally {
48
+ lock.release();
49
+ }
50
+ }
51
+ getContractUrl(verificationTarget) {
52
+ return this.etherscan.getContractUrl(verificationTarget.contractAddress);
53
+ }
54
+ async getVerifyParameters(contractName) {
55
+ const parameters = await super.getVerifyParameters(contractName);
56
+ return { ...parameters, compilerVersion: `v${parameters.compilerVersion}` };
57
+ }
58
+ // Private
59
+ static async loadEtherscanSupportedChains() {
60
+ await lock.acquire();
61
+ try {
62
+ const resp = await fetch("https://api.etherscan.io/v2/chainlist");
63
+ if (!resp.ok) {
64
+ throw new Error(`Etherscan API error: ${resp.status} ${resp.statusText}`);
65
+ }
66
+ const data = await resp.json();
67
+ return data.result.map((element) => ({
68
+ chainId: parseInt(element.chainid, 10),
69
+ network: element.chainname,
70
+ urls: {
71
+ apiURL: element.apiurl,
72
+ browserURL: element.blockexplorer
73
+ }
74
+ }));
75
+ }
76
+ finally {
77
+ lock.release();
78
+ }
79
+ }
80
+ async processContractVerificationMissingBytecodeError(error, data, retries) {
81
+ if (retries > ZERO_ATTEMPTS) {
82
+ console.log(chalk_1.default.gray(error.message));
83
+ console.log(chalk_1.default.gray(`Waiting for ${BLOCKS_TO_WAIT} blocks before retrying...`));
84
+ await EtherscanVerifier.waitForBlocks(BLOCKS_TO_WAIT);
85
+ return this.submitVerificationRequest(data.target, data.params, retries - ONE_ATTEMPT);
86
+ }
87
+ throw error;
88
+ }
89
+ static waitForBlocks(numBlocks) {
90
+ return new Promise((resolve) => {
91
+ hardhat_1.ethers.provider.getBlockNumber().then((currentBlockNumber) => {
92
+ const targetBlock = currentBlockNumber + numBlocks;
93
+ const listener = (blockNumber) => {
94
+ if (blockNumber >= targetBlock) {
95
+ hardhat_1.ethers.provider.removeListener("block", listener);
96
+ resolve();
97
+ }
98
+ };
99
+ hardhat_1.ethers.provider.on("block", listener);
100
+ });
101
+ });
102
+ }
103
+ }
104
+ exports.EtherscanVerifier = EtherscanVerifier;
105
+ //# sourceMappingURL=etherscanVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"etherscanVerifier.js","sourceRoot":"","sources":["../../../src/verifiers/etherscanVerifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { BlockscoutVerifier } from "./blockscoutVerifier";
2
+ export declare class SkaleBlockscoutVerifier extends BlockscoutVerifier {
3
+ name: string;
4
+ static createFromEndpoint(endpoint: string): Promise<SkaleBlockscoutVerifier | null>;
5
+ private static parseEndpoint;
6
+ private static pingExplorer;
7
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ // Cspell:words skalenodes
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.SkaleBlockscoutVerifier = void 0;
5
+ const blockscoutVerifier_1 = require("./blockscoutVerifier");
6
+ const BASE_EXPLORER_URLS = {
7
+ legacy: "legacy-explorer.skalenodes.com",
8
+ mainnet: "explorer.mainnet.skalenodes.com",
9
+ testnet: "explorer.testnet.skalenodes.com"
10
+ };
11
+ class SkaleBlockscoutVerifier extends blockscoutVerifier_1.BlockscoutVerifier {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.name = "SKALE Blockscout";
15
+ }
16
+ static async createFromEndpoint(endpoint) {
17
+ const { schainName, networkType } = SkaleBlockscoutVerifier.parseEndpoint(endpoint);
18
+ const browserURL = `https://${schainName}.${BASE_EXPLORER_URLS[networkType]}`;
19
+ const apiURL = `${browserURL}/api`;
20
+ if (!await SkaleBlockscoutVerifier.pingExplorer(browserURL)) {
21
+ throw new Error(`SKALE block explorer (${browserURL}) is not reachable, set EXPLORER_URL`);
22
+ }
23
+ return new SkaleBlockscoutVerifier(apiURL, browserURL);
24
+ }
25
+ // Private
26
+ static parseEndpoint(endpoint) {
27
+ const { host, pathname } = new URL(endpoint);
28
+ const schainName = pathname.split("/").filter(Boolean).pop();
29
+ let networkType = "mainnet";
30
+ if (host.includes("mainnet.")) {
31
+ networkType = "mainnet";
32
+ }
33
+ else if (host.includes("testnet.")) {
34
+ networkType = "testnet";
35
+ }
36
+ else if (host.includes("legacy-proxy.")) {
37
+ networkType = "legacy";
38
+ }
39
+ else {
40
+ throw new Error(`The chain is not supported by SKALE block explorer or unknown network in ENDPOINT: ${endpoint}`);
41
+ }
42
+ return { networkType, schainName };
43
+ }
44
+ static async pingExplorer(baseUrl) {
45
+ const url = `${baseUrl}/api/health`;
46
+ try {
47
+ const res = await fetch(url);
48
+ if (!res.ok) {
49
+ return false;
50
+ }
51
+ const jsonResponse = await res.json();
52
+ return jsonResponse.healthy;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ }
59
+ exports.SkaleBlockscoutVerifier = SkaleBlockscoutVerifier;
60
+ //# sourceMappingURL=skaleBlockscoutVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skaleBlockscoutVerifier.js","sourceRoot":"","sources":["../../../src/verifiers/skaleBlockscoutVerifier.ts"],"names":[],"mappings":";AAAA,0BAA0B;;;AAE1B,6DAAwD;AAExD,MAAM,kBAAkB,GAAG;IACvB,MAAM,EAAE,gCAAgC;IACxC,OAAO,EAAE,iCAAiC;IAC1C,OAAO,EAAE,iCAAiC;CAC7C,CAAC;AAEF,MAAa,uBAAwB,SAAQ,uCAAkB;IAA/D;;QACW,SAAI,GAAG,kBAAkB,CAAC;IA6CrC,CAAC;IA3CU,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAgB;QACnD,MAAM,EAAC,UAAU,EAAE,WAAW,EAAC,GAAG,uBAAuB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAClF,MAAM,UAAU,GAAG,WAAW,UAAU,IAAI,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,GAAG,UAAU,MAAM,CAAC;QACnC,IAAI,CAAC,MAAM,uBAAuB,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,sCAAsC,CAAC,CAAC;QAC/F,CAAC;QACD,OAAO,IAAI,uBAAuB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC;IAED,UAAU;IAEF,MAAM,CAAC,aAAa,CAAC,QAAgB;QACzC,MAAM,EAAC,IAAI,EAAE,QAAQ,EAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAG,CAAC;QAE9D,IAAI,WAAW,GAAoC,SAAS,CAAC;QAC7D,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,WAAW,GAAG,SAAS,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,WAAW,GAAG,SAAS,CAAC;QAC5B,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACxC,WAAW,GAAG,QAAQ,CAAC;QAC3B,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,KAAK,CACX,sFAAsF,QAAQ,EAAE,CAAC,CAAC;QAC1G,CAAC;QACD,OAAO,EAAC,WAAW,EAAE,UAAU,EAAC,CAAC;IACrC,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,YAAY,CAAE,OAAe;QAC9C,MAAM,GAAG,GAAG,GAAG,OAAO,aAAa,CAAC;QACpC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO,YAAY,CAAC,OAAO,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;CACJ;AA9CD,0DA8CC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skalenetwork/upgrade-tools",
3
- "version": "4.0.0-update-verify.6",
3
+ "version": "4.0.0-verification.1",
4
4
  "description": "Scripts to support upgrades of smart contracts",
5
5
  "files": [
6
6
  "dist/**/*"