Skip to content

How to Configure Networks with Hardhat-Deploy Helpers

Hardhat-deploy provides powerful helper functions that automatically generate network configurations from environment variables and known chain lists. This eliminates the need to manually configure each network in your hardhat.config.ts.

Overview

Hardhat-deploy provides three key helper functions that work together:

typescript
import {
  addForkConfiguration,
  addNetworksFromEnv,
  addNetworksFromKnownList,
} from 'hardhat-deploy/helpers';

These helpers automatically:

  • Configure networks from environment variables
  • Add all known chains with standard naming
  • Set up fork configurations for testing
  • Handle account management with mnemonics or private keys

Helper Functions

1. addNetworksFromEnv

Scans environment variables for ETH_NODE_URI_<network> patterns and automatically creates network configurations.

How it Works

typescript
// Looks for environment variables like:
// ETH_NODE_URI_sepolia=https://sepolia.infura.io/v3/YOUR-PROJECT-ID
// ETH_NODE_URI_polygon=https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID
// MNEMONIC_sepolia=your mnemonic here
// MNEMONIC_polygon=your mnemonic here

const networks = addNetworksFromEnv({
  // Your custom networks here
  localhost: {
    type: 'edr-simulated',
    chainType: 'l1',
  },
});

Environment Variable Patterns

bash
# Network RPC URLs
ETH_NODE_URI_sepolia=https://sepolia.infura.io/v3/YOUR-PROJECT-ID
ETH_NODE_URI_polygon=https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID
ETH_NODE_URI_arbitrum=https://arb1.arbitrum.io/rpc

# Network-specific mnemonics
MNEMONIC_sepolia=your testnet mnemonic here
MNEMONIC_polygon=your polygon mnemonic here

# Fallback mnemonic (used if network-specific not found)
MNEMONIC=your default mnemonic here

# Secret management (uses Hardhat's configVariable)
ETH_NODE_URI_mainnet=SECRET
MNEMONIC_mainnet=SECRET

Secret Management

For production deployments, use Hardhat's secret management:

bash
# Set environment variable to "SECRET" to use configVariable
ETH_NODE_URI_mainnet=SECRET
MNEMONIC_mainnet=SECRET

# Or specify custom secret name
ETH_NODE_URI_mainnet=SECRET:MAINNET_RPC_URL
MNEMONIC_mainnet=SECRET:MAINNET_MNEMONIC

This will use configVariable('SECRET_ETH_NODE_URI_mainnet') or configVariable('SECRET_MAINNET_RPC_URL').

2. addNetworksFromKnownList

Automatically adds configurations for all known blockchain networks using their kebab-case names.

How it Works

typescript
// Adds networks for all known chains using kebab-case names:
// ethereum, polygon, arbitrum, optimism, base, arbitrum-sepolia, etc.
const networks = addNetworksFromKnownList(
  addNetworksFromEnv({
    // Your custom networks
  })
);

Network Name Conversion

Network names are converted from their display names to kebab-case:

  • "Arbitrum Sepolia"arbitrum-sepolia
  • "MegaETH Testnet"mega-eth-testnet
  • "Polygon Mumbai"polygon-mumbai

Important: Environment variables use underscores instead of dashes (since dashes aren't allowed in env var names):

  • Network name: arbitrum-sepolia
  • Environment variable: ETH_NODE_URI_arbitrum_sepolia
  • Environment variable: MNEMONIC_arbitrum_sepolia

Supported Networks

The helper includes configurations for major networks:

  • Ethereum: ethereum (mainnet)
  • Layer 2s: polygon, arbitrum, optimism, base
  • Testnets: sepolia, goerli, mumbai, arbitrum-sepolia
  • Other chains: bsc, avalanche, fantom, and many more

Automatic Configuration

For each known network, it automatically sets:

  • Chain ID: Correct chain ID for the network
  • RPC URL: Default public RPC or your custom ETH_NODE_URI_<network>
  • Accounts: Network-specific mnemonic or fallback
  • Chain Type: L1, L2, or OP-stack classification

3. addForkConfiguration

Enables fork testing by automatically configuring the fork network based on the HARDHAT_FORK environment variable.

How it Works

typescript
const networks = addForkConfiguration(
  addNetworksFromKnownList(
    addNetworksFromEnv({
      // Base networks
    })
  )
);

Fork Environment Variables

bash
# Fork mainnet at latest block
HARDHAT_FORK=ethereum

# Fork at specific block number
HARDHAT_FORK=ethereum
HARDHAT_FORK_NUMBER=18500000

# Fork other networks
HARDHAT_FORK=polygon
HARDHAT_FORK=arbitrum

Fork Network Configuration

The helper automatically:

  • Creates a fork network configuration
  • Uses the target network's RPC URL for forking
  • Copies account configuration from the target network
  • Sets up proper forking parameters

Complete Configuration Example

Here's how the template uses all three helpers together:

typescript
// hardhat.config.ts
import { HardhatUserConfig } from 'hardhat/config';
import HardhatDeploy from 'hardhat-deploy';
import {
  addForkConfiguration,
  addNetworksFromEnv,
  addNetworksFromKnownList,
} from 'hardhat-deploy/helpers';

const config: HardhatUserConfig = {
  plugins: [HardhatDeploy],
  solidity: {
    version: '0.8.28',
    settings: {
      optimizer: {
        enabled: true,
        runs: 999999,
      },
    },
  },
  networks:
    // Step 3: Add fork configuration for chosen network
    addForkConfiguration(
      // Step 2: Add network config for all known chains using kebab-case names
      // Uses MNEMONIC_<network> (or MNEMONIC if not set) for accounts
      // Uses ETH_NODE_URI_<network> for RPC URLs
      addNetworksFromKnownList(
        // Step 1: Add networks for each ETH_NODE_URI_<network> env var found
        // Also reads MNEMONIC_<network> to populate accounts
        addNetworksFromEnv(
          // Base configuration - your custom networks
          {
            default: {
              type: 'edr-simulated',
              chainType: 'l1',
            },
          }
        )
      )
    ),
  paths: {
    sources: ['src'],
  },
};

export default config;

Environment Variable Setup

Development Environment

bash
# .env.local (not committed)
ETH_NODE_URI_sepolia=https://sepolia.infura.io/v3/YOUR-PROJECT-ID
ETH_NODE_URI_polygon=https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID
MNEMONIC_sepolia=your testnet mnemonic here
MNEMONIC_polygon=your polygon mnemonic here

# For fork testing
HARDHAT_FORK=ethereum

Production Environment

bash
# Production environment variables
ETH_NODE_URI_ethereum=SECRET
ETH_NODE_URI_polygon=SECRET
MNEMONIC_ethereum=SECRET
MNEMONIC_polygon=SECRET

With corresponding Hardhat configuration variables:

bash
# Hardhat configuration variables (secure)
SECRET_ETH_NODE_URI_ethereum=https://mainnet.infura.io/v3/YOUR-PROJECT-ID
SECRET_ETH_NODE_URI_polygon=https://polygon-mainnet.infura.io/v3/YOUR-PROJECT-ID
SECRET_MNEMONIC_ethereum=your production mnemonic here
SECRET_MNEMONIC_polygon=your production mnemonic here

Advanced Usage

Custom Network with Helpers

typescript
const config: HardhatUserConfig = {
  networks: addForkConfiguration(
    addNetworksFromKnownList(
      addNetworksFromEnv({
        // Custom local network
        localhost: {
          type: 'edr-simulated',
          chainType: 'l1',
        },
        // Custom testnet
        'custom-testnet': {
          type: 'http',
          url: 'https://rpc.custom-testnet.com',
          chainId: 12345,
          accounts: { mnemonic: 'your custom testnet mnemonic' },
        },
      })
    )
  ),
};

Network-Specific Configuration

typescript
// The helpers automatically handle network-specific settings
// Based on environment variables:

// ETH_NODE_URI_arbitrum=https://arb1.arbitrum.io/rpc
// MNEMONIC_arbitrum=your arbitrum mnemonic

// Results in:
// networks: {
//   arbitrum: {
//     type: 'http',
//     url: 'https://arb1.arbitrum.io/rpc',
//     accounts: { mnemonic: 'your arbitrum mnemonic' },
//     chainId: 42161,
//     chainType: 'op', // Automatically detected for OP-stack chains
//   }
// }

Template Replacement

You can use template replacement in RPC URLs:

bash
# Single RPC URL for multiple networks
ETH_NODE_URI=https://{{networkName}}.infura.io/v3/YOUR-PROJECT-ID

# This works for networks like:
# - mainnet.infura.io
# - sepolia.infura.io
# - polygon-mainnet.infura.io

Benefits of Using Helpers

1. Reduced Configuration

  • No need to manually configure each network
  • Automatic chain ID and RPC URL management
  • Built-in support for major networks

2. Environment-Based Configuration

  • Easy switching between development and production
  • Network-specific account management
  • Secure secret handling

3. Fork Testing Support

  • Automatic fork configuration
  • Easy network switching for testing
  • Proper account inheritance

4. Maintainability

  • Single source of truth for network configurations
  • Automatic updates when new networks are added
  • Consistent naming conventions

Common Patterns

Multi-Environment Setup

bash
# Development
ETH_NODE_URI_sepolia=https://sepolia.infura.io/v3/DEV-PROJECT-ID
MNEMONIC_sepolia=test test test test test test test test test test test junk

# Staging
ETH_NODE_URI_sepolia=https://sepolia.infura.io/v3/STAGING-PROJECT-ID
MNEMONIC_sepolia=your staging mnemonic

# Production
ETH_NODE_URI_ethereum=SECRET
MNEMONIC_ethereum=SECRET

Fork Testing Workflow

bash
# Test against mainnet fork
HARDHAT_FORK=ethereum npm run test

# Test against polygon fork at specific block
HARDHAT_FORK=polygon HARDHAT_FORK_NUMBER=50000000 npm run test

# Deploy to fork for testing
HARDHAT_FORK=ethereum npm run deploy

CI/CD Integration

yaml
# .github/workflows/test.yml
- name: Test on multiple networks
  run: |
    HARDHAT_FORK=ethereum npm run test
    HARDHAT_FORK=polygon npm run test
    HARDHAT_FORK=arbitrum npm run test
  env:
    ETH_NODE_URI_ethereum: ${{ secrets.MAINNET_RPC_URL }}
    ETH_NODE_URI_polygon: ${{ secrets.POLYGON_RPC_URL }}
    ETH_NODE_URI_arbitrum: ${{ secrets.ARBITRUM_RPC_URL }}

Troubleshooting

Network Not Found

If a network isn't automatically configured:

bash
# Add explicit environment variable
ETH_NODE_URI_custom_network=https://rpc.custom-network.com
MNEMONIC_custom_network=your mnemonic here

RPC URL Issues

bash
# Check if environment variable is set
echo $ETH_NODE_URI_sepolia

# Verify template replacement
ETH_NODE_URI=https://{{networkName}}.example.com/rpc
# Should work for: sepolia.example.com, polygon.example.com, etc.

Fork Configuration Problems

bash
# Ensure target network is configured
ETH_NODE_URI_ethereum=https://mainnet.infura.io/v3/YOUR-PROJECT-ID

# Then fork will work
HARDHAT_FORK=ethereum

Next Steps