| name | hardhat-toolbox-mocha-ethers |
| description | Use alongside the `hardhat` skill when the project depends on `@nomicfoundation/hardhat-toolbox-mocha-ethers`. Covers the ethers helpers exposed on `network.create()`, contract interaction (`ethers.deployContract`, calling functions, `connect`), TypeChain-typed contract instances, and the chai matchers from `@nomicfoundation/hardhat-ethers-chai-matchers` (`.to.emit`, `.to.be.revertedWith*`, `.to.changeEtherBalance(s)`). |
| metadata | {"package":"@nomicfoundation/hardhat-toolbox-mocha-ethers"} |
Hardhat toolbox: ethers + Mocha
This skill builds on the core hardhat skill. Load that first for test organization, the network.create() shape, networkHelpers, fixtures, and the typechecking workflow. Everything below hangs off the connection returned by network.create().
This stack runs tests under Mocha (global describe / it) and asserts with chai. Mocha doesn't await describe callbacks, so the connection is set up at the top of the file with top-level await:
import { expect } from "chai";
import { network } from "hardhat";
const { ethers, networkHelpers } = await network.create();
describe("Counter", function () {
});
One connection per file is the norm. State isolation between tests comes from loadFixture (see the hardhat skill), not from creating a fresh connection per describe.
ethers: signers and contract interaction
Contract types are generated by TypeChain from the compiled ABI. Run hardhat build before typechecking so the types reflect the latest contracts.
const blockNumber = await ethers.provider.getBlockNumber();
const balance = await ethers.provider.getBalance("0xabc...");
const [owner, alice, bob] = await ethers.getSigners();
const oneEth = ethers.parseEther("1.0");
const counter = await ethers.deployContract("Counter");
const counterWithArgs = await ethers.deployContract("Counter", [42n]);
const counterFromAlice = await ethers.deployContract("Counter", [], alice);
const value = await counter.x();
await counter.inc();
await counter.incBy(3n);
await counter.connect(alice).inc();
await counter.deposit({ value: oneEth });
const existing = await ethers.getContractAt("Counter", "0xabc...");
Inside a loadFixture setup function (see the hardhat skill for the surrounding pattern), ethers.deployContract is the canonical deploy step:
async function deployCounterFixture() {
const counter = await ethers.deployContract("Counter");
return { counter };
}
const { counter } = await networkHelpers.loadFixture(deployCounterFixture);
To send a transaction from an arbitrary address (not one of the default-funded accounts), fund it for gas and pull an impersonating signer with ethers.getImpersonatedSigner — it handles the impersonation internally, no separate networkHelpers.impersonateAccount call needed:
const addr = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
await networkHelpers.setBalance(addr, ethers.parseEther("1.0"));
const signer = await ethers.getImpersonatedSigner(addr);
await counter.connect(signer).inc();
Chai matchers: Ethereum-specific assertions
The hardhat-ethers-chai-matchers plugin extends chai's expect with matchers for transactions, events, and balance changes. Pass the transaction promise (the result of a write call, unawaited) into expect:
import { expect } from "chai";
await expect(counter.connect(banned).inc()).to.revert(ethers);
await expect(counter.connect(banned).inc()).to.be.revertedWith(
"only the owner can increment the counter",
);
await expect(counter.connect(banned).inc()).to.be.revertedWithCustomError(
counter,
"Unauthorized",
);
await expect(counter.connect(banned).inc())
.to.be.revertedWithCustomError(counter, "Unauthorized")
.withArgs(banned.address);
await expect(counter.inc()).to.emit(counter, "Increment");
await expect(counter.inc()).to.emit(counter, "Increment").withArgs(1n);
await expect(game.claim()).to.changeEtherBalance(ethers, winner, PRIZE);
await expect(game.claim()).to.changeEtherBalances(
ethers,
[winner, loser],
[PRIZE, -STAKE],
);
For plain assertions (equality, arrays, types), use expect from chai directly without the Ethereum matchers.