#Using Viem
Hardhat Ignition provides a variant based on using Viem as your connection library. Viem is a lightweight alternative to ethers with a focus on type safety.
The Viem support in Hardhat Ignition includes a helper function, for use in Hardhat tests and scripts, that allows you to deploy Ignition modules and get back the deployed contracts as fully typed Viem contract instances.
# Installation
To install Hardhat Ignition with Viem support in an existing Hardhat project, you will need:
- Hardhat version 2.18.0 or higher
- Viem version 1.18.0 or higher
You can also follow Hardhat's Viem Quick Start to create a new Hardhat Viem project from scratch.
From the root directory of your Hardhat project run:
npm install --save-dev @nomicfoundation/hardhat-ignition-viem
npm install --save-dev @nomicfoundation/hardhat-ignition-viem @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-verify @nomicfoundation/hardhat-viem @nomicfoundation/ignition-core typescript viem
yarn add --dev @nomicfoundation/hardhat-ignition-viem @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-verify @nomicfoundation/hardhat-viem @nomicfoundation/ignition-core typescript viem
pnpm add -D @nomicfoundation/hardhat-ignition-viem viem typescript
Then enable the plugin in your config file:
import "@nomicfoundation/hardhat-ignition-viem";
require("@nomicfoundation/hardhat-ignition-viem");
TIP
Only one Hardhat Ignition package should be imported within your Hardhat config file. Viem and ethers support cannot both be enabled at the same time.
# The Ignition object
The @nomicfoundation/hardhat-plugin-viem
plugin adds an ignition
object to the Hardhat Runtime Environment.
The ignition
object exposes a deploy
method, which takes an Ignition module, deploys it against the current network, like Hardhat Network, and returns the results of the module as typed Viem contract instances.
The deploy
method takes the Module as its first argument:
const ApolloModule = buildModule("Apollo", (m) => {
const apollo = m.contract("Rocket", ["Saturn V"]);
return { apollo };
});
it("should have named the rocket Saturn V", async function () {
const { apollo } = await hre.ignition.deploy(ApolloModule);
assert.equal(await apollo.read.name(), "Saturn V");
});
The ignition.deploy
method returns an object with a Viem contract instance per Future
returned as a result in the module.
# Usage with Artifacts
To infer the type of a Viem contract instance, the full type of the ABI must be available when initializing a Future
within a module.
For named Hardhat contracts, the ABI and type information will be retrieved automatically using hardhat-viem's type generation.
If you are passing an artifact object to initialize a Future
within a module, you will need to ensure the artifact's ABI is either declared with const assertions or defined inline:
const counterArtifact = {
// ...
abi: [...] as const, // <--- const assertion
}
const CounterModule = buildModule("Counter", (m) => {
const counter = m.contract("Counter", CounterArtifact, [42]);
return { counter };
});
If type inference isn't working for the returned contract, it is likely that the ABI type needs a const
assertion or to be defined inline.
This is because the ABI type must be as narrow as possible for Viem to infer the correct type for the contract, and by default Typescript will broaden the types within object literals.
TIP
Typescript doesn't support importing JSON as const, it will instead automatically broaden the type, breaking Viem's inference. The artifact must be defined inline within Typescript.
See Viem's type inference requirements for more details.
# Sending transactions with a different account
The ignition.deploy
method will default to using the first account in Hardhat network's accounts
array as the sender for all transactions.
You can change this by passing a defaultSender
within the options object as a second argument to the deploy
method:
const [first, second] = await hre.viem.getWalletClients();
const result = await hre.ignition.deploy(ApolloModule, {
defaultSender: second.account.address,
});
# Hardhat Ignition and Hardhat Viem
Hardhat Ignition leverages the hardhat-viem plugin for its type generation support, and inherits the same approach to managing types and version stability.
Read the documentation on hardhat-viem to learn more about Hardhat's Viem capabilities.