Claude-skill-registry hardhat-setup
Templates and automation for initializing and configuring Hardhat projects. Use when setting up new Hardhat projects or adding Hardhat to existing codebases.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/hardhat-setup" ~/.claude/skills/majiayu000-claude-skill-registry-hardhat-setup && rm -rf "$T"
skills/data/hardhat-setup/SKILL.mdHardhat Setup Skill
This skill provides templates, scripts, and best practices for setting up Hardhat-based Solidity projects.
When to Use
Use this skill when:
- Initializing a new Hardhat project
- Adding Hardhat to an existing Solidity codebase
- Configuring Hardhat settings (networks, plugins, etc.)
- Setting up Hardhat in a hybrid Foundry/Hardhat project
- Updating Hardhat configuration
Prerequisites: Node.js and npm/yarn/pnpm must be installed
Integration with Framework Detection
Before using this skill, reference the
framework-detection skill to:
- Check if Hardhat is already configured
- Determine if this is a hybrid setup
- Avoid overwriting existing configuration
Quick Setup
Basic Initialization
# Initialize new Hardhat project npm init -y npm install --save-dev hardhat npx hardhat init # Or with yarn yarn init -y yarn add --dev hardhat npx hardhat init
Project Structure
Hardhat creates this structure:
project/ ├── hardhat.config.js # Configuration ├── .env # Environment variables ├── package.json # Dependencies ├── contracts/ # Contract source files │ └── Lock.sol # Example contract ├── test/ # Test files │ └── Lock.js # Example test ├── scripts/ # Deployment scripts │ └── deploy.js # Example script └── ignition/ # Hardhat Ignition (deployment modules)
Configuration Templates
hardhat.config.js
See
./templates/hardhat.config.js for JavaScript configuration template.
Key Configuration Sections:
require("@nomicfoundation/hardhat-toolbox"); require("dotenv").config(); module.exports = { solidity: { version: "0.8.30", settings: { optimizer: { enabled: true, runs: 200 } } }, networks: { hardhat: {}, sepolia: { url: process.env.SEPOLIA_RPC_URL || "", accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] } }, etherscan: { apiKey: process.env.ETHERSCAN_API_KEY } };
hardhat.config.ts
See
./templates/hardhat.config.ts for TypeScript configuration template.
TypeScript Configuration:
import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import "dotenv/config"; const config: HardhatUserConfig = { solidity: "0.8.30", networks: { sepolia: { url: process.env.SEPOLIA_RPC_URL || "", accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] } } }; export default config;
Environment Variables
See
./templates/.env.example for complete environment variable template.
Essential Variables:
# RPC URLs MAINNET_RPC_URL= SEPOLIA_RPC_URL= # Private Keys (NEVER commit actual keys) PRIVATE_KEY= # Etherscan API Keys ETHERSCAN_API_KEY= # Gas Settings GAS_PRICE=
Essential Plugins
Hardhat Toolbox (Recommended)
Includes all essential plugins:
npm install --save-dev @nomicfoundation/hardhat-toolbox
Includes:
- Ethers.js integration@nomicfoundation/hardhat-ethers
- Chai matchers for testing@nomicfoundation/hardhat-chai-matchers
- Contract verification@nomicfoundation/hardhat-verify
- Gas usage reportinghardhat-gas-reporter
- Code coveragesolidity-coverage
- TypeScript types for contracts@typechain/hardhat
Individual Plugins
# Contract verification npm install --save-dev @nomicfoundation/hardhat-verify # Gas reporting npm install --save-dev hardhat-gas-reporter # Code coverage npm install --save-dev solidity-coverage # OpenZeppelin Upgrades npm install --save-dev @openzeppelin/hardhat-upgrades
Common Configurations
1. Multiple Networks
networks: { mainnet: { url: process.env.MAINNET_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 1 }, sepolia: { url: process.env.SEPOLIA_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 11155111 }, arbitrum: { url: process.env.ARBITRUM_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 42161 } }
2. High Optimization for Production
solidity: { version: "0.8.30", settings: { optimizer: { enabled: true, runs: 10000 }, viaIR: true } }
3. Multiple Solidity Versions
solidity: { compilers: [ { version: "0.8.30", settings: { optimizer: { enabled: true, runs: 200 } } }, { version: "0.8.20", settings: { optimizer: { enabled: true, runs: 200 } } } ] }
4. Gas Reporter Configuration
gasReporter: { enabled: process.env.REPORT_GAS === "true", currency: "USD", coinmarketcap: process.env.COINMARKETCAP_API_KEY, outputFile: "gas-report.txt", noColors: true }
Dependencies Management
Installing OpenZeppelin
# OpenZeppelin Contracts npm install @openzeppelin/contracts # OpenZeppelin Upgrades Plugin npm install --save-dev @openzeppelin/hardhat-upgrades
Installing Common Libraries
# Ethers.js (usually included with hardhat-toolbox) npm install ethers # Chai for testing npm install --save-dev chai # Dotenv for environment variables npm install --save-dev dotenv
Initialization Script
See
./scripts/init-hardhat.sh for automated setup.
Usage:
# Basic initialization ./scripts/init-hardhat.sh # With project name ./scripts/init-hardhat.sh my-project # With TypeScript ./scripts/init-hardhat.sh my-project --typescript
What the script does:
- Checks if Node.js is installed
- Initializes npm/yarn project
- Installs Hardhat and essential plugins
- Creates configuration files
- Sets up .gitignore
- Installs OpenZeppelin contracts
- Creates example contract and test
Hybrid Setup (Hardhat + Foundry)
When adding Hardhat to an existing Foundry project:
1. Initialize Hardhat Without Overwriting
# Initialize npm project npm init -y # Install Hardhat npm install --save-dev hardhat npx hardhat init # Choose "Create an empty hardhat.config.js"
2. Configure Shared Directories
// hardhat.config.js module.exports = { paths: { sources: "./src", // Use Foundry's src dir tests: "./test", // Shared test dir cache: "./cache_hardhat", // Separate cache artifacts: "./artifacts" }, solidity: "0.8.30" };
3. Update .gitignore
# Hardhat artifacts/ cache/ cache_hardhat/ node_modules/ coverage/ coverage.json typechain-types/ # Foundry out/ lib/ # Environment .env .env.local
4. Shared Dependencies
# Install OpenZeppelin via npm (for Hardhat) npm install @openzeppelin/contracts # Foundry can reference node_modules # Add to foundry.toml: # libs = ["node_modules", "lib"]
Testing Setup
Basic Test Structure (JavaScript)
const { expect } = require("chai"); const { ethers } = require("hardhat"); describe("MyContract", function () { let myContract; let owner; beforeEach(async function () { [owner] = await ethers.getSigners(); const MyContract = await ethers.getContractFactory("MyContract"); myContract = await MyContract.deploy(); }); it("Should work correctly", async function () { // Test implementation expect(await myContract.someFunction()).to.equal(expectedValue); }); });
Basic Test Structure (TypeScript)
import { expect } from "chai"; import { ethers } from "hardhat"; import { MyContract } from "../typechain-types"; describe("MyContract", function () { let myContract: MyContract; beforeEach(async function () { const MyContract = await ethers.getContractFactory("MyContract"); myContract = await MyContract.deploy(); }); it("Should work correctly", async function () { expect(await myContract.someFunction()).to.equal(expectedValue); }); });
Running Tests
# Run all tests npx hardhat test # Run specific test npx hardhat test test/MyContract.test.js # With gas reporting REPORT_GAS=true npx hardhat test # With coverage npx hardhat coverage
Security Best Practices for Private Keys
⚠️ CRITICAL: Never store production private keys in .env files!
Recommended Approaches (in order of preference)
1. Hardware Wallets (Most Secure - Production)
Install the Ledger plugin:
npm install --save-dev @nomicfoundation/hardhat-ledger
Configure in
hardhat.config.js:
require("@nomicfoundation/hardhat-ledger"); module.exports = { networks: { mainnet: { url: process.env.MAINNET_RPC_URL, ledgerAccounts: [ "0xYourLedgerAddress" ] } } };
Deploy with Ledger:
npx hardhat run scripts/deploy.js --network mainnet
2. Hardhat Configuration Variables (Recommended - Built-in)
Hardhat 2.x+ includes built-in support for secure configuration variables:
# Set a configuration variable (prompts for value, stores encrypted) npx hardhat vars set PRIVATE_KEY # List all configuration variables npx hardhat vars list # Delete a variable npx hardhat vars delete PRIVATE_KEY
Use in
hardhat.config.js:
const { vars } = require("hardhat/config"); module.exports = { networks: { sepolia: { url: vars.get("SEPOLIA_RPC_URL"), accounts: [vars.get("PRIVATE_KEY")] } } };
This stores encrypted values in your home directory and prompts for decryption when needed.
3. hardhat-keystore Plugin (Encrypted Keystore)
Similar to Foundry's
cast wallet, provides encrypted keystore management:
npm install --save-dev hardhat-keystore
Configure in
hardhat.config.js:
require("hardhat-keystore"); module.exports = { networks: { sepolia: { url: process.env.SEPOLIA_RPC_URL, accounts: { mnemonic: keystore.getMnemonic(), // or privateKey: keystore.getPrivateKey("deployer") } } } };
4. hardhat-secure-accounts Plugin (Third-Party Alternative)
npm install --save-dev hardhat-secure-accounts
Creates encrypted keystore files:
# Create new encrypted account npx hardhat accounts:create # Import existing private key npx hardhat accounts:import --name deployer
Use in scripts:
const { getSecureAccount } = require("hardhat-secure-accounts"); async function main() { const signer = await getSecureAccount("deployer"); // Use signer for deployment }
5. Interactive Environment Variable (Development Only)
Prompt for private key at runtime (doesn't store on disk):
const readline = require("readline"); async function getPrivateKey() { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { rl.question("Enter private key: ", (answer) => { rl.close(); resolve(answer); }); }); } async function main() { const privateKey = await getPrivateKey(); const wallet = new ethers.Wallet(privateKey, ethers.provider); // Use wallet for deployment }
6. .env Variables (Development/Testing ONLY)
⚠️ Use ONLY for local development or testnet testing with non-production keys!
require("dotenv").config(); module.exports = { networks: { sepolia: { url: process.env.SEPOLIA_RPC_URL, accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [] } } };
If using .env:
- ✅ Only use accounts created specifically for development/testing
- ✅ Never reuse production private keys
- ✅ Keep test funds minimal
- ✅ Add .env to .gitignore
- ❌ Never commit .env to version control
- ❌ Never use for mainnet deployments
Deployment Setup
Basic Deployment Script
// scripts/deploy.js const hre = require("hardhat"); async function main() { const MyContract = await hre.ethers.getContractFactory("MyContract"); const myContract = await MyContract.deploy(); await myContract.waitForDeployment(); console.log("MyContract deployed to:", await myContract.getAddress()); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
Deploy Commands
# Deploy to local network npx hardhat run scripts/deploy.js # Deploy to Sepolia with hardware wallet (RECOMMENDED for production) npx hardhat run scripts/deploy.js --network sepolia # (Ledger will prompt for approval) # Deploy to Sepolia with Hardhat vars (RECOMMENDED for all deployments) # First time: npx hardhat vars set PRIVATE_KEY npx hardhat run scripts/deploy.js --network sepolia # Development only: with .env private key npx hardhat run scripts/deploy.js --network sepolia # Verify contract npx hardhat verify --network sepolia DEPLOYED_CONTRACT_ADDRESS
Best Practices
- Secure private key management - Use hardware wallets or Hardhat Configuration Variables for all deployments; never store production keys in .env
- Use hardhat-toolbox - Includes all essential plugins
- TypeScript for large projects - Better type safety and IDE support
- Comprehensive .env.example - Document all required environment variables (but discourage private keys)
- Separate networks - Configure all networks you'll deploy to
- Gas reporting - Enable gas reports for optimization
- Code coverage - Run coverage regularly
- Contract verification - Always verify deployed contracts
- Version lock dependencies - Use exact versions in package.json
Troubleshooting
Issue: "hardhat: command not found"
# Use npx npx hardhat compile # Or install globally (not recommended) npm install -g hardhat
Issue: Module not found errors
# Clear cache and reinstall rm -rf node_modules package-lock.json npm install
Issue: Compilation errors with OpenZeppelin
# Ensure correct import paths import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
Issue: Network connection errors
# Check RPC URL in .env # Test with curl curl -X POST -H "Content-Type: application/json" \ --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ $SEPOLIA_RPC_URL
Quick Reference
| Task | Command | Notes |
|---|---|---|
| Init project | | Creates new project |
| Add dependency | | Uses npm |
| Compile | | Compiles contracts |
| Test | | Runs tests |
| Coverage | | Test coverage |
| Gas report | | Gas usage |
| Deploy | | Run deployment |
| Verify | | Verify on Etherscan |
| Clean | | Clean artifacts |
Template Files
This skill provides the following templates:
- JavaScript configuration./templates/hardhat.config.js
- TypeScript configuration./templates/hardhat.config.ts
- Environment variables template./templates/.env.example
- Deployment script template./templates/deploy-script.js
Scripts
This skill provides the following scripts:
- Automated project initialization./scripts/init-hardhat.sh
Next Steps After Setup:
- Configure
for your networkshardhat.config.js - Copy
to.env.example
and fill in values.env - Install required dependencies with
npm install - Write contracts in
contracts/ - Write tests in
test/ - Run
to verify setupnpx hardhat test