UNPKG

@nomiclabs/hardhat-etherscan

Version:
122 lines 5.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isAlreadyVerified = exports.EtherscanResponse = exports.getVerificationStatus = exports.verifyContract = exports.delay = void 0; const constants_1 = require("../constants"); const undici_1 = require("../undici"); const errors_1 = require("../errors"); async function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } exports.delay = delay; // Used for polling the result of the contract verification. const verificationIntervalMs = 3000; async function verifyContract(url, req) { const parameters = new URLSearchParams({ ...req }); let response; try { response = await (0, undici_1.sendPostRequest)(new URL(url), parameters.toString()); } catch (error) { throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, `Failed to send contract verification request. Endpoint URL: ${url} Reason: ${error.message}`, error); } if (!(response.statusCode >= 200 && response.statusCode <= 299)) { // This could be always interpreted as JSON if there were any such guarantee in the Etherscan API. const responseText = await response.body.text(); throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, `Failed to send contract verification request. Endpoint URL: ${url} The HTTP server response is not ok. Status code: ${response.statusCode} Response text: ${responseText}`); } const etherscanResponse = new EtherscanResponse(await response.body.json()); if (etherscanResponse.isBytecodeMissingInNetworkError()) { throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, `Failed to send contract verification request. Endpoint URL: ${url} Reason: The Etherscan API responded that the address ${req.contractaddress} does not have bytecode. This can happen if the contract was recently deployed and this fact hasn't propagated to the backend yet. Try waiting for a minute before verifying your contract. If you are invoking this from a script, try to wait for five confirmations of your contract deployment transaction before running the verification subtask.`); } if (!etherscanResponse.isOk()) { throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, etherscanResponse.message); } return etherscanResponse; } exports.verifyContract = verifyContract; async function getVerificationStatus(url, req) { const parameters = new URLSearchParams({ ...req }); const urlWithQuery = new URL(url); urlWithQuery.search = parameters.toString(); let response; try { response = await (0, undici_1.sendGetRequest)(urlWithQuery); if (!(response.statusCode >= 200 && response.statusCode <= 299)) { // This could be always interpreted as JSON if there were any such guarantee in the Etherscan API. const responseText = await response.body.text(); const message = `The HTTP server response is not ok. Status code: ${response.statusCode} Response text: ${responseText}`; throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, message); } } catch (error) { throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, `Failure during etherscan status polling. The verification may still succeed but should be checked manually. Endpoint URL: ${urlWithQuery.toString()} Reason: ${error.message}`, error); } const etherscanResponse = new EtherscanResponse(await response.body.json()); if (etherscanResponse.isPending()) { await delay(verificationIntervalMs); return getVerificationStatus(url, req); } if (etherscanResponse.isVerificationFailure()) { return etherscanResponse; } if (!etherscanResponse.isOk()) { throw new errors_1.HardhatEtherscanPluginError(constants_1.pluginName, `The Etherscan API responded with a failure status. The verification may still succeed but should be checked manually. Reason: ${etherscanResponse.message}`); } return etherscanResponse; } exports.getVerificationStatus = getVerificationStatus; class EtherscanResponse { constructor(response) { this.status = parseInt(response.status, 10); this.message = response.result; } isPending() { return this.message === "Pending in queue"; } isVerificationFailure() { return this.message === "Fail - Unable to verify"; } isVerificationSuccess() { return this.message === "Pass - Verified"; } isBytecodeMissingInNetworkError() { return this.message.startsWith("Unable to locate ContractCode at"); } isOk() { return this.status === 1; } } exports.EtherscanResponse = EtherscanResponse; async function isAlreadyVerified(apiURL, apiKey, address) { const parameters = new URLSearchParams({ module: "contract", action: "getsourcecode", address, apikey: apiKey, }); const url = new URL(apiURL); url.search = parameters.toString(); const response = await (0, undici_1.sendGetRequest)(url); const json = await response.body.json(); if (json.message !== "OK") { return false; } const sourceCode = json?.result?.[0]?.SourceCode; return sourceCode !== undefined && sourceCode !== ""; } exports.isAlreadyVerified = isAlreadyVerified; //# sourceMappingURL=EtherscanService.js.map