Hardhat v2.19.0: Introducing Configuration Variables

Handling configuration settings is a common situation in Ethereum development, and it often involves sensitive information that could cause…

Hardhat v2.19.0: Introducing Configuration Variables

Handling configuration settings is a common situation in Ethereum development, and it often involves sensitive information that could cause issues if leaked. A common example are Infura API keys. Different developers may also have varying settings, which adds to the complexity of managing these configurations.

Configuration variables are a new Hardhat feature that lets you use values in a configuration file without making them part of your codebase. They work as a replacement for environment variables and dotenv, but are more secure, flexible, and powerful.

This is how most projects handle configuration values today:

module.exports = { 
  networks: { 
    sepolia: { 
      url: `https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`, 
    }, 
  }, 
};

These variables are then put in an .env file and loaded using the dotenv package. This approach works, but it has a couple of problems:

  • A user might accidentally push the .env file to a public repository, making all the data within it accessible to other users or to bots.
  • It’s not clear which of these variables need to be set before running the project and which ones are optional.
  • If you have multiple projects and want to share some value between them, you have to copy their .env files and keep them in sync.

Using configuration variables

Hardhat v2.19.0 introduces a new set of tasks under the vars scope to manage your configuration variables:

$ npx hardhat vars set INFURA_API_KEY 
✔ Enter value: ********************************

After setting a configuration variable, you can retrieve it from any Hardhat configuration using vars.get:

const INFURA_API_KEY = vars.get("INFURA_API_KEY"); 
 
module.exports = { 
  networks: { 
    sepolia: { 
      url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, 
    }, 
  }, 
};

For variables that may not exist, you can specify a default value as the second parameter:

const salt = vars.get("DEPLOY_SALT", "12345");

You can also use vars.has to check if a variable exists:

const accounts = vars.has("TEST_PK") ? [vars.get("TEST_PK")] : [];

Migrating from dotenv

If you are using dotenv, we recommend migrating to our built-in configuration variables manager. This will make it easier to share values across various Hardhat projects, and will minimize the risk of exposing sensitive data by accidentally uploading a .env file to a public repository.

To migrate from dotenv, follow these steps:

  1. Replace process.env.KEY references in your configuration with vars.get("KEY"). Replace conditions like process.env.KEY !== undefined with vars.has("KEY")
  2. Run npx hardhat vars setup to identify all the variables that are used by your project.
  3. Use npx hardhat vars set for each variable as indicated by the setup task.
  4. After substituting all instances of process.env, you may uninstall the dotenv package and remove its import from your configuration.

Under the hood

Configuration variables are stored in plain text on your disk. Avoid using this feature for data you wouldn’t normally save in an unencrypted file. You can run npx hardhat vars path to get the path to the storage file.

Give it a try

Upgrade to Hardhat v2.19.0 and check our Configuration variables guide to learn more. And don’t forget to star Hardhat on GitHub!