UNPKG

hashscan-verify

Version:

Hardhat plugin for verifying smart contracts on HashScan (Hedera's contract verification service)

131 lines 5.52 kB
import { task } from "hardhat/config"; import "hardhat/types/tasks"; import { NetworkConfig, HEDERA_NETWORKS } from "./config/networks.js"; import { SourcifyService } from "./services/sourcify-service.js"; import { ValidationService } from "./services/validation-service.js"; import { ArtifactResolver } from "./services/artifact-resolver.js"; const hashscanVerifyTask = task("hashscan-verify", "Verify contract on HashScan/Sourcify") .addPositionalArgument({ name: "address", description: "Deployed contract address", }) .addOption({ name: "contract", description: "Fully qualified contract name (e.g., contracts/Counter.sol:Counter)", defaultValue: "", }) .addVariadicArgument({ name: "constructorArgs", description: "Constructor arguments (if any)", defaultValue: [], }) .setAction(async () => ({ default: async (args, hre) => { var _a, _b, _c; const { address, contract, constructorArgs = [] } = args; // Validation const validator = new ValidationService(); const validationError = validator.validateInput(address, contract); if (validationError) { console.error(validationError); return; } const { contractPath, contractName } = validator.parseContract(contract); // Get network configuration const connection = await ((_a = hre.network) === null || _a === void 0 ? void 0 : _a.connect()); const chainId = (_b = connection === null || connection === void 0 ? void 0 : connection.networkConfig) === null || _b === void 0 ? void 0 : _b.chainId; if (!chainId) { console.error("Error: Could not determine chain ID. Make sure you're using the --network flag."); return; } const networkConfig = NetworkConfig.fromChainId(chainId); const apiUrl = ((_c = hre.config.sourcify) === null || _c === void 0 ? void 0 : _c.apiUrl) || networkConfig.defaultApiUrl; // Initialize services const sourcifyService = new SourcifyService(apiUrl); const artifactResolver = new ArtifactResolver(hre); // Check if already verified const isVerified = await sourcifyService.checkIfVerified(address, chainId.toString()); if (isVerified.status) { console.log(`Contract is already verified with ${isVerified.status} match.`); } else { console.log(`Verifying ${contractName} at ${address}...`); try { // Resolve artifact and build info const { artifact, buildInfo, sourcePaths } = await artifactResolver.resolve(contractPath, contractName); // Verify contract const result = await sourcifyService.verify({ address, chainId: chainId.toString(), contractName, artifact, buildInfo, sourcePaths, }); if (result.status === "perfect") { console.log("✔ Contract verified successfully (perfect match)"); } else if (result.status === "partial") { console.log("✔ Contract verified successfully (partial match)"); } else { console.error(`✗ Verification failed: ${result.message}`); } } catch (error) { console.error(`✗ Verification failed: ${error.message}`); } } const viewUrl = networkConfig.getHashScanUrl(address); if (viewUrl) { console.log(`\nView on HashScan: ${viewUrl}`); } else { console.log(`\nChain ID ${chainId} is not a recognized Hedera network.`); } }, })); async function extendUserConfig(config, next) { var _a, _b; const nextConfig = await next(config); const hardhatNetwork = (_a = process.env.HARDHAT_NETWORK) !== null && _a !== void 0 ? _a : ""; const explicitApiUrl = (_b = process.env.HASHSCAN_API_URL) !== null && _b !== void 0 ? _b : process.env.SOURCIFY_API_URL; const isLocalNetwork = /^(localhost|hedera_local|local)$/i.test(hardhatNetwork); const computedApiUrl = explicitApiUrl !== null && explicitApiUrl !== void 0 ? explicitApiUrl : (isLocalNetwork ? "http://localhost:8080" : "https://server-verify.hashscan.io"); const sourcifyConfig = { apiUrl: computedApiUrl, }; return { ...nextConfig, sourcify: sourcifyConfig, }; } async function resolveUserConfig(userConfig, resolveConfigurationVariable, next) { var _a; const resolved = await next(userConfig, resolveConfigurationVariable); const nets = (_a = resolved.networks) !== null && _a !== void 0 ? _a : {}; // Set chain IDs for Hedera networks if not already set HEDERA_NETWORKS.forEach((network) => { network.names.forEach((name) => { if (nets[name] && nets[name].chainId == null) { nets[name].chainId = network.chainId; } }); }); return resolved; } const plugin = { id: "hashscan-verify", dependencies: () => [], hookHandlers: { config: async () => ({ default: async () => ({ extendUserConfig, resolveUserConfig, }), }), }, tasks: [hashscanVerifyTask.build()], }; export default plugin; //# sourceMappingURL=index.js.map