UNPKG

@enjinstarter/hardhat-oklink-verify

Version:
244 lines (243 loc) 9.94 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OklinkResponse = exports.verifyContract = exports.delay = void 0; const buffer_1 = require("buffer"); const path_1 = __importDefault(require("path")); const plugins_1 = require("hardhat/plugins"); const undici_1 = require("undici"); const constants_1 = require("../constants"); async function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } exports.delay = delay; async function verifyContract(url, req) { const { request } = await Promise.resolve().then(() => __importStar(require("undici"))); const method = "POST"; let licenseType = "UNLICENSED"; if (req.sources[req.sourceName] !== undefined) { const matches = req.sources[req.sourceName].content.match(/^\/\/\s+SPDX-License-Identifier:\s+([A-Za-z0-9.-]+)$/im); /* if (matches !== null) { console.log(`matches.length: ${matches.length}`); for (let i = 0; i < matches.length; i++) { console.log(`matches[${i}]: ${matches[i]}`); } } */ if (matches !== null && matches.length > 1) { licenseType = matches[1]; /* console.log( `matches.length=${matches.length}, licenseType=${licenseType}` ); */ } } // console.log(`req.licenseType=${req.licenseType}, licenseType=${licenseType}`); const body = new undici_1.FormData(); for (const [sourceName, _source] of Object.entries(req.sources)) { /* console.log( `files: sourceName=${sourceName}, basename=${path.posix.basename( sourceName )}, content=${req.sources[sourceName].content}` ); */ const contentImportAddCurrentDirectory = req.sources[sourceName].content .replace(/^import\s+"\//gm, 'import "./') .replace(/^import\s+"(?!\.\/)/gm, 'import "./'); /* console.log( `files: contentImportAddCurrentDirectory=${contentImportAddCurrentDirectory}` ); */ body.append("files", new buffer_1.Blob([contentImportAddCurrentDirectory]), path_1.default.posix.basename(sourceName)); } /* console.log(`url: ${url}`); console.log(`apkKey: ${req.apiKey}`); console.log(`sourceName: ${req.sourceName}`); console.log(`contractAddress: ${req.contractAddress}`); console.log(`compilerVersion: ${req.compilerVersion}`); console.log(`evmVersion: ${req.evmVersion}`); console.log( `optimization: ${ req.optimization === undefined ? "N.A." : req.optimization.toString() }` ); console.log( `optimizationRuns: ${ req.optimizationRuns === undefined ? "N.A." : req.optimizationRuns.toString() }` ); console.log( `licenseType: ${ req.licenseType === null || req.licenseType.trim() === "" ? licenseType : req.licenseType }` ); console.log(`contractAbi: ${req.contractAbi}`); console.log(`compilerType: ${req.compilerType}`); */ body.set("contractAddress", req.contractAddress); body.set("compilerVersion", req.compilerVersion); body.set("evmVersion", req.evmVersion); if (req.optimization !== undefined) { body.set("optimization", req.optimization); } if (req.optimizationRuns !== undefined) { body.set("optimizationRuns", req.optimizationRuns); } body.set("licenseType", req.licenseType === null || req.licenseType.trim() === "" ? licenseType : req.licenseType); body.set("contractAbi", req.contractAbi); if (req.libraryList !== undefined) { // console.log(`req.libraryList: ${JSON.stringify(req.libraryList)}`); const libraryList = []; for (const [_libraryFileName, libraryInfo] of Object.entries(req.libraryList)) { for (const [libraryName, libraryAddress] of Object.entries(libraryInfo)) { /* console.log( `libraryList[]: libraryName=${libraryName}, libraryAddress=${libraryAddress}` ); */ libraryList.push({ address: libraryAddress, name: libraryName }); } } if (libraryList.length > 0) { // console.log(`libraryList: ${JSON.stringify(libraryList)}`); body.set("libraryList", JSON.stringify(libraryList)); } } body.set("compilerType", req.compilerType); const requestDetails = { method, headers: { "x-apiKey": req.apiKey }, body, }; let response; try { response = await request(url, requestDetails); } catch (error) { throw new plugins_1.NomicLabsHardhatPluginError(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 OKLink API. const responseText = await response.body.text(); throw new plugins_1.NomicLabsHardhatPluginError(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 responseBody = await response.body.json(); // console.log(`response: ${JSON.stringify(responseBody)}`); const oklinkResponse = new OklinkResponse(responseBody); if (oklinkResponse.isBytecodeMissingInNetworkError()) { throw new plugins_1.NomicLabsHardhatPluginError(constants_1.pluginName, `Failed to send contract verification request. Endpoint URL: ${url} Reason: The OKLink 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 (!oklinkResponse.isOk()) { throw new plugins_1.NomicLabsHardhatPluginError(constants_1.pluginName, `The OKLink API responded with a failure status. The verification may still succeed but should be checked manually. Reason: ${oklinkResponse.errorType}`); } return oklinkResponse; } exports.verifyContract = verifyContract; class OklinkResponse { // public readonly contractErrorCodeList?: string; // public readonly errorLibrary?: string; constructor(response) { this.code = response.code; this.msg = response.msg; this.detailMsg = response.detailMsg; this.isSuccess = response.data.isSuccess; if (response.data.contractAddress !== undefined) { this.contractAddress = response.data.contractAddress; } if (response.data.contractCreateTxHash !== undefined) { this.contractCreateTxHash = response.data.contractCreateTxHash; } if (response.data.compilerVersion !== undefined) { this.compilerVersion = response.data.compilerVersion; } if (response.data.optimization !== undefined) { this.optimization = response.data.optimization; } if (response.data.optimizationRuns !== undefined) { this.optimizationRuns = response.data.optimizationRuns; } this.errorType = response.data.errorType === undefined ? response.data.isSuccess === true ? "" : "OKLINK_UNKNOWN_ERROR" : response.data.errorType; if (response.data.statusCode !== undefined) { this.statusCode = response.data.statusCode; } if (response.data.compileErrorMessage !== undefined) { this.compileErrorMessage = response.data.compileErrorMessage; } if (response.data.contractCreationCode !== undefined) { this.contractCreationCode = response.data.contractCreationCode; } /* if (response.data.contractErrorCodeList !== undefined) { this.contractErrorCodeList = response.data.contractErrorCodeList; } if (response.data.errorLibrary !== undefined) { this.errorLibrary = response.data.errorLibrary; } */ } isPending() { return false; } isVerificationFailure() { return this.isSuccess !== true; } isVerificationSuccess() { return this.isSuccess === true; } isBytecodeMissingInNetworkError() { return false; } isOk() { return true; } } exports.OklinkResponse = OklinkResponse; //# sourceMappingURL=OklinkService.js.map