UNPKG

@nomicfoundation/hardhat-verify

Version:
260 lines (239 loc) 8.06 kB
import type { BaseVerifyFunctionArgs } from "./types.js"; export interface EtherscanResponseBody { status: string; message: string; result: any; } export type EtherscanGetSourceCodeResponse = | EtherscanNotOkResponse | EtherscanGetSourceCodeOkResponse; interface EtherscanGetSourceCodeOkResponse extends EtherscanResponseBody { status: "1"; message: "OK"; result: EtherscanContract[]; } // TODO: maybe we don't need the complete contract interface // and we can just use the SourceCode property interface EtherscanContract { SourceCode: string; ABI: string; ContractName: string; CompilerVersion: string; OptimizationUsed: string; Runs: string; ConstructorArguments: string; EVMVersion: string; Library: string; LicenseType: string; Proxy: string; Implementation: string; SwarmSource: string; SimilarMatch: string; } export type EtherscanResponse = EtherscanNotOkResponse | EtherscanOkResponse; interface EtherscanNotOkResponse extends EtherscanResponseBody { status: "0"; message: "NOTOK"; result: string; } interface EtherscanOkResponse extends EtherscanResponseBody { status: "1"; message: "OK"; result: string; } export interface EtherscanChainListResponse { comments: string; totalcount: string; result: Array<{ chainname: string; chainid: string; blockexplorer: string; apiurl: string; status: number; comment: string; }>; } export interface EtherscanVerifyArgs extends BaseVerifyFunctionArgs { constructorArguments: string; } export type EtherscanCustomApiCallOptions = | { method: "GET"; } | { method: "POST"; body?: Record<string, unknown>; }; /** * Provides access to the Etherscan API for contract verification and * custom API calls. * * This interface is designed for plugin authors who need direct access * to Etherscan's verification API beyond the standard verification * workflow. It can be accessed through `network.create()` in the * Hardhat Runtime Environment. * * @example * ```typescript * const { verification } = await hre.network.create(); * const etherscan = verification.etherscan; * * // Use Etherscan methods * const isVerified = await etherscan.isVerified("0x1234..."); * ``` */ export interface LazyEtherscan { /** * Gets the chain ID that this Etherscan instance is configured for. * * @returns The chain ID as a string (e.g., "1" for Ethereum mainnet) */ getChainId(): Promise<string>; /** * Gets the name of the block explorer. * * @returns The explorer name (e.g., "Etherscan", "BscScan", * "PolygonScan") */ getName(): Promise<string>; /** * Gets the base URL of the block explorer web interface. * * @returns The block explorer web URL (e.g., "https://etherscan.io") */ getUrl(): Promise<string>; /** * Gets the API URL used for verification requests. * * @returns The API endpoint URL */ getApiUrl(): Promise<string>; /** * Gets the configured API key for this Etherscan instance. * * @returns The API key */ getApiKey(): Promise<string>; /** * Gets the block explorer URL for a specific contract address. * * @param address - The contract address * @returns The full URL to view the contract on the block explorer */ getContractUrl(address: string): Promise<string>; /** * Checks whether a contract at the given address is verified on the * block explorer. * * @param address - The contract address to check * @returns True if the contract is verified, false otherwise */ isVerified(address: string): Promise<boolean>; /** * Submits a contract for verification on the block explorer. * * @param args - The verification arguments containing: * - contractAddress: The deployed contract address to verify * - compilerInput: The Solidity compiler input JSON containing * sources and settings * - contractName: The fully qualified name of the contract * (e.g., "contracts/Token.sol:Token") * - compilerVersion: The Solidity compiler version used * (e.g., "v0.8.19+commit.7dd6d404") * - constructorArguments: The ABI-encoded constructor arguments * as a hex string * @returns A GUID (Globally Unique Identifier) that can be used with * `pollVerificationStatus()` to check the verification progress * * @throws {HardhatError} CONTRACT_VERIFICATION_MISSING_BYTECODE - * If the contract bytecode is not found on the network * @throws {HardhatError} CONTRACT_ALREADY_VERIFIED - * If the contract is already verified * @throws {HardhatError} CONTRACT_VERIFICATION_REQUEST_FAILED - * If the verification request fails * @throws {HardhatError} EXPLORER_REQUEST_FAILED - * If the HTTP request fails */ verify(args: EtherscanVerifyArgs): Promise<string>; /** * Polls the block explorer to check the status of a pending * verification request. * * This method recursively polls the verification status until the * verification completes (either successfully or with a failure). * It automatically waits between poll attempts to avoid overwhelming * the API. * * @param guid - The verification GUID returned by the verify method * @param contractAddress - The address of the contract being verified * @param contractName - The name of the contract being verified * @returns An object containing: * - `success`: true if verification succeeded, false if it failed * - `message`: The status message from Etherscan * (e.g., "Pass - Verified", "Fail - Unable to verify") * * @throws {HardhatError} CONTRACT_ALREADY_VERIFIED - * If the contract was already verified * @throws {HardhatError} CONTRACT_VERIFICATION_STATUS_POLLING_FAILED - * If the API returns an unexpected error * @throws {HardhatError} EXPLORER_REQUEST_FAILED - * If the HTTP request fails */ pollVerificationStatus( guid: string, contractAddress: string, contractName: string, ): Promise<{ success: boolean; message: string }>; /** * Makes a custom API call to the Etherscan API with specified * parameters. * * This method is designed for advanced use cases where plugins need * to call Etherscan API endpoints that aren't covered by the standard * methods. It automatically handles authentication and chain * identification. * * @param params - The API call parameters as key-value pairs * (e.g., `{ module: "contract", action: "getsourcecode", * address: "0x..." }`) * @param options - Optional request options: * - `method`: HTTP method to use ("GET" or "POST", defaults to * "GET") * - `body`: Request body for POST requests as key-value pairs * * @returns The raw response body from the Etherscan API containing: * - `status`: "0" for error, "1" for success * - `message`: Status message (e.g., "OK", "NOTOK") * - `result`: Response data (type varies by endpoint - can be * string, array, or object) * * @throws {HardhatError} EXPLORER_REQUEST_FAILED - * If the HTTP request fails * @throws {HardhatError} EXPLORER_REQUEST_STATUS_CODE_ERROR - * If the response status code is not 2xx * * @remarks * - The `apikey` and `chainid` parameters are automatically added * to the query parameters. You can override these by explicitly * passing them in the `params` object. * - This method returns the raw API response. Callers should check * the `status` field and handle `result` appropriately. * * @example * ```typescript * const response = await verification.etherscan.customApiCall({ * module: "contract", * action: "getsourcecode", * address: "0x1234..." * }); * * if (response.status === "1") { * console.log("Success:", response.result); * } * ``` */ customApiCall( params: Record<string, unknown>, options?: EtherscanCustomApiCallOptions, ): Promise<EtherscanResponseBody>; }