@skalenetwork/upgrade-tools 4.0.0-develop.0 → 4.0.0-develop.10
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.
- package/README.md +3 -1
- package/dist/src/contractFactory.js +1 -1
- package/dist/src/contractFactory.js.map +1 -1
- package/dist/src/contractVerifier.d.ts +24 -12
- package/dist/src/contractVerifier.js +47 -43
- package/dist/src/contractVerifier.js.map +1 -1
- package/dist/src/deploy.d.ts +1 -0
- package/dist/src/deploy.js +16 -9
- package/dist/src/deploy.js.map +1 -1
- package/dist/src/gnosis-safe.js +6 -37
- package/dist/src/gnosis-safe.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/ownership-transfer/constants.d.ts +8 -0
- package/dist/src/ownership-transfer/constants.js +33 -0
- package/dist/src/ownership-transfer/constants.js.map +1 -0
- package/dist/src/ownership-transfer/contractAdmin.d.ts +55 -0
- package/dist/src/ownership-transfer/contractAdmin.js +211 -0
- package/dist/src/ownership-transfer/contractAdmin.js.map +1 -0
- package/dist/src/ownership-transfer/instanceAdmin.d.ts +51 -0
- package/dist/src/ownership-transfer/instanceAdmin.js +221 -0
- package/dist/src/ownership-transfer/instanceAdmin.js.map +1 -0
- package/dist/src/ownership-transfer/permission-utils.d.ts +37 -0
- package/dist/src/ownership-transfer/permission-utils.js +191 -0
- package/dist/src/ownership-transfer/permission-utils.js.map +1 -0
- package/dist/src/ownership-transfer/utils.d.ts +19 -0
- package/dist/src/ownership-transfer/utils.js +201 -0
- package/dist/src/ownership-transfer/utils.js.map +1 -0
- package/dist/src/proxyUpgrader.d.ts +19 -0
- package/dist/src/proxyUpgrader.js +89 -0
- package/dist/src/proxyUpgrader.js.map +1 -0
- package/dist/src/submitters/auto-submitter.d.ts +3 -0
- package/dist/src/submitters/auto-submitter.js +11 -2
- package/dist/src/submitters/auto-submitter.js.map +1 -1
- package/dist/src/submitters/eoa-submitter.js +0 -1
- package/dist/src/submitters/eoa-submitter.js.map +1 -1
- package/dist/src/submitters/safe-ima-legacy-marionette-submitter.js +0 -4
- package/dist/src/submitters/safe-ima-legacy-marionette-submitter.js.map +1 -1
- package/dist/src/submitters/safe-ima-marionette-submitter.d.ts +1 -0
- package/dist/src/submitters/safe-ima-marionette-submitter.js +1 -0
- package/dist/src/submitters/safe-ima-marionette-submitter.js.map +1 -1
- package/dist/src/submitters/safe-submitter.d.ts +2 -0
- package/dist/src/submitters/safe-submitter.js +3 -0
- package/dist/src/submitters/safe-submitter.js.map +1 -1
- package/dist/src/submitters/safe-to-ima-submitter.d.ts +1 -0
- package/dist/src/submitters/safe-to-ima-submitter.js +4 -4
- package/dist/src/submitters/safe-to-ima-submitter.js.map +1 -1
- package/dist/src/submitters/submitter.d.ts +3 -1
- package/dist/src/submitters/submitter.js +5 -17
- package/dist/src/submitters/submitter.js.map +1 -1
- package/dist/src/upgrader.d.ts +12 -6
- package/dist/src/upgrader.js +80 -61
- package/dist/src/upgrader.js.map +1 -1
- package/dist/src/upgraders/abstractTransparentProxyUpgrader.d.ts +19 -0
- package/dist/src/upgraders/abstractTransparentProxyUpgrader.js +57 -0
- package/dist/src/upgraders/abstractTransparentProxyUpgrader.js.map +1 -0
- package/dist/src/upgraders/beaconUpgrader.d.ts +8 -0
- package/dist/src/upgraders/beaconUpgrader.js +37 -0
- package/dist/src/upgraders/beaconUpgrader.js.map +1 -0
- package/dist/src/upgraders/transparentProxyUpgrader.d.ts +5 -0
- package/dist/src/upgraders/transparentProxyUpgrader.js +20 -0
- package/dist/src/upgraders/transparentProxyUpgrader.js.map +1 -0
- package/dist/src/upgraders/v4TransparentProxyUpgrader.d.ts +5 -0
- package/dist/src/upgraders/v4TransparentProxyUpgrader.js +19 -0
- package/dist/src/upgraders/v4TransparentProxyUpgrader.js.map +1 -0
- package/dist/src/verification.d.ts +2 -17
- package/dist/src/verification.js +64 -203
- package/dist/src/verification.js.map +1 -1
- package/dist/src/verifiers/blockscoutVerifier.d.ts +11 -0
- package/dist/src/verifiers/blockscoutVerifier.js +85 -0
- package/dist/src/verifiers/blockscoutVerifier.js.map +1 -0
- package/dist/src/verifiers/etherscanVerifier.d.ts +19 -0
- package/dist/src/verifiers/etherscanVerifier.js +105 -0
- package/dist/src/verifiers/etherscanVerifier.js.map +1 -0
- package/dist/src/verifiers/skaleBlockscoutVerifier.d.ts +7 -0
- package/dist/src/verifiers/skaleBlockscoutVerifier.js +60 -0
- package/dist/src/verifiers/skaleBlockscoutVerifier.js.map +1 -0
- package/package.json +6 -6
- package/dist/src/proxyAdmin.d.ts +0 -4
- package/dist/src/proxyAdmin.js +0 -56
- package/dist/src/proxyAdmin.js.map +0 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransparentProxyUpgrader = void 0;
|
|
4
|
+
const abstractTransparentProxyUpgrader_1 = require("./abstractTransparentProxyUpgrader");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const hardhat_1 = require("hardhat");
|
|
7
|
+
class TransparentProxyUpgrader extends abstractTransparentProxyUpgrader_1.AbstractTransparentProxyUpgrader {
|
|
8
|
+
async makeUpgradeTransaction() {
|
|
9
|
+
return ethers_1.Transaction.from({
|
|
10
|
+
"data": this.proxyAdmin.interface.encodeFunctionData("upgradeAndCall", [
|
|
11
|
+
await hardhat_1.ethers.resolveAddress(this.proxyAddress),
|
|
12
|
+
await hardhat_1.ethers.resolveAddress(this.newImplementationAddress),
|
|
13
|
+
"0x"
|
|
14
|
+
]),
|
|
15
|
+
"to": await hardhat_1.ethers.resolveAddress(this.proxyAdmin)
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.TransparentProxyUpgrader = TransparentProxyUpgrader;
|
|
20
|
+
//# sourceMappingURL=transparentProxyUpgrader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transparentProxyUpgrader.js","sourceRoot":"","sources":["../../../src/upgraders/transparentProxyUpgrader.ts"],"names":[],"mappings":";;;AAAA,yFAAoF;AACpF,mCAAmC;AACnC,qCAA+B;AAE/B,MAAa,wBAAyB,SAAQ,mEAAgC;IAChE,KAAK,CAAC,sBAAsB;QAClC,OAAO,oBAAW,CAAC,IAAI,CAAC;YACpB,MAAM,EAAE,IAAI,CAAC,UAAW,CAAC,SAAS,CAAC,kBAAkB,CACjD,gBAAgB,EAChB;gBACI,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;gBAC9C,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,wBAAyB,CAAC;gBAC3D,IAAI;aACP,CACJ;YACD,IAAI,EAAE,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAW,CAAC;SACtD,CAAC,CAAC;IACP,CAAC;CACJ;AAdD,4DAcC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AbstractTransparentProxyUpgrader } from "./abstractTransparentProxyUpgrader";
|
|
2
|
+
import { Transaction } from "ethers";
|
|
3
|
+
export declare class V4TransparentProxyUpgrader extends AbstractTransparentProxyUpgrader {
|
|
4
|
+
protected makeUpgradeTransaction(): Promise<Transaction>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.V4TransparentProxyUpgrader = void 0;
|
|
4
|
+
const abstractTransparentProxyUpgrader_1 = require("./abstractTransparentProxyUpgrader");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const hardhat_1 = require("hardhat");
|
|
7
|
+
class V4TransparentProxyUpgrader extends abstractTransparentProxyUpgrader_1.AbstractTransparentProxyUpgrader {
|
|
8
|
+
async makeUpgradeTransaction() {
|
|
9
|
+
return ethers_1.Transaction.from({
|
|
10
|
+
"data": this.proxyAdmin.interface.encodeFunctionData("upgrade", [
|
|
11
|
+
await hardhat_1.ethers.resolveAddress(this.proxyAddress),
|
|
12
|
+
await hardhat_1.ethers.resolveAddress(this.newImplementationAddress),
|
|
13
|
+
]),
|
|
14
|
+
"to": await hardhat_1.ethers.resolveAddress(this.proxyAdmin)
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.V4TransparentProxyUpgrader = V4TransparentProxyUpgrader;
|
|
19
|
+
//# sourceMappingURL=v4TransparentProxyUpgrader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v4TransparentProxyUpgrader.js","sourceRoot":"","sources":["../../../src/upgraders/v4TransparentProxyUpgrader.ts"],"names":[],"mappings":";;;AAAA,yFAAoF;AACpF,mCAAmC;AACnC,qCAA+B;AAE/B,MAAa,0BAA2B,SAAQ,mEAAgC;IAClE,KAAK,CAAC,sBAAsB;QAClC,OAAO,oBAAW,CAAC,IAAI,CAAC;YACpB,MAAM,EAAE,IAAI,CAAC,UAAW,CAAC,SAAS,CAAC,kBAAkB,CACjD,SAAS,EACT;gBACI,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;gBAC9C,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,wBAAyB,CAAC;aAC9D,CACJ;YACD,IAAI,EAAE,MAAM,gBAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAW,CAAC;SACtD,CAAC,CAAC;IACP,CAAC;CACJ;AAbD,gEAaC"}
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
export declare const verify: (contractName: string, contractAddress: string) => Promise<void>;
|
|
1
|
+
import { AddressLike } from "ethers";
|
|
2
|
+
export declare const verify: (contractName: string, contractAddress: AddressLike, constructorArguments?: string) => Promise<void>;
|
|
18
3
|
export declare const verifyProxy: (contractName: string, proxyAddress: string) => Promise<void>;
|
package/dist/src/verification.js
CHANGED
|
@@ -3,228 +3,89 @@ 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 =
|
|
6
|
+
exports.verifyProxy = exports.verify = void 0;
|
|
7
7
|
const hardhat_1 = require("hardhat");
|
|
8
|
-
const
|
|
8
|
+
const blockscoutVerifier_1 = require("./verifiers/blockscoutVerifier");
|
|
9
|
+
const etherscanVerifier_1 = require("./verifiers/etherscanVerifier");
|
|
9
10
|
const semaphore_async_await_1 = __importDefault(require("semaphore-async-await"));
|
|
11
|
+
const skaleBlockscoutVerifier_1 = require("./verifiers/skaleBlockscoutVerifier");
|
|
10
12
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
13
|
const upgrades_core_1 = require("@openzeppelin/upgrades-core");
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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();
|
|
14
|
+
const setupEtherscan = async (chainId) => {
|
|
15
|
+
if (process.env.ETHERSCAN) {
|
|
16
|
+
if (await etherscanVerifier_1.EtherscanVerifier.isChainSupported(chainId)) {
|
|
17
|
+
return new etherscanVerifier_1.EtherscanVerifier(process.env.ETHERSCAN, chainId);
|
|
46
18
|
}
|
|
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",
|
|
83
|
-
}
|
|
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";
|
|
19
|
+
console.log(chalk_1.default.gray(`Etherscan does not support chainId ${chainId}. Skipping verification on Etherscan.`));
|
|
112
20
|
}
|
|
113
21
|
else {
|
|
114
|
-
|
|
22
|
+
console.log(chalk_1.default.yellow(`No etherscan API key provided. Skipping verification on Etherscan.`));
|
|
115
23
|
}
|
|
116
|
-
return
|
|
24
|
+
return null;
|
|
117
25
|
};
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
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`);
|
|
26
|
+
const setupBlockscout = (chainId) => {
|
|
27
|
+
const verifier = blockscoutVerifier_1.BlockscoutVerifier.createFromChainId(chainId);
|
|
28
|
+
if (verifier) {
|
|
29
|
+
return verifier;
|
|
127
30
|
}
|
|
128
|
-
|
|
129
|
-
};
|
|
130
|
-
const getExplorerUrls = async (chainConfig) => {
|
|
31
|
+
console.log(chalk_1.default.gray(`Blockscout API url is not known for chainId ${chainId}.`));
|
|
131
32
|
if (process.env.EXPLORER_URL) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
33
|
+
console.log(chalk_1.default.gray("Using EXPLORER_URL to setup verification."));
|
|
34
|
+
return new blockscoutVerifier_1.BlockscoutVerifier(`${process.env.EXPLORER_URL}/api`, process.env.EXPLORER_URL);
|
|
35
|
+
}
|
|
36
|
+
console.log(chalk_1.default.gray("Skipping verification on Blockscout."));
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
const setupSkale = async () => {
|
|
40
|
+
if (process.env.ENDPOINT) {
|
|
41
|
+
try {
|
|
42
|
+
const verifier = await skaleBlockscoutVerifier_1.SkaleBlockscoutVerifier.createFromEndpoint(process.env.ENDPOINT);
|
|
43
|
+
if (verifier) {
|
|
44
|
+
return verifier;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.log(chalk_1.default.yellow(error));
|
|
49
|
+
}
|
|
136
50
|
}
|
|
137
|
-
|
|
138
|
-
|
|
51
|
+
else {
|
|
52
|
+
console.log(chalk_1.default.gray("ENDPOINT is not provided. Can't determine SKALE block explorer API url."));
|
|
139
53
|
}
|
|
140
|
-
|
|
54
|
+
console.log(chalk_1.default.gray("Skipping verification on SKALE block explorer."));
|
|
55
|
+
return null;
|
|
141
56
|
};
|
|
142
|
-
const
|
|
143
|
-
|
|
57
|
+
const verifiers = [];
|
|
58
|
+
let verifiersSetup = false;
|
|
59
|
+
// Semaphore to limit concurrent creation of verifiers
|
|
60
|
+
const MAX_CONCURRENCY = 1;
|
|
61
|
+
const lock = new semaphore_async_await_1.default(MAX_CONCURRENCY);
|
|
62
|
+
const setupVerifiers = async () => {
|
|
144
63
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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);
|
|
64
|
+
await lock.acquire();
|
|
65
|
+
if (!verifiersSetup) {
|
|
66
|
+
verifiersSetup = true;
|
|
67
|
+
const { chainId } = await hardhat_1.ethers.provider.getNetwork();
|
|
68
|
+
const candidates = [
|
|
69
|
+
await setupEtherscan(chainId),
|
|
70
|
+
setupBlockscout(chainId),
|
|
71
|
+
await setupSkale()
|
|
72
|
+
];
|
|
73
|
+
verifiers.push(...candidates.filter(item => item !== null));
|
|
181
74
|
}
|
|
182
75
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (!process.env.ETHERSCAN) {
|
|
186
|
-
console.log(chalk_1.default.yellow(`No etherscan API key provided. Skipping verification for ${contractName}.`));
|
|
187
|
-
return;
|
|
76
|
+
finally {
|
|
77
|
+
lock.release();
|
|
188
78
|
}
|
|
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);
|
|
197
79
|
};
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
await
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const explorerUrls = await getExplorerUrls();
|
|
208
|
-
await verifyWithRetry({
|
|
209
|
-
contractAddress,
|
|
210
|
-
contractName,
|
|
211
|
-
explorerUrls
|
|
212
|
-
}, RETRIES_AMOUNT);
|
|
213
|
-
};
|
|
214
|
-
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
|
-
}
|
|
80
|
+
const verify = async (contractName, contractAddress, constructorArguments) => {
|
|
81
|
+
await setupVerifiers();
|
|
82
|
+
const contractAddressString = await hardhat_1.ethers.resolveAddress(contractAddress);
|
|
83
|
+
// Try all, don't fail if one fails
|
|
84
|
+
await Promise.allSettled(verifiers.map(verifier => verifier.verify({
|
|
85
|
+
constructorArguments,
|
|
86
|
+
contractAddress: contractAddressString,
|
|
87
|
+
contractName
|
|
88
|
+
})));
|
|
228
89
|
};
|
|
229
90
|
exports.verify = verify;
|
|
230
91
|
const verifyProxy = async (contractName, proxyAddress) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/verification.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
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,85 @@
|
|
|
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
|
+
chainId: 8453,
|
|
42
|
+
network: "base",
|
|
43
|
+
urls: {
|
|
44
|
+
apiURL: "https://base.blockscout.com/api",
|
|
45
|
+
browserURL: "https://base.blockscout.com",
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
chainId: 84532,
|
|
50
|
+
network: "base-sepolia",
|
|
51
|
+
urls: {
|
|
52
|
+
apiURL: "https://base-sepolia.blockscout.com/api",
|
|
53
|
+
browserURL: "https://base-sepolia.blockscout.com",
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
class BlockscoutVerifier extends contractVerifier_1.ContractVerifier {
|
|
58
|
+
constructor(apiURL, browserURL) {
|
|
59
|
+
super();
|
|
60
|
+
this.name = "Blockscout";
|
|
61
|
+
this.blockscout = new blockscout_1.Blockscout(apiURL, browserURL);
|
|
62
|
+
}
|
|
63
|
+
static createFromChainId(chainId) {
|
|
64
|
+
const config = BLOCKSCOUT_CHAINS.find(chain => chain.chainId === Number(chainId));
|
|
65
|
+
if (config) {
|
|
66
|
+
return new BlockscoutVerifier(config.urls.apiURL, config.urls.browserURL);
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
async isAlreadyVerified(verificationTarget) {
|
|
71
|
+
return await this.blockscout.isVerified(verificationTarget.contractAddress);
|
|
72
|
+
}
|
|
73
|
+
async submitVerificationRequest(target, params) {
|
|
74
|
+
if (target.constructorArguments) {
|
|
75
|
+
// TODO: remove this when Blockscout supports constructor arguments
|
|
76
|
+
console.log(`Ignoring constructor arguments for Blockscout verification of ${target.contractAddress}`);
|
|
77
|
+
}
|
|
78
|
+
return await this.blockscout.verify(target.contractAddress, params.solcInputJson, params.fullContractName, params.compilerVersion);
|
|
79
|
+
}
|
|
80
|
+
getContractUrl(verificationTarget) {
|
|
81
|
+
return this.blockscout.getContractUrl(verificationTarget.contractAddress);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.BlockscoutVerifier = BlockscoutVerifier;
|
|
85
|
+
//# 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;IACD;QACI,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,MAAM;QACf,IAAI,EAAE;YACF,MAAM,EAAE,iCAAiC;YACzC,UAAU,EAAE,6BAA6B;SAC5C;KACJ;IACD;QACI,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,cAAc;QACvB,IAAI,EAAE;YACF,MAAM,EAAE,yCAAyC;YACjD,UAAU,EAAE,qCAAqC;SACpD;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,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAC9B,mEAAmE;YACnE,OAAO,CAAC,GAAG,CAAC,iEAAiE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,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;AArCD,gDAqCC"}
|
|
@@ -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, target.constructorArguments || "");
|
|
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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"}
|