UNPKG

@tenderly/hardhat-integration

Version:

Hardhat plugin for integration with Tenderly

259 lines 10.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TenderlyNetwork = void 0; const axios = __importStar(require("axios")); const api_client_1 = require("@tenderly/api-client"); const config_1 = require("@tenderly/api-client/utils/config"); const constants_1 = require("@tenderly/api-client/common/constants"); const log_compliance_1 = require("@tenderly/api-client/utils/log-compliance"); const constants_2 = require("./constants"); const errors_1 = require("./tenderly/errors"); const util_1 = require("./utils/util"); const logger_1 = require("./utils/logger"); class TenderlyNetwork { constructor(hre) { this.tenderlyService = new api_client_1.TenderlyService(constants_2.PLUGIN_NAME); logger_1.logger.debug("Making an interface towards tenderly network."); this.env = hre; this.connected = true; const tdlyGlobalConfig = (0, config_1.getConfig)(); this.accessKey = tdlyGlobalConfig?.access_key; this.tenderlyJsonRpc = this._configureTenderlyRPCInstance(); this.host = this.tenderlyJsonRpc.defaults.baseURL; if ((0, util_1.isTenderlyNetworkConfig)(hre.network.config) && "url" in hre.network.config && hre.network.config.url !== undefined) { if (hre.network.config.url.includes("devnet")) { this.devnetID = hre.network.config.url.split("/").pop(); logger_1.logger.info("Devnet ID is:", this.devnetID); } else { this.forkID = hre.network.config.url.split("/").pop(); logger_1.logger.info("Fork ID is:", this.forkID); } } } supportsSubscriptions() { if (!this._checkNetwork()) { return; } return false; } disconnect() { if (!this._checkNetwork()) { return; } return true; } async send(payload, cb) { if (!this._checkNetwork()) { return; } if (this.head === undefined) { await this.initializeFork(); } try { if (this.head !== undefined) { this.tenderlyJsonRpc.defaults.headers.common.Head = this.head; } const resp = await this.tenderlyJsonRpc.post("", payload); this.head = resp.headers.head; this._writeHead(); cb(null, resp.data); } catch (err) { cb(err.response.data); } } resetFork() { const tdlyGlobalConfig = (0, config_1.getConfig)(); const oldHead = tdlyGlobalConfig.head; delete tdlyGlobalConfig.head; delete tdlyGlobalConfig.fork; (0, config_1.writeConfig)(tdlyGlobalConfig); return oldHead; } async verify(requestData) { logger_1.logger.info("Invoked verification."); if (!this._checkNetwork()) { return; } if (this.devnetID !== undefined) { await this.tenderlyService.verifyDevnetContractsMultiCompiler(requestData, this.env.config.tenderly.project, this.env.config.tenderly.username, this.devnetID, this.env.config.tenderly.accessKey); return; } if (this.head === undefined && this.forkID === undefined) { logger_1.logger.warn("Head or fork are not initialized."); await this.initializeFork(); } await this.tenderlyService.verifyForkContractsMultiCompiler(requestData, this.env.config.tenderly.project, this.env.config.tenderly.username, this.forkID); } async verifyMultiCompilerAPI(request, tenderlyProject, username, forkID) { logger_1.logger.info("Invoked fork verification via API."); await this.tenderlyService.verifyForkContractsMultiCompiler(request, tenderlyProject, username, forkID); } async verifyDevnetMultiCompilerAPI(request, tenderlyProject, username, devnetID) { logger_1.logger.info("Invoked devnet verification via API."); await this.tenderlyService.verifyDevnetContractsMultiCompiler(request, tenderlyProject, username, devnetID); } async verifyAPI(request, tenderlyProject, username, forkID) { logger_1.logger.info("Invoked fork verification via API."); await this.tenderlyService.verifyForkContracts(request, tenderlyProject, username, forkID); } getHead() { if (!this._checkNetwork()) { return; } return this.head; } setHead(head) { if (!this._checkNetwork()) { return; } this.head = head; } async getForkID() { if (!this._checkNetwork()) { return; } return this.forkID; } setFork(fork) { if (!this._checkNetwork()) { return; } this.forkID = fork; } async initializeFork() { logger_1.logger.debug("Initializing tenderly fork."); if (!this._checkNetwork()) { return; } if (this.env.config.tenderly?.forkNetwork === undefined) { logger_1.logger.error("There is no information about the fork network. Fork won't be initialized"); return; } const username = this.env.config.tenderly.username; const projectID = this.env.config.tenderly.project; logger_1.logger.trace("ProjectID obtained from tenderly configuration:", { projectID, }); try { const resp = await this.tenderlyJsonRpc.post(`/account/${username}/project/${projectID}/fork`, { network_id: this.env.config.tenderly.forkNetwork, }); const logCompliantInitializeForkResponse = (0, log_compliance_1.convertToLogCompliantForkInitializeResponse)(resp); logger_1.logger.trace("Initialized fork:", logCompliantInitializeForkResponse); this.head = resp.data.root_transaction.id; this.accounts = resp.data.simulation_fork.accounts; this.forkID = resp.data.simulation_fork.id; logger_1.logger.debug("Successfully initialized tenderly fork."); } catch (err) { logger_1.logger.error("Error was caught while calling fork initialization:", err); throw err; } } setDevnetID(devnetID) { if (!this._checkNetwork()) { return; } this.devnetID = devnetID; } _writeHead() { const tdlyGlobalConfig = (0, config_1.getConfig)(); tdlyGlobalConfig.head = this.head; (0, config_1.writeConfig)(tdlyGlobalConfig); } async _filterContracts(flatContracts) { logger_1.logger.info("Processing data needed for fork verification."); let contract; let requestData; try { requestData = await this._getForkContractData(flatContracts); logger_1.logger.silly("Obtained request data needed for fork verification:", requestData); } catch (e) { logger_1.logger.error("Caught and error while trying to obtain data needed for fork verification", e); return null; } for (contract of flatContracts) { const index = requestData.contracts.findIndex((requestContract) => requestContract.contractName === contract.name); if (index === -1) { logger_1.logger.error(`Couldn't find a contract '${contract.name}' among the obtained request data.`); continue; } logger_1.logger.trace("Currently processing contract:", contract.name); requestData.contracts[index].networks = { [this.forkID]: { address: contract.address, links: contract.libraries, }, }; logger_1.logger.trace(`Contract ${contract.name} has been processed,`); } return requestData; } async _getForkContractData(flatContracts) { logger_1.logger.trace("Getting contract data needed for fork verification."); const contracts = await (0, util_1.getContracts)(this.env, flatContracts); if (contracts.length === 0) { throw new Error("Fork verification failed due to bad processing of data in /artifacts folder."); } const solcConfig = (0, util_1.getCompilerDataFromContracts)(contracts, flatContracts, this.env.config); if (solcConfig === undefined) { logger_1.logger.error(errors_1.NO_COMPILER_FOUND_FOR_CONTRACT_ERR_MSG); } return { contracts, config: solcConfig, root: this.head, }; } _checkNetwork() { if (!(0, util_1.isTenderlyNetworkConfig)(this.env.network.config)) { logger_1.logger.error(`Warning in ${constants_2.PLUGIN_NAME}: Network is not set to 'tenderly'. Please call the task again with --network tenderly`); return false; } return true; } /** * Note: _configureTenderlyRPCInstance needs to be deleted this is only a temporary solution. * @deprecated */ _configureTenderlyRPCInstance() { const tdlyConfig = (0, config_1.getConfig)(); return axios.default.create({ baseURL: constants_1.TENDERLY_JSON_RPC_BASE_URL, headers: { "x-access-key": tdlyConfig.access_key, Head: tdlyConfig.head !== undefined ? tdlyConfig.head : "", }, }); } } exports.TenderlyNetwork = TenderlyNetwork; //# sourceMappingURL=TenderlyNetwork.js.map