@solarity/hardhat-migrate
Version:
The simplest way to deploy smart contracts
219 lines • 12.5 kB
JavaScript
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
import { ethers } from "ethers";
import { verifyContract } from "@nomicfoundation/hardhat-verify/verify";
import { CatchMethodError, getChainId, getPossibleImplementationAddress, sleep, SuppressLogs } from "../utils/index.js";
import { buildNetworkDeps } from "../tools/network/NetworkManager.js";
import { createAndInitReporter, Reporter } from "../tools/reporters/Reporter.js";
import { callEtherscanApi, RESPONSE_OK } from "../tools/network/etherscan-api.js";
let Verifier = (() => {
let _instanceExtraInitializers = [];
let _verifyBatch_decorators;
let __verify_decorators;
let __tryVerify_decorators;
let __tryVerifyWithProvider_decorators;
let __handleVerificationError_decorators;
return class Verifier {
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
_verifyBatch_decorators = [CatchMethodError];
__verify_decorators = [CatchMethodError];
__tryVerify_decorators = [CatchMethodError];
__tryVerifyWithProvider_decorators = [SuppressLogs];
__handleVerificationError_decorators = [CatchMethodError];
__esDecorate(this, null, _verifyBatch_decorators, { kind: "method", name: "verifyBatch", static: false, private: false, access: { has: obj => "verifyBatch" in obj, get: obj => obj.verifyBatch }, metadata: _metadata }, null, _instanceExtraInitializers);
__esDecorate(this, null, __verify_decorators, { kind: "method", name: "_verify", static: false, private: false, access: { has: obj => "_verify" in obj, get: obj => obj._verify }, metadata: _metadata }, null, _instanceExtraInitializers);
__esDecorate(this, null, __tryVerify_decorators, { kind: "method", name: "_tryVerify", static: false, private: false, access: { has: obj => "_tryVerify" in obj, get: obj => obj._tryVerify }, metadata: _metadata }, null, _instanceExtraInitializers);
__esDecorate(this, null, __tryVerifyWithProvider_decorators, { kind: "method", name: "_tryVerifyWithProvider", static: false, private: false, access: { has: obj => "_tryVerifyWithProvider" in obj, get: obj => obj._tryVerifyWithProvider }, metadata: _metadata }, null, _instanceExtraInitializers);
__esDecorate(this, null, __handleVerificationError_decorators, { kind: "method", name: "_handleVerificationError", static: false, private: false, access: { has: obj => "_handleVerificationError" in obj, get: obj => obj._handleVerificationError }, metadata: _metadata }, null, _instanceExtraInitializers);
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
}
_hre = __runInitializers(this, _instanceExtraInitializers);
_config;
_standalone;
constructor(_hre, _config, _standalone = false) {
this._hre = _hre;
this._config = _config;
this._standalone = _standalone;
}
async verifyBatch(verifierBatchArgs) {
const currentChainId = Number(await getChainId());
const toVerify = verifierBatchArgs.filter((args) => args.chainId && currentChainId == args.chainId);
if (!toVerify || toVerify.length === 0) {
Reporter.reportNothingToVerify();
return;
}
const verificationDelay = this._hre.config.migrate.verification.verificationDelay;
if (verificationDelay > 0 && !this._standalone) {
await Reporter.startSpinner("verification-delay", () => "Waiting for the explorer to sync up");
await sleep(verificationDelay);
Reporter.stopSpinner();
}
Reporter.reportVerificationBatchBegin();
const parallel = this._config.parallel;
for (let i = 0; i < toVerify.length; i += parallel) {
const batch = toVerify.slice(i, i + parallel);
await Promise.all(batch.map((args) => this._verify(args)));
}
}
async _verify(verifierArgs) {
const { contractAddress, contractName, constructorArguments } = verifierArgs;
for (let attempts = 0; attempts < this._config.attempts; attempts++) {
try {
await this._tryVerify(contractAddress, contractName, constructorArguments);
break;
}
catch (e) {
this._handleVerificationError(contractAddress, contractName, e);
if (e.message !== undefined &&
typeof e.message === "string" &&
(e.message.includes("HH303: Unrecognized task 'verify:verify'") || e.message.includes("already verified"))) {
break;
}
}
await sleep(2500);
}
}
async _tryVerify(contractAddress, contractName, constructorArguments) {
const verified = (await this._tryVerifyWithProvider("etherscan", contractAddress, contractName, constructorArguments)) ||
(await this._tryVerifyWithProvider("blockscout", contractAddress, contractName, constructorArguments));
if (verified)
Reporter.reportSuccessfulVerification(contractAddress, contractName);
else
Reporter.reportVerificationError(contractAddress, contractName, "Verification failed");
}
async _tryVerifyWithProvider(provider, contractAddress, contractName, constructorArguments) {
try {
const ok = await verifyContract({
address: contractAddress,
constructorArgs: constructorArguments,
contract: contractName,
force: true,
provider,
}, this._hre);
// In previous versions we linked proxy ABI on Etherscan. Skip for Blockscout.
if (ok && provider === "etherscan") {
// Best-effort proxy linking; ignore failures.
await this._verifyProxy(contractAddress).catch(() => { });
}
return ok;
}
catch (e) {
// Fallback when provider isn't configured or unsupported; let caller try the next provider.
const msg = (e?.message ?? "").toString().toLowerCase();
const isProviderConfigError = msg.includes("block explorer not configured") ||
msg.includes("explorer_request") ||
msg.includes("invalid verification provider");
if (isProviderConfigError)
return false;
throw e;
}
}
_handleVerificationError(contractAddress, contractName, error) {
if (error.message.toLowerCase().includes("already verified")) {
Reporter.reportAlreadyVerified(contractAddress, contractName);
return;
}
else {
Reporter.reportVerificationError(contractAddress, contractName, error.message);
}
}
async _verifyProxy(proxyAddress) {
try {
const implementationAddress = await getPossibleImplementationAddress(proxyAddress);
if (implementationAddress === ethers.ZeroAddress) {
return;
}
await this._linkProxyWithImplementationAbi(proxyAddress, implementationAddress);
}
catch (e) {
/* empty */
}
}
/**
* Calls the Etherscan API to link a proxy with its implementation ABI.
*
* Source: https://github.com/OpenZeppelin/openzeppelin-upgrades
*/
async _linkProxyWithImplementationAbi(proxyAddress, implAddress) {
const etherscanApiKey =
// New config location (hardhat-verify v3)
(await this._hre.config?.verify?.etherscan?.apiKey?.get?.()) ??
// Legacy config location (fallback)
this._hre.config?.etherscan?.apiKey ??
"";
const etherscanApiUrl = this._hre.config?.verify?.etherscan?.apiUrl ??
// Default public API endpoint
"https://api.etherscan.io/v2/api";
const params = {
module: "contract",
action: "verifyproxycontract",
address: proxyAddress,
expectedimplementation: implAddress,
};
let verifyProxyResponse = await callEtherscanApi({ apiUrl: etherscanApiUrl, apiKey: etherscanApiKey }, params);
if (verifyProxyResponse.status === RESPONSE_OK) {
// initial call was OK, but need to send a status request using the
// returned guid to get the actual verification status
let responseBody = await this._checkProxyVerificationStatus({ apiUrl: etherscanApiUrl, apiKey: etherscanApiKey }, verifyProxyResponse.result);
while (responseBody.result === "Pending in queue") {
await sleep(5000);
responseBody = await this._checkProxyVerificationStatus({ apiUrl: etherscanApiUrl, apiKey: etherscanApiKey }, verifyProxyResponse.result);
}
}
if (verifyProxyResponse.status === RESPONSE_OK) {
Reporter.reportSuccessfulProxyLinking(proxyAddress, implAddress);
}
else {
Reporter.reportFailedProxyLinking(proxyAddress, implAddress, verifyProxyResponse.result);
}
}
async _checkProxyVerificationStatus(instance, guid) {
const checkProxyVerificationParams = {
module: "contract",
action: "checkproxyverification",
apikey: instance.apiKey,
guid: guid,
};
return callEtherscanApi(instance, checkProxyVerificationParams);
}
static async buildVerifierTaskDeps(hre) {
await buildNetworkDeps(hre);
await createAndInitReporter(hre);
}
};
})();
export { Verifier };
//# sourceMappingURL=Verifier.js.map