/** * Copyright (c) 2024-2026 Тарабанов Александр Викторович * All rights reserved. * * This software is proprietary and confidential. * Unauthorized copying, modification, or distribution is prohibited. * * For licensing inquiries: info@hb3-accelerator.com * Website: https://hb3-accelerator.com * GitHub: https://github.com/VC-HB3-Accelerator */ require('@nomicfoundation/hardhat-toolbox'); require('@nomicfoundation/hardhat-verify'); require('hardhat-contract-sizer'); require('dotenv').config(); function getNetworks() { // Синхронная загрузка сетей из переменных окружения // Hardhat не поддерживает асинхронную инициализацию конфигурации // Получаем supported_chain_ids из переменных окружения const supportedChainIdsEnv = process.env.SUPPORTED_CHAIN_IDS; const supportedChainIds = supportedChainIdsEnv ? JSON.parse(supportedChainIdsEnv) : []; // Получаем RPC URLs из переменных окружения const rpcUrlsEnv = process.env.RPC_URLS; const rpcUrls = rpcUrlsEnv ? JSON.parse(rpcUrlsEnv) : {}; // Если нет supported_chain_ids, ничего не настраиваем (используются только локальные сети Hardhat) if (!supportedChainIds || supportedChainIds.length === 0) { return {}; } const networks = {}; const supportedChainIdsNumbers = supportedChainIds.map((id) => Number(id)); // RPC_URLS может быть либо объектом { [chainId]: url }, либо массивом URL-ов. const isRpcArray = Array.isArray(rpcUrls); supportedChainIdsNumbers.forEach((chainId, index) => { let url; if (isRpcArray) { url = rpcUrls[index]; } else { url = rpcUrls[chainId] || rpcUrls[chainId.toString()]; } if (!url) { // Если для chainId нет URL — пропускаем сеть return; } const networkName = `chain_${chainId}`; networks[networkName] = { chainId, url // accounts не указываем: для verify достаточно RPC + ETHERSCAN_API_KEY }; }); return networks; } // Функция для получения базовых сетей (fallback) — оставлена для совместимости function getBaseNetworks() { return {}; } module.exports = { solidity: { version: "0.8.20", settings: { optimizer: { enabled: true, runs: 0 // Максимальная оптимизация размера }, viaIR: true, evmVersion: "paris" } }, contractSizer: { alphaSort: true, runOnCompile: true, disambiguatePaths: false, }, // Автокомпиляция при изменениях watch: { compilation: { tasks: ["compile"], files: ["./contracts/**/*.sol"], verbose: true } }, networks: getNetworks(), etherscan: { // Единый API ключ для всех сетей (V2 API) apiKey: process.env.ETHERSCAN_API_KEY || '', customChains: [ { network: "sepolia", chainId: 11155111, urls: { apiURL: "https://api-sepolia.etherscan.io/api", browserURL: "https://sepolia.etherscan.io" } }, { network: "holesky", chainId: 17000, urls: { apiURL: "https://api.etherscan.io/v2/api", browserURL: "https://holesky.etherscan.io" } }, { network: "polygon", chainId: 137, urls: { apiURL: "https://api.etherscan.io/v2/api", browserURL: "https://polygonscan.com" } }, { network: "arbitrumOne", chainId: 42161, urls: { apiURL: "https://api.etherscan.io/v2/api", browserURL: "https://arbiscan.io" } }, { network: "arbitrumSepolia", chainId: 421614, urls: { apiURL: "https://api.etherscan.io/v2/api?chainid=421614", browserURL: "https://sepolia.arbiscan.io" } }, { network: "bsc", chainId: 56, urls: { apiURL: "https://api.etherscan.io/v2/api?chainid=56", browserURL: "https://bscscan.com" } }, { network: "base", chainId: 8453, urls: { apiURL: "https://api.etherscan.io/v2/api?chainid=8453", browserURL: "https://basescan.org" } }, { network: "baseSepolia", chainId: 84532, urls: { apiURL: "https://api.etherscan.io/v2/api?chainid=84532", browserURL: "https://sepolia.basescan.org" } } ] }, sourcify: { enabled: true // Включаем Sourcify для децентрализованной верификации }, solidityCoverage: { excludeContracts: [], skipFiles: [], // Исключаем строки с revert функциями из покрытия excludeLines: [ '// coverage:ignore-line', 'revert ErrTransfersDisabled();', 'revert ErrApprovalsDisabled();' ] } };