From ba6720254333c81a795f971e4225dc3d74107792 Mon Sep 17 00:00:00 2001 From: Luis Schaab <schaable@gmail.com> Date: Thu, 15 Feb 2024 16:36:45 -0300 Subject: [PATCH 01/41] Upgrade the viem toolbox and project creation to viem@2 --- .changeset/silver-waves-cough.md | 6 ++++ .../src/internal/cli/project-creation.ts | 6 ++-- packages/hardhat-toolbox-viem/package.json | 6 ++-- pnpm-lock.yaml | 32 ++++++------------- 4 files changed, 21 insertions(+), 29 deletions(-) create mode 100644 .changeset/silver-waves-cough.md diff --git a/.changeset/silver-waves-cough.md b/.changeset/silver-waves-cough.md new file mode 100644 index 0000000000..636032268e --- /dev/null +++ b/.changeset/silver-waves-cough.md @@ -0,0 +1,6 @@ +--- +"@nomicfoundation/hardhat-toolbox-viem": major +"hardhat": patch +--- + +Upgraded hardhat-toolbox-viem and project creation to support viem@2 diff --git a/packages/hardhat-core/src/internal/cli/project-creation.ts b/packages/hardhat-core/src/internal/cli/project-creation.ts index fb14bdb388..e5b98bc46a 100644 --- a/packages/hardhat-core/src/internal/cli/project-creation.ts +++ b/packages/hardhat-core/src/internal/cli/project-creation.ts @@ -46,7 +46,7 @@ const ETHERS_PROJECT_DEPENDENCIES: Dependencies = { }; const VIEM_PROJECT_DEPENDENCIES: Dependencies = { - "@nomicfoundation/hardhat-toolbox-viem": "^2.0.0", + "@nomicfoundation/hardhat-toolbox-viem": "^3.0.0", }; const PEER_DEPENDENCIES: Dependencies = { @@ -68,8 +68,8 @@ const ETHERS_PEER_DEPENDENCIES: Dependencies = { }; const VIEM_PEER_DEPENDENCIES: Dependencies = { - "@nomicfoundation/hardhat-viem": "^1.0.0", - viem: "^1.15.1", + "@nomicfoundation/hardhat-viem": "^2.0.0", + viem: "^2.7.6", }; const TYPESCRIPT_DEPENDENCIES: Dependencies = {}; diff --git a/packages/hardhat-toolbox-viem/package.json b/packages/hardhat-toolbox-viem/package.json index 652eb0de95..500bf6a34e 100644 --- a/packages/hardhat-toolbox-viem/package.json +++ b/packages/hardhat-toolbox-viem/package.json @@ -68,12 +68,12 @@ "solidity-coverage": "^0.8.1", "ts-node": "^10.8.0", "typescript": "~5.0.4", - "viem": "^1.15.1" + "viem": "^2.7.6" }, "peerDependencies": { "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", - "@nomicfoundation/hardhat-viem": "workspace:^1.0.0", + "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", "@types/chai": "^4.2.0", "@types/chai-as-promised": "^7.1.6", "@types/mocha": ">=9.1.0", @@ -84,7 +84,7 @@ "solidity-coverage": "^0.8.1", "ts-node": ">=8.0.0", "typescript": "~5.0.4", - "viem": "^1.15.1" + "viem": "^2.7.6" }, "bugs": { "url": "https://github.com/nomicfoundation/hardhat/issues" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8129e6a521..de0eee8113 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1215,8 +1215,8 @@ importers: specifier: ~5.0.4 version: 5.0.4 viem: - specifier: ^1.15.1 - version: 1.21.4(typescript@5.0.4) + specifier: ^2.7.6 + version: 2.7.6(typescript@5.0.4) packages/hardhat-truffle4: dependencies: @@ -3491,7 +3491,7 @@ packages: resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} dependencies: '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.5 dev: true @@ -3511,7 +3511,7 @@ packages: /@scure/bip39@1.2.1: resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 '@scure/base': 1.1.5 dev: true @@ -4253,20 +4253,6 @@ packages: typescript: 5.0.4 dev: false - /abitype@0.9.8(typescript@5.0.4): - resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} - peerDependencies: - typescript: '>=5.0.4' - zod: ^3 >=3.19.1 - peerDependenciesMeta: - typescript: - optional: true - zod: - optional: true - dependencies: - typescript: 5.0.4 - dev: true - /abitype@1.0.0(typescript@5.0.4): resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} peerDependencies: @@ -10921,8 +10907,8 @@ packages: core-util-is: 1.0.2 extsprintf: 1.3.0 - /viem@1.21.4(typescript@5.0.4): - resolution: {integrity: sha512-BNVYdSaUjeS2zKQgPs+49e5JKocfo60Ib2yiXOWBT6LuVxY1I/6fFX3waEtpXvL1Xn4qu+BVitVtMh9lyThyhQ==} + /viem@2.7.14(typescript@5.0.4): + resolution: {integrity: sha512-5b1KB1gXli02GOQHZIUsRluNUwssl2t4hqdFAzyWPwJ744N83jAOBOjOkrGz7K3qMIv9b0GQt3DoZIErSQTPkQ==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -10934,7 +10920,7 @@ packages: '@noble/hashes': 1.3.2 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 - abitype: 0.9.8(typescript@5.0.4) + abitype: 1.0.0(typescript@5.0.4) isows: 1.0.3(ws@8.13.0) typescript: 5.0.4 ws: 8.13.0 @@ -10944,8 +10930,8 @@ packages: - zod dev: true - /viem@2.7.14(typescript@5.0.4): - resolution: {integrity: sha512-5b1KB1gXli02GOQHZIUsRluNUwssl2t4hqdFAzyWPwJ744N83jAOBOjOkrGz7K3qMIv9b0GQt3DoZIErSQTPkQ==} + /viem@2.7.6(typescript@5.0.4): + resolution: {integrity: sha512-43TF0VYcTeNef9dax1/BhqlRLXpAo6HAiQ68hrJ8XRhDOou73nHZEjeFl8Eai4UFFodKhu+PbRUFzuuoixOUfg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: From 6f0e3f8a99295a2f76dcbd6766ed976541ca708b Mon Sep 17 00:00:00 2001 From: zoeyTM <probablyzoey+github@gmail.com> Date: Thu, 7 Dec 2023 00:42:40 -0500 Subject: [PATCH 02/41] update sample projects to use ignition * add ignition to hardhat-toolbox * update relevant docs with inclusion of ignition in hardhat-toolbox --- .../advanced/migrating-from-hardhat-waffle.md | 6 +- .../hardhat-runner/docs/advanced/scripts.md | 2 + .../docs/getting-started/index.md | 60 ++++++++++++----- .../hardhat-runner/docs/guides/deploying.md | 28 ++++---- .../docs/guides/project-setup.md | 4 +- .../docs/guides/test-contracts.md | 60 +++++++++++++---- .../hardhat-runner/docs/guides/verifying.md | 6 ++ .../docs/reference/environment-variables.md | 8 +-- .../hardhat-runner/plugins/_dirinfo.yaml | 1 + .../content/tutorial/boilerplate-project.md | 2 +- .../creating-a-new-hardhat-project.md | 4 +- .../tutorial/deploying-to-a-live-network.md | 64 +++++++++++-------- docs/src/content/tutorial/final-thoughts.md | 1 + .../src/content/tutorial/testing-contracts.md | 61 ++++++++++++++---- .../sample-projects/javascript-esm/README.md | 4 +- .../ignition/modules/LockModule.js | 19 ++++++ .../javascript-esm/scripts/deploy.js | 24 ------- .../javascript-esm/test/Lock.js | 7 +- .../sample-projects/javascript/README.md | 4 +- .../javascript/ignition/modules/LockModule.js | 19 ++++++ .../javascript/scripts/deploy.js | 33 ---------- .../sample-projects/javascript/test/Lock.js | 7 +- .../sample-projects/typescript/README.md | 4 +- .../typescript/ignition/modules/LockModule.ts | 23 +++++++ .../typescript/scripts/deploy.ts | 27 -------- .../sample-projects/typescript/test/Lock.ts | 7 +- packages/hardhat-toolbox/README.md | 3 +- packages/hardhat-toolbox/package.json | 4 ++ packages/hardhat-toolbox/src/index.ts | 2 + 29 files changed, 304 insertions(+), 190 deletions(-) create mode 100644 packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js delete mode 100644 packages/hardhat-core/sample-projects/javascript-esm/scripts/deploy.js create mode 100644 packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js delete mode 100644 packages/hardhat-core/sample-projects/javascript/scripts/deploy.js create mode 100644 packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts delete mode 100644 packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts diff --git a/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md b/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md index b80fbcdbd8..8b89597a1b 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md +++ b/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md @@ -55,7 +55,7 @@ Follow these steps to migrate your project to Hardhat Toolbox. :::tab{value="npm 6"} ``` - npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 + npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: @@ -63,7 +63,7 @@ Follow these steps to migrate your project to Hardhat Toolbox. :::tab{value="yarn"} ``` - yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers@1 @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai@4 ethers@5 hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 + yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers@1 @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai@4 ethers@5 hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: @@ -98,6 +98,8 @@ Follow these steps to migrate your project to Hardhat Toolbox. - `@nomicfoundation/hardhat-ethers` - `@nomicfoundation/hardhat-verify` + - `@nomicfoundation/hardhat-ignition` + - `@nomicfoundation/hardhat-ignition-ethers` - `hardhat-gas-reporter` - `solidity-coverage` - `@typechain/hardhat` diff --git a/docs/src/content/hardhat-runner/docs/advanced/scripts.md b/docs/src/content/hardhat-runner/docs/advanced/scripts.md index e36a8b004b..a89003663e 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/scripts.md +++ b/docs/src/content/hardhat-runner/docs/advanced/scripts.md @@ -1,5 +1,7 @@ # Writing scripts with Hardhat +<!-- TODO: We should write this guide based on a different common use case for scripts now that Ignition exists --> + In this guide we will go through the steps of creating a script with Hardhat. For a general overview of using Hardhat refer to the [Getting started guide](../getting-started/index.md). You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a deployment script for your smart contracts. diff --git a/docs/src/content/hardhat-runner/docs/getting-started/index.md b/docs/src/content/hardhat-runner/docs/getting-started/index.md index 3fc4c37501..647a549125 100644 --- a/docs/src/content/hardhat-runner/docs/getting-started/index.md +++ b/docs/src/content/hardhat-runner/docs/getting-started/index.md @@ -151,7 +151,7 @@ If you created a TypeScript project, this task will also generate TypeScript bin ### Testing your contracts -Your project comes with tests that use [Mocha](https://mochajs.org), [Chai](https://www.chaijs.com), and [Ethers.js](https://docs.ethers.org/v6/). +Your project comes with tests that use [Hardhat Ignition](/ignition), [Mocha](https://mochajs.org), [Chai](https://www.chaijs.com), and [Ethers.js](https://docs.ethers.org/v6/). If you take a look in the `test/` folder, you'll see a test file: @@ -239,41 +239,51 @@ Compiled 2 Solidity files successfully ### Deploying your contracts -:::tip - -Try [Hardhat Ignition](/ignition) for your deployments! Our new declarative system for deploying smart contracts without getting caught up in execution details. - -::: - -Next, to deploy the contract we will use a Hardhat script. +Next, to deploy the contract we will use a Hardhat Ignition module. -Inside the `scripts/` folder you will find a file with the following code: +Inside the `ignition/modules` folder you will find a file with the following code: ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} -<<< @/../packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts +<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts ::: :::tab{value="JavaScript"} -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js +<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js ::: :::: -You can run it using `npx hardhat run`: +You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.ts`: ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} ``` -$ npx hardhat run scripts/deploy.ts -Lock with 0.001ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 +$ npx hardhat ignition deploy ./ignition/modules/LockModule.ts +Compiled 1 Solidity file successfully (evm target: paris). +You are running Hardhat Ignition against an in-process instance of Hardhat Network. +This will execute the deployment, but the results will be lost. +You can use --network <network-name> to deploy to a different network. + +Hardhat Ignition 🚀 + +Deploying [ LockModule ] + +Batch #1 + Executed LockModule#Lock + +[ LockModule ] successfully deployed 🚀 + +Deployed Addresses + +LockModule#Lock - 0x5FbDB2315678afecb367f032d93F642f64180aa3 ``` ::: @@ -281,14 +291,32 @@ Lock with 0.001ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 :::tab{value="JavaScript"} ``` -$ npx hardhat run scripts/deploy.js -Lock with 0.001ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 +$ npx hardhat ignition deploy ./ignition/modules/LockModule.js +Compiled 1 Solidity file successfully (evm target: paris). +You are running Hardhat Ignition against an in-process instance of Hardhat Network. +This will execute the deployment, but the results will be lost. +You can use --network <network-name> to deploy to a different network. + +Hardhat Ignition 🚀 + +Deploying [ LockModule ] + +Batch #1 + Executed LockModule#Lock + +[ LockModule ] successfully deployed 🚀 + +Deployed Addresses + +LockModule#Lock - 0x5FbDB2315678afecb367f032d93F642f64180aa3 ``` ::: :::: +To read more about Hardhat Ignition, check out the [Hardhat Ignition documentation](/ignition). + ### Connecting a wallet or Dapp to Hardhat Network By default, Hardhat will spin up a new in-memory instance of Hardhat Network on startup. It's also possible to run Hardhat Network in a standalone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a script. diff --git a/docs/src/content/hardhat-runner/docs/guides/deploying.md b/docs/src/content/hardhat-runner/docs/guides/deploying.md index 9c93208e5e..1bbf75c5d6 100644 --- a/docs/src/content/hardhat-runner/docs/guides/deploying.md +++ b/docs/src/content/hardhat-runner/docs/guides/deploying.md @@ -1,24 +1,18 @@ # Deploying your contracts -:::tip - -Try [Hardhat Ignition](/ignition) for your deployments! Our new declarative system for deploying smart contracts without getting caught up in execution details. - -::: - -When it comes to deploying, you can use a deployment system like [Hardhat Ignition](/ignition) or you can deploy your smart contracts using scripts. You can deploy the `Lock` contract from the sample project with a deployment script like this: +To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declarative deployment system. You can find a sample Hardhat Ignition module inside the `ignition/modules` directory of the sample project: ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} -<<< @/../packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts +<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts ::: :::tab{value="JavaScript"} -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js +<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js ::: @@ -32,14 +26,14 @@ You can deploy in the `localhost` network following these steps: npx hardhat node ``` -2. Open a new terminal and deploy the smart contract in the `localhost` network +2. Open a new terminal and deploy the Hardhat Ignition module in the `localhost` network ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} ``` - npx hardhat run --network localhost scripts/deploy.ts + npx hardhat ignition deploy ./ignition/modules/LockModule.ts --network localhost ``` ::: @@ -47,7 +41,7 @@ You can deploy in the `localhost` network following these steps: :::tab{value="JavaScript"} ``` - npx hardhat run --network localhost scripts/deploy.js + npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost ``` ::: @@ -57,5 +51,13 @@ You can deploy in the `localhost` network following these steps: As general rule, you can target any network from your Hardhat config using: ``` -npx hardhat run --network <your-network> scripts/deploy.js +npx hardhat ignition deploy ./ignition/modules/LockModule.js --network <your-network> ``` + +Alternatively, you can also deploy to an ephemeral instance of the Hardhat Network by running the command without the `--network` parameter: + +``` +npx hardhat ignition deploy ./ignition/modules/LockModule.js +``` + +Read more about Hardhat Ignition in the [Ignition documentation](/ignition). diff --git a/docs/src/content/hardhat-runner/docs/guides/project-setup.md b/docs/src/content/hardhat-runner/docs/guides/project-setup.md index dff9cc1bde..61b8f291d4 100644 --- a/docs/src/content/hardhat-runner/docs/guides/project-setup.md +++ b/docs/src/content/hardhat-runner/docs/guides/project-setup.md @@ -110,6 +110,7 @@ The initialized project has the following structure: ``` contracts/ +ignition/modules/ scripts/ test/ hardhat.config.js @@ -118,6 +119,7 @@ hardhat.config.js These are the default paths for a Hardhat project. - `contracts/` is where the source files for your contracts should be. +- `ignition/modules/` is where the files exporting your Ignition modules should be. - `test/` is where your tests should go. - `scripts/` is where simple automation scripts go. @@ -129,7 +131,7 @@ When it comes to testing your contracts, the sample project comes with some usef - The built-in [Hardhat Network](/hardhat-network/docs) as the development network to test on, along with the [Hardhat Network Helpers](/hardhat-network-helpers) library to manipulate this network. - [Mocha](https://mochajs.org/) as the test runner, [Chai](https://chaijs.com/) as the assertion library, and the [Hardhat Chai Matchers](/hardhat-chai-matchers) to extend Chai with contracts-related functionality. -- The [`ethers.js`](https://docs.ethers.org/v6/) library to interact with the network and with contracts. +- [Hardhat Ignition](/ignition) to deploy your contracts and the [`ethers.js`](https://docs.ethers.org/v6/) library to interact with interact with them. As well as other useful plugins. You can learn more about this in the [Testing contracts guide](./test-contracts.md). diff --git a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md index f967343d76..f7e8997035 100644 --- a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md +++ b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md @@ -2,7 +2,7 @@ After [compiling your contracts](./compile-contracts.md), the next step is to write some tests to verify that they work as intended. -This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network) and on [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. +This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network) and on [Hardhat Ignition](/ignition), [Mocha](https://mochajs.org/), and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. While this is our recommended test setup, Hardhat is flexible: you can customize the approach or take a completely different path with other tools. @@ -27,8 +27,21 @@ For our first test we’ll deploy the `Lock` contract and assert that the unlock ```tsx import { expect } from "chai"; import hre from "hardhat"; +import { buildModule } from "@nomicfoundation/hardhat-toolbox"; import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; +// We define a module in the test file here, but you can also `import` it. +const LockModule = buildModule("Lock", (m) => { + const lockedAmount = m.getParameter("lockedAmount"); + const unlockTime = m.getParameter("unlockTime"); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + describe("Lock", function () { it("Should set the right unlockTime", async function () { const lockedAmount = 1_000_000_000; @@ -37,8 +50,8 @@ describe("Lock", function () { // deploy a lock contract where funds can be withdrawn // one year in the future - const lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const { lock } = await hre.ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, }); // assert that the value is correct @@ -54,8 +67,21 @@ describe("Lock", function () { ```js const { expect } = require("chai"); const hre = require("hardhat"); +const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +// We define a module in the test file here, but you can also `require` it. +const LockModule = buildModule("Lock", (m) => { + const lockedAmount = m.getParameter("lockedAmount"); + const unlockTime = m.getParameter("unlockTime"); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + describe("Lock", function () { it("Should set the right unlockTime", async function () { const lockedAmount = 1_000_000_000; @@ -64,8 +90,8 @@ describe("Lock", function () { // deploy a lock contract where funds can be withdrawn // one year in the future - const lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const { lock } = await hre.ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, }); // assert that the value is correct @@ -78,9 +104,11 @@ describe("Lock", function () { :::: -First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) +First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), the [`buildModule`](/ignition/docs/guides/creating-modules) function from Hardhat Ignition to deploy and interact with our contracts, and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) -The test itself is what’s inside the callback argument to the `it` function. First we set the values for the amount we want to lock (in [wei](https://ethereum.org/en/glossary/#wei)) and the unlock time. For the latter we use [`time.latest`](</hardhat-network-helpers/docs/reference#latest()>), a network helper that returns the timestamp of the last mined block. Then we deploy the contract itself: we call `ethers.deployContract` with the name of the contract we want to deploy and an array of constructor arguments that has the unlock time. We also pass an object with the transaction parameters. This is optional, but we'll use it to send some ETH by setting its `value` field. +Before we write our actual test, we define an Ignition module to deploy our contract using the `buildModule` function. For brevity, we define our module in the test file here, but the recommended way to define your Ignition modules is in separate files. You can read more about creating Ignition modules in the [Hardhat Ignition docs](/ignition/docs/guides/creating-modules). + +The test itself is what’s inside the callback argument to the `it` function. First we set the values for the amount we want to lock (in [wei](https://ethereum.org/en/glossary/#wei)) and the unlock time. For the latter we use [`time.latest`](</hardhat-network-helpers/docs/reference#latest()>), a network helper that returns the timestamp of the last mined block. Then we deploy the contract itself: we call `hre.ignition.deploy` with our Ignition module we want to deploy and an object containing the deployment parameters `lockedAmount` and `unlockTime`. Finally, we check that the value returned by the `unlockTime()` [getter](https://docs.soliditylang.org/en/v0.8.13/contracts.html#getter-functions) in the contract matches the value that we used when we deployed it. Since all the functions on a contract are async, we have to use the `await` keyword to get its value; otherwise, we would be comparing a promise with a number and this would always fail. @@ -153,7 +181,7 @@ Here again we are calling a function and asserting that it reverts with the corr ### Using fixtures -So far we've deployed the `Lock` contract in each test. This means that at the beginning of each test we have to get the contract factory and then deploy the contract. This might be fine for a single contract but, if you have a more complicated setup, each test will have several lines at the beginning just to set up the desired state, and most of the time these lines will be the same. +So far we've deployed the `Lock` contract in each test. This means that at the beginning of each test we have to redeploy our Ignition module. This might be fine for a single contract but, if you have a more complicated setup, each test will have several lines at the beginning just to set up the desired state, and most of the time these lines will be the same. In a typical Mocha test, this duplication of code is handled with a `beforeEach` hook: @@ -173,9 +201,11 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const result = await hre.ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, }); + + lock = result.lock; }); it("some test", async function () { @@ -198,9 +228,11 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const result = await hre.ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, }); + + lock = result.lock; }); it("some test", async function () { @@ -236,8 +268,8 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - const lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const { lock } = await hre.ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, }); return { lock, unlockTime, lockedAmount }; diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index 35e91c571e..8463e237da 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -2,6 +2,12 @@ Once your contract is ready, the next step is to deploy it to a live network and verify its source code. +:::tip + +Looking for a way to verify your contracts deployed via a Hardhat Ignition module? Check out the Hardhat Ignition [guide to verifying contracts](/ignition/guides/verify). + +::: + Verifying a contract means making its source code public, along with the compiler settings you used, which allows anyone to compile it and compare the generated bytecode with the one that is deployed on-chain. Doing this is extremely important in an open platform like Ethereum. In this guide we'll explain how to do this in the [Etherscan](https://etherscan.io/) explorer, but there are other ways to verify a contract, for example with [Sourcify](https://sourcify.dev/). diff --git a/docs/src/content/hardhat-runner/docs/reference/environment-variables.md b/docs/src/content/hardhat-runner/docs/reference/environment-variables.md index 78345a5b05..c3256396ef 100644 --- a/docs/src/content/hardhat-runner/docs/reference/environment-variables.md +++ b/docs/src/content/hardhat-runner/docs/reference/environment-variables.md @@ -7,25 +7,25 @@ You can use certain environment variables to configure Hardhat's behavior. Every global flag or parameter accepted by Hardhat can also be specified using an environment variable. For example, to select the network you normally do: ```bash -npx hardhat --network localhost run scripts/deploy.js +npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost ``` But you can get the same behavior by setting the `HARDHAT_NETWORK` environment variable: ```bash -HARDHAT_NETWORK=localhost npx hardhat run scripts/deploy.js +HARDHAT_NETWORK=localhost npx hardhat ignition deploy ./ignition/modules/LockModule.js ``` In general, each flag or parameter of the form `--some-option` can be set using the `HARDHAT_SOME_OPTION` environment variable. For flags, which don't accept values, you can enable or disable them by setting them to `true` or `false`: ```bash -HARDHAT_VERBOSE=true npx hardhat run scripts/deploy.js +HARDHAT_VERBOSE=true npx hardhat ignition deploy ./ignition/modules/LockModule.js ``` Options specified with the `--some-option` form have precedence over environment variables. That is, if you run: ```bash -HARDHAT_NETWORK=mainnet npx hardhat run --network localhost scripts/deploy.js +HARDHAT_NETWORK=mainnet npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost ``` then the `localhost` network is going to be used. diff --git a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml b/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml index 36210f0172..0617f9c409 100644 --- a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml +++ b/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml @@ -1,6 +1,7 @@ section-type: plugins section-title: Plugins order: + - "@nomicfoundation/hardhat-ignition" - "@nomicfoundation/hardhat-toolbox" - "@nomicfoundation/hardhat-toolbox-viem" - "@nomicfoundation/hardhat-chai-matchers" diff --git a/docs/src/content/tutorial/boilerplate-project.md b/docs/src/content/tutorial/boilerplate-project.md index 8137fb3168..c0ee4b5c04 100644 --- a/docs/src/content/tutorial/boilerplate-project.md +++ b/docs/src/content/tutorial/boilerplate-project.md @@ -48,7 +48,7 @@ npx hardhat node Here we just install the npm project's dependencies, and by running `npx hardhat node` we spin up an instance of Hardhat Network that you can connect to using your wallet. In a different terminal in the same directory, run: ``` -npx hardhat --network localhost run scripts/deploy.js +npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network localhost ``` This will deploy the contract to Hardhat Network. After this completes, start the react web app: diff --git a/docs/src/content/tutorial/creating-a-new-hardhat-project.md b/docs/src/content/tutorial/creating-a-new-hardhat-project.md index 41460313f7..c2ef079d0d 100644 --- a/docs/src/content/tutorial/creating-a-new-hardhat-project.md +++ b/docs/src/content/tutorial/creating-a-new-hardhat-project.md @@ -143,7 +143,7 @@ npm install --save-dev @nomicfoundation/hardhat-toolbox :::tab{value="npm 6"} ``` -npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 +npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: @@ -151,7 +151,7 @@ npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat :::tab{value=yarn} ``` -yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 +yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md index 80d6f61b32..f83fd48beb 100644 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ b/docs/src/content/tutorial/deploying-to-a-live-network.md @@ -1,52 +1,56 @@ # 7. Deploying to a live network -:::tip - -Try [Hardhat Ignition](/ignition) for your deployments! Our new declarative system for deploying smart contracts without getting caught up in execution details. - -::: - Once you're ready to share your dApp with other people, you may want to deploy it to a live network. This way others can access an instance that's not running locally on your system. The "mainnet" Ethereum network deals with real money, but there are separate "testnet" networks that do not. These testnets provide shared staging environments that do a good job of mimicking the real world scenario without putting real money at stake, and [Ethereum has several](https://ethereum.org/en/developers/docs/networks/#ethereum-testnets), like _Sepolia_ and _Goerli_. We recommend you deploy your contracts to the _Sepolia_ testnet. -At the software level, deploying to a testnet is the same as deploying to mainnet. The only difference is which network you connect to. Let's look into what the code to deploy your contracts using ethers.js would look like. +At the software level, deploying to a testnet is the same as deploying to mainnet. The only difference is which network you connect to. Let's look into what the code to deploy your contracts using [Hardhat Ignition](/ignition) would look like. -The main concepts used are `Signer` and `Contract` which we explained back in the [testing](testing-contracts.md) section. There's nothing new that needs to be done when compared to testing, given that when you're testing your contracts you're _actually_ making a deployment to your development network. This makes the code very similar, or even the same. +In Hardhat Ignition, deployments are defined through Ignition Modules. These modules serve as abstractions, helping you outline and describe the system that you want to deploy. Each Ignition Module encapsulates a group of smart contract instances and operations within your system. -Let's create a new directory `scripts` inside the project root's directory, and paste the following into a `deploy.js` file in that directory: +You can think of Ignition Modules as being conceptually similar to JavaScript modules. In JavaScript, you create a module to group definitions of functions, classes, and values, and then you export some of them. In Hardhat Ignition, you create a module where you group definitions of smart contract instances and operations, and you export some of those contracts. -```js -async function main() { - const [deployer] = await ethers.getSigners(); +Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: - console.log("Deploying contracts with the account:", deployer.address); +```js +const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); - const token = await ethers.deployContract("Token"); +const TokenModule = buildModule("TokenModule", (m) => { + const token = m.contract("Token"); - console.log("Token address:", await token.getAddress()); -} + return { token }; +}); -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); +module.exports = TokenModule; ``` To tell Hardhat to connect to a specific Ethereum network, you can use the `--network` parameter when running any task, like this: ``` -npx hardhat run scripts/deploy.js --network <network-name> +npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network <network-name> ``` With our current configuration, running it without the `--network` parameter would cause the code to run against an embedded instance of Hardhat Network. In this scenario, the deployment actually gets lost when Hardhat finishes running, but it's still useful to test that our deployment code works: ``` -$ npx hardhat run scripts/deploy.js -Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -Token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 +$ npx hardhat ignition deploy ./ignition/modules/TokenModule.js +Compiled 1 Solidity file successfully (evm target: paris). +You are running Hardhat Ignition against an in-process instance of Hardhat Network. +This will execute the deployment, but the results will be lost. +You can use --network <network-name> to deploy to a different network. + +Hardhat Ignition 🚀 + +Deploying [ TokenModule ] + +Batch #1 + Executed TokenModule#Token + +[ TokenModule ] successfully deployed 🚀 + +Deployed Addresses + +TokenModule#Token - 0x5FbDB2315678afecb367f032d93F642f64180aa3 ``` ## Deploying to remote networks @@ -137,7 +141,13 @@ You can learn more about other testnets and find links to their faucets on the [ Finally, run: ``` -npx hardhat run scripts/deploy.js --network sepolia +npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network sepolia ``` If everything went well, you should see the deployed contract address. + +:::tip + +For more information on Hardhat Ignition, check out the [Ignition documentation](/ignition). + +::: diff --git a/docs/src/content/tutorial/final-thoughts.md b/docs/src/content/tutorial/final-thoughts.md index bda100dde5..a957b78a72 100644 --- a/docs/src/content/tutorial/final-thoughts.md +++ b/docs/src/content/tutorial/final-thoughts.md @@ -7,6 +7,7 @@ Here are some links you might find useful throughout your journey: - [Hardhat's Boilerplate](https://github.com/NomicFoundation/hardhat-boilerplate) - [Hardhat's documentation site](/docs/) - [Hardhat Toolbox's documentation](/hardhat-runner/plugins/nomicfoundation-hardhat-toolbox) +- [Hardhat Ignition's documentation](/ignition) - [Hardhat Support Discord server](/discord) - [Ethers.js Documentation](https://docs.ethers.org/v6/) - [Mocha Documentation](https://mochajs.org/) diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md index e6d421e1ee..4fbacd2bb6 100644 --- a/docs/src/content/tutorial/testing-contracts.md +++ b/docs/src/content/tutorial/testing-contracts.md @@ -4,7 +4,7 @@ Writing automated tests when building smart contracts is of crucial importance, To test our contract, we are going to use Hardhat Network, a local Ethereum network designed for development. It comes built-in with Hardhat, and it's used as the default network. You don't need to setup anything to use it. -In our tests we're going to use [ethers.js](https://docs.ethers.org/v6/) to interact with the Ethereum contract we built in the previous section, and we'll use [Mocha](https://mochajs.org/) as our test runner. +In our tests we're going to use [Hardhat Ignition](/ignition) to deploy and interact with the Ethereum contract we built in the previous section, and we'll use [Mocha](https://mochajs.org/) as our test runner. ## Writing tests @@ -14,12 +14,20 @@ Let's start with the code below. We'll explain it next, but for now paste this i ```js const { expect } = require("chai"); +const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); + +// We define a module in the test file here, but you can also `require` it. +const TokenModule = buildModule("TokenModule", (m) => { + const token = m.contract("Token"); + + return { token }; +}); describe("Token contract", function () { it("Deployment should assign the total supply of tokens to the owner", async function () { const [owner] = await ethers.getSigners(); - const hardhatToken = await ethers.deployContract("Token"); + const { token: hardhatToken } = await ignition.deploy(TokenModule); const ownerBalance = await hardhatToken.balanceOf(owner.address); expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); @@ -41,6 +49,17 @@ $ npx hardhat test This means the test passed. Let's now explain each line: +```js +// We define a module in the test file here, but you can also `require` it. +const TokenModule = buildModule("TokenModule", (m) => { + const hardhatToken = m.contract("Token"); + + return { hardhatToken }; +}); +``` + +This is a Hardhat Ignition module. It's a way to deploy and interact with smart contracts in your Hardhat project. In this case, we're defining a module that contains a single contract, our token. We're defining it here in the test file, but you can also define it in a separate file and `require` it. We'll go more in depth with Hardhat Ignition modules in the [deploying to a live network](./deploying-to-a-live-network.md) section. For now it's enough to know that this module will deploy our token contract. + ```js const [owner] = await ethers.getSigners(); ``` @@ -60,17 +79,23 @@ To learn more about `Signer`, you can look at the [Signers documentation](https: ::: ```js -const hardhatToken = await ethers.deployContract("Token"); +const { hardhatToken } = await ignition.deploy(TokenModule); ``` -Calling `ethers.deployContract("Token")` will start the deployment of our token contract, and return a `Promise` that resolves to a `Contract`. This is the object that has a method for each of your smart contract functions. +Calling `ignition.deploy(TokenModule)` will start the deployment of our token contract, and return a `Promise` that resolves to an object containing the `Contract` we returned from `TestModule`. This contract is the object that has a method for each of your smart contract functions. + +Similar to `ethers`, `ignition` is available in the global scope. If you like your code always being explicit, you can add this line at the top: ```js -const ownerBalance = await hardhatToken.balanceOf(owner.address); +const { ignition } = require("hardhat"); ``` Once the contract is deployed, we can call our contract methods on `hardhatToken`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. +```js +const ownerBalance = await hardhatToken.balanceOf(owner.address); +``` + Recall that the account that deploys the token gets its entire supply. By default, `Contract` instances are connected to the first signer. This means that the account in the `owner` variable executed the deployment, and `balanceOf()` should return the entire supply amount. ```js @@ -94,7 +119,7 @@ describe("Token contract", function () { it("Should transfer tokens between accounts", async function() { const [owner, addr1, addr2] = await ethers.getSigners(); - const hardhatToken = await ethers.deployContract("Token"); + const { hardhatToken } = await ignition.deploy(TokenModule); // Transfer 50 tokens from owner to addr1 await hardhatToken.transfer(addr1.address, 50); @@ -119,11 +144,18 @@ const { } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); const { expect } = require("chai"); +// We define a module in the test file here, but you can also `require` it. +const TokenModule = buildModule("TokenModule", (m) => { + const hardhatToken = m.contract("Token"); + + return { hardhatToken }; +}); + describe("Token contract", function () { async function deployTokenFixture() { const [owner, addr1, addr2] = await ethers.getSigners(); - const hardhatToken = await ethers.deployContract("Token"); + const { hardhatToken } = await ignition.deploy(TokenModule); // Fixtures can return anything you consider useful for your tests return { hardhatToken, owner, addr1, addr2 }; @@ -177,6 +209,12 @@ const { loadFixture, } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +// We recommend writing your Hardhat Ignition modules in a separate file and +// importing them into your tests, instead of writing them in the test file. +// The reason for this is that you will be using these same Hardhat Ignition modules +// when you're ready to deploy to live networks as well. +const TokenModule = require("../ignition/modules/TokenModule"); + // `describe` is a Mocha function that allows you to organize your tests. // Having your tests organized makes debugging them easier. All Mocha // functions are available in the global scope. @@ -192,12 +230,9 @@ describe("Token contract", function () { // Get the Signers here. const [owner, addr1, addr2] = await ethers.getSigners(); - // To deploy our contract, we just have to call ethers.deployContract and await - // its waitForDeployment() method, which happens once its transaction has been - // mined. - const hardhatToken = await ethers.deployContract("Token"); - - await hardhatToken.waitForDeployment(); + // To deploy our contract, we just have to call ignition.deploy with our + // imported Hardhat Ignition module. + const { hardhatToken } = await ignition.deploy(TokenModule); // Fixtures can return anything you consider useful for your tests return { hardhatToken, owner, addr1, addr2 }; diff --git a/packages/hardhat-core/sample-projects/javascript-esm/README.md b/packages/hardhat-core/sample-projects/javascript-esm/README.md index e9dd5f3485..f31298a817 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/README.md +++ b/packages/hardhat-core/sample-projects/javascript-esm/README.md @@ -1,6 +1,6 @@ # Sample Hardhat Project -This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. +This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract. Try running some of the following tasks: @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat run scripts/deploy.js +npx hardhat ignition deploy ./ignition/modules/LockModule.js ``` diff --git a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js new file mode 100644 index 0000000000..e22c7bcfcb --- /dev/null +++ b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js @@ -0,0 +1,19 @@ +// ./ignition/LockModule.js +import { buildModule } from "@nomicfoundation/hardhat-toolbox"; + +const currentTimestampInSeconds = Math.round(new Date(2023, 0, 1) / 1000); +const TEN_YEAR_IN_SECS = 10 * 365 * 24 * 60 * 60; +const TEN_YEARS_IN_FUTURE = currentTimestampInSeconds + TEN_YEAR_IN_SECS; + +const ONE_GWEI = BigInt(hre.ethers.parseUnits("1", "gwei")); + +export default buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); diff --git a/packages/hardhat-core/sample-projects/javascript-esm/scripts/deploy.js b/packages/hardhat-core/sample-projects/javascript-esm/scripts/deploy.js deleted file mode 100644 index b17ce00262..0000000000 --- a/packages/hardhat-core/sample-projects/javascript-esm/scripts/deploy.js +++ /dev/null @@ -1,24 +0,0 @@ -// We require the Hardhat Runtime Environment explicitly here. This is optional -// but useful for running the script in a standalone fashion through `node <script>`. -// -// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat -// will compile your contracts, add the Hardhat Runtime Environment's members to the -// global scope, and execute the script. -import hre from "hardhat"; - -const currentTimestampInSeconds = Math.round(Date.now() / 1000); -const unlockTime = currentTimestampInSeconds + 60; - -const lockedAmount = hre.ethers.parseEther("0.001"); - -const lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, -}); - -await lock.waitForDeployment(); - -console.log( - `Lock with ${ethers.formatEther( - lockedAmount - )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}` -); diff --git a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js index e55e5ddbb4..d370c2d9c5 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js @@ -7,6 +7,8 @@ import chai from "chai"; const { expect } = chai; +import LockModule from "../ignition/modules/LockModule"; + describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, @@ -21,8 +23,9 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); + const { lock } = await ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, + }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } diff --git a/packages/hardhat-core/sample-projects/javascript/README.md b/packages/hardhat-core/sample-projects/javascript/README.md index e9dd5f3485..f31298a817 100644 --- a/packages/hardhat-core/sample-projects/javascript/README.md +++ b/packages/hardhat-core/sample-projects/javascript/README.md @@ -1,6 +1,6 @@ # Sample Hardhat Project -This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. +This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract. Try running some of the following tasks: @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat run scripts/deploy.js +npx hardhat ignition deploy ./ignition/modules/LockModule.js ``` diff --git a/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js new file mode 100644 index 0000000000..5dda0242e1 --- /dev/null +++ b/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js @@ -0,0 +1,19 @@ +// ./ignition/LockModule.js +const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); + +const currentTimestampInSeconds = Math.round(new Date(2023, 0, 1) / 1000); +const TEN_YEAR_IN_SECS = 10 * 365 * 24 * 60 * 60; +const TEN_YEARS_IN_FUTURE = currentTimestampInSeconds + TEN_YEAR_IN_SECS; + +const ONE_GWEI = BigInt(hre.ethers.parseUnits("1", "gwei")); + +module.exports = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); diff --git a/packages/hardhat-core/sample-projects/javascript/scripts/deploy.js b/packages/hardhat-core/sample-projects/javascript/scripts/deploy.js deleted file mode 100644 index 39c08d67b2..0000000000 --- a/packages/hardhat-core/sample-projects/javascript/scripts/deploy.js +++ /dev/null @@ -1,33 +0,0 @@ -// We require the Hardhat Runtime Environment explicitly here. This is optional -// but useful for running the script in a standalone fashion through `node <script>`. -// -// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat -// will compile your contracts, add the Hardhat Runtime Environment's members to the -// global scope, and execute the script. -const hre = require("hardhat"); - -async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const unlockTime = currentTimestampInSeconds + 60; - - const lockedAmount = hre.ethers.parseEther("0.001"); - - const lock = await hre.ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, - }); - - await lock.waitForDeployment(); - - console.log( - `Lock with ${ethers.formatEther( - lockedAmount - )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/packages/hardhat-core/sample-projects/javascript/test/Lock.js b/packages/hardhat-core/sample-projects/javascript/test/Lock.js index f0e6ba1b2c..a36eb6669b 100644 --- a/packages/hardhat-core/sample-projects/javascript/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript/test/Lock.js @@ -5,6 +5,8 @@ const { const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); const { expect } = require("chai"); +const LockModule = require("../ignition/modules/LockModule"); + describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, @@ -19,8 +21,9 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); + const { lock } = await ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, + }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } diff --git a/packages/hardhat-core/sample-projects/typescript/README.md b/packages/hardhat-core/sample-projects/typescript/README.md index 7be82e5d68..c678372981 100644 --- a/packages/hardhat-core/sample-projects/typescript/README.md +++ b/packages/hardhat-core/sample-projects/typescript/README.md @@ -1,6 +1,6 @@ # Sample Hardhat Project -This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. +This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract. Try running some of the following tasks: @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat run scripts/deploy.ts +npx hardhat ignition deploy ./ignition/modules/LockModule.ts ``` diff --git a/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts b/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts new file mode 100644 index 0000000000..d951656a6e --- /dev/null +++ b/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts @@ -0,0 +1,23 @@ +import { buildModule } from "@nomicfoundation/hardhat-toolbox"; + +const currentTimestampInSeconds = Math.round( + new Date(2023, 0, 1).valueOf() / 1000 +); +const TEN_YEAR_IN_SECS: number = 10 * 365 * 24 * 60 * 60; +const TEN_YEARS_IN_FUTURE: number = + currentTimestampInSeconds + TEN_YEAR_IN_SECS; + +const ONE_GWEI: bigint = BigInt(hre.ethers.parseUnits("1", "gwei").toString()); + +const LockModule = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + +export default LockModule; diff --git a/packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts b/packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts deleted file mode 100644 index 181925391f..0000000000 --- a/packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ethers } from "hardhat"; - -async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const unlockTime = currentTimestampInSeconds + 60; - - const lockedAmount = ethers.parseEther("0.001"); - - const lock = await ethers.deployContract("Lock", [unlockTime], { - value: lockedAmount, - }); - - await lock.waitForDeployment(); - - console.log( - `Lock with ${ethers.formatEther( - lockedAmount - )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts index a6e866b400..ec08a13d90 100644 --- a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts @@ -6,6 +6,8 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; import { ethers } from "hardhat"; +import LockModule from "../ignition/modules/LockModule"; + describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, @@ -20,8 +22,9 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); + const { lock } = await ignition.deploy(LockModule, { + parameters: { Lock: { lockedAmount, unlockTime } }, + }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } diff --git a/packages/hardhat-toolbox/README.md b/packages/hardhat-toolbox/README.md index 6bd2832620..c20066e1a9 100644 --- a/packages/hardhat-toolbox/README.md +++ b/packages/hardhat-toolbox/README.md @@ -6,7 +6,8 @@ The `@nomicfoundation/hardhat-toolbox` plugin bundles all the commonly used pack When you use this plugin, you'll be able to: -- Deploy and interact with your contracts using [ethers.js](https://docs.ethers.org/v6/) and the [`hardhat-ethers`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers) plugin. +- Deploy and test your contracts with [Hardhat Ignition](https://hardhat.org/ignition). +- Interact with your contracts using [ethers.js](https://docs.ethers.org/v6/) and the [`hardhat-ethers`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers) plugin. - Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and our own [Hardhat Chai Matchers](https://hardhat.org/hardhat-chai-matchers) plugin. - Interact with Hardhat Network with our [Hardhat Network Helpers](https://hardhat.org/hardhat-network-helpers). - Verify the source code of your contracts with the [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify) plugin. diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index 191eda5bfe..5f8207b4d7 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -45,6 +45,8 @@ "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", + "@nomicfoundation/hardhat-ignition": "^0.12.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.12.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", @@ -74,6 +76,8 @@ "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", + "@nomicfoundation/hardhat-ignition": "^0.12.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.12.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", diff --git a/packages/hardhat-toolbox/src/index.ts b/packages/hardhat-toolbox/src/index.ts index 0a58d631e4..b8f683b117 100644 --- a/packages/hardhat-toolbox/src/index.ts +++ b/packages/hardhat-toolbox/src/index.ts @@ -1,5 +1,7 @@ import "@nomicfoundation/hardhat-chai-matchers"; import "@nomicfoundation/hardhat-ethers"; +import "@nomicfoundation/hardhat-ignition"; +import "@nomicfoundation/hardhat-ignition-ethers"; import "@nomicfoundation/hardhat-verify"; import "@typechain/hardhat"; import "hardhat-gas-reporter"; From d953a0d372fe0e5554504bb80a5c47215d03a88a Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 15 Dec 2023 11:20:22 +0000 Subject: [PATCH 03/41] refactor: tweaks for ethers support * chore: update ignition version to v0.13.0 It is only with v0.13.0 that we have a separate ethers package. Apply changes to get a working build: - remove from nav for the moment - exclude toolbox from typescript v4 build check * docs: update toolbox Ignition text feat: update toolbox viem to include HH ignition viem feat: update viem toolbox chore: tweak pnpm lock file fix: update the sample projects docs: update waffle upgrade docs: tweak ignition docs line docs: project setup tweak docs: update testing guide with small tweaks chore: tweak the changeset message chore: cleanup sample projects code docs: split js/ts versions docs: update getting started with missing section changes docs: tweak ephemeral network section docs: one more time docs: clarify intro to deploying section docs: additional language on verify guide docs: update the testing section of tutorial docs: tweaks to testing in tutorial docs: more testing tutorial tweaks docs: testing in tutorial again chore: remove unneeded line from sample project chore: remove unlocktime default in sample Ignition modules should not have changing default parameters, as this will fail reconciliation on repeat runs where the default is taken. chore: tweak import statement in sample chore: linting fix chore: improve comment docs: update the testing guide test: add in check for scopes test: switch back test: keep viem test switched but fix ethers The `chai.assert.isDefined` function continues to hang when run against `this.env`. Chai is proxifying the object under the hood. For reasons we shall never know. --- .changeset/cyan-ligers-brake.md | 6 + .../advanced/migrating-from-hardhat-waffle.md | 4 +- .../hardhat-runner/docs/advanced/scripts.md | 3 +- .../docs/getting-started/index.md | 18 +- .../hardhat-runner/docs/guides/deploying.md | 10 +- .../docs/guides/project-setup.md | 4 +- .../docs/guides/test-contracts.md | 28 ++- .../hardhat-runner/plugins/_dirinfo.yaml | 1 - .../tutorial/deploying-to-a-live-network.md | 10 +- .../src/content/tutorial/testing-contracts.md | 118 +++++------ .../ignition/modules/LockModule.js | 11 +- .../javascript-esm/test/Lock.js | 4 +- .../javascript/ignition/modules/LockModule.js | 11 +- .../sample-projects/javascript/test/Lock.js | 4 +- .../sample-projects/typescript-viem/README.md | 4 +- .../ignition/modules/LockModule.ts | 17 ++ .../typescript-viem/scripts/deploy.ts | 26 --- .../typescript-viem/test/Lock.ts | 14 +- .../typescript/ignition/modules/LockModule.ts | 13 +- .../sample-projects/typescript/test/Lock.ts | 6 +- packages/hardhat-toolbox-viem/README.md | 3 +- packages/hardhat-toolbox-viem/package.json | 2 + packages/hardhat-toolbox-viem/src/index.ts | 1 + .../fixture-projects/only-toolbox/script.js | 5 + packages/hardhat-toolbox-viem/test/test.ts | 2 +- packages/hardhat-toolbox/README.md | 2 +- packages/hardhat-toolbox/package.json | 6 +- packages/hardhat-toolbox/src/index.ts | 4 +- .../fixture-projects/only-toolbox/script.js | 6 + packages/hardhat-toolbox/test/test.ts | 9 +- pnpm-lock.yaml | 183 +++++++++++++++++- 31 files changed, 355 insertions(+), 180 deletions(-) create mode 100644 .changeset/cyan-ligers-brake.md create mode 100644 packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts delete mode 100644 packages/hardhat-core/sample-projects/typescript-viem/scripts/deploy.ts diff --git a/.changeset/cyan-ligers-brake.md b/.changeset/cyan-ligers-brake.md new file mode 100644 index 0000000000..416296d4ae --- /dev/null +++ b/.changeset/cyan-ligers-brake.md @@ -0,0 +1,6 @@ +--- +"@nomicfoundation/hardhat-toolbox": major +"@nomicfoundation/hardhat-toolbox-viem": major +--- + +Include Hardhat Ignition among the toolbox plugins. diff --git a/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md b/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md index 8b89597a1b..a1f8e58e0d 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md +++ b/docs/src/content/hardhat-runner/docs/advanced/migrating-from-hardhat-waffle.md @@ -55,7 +55,7 @@ Follow these steps to migrate your project to Hardhat Toolbox. :::tab{value="npm 6"} ``` - npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 + npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-verify chai@4 ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: @@ -63,7 +63,7 @@ Follow these steps to migrate your project to Hardhat Toolbox. :::tab{value="yarn"} ``` - yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers@1 @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai@4 ethers@5 hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 + yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers@1 @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai@4 ethers@5 hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v6 ``` ::: diff --git a/docs/src/content/hardhat-runner/docs/advanced/scripts.md b/docs/src/content/hardhat-runner/docs/advanced/scripts.md index a89003663e..116f8415f0 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/scripts.md +++ b/docs/src/content/hardhat-runner/docs/advanced/scripts.md @@ -42,7 +42,8 @@ drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test Inside `scripts/` you will find `deploy.js`. Read through its comments to have a better idea of what it does. -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js +<!-- FIX: What needs to be swapped in for this? --> +<!-- <<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js --> Now run the script: diff --git a/docs/src/content/hardhat-runner/docs/getting-started/index.md b/docs/src/content/hardhat-runner/docs/getting-started/index.md index 647a549125..214056a056 100644 --- a/docs/src/content/hardhat-runner/docs/getting-started/index.md +++ b/docs/src/content/hardhat-runner/docs/getting-started/index.md @@ -151,7 +151,7 @@ If you created a TypeScript project, this task will also generate TypeScript bin ### Testing your contracts -Your project comes with tests that use [Hardhat Ignition](/ignition), [Mocha](https://mochajs.org), [Chai](https://www.chaijs.com), and [Ethers.js](https://docs.ethers.org/v6/). +Your project comes with tests that use [Mocha](https://mochajs.org), [Chai](https://www.chaijs.com), [Ethers.js](https://docs.ethers.org/v6/) and [Hardhat Ignition](/ignition). If you take a look in the `test/` folder, you'll see a test file: @@ -259,12 +259,12 @@ Inside the `ignition/modules` folder you will find a file with the following cod :::: -You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.ts`: - ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} +You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.ts`: + ``` $ npx hardhat ignition deploy ./ignition/modules/LockModule.ts Compiled 1 Solidity file successfully (evm target: paris). @@ -290,6 +290,8 @@ LockModule#Lock - 0x5FbDB2315678afecb367f032d93F642f64180aa3 :::tab{value="JavaScript"} +You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.js`: + ``` $ npx hardhat ignition deploy ./ignition/modules/LockModule.js Compiled 1 Solidity file successfully (evm target: paris). @@ -315,7 +317,7 @@ LockModule#Lock - 0x5FbDB2315678afecb367f032d93F642f64180aa3 :::: -To read more about Hardhat Ignition, check out the [Hardhat Ignition documentation](/ignition). +To learn more check out the [Hardhat Ignition documentation](/ignition). ### Connecting a wallet or Dapp to Hardhat Network @@ -330,16 +332,16 @@ Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/ This will expose a JSON-RPC interface to Hardhat Network. To use it connect your wallet or application to `http://127.0.0.1:8545`. -If you want to connect Hardhat to this node, for example to run a deployment script against it, you simply need to run it using `--network localhost`. +If you want to connect Hardhat to this node, for example to run a deployment against it, you simply need to run it using `--network localhost`. -To try this, start a node with `npx hardhat node` and re-run the deployment script using the `network` option: +To try this, start a node with `npx hardhat node` and re-run the deployment using the `network` option: ::::tabsgroup{options="TypeScript,JavaScript"} :::tab{value="TypeScript"} ``` -npx hardhat run scripts/deploy.ts --network localhost +npx hardhat ignition deploy ./ignition/modules/LockModule.ts --network localhost ``` ::: @@ -347,7 +349,7 @@ npx hardhat run scripts/deploy.ts --network localhost :::tab{value="JavaScript"} ``` -npx hardhat run scripts/deploy.js --network localhost +npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost ``` ::: diff --git a/docs/src/content/hardhat-runner/docs/guides/deploying.md b/docs/src/content/hardhat-runner/docs/guides/deploying.md index 1bbf75c5d6..f3bd1be1b8 100644 --- a/docs/src/content/hardhat-runner/docs/guides/deploying.md +++ b/docs/src/content/hardhat-runner/docs/guides/deploying.md @@ -1,6 +1,6 @@ # Deploying your contracts -To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declarative deployment system. You can find a sample Hardhat Ignition module inside the `ignition/modules` directory of the sample project: +To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declarative deployment system. You can deploy the `Lock` contract from the sample project by specifying a deployment with an Ignition Module file like this: ::::tabsgroup{options="TypeScript,JavaScript"} @@ -54,10 +54,6 @@ As general rule, you can target any network from your Hardhat config using: npx hardhat ignition deploy ./ignition/modules/LockModule.js --network <your-network> ``` -Alternatively, you can also deploy to an ephemeral instance of the Hardhat Network by running the command without the `--network` parameter: +If no network is specified, Hardhat Ignition will run against an in-memory instance of Hardhat Network. -``` -npx hardhat ignition deploy ./ignition/modules/LockModule.js -``` - -Read more about Hardhat Ignition in the [Ignition documentation](/ignition). +Read more about Hardhat Ignition in the [Hardhat Ignition documentation](/ignition). diff --git a/docs/src/content/hardhat-runner/docs/guides/project-setup.md b/docs/src/content/hardhat-runner/docs/guides/project-setup.md index 61b8f291d4..2d56741d68 100644 --- a/docs/src/content/hardhat-runner/docs/guides/project-setup.md +++ b/docs/src/content/hardhat-runner/docs/guides/project-setup.md @@ -119,7 +119,7 @@ hardhat.config.js These are the default paths for a Hardhat project. - `contracts/` is where the source files for your contracts should be. -- `ignition/modules/` is where the files exporting your Ignition modules should be. +- `ignition/modules/` is where the Ignition modules that handle contract deployments should be. - `test/` is where your tests should go. - `scripts/` is where simple automation scripts go. @@ -131,7 +131,7 @@ When it comes to testing your contracts, the sample project comes with some usef - The built-in [Hardhat Network](/hardhat-network/docs) as the development network to test on, along with the [Hardhat Network Helpers](/hardhat-network-helpers) library to manipulate this network. - [Mocha](https://mochajs.org/) as the test runner, [Chai](https://chaijs.com/) as the assertion library, and the [Hardhat Chai Matchers](/hardhat-chai-matchers) to extend Chai with contracts-related functionality. -- [Hardhat Ignition](/ignition) to deploy your contracts and the [`ethers.js`](https://docs.ethers.org/v6/) library to interact with interact with them. +- [Hardhat Ignition](/ignition) to deploy your contracts and the [`ethers.js`](https://docs.ethers.org/v6/) library to interact with them. As well as other useful plugins. You can learn more about this in the [Testing contracts guide](./test-contracts.md). diff --git a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md index f7e8997035..f9148a219a 100644 --- a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md +++ b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md @@ -2,7 +2,7 @@ After [compiling your contracts](./compile-contracts.md), the next step is to write some tests to verify that they work as intended. -This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network) and on [Hardhat Ignition](/ignition), [Mocha](https://mochajs.org/), and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. +This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network), [Hardhat Ignition](/ignition) to deploy the contracts and [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. While this is our recommended test setup, Hardhat is flexible: you can customize the approach or take a completely different path with other tools. @@ -27,11 +27,10 @@ For our first test we’ll deploy the `Lock` contract and assert that the unlock ```tsx import { expect } from "chai"; import hre from "hardhat"; -import { buildModule } from "@nomicfoundation/hardhat-toolbox"; +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; -// We define a module in the test file here, but you can also `import` it. -const LockModule = buildModule("Lock", (m) => { +const LockModule = buildModule("LockModule", (m) => { const lockedAmount = m.getParameter("lockedAmount"); const unlockTime = m.getParameter("unlockTime"); @@ -44,14 +43,14 @@ const LockModule = buildModule("Lock", (m) => { describe("Lock", function () { it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000; + const lockedAmount = 1_000_000_000n; const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // deploy a lock contract where funds can be withdrawn // one year in the future const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); // assert that the value is correct @@ -67,11 +66,10 @@ describe("Lock", function () { ```js const { expect } = require("chai"); const hre = require("hardhat"); -const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -// We define a module in the test file here, but you can also `require` it. -const LockModule = buildModule("Lock", (m) => { +const LockModule = buildModule("LockModule", (m) => { const lockedAmount = m.getParameter("lockedAmount"); const unlockTime = m.getParameter("unlockTime"); @@ -84,14 +82,14 @@ const LockModule = buildModule("Lock", (m) => { describe("Lock", function () { it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000; + const lockedAmount = 1_000_000_000n; const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // deploy a lock contract where funds can be withdrawn // one year in the future const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); // assert that the value is correct @@ -104,7 +102,7 @@ describe("Lock", function () { :::: -First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), the [`buildModule`](/ignition/docs/guides/creating-modules) function from Hardhat Ignition to deploy and interact with our contracts, and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) +First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), the [`buildModule`](/ignition/docs/guides/creating-modules) function from Hardhat Ignition to deploy our contracts, and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) Before we write our actual test, we define an Ignition module to deploy our contract using the `buildModule` function. For brevity, we define our module in the test file here, but the recommended way to define your Ignition modules is in separate files. You can read more about creating Ignition modules in the [Hardhat Ignition docs](/ignition/docs/guides/creating-modules). @@ -202,7 +200,7 @@ describe("Lock", function () { unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; const result = await hre.ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); lock = result.lock; @@ -229,7 +227,7 @@ describe("Lock", function () { unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; const result = await hre.ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); lock = result.lock; @@ -269,7 +267,7 @@ describe("Lock", function () { const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); return { lock, unlockTime, lockedAmount }; diff --git a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml b/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml index 0617f9c409..36210f0172 100644 --- a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml +++ b/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml @@ -1,7 +1,6 @@ section-type: plugins section-title: Plugins order: - - "@nomicfoundation/hardhat-ignition" - "@nomicfoundation/hardhat-toolbox" - "@nomicfoundation/hardhat-toolbox-viem" - "@nomicfoundation/hardhat-chai-matchers" diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md index f83fd48beb..f4642a9ba8 100644 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ b/docs/src/content/tutorial/deploying-to-a-live-network.md @@ -6,14 +6,12 @@ The "mainnet" Ethereum network deals with real money, but there are separate "te At the software level, deploying to a testnet is the same as deploying to mainnet. The only difference is which network you connect to. Let's look into what the code to deploy your contracts using [Hardhat Ignition](/ignition) would look like. -In Hardhat Ignition, deployments are defined through Ignition Modules. These modules serve as abstractions, helping you outline and describe the system that you want to deploy. Each Ignition Module encapsulates a group of smart contract instances and operations within your system. +In Hardhat Ignition, deployments are defined through Ignition Modules. These modules are abstractions to describe a deployment; that is, JavaScript functions that specify what you want to deploy. -You can think of Ignition Modules as being conceptually similar to JavaScript modules. In JavaScript, you create a module to group definitions of functions, classes, and values, and then you export some of them. In Hardhat Ignition, you create a module where you group definitions of smart contract instances and operations, and you export some of those contracts. - -Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: +Ignition modules are expected to be within the `./ignition/modules` directory. Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: ```js -const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); const TokenModule = buildModule("TokenModule", (m) => { const token = m.contract("Token"); @@ -148,6 +146,6 @@ If everything went well, you should see the deployed contract address. :::tip -For more information on Hardhat Ignition, check out the [Ignition documentation](/ignition). +For more information on Hardhat Ignition, including how to verify deployments via Etherscan, check out the [Ignition documentation](/ignition). ::: diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md index 4fbacd2bb6..838918b00d 100644 --- a/docs/src/content/tutorial/testing-contracts.md +++ b/docs/src/content/tutorial/testing-contracts.md @@ -14,9 +14,8 @@ Let's start with the code below. We'll explain it next, but for now paste this i ```js const { expect } = require("chai"); -const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); -// We define a module in the test file here, but you can also `require` it. const TokenModule = buildModule("TokenModule", (m) => { const token = m.contract("Token"); @@ -27,10 +26,10 @@ describe("Token contract", function () { it("Deployment should assign the total supply of tokens to the owner", async function () { const [owner] = await ethers.getSigners(); - const { token: hardhatToken } = await ignition.deploy(TokenModule); + const { token } = await ignition.deploy(TokenModule); - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); + const ownerBalance = await token.balanceOf(owner.address); + expect(await token.totalSupply()).to.equal(ownerBalance); }); }); ``` @@ -50,15 +49,14 @@ $ npx hardhat test This means the test passed. Let's now explain each line: ```js -// We define a module in the test file here, but you can also `require` it. const TokenModule = buildModule("TokenModule", (m) => { - const hardhatToken = m.contract("Token"); + const token = m.contract("Token"); - return { hardhatToken }; + return { token }; }); ``` -This is a Hardhat Ignition module. It's a way to deploy and interact with smart contracts in your Hardhat project. In this case, we're defining a module that contains a single contract, our token. We're defining it here in the test file, but you can also define it in a separate file and `require` it. We'll go more in depth with Hardhat Ignition modules in the [deploying to a live network](./deploying-to-a-live-network.md) section. For now it's enough to know that this module will deploy our token contract. +This is a Hardhat Ignition module. It's a way to deploy smart contracts in your Hardhat project. In this case, we're defining a module that deploys a single contract, our token. We're defining it inline in the test file, but you can also define it in a separate file within the `./ignition/modules` directory. We'll discuss Hardhat Ignition modules in depth in the [deploying to a live network](./deploying-to-a-live-network.md) section. For now it's enough to know that this module will deploy our token contract. ```js const [owner] = await ethers.getSigners(); @@ -79,27 +77,27 @@ To learn more about `Signer`, you can look at the [Signers documentation](https: ::: ```js -const { hardhatToken } = await ignition.deploy(TokenModule); +const { token } = await ignition.deploy(TokenModule); ``` -Calling `ignition.deploy(TokenModule)` will start the deployment of our token contract, and return a `Promise` that resolves to an object containing the `Contract` we returned from `TestModule`. This contract is the object that has a method for each of your smart contract functions. +Calling `await ignition.deploy(TokenModule)` will deploy an instance of the `Token` contract and return it as part of the results object. This contract is available as the `token` property of the results object. It is an `ethers` contract instance that acts as a proxy for the on-chain contract and has methods for each of `Token` contract's functions. -Similar to `ethers`, `ignition` is available in the global scope. If you like your code always being explicit, you can add this line at the top: +Similarly to `ethers`, `ignition` is available in the global scope. You can expand the Hardhat require line at the top of your test file to make it explicit: ```js -const { ignition } = require("hardhat"); +const { ignition, ethers } = require("hardhat"); ``` -Once the contract is deployed, we can call our contract methods on `hardhatToken`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. +Once the contract is deployed, we can call our contract methods on `token`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. ```js -const ownerBalance = await hardhatToken.balanceOf(owner.address); +const ownerBalance = await token.balanceOf(owner.address); ``` -Recall that the account that deploys the token gets its entire supply. By default, `Contract` instances are connected to the first signer. This means that the account in the `owner` variable executed the deployment, and `balanceOf()` should return the entire supply amount. +Recall that the account that deploys the token gets its entire supply. By default, an Ignition module is deployed with the first Hardhat account. `ethers.getSigners()` mirrors this ordering which means that the account in the `owner` variable executed the deployment, and that `balanceOf()` should return the entire supply amount. ```js -expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); +expect(await token.totalSupply()).to.equal(ownerBalance); ``` Here we're again using our `Contract` instance to call a smart contract function in our Solidity code. `totalSupply()` returns the token's supply amount and we're checking that it's equal to `ownerBalance`, as it should be. @@ -119,15 +117,15 @@ describe("Token contract", function () { it("Should transfer tokens between accounts", async function() { const [owner, addr1, addr2] = await ethers.getSigners(); - const { hardhatToken } = await ignition.deploy(TokenModule); + const { token } = await ignition.deploy(TokenModule); // Transfer 50 tokens from owner to addr1 - await hardhatToken.transfer(addr1.address, 50); - expect(await hardhatToken.balanceOf(addr1.address)).to.equal(50); + await token.transfer(addr1.address, 50); + expect(await token.balanceOf(addr1.address)).to.equal(50); // Transfer 50 tokens from addr1 to addr2 - await hardhatToken.connect(addr1).transfer(addr2.address, 50); - expect(await hardhatToken.balanceOf(addr2.address)).to.equal(50); + await token.connect(addr1).transfer(addr2.address, 50); + expect(await token.balanceOf(addr2.address)).to.equal(50); }); }); ``` @@ -146,43 +144,45 @@ const { expect } = require("chai"); // We define a module in the test file here, but you can also `require` it. const TokenModule = buildModule("TokenModule", (m) => { - const hardhatToken = m.contract("Token"); + const token = m.contract("Token"); - return { hardhatToken }; + return { token }; }); describe("Token contract", function () { async function deployTokenFixture() { const [owner, addr1, addr2] = await ethers.getSigners(); - const { hardhatToken } = await ignition.deploy(TokenModule); + const { token } = await ignition.deploy(TokenModule); // Fixtures can return anything you consider useful for your tests - return { hardhatToken, owner, addr1, addr2 }; + return { token, owner, addr1, addr2 }; } it("Should assign the total supply of tokens to the owner", async function () { - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); + const { token, owner } = await loadFixture(deployTokenFixture); - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); + const ownerBalance = await token.balanceOf(owner.address); + expect(await token.totalSupply()).to.equal(ownerBalance); }); it("Should transfer tokens between accounts", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( + const { token, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect( - hardhatToken.transfer(addr1.address, 50) - ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); + await expect(token.transfer(addr1.address, 50)).to.changeTokenBalances( + token, + [owner, addr1], + [-50, 50] + ); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account await expect( - hardhatToken.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); + token.connect(addr1).transfer(addr2.address, 50) + ).to.changeTokenBalances(token, [addr1, addr2], [-50, 50]); }); }); ``` @@ -232,10 +232,10 @@ describe("Token contract", function () { // To deploy our contract, we just have to call ignition.deploy with our // imported Hardhat Ignition module. - const { hardhatToken } = await ignition.deploy(TokenModule); + const { token } = await ignition.deploy(TokenModule); // Fixtures can return anything you consider useful for your tests - return { hardhatToken, owner, addr1, addr2 }; + return { token, owner, addr1, addr2 }; } // You can nest describe calls to create subsections. @@ -247,71 +247,71 @@ describe("Token contract", function () { it("Should set the right owner", async function () { // We use loadFixture to setup our environment, and then assert that // things went well - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); + const { token, owner } = await loadFixture(deployTokenFixture); // `expect` receives a value and wraps it in an assertion object. These // objects have a lot of utility methods to assert values. // This test expects the owner variable stored in the contract to be // equal to our Signer's owner. - expect(await hardhatToken.owner()).to.equal(owner.address); + expect(await token.owner()).to.equal(owner.address); }); it("Should assign the total supply of tokens to the owner", async function () { - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); + const { token, owner } = await loadFixture(deployTokenFixture); + const ownerBalance = await token.balanceOf(owner.address); + expect(await token.totalSupply()).to.equal(ownerBalance); }); }); describe("Transactions", function () { it("Should transfer tokens between accounts", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( + const { token, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect( - hardhatToken.transfer(addr1.address, 50) - ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); + await expect(token.transfer(addr1.address, 50)).to.changeTokenBalances( + token, + [owner, addr1], + [-50, 50] + ); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account await expect( - hardhatToken.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); + token.connect(addr1).transfer(addr2.address, 50) + ).to.changeTokenBalances(token, [addr1, addr2], [-50, 50]); }); it("Should emit Transfer events", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( + const { token, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect(hardhatToken.transfer(addr1.address, 50)) - .to.emit(hardhatToken, "Transfer") + await expect(token.transfer(addr1.address, 50)) + .to.emit(token, "Transfer") .withArgs(owner.address, addr1.address, 50); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account - await expect(hardhatToken.connect(addr1).transfer(addr2.address, 50)) - .to.emit(hardhatToken, "Transfer") + await expect(token.connect(addr1).transfer(addr2.address, 50)) + .to.emit(token, "Transfer") .withArgs(addr1.address, addr2.address, 50); }); it("Should fail if sender doesn't have enough tokens", async function () { - const { hardhatToken, owner, addr1 } = await loadFixture( - deployTokenFixture - ); - const initialOwnerBalance = await hardhatToken.balanceOf(owner.address); + const { token, owner, addr1 } = await loadFixture(deployTokenFixture); + const initialOwnerBalance = await token.balanceOf(owner.address); // Try to send 1 token from addr1 (0 tokens) to owner. // `require` will evaluate false and revert the transaction. await expect( - hardhatToken.connect(addr1).transfer(owner.address, 1) + token.connect(addr1).transfer(owner.address, 1) ).to.be.revertedWith("Not enough tokens"); // Owner balance shouldn't have changed. - expect(await hardhatToken.balanceOf(owner.address)).to.equal( + expect(await token.balanceOf(owner.address)).to.equal( initialOwnerBalance ); }); diff --git a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js index e22c7bcfcb..ccb7b43b8e 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js @@ -1,14 +1,9 @@ -// ./ignition/LockModule.js -import { buildModule } from "@nomicfoundation/hardhat-toolbox"; +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; -const currentTimestampInSeconds = Math.round(new Date(2023, 0, 1) / 1000); -const TEN_YEAR_IN_SECS = 10 * 365 * 24 * 60 * 60; -const TEN_YEARS_IN_FUTURE = currentTimestampInSeconds + TEN_YEAR_IN_SECS; - -const ONE_GWEI = BigInt(hre.ethers.parseUnits("1", "gwei")); +const ONE_GWEI = 1_000_000_000n; export default buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const unlockTime = m.getParameter("unlockTime"); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js index d370c2d9c5..af1fb4c270 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js @@ -15,7 +15,7 @@ describe("Lock", function () { // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000; + const ONE_GWEI = 1_000_000_000n; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -24,7 +24,7 @@ describe("Lock", function () { const [owner, otherAccount] = await ethers.getSigners(); const { lock } = await ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; diff --git a/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js index 5dda0242e1..a83eb005cd 100644 --- a/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js +++ b/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js @@ -1,14 +1,9 @@ -// ./ignition/LockModule.js -const { buildModule } = require("@nomicfoundation/hardhat-toolbox"); +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); -const currentTimestampInSeconds = Math.round(new Date(2023, 0, 1) / 1000); -const TEN_YEAR_IN_SECS = 10 * 365 * 24 * 60 * 60; -const TEN_YEARS_IN_FUTURE = currentTimestampInSeconds + TEN_YEAR_IN_SECS; - -const ONE_GWEI = BigInt(hre.ethers.parseUnits("1", "gwei")); +const ONE_GWEI = 1_000_000_000n; module.exports = buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const unlockTime = m.getParameter("unlockTime"); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/javascript/test/Lock.js b/packages/hardhat-core/sample-projects/javascript/test/Lock.js index a36eb6669b..3dc456fa22 100644 --- a/packages/hardhat-core/sample-projects/javascript/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript/test/Lock.js @@ -13,7 +13,7 @@ describe("Lock", function () { // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000; + const ONE_GWEI = 1_000_000_000n; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -22,7 +22,7 @@ describe("Lock", function () { const [owner, otherAccount] = await ethers.getSigners(); const { lock } = await ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; diff --git a/packages/hardhat-core/sample-projects/typescript-viem/README.md b/packages/hardhat-core/sample-projects/typescript-viem/README.md index 7be82e5d68..c678372981 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/README.md +++ b/packages/hardhat-core/sample-projects/typescript-viem/README.md @@ -1,6 +1,6 @@ # Sample Hardhat Project -This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract. +This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract. Try running some of the following tasks: @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat run scripts/deploy.ts +npx hardhat ignition deploy ./ignition/modules/LockModule.ts ``` diff --git a/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts b/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts new file mode 100644 index 0000000000..f25dd28d79 --- /dev/null +++ b/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts @@ -0,0 +1,17 @@ +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; +import { parseEther } from "viem"; + +const ONE_GWEI: bigint = parseEther("0.001"); + +const LockModule = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime"); + const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + +export default LockModule; diff --git a/packages/hardhat-core/sample-projects/typescript-viem/scripts/deploy.ts b/packages/hardhat-core/sample-projects/typescript-viem/scripts/deploy.ts deleted file mode 100644 index 44dc5df8af..0000000000 --- a/packages/hardhat-core/sample-projects/typescript-viem/scripts/deploy.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { formatEther, parseEther } from "viem"; -import hre from "hardhat"; - -async function main() { - const currentTimestampInSeconds = Math.round(Date.now() / 1000); - const unlockTime = BigInt(currentTimestampInSeconds + 60); - - const lockedAmount = parseEther("0.001"); - - const lock = await hre.viem.deployContract("Lock", [unlockTime], { - value: lockedAmount, - }); - - console.log( - `Lock with ${formatEther( - lockedAmount - )}ETH and unlock timestamp ${unlockTime} deployed to ${lock.address}` - ); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts index 59d6906d96..6c51e4d463 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts @@ -6,6 +6,8 @@ import { expect } from "chai"; import hre from "hardhat"; import { getAddress, parseGwei } from "viem"; +import LockModule from "../ignition/modules/LockModule"; + describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, @@ -14,13 +16,13 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const lockedAmount = parseGwei("1"); - const unlockTime = BigInt((await time.latest()) + ONE_YEAR_IN_SECS); + const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await hre.viem.getWalletClients(); - const lock = await hre.viem.deployContract("Lock", [unlockTime], { - value: lockedAmount, + const { lock } = await hre.ignition.deploy(LockModule, { + parameters: { LockModule: { lockedAmount, unlockTime } }, }); const publicClient = await hre.viem.getPublicClient(); @@ -45,7 +47,9 @@ describe("Lock", function () { it("Should set the right owner", async function () { const { lock, owner } = await loadFixture(deployOneYearLockFixture); - expect(await lock.read.owner()).to.equal(getAddress(owner.account.address)); + expect(await lock.read.owner()).to.equal( + getAddress(owner.account.address) + ); }); it("Should receive and store the funds to lock", async function () { @@ -123,7 +127,7 @@ describe("Lock", function () { await publicClient.waitForTransactionReceipt({ hash }); // get the withdrawal events in the latest block - const withdrawalEvents = await lock.getEvents.Withdrawal() + const withdrawalEvents = await lock.getEvents.Withdrawal(); expect(withdrawalEvents).to.have.lengthOf(1); expect(withdrawalEvents[0].args.amount).to.equal(lockedAmount); }); diff --git a/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts b/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts index d951656a6e..3e8938ad9b 100644 --- a/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts +++ b/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts @@ -1,16 +1,9 @@ -import { buildModule } from "@nomicfoundation/hardhat-toolbox"; +import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; -const currentTimestampInSeconds = Math.round( - new Date(2023, 0, 1).valueOf() / 1000 -); -const TEN_YEAR_IN_SECS: number = 10 * 365 * 24 * 60 * 60; -const TEN_YEARS_IN_FUTURE: number = - currentTimestampInSeconds + TEN_YEAR_IN_SECS; - -const ONE_GWEI: bigint = BigInt(hre.ethers.parseUnits("1", "gwei").toString()); +const ONE_GWEI: bigint = 1_000_000_000n; const LockModule = buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime", TEN_YEARS_IN_FUTURE); + const unlockTime = m.getParameter("unlockTime"); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts index ec08a13d90..930979a2d3 100644 --- a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts @@ -4,7 +4,7 @@ import { } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; -import { ethers } from "hardhat"; +import { ethers, ignition } from "hardhat"; import LockModule from "../ignition/modules/LockModule"; @@ -14,7 +14,7 @@ describe("Lock", function () { // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000; + const ONE_GWEI = 1_000_000_000n; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -23,7 +23,7 @@ describe("Lock", function () { const [owner, otherAccount] = await ethers.getSigners(); const { lock } = await ignition.deploy(LockModule, { - parameters: { Lock: { lockedAmount, unlockTime } }, + parameters: { LockModule: { lockedAmount, unlockTime } }, }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; diff --git a/packages/hardhat-toolbox-viem/README.md b/packages/hardhat-toolbox-viem/README.md index c6ec648044..51ff7fb1b7 100644 --- a/packages/hardhat-toolbox-viem/README.md +++ b/packages/hardhat-toolbox-viem/README.md @@ -6,8 +6,9 @@ The `@nomicfoundation/hardhat-toolbox-viem` plugin bundles all the commonly used When you use this plugin, you'll be able to: -- Deploy and interact with your contracts using [Viem](https://viem.sh/) and the [`hardhat-viem`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-viem) plugin. +- Interact with your contracts using [Viem](https://viem.sh/) and the [`hardhat-viem`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-viem) plugin. - Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and [Chai as Promised](https://github.com/domenic/chai-as-promised#chai-assertions-for-promises). Note: the plugin Hardhat Chai Matchers is currently not available for Viem. +- Deploy your contracts with [Hardhat Ignition](https://hardhat.org/ignition). - Interact with Hardhat Network with our [Hardhat Network Helpers](https://hardhat.org/hardhat-network-helpers). - Verify the source code of your contracts with the [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify) plugin. - Get metrics on the gas used by your contracts with the [hardhat-gas-reporter](https://github.com/cgewecke/hardhat-gas-reporter) plugin. diff --git a/packages/hardhat-toolbox-viem/package.json b/packages/hardhat-toolbox-viem/package.json index 500bf6a34e..6304071a19 100644 --- a/packages/hardhat-toolbox-viem/package.json +++ b/packages/hardhat-toolbox-viem/package.json @@ -45,6 +45,7 @@ "devDependencies": { "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", @@ -71,6 +72,7 @@ "viem": "^2.7.6" }, "peerDependencies": { + "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", diff --git a/packages/hardhat-toolbox-viem/src/index.ts b/packages/hardhat-toolbox-viem/src/index.ts index c3e0f8d0f3..f166ee5e6c 100644 --- a/packages/hardhat-toolbox-viem/src/index.ts +++ b/packages/hardhat-toolbox-viem/src/index.ts @@ -1,5 +1,6 @@ import "@nomicfoundation/hardhat-verify"; import "@nomicfoundation/hardhat-viem"; +import "@nomicfoundation/hardhat-ignition-viem"; import "hardhat-gas-reporter"; import "solidity-coverage"; import "./internal/chai-setup"; diff --git a/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js index 7a6ae79dd4..1247c84d46 100644 --- a/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js +++ b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js @@ -10,6 +10,11 @@ async function main() { assert(taskNames.includes("verify")); assert(taskNames.includes("coverage")); + // check that the expected scopes are there + const scopeNames = Object.keys(scopes); + assert(scopeNames.includes("vars")); + assert(scopeNames.includes("ignition")); + // assert that chai-as-promised is loaded assert(chai.assert.eventually); } diff --git a/packages/hardhat-toolbox-viem/test/test.ts b/packages/hardhat-toolbox-viem/test/test.ts index 1b77777598..9bda13607e 100644 --- a/packages/hardhat-toolbox-viem/test/test.ts +++ b/packages/hardhat-toolbox-viem/test/test.ts @@ -20,7 +20,7 @@ describe("hardhat-toolbox-viem", function () { useEnvironment("with-gas-reporter-config"); it("Should not crash while loading the HRE", async function () { - assert.isDefined(this.env); + assert.isDefined(this.env, "The environment should be loaded"); }); }); }); diff --git a/packages/hardhat-toolbox/README.md b/packages/hardhat-toolbox/README.md index c20066e1a9..a3c8e86803 100644 --- a/packages/hardhat-toolbox/README.md +++ b/packages/hardhat-toolbox/README.md @@ -6,9 +6,9 @@ The `@nomicfoundation/hardhat-toolbox` plugin bundles all the commonly used pack When you use this plugin, you'll be able to: -- Deploy and test your contracts with [Hardhat Ignition](https://hardhat.org/ignition). - Interact with your contracts using [ethers.js](https://docs.ethers.org/v6/) and the [`hardhat-ethers`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers) plugin. - Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and our own [Hardhat Chai Matchers](https://hardhat.org/hardhat-chai-matchers) plugin. +- Deploy your contracts with [Hardhat Ignition](https://hardhat.org/ignition). - Interact with Hardhat Network with our [Hardhat Network Helpers](https://hardhat.org/hardhat-network-helpers). - Verify the source code of your contracts with the [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify) plugin. - Get metrics on the gas used by your contracts with the [hardhat-gas-reporter](https://github.com/cgewecke/hardhat-gas-reporter) plugin. diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index 5f8207b4d7..8c148f74ae 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -45,8 +45,7 @@ "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition": "^0.12.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.12.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.13.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", @@ -76,8 +75,7 @@ "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition": "^0.12.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.12.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.13.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", diff --git a/packages/hardhat-toolbox/src/index.ts b/packages/hardhat-toolbox/src/index.ts index b8f683b117..df2c51973b 100644 --- a/packages/hardhat-toolbox/src/index.ts +++ b/packages/hardhat-toolbox/src/index.ts @@ -1,11 +1,11 @@ import "@nomicfoundation/hardhat-chai-matchers"; import "@nomicfoundation/hardhat-ethers"; -import "@nomicfoundation/hardhat-ignition"; -import "@nomicfoundation/hardhat-ignition-ethers"; import "@nomicfoundation/hardhat-verify"; +import "@nomicfoundation/hardhat-ignition-ethers"; import "@typechain/hardhat"; import "hardhat-gas-reporter"; import "solidity-coverage"; + /** * If a new official plugin is added, make sure to update: * - The tsconfig.json file diff --git a/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js b/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js index c0ebd4b5fa..8552eccb3b 100644 --- a/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js +++ b/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js @@ -6,9 +6,15 @@ async function main() { // check that the expected tasks are there const taskNames = Object.keys(tasks); + assert(taskNames.includes("verify")); assert(taskNames.includes("coverage")); assert(taskNames.includes("typechain")); + + // check that the expected scopes are there + const scopeNames = Object.keys(scopes); + assert(scopeNames.includes("vars")); + assert(scopeNames.includes("ignition")); } main() diff --git a/packages/hardhat-toolbox/test/test.ts b/packages/hardhat-toolbox/test/test.ts index b977417f79..8dddc9a204 100644 --- a/packages/hardhat-toolbox/test/test.ts +++ b/packages/hardhat-toolbox/test/test.ts @@ -19,15 +19,18 @@ describe("hardhat-toolbox", function () { describe("hardhat-gas-reporter-config", function () { useEnvironment("with-gas-reporter-config"); - it("Should not crash while loading the HRE", async function () { - assert.isDefined(this.env); + it("Should not crash while loading the HRE", function () { + assert.isTrue( + this.env !== undefined && this.env !== null, + "The environment should be loaded" + ); }); }); describe("typechain config", function () { useEnvironment("typechain-config"); - it("should disable typechain overrides for js projects", async function () { + it("should disable typechain overrides for js projects", function () { assert.isTrue(this.env.config.typechain.dontOverrideCompile); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de0eee8113..62e95afbce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1057,6 +1057,9 @@ importers: '@nomicfoundation/hardhat-ethers': specifier: workspace:^3.0.0 version: link:../hardhat-ethers + '@nomicfoundation/hardhat-ignition-ethers': + specifier: ^0.13.0 + version: 0.13.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.13.2)(@nomicfoundation/ignition-core@0.13.2)(ethers@6.11.1)(hardhat@packages+hardhat-core) '@nomicfoundation/hardhat-network-helpers': specifier: workspace:^1.0.0 version: link:../hardhat-network-helpers @@ -1145,6 +1148,9 @@ importers: '@nomicfoundation/eslint-plugin-slow-imports': specifier: workspace:^ version: link:../eslint-plugin-slow-imports + '@nomicfoundation/hardhat-ignition-viem': + specifier: ^0.14.0 + version: 0.14.0(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.14.0)(hardhat@packages+hardhat-core)(viem@2.7.6) '@nomicfoundation/hardhat-network-helpers': specifier: workspace:^1.0.0 version: link:../hardhat-network-helpers @@ -2657,6 +2663,16 @@ packages: '@ethersproject/logger': 5.7.0 '@ethersproject/properties': 5.7.0 + /@ethersproject/address@5.6.1: + resolution: {integrity: sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==} + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + dev: true + /@ethersproject/address@5.7.0: resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} dependencies: @@ -3306,6 +3322,120 @@ packages: '@nomicfoundation/ethereumjs-rlp': 5.0.4 ethereum-cryptography: 0.1.3 + /@nomicfoundation/hardhat-ignition-ethers@0.13.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.13.2)(@nomicfoundation/ignition-core@0.13.2)(ethers@6.11.1)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-REkwFOhcyNqriB3HK5MYVJF4LC+u5cec2JZ5asM5UFmGNTigMMt8GNpPIIkZhp0r0xSFyw6OF3MMcONaZ+ocew==} + peerDependencies: + '@nomicfoundation/hardhat-ethers': ^3.0.4 + '@nomicfoundation/hardhat-ignition': ^0.13.0 + '@nomicfoundation/ignition-core': ^0.13.0 + ethers: ^6.7.0 + hardhat: ^2.18.0 + dependencies: + '@nomicfoundation/hardhat-ethers': link:packages/hardhat-ethers + '@nomicfoundation/hardhat-ignition': 0.13.2(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) + '@nomicfoundation/ignition-core': 0.13.2 + ethers: 6.11.1 + hardhat: link:packages/hardhat-core + dev: true + + /@nomicfoundation/hardhat-ignition-viem@0.14.0(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.14.0)(hardhat@packages+hardhat-core)(viem@2.7.6): + resolution: {integrity: sha512-FmfEseiUIuKZEmIhsStpQ4RrQCjUkXKHO3gGnK0a8XXbVkpXbqoVXhBuI0DzTDMGGQg41ulkthMKFsal2ocQxg==} + peerDependencies: + '@nomicfoundation/hardhat-ignition': ^0.14.0 + '@nomicfoundation/hardhat-viem': ^2.0.0 + '@nomicfoundation/ignition-core': ^0.14.0 + hardhat: ^2.18.0 + viem: ^2.7.6 + dependencies: + '@nomicfoundation/hardhat-ignition': 0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) + '@nomicfoundation/hardhat-viem': link:packages/hardhat-viem + '@nomicfoundation/ignition-core': 0.14.0 + hardhat: link:packages/hardhat-core + viem: 2.7.6(typescript@5.0.4) + dev: true + + /@nomicfoundation/hardhat-ignition@0.13.2(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-KfZkoJ3Zbbo2sSMjVr45LyaWaSQ7RUeGOPidVGdvP7Zf42ZV4A39wZFLWLY1mR00gdw42Y5CWRzUht/ThTH0rQ==} + peerDependencies: + '@nomicfoundation/hardhat-verify': ^2.0.1 + hardhat: ^2.18.0 + dependencies: + '@nomicfoundation/hardhat-verify': link:packages/hardhat-verify + '@nomicfoundation/ignition-core': 0.13.2 + '@nomicfoundation/ignition-ui': 0.13.2 + chalk: 4.1.2 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 10.1.0 + hardhat: link:packages/hardhat-core + prompts: 2.4.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /@nomicfoundation/hardhat-ignition@0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-NkGHARYrLzH/w8hbgbmBHmAe8oF0UrMRYJ7RecBelICFz+Kn0IwHy3S0arfOBiaugv54Me9tkhIsPvQwuApgTA==} + peerDependencies: + '@nomicfoundation/hardhat-verify': ^2.0.1 + hardhat: ^2.18.0 + dependencies: + '@nomicfoundation/hardhat-verify': link:packages/hardhat-verify + '@nomicfoundation/ignition-core': 0.14.0 + '@nomicfoundation/ignition-ui': 0.14.0 + chalk: 4.1.2 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 10.1.0 + hardhat: link:packages/hardhat-core + prompts: 2.4.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /@nomicfoundation/ignition-core@0.13.2: + resolution: {integrity: sha512-YuOsyCMy8C76CkKRZdK2tBx14RvXoBlDcN/BYagTbMiqazKJwUDdH3VdBHvy0OH2j9P6ByDDO0BuWADxF7WjMg==} + dependencies: + '@ethersproject/address': 5.6.1 + cbor: 9.0.2 + debug: 4.3.4(supports-color@8.1.1) + ethers: 6.11.1 + fs-extra: 10.1.0 + immer: 10.0.2 + lodash: 4.17.21 + ndjson: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /@nomicfoundation/ignition-core@0.14.0: + resolution: {integrity: sha512-W7G2SSoQtsV9JRhJRfj8dZKHWkAxd7KU1mbA7M/r7UON5pJXDUr2SVwub3ydPUSgj/HE89JkvbMzHR2qZJcEeA==} + dependencies: + '@ethersproject/address': 5.6.1 + cbor: 9.0.2 + debug: 4.3.4(supports-color@8.1.1) + ethers: 6.11.1 + fs-extra: 10.1.0 + immer: 10.0.2 + lodash: 4.17.21 + ndjson: 2.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /@nomicfoundation/ignition-ui@0.13.2: + resolution: {integrity: sha512-rSwNFMDHyCao6RkX/Bc9waIM8R6sFnSwIf/JcoIXw1GffpKf6M/ObIR5b7S0IbGP5w+sUKEr8MuY//rabHr77Q==} + dev: true + + /@nomicfoundation/ignition-ui@0.14.0: + resolution: {integrity: sha512-aQCEVquuJfSBi3F/ywHygNtbcM9GjshtCxuI2tNDH9+/9pRFF1FL9ZflXcAv9bZD465JLNoQVTnq2XuEbx2EEQ==} + dev: true + /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1: resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} engines: {node: '>= 10'} @@ -4947,6 +5077,13 @@ packages: nofilter: 3.1.0 dev: false + /cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} + engines: {node: '>=16'} + dependencies: + nofilter: 3.1.0 + dev: true + /chai-as-promised@7.1.1(chai@4.4.1): resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} peerDependencies: @@ -7429,6 +7566,10 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} + /immer@10.0.2: + resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==} + dev: true + /immutable@4.3.5: resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} dev: false @@ -7964,6 +8105,11 @@ packages: graceful-fs: 4.2.11 dev: false + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + /kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} @@ -8465,6 +8611,18 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + /ndjson@2.0.0: + resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + json-stringify-safe: 5.0.1 + minimist: 1.2.8 + readable-stream: 3.6.2 + split2: 3.2.2 + through2: 4.0.2 + dev: true + /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -8568,7 +8726,6 @@ packages: /nofilter@3.1.0: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} - dev: false /nopt@3.0.6: resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} @@ -9138,6 +9295,14 @@ packages: asap: 2.0.6 dev: true + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -9831,6 +9996,10 @@ packages: supports-color: 7.2.0 dev: true + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -10022,6 +10191,12 @@ packages: /spdx-license-ids@3.0.17: resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} + /split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + dependencies: + readable-stream: 3.6.2 + dev: true + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -10371,6 +10546,12 @@ packages: any-promise: 1.3.0 dev: false + /through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + dependencies: + readable-stream: 3.6.2 + dev: true + /time-require@0.1.2: resolution: {integrity: sha512-IqcSpa1sVNleRbC9eHnN7p7vwEHNmsjsXUDqjlnvo4+2VLJ7/gIY2XACTBuRhMB4weYbDYKsR3av2ySykRhDIA==} engines: {node: '>= 0.10.0'} From 7267bf83dc3b6e943c2ac01ec00abae2519cb911 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Tue, 13 Feb 2024 16:09:54 +0000 Subject: [PATCH 04/41] chore: bump chai version in toolbox Chai's proxifying magic was failing on the recursive object graph of the HRE + Ignition + Ethers. A version bump to chai resolves the issue. --- packages/hardhat-toolbox/package.json | 3 +-- packages/hardhat-toolbox/test/test.ts | 5 +---- pnpm-lock.yaml | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index 8c148f74ae..5e61530df9 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -39,7 +39,6 @@ "LICENSE", "README.md" ], - "dependencies": {}, "devDependencies": { "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", @@ -55,7 +54,7 @@ "@types/node": "^18.0.0", "@typescript-eslint/eslint-plugin": "5.61.0", "@typescript-eslint/parser": "5.61.0", - "chai": "^4.2.0", + "chai": "^4.4.1", "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", "eslint-plugin-import": "2.27.5", diff --git a/packages/hardhat-toolbox/test/test.ts b/packages/hardhat-toolbox/test/test.ts index 8dddc9a204..4b08055027 100644 --- a/packages/hardhat-toolbox/test/test.ts +++ b/packages/hardhat-toolbox/test/test.ts @@ -20,10 +20,7 @@ describe("hardhat-toolbox", function () { useEnvironment("with-gas-reporter-config"); it("Should not crash while loading the HRE", function () { - assert.isTrue( - this.env !== undefined && this.env !== null, - "The environment should be loaded" - ); + assert.isDefined(this.env, "The environment should be loaded"); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62e95afbce..61ea8daf6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1088,7 +1088,7 @@ importers: specifier: 5.61.0 version: 5.61.0(eslint@8.57.0)(typescript@5.0.4) chai: - specifier: ^4.2.0 + specifier: ^4.4.1 version: 4.4.1 eslint: specifier: ^8.44.0 From 94426aab5f5c18622159652b7e879ba660e8a9fb Mon Sep 17 00:00:00 2001 From: Zoey <morgansliman@gmail.com> Date: Mon, 12 Feb 2024 19:12:39 -0500 Subject: [PATCH 05/41] Update verification guide to use ignition (#4833) * update verification guide to use ignition * docs: add lang to code sections in verify * docs: update the verification guide to use vars * docs: fix linting issue --------- Co-authored-by: John Kane <john@kanej.me> --- .../hardhat-runner/docs/guides/verifying.md | 91 +++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index 8463e237da..74bc43d4f1 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -2,31 +2,48 @@ Once your contract is ready, the next step is to deploy it to a live network and verify its source code. -:::tip +Verifying a contract means making its source code public, along with the compiler settings you used, which allows anyone to compile it and compare the generated bytecode with the one that is deployed on-chain. Doing this is extremely important in an open platform like Ethereum. -Looking for a way to verify your contracts deployed via a Hardhat Ignition module? Check out the Hardhat Ignition [guide to verifying contracts](/ignition/guides/verify). +In this guide we'll explain how to do this in the [Etherscan](https://etherscan.io/) explorer. -::: +:::tip -Verifying a contract means making its source code public, along with the compiler settings you used, which allows anyone to compile it and compare the generated bytecode with the one that is deployed on-chain. Doing this is extremely important in an open platform like Ethereum. +If you'd like to verify on Sourcify instead of Etherscan, or if you wish to verify a contract deployed outside of Hardhat Ignition, you can use the [hardhat-verify plugin](/hardhat-runner/plugins/nomicfoundation-hardhat-verify). -In this guide we'll explain how to do this in the [Etherscan](https://etherscan.io/) explorer, but there are other ways to verify a contract, for example with [Sourcify](https://sourcify.dev/). +::: ## Getting an API key from Etherscan The first thing you need is an API key from Etherscan. To get one, go to [their site](https://etherscan.io/login), sign in (or create an account if you don't have one) and open the "API Keys" tab. Then click the "Add" button and give a name (like "Hardhat") to the API key you are creating. After that you'll see the newly created key in the list. -Open your Hardhat config and add the API key you just created: +Store the API key as the configuration variable `ETHERSCAN_API_KEY`: + +```sh +$ npx hardhat vars set ETHERSCAN_API_KEY +✔ Enter value: ******************************** +``` + +:::tip + +Learn more about setting and using configuration variable in [our guide](/guides/configuration-variables). + +::: + +Open your Hardhat config and set the Etherscan API key as the stored configuration variable `ETHERSCAN_API_KEY`: ::::tabsgroup{options=TypeScript,JavaScript} :::tab{value=TypeScript} ```ts +import { vars } from "hardhat/config"; + +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + export default { // ...rest of the config... etherscan: { - apiKey: "ABCDE12345ABCDE12345ABCDE123456789", + apiKey: ETHERSCAN_API_KEY, }, }; ``` @@ -36,10 +53,14 @@ export default { :::tab{value=JavaScript} ```js +const { vars } = require("hardhat/config"); + +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + module.exports = { // ...rest of the config... etherscan: { - apiKey: "ABCDE12345ABCDE12345ABCDE123456789", + apiKey: ETHERSCAN_API_KEY, }, }; ``` @@ -58,16 +79,19 @@ We are going to use the [Sepolia testnet](https://ethereum.org/en/developers/doc ```js // Go to https://infura.io, sign up, create a new API key -// in its dashboard, and replace "KEY" with it -const INFURA_API_KEY = "KEY"; +// in its dashboard, and store it as the "INFURA_API_KEY" +// configuration variable +const INFURA_API_KEY = vars.get("INFURA_API_KEY"); // Replace this private key with your Sepolia account private key // To export your private key from Coinbase Wallet, go to // Settings > Developer Settings > Show private key // To export your private key from Metamask, open Metamask and // go to Account Details > Export Private Key +// Store the private key as the "SEPOLIA_PRIVATE_KEY" configuration +// variable. // Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); module.exports = { // ...rest of your config... @@ -86,16 +110,19 @@ module.exports = { ```js // Go to https://alchemy.com, sign up, create a new App in -// its dashboard, and replace "KEY" with its key -const ALCHEMY_API_KEY = "KEY"; +// its dashboard, and store it as the "ALCHEMY_API_KEY" +// configuration variable +const ALCHEMY_API_KEY = vars.get("ALCHEMY_API_KEY"); // Replace this private key with your Sepolia account private key // To export your private key from Coinbase Wallet, go to // Settings > Developer Settings > Show private key // To export your private key from Metamask, open Metamask and // go to Account Details > Export Private Key +// Store the private key as the "SEPOLIA_PRIVATE_KEY" configuration +// variable. // Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); module.exports = { // ...rest of your config... @@ -125,32 +152,44 @@ Open your contract and add a comment with something unique, like your GitHub's u contract Lock { ``` -You can now run the deploy script using the newly added Sepolia network: +To run the deployment we will leverage the Ignition module `LockModule` that we created in the [Deploying your contracts](./deploying.md) guide. Run the deployment using Hardhat Ignition and the newly added Sepolia network: -::::tabsgroup{options=TypeScript,JavaScript} +::::tabsgroup{options="TypeScript,JavaScript"} -:::tab{value=TypeScript} +:::tab{value="TypeScript"} -``` -npx hardhat run scripts/deploy.ts --network sepolia +```shell +npx hardhat ignition deploy ignition/modules/LockModule.ts --network sepolia --deployment-id sepolia-deployment ``` ::: -:::tab{value=JavaScript} +:::tab{value="JavaScript"} -``` -npx hardhat run scripts/deploy.js --network sepolia +```shell +npx hardhat ignition deploy ignition/modules/LockModule.js --network sepolia --deployment-id sepolia-deployment ``` ::: :::: -Take note of the address and the unlock time and run the `verify` task with them: +:::tip +The `--deployment-id` flag is optional, but it allows you to give a custom name to your deployment. This makes it easier to refer to later, for instance when you want to verify it. + +::: + +Lastly, to verify the deployed contract, you can run the `ignition verify` task and pass the deployment Id: + +```sh +npx hardhat ignition verify sepolia-deployment ``` -npx hardhat verify --network sepolia <address> <unlock time> + +Alternatively, you can combine deployment and verification into one step, by invoking the `deploy` task with the `--verify` flag: + +```sh +npx hardhat ignition deploy ignition/modules/LockModule.js --network sepolia --deployment-id sepolia-deployment --verify ``` :::tip @@ -159,6 +198,4 @@ If you get an error saying that the address does not have bytecode, it probably ::: -After the task is successfully executed, you'll see a link to the publicly verified code of your contract. - -To learn more about verifying, read the [hardhat-verify](/hardhat-runner/plugins/nomicfoundation-hardhat-verify) documentation. +After the `ignition verify` task is successfully executed, you'll see a link to the publicly verified code of your contract. From eddc2dd313010f4494a34b8a13e68162be664e0f Mon Sep 17 00:00:00 2001 From: Zoey <morgansliman@gmail.com> Date: Wed, 14 Feb 2024 12:57:12 -0500 Subject: [PATCH 06/41] Update scripts guide (#4853) * update scripts guide to remove deployment example * de-emphasize scripts in general --- .../docs/guides/forking-other-networks.md | 2 +- .../hardhat-network/docs/overview/index.md | 4 +- .../docs/advanced/building-plugins.md | 4 +- .../hardhat-runner/docs/advanced/scripts.md | 51 ++++------- .../docs/getting-started/index.md | 4 +- .../hardhat-runner/docs/guides/_dirinfo.yaml | 2 +- .../docs/guides/hardhat-console.md | 2 +- .../docs/guides/project-setup.md | 2 - .../docs/guides/tasks-and-scripts.md | 85 ------------------- .../hardhat-runner/docs/guides/tasks.md | 42 +++++++++ .../hardhat-runner/docs/guides/typescript.md | 14 +-- .../docs/other-guides/ganache-tests.md | 2 +- .../docs/other-guides/truffle-migration.md | 2 +- 13 files changed, 78 insertions(+), 138 deletions(-) delete mode 100644 docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md create mode 100644 docs/src/content/hardhat-runner/docs/guides/tasks.md diff --git a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md b/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md index af7402898f..1df4c3af41 100644 --- a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md +++ b/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md @@ -73,7 +73,7 @@ Hardhat Network will by default fork from a recent mainnet block. While this mig There are two reasons for this: -- The state your tests run against may change between runs. This could cause your tests or scripts to behave differently. +- The state your tests run against may change between runs. This could cause your tests to behave differently. - Pinning enables caching. Every time data is fetched from mainnet, Hardhat Network caches it on disk to speed up future access. If you don't pin the block, there's going to be new data with each new block and the cache won't be useful. We measured up to 20x speed improvements with block pinning. **You will need access to a node with archival data for this to work.** This is why we recommend [Infura] or [Alchemy], since their free plans include archival data. diff --git a/docs/src/content/hardhat-network/docs/overview/index.md b/docs/src/content/hardhat-network/docs/overview/index.md index 0d35fe2d41..def300c2ba 100644 --- a/docs/src/content/hardhat-network/docs/overview/index.md +++ b/docs/src/content/hardhat-network/docs/overview/index.md @@ -25,11 +25,11 @@ When Hardhat executes your tests, scripts or tasks, an in-process Hardhat Networ There's no need to make any changes to your tests or scripts. -Hardhat Network is simply another network. If you wanted to be explicit, you could run, for example, `npx hardhat run --network hardhat scripts/my-script.js`. +Hardhat Network is simply another network. If you wanted to be explicit, you could run, for example, `npx hardhat ignition deploy ./ignition/modules/MyModule.ts --network hardhat`. ### Running stand-alone in order to support wallets and other software -Alternatively, Hardhat Network can run in a stand-alone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a script. To run Hardhat Network in this way, run: +Alternatively, Hardhat Network can run in a stand-alone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a Hardhat Ignition deployment. To run Hardhat Network in this way, run: ``` $ npx hardhat node diff --git a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md b/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md index 163cb670f6..53c4fa0442 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md +++ b/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md @@ -12,7 +12,7 @@ Some examples of things you could achieve by creating a plugin are: running a li ## Extending the Hardhat Runtime Environment -Let’s go through the process of creating a plugin that adds new functionality to the Hardhat Runtime Environment. By doing this, we make sure our new feature is available everywhere. This means your plugin users can access it from tasks, tests, scripts, and the Hardhat console. +Let’s go through the process of creating a plugin that adds new functionality to the Hardhat Runtime Environment. By doing this, we make sure our new feature is available everywhere. This means your plugin users can access it from tasks, tests, scripts and the Hardhat console. The Hardhat Runtime Environment (HRE) is configured through a queue of extension functions that you can add to using the `extendEnvironment()` function. It receives one parameter which is a callback which will be executed after the HRE is initialized. If `extendEnvironment` is called multiple times, its callbacks will be executed in order. @@ -129,7 +129,7 @@ An example on how to add fields to the Hardhat config can be found in [`src/inde To show better stack traces to your users when an error is meant to interrupt a task's execution, please consider throwing `HardhatPluginError` errors, which can be found in `hardhat/plugins`. -If your error originated in your user's code, like a test or script calling one of your functions, you shouldn't use `HardhatPluginError`. +If your error originated in your user's code, like a test calling one of your functions, you shouldn't use `HardhatPluginError`. ### Optimizing your plugin for better startup time diff --git a/docs/src/content/hardhat-runner/docs/advanced/scripts.md b/docs/src/content/hardhat-runner/docs/advanced/scripts.md index 116f8415f0..e91565cc55 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/scripts.md +++ b/docs/src/content/hardhat-runner/docs/advanced/scripts.md @@ -1,10 +1,8 @@ # Writing scripts with Hardhat -<!-- TODO: We should write this guide based on a different common use case for scripts now that Ignition exists --> - In this guide we will go through the steps of creating a script with Hardhat. For a general overview of using Hardhat refer to the [Getting started guide](../getting-started/index.md). -You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a deployment script for your smart contracts. +You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a script that prints the list of available accounts. There are two ways of writing a script that accesses the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). @@ -26,45 +24,32 @@ const hre = require("hardhat"); You can get access to all your tasks and plugins. To run these scripts you simply go through node: `node script.js`. -To try this out, let's look at [a fresh Hardhat project](../guides/project-setup.md). Run `npx hardhat init` and go through the steps to create a JavaScript project. When you're done, your project directory should look like this: - -``` -$ ls -l -total 400 -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 contracts --rw-r--r-- 1 fzeoli staff 195 Jul 30 15:27 hardhat.config.js -drwxr-xr-x 502 fzeoli staff 16064 Jul 30 15:31 node_modules --rw-r--r-- 1 fzeoli staff 194953 Jul 30 15:31 package-lock.json --rw-r--r-- 1 fzeoli staff 365 Jul 30 15:31 package.json -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 scripts -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test -``` +To try this out, create a new directory called `scripts` in your project's root directory. Then, inside that directory, create a file called `accounts.js` with the following content: -Inside `scripts/` you will find `deploy.js`. Read through its comments to have a better idea of what it does. +```js +const hre = require("hardhat"); -<!-- FIX: What needs to be swapped in for this? --> -<!-- <<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js --> +async function main() { + const accounts = await hre.ethers.getSigners(); -Now run the script: + for (const account of accounts) { + console.log(account.address); + } +} -``` -$ node scripts/deploy.js -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); ``` -By accessing the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) at the top, you are allowed to run the script in a standalone fashion. - -Hardhat always runs the compile task when it's invoked via `npx hardhat run`, but in a standalone fashion you may want to call compile manually to make sure everything is compiled. This can be done by calling `hre.run("compile")`. Add the following line at the beginning of the `main` function and re-run the script with node: +Now run the script: -```js -await hre.run("compile"); +```sh +node scripts/accounts.js ``` -``` -$ node scripts/deploy.js -Nothing to compile -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` +By accessing the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) at the top, you are allowed to run the script in a standalone fashion. ### Hardhat arguments diff --git a/docs/src/content/hardhat-runner/docs/getting-started/index.md b/docs/src/content/hardhat-runner/docs/getting-started/index.md index 214056a056..e979871117 100644 --- a/docs/src/content/hardhat-runner/docs/getting-started/index.md +++ b/docs/src/content/hardhat-runner/docs/getting-started/index.md @@ -65,7 +65,7 @@ If you are using Windows, we **strongly recommend** using [WSL 2](https://docs.m ::: -We will explore the basics of creating a Hardhat project with a sample contract, tests of that contract, and a script to deploy it. +We will explore the basics of creating a Hardhat project with a sample contract, tests of that contract, and a Hardhat Ignition module to deploy it. To create the sample project, run `npx hardhat init` in your project folder: @@ -321,7 +321,7 @@ To learn more check out the [Hardhat Ignition documentation](/ignition). ### Connecting a wallet or Dapp to Hardhat Network -By default, Hardhat will spin up a new in-memory instance of Hardhat Network on startup. It's also possible to run Hardhat Network in a standalone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a script. +By default, Hardhat will spin up a new in-memory instance of Hardhat Network on startup. It's also possible to run Hardhat Network in a standalone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a Hardhat Ignition deployment. To run Hardhat Network in this way, run `npx hardhat node`: diff --git a/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml index d45c59fac7..edb595f546 100644 --- a/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml +++ b/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml @@ -6,7 +6,7 @@ order: - /test-contracts - /deploying - /verifying - - /tasks-and-scripts + - /tasks - /hardhat-console - /typescript - /command-line-completion diff --git a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md b/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md index 451a30a51e..7dbab7e72d 100644 --- a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md +++ b/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md @@ -11,7 +11,7 @@ Type ".help" for more information. The `compile` task will be called before opening the console prompt, but you can skip this with the `--no-compile` parameter. -The execution environment for the console is the same as for tasks, scripts and tests. This means the configuration has been processed, and the [Hardhat Runtime Environment] has been initialized and injected into the global scope. +The execution environment for the console is the same as for tasks and tests. This means the configuration has been processed, and the [Hardhat Runtime Environment] has been initialized and injected into the global scope. For example, you'll have access in the global scope to the `config` object: diff --git a/docs/src/content/hardhat-runner/docs/guides/project-setup.md b/docs/src/content/hardhat-runner/docs/guides/project-setup.md index 2d56741d68..59f67066f4 100644 --- a/docs/src/content/hardhat-runner/docs/guides/project-setup.md +++ b/docs/src/content/hardhat-runner/docs/guides/project-setup.md @@ -111,7 +111,6 @@ The initialized project has the following structure: ``` contracts/ ignition/modules/ -scripts/ test/ hardhat.config.js ``` @@ -121,7 +120,6 @@ These are the default paths for a Hardhat project. - `contracts/` is where the source files for your contracts should be. - `ignition/modules/` is where the Ignition modules that handle contract deployments should be. - `test/` is where your tests should go. -- `scripts/` is where simple automation scripts go. If you need to change these paths, take a look at the [paths configuration section](../config/index.md#path-configuration). diff --git a/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md b/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md deleted file mode 100644 index cfe6233697..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md +++ /dev/null @@ -1,85 +0,0 @@ -# Writing tasks and scripts - -At its core, Hardhat is a task runner that allows you to automate your development workflow. It comes with some built-in tasks, like `compile` and `test`, but you can add your own custom tasks as well. - -This guide will show you how to extend Hardhat's functionality using tasks and scripts. It assumes you have initialized a sample project. If you haven't done it, please read [this guide](./project-setup.md) first. - -## Writing Hardhat Tasks - -Let's write a very simple task that prints the list of available accounts, and explore how it works. - -Copy this task definition and paste it into your hardhat config file: - -```js -task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { - const accounts = await hre.ethers.getSigners(); - - for (const account of accounts) { - console.log(account.address); - } -}); -``` - -Now you should be able to run it: - -``` -npx hardhat accounts -``` - -We are using the `task` function to define our new task. Its first argument is the name of the task, and it's what we use in the command line to run it. The second argument is the description of the task, which is printed when you use `npx hardhat help`. - -The third argument is an async function that gets executed when you run the task. It receives two arguments: - -1. An object with the arguments for the task. We didn't define any yet. -2. The [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) or HRE, which contains all the functionality of Hardhat and its plugins. You can also find all of its properties injected into the `global` namespace during the task execution. - -You are free to do anything you want in this function. In this case, we use `ethers.getSigners()` to obtain all the configured accounts and print each of their addresses. - -You can add parameters to your tasks, and Hardhat will handle their parsing and validation for you. - -You can also override existing tasks, which allows you to change how different parts of Hardhat work. - -To learn more about tasks, please read [this guide](../advanced/create-task). - -## Writing Hardhat scripts - -You can write scripts and run them with Hardhat. They can take advantage of the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) to access all of Hardhat's functionality, including the task runner. - -Here's a script that does the same as our `accounts` task. Create an `accounts.js` file in the `scripts` directory with this content: - -```js -async function main() { - const accounts = await ethers.getSigners(); - - for (const account of accounts) { - console.log(account.address); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); -``` - -And run it using the built-in `run` task: - -``` -npx hardhat run scripts/accounts.js -``` - -Note that we are using `ethers` without importing it. This is possible because everything that is available in the Hardhat Runtime Environment is also globally available in the script. - -To learn more about scripts, including how to run them without using Hardhat's CLI, please read [this guide](../advanced/scripts). - -## Choosing between tasks and scripts - -Choosing between tasks and scripts is up to you. If you are in doubt which one you should use, you may find this useful: - -1. If you want to automate a workflow that requires no parameters, a script is probably the best choice. - -2. If the workflow you are automating requires some parameters, consider creating a Hardhat task. - -3. If you need to access the Hardhat Runtime Environment from another tool which has its own CLI, like [`jest`](https://jestjs.io/) or [`ndb`](https://www.npmjs.com/package/ndb), you should write a script. Make sure to import the Hardhat runtime environment explicitly, so it can be [run with that tool instead of Hardhat's CLI](../advanced/scripts#standalone-scripts:-using-hardhat-as-a-library). - -4. If you feel Hardhat's parameter handling is falling short of your needs, you should write a script. Just import the Hardhat runtime environment explicitly, use your own argument parsing logic (e.g. using [`yargs`](https://yargs.js.org/)), and [run it as a standalone Node.js script](../advanced/scripts#standalone-scripts:-using-hardhat-as-a-library). diff --git a/docs/src/content/hardhat-runner/docs/guides/tasks.md b/docs/src/content/hardhat-runner/docs/guides/tasks.md new file mode 100644 index 0000000000..8b434ad84e --- /dev/null +++ b/docs/src/content/hardhat-runner/docs/guides/tasks.md @@ -0,0 +1,42 @@ +# Writing tasks + +At its core, Hardhat is a task runner that allows you to automate your development workflow. It comes with some built-in tasks, like `compile` and `test`, but you can add your own custom tasks as well. + +This guide will show you how to extend Hardhat's functionality using tasks. It assumes you have initialized a sample project. If you haven't done it, please read [this guide](./project-setup.md) first. + +## Writing Hardhat Tasks + +Let's write a very simple task that prints the list of available accounts, and explore how it works. + +Copy this task definition and paste it into your hardhat config file: + +```js +task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { + const accounts = await hre.ethers.getSigners(); + + for (const account of accounts) { + console.log(account.address); + } +}); +``` + +Now you should be able to run it: + +``` +npx hardhat accounts +``` + +We are using the `task` function to define our new task. Its first argument is the name of the task, and it's what we use in the command line to run it. The second argument is the description of the task, which is printed when you use `npx hardhat help`. + +The third argument is an async function that gets executed when you run the task. It receives two arguments: + +1. An object with the arguments for the task. We didn't define any yet. +2. The [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) or HRE, which contains all the functionality of Hardhat and its plugins. You can also find all of its properties injected into the `global` namespace during the task execution. + +You are free to do anything you want in this function. In this case, we use `ethers.getSigners()` to obtain all the configured accounts and print each of their addresses. + +You can add parameters to your tasks, and Hardhat will handle their parsing and validation for you. + +You can also override existing tasks, which allows you to change how different parts of Hardhat work. + +To learn more about tasks, please read [this guide](../advanced/create-task). diff --git a/docs/src/content/hardhat-runner/docs/guides/typescript.md b/docs/src/content/hardhat-runner/docs/guides/typescript.md index da04031ca6..e6556f864d 100644 --- a/docs/src/content/hardhat-runner/docs/guides/typescript.md +++ b/docs/src/content/hardhat-runner/docs/guides/typescript.md @@ -90,7 +90,7 @@ drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 contracts/ drwxr-xr-x 434 pato wheel 13888 Oct 20 12:52 node_modules/ -rw-r--r-- 1 pato wheel 604835 Oct 20 12:52 package-lock.json -rw-r--r-- 1 pato wheel 460 Oct 20 12:52 package.json -drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 scripts/ +drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 ignition/modules/ drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 test/ ``` @@ -118,7 +118,7 @@ Finally, you need to create a [`tsconfig.json`](https://www.typescriptlang.org/d <<< @/../packages/hardhat-core/sample-projects/typescript/tsconfig.json -And that's really all it takes. Now you can write your config, tests, tasks and scripts in TypeScript. +And that's really all it takes. Now you can write your config, tests, tasks and Ignition modules in TypeScript. ## Type-checking your project @@ -128,11 +128,11 @@ For example, if you run `npx hardhat test` and one of your tests has a compilati Since type-checking adds significant overhead, we recommend to do it only in your CI or in pre-commit/pre-push hooks. -## Writing tests and scripts in TypeScript +## Writing tests in TypeScript When using JavaScript, all the properties in the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) are injected into the global scope. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly using, for example, `import { ethers } from "hardhat"`. -Follow the [Getting started guide](../getting-started/index.md) and create a TypeScript project for a complete example on how to write tests and scripts using TypeScript. +Follow the [Getting started guide](../getting-started/index.md) and create a TypeScript project for a complete example on how to write tests using TypeScript. ## Type-safe smart contract interactions @@ -157,7 +157,7 @@ Typescript allows defining custom [path mappings](https://www.typescriptlang.org } ``` -To support this option when running Hardhat tests or scripts, you need to install the package [`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) and register it in your `hardhat.config.ts`: +To support this option when running Hardhat tests, you need to install the package [`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) and register it in your `hardhat.config.ts`: ```typescript import { HardhatUserConfig } from "hardhat/config"; @@ -172,9 +172,9 @@ const config: HardhatUserConfig = { export default config; ``` -## Running your tests and scripts directly with `ts-node` +## Running your tests directly with `ts-node` -When running Hardhat scripts without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). +When running Hardhat tests without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). This can also be enabled with `TS_NODE_FILES=true`. diff --git a/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md b/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md index 6ff3ba1524..84b1f924b6 100644 --- a/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md +++ b/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md @@ -22,7 +22,7 @@ npx hardhat --network localhost test If you don't want to manually start and stop Ganache every time, you can use the `hardhat-ganache` plugin. -This plugin creates a network called `ganache`, and automatically starts and stops Ganache before and after running your tests and scripts. +This plugin creates a network called `ganache`, and automatically starts and stops Ganache before and after running your tests. To use it, you have to install it with npm diff --git a/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md b/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md index 1bb1a9eb55..ac15e2eb1e 100644 --- a/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md +++ b/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md @@ -169,7 +169,7 @@ Once you've written your hardhat-truffle fixtures for your migrations and comple ### Deployment -When it comes to deploying, there are no official plugins that implement a deployment system for Hardhat yet. In the meantime, we recommend [deploying your smart contracts using scripts](../guides/deploying.md), or using [the hardhat-deploy community plugin](https://github.com/wighawag/hardhat-deploy/tree/master). +When it comes to deploying, we recommend using our declarative deployment system, [Hardhat Ignition](/ignition). It's a powerful and flexible system that allows you to define your deployments in code, and it's the recommended way to deploy your contracts with Hardhat. ### Truffle 4 and Web3.js' synchronous calls From f16b22ae1d5259cdb811290e40ad1dea7a1424e6 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 16 Feb 2024 12:02:12 +0000 Subject: [PATCH 07/41] chore: exclude next dir from linting check --- .prettierignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .prettierignore diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..9005ebe57b --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +docs/.next From bd31edae4d2c422fb5eeeff25ab0277859e70bd3 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 16 Feb 2024 12:41:24 +0000 Subject: [PATCH 08/41] chore: tweak the changeset --- .changeset/cyan-ligers-brake.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/cyan-ligers-brake.md b/.changeset/cyan-ligers-brake.md index 416296d4ae..dcd75e876b 100644 --- a/.changeset/cyan-ligers-brake.md +++ b/.changeset/cyan-ligers-brake.md @@ -1,6 +1,7 @@ --- +"hardhat": patch "@nomicfoundation/hardhat-toolbox": major "@nomicfoundation/hardhat-toolbox-viem": major --- -Include Hardhat Ignition among the toolbox plugins. +Include Hardhat Ignition in the toolboxes. From 2895315e036f2f34feec63aa1a5cda036e21a363 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:01:57 +0100 Subject: [PATCH 09/41] fix errors + improve tutorial docs (missing boilerplate step) --- .../creating-a-new-hardhat-project.md | 4 +- .../debugging-with-hardhat-network.md | 2 +- .../tutorial/deploying-to-a-live-network.md | 42 ++++++++++++------- .../src/content/tutorial/testing-contracts.md | 17 ++++++++ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/docs/src/content/tutorial/creating-a-new-hardhat-project.md b/docs/src/content/tutorial/creating-a-new-hardhat-project.md index c2ef079d0d..e2cc269b94 100644 --- a/docs/src/content/tutorial/creating-a-new-hardhat-project.md +++ b/docs/src/content/tutorial/creating-a-new-hardhat-project.md @@ -85,7 +85,7 @@ npx hardhat init Select `Create an empty hardhat.config.js` with your keyboard and hit enter. -```markup{16} +```markup{17} $ npx hardhat init 888 888 888 888 888 888 888 888 888 888 @@ -101,7 +101,7 @@ $ npx hardhat init ? What do you want to do? … Create a JavaScript project Create a TypeScript project - Create a TypeScript project (with Viem) + Create a TypeScript project (with Viem) ❯ Create an empty hardhat.config.js Quit ``` diff --git a/docs/src/content/tutorial/debugging-with-hardhat-network.md b/docs/src/content/tutorial/debugging-with-hardhat-network.md index 879a85b86a..7e667e857a 100644 --- a/docs/src/content/tutorial/debugging-with-hardhat-network.md +++ b/docs/src/content/tutorial/debugging-with-hardhat-network.md @@ -40,7 +40,7 @@ function transfer(address to, uint256 amount) external { The logging output will show when you run your tests: -```markup{8-11,14-17} +```markup{8-9,12-13} $ npx hardhat test Token contract diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md index f4642a9ba8..3f58c27d37 100644 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ b/docs/src/content/tutorial/deploying-to-a-live-network.md @@ -53,35 +53,44 @@ TokenModule#Token - 0x5FbDB2315678afecb367f032d93F642f64180aa3 ## Deploying to remote networks -To deploy to a remote network such as mainnet or any testnet, you need to add a `network` entry to your `hardhat.config.js` file. We’ll use Sepolia for this example, but you can add any network similarly: +To deploy to a remote network such as mainnet or any testnet, you need to add a `network` entry to your `hardhat.config.js` file. We’ll use Sepolia for this example, but you can add any network. For key storage, utilize the `configuration variables`. + +:::tip + +For more information on `vars` and configuration variables, please see our [configuration variables guide](../hardhat-runner/docs/guides/configuration-variables.md). + +::: ::::tabsgroup{options=Infura,Alchemy} :::tab{value=Infura} -```js{5,11,15-20} +```js{4,8,16,22-23} require("@nomicfoundation/hardhat-toolbox"); +// Ensure your configuration variables are set before executing the script +const { vars } = require("hardhat/config"); + // Go to https://infura.io, sign up, create a new API key -// in its dashboard, and replace "KEY" with it -const INFURA_API_KEY = "KEY"; +// in its dashboard, and add it to the configuration variables +const INFURA_API_KEY = vars.get("INFURA_API_KEY"); -// Replace this private key with your Sepolia account private key +// Add your Sepolia account private key to the configuration variables // To export your private key from Coinbase Wallet, go to // Settings > Developer Settings > Show private key // To export your private key from Metamask, open Metamask and // go to Account Details > Export Private Key // Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); module.exports = { - solidity: "{RECOMMENDED_SOLC_VERSION}", + solidity: "0.8.24", networks: { sepolia: { url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, - accounts: [SEPOLIA_PRIVATE_KEY] - } - } + accounts: [SEPOLIA_PRIVATE_KEY], + }, + }, }; ``` @@ -89,20 +98,23 @@ module.exports = { :::tab{value=Alchemy} -```js{5,11,15-20} +```js{4,8,16,22-23} require("@nomicfoundation/hardhat-toolbox"); +// Ensure your configuration variables are set before executing the script +const { vars } = require("hardhat/config"); + // Go to https://alchemy.com, sign up, create a new App in -// its dashboard, and replace "KEY" with its key -const ALCHEMY_API_KEY = "KEY"; +// its dashboard, and add its key to the configuration variables +const ALCHEMY_API_KEY = vars.get("ALCHEMY_API_KEY"); -// Replace this private key with your Sepolia account private key +// Add your Sepolia account private key to the configuration variables // To export your private key from Coinbase Wallet, go to // Settings > Developer Settings > Show private key // To export your private key from Metamask, open Metamask and // go to Account Details > Export Private Key // Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); module.exports = { solidity: "{RECOMMENDED_SOLC_VERSION}", diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md index 838918b00d..a28ebabb12 100644 --- a/docs/src/content/tutorial/testing-contracts.md +++ b/docs/src/content/tutorial/testing-contracts.md @@ -137,6 +137,7 @@ The two tests that we wrote begin with their setup, which in this case means dep You can avoid code duplication and improve the performance of your test suite by using **fixtures**. A fixture is a setup function that is run only the first time it's invoked. On subsequent invocations, instead of re-running it, Hardhat will reset the state of the network to what it was at the point after the fixture was initially executed. ```js +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); const { loadFixture, } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); @@ -193,6 +194,22 @@ Here we wrote a `deployTokenFixture` function that does the necessary setup and Now that we've covered the basics that you'll need for testing your contracts, here's a full test suite for the token with a lot of additional information about Mocha and how to structure your tests. We recommend reading it thoroughly. +First, let's move the TokenModule code into an [Ignition module](/ignition). Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: + +```js +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); + +const TokenModule = buildModule("TokenModule", (m) => { + const token = m.contract("Token"); + + return { token }; +}); + +module.exports = TokenModule; +``` + +Then, let's use this code in the test: + ```js // This is an example test file. Hardhat will run every *.js file in `test/`, // so feel free to add new ones. From 62b873ab24988bef35a3a947038d0efea1fd6442 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Tue, 20 Feb 2024 12:41:27 +0000 Subject: [PATCH 10/41] refactor: switch convention for Module file names Module files should not include the word `Module`. So prefer: `ignition/modules/Lock.ts` to `ignition/modules/LockModule.ts` --- .../hardhat-runner/docs/getting-started/index.md | 16 ++++++++-------- .../hardhat-runner/docs/guides/deploying.md | 10 +++++----- .../hardhat-runner/docs/guides/verifying.md | 6 +++--- .../docs/reference/environment-variables.md | 8 ++++---- docs/src/content/tutorial/boilerplate-project.md | 2 +- .../tutorial/deploying-to-a-live-network.md | 8 ++++---- docs/src/content/tutorial/testing-contracts.md | 2 +- .../sample-projects/javascript-esm/README.md | 2 +- .../ignition/modules/{LockModule.js => Lock.js} | 0 .../sample-projects/javascript-esm/test/Lock.js | 2 +- .../sample-projects/javascript/README.md | 2 +- .../ignition/modules/{LockModule.js => Lock.js} | 0 .../sample-projects/javascript/test/Lock.js | 2 +- .../sample-projects/typescript-viem/README.md | 2 +- .../ignition/modules/{LockModule.ts => Lock.ts} | 0 .../sample-projects/typescript-viem/test/Lock.ts | 2 +- .../sample-projects/typescript/README.md | 2 +- .../ignition/modules/{LockModule.ts => Lock.ts} | 0 .../sample-projects/typescript/test/Lock.ts | 2 +- 19 files changed, 34 insertions(+), 34 deletions(-) rename packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/{LockModule.js => Lock.js} (100%) rename packages/hardhat-core/sample-projects/javascript/ignition/modules/{LockModule.js => Lock.js} (100%) rename packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/{LockModule.ts => Lock.ts} (100%) rename packages/hardhat-core/sample-projects/typescript/ignition/modules/{LockModule.ts => Lock.ts} (100%) diff --git a/docs/src/content/hardhat-runner/docs/getting-started/index.md b/docs/src/content/hardhat-runner/docs/getting-started/index.md index e979871117..55b9dcbeed 100644 --- a/docs/src/content/hardhat-runner/docs/getting-started/index.md +++ b/docs/src/content/hardhat-runner/docs/getting-started/index.md @@ -247,13 +247,13 @@ Inside the `ignition/modules` folder you will find a file with the following cod :::tab{value="TypeScript"} -<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts +<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts ::: :::tab{value="JavaScript"} -<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js +<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js ::: @@ -263,10 +263,10 @@ Inside the `ignition/modules` folder you will find a file with the following cod :::tab{value="TypeScript"} -You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.ts`: +You can deploy it using `npx hardhat ignition deploy ./ignition/modules/Lock.ts`: ``` -$ npx hardhat ignition deploy ./ignition/modules/LockModule.ts +$ npx hardhat ignition deploy ./ignition/modules/Lock.ts Compiled 1 Solidity file successfully (evm target: paris). You are running Hardhat Ignition against an in-process instance of Hardhat Network. This will execute the deployment, but the results will be lost. @@ -290,10 +290,10 @@ LockModule#Lock - 0x5FbDB2315678afecb367f032d93F642f64180aa3 :::tab{value="JavaScript"} -You can deploy it using `npx hardhat ignition deploy ./ignition/modules/LockModule.js`: +You can deploy it using `npx hardhat ignition deploy ./ignition/modules/Lock.js`: ``` -$ npx hardhat ignition deploy ./ignition/modules/LockModule.js +$ npx hardhat ignition deploy ./ignition/modules/Lock.js Compiled 1 Solidity file successfully (evm target: paris). You are running Hardhat Ignition against an in-process instance of Hardhat Network. This will execute the deployment, but the results will be lost. @@ -341,7 +341,7 @@ To try this, start a node with `npx hardhat node` and re-run the deployment usin :::tab{value="TypeScript"} ``` -npx hardhat ignition deploy ./ignition/modules/LockModule.ts --network localhost +npx hardhat ignition deploy ./ignition/modules/Lock.ts --network localhost ``` ::: @@ -349,7 +349,7 @@ npx hardhat ignition deploy ./ignition/modules/LockModule.ts --network localhost :::tab{value="JavaScript"} ``` -npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost +npx hardhat ignition deploy ./ignition/modules/Lock.js --network localhost ``` ::: diff --git a/docs/src/content/hardhat-runner/docs/guides/deploying.md b/docs/src/content/hardhat-runner/docs/guides/deploying.md index f3bd1be1b8..e76df0f158 100644 --- a/docs/src/content/hardhat-runner/docs/guides/deploying.md +++ b/docs/src/content/hardhat-runner/docs/guides/deploying.md @@ -6,13 +6,13 @@ To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declara :::tab{value="TypeScript"} -<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts +<<< @/../packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts ::: :::tab{value="JavaScript"} -<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js +<<< @/../packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js ::: @@ -33,7 +33,7 @@ You can deploy in the `localhost` network following these steps: :::tab{value="TypeScript"} ``` - npx hardhat ignition deploy ./ignition/modules/LockModule.ts --network localhost + npx hardhat ignition deploy ./ignition/modules/Lock.ts --network localhost ``` ::: @@ -41,7 +41,7 @@ You can deploy in the `localhost` network following these steps: :::tab{value="JavaScript"} ``` - npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost + npx hardhat ignition deploy ./ignition/modules/Lock.js --network localhost ``` ::: @@ -51,7 +51,7 @@ You can deploy in the `localhost` network following these steps: As general rule, you can target any network from your Hardhat config using: ``` -npx hardhat ignition deploy ./ignition/modules/LockModule.js --network <your-network> +npx hardhat ignition deploy ./ignition/modules/Lock.js --network <your-network> ``` If no network is specified, Hardhat Ignition will run against an in-memory instance of Hardhat Network. diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index 74bc43d4f1..f3f1075c3d 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -159,7 +159,7 @@ To run the deployment we will leverage the Ignition module `LockModule` that we :::tab{value="TypeScript"} ```shell -npx hardhat ignition deploy ignition/modules/LockModule.ts --network sepolia --deployment-id sepolia-deployment +npx hardhat ignition deploy ignition/modules/Lock.ts --network sepolia --deployment-id sepolia-deployment ``` ::: @@ -167,7 +167,7 @@ npx hardhat ignition deploy ignition/modules/LockModule.ts --network sepolia --d :::tab{value="JavaScript"} ```shell -npx hardhat ignition deploy ignition/modules/LockModule.js --network sepolia --deployment-id sepolia-deployment +npx hardhat ignition deploy ignition/modules/Lock.js --network sepolia --deployment-id sepolia-deployment ``` ::: @@ -189,7 +189,7 @@ npx hardhat ignition verify sepolia-deployment Alternatively, you can combine deployment and verification into one step, by invoking the `deploy` task with the `--verify` flag: ```sh -npx hardhat ignition deploy ignition/modules/LockModule.js --network sepolia --deployment-id sepolia-deployment --verify +npx hardhat ignition deploy ignition/modules/Lock.js --network sepolia --deployment-id sepolia-deployment --verify ``` :::tip diff --git a/docs/src/content/hardhat-runner/docs/reference/environment-variables.md b/docs/src/content/hardhat-runner/docs/reference/environment-variables.md index c3256396ef..3e4e75e63e 100644 --- a/docs/src/content/hardhat-runner/docs/reference/environment-variables.md +++ b/docs/src/content/hardhat-runner/docs/reference/environment-variables.md @@ -7,25 +7,25 @@ You can use certain environment variables to configure Hardhat's behavior. Every global flag or parameter accepted by Hardhat can also be specified using an environment variable. For example, to select the network you normally do: ```bash -npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost +npx hardhat ignition deploy ./ignition/modules/Lock.js --network localhost ``` But you can get the same behavior by setting the `HARDHAT_NETWORK` environment variable: ```bash -HARDHAT_NETWORK=localhost npx hardhat ignition deploy ./ignition/modules/LockModule.js +HARDHAT_NETWORK=localhost npx hardhat ignition deploy ./ignition/modules/Lock.js ``` In general, each flag or parameter of the form `--some-option` can be set using the `HARDHAT_SOME_OPTION` environment variable. For flags, which don't accept values, you can enable or disable them by setting them to `true` or `false`: ```bash -HARDHAT_VERBOSE=true npx hardhat ignition deploy ./ignition/modules/LockModule.js +HARDHAT_VERBOSE=true npx hardhat ignition deploy ./ignition/modules/Lock.js ``` Options specified with the `--some-option` form have precedence over environment variables. That is, if you run: ```bash -HARDHAT_NETWORK=mainnet npx hardhat ignition deploy ./ignition/modules/LockModule.js --network localhost +HARDHAT_NETWORK=mainnet npx hardhat ignition deploy ./ignition/modules/Lock.js --network localhost ``` then the `localhost` network is going to be used. diff --git a/docs/src/content/tutorial/boilerplate-project.md b/docs/src/content/tutorial/boilerplate-project.md index c0ee4b5c04..c0d9c2f74e 100644 --- a/docs/src/content/tutorial/boilerplate-project.md +++ b/docs/src/content/tutorial/boilerplate-project.md @@ -48,7 +48,7 @@ npx hardhat node Here we just install the npm project's dependencies, and by running `npx hardhat node` we spin up an instance of Hardhat Network that you can connect to using your wallet. In a different terminal in the same directory, run: ``` -npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network localhost +npx hardhat ignition deploy ./ignition/modules/Token.js --network localhost ``` This will deploy the contract to Hardhat Network. After this completes, start the react web app: diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md index 3f58c27d37..7b07798798 100644 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ b/docs/src/content/tutorial/deploying-to-a-live-network.md @@ -8,7 +8,7 @@ At the software level, deploying to a testnet is the same as deploying to mainne In Hardhat Ignition, deployments are defined through Ignition Modules. These modules are abstractions to describe a deployment; that is, JavaScript functions that specify what you want to deploy. -Ignition modules are expected to be within the `./ignition/modules` directory. Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: +Ignition modules are expected to be within the `./ignition/modules` directory. Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `Token.js` file in that directory: ```js const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); @@ -25,13 +25,13 @@ module.exports = TokenModule; To tell Hardhat to connect to a specific Ethereum network, you can use the `--network` parameter when running any task, like this: ``` -npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network <network-name> +npx hardhat ignition deploy ./ignition/modules/Token.js --network <network-name> ``` With our current configuration, running it without the `--network` parameter would cause the code to run against an embedded instance of Hardhat Network. In this scenario, the deployment actually gets lost when Hardhat finishes running, but it's still useful to test that our deployment code works: ``` -$ npx hardhat ignition deploy ./ignition/modules/TokenModule.js +$ npx hardhat ignition deploy ./ignition/modules/Token.js Compiled 1 Solidity file successfully (evm target: paris). You are running Hardhat Ignition against an in-process instance of Hardhat Network. This will execute the deployment, but the results will be lost. @@ -151,7 +151,7 @@ You can learn more about other testnets and find links to their faucets on the [ Finally, run: ``` -npx hardhat ignition deploy ./ignition/modules/TokenModule.js --network sepolia +npx hardhat ignition deploy ./ignition/modules/Token.js --network sepolia ``` If everything went well, you should see the deployed contract address. diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md index a28ebabb12..8400bbe803 100644 --- a/docs/src/content/tutorial/testing-contracts.md +++ b/docs/src/content/tutorial/testing-contracts.md @@ -230,7 +230,7 @@ const { // importing them into your tests, instead of writing them in the test file. // The reason for this is that you will be using these same Hardhat Ignition modules // when you're ready to deploy to live networks as well. -const TokenModule = require("../ignition/modules/TokenModule"); +const TokenModule = require("../ignition/modules/Token"); // `describe` is a Mocha function that allows you to organize your tests. // Having your tests organized makes debugging them easier. All Mocha diff --git a/packages/hardhat-core/sample-projects/javascript-esm/README.md b/packages/hardhat-core/sample-projects/javascript-esm/README.md index f31298a817..d04248dab9 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/README.md +++ b/packages/hardhat-core/sample-projects/javascript-esm/README.md @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat ignition deploy ./ignition/modules/LockModule.js +npx hardhat ignition deploy ./ignition/modules/Lock.js ``` diff --git a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js similarity index 100% rename from packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/LockModule.js rename to packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js diff --git a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js index af1fb4c270..ba101f14f5 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js @@ -7,7 +7,7 @@ import chai from "chai"; const { expect } = chai; -import LockModule from "../ignition/modules/LockModule"; +import LockModule from "../ignition/modules/Lock"; describe("Lock", function () { // We define a fixture to reuse the same setup in every test. diff --git a/packages/hardhat-core/sample-projects/javascript/README.md b/packages/hardhat-core/sample-projects/javascript/README.md index f31298a817..d04248dab9 100644 --- a/packages/hardhat-core/sample-projects/javascript/README.md +++ b/packages/hardhat-core/sample-projects/javascript/README.md @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat ignition deploy ./ignition/modules/LockModule.js +npx hardhat ignition deploy ./ignition/modules/Lock.js ``` diff --git a/packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js b/packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js similarity index 100% rename from packages/hardhat-core/sample-projects/javascript/ignition/modules/LockModule.js rename to packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js diff --git a/packages/hardhat-core/sample-projects/javascript/test/Lock.js b/packages/hardhat-core/sample-projects/javascript/test/Lock.js index 3dc456fa22..a14c1767c7 100644 --- a/packages/hardhat-core/sample-projects/javascript/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript/test/Lock.js @@ -5,7 +5,7 @@ const { const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); const { expect } = require("chai"); -const LockModule = require("../ignition/modules/LockModule"); +const LockModule = require("../ignition/modules/Lock"); describe("Lock", function () { // We define a fixture to reuse the same setup in every test. diff --git a/packages/hardhat-core/sample-projects/typescript-viem/README.md b/packages/hardhat-core/sample-projects/typescript-viem/README.md index c678372981..17f8ed190d 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/README.md +++ b/packages/hardhat-core/sample-projects/typescript-viem/README.md @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat ignition deploy ./ignition/modules/LockModule.ts +npx hardhat ignition deploy ./ignition/modules/Lock.ts ``` diff --git a/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts b/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts similarity index 100% rename from packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/LockModule.ts rename to packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts diff --git a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts index 6c51e4d463..9a14bc7b0f 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts @@ -6,7 +6,7 @@ import { expect } from "chai"; import hre from "hardhat"; import { getAddress, parseGwei } from "viem"; -import LockModule from "../ignition/modules/LockModule"; +import LockModule from "../ignition/modules/Lock"; describe("Lock", function () { // We define a fixture to reuse the same setup in every test. diff --git a/packages/hardhat-core/sample-projects/typescript/README.md b/packages/hardhat-core/sample-projects/typescript/README.md index c678372981..17f8ed190d 100644 --- a/packages/hardhat-core/sample-projects/typescript/README.md +++ b/packages/hardhat-core/sample-projects/typescript/README.md @@ -9,5 +9,5 @@ npx hardhat help npx hardhat test REPORT_GAS=true npx hardhat test npx hardhat node -npx hardhat ignition deploy ./ignition/modules/LockModule.ts +npx hardhat ignition deploy ./ignition/modules/Lock.ts ``` diff --git a/packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts b/packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts similarity index 100% rename from packages/hardhat-core/sample-projects/typescript/ignition/modules/LockModule.ts rename to packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts diff --git a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts index 930979a2d3..f60645fbba 100644 --- a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts @@ -6,7 +6,7 @@ import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; import { ethers, ignition } from "hardhat"; -import LockModule from "../ignition/modules/LockModule"; +import LockModule from "../ignition/modules/Lock"; describe("Lock", function () { // We define a fixture to reuse the same setup in every test. From 5697002b8e894265c0daf2970806b275b637ab47 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Tue, 20 Feb 2024 17:08:45 +0000 Subject: [PATCH 11/41] test: fix broken viem sample project test --- .../hardhat-core/sample-projects/typescript-viem/test/Lock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts index 9a14bc7b0f..1cf6706e4c 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts @@ -16,7 +16,7 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const lockedAmount = parseGwei("1"); - const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; + const unlockTime = BigInt((await time.latest()) + ONE_YEAR_IN_SECS); // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await hre.viem.getWalletClients(); From a975a47a7447c7e50621efef1c41aadc4e17a0f3 Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:57:14 +0100 Subject: [PATCH 12/41] error fix: re-add RECOMMENDED_SOLC_VERSION in docs --- docs/src/content/tutorial/deploying-to-a-live-network.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md index 7b07798798..581b75bd11 100644 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ b/docs/src/content/tutorial/deploying-to-a-live-network.md @@ -84,7 +84,7 @@ const INFURA_API_KEY = vars.get("INFURA_API_KEY"); const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); module.exports = { - solidity: "0.8.24", + solidity: "{RECOMMENDED_SOLC_VERSION}", networks: { sepolia: { url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, From 65770b2ab6a0079b2f7a9303069d518e61f4cde1 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 11:31:25 +0000 Subject: [PATCH 13/41] revert using Ignition in test in sample projects We have opted to not force Ignition usage in tests. --- .../sample-projects/javascript-esm/test/Lock.js | 9 +++------ .../sample-projects/javascript/test/Lock.js | 9 +++------ .../sample-projects/typescript-viem/test/Lock.ts | 6 ++---- .../sample-projects/typescript/test/Lock.ts | 11 ++++------- 4 files changed, 12 insertions(+), 23 deletions(-) diff --git a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js index ba101f14f5..e55e5ddbb4 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/test/Lock.js @@ -7,15 +7,13 @@ import chai from "chai"; const { expect } = chai; -import LockModule from "../ignition/modules/Lock"; - describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000n; + const ONE_GWEI = 1_000_000_000; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -23,9 +21,8 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const { lock } = await ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, - }); + const Lock = await ethers.getContractFactory("Lock"); + const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } diff --git a/packages/hardhat-core/sample-projects/javascript/test/Lock.js b/packages/hardhat-core/sample-projects/javascript/test/Lock.js index a14c1767c7..f0e6ba1b2c 100644 --- a/packages/hardhat-core/sample-projects/javascript/test/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript/test/Lock.js @@ -5,15 +5,13 @@ const { const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); const { expect } = require("chai"); -const LockModule = require("../ignition/modules/Lock"); - describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000n; + const ONE_GWEI = 1_000_000_000; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -21,9 +19,8 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const { lock } = await ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, - }); + const Lock = await ethers.getContractFactory("Lock"); + const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } diff --git a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts index 1cf6706e4c..6a746fc57e 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts @@ -6,8 +6,6 @@ import { expect } from "chai"; import hre from "hardhat"; import { getAddress, parseGwei } from "viem"; -import LockModule from "../ignition/modules/Lock"; - describe("Lock", function () { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, @@ -21,8 +19,8 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await hre.viem.getWalletClients(); - const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + const lock = await hre.viem.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); const publicClient = await hre.viem.getPublicClient(); diff --git a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts index f60645fbba..a6e866b400 100644 --- a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts @@ -4,9 +4,7 @@ import { } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; -import { ethers, ignition } from "hardhat"; - -import LockModule from "../ignition/modules/Lock"; +import { ethers } from "hardhat"; describe("Lock", function () { // We define a fixture to reuse the same setup in every test. @@ -14,7 +12,7 @@ describe("Lock", function () { // and reset Hardhat Network to that snapshot in every test. async function deployOneYearLockFixture() { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const ONE_GWEI = 1_000_000_000n; + const ONE_GWEI = 1_000_000_000; const lockedAmount = ONE_GWEI; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; @@ -22,9 +20,8 @@ describe("Lock", function () { // Contracts are deployed using the first signer/account by default const [owner, otherAccount] = await ethers.getSigners(); - const { lock } = await ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, - }); + const Lock = await ethers.getContractFactory("Lock"); + const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; } From 93c269ff3f9e54c816e1c25262306400e1a959af Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 11:47:36 +0000 Subject: [PATCH 14/41] make typescript sample project tests use explicit `hre.ethers` This brings it into line with the viem project. --- .../sample-projects/typescript/test/Lock.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts index a6e866b400..160dbfa163 100644 --- a/packages/hardhat-core/sample-projects/typescript/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/test/Lock.ts @@ -4,7 +4,7 @@ import { } from "@nomicfoundation/hardhat-toolbox/network-helpers"; import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; import { expect } from "chai"; -import { ethers } from "hardhat"; +import hre from "hardhat"; describe("Lock", function () { // We define a fixture to reuse the same setup in every test. @@ -18,9 +18,9 @@ describe("Lock", function () { const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // Contracts are deployed using the first signer/account by default - const [owner, otherAccount] = await ethers.getSigners(); + const [owner, otherAccount] = await hre.ethers.getSigners(); - const Lock = await ethers.getContractFactory("Lock"); + const Lock = await hre.ethers.getContractFactory("Lock"); const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); return { lock, unlockTime, lockedAmount, owner, otherAccount }; @@ -44,7 +44,7 @@ describe("Lock", function () { deployOneYearLockFixture ); - expect(await ethers.provider.getBalance(lock.target)).to.equal( + expect(await hre.ethers.provider.getBalance(lock.target)).to.equal( lockedAmount ); }); @@ -52,7 +52,7 @@ describe("Lock", function () { it("Should fail if the unlockTime is not in the future", async function () { // We don't use the fixture here because we want a different deployment const latestTime = await time.latest(); - const Lock = await ethers.getContractFactory("Lock"); + const Lock = await hre.ethers.getContractFactory("Lock"); await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith( "Unlock time should be in the future" ); From 4e0d856330d90f4d55b5b8304b5156233df78108 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 22:55:00 +0000 Subject: [PATCH 15/41] add default unlockTime to sample projects The unlock is arbitrary (1st Jan 2030), but it a set point in time. This means we will not have a problem with reconciliation if there is a rerun without a module parameter setting the unlock time. --- .../sample-projects/javascript-esm/ignition/modules/Lock.js | 3 ++- .../sample-projects/javascript/ignition/modules/Lock.js | 3 ++- .../sample-projects/typescript-viem/ignition/modules/Lock.ts | 3 ++- .../sample-projects/typescript/ignition/modules/Lock.ts | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js index ccb7b43b8e..d2c5b15f8a 100644 --- a/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript-esm/ignition/modules/Lock.js @@ -1,9 +1,10 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; +const JAN_1ST_2030 = 1893456000; const ONE_GWEI = 1_000_000_000n; export default buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime"); + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js b/packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js index a83eb005cd..192492a363 100644 --- a/packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js +++ b/packages/hardhat-core/sample-projects/javascript/ignition/modules/Lock.js @@ -1,9 +1,10 @@ const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); +const JAN_1ST_2030 = 1893456000; const ONE_GWEI = 1_000_000_000n; module.exports = buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime"); + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts index f25dd28d79..c84809a49e 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/ignition/modules/Lock.ts @@ -1,10 +1,11 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import { parseEther } from "viem"; +const JAN_1ST_2030 = 1893456000; const ONE_GWEI: bigint = parseEther("0.001"); const LockModule = buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime"); + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { diff --git a/packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts b/packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts index 3e8938ad9b..eda0eba45b 100644 --- a/packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript/ignition/modules/Lock.ts @@ -1,9 +1,10 @@ import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; +const JAN_1ST_2030 = 1893456000; const ONE_GWEI: bigint = 1_000_000_000n; const LockModule = buildModule("LockModule", (m) => { - const unlockTime = m.getParameter("unlockTime"); + const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030); const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI); const lock = m.contract("Lock", [unlockTime], { From a6ed97c93e8bc22fe698513882f5523f586153cf Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:03:08 +0000 Subject: [PATCH 16/41] revert scripts change in forking-other-networks --- .../hardhat-network/docs/guides/forking-other-networks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md b/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md index 1df4c3af41..af7402898f 100644 --- a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md +++ b/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md @@ -73,7 +73,7 @@ Hardhat Network will by default fork from a recent mainnet block. While this mig There are two reasons for this: -- The state your tests run against may change between runs. This could cause your tests to behave differently. +- The state your tests run against may change between runs. This could cause your tests or scripts to behave differently. - Pinning enables caching. Every time data is fetched from mainnet, Hardhat Network caches it on disk to speed up future access. If you don't pin the block, there's going to be new data with each new block and the cache won't be useful. We measured up to 20x speed improvements with block pinning. **You will need access to a node with archival data for this to work.** This is why we recommend [Infura] or [Alchemy], since their free plans include archival data. From b05718279bdf73b5d81c5f7d5f60dd1074532cc6 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:07:43 +0000 Subject: [PATCH 17/41] revert scripts change in building plugins --- .../content/hardhat-runner/docs/advanced/building-plugins.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md b/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md index 53c4fa0442..2fe3706e7f 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md +++ b/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md @@ -129,7 +129,7 @@ An example on how to add fields to the Hardhat config can be found in [`src/inde To show better stack traces to your users when an error is meant to interrupt a task's execution, please consider throwing `HardhatPluginError` errors, which can be found in `hardhat/plugins`. -If your error originated in your user's code, like a test calling one of your functions, you shouldn't use `HardhatPluginError`. +If your error originated in your user's code, like a test or script calling one of your functions, you shouldn't use `HardhatPluginError`. ### Optimizing your plugin for better startup time From 31683563203f40309dcc9dad9c164b870955b36f Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:19:22 +0000 Subject: [PATCH 18/41] update the scripts guide intro --- docs/src/content/hardhat-runner/docs/advanced/scripts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/advanced/scripts.md b/docs/src/content/hardhat-runner/docs/advanced/scripts.md index e91565cc55..e2958914d8 100644 --- a/docs/src/content/hardhat-runner/docs/advanced/scripts.md +++ b/docs/src/content/hardhat-runner/docs/advanced/scripts.md @@ -2,7 +2,7 @@ In this guide we will go through the steps of creating a script with Hardhat. For a general overview of using Hardhat refer to the [Getting started guide](../getting-started/index.md). -You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a script that prints the list of available accounts. +You can write your own custom scripts that can use all of Hardhat's functionality; for example, in this guide, we will work through scripts that print the list of available accounts. There are two ways of writing a script that accesses the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). From 8661dd9578a820f45a8ffd95c3cdf480550fcdce Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:25:01 +0000 Subject: [PATCH 19/41] revert scripts removal from hardhat console --- docs/src/content/hardhat-runner/docs/guides/hardhat-console.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md b/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md index 7dbab7e72d..451a30a51e 100644 --- a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md +++ b/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md @@ -11,7 +11,7 @@ Type ".help" for more information. The `compile` task will be called before opening the console prompt, but you can skip this with the `--no-compile` parameter. -The execution environment for the console is the same as for tasks and tests. This means the configuration has been processed, and the [Hardhat Runtime Environment] has been initialized and injected into the global scope. +The execution environment for the console is the same as for tasks, scripts and tests. This means the configuration has been processed, and the [Hardhat Runtime Environment] has been initialized and injected into the global scope. For example, you'll have access in the global scope to the `config` object: From 92724da98365d4c14c6d507a8cc912ce9307b3b2 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:45:23 +0000 Subject: [PATCH 20/41] revert removal of script refs in typescript.md --- docs/src/content/hardhat-runner/docs/guides/typescript.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/typescript.md b/docs/src/content/hardhat-runner/docs/guides/typescript.md index e6556f864d..ed02538a47 100644 --- a/docs/src/content/hardhat-runner/docs/guides/typescript.md +++ b/docs/src/content/hardhat-runner/docs/guides/typescript.md @@ -128,7 +128,7 @@ For example, if you run `npx hardhat test` and one of your tests has a compilati Since type-checking adds significant overhead, we recommend to do it only in your CI or in pre-commit/pre-push hooks. -## Writing tests in TypeScript +## Writing tests and scripts in TypeScript When using JavaScript, all the properties in the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) are injected into the global scope. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly using, for example, `import { ethers } from "hardhat"`. @@ -157,7 +157,7 @@ Typescript allows defining custom [path mappings](https://www.typescriptlang.org } ``` -To support this option when running Hardhat tests, you need to install the package [`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) and register it in your `hardhat.config.ts`: +To support this option when running Hardhat tests or scripts, you need to install the package [`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) and register it in your `hardhat.config.ts`: ```typescript import { HardhatUserConfig } from "hardhat/config"; @@ -172,9 +172,9 @@ const config: HardhatUserConfig = { export default config; ``` -## Running your tests directly with `ts-node` +## Running your tests and scripts directly with `ts-node` -When running Hardhat tests without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). +When running Hardhat scripts without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). This can also be enabled with `TS_NODE_FILES=true`. From cc1aea4bea626e944c1bf0afe823bcae7262326c Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:53:11 +0000 Subject: [PATCH 21/41] revert contract testing guide --- .../docs/guides/test-contracts.md | 62 +++++-------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md index f9148a219a..f967343d76 100644 --- a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md +++ b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md @@ -2,7 +2,7 @@ After [compiling your contracts](./compile-contracts.md), the next step is to write some tests to verify that they work as intended. -This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network), [Hardhat Ignition](/ignition) to deploy the contracts and [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. +This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.org/v6/) to connect to [Hardhat Network](/hardhat-network) and on [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. While this is our recommended test setup, Hardhat is flexible: you can customize the approach or take a completely different path with other tools. @@ -27,30 +27,18 @@ For our first test we’ll deploy the `Lock` contract and assert that the unlock ```tsx import { expect } from "chai"; import hre from "hardhat"; -import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; -const LockModule = buildModule("LockModule", (m) => { - const lockedAmount = m.getParameter("lockedAmount"); - const unlockTime = m.getParameter("unlockTime"); - - const lock = m.contract("Lock", [unlockTime], { - value: lockedAmount, - }); - - return { lock }; -}); - describe("Lock", function () { it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000n; + const lockedAmount = 1_000_000_000; const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // deploy a lock contract where funds can be withdrawn // one year in the future - const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + const lock = await ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); // assert that the value is correct @@ -66,30 +54,18 @@ describe("Lock", function () { ```js const { expect } = require("chai"); const hre = require("hardhat"); -const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -const LockModule = buildModule("LockModule", (m) => { - const lockedAmount = m.getParameter("lockedAmount"); - const unlockTime = m.getParameter("unlockTime"); - - const lock = m.contract("Lock", [unlockTime], { - value: lockedAmount, - }); - - return { lock }; -}); - describe("Lock", function () { it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000n; + const lockedAmount = 1_000_000_000; const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; // deploy a lock contract where funds can be withdrawn // one year in the future - const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + const lock = await ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); // assert that the value is correct @@ -102,11 +78,9 @@ describe("Lock", function () { :::: -First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), the [`buildModule`](/ignition/docs/guides/creating-modules) function from Hardhat Ignition to deploy our contracts, and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) +First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) -Before we write our actual test, we define an Ignition module to deploy our contract using the `buildModule` function. For brevity, we define our module in the test file here, but the recommended way to define your Ignition modules is in separate files. You can read more about creating Ignition modules in the [Hardhat Ignition docs](/ignition/docs/guides/creating-modules). - -The test itself is what’s inside the callback argument to the `it` function. First we set the values for the amount we want to lock (in [wei](https://ethereum.org/en/glossary/#wei)) and the unlock time. For the latter we use [`time.latest`](</hardhat-network-helpers/docs/reference#latest()>), a network helper that returns the timestamp of the last mined block. Then we deploy the contract itself: we call `hre.ignition.deploy` with our Ignition module we want to deploy and an object containing the deployment parameters `lockedAmount` and `unlockTime`. +The test itself is what’s inside the callback argument to the `it` function. First we set the values for the amount we want to lock (in [wei](https://ethereum.org/en/glossary/#wei)) and the unlock time. For the latter we use [`time.latest`](</hardhat-network-helpers/docs/reference#latest()>), a network helper that returns the timestamp of the last mined block. Then we deploy the contract itself: we call `ethers.deployContract` with the name of the contract we want to deploy and an array of constructor arguments that has the unlock time. We also pass an object with the transaction parameters. This is optional, but we'll use it to send some ETH by setting its `value` field. Finally, we check that the value returned by the `unlockTime()` [getter](https://docs.soliditylang.org/en/v0.8.13/contracts.html#getter-functions) in the contract matches the value that we used when we deployed it. Since all the functions on a contract are async, we have to use the `await` keyword to get its value; otherwise, we would be comparing a promise with a number and this would always fail. @@ -179,7 +153,7 @@ Here again we are calling a function and asserting that it reverts with the corr ### Using fixtures -So far we've deployed the `Lock` contract in each test. This means that at the beginning of each test we have to redeploy our Ignition module. This might be fine for a single contract but, if you have a more complicated setup, each test will have several lines at the beginning just to set up the desired state, and most of the time these lines will be the same. +So far we've deployed the `Lock` contract in each test. This means that at the beginning of each test we have to get the contract factory and then deploy the contract. This might be fine for a single contract but, if you have a more complicated setup, each test will have several lines at the beginning just to set up the desired state, and most of the time these lines will be the same. In a typical Mocha test, this duplication of code is handled with a `beforeEach` hook: @@ -199,11 +173,9 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - const result = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + lock = await ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); - - lock = result.lock; }); it("some test", async function () { @@ -226,11 +198,9 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - const result = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + lock = await ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); - - lock = result.lock; }); it("some test", async function () { @@ -266,8 +236,8 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - const { lock } = await hre.ignition.deploy(LockModule, { - parameters: { LockModule: { lockedAmount, unlockTime } }, + const lock = await ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, }); return { lock, unlockTime, lockedAmount }; From 13cb179d49a688529e0e145eaf1dcb2ad927fe3a Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 22 Feb 2024 23:58:06 +0000 Subject: [PATCH 22/41] revert testing-contracts in tutorial --- .../src/content/tutorial/testing-contracts.md | 162 ++++++------------ 1 file changed, 55 insertions(+), 107 deletions(-) diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md index 8400bbe803..e6d421e1ee 100644 --- a/docs/src/content/tutorial/testing-contracts.md +++ b/docs/src/content/tutorial/testing-contracts.md @@ -4,7 +4,7 @@ Writing automated tests when building smart contracts is of crucial importance, To test our contract, we are going to use Hardhat Network, a local Ethereum network designed for development. It comes built-in with Hardhat, and it's used as the default network. You don't need to setup anything to use it. -In our tests we're going to use [Hardhat Ignition](/ignition) to deploy and interact with the Ethereum contract we built in the previous section, and we'll use [Mocha](https://mochajs.org/) as our test runner. +In our tests we're going to use [ethers.js](https://docs.ethers.org/v6/) to interact with the Ethereum contract we built in the previous section, and we'll use [Mocha](https://mochajs.org/) as our test runner. ## Writing tests @@ -14,22 +14,15 @@ Let's start with the code below. We'll explain it next, but for now paste this i ```js const { expect } = require("chai"); -const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); - -const TokenModule = buildModule("TokenModule", (m) => { - const token = m.contract("Token"); - - return { token }; -}); describe("Token contract", function () { it("Deployment should assign the total supply of tokens to the owner", async function () { const [owner] = await ethers.getSigners(); - const { token } = await ignition.deploy(TokenModule); + const hardhatToken = await ethers.deployContract("Token"); - const ownerBalance = await token.balanceOf(owner.address); - expect(await token.totalSupply()).to.equal(ownerBalance); + const ownerBalance = await hardhatToken.balanceOf(owner.address); + expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); }); }); ``` @@ -48,16 +41,6 @@ $ npx hardhat test This means the test passed. Let's now explain each line: -```js -const TokenModule = buildModule("TokenModule", (m) => { - const token = m.contract("Token"); - - return { token }; -}); -``` - -This is a Hardhat Ignition module. It's a way to deploy smart contracts in your Hardhat project. In this case, we're defining a module that deploys a single contract, our token. We're defining it inline in the test file, but you can also define it in a separate file within the `./ignition/modules` directory. We'll discuss Hardhat Ignition modules in depth in the [deploying to a live network](./deploying-to-a-live-network.md) section. For now it's enough to know that this module will deploy our token contract. - ```js const [owner] = await ethers.getSigners(); ``` @@ -77,27 +60,21 @@ To learn more about `Signer`, you can look at the [Signers documentation](https: ::: ```js -const { token } = await ignition.deploy(TokenModule); +const hardhatToken = await ethers.deployContract("Token"); ``` -Calling `await ignition.deploy(TokenModule)` will deploy an instance of the `Token` contract and return it as part of the results object. This contract is available as the `token` property of the results object. It is an `ethers` contract instance that acts as a proxy for the on-chain contract and has methods for each of `Token` contract's functions. - -Similarly to `ethers`, `ignition` is available in the global scope. You can expand the Hardhat require line at the top of your test file to make it explicit: +Calling `ethers.deployContract("Token")` will start the deployment of our token contract, and return a `Promise` that resolves to a `Contract`. This is the object that has a method for each of your smart contract functions. ```js -const { ignition, ethers } = require("hardhat"); +const ownerBalance = await hardhatToken.balanceOf(owner.address); ``` -Once the contract is deployed, we can call our contract methods on `token`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. - -```js -const ownerBalance = await token.balanceOf(owner.address); -``` +Once the contract is deployed, we can call our contract methods on `hardhatToken`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. -Recall that the account that deploys the token gets its entire supply. By default, an Ignition module is deployed with the first Hardhat account. `ethers.getSigners()` mirrors this ordering which means that the account in the `owner` variable executed the deployment, and that `balanceOf()` should return the entire supply amount. +Recall that the account that deploys the token gets its entire supply. By default, `Contract` instances are connected to the first signer. This means that the account in the `owner` variable executed the deployment, and `balanceOf()` should return the entire supply amount. ```js -expect(await token.totalSupply()).to.equal(ownerBalance); +expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); ``` Here we're again using our `Contract` instance to call a smart contract function in our Solidity code. `totalSupply()` returns the token's supply amount and we're checking that it's equal to `ownerBalance`, as it should be. @@ -117,15 +94,15 @@ describe("Token contract", function () { it("Should transfer tokens between accounts", async function() { const [owner, addr1, addr2] = await ethers.getSigners(); - const { token } = await ignition.deploy(TokenModule); + const hardhatToken = await ethers.deployContract("Token"); // Transfer 50 tokens from owner to addr1 - await token.transfer(addr1.address, 50); - expect(await token.balanceOf(addr1.address)).to.equal(50); + await hardhatToken.transfer(addr1.address, 50); + expect(await hardhatToken.balanceOf(addr1.address)).to.equal(50); // Transfer 50 tokens from addr1 to addr2 - await token.connect(addr1).transfer(addr2.address, 50); - expect(await token.balanceOf(addr2.address)).to.equal(50); + await hardhatToken.connect(addr1).transfer(addr2.address, 50); + expect(await hardhatToken.balanceOf(addr2.address)).to.equal(50); }); }); ``` @@ -137,53 +114,43 @@ The two tests that we wrote begin with their setup, which in this case means dep You can avoid code duplication and improve the performance of your test suite by using **fixtures**. A fixture is a setup function that is run only the first time it's invoked. On subsequent invocations, instead of re-running it, Hardhat will reset the state of the network to what it was at the point after the fixture was initially executed. ```js -const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); const { loadFixture, } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); const { expect } = require("chai"); -// We define a module in the test file here, but you can also `require` it. -const TokenModule = buildModule("TokenModule", (m) => { - const token = m.contract("Token"); - - return { token }; -}); - describe("Token contract", function () { async function deployTokenFixture() { const [owner, addr1, addr2] = await ethers.getSigners(); - const { token } = await ignition.deploy(TokenModule); + const hardhatToken = await ethers.deployContract("Token"); // Fixtures can return anything you consider useful for your tests - return { token, owner, addr1, addr2 }; + return { hardhatToken, owner, addr1, addr2 }; } it("Should assign the total supply of tokens to the owner", async function () { - const { token, owner } = await loadFixture(deployTokenFixture); + const { hardhatToken, owner } = await loadFixture(deployTokenFixture); - const ownerBalance = await token.balanceOf(owner.address); - expect(await token.totalSupply()).to.equal(ownerBalance); + const ownerBalance = await hardhatToken.balanceOf(owner.address); + expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); }); it("Should transfer tokens between accounts", async function () { - const { token, owner, addr1, addr2 } = await loadFixture( + const { hardhatToken, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect(token.transfer(addr1.address, 50)).to.changeTokenBalances( - token, - [owner, addr1], - [-50, 50] - ); + await expect( + hardhatToken.transfer(addr1.address, 50) + ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account await expect( - token.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(token, [addr1, addr2], [-50, 50]); + hardhatToken.connect(addr1).transfer(addr2.address, 50) + ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); }); }); ``` @@ -194,22 +161,6 @@ Here we wrote a `deployTokenFixture` function that does the necessary setup and Now that we've covered the basics that you'll need for testing your contracts, here's a full test suite for the token with a lot of additional information about Mocha and how to structure your tests. We recommend reading it thoroughly. -First, let's move the TokenModule code into an [Ignition module](/ignition). Let's create a new directory `ignition` inside the project root's directory, then, create a directory named `modules` inside of the `ignition` directory. Paste the following into a `TokenModule.js` file in that directory: - -```js -const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); - -const TokenModule = buildModule("TokenModule", (m) => { - const token = m.contract("Token"); - - return { token }; -}); - -module.exports = TokenModule; -``` - -Then, let's use this code in the test: - ```js // This is an example test file. Hardhat will run every *.js file in `test/`, // so feel free to add new ones. @@ -226,12 +177,6 @@ const { loadFixture, } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -// We recommend writing your Hardhat Ignition modules in a separate file and -// importing them into your tests, instead of writing them in the test file. -// The reason for this is that you will be using these same Hardhat Ignition modules -// when you're ready to deploy to live networks as well. -const TokenModule = require("../ignition/modules/Token"); - // `describe` is a Mocha function that allows you to organize your tests. // Having your tests organized makes debugging them easier. All Mocha // functions are available in the global scope. @@ -247,12 +192,15 @@ describe("Token contract", function () { // Get the Signers here. const [owner, addr1, addr2] = await ethers.getSigners(); - // To deploy our contract, we just have to call ignition.deploy with our - // imported Hardhat Ignition module. - const { token } = await ignition.deploy(TokenModule); + // To deploy our contract, we just have to call ethers.deployContract and await + // its waitForDeployment() method, which happens once its transaction has been + // mined. + const hardhatToken = await ethers.deployContract("Token"); + + await hardhatToken.waitForDeployment(); // Fixtures can return anything you consider useful for your tests - return { token, owner, addr1, addr2 }; + return { hardhatToken, owner, addr1, addr2 }; } // You can nest describe calls to create subsections. @@ -264,71 +212,71 @@ describe("Token contract", function () { it("Should set the right owner", async function () { // We use loadFixture to setup our environment, and then assert that // things went well - const { token, owner } = await loadFixture(deployTokenFixture); + const { hardhatToken, owner } = await loadFixture(deployTokenFixture); // `expect` receives a value and wraps it in an assertion object. These // objects have a lot of utility methods to assert values. // This test expects the owner variable stored in the contract to be // equal to our Signer's owner. - expect(await token.owner()).to.equal(owner.address); + expect(await hardhatToken.owner()).to.equal(owner.address); }); it("Should assign the total supply of tokens to the owner", async function () { - const { token, owner } = await loadFixture(deployTokenFixture); - const ownerBalance = await token.balanceOf(owner.address); - expect(await token.totalSupply()).to.equal(ownerBalance); + const { hardhatToken, owner } = await loadFixture(deployTokenFixture); + const ownerBalance = await hardhatToken.balanceOf(owner.address); + expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); }); }); describe("Transactions", function () { it("Should transfer tokens between accounts", async function () { - const { token, owner, addr1, addr2 } = await loadFixture( + const { hardhatToken, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect(token.transfer(addr1.address, 50)).to.changeTokenBalances( - token, - [owner, addr1], - [-50, 50] - ); + await expect( + hardhatToken.transfer(addr1.address, 50) + ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account await expect( - token.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(token, [addr1, addr2], [-50, 50]); + hardhatToken.connect(addr1).transfer(addr2.address, 50) + ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); }); it("Should emit Transfer events", async function () { - const { token, owner, addr1, addr2 } = await loadFixture( + const { hardhatToken, owner, addr1, addr2 } = await loadFixture( deployTokenFixture ); // Transfer 50 tokens from owner to addr1 - await expect(token.transfer(addr1.address, 50)) - .to.emit(token, "Transfer") + await expect(hardhatToken.transfer(addr1.address, 50)) + .to.emit(hardhatToken, "Transfer") .withArgs(owner.address, addr1.address, 50); // Transfer 50 tokens from addr1 to addr2 // We use .connect(signer) to send a transaction from another account - await expect(token.connect(addr1).transfer(addr2.address, 50)) - .to.emit(token, "Transfer") + await expect(hardhatToken.connect(addr1).transfer(addr2.address, 50)) + .to.emit(hardhatToken, "Transfer") .withArgs(addr1.address, addr2.address, 50); }); it("Should fail if sender doesn't have enough tokens", async function () { - const { token, owner, addr1 } = await loadFixture(deployTokenFixture); - const initialOwnerBalance = await token.balanceOf(owner.address); + const { hardhatToken, owner, addr1 } = await loadFixture( + deployTokenFixture + ); + const initialOwnerBalance = await hardhatToken.balanceOf(owner.address); // Try to send 1 token from addr1 (0 tokens) to owner. // `require` will evaluate false and revert the transaction. await expect( - token.connect(addr1).transfer(owner.address, 1) + hardhatToken.connect(addr1).transfer(owner.address, 1) ).to.be.revertedWith("Not enough tokens"); // Owner balance shouldn't have changed. - expect(await token.balanceOf(owner.address)).to.equal( + expect(await hardhatToken.balanceOf(owner.address)).to.equal( initialOwnerBalance ); }); From 2116e3f88a634d5ca90e2d0df071691b50612aec Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 23 Feb 2024 11:15:24 +0000 Subject: [PATCH 23/41] improve tip on verifying --- docs/src/content/hardhat-runner/docs/guides/verifying.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index f3f1075c3d..5e8bd43ec8 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -8,7 +8,7 @@ In this guide we'll explain how to do this in the [Etherscan](https://etherscan. :::tip -If you'd like to verify on Sourcify instead of Etherscan, or if you wish to verify a contract deployed outside of Hardhat Ignition, you can use the [hardhat-verify plugin](/hardhat-runner/plugins/nomicfoundation-hardhat-verify). +If you wish to verify a contract deployed outside of Hardhat Ignition or if you'd like to verify on Sourcify instead of Etherscan, you can use the [hardhat-verify plugin](/hardhat-runner/plugins/nomicfoundation-hardhat-verify). ::: From 0ea9d86adf04fa8d465731730d456266ed500437 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 23 Feb 2024 11:40:47 +0000 Subject: [PATCH 24/41] Add redirect for removed tasks-and-scripts file --- docs/redirects.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/redirects.config.js b/docs/redirects.config.js index b80c5eea40..efaeed44af 100644 --- a/docs/redirects.config.js +++ b/docs/redirects.config.js @@ -250,6 +250,11 @@ const customRedirects = [ destination: "/hardhat-runner/docs/guides/command-line-completion", permanent: false, }, + { + source: "/hardhat-runner/docs/guides/tasks-and-scripts", + destination: "/hardhat-runner/docs/guides/tasks", + permanent: false, + }, // guides redirects, exceptions go first { source: From a1f762bce9939975a9a481ff42e7494e9398c0be Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 23 Feb 2024 13:09:04 +0000 Subject: [PATCH 25/41] test: update viem sample with new viem2 api --- .../hardhat-core/sample-projects/typescript-viem/test/Lock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts index 6a746fc57e..ecf8ad3c85 100644 --- a/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts +++ b/packages/hardhat-core/sample-projects/typescript-viem/test/Lock.ts @@ -95,7 +95,7 @@ describe("Lock", function () { const lockAsOtherAccount = await hre.viem.getContractAt( "Lock", lock.address, - { walletClient: otherAccount } + { client: { wallet: otherAccount } } ); await expect(lockAsOtherAccount.write.withdraw()).to.be.rejectedWith( "You aren't the owner" From d1b0660969548001d292cdf80a9bd12a0d4503f5 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 23 Feb 2024 12:44:14 +0000 Subject: [PATCH 26/41] chore: bump the project creation version The rest of the version changes will happen with changeset application. Also update some of the test fixture projects that don't seem to update when the changeset is applied. --- e2e/fixture-projects/gas-reporter/package.json | 2 +- e2e/fixture-projects/solidity-coverage/package.json | 2 +- packages/hardhat-core/src/internal/cli/project-creation.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/fixture-projects/gas-reporter/package.json b/e2e/fixture-projects/gas-reporter/package.json index 3cd8dcbaee..5a8f955016 100644 --- a/e2e/fixture-projects/gas-reporter/package.json +++ b/e2e/fixture-projects/gas-reporter/package.json @@ -1,6 +1,6 @@ { "name": "gas-reporter", "devDependencies": { - "@nomicfoundation/hardhat-toolbox": "^4.0.0" + "@nomicfoundation/hardhat-toolbox": "^5.0.0" } } diff --git a/e2e/fixture-projects/solidity-coverage/package.json b/e2e/fixture-projects/solidity-coverage/package.json index 12efd8efe5..94e4948ee3 100644 --- a/e2e/fixture-projects/solidity-coverage/package.json +++ b/e2e/fixture-projects/solidity-coverage/package.json @@ -1,6 +1,6 @@ { "name": "solidity-coverage", "devDependencies": { - "@nomicfoundation/hardhat-toolbox": "^4.0.0" + "@nomicfoundation/hardhat-toolbox": "^5.0.0" } } diff --git a/packages/hardhat-core/src/internal/cli/project-creation.ts b/packages/hardhat-core/src/internal/cli/project-creation.ts index e5b98bc46a..dd72ee0715 100644 --- a/packages/hardhat-core/src/internal/cli/project-creation.ts +++ b/packages/hardhat-core/src/internal/cli/project-creation.ts @@ -42,7 +42,7 @@ const HARDHAT_PACKAGE_NAME = "hardhat"; const PROJECT_DEPENDENCIES: Dependencies = {}; const ETHERS_PROJECT_DEPENDENCIES: Dependencies = { - "@nomicfoundation/hardhat-toolbox": "^4.0.0", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", }; const VIEM_PROJECT_DEPENDENCIES: Dependencies = { From 50c7fe372bef36956fc131fd475c2857c4dc9de2 Mon Sep 17 00:00:00 2001 From: Luis Schaab <schaable@gmail.com> Date: Fri, 23 Feb 2024 11:38:22 -0300 Subject: [PATCH 27/41] Update peer dependencies in project-creation.ts --- packages/hardhat-core/src/internal/cli/project-creation.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/hardhat-core/src/internal/cli/project-creation.ts b/packages/hardhat-core/src/internal/cli/project-creation.ts index dd72ee0715..261df5ddb4 100644 --- a/packages/hardhat-core/src/internal/cli/project-creation.ts +++ b/packages/hardhat-core/src/internal/cli/project-creation.ts @@ -56,6 +56,8 @@ const PEER_DEPENDENCIES: Dependencies = { chai: "^4.2.0", "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.0", + "@nomicfoundation/hardhat-ignition": "^0.14.0", + "@nomicfoundation/ignition-core": "^0.14.0", }; const ETHERS_PEER_DEPENDENCIES: Dependencies = { @@ -65,11 +67,13 @@ const ETHERS_PEER_DEPENDENCIES: Dependencies = { "@typechain/hardhat": "^9.0.0", typechain: "^8.3.0", "@typechain/ethers-v6": "^0.5.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", }; const VIEM_PEER_DEPENDENCIES: Dependencies = { "@nomicfoundation/hardhat-viem": "^2.0.0", viem: "^2.7.6", + "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", }; const TYPESCRIPT_DEPENDENCIES: Dependencies = {}; From c28a266c812c056a2273175632a63bd181c88c31 Mon Sep 17 00:00:00 2001 From: Luis Schaab <schaable@gmail.com> Date: Fri, 23 Feb 2024 14:54:54 -0300 Subject: [PATCH 28/41] Fix code snippets in Testing contracts guide --- .../docs/guides/test-contracts.md | 115 +++++++++++++++--- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md index f967343d76..e7787776f0 100644 --- a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md +++ b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md @@ -10,7 +10,7 @@ While this is our recommended test setup, Hardhat is flexible: you can customize In this guide we’ll write some tests for the sample project. If you haven’t done it yet, go and [initialize it](./project-setup.md). -We recommend you [use TypeScript](./typescript.md) to get better autocompletion and catch possible errors earlier. This guide will assume you are using TypeScript, but you can click the tabs of the code examples to switch their language. +We recommend you [use TypeScript](./typescript.md) to get better autocompletion and catch possible errors earlier. This guide will assume you are using TypeScript, but you can click the tabs of the code examples to see the Javascript counterpart. The setup includes some example tests in the `test/Lock.ts` file, but ignore them for now. Instead, create a `test/my-tests.ts` file. During this guide we'll only run those, by running `npx hardhat test test/my-tests.ts`, instead of just `npx hardhat test`. @@ -24,7 +24,7 @@ For our first test we’ll deploy the `Lock` contract and assert that the unlock :::tab{value="TypeScript"} -```tsx +```ts import { expect } from "chai"; import hre from "hardhat"; import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; @@ -37,7 +37,7 @@ describe("Lock", function () { // deploy a lock contract where funds can be withdrawn // one year in the future - const lock = await ethers.deployContract("Lock", [unlockTime], { + const lock = await hre.ethers.deployContract("Lock", [unlockTime], { value: lockedAmount, }); @@ -64,7 +64,7 @@ describe("Lock", function () { // deploy a lock contract where funds can be withdrawn // one year in the future - const lock = await ethers.deployContract("Lock", [unlockTime], { + const lock = await hre.ethers.deployContract("Lock", [unlockTime], { value: lockedAmount, }); @@ -96,7 +96,7 @@ function withdraw() public { The first statement checks that the unlock time has been reached, and the second one checks that the address calling the contract is its owner. Let’s start by writing a test for the first pre-condition: -```tsx +```ts it("Should revert with the right error if called too soon", async function () { // ...deploy the contract as before... @@ -114,7 +114,7 @@ We are deploying our `Lock` contract with an unlock time of one year. If we want The solution is to simulate the passage of time. This can be done with the [`time.increaseTo`](</hardhat-network-helpers/docs/reference#increaseto(timestamp)>) network helper, which mines a new block with the given timestamp: -```tsx +```ts it("Should transfer the funds to the owner", async function () { // ...deploy the contract... @@ -133,11 +133,11 @@ The second check done by the `withdraw` function is that the function was called The `ethers.getSigners()` returns an array with all the configured accounts. We can use the `.connect` method of the contract to call the function with a different account and check that the transaction reverts: -```tsx +```ts it("Should revert with the right error if called from another account", async function () { // ...deploy the contract... - const [owner, otherAccount] = await ethers.getSigners(); + const [owner, otherAccount] = await hre.ethers.getSigners(); // we increase the time of the chain to pass the first check await time.increaseTo(unlockTime); @@ -161,19 +161,20 @@ In a typical Mocha test, this duplication of code is handled with a `beforeEach` :::tab{value="TypeScript"} -```tsx -import { Contract } from "ethers"; +```ts +import hre from "hardhat"; +import { time } from "@nomicfoundation/hardhat-toolbox/network-helpers"; describe("Lock", function () { - let lock: Contract; + let lock: any; let unlockTime: number; let lockedAmount = 1_000_000_000; beforeEach(async function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; + unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - lock = await ethers.deployContract("Lock", [unlockTime], { + lock = await hre.ethers.deployContract("Lock", [unlockTime], { value: lockedAmount, }); }); @@ -188,7 +189,10 @@ describe("Lock", function () { :::tab{value="JavaScript"} -```tsx +```js +const hre = require("hardhat"); +const { time } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); + describe("Lock", function () { let lock; let unlockTime; @@ -196,9 +200,9 @@ describe("Lock", function () { beforeEach(async function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; + unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - lock = await ethers.deployContract("Lock", [unlockTime], { + lock = await hre.ethers.deployContract("Lock", [unlockTime], { value: lockedAmount, }); }); @@ -222,7 +226,74 @@ The `loadFixture` helper in the Hardhat Network Helpers fixes both of these prob This is how our tests look like when a fixture is used: -```tsx +::::tabsgroup{options="TypeScript,JavaScript"} + +:::tab{value="TypeScript"} + +```ts +import { expect } from "chai"; +import hre from "hardhat"; +import { + time, + loadFixture, +} from "@nomicfoundation/hardhat-toolbox/network-helpers"; + +describe("Lock", function () { + async function deployOneYearLockFixture() { + const lockedAmount = 1_000_000_000; + const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; + const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; + + const lock = await hre.ethers.deployContract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock, unlockTime, lockedAmount }; + } + + it("Should set the right unlockTime", async function () { + const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); + + // assert that the value is correct + expect(await lock.unlockTime()).to.equal(unlockTime); + }); + + it("Should revert with the right error if called too soon", async function () { + const { lock } = await loadFixture(deployOneYearLockFixture); + + await expect(lock.withdraw()).to.be.revertedWith("You can't withdraw yet"); + }); + + it("Should transfer the funds to the owner", async function () { + const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); + + await time.increaseTo(unlockTime); + + // this will throw if the transaction reverts + await lock.withdraw(); + }); + + it("Should revert with the right error if called from another account", async function () { + const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); + + const [owner, otherAccount] = await hre.ethers.getSigners(); + + // we increase the time of the chain to pass the first check + await time.increaseTo(unlockTime); + + // We use lock.connect() to send a transaction from another account + await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith( + "You aren't the owner" + ); + }); +}); +``` + +::: + +:::tab{value="JavaScript"} + +```js const { expect } = require("chai"); const hre = require("hardhat"); const { @@ -236,7 +307,7 @@ describe("Lock", function () { const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - const lock = await ethers.deployContract("Lock", [unlockTime], { + const lock = await hre.ethers.deployContract("Lock", [unlockTime], { value: lockedAmount, }); @@ -268,7 +339,7 @@ describe("Lock", function () { it("Should revert with the right error if called from another account", async function () { const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); - const [owner, otherAccount] = await ethers.getSigners(); + const [owner, otherAccount] = await hre.ethers.getSigners(); // we increase the time of the chain to pass the first check await time.increaseTo(unlockTime); @@ -281,11 +352,15 @@ describe("Lock", function () { }); ``` +::: + +:::: + The fixture function can return anything you want, and the `loadFixture` helper will return it. We recommend returning an object like we did here, so you can extract only the values you care about for that test. ### Other tests -There are several other things you can test, like [which events are emitted](/hardhat-chai-matchers/docs/reference#.emit) or [how the balances of the involved addresses change](/hardhat-chai-matchers/docs/reference#balance-change). Check the `test/Lock.js` file to see the other examples. +There are several other things you can test, like [which events are emitted](/hardhat-chai-matchers/docs/reference#.emit) or [how the balances of the involved addresses change](/hardhat-chai-matchers/docs/reference#balance-change). Check the `test/Lock.ts` file to see the other examples. ### Measuring code coverage From 94c2fdf327bf576a8cae97bb8aec5391e49266f8 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Fri, 23 Feb 2024 18:35:56 +0000 Subject: [PATCH 29/41] bump the version of hardhat-ignition-ethers to the latest --- packages/hardhat-toolbox/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index 5e61530df9..da2eaf3d8d 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -44,7 +44,7 @@ "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.13.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", @@ -74,7 +74,7 @@ "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.13.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", From b941f021cda594b1b23b83653f5dd8eab2ef17bc Mon Sep 17 00:00:00 2001 From: Luis Schaab <schaable@gmail.com> Date: Fri, 23 Feb 2024 16:59:25 -0300 Subject: [PATCH 30/41] Fix code snippets in Verifying your contracts --- .../hardhat-runner/docs/guides/verifying.md | 116 +++++++++++++++++- 1 file changed, 111 insertions(+), 5 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index 5e8bd43ec8..ee250f537c 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -73,9 +73,85 @@ module.exports = { We are going to use the [Sepolia testnet](https://ethereum.org/en/developers/docs/networks/#sepolia) to deploy and verify our contract, so you need to add this network in your Hardhat config. Here we are using [Infura](https://infura.io/) to connect to the network, but you can use an alternative JSON-RPC URL like [Alchemy](https://alchemy.com/) if you want. -::::tabsgroup{options=Infura,Alchemy} +::::tabsgroup{options="Infura | Typescript,Alchemy | Typescript,Infura | Javascript,Alchemy | Javascript"} -:::tab{value=Infura} +:::tab{value="Infura | Typescript"} + +```ts +// Go to https://infura.io, sign up, create a new API key +// in its dashboard, and store it as the "INFURA_API_KEY" +// configuration variable +const INFURA_API_KEY = vars.get("INFURA_API_KEY"); + +// Replace this private key with your Sepolia account private key +// To export your private key from Coinbase Wallet, go to +// Settings > Developer Settings > Show private key +// To export your private key from Metamask, open Metamask and +// go to Account Details > Export Private Key +// Store the private key as the "SEPOLIA_PRIVATE_KEY" configuration +// variable. +// Beware: NEVER put real Ether into testing accounts +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); + +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + +export default { + // ...rest of your config... + networks: { + sepolia: { + url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, + accounts: [SEPOLIA_PRIVATE_KEY], + }, + }, + etherscan: { + apiKey: { + sepolia: ETHERSCAN_API_KEY, + }, + }, +}; +``` + +::: + +:::tab{value="Alchemy | Typescript"} + +```ts +// Go to https://alchemy.com, sign up, create a new App in +// its dashboard, and store it as the "ALCHEMY_API_KEY" +// configuration variable +const ALCHEMY_API_KEY = vars.get("ALCHEMY_API_KEY"); + +// Replace this private key with your Sepolia account private key +// To export your private key from Coinbase Wallet, go to +// Settings > Developer Settings > Show private key +// To export your private key from Metamask, open Metamask and +// go to Account Details > Export Private Key +// Store the private key as the "SEPOLIA_PRIVATE_KEY" configuration +// variable. +// Beware: NEVER put real Ether into testing accounts +const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); + +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + +export default { + // ...rest of your config... + networks: { + sepolia: { + url: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, + accounts: [SEPOLIA_PRIVATE_KEY], + }, + }, + etherscan: { + apiKey: { + sepolia: ETHERSCAN_API_KEY, + }, + }, +}; +``` + +::: + +:::tab{value="Infura | Javascript"} ```js // Go to https://infura.io, sign up, create a new API key @@ -93,6 +169,8 @@ const INFURA_API_KEY = vars.get("INFURA_API_KEY"); // Beware: NEVER put real Ether into testing accounts const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + module.exports = { // ...rest of your config... networks: { @@ -101,12 +179,17 @@ module.exports = { accounts: [SEPOLIA_PRIVATE_KEY], }, }, + etherscan: { + apiKey: { + sepolia: ETHERSCAN_API_KEY, + }, + }, }; ``` ::: -:::tab{value=Alchemy} +:::tab{value="Alchemy | Javascript"} ```js // Go to https://alchemy.com, sign up, create a new App in @@ -124,6 +207,8 @@ const ALCHEMY_API_KEY = vars.get("ALCHEMY_API_KEY"); // Beware: NEVER put real Ether into testing accounts const SEPOLIA_PRIVATE_KEY = vars.get("SEPOLIA_PRIVATE_KEY"); +const ETHERSCAN_API_KEY = vars.get("ETHERSCAN_API_KEY"); + module.exports = { // ...rest of your config... networks: { @@ -132,6 +217,11 @@ module.exports = { accounts: [SEPOLIA_PRIVATE_KEY], }, }, + etherscan: { + apiKey: { + sepolia: ETHERSCAN_API_KEY, + }, + }, }; ``` @@ -188,10 +278,26 @@ npx hardhat ignition verify sepolia-deployment Alternatively, you can combine deployment and verification into one step, by invoking the `deploy` task with the `--verify` flag: -```sh -npx hardhat ignition deploy ignition/modules/Lock.js --network sepolia --deployment-id sepolia-deployment --verify +::::tabsgroup{options="TypeScript,JavaScript"} + +:::tab{value="TypeScript"} + +```shell +npx hardhat ignition deploy ignition/modules/Lock.ts --network sepolia --verify +``` + +::: + +:::tab{value="JavaScript"} + +```shell +npx hardhat ignition deploy ignition/modules/Lock.js --network sepolia --verify ``` +::: + +:::: + :::tip If you get an error saying that the address does not have bytecode, it probably means that Etherscan has not indexed your contract yet. In that case, wait for a minute and then try again. From 04be75eda963b026f2bd7121b6554e63f8c490ff Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 26 Feb 2024 10:53:01 +0000 Subject: [PATCH 31/41] Update docs/src/content/hardhat-runner/docs/guides/verifying.md Co-authored-by: Luis Schaab <schaable@gmail.com> --- docs/src/content/hardhat-runner/docs/guides/verifying.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md index ee250f537c..b06c88c0d8 100644 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ b/docs/src/content/hardhat-runner/docs/guides/verifying.md @@ -242,7 +242,7 @@ Open your contract and add a comment with something unique, like your GitHub's u contract Lock { ``` -To run the deployment we will leverage the Ignition module `LockModule` that we created in the [Deploying your contracts](./deploying.md) guide. Run the deployment using Hardhat Ignition and the newly added Sepolia network: +To run the deployment we will leverage the Ignition module `Lock` that we created in the [Deploying your contracts](./deploying.md) guide. Run the deployment using Hardhat Ignition and the newly added Sepolia network: ::::tabsgroup{options="TypeScript,JavaScript"} From 7b21e3aa72e339ee56d2d1938d36cdfd4f9306b9 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 26 Feb 2024 11:13:58 +0000 Subject: [PATCH 32/41] chore: update the pnpm lock file --- pnpm-lock.yaml | 57 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 49 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 61ea8daf6e..ff9d6a217c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1058,8 +1058,8 @@ importers: specifier: workspace:^3.0.0 version: link:../hardhat-ethers '@nomicfoundation/hardhat-ignition-ethers': - specifier: ^0.13.0 - version: 0.13.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.13.2)(@nomicfoundation/ignition-core@0.13.2)(ethers@6.11.1)(hardhat@packages+hardhat-core) + specifier: ^0.14.0 + version: 0.14.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/ignition-core@0.14.0)(ethers@6.11.1)(hardhat@packages+hardhat-core) '@nomicfoundation/hardhat-network-helpers': specifier: workspace:^1.0.0 version: link:../hardhat-network-helpers @@ -3322,18 +3322,18 @@ packages: '@nomicfoundation/ethereumjs-rlp': 5.0.4 ethereum-cryptography: 0.1.3 - /@nomicfoundation/hardhat-ignition-ethers@0.13.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.13.2)(@nomicfoundation/ignition-core@0.13.2)(ethers@6.11.1)(hardhat@packages+hardhat-core): - resolution: {integrity: sha512-REkwFOhcyNqriB3HK5MYVJF4LC+u5cec2JZ5asM5UFmGNTigMMt8GNpPIIkZhp0r0xSFyw6OF3MMcONaZ+ocew==} + /@nomicfoundation/hardhat-ignition-ethers@0.14.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/ignition-core@0.14.0)(ethers@6.11.1)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-XqRGo9lUxmnoCnuUbM16nwzUtOYD3qR+/K96PNsGJhfzshY6xLWk4nyrXHQ8A65tDaqwBl5wnH627qxYiYv7Qg==} peerDependencies: '@nomicfoundation/hardhat-ethers': ^3.0.4 - '@nomicfoundation/hardhat-ignition': ^0.13.0 - '@nomicfoundation/ignition-core': ^0.13.0 + '@nomicfoundation/hardhat-ignition': ^0.14.0 + '@nomicfoundation/ignition-core': ^0.14.0 ethers: ^6.7.0 hardhat: ^2.18.0 dependencies: '@nomicfoundation/hardhat-ethers': link:packages/hardhat-ethers - '@nomicfoundation/hardhat-ignition': 0.13.2(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) - '@nomicfoundation/ignition-core': 0.13.2 + '@nomicfoundation/hardhat-ignition': 0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) + '@nomicfoundation/ignition-core': 0.14.0 ethers: 6.11.1 hardhat: link:packages/hardhat-core dev: true @@ -3354,26 +3354,6 @@ packages: viem: 2.7.6(typescript@5.0.4) dev: true - /@nomicfoundation/hardhat-ignition@0.13.2(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): - resolution: {integrity: sha512-KfZkoJ3Zbbo2sSMjVr45LyaWaSQ7RUeGOPidVGdvP7Zf42ZV4A39wZFLWLY1mR00gdw42Y5CWRzUht/ThTH0rQ==} - peerDependencies: - '@nomicfoundation/hardhat-verify': ^2.0.1 - hardhat: ^2.18.0 - dependencies: - '@nomicfoundation/hardhat-verify': link:packages/hardhat-verify - '@nomicfoundation/ignition-core': 0.13.2 - '@nomicfoundation/ignition-ui': 0.13.2 - chalk: 4.1.2 - debug: 4.3.4(supports-color@8.1.1) - fs-extra: 10.1.0 - hardhat: link:packages/hardhat-core - prompts: 2.4.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - /@nomicfoundation/hardhat-ignition@0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): resolution: {integrity: sha512-NkGHARYrLzH/w8hbgbmBHmAe8oF0UrMRYJ7RecBelICFz+Kn0IwHy3S0arfOBiaugv54Me9tkhIsPvQwuApgTA==} peerDependencies: @@ -3394,23 +3374,6 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ignition-core@0.13.2: - resolution: {integrity: sha512-YuOsyCMy8C76CkKRZdK2tBx14RvXoBlDcN/BYagTbMiqazKJwUDdH3VdBHvy0OH2j9P6ByDDO0BuWADxF7WjMg==} - dependencies: - '@ethersproject/address': 5.6.1 - cbor: 9.0.2 - debug: 4.3.4(supports-color@8.1.1) - ethers: 6.11.1 - fs-extra: 10.1.0 - immer: 10.0.2 - lodash: 4.17.21 - ndjson: 2.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: true - /@nomicfoundation/ignition-core@0.14.0: resolution: {integrity: sha512-W7G2SSoQtsV9JRhJRfj8dZKHWkAxd7KU1mbA7M/r7UON5pJXDUr2SVwub3ydPUSgj/HE89JkvbMzHR2qZJcEeA==} dependencies: @@ -3428,10 +3391,6 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ignition-ui@0.13.2: - resolution: {integrity: sha512-rSwNFMDHyCao6RkX/Bc9waIM8R6sFnSwIf/JcoIXw1GffpKf6M/ObIR5b7S0IbGP5w+sUKEr8MuY//rabHr77Q==} - dev: true - /@nomicfoundation/ignition-ui@0.14.0: resolution: {integrity: sha512-aQCEVquuJfSBi3F/ywHygNtbcM9GjshtCxuI2tNDH9+/9pRFF1FL9ZflXcAv9bZD465JLNoQVTnq2XuEbx2EEQ==} dev: true From 502d6e705adefef11c80d047074b16fc261159ce Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 26 Feb 2024 12:00:03 +0000 Subject: [PATCH 33/41] docs: clarify module file in deploying guide --- docs/src/content/hardhat-runner/docs/guides/deploying.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/deploying.md b/docs/src/content/hardhat-runner/docs/guides/deploying.md index e76df0f158..f0784a2d28 100644 --- a/docs/src/content/hardhat-runner/docs/guides/deploying.md +++ b/docs/src/content/hardhat-runner/docs/guides/deploying.md @@ -1,6 +1,8 @@ # Deploying your contracts -To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declarative deployment system. You can deploy the `Lock` contract from the sample project by specifying a deployment with an Ignition Module file like this: +To deploy your contracts, you can use [Hardhat Ignition](/ignition), our declarative deployment system. You can deploy the `Lock` contract from the sample project by using its accompanying Ignition module. An Ignition module is a TypeScript or JavaScript file that allows you to specify what needs to be deployed. + +In the sample project, the Ignition module `LockModule` which deploys the `Lock` contract, is under the `./ignition/modules` directory and looks like this: ::::tabsgroup{options="TypeScript,JavaScript"} @@ -56,4 +58,6 @@ npx hardhat ignition deploy ./ignition/modules/Lock.js --network <your-network> If no network is specified, Hardhat Ignition will run against an in-memory instance of Hardhat Network. -Read more about Hardhat Ignition in the [Hardhat Ignition documentation](/ignition). +In the sample `LockModule` above, two module parameters are used: `unlockTime` which will default to the 1st of Jan 2030 and `lockedAmount` which will default to one Gwei. You can learn more about overriding these values by providing your own module parameters during deployment in our [Deploying a module](/ignition/docs/guides/deploy#defining-parameters-during-deployment) guide. + +Read more about Hardhat Ignition generally in the [Hardhat Ignition documentation](/ignition). From 8f141f03adfd0c7732078d34b6b79541bd1ad442 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 26 Feb 2024 12:46:44 +0000 Subject: [PATCH 34/41] docs: revert the change to project setup We don't show Ignition in tests in the sample. --- docs/src/content/hardhat-runner/docs/guides/project-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/hardhat-runner/docs/guides/project-setup.md b/docs/src/content/hardhat-runner/docs/guides/project-setup.md index 59f67066f4..728b0436c6 100644 --- a/docs/src/content/hardhat-runner/docs/guides/project-setup.md +++ b/docs/src/content/hardhat-runner/docs/guides/project-setup.md @@ -129,7 +129,7 @@ When it comes to testing your contracts, the sample project comes with some usef - The built-in [Hardhat Network](/hardhat-network/docs) as the development network to test on, along with the [Hardhat Network Helpers](/hardhat-network-helpers) library to manipulate this network. - [Mocha](https://mochajs.org/) as the test runner, [Chai](https://chaijs.com/) as the assertion library, and the [Hardhat Chai Matchers](/hardhat-chai-matchers) to extend Chai with contracts-related functionality. -- [Hardhat Ignition](/ignition) to deploy your contracts and the [`ethers.js`](https://docs.ethers.org/v6/) library to interact with them. +- The [`ethers.js`](https://docs.ethers.org/v6/) library to interact with the network and with contracts. As well as other useful plugins. You can learn more about this in the [Testing contracts guide](./test-contracts.md). From 48fc9b0d94eea27a98344382fdd78570a91f66ce Mon Sep 17 00:00:00 2001 From: Christopher Dedominici <18092467+ChristopherDedominici@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:42:08 +0100 Subject: [PATCH 35/41] update boilerplate docs --- docs/src/content/tutorial/boilerplate-project.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/src/content/tutorial/boilerplate-project.md b/docs/src/content/tutorial/boilerplate-project.md index c0d9c2f74e..7b535b956d 100644 --- a/docs/src/content/tutorial/boilerplate-project.md +++ b/docs/src/content/tutorial/boilerplate-project.md @@ -48,7 +48,7 @@ npx hardhat node Here we just install the npm project's dependencies, and by running `npx hardhat node` we spin up an instance of Hardhat Network that you can connect to using your wallet. In a different terminal in the same directory, run: ``` -npx hardhat ignition deploy ./ignition/modules/Token.js --network localhost +npx hardhat run scripts/deploy.js --network localhost ``` This will deploy the contract to Hardhat Network. After this completes, start the react web app: @@ -61,7 +61,13 @@ npm run start Then open [http://127.0.0.1:3000/](http://127.0.0.1:3000/) in your browser and you should see this:  -Click the button to connect your wallet. If you are using MetaMask, make sure you have selected the `Localhost 8545` network. +Click the button to connect your wallet. + +:::tip + +If you are using MetaMask, ensure you have configured and selected the `Localhost 8545` network. + +::: After connecting your wallet, you should see this: @@ -73,7 +79,7 @@ What's happening here is that the frontend code to show the current wallet's bal npx hardhat --network localhost faucet <your address> ``` -You'll run a custom Hardhat task we included that uses the balance of the deploying account to send 100 MHT and 1 ETH to your address. This will allow you to send tokens to another address. +You'll run a custom Hardhat task we included that uses the balance of the deploying account to send 100 MHT and 1 ETH to your address. This will allow you to send tokens to another address. The transaction might take a few seconds before updating the balance visible in the frontend. You can check out the code for the task in [`/tasks/faucet.js`](https://github.com/NomicFoundation/hardhat-boilerplate/blob/master/tasks/faucet.js), which is required from `hardhat.config.js`. From e029eaf375bf31e767c74843f5ef50d304be7a31 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Tue, 27 Feb 2024 16:29:52 +0000 Subject: [PATCH 36/41] remove ignition-core as peer dep It will be installed because both `hardhat-ignition-ethers and `hardhat-ignition-viem` have it as a dep. --- packages/hardhat-core/src/internal/cli/project-creation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/hardhat-core/src/internal/cli/project-creation.ts b/packages/hardhat-core/src/internal/cli/project-creation.ts index 261df5ddb4..33e4940fa4 100644 --- a/packages/hardhat-core/src/internal/cli/project-creation.ts +++ b/packages/hardhat-core/src/internal/cli/project-creation.ts @@ -57,7 +57,6 @@ const PEER_DEPENDENCIES: Dependencies = { "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.0", "@nomicfoundation/hardhat-ignition": "^0.14.0", - "@nomicfoundation/ignition-core": "^0.14.0", }; const ETHERS_PEER_DEPENDENCIES: Dependencies = { From 1822c2bd3f964483a43dee29c09959ce961f5343 Mon Sep 17 00:00:00 2001 From: Luis Schaab <schaable@gmail.com> Date: Mon, 4 Mar 2024 21:08:27 -0300 Subject: [PATCH 37/41] Add default tab for new combination --- docs/temp/tabsConfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/temp/tabsConfig.json b/docs/temp/tabsConfig.json index b4e9357913..963eb3ad99 100644 --- a/docs/temp/tabsConfig.json +++ b/docs/temp/tabsConfig.json @@ -1,5 +1,6 @@ { "TypeScript/JavaScript": "TypeScript", "npm 7+/npm 6/yarn": "npm 7+", - "Infura/Alchemy": "Infura" + "Infura/Alchemy": "Infura", + "Infura | Typescript/Alchemy | Typescript/Infura | Javascript/Alchemy | Javascript": "Infura | Typescript" } From ce8f48bf4dba4edc2f5154b1850f40506b93a313 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 11 Mar 2024 13:55:46 +0000 Subject: [PATCH 38/41] chore: bump the version of Ignition in toolboxes Move to `v0.15.0` to get create2 support. --- packages/hardhat-core/src/internal/cli/project-creation.ts | 6 +++--- packages/hardhat-toolbox-viem/package.json | 4 ++-- packages/hardhat-toolbox/package.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/hardhat-core/src/internal/cli/project-creation.ts b/packages/hardhat-core/src/internal/cli/project-creation.ts index 33e4940fa4..d3bff56dc4 100644 --- a/packages/hardhat-core/src/internal/cli/project-creation.ts +++ b/packages/hardhat-core/src/internal/cli/project-creation.ts @@ -56,7 +56,7 @@ const PEER_DEPENDENCIES: Dependencies = { chai: "^4.2.0", "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.0", - "@nomicfoundation/hardhat-ignition": "^0.14.0", + "@nomicfoundation/hardhat-ignition": "^0.15.0", }; const ETHERS_PEER_DEPENDENCIES: Dependencies = { @@ -66,13 +66,13 @@ const ETHERS_PEER_DEPENDENCIES: Dependencies = { "@typechain/hardhat": "^9.0.0", typechain: "^8.3.0", "@typechain/ethers-v6": "^0.5.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", }; const VIEM_PEER_DEPENDENCIES: Dependencies = { "@nomicfoundation/hardhat-viem": "^2.0.0", viem: "^2.7.6", - "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", + "@nomicfoundation/hardhat-ignition-viem": "^0.15.0", }; const TYPESCRIPT_DEPENDENCIES: Dependencies = {}; diff --git a/packages/hardhat-toolbox-viem/package.json b/packages/hardhat-toolbox-viem/package.json index 6304071a19..d463468fae 100644 --- a/packages/hardhat-toolbox-viem/package.json +++ b/packages/hardhat-toolbox-viem/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", - "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", + "@nomicfoundation/hardhat-ignition-viem": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", @@ -72,7 +72,7 @@ "viem": "^2.7.6" }, "peerDependencies": { - "@nomicfoundation/hardhat-ignition-viem": "^0.14.0", + "@nomicfoundation/hardhat-ignition-viem": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index da2eaf3d8d..973bd8a9b6 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -44,7 +44,7 @@ "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", @@ -74,7 +74,7 @@ "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", - "@nomicfoundation/hardhat-ignition-ethers": "^0.14.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", "@typechain/ethers-v6": "^0.5.0", From 67fa3e0e0c3f5972ec5a1fbc2ea141af9d77f074 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Mon, 11 Mar 2024 15:49:41 +0000 Subject: [PATCH 39/41] chore: loosen typescript peer dep for viem toolbox Viem requires `5.0.4` or greater, but we should allow higher minor versions in the peer deps for projects pulling in the viem toolbox. --- packages/hardhat-toolbox-viem/package.json | 2 +- pnpm-lock.yaml | 48 +++++++++++----------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/hardhat-toolbox-viem/package.json b/packages/hardhat-toolbox-viem/package.json index d463468fae..337c4e838d 100644 --- a/packages/hardhat-toolbox-viem/package.json +++ b/packages/hardhat-toolbox-viem/package.json @@ -85,7 +85,7 @@ "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.1", "ts-node": ">=8.0.0", - "typescript": "~5.0.4", + "typescript": "^5.0.4", "viem": "^2.7.6" }, "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff9d6a217c..545eb58330 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1058,8 +1058,8 @@ importers: specifier: workspace:^3.0.0 version: link:../hardhat-ethers '@nomicfoundation/hardhat-ignition-ethers': - specifier: ^0.14.0 - version: 0.14.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/ignition-core@0.14.0)(ethers@6.11.1)(hardhat@packages+hardhat-core) + specifier: ^0.15.0 + version: 0.15.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.15.0)(@nomicfoundation/ignition-core@0.15.0)(ethers@6.11.1)(hardhat@packages+hardhat-core) '@nomicfoundation/hardhat-network-helpers': specifier: workspace:^1.0.0 version: link:../hardhat-network-helpers @@ -1149,8 +1149,8 @@ importers: specifier: workspace:^ version: link:../eslint-plugin-slow-imports '@nomicfoundation/hardhat-ignition-viem': - specifier: ^0.14.0 - version: 0.14.0(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.14.0)(hardhat@packages+hardhat-core)(viem@2.7.6) + specifier: ^0.15.0 + version: 0.15.0(@nomicfoundation/hardhat-ignition@0.15.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.15.0)(hardhat@packages+hardhat-core)(viem@2.7.6) '@nomicfoundation/hardhat-network-helpers': specifier: workspace:^1.0.0 version: link:../hardhat-network-helpers @@ -3322,47 +3322,47 @@ packages: '@nomicfoundation/ethereumjs-rlp': 5.0.4 ethereum-cryptography: 0.1.3 - /@nomicfoundation/hardhat-ignition-ethers@0.14.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/ignition-core@0.14.0)(ethers@6.11.1)(hardhat@packages+hardhat-core): - resolution: {integrity: sha512-XqRGo9lUxmnoCnuUbM16nwzUtOYD3qR+/K96PNsGJhfzshY6xLWk4nyrXHQ8A65tDaqwBl5wnH627qxYiYv7Qg==} + /@nomicfoundation/hardhat-ignition-ethers@0.15.0(@nomicfoundation/hardhat-ethers@packages+hardhat-ethers)(@nomicfoundation/hardhat-ignition@0.15.0)(@nomicfoundation/ignition-core@0.15.0)(ethers@6.11.1)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-KmMNUc/jptfwdPA9ukQf+Ajon+m2vLBjDL2ze7d/vQdrS+fDxmoVwmbbEk4GOjianZcwgQOWD9dEWaj04QiowA==} peerDependencies: '@nomicfoundation/hardhat-ethers': ^3.0.4 - '@nomicfoundation/hardhat-ignition': ^0.14.0 - '@nomicfoundation/ignition-core': ^0.14.0 + '@nomicfoundation/hardhat-ignition': ^0.15.0 + '@nomicfoundation/ignition-core': ^0.15.0 ethers: ^6.7.0 hardhat: ^2.18.0 dependencies: '@nomicfoundation/hardhat-ethers': link:packages/hardhat-ethers - '@nomicfoundation/hardhat-ignition': 0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) - '@nomicfoundation/ignition-core': 0.14.0 + '@nomicfoundation/hardhat-ignition': 0.15.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) + '@nomicfoundation/ignition-core': 0.15.0 ethers: 6.11.1 hardhat: link:packages/hardhat-core dev: true - /@nomicfoundation/hardhat-ignition-viem@0.14.0(@nomicfoundation/hardhat-ignition@0.14.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.14.0)(hardhat@packages+hardhat-core)(viem@2.7.6): - resolution: {integrity: sha512-FmfEseiUIuKZEmIhsStpQ4RrQCjUkXKHO3gGnK0a8XXbVkpXbqoVXhBuI0DzTDMGGQg41ulkthMKFsal2ocQxg==} + /@nomicfoundation/hardhat-ignition-viem@0.15.0(@nomicfoundation/hardhat-ignition@0.15.0)(@nomicfoundation/hardhat-viem@packages+hardhat-viem)(@nomicfoundation/ignition-core@0.15.0)(hardhat@packages+hardhat-core)(viem@2.7.6): + resolution: {integrity: sha512-st6W+WTyqnHc3bs039/H5Du1+CNvLinwJ86O0yp5h4QWKTn0gfpojY7nWn9RjqSkMdpzsKVdifqzywfgXsGZlQ==} peerDependencies: - '@nomicfoundation/hardhat-ignition': ^0.14.0 + '@nomicfoundation/hardhat-ignition': ^0.15.0 '@nomicfoundation/hardhat-viem': ^2.0.0 - '@nomicfoundation/ignition-core': ^0.14.0 + '@nomicfoundation/ignition-core': ^0.15.0 hardhat: ^2.18.0 viem: ^2.7.6 dependencies: - '@nomicfoundation/hardhat-ignition': 0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) + '@nomicfoundation/hardhat-ignition': 0.15.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core) '@nomicfoundation/hardhat-viem': link:packages/hardhat-viem - '@nomicfoundation/ignition-core': 0.14.0 + '@nomicfoundation/ignition-core': 0.15.0 hardhat: link:packages/hardhat-core viem: 2.7.6(typescript@5.0.4) dev: true - /@nomicfoundation/hardhat-ignition@0.14.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): - resolution: {integrity: sha512-NkGHARYrLzH/w8hbgbmBHmAe8oF0UrMRYJ7RecBelICFz+Kn0IwHy3S0arfOBiaugv54Me9tkhIsPvQwuApgTA==} + /@nomicfoundation/hardhat-ignition@0.15.0(@nomicfoundation/hardhat-verify@packages+hardhat-verify)(hardhat@packages+hardhat-core): + resolution: {integrity: sha512-GbAe90O22uM67U/JnffXX+mBMn0HqCKSH+D98Tb5uWqR1N/M00cB3yY8OdqzVai7I6SuIKTc91mPdvtWt8R3MA==} peerDependencies: '@nomicfoundation/hardhat-verify': ^2.0.1 hardhat: ^2.18.0 dependencies: '@nomicfoundation/hardhat-verify': link:packages/hardhat-verify - '@nomicfoundation/ignition-core': 0.14.0 - '@nomicfoundation/ignition-ui': 0.14.0 + '@nomicfoundation/ignition-core': 0.15.0 + '@nomicfoundation/ignition-ui': 0.15.0 chalk: 4.1.2 debug: 4.3.4(supports-color@8.1.1) fs-extra: 10.1.0 @@ -3374,8 +3374,8 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ignition-core@0.14.0: - resolution: {integrity: sha512-W7G2SSoQtsV9JRhJRfj8dZKHWkAxd7KU1mbA7M/r7UON5pJXDUr2SVwub3ydPUSgj/HE89JkvbMzHR2qZJcEeA==} + /@nomicfoundation/ignition-core@0.15.0: + resolution: {integrity: sha512-d/h8jgJHY4xIroHqdaGeTkTqjQeuzmU759AOn1Fg88cuxVhS7JM22ZI0bQWyLNSMsVstHBIo+lSMIsvm9jBF2w==} dependencies: '@ethersproject/address': 5.6.1 cbor: 9.0.2 @@ -3391,8 +3391,8 @@ packages: - utf-8-validate dev: true - /@nomicfoundation/ignition-ui@0.14.0: - resolution: {integrity: sha512-aQCEVquuJfSBi3F/ywHygNtbcM9GjshtCxuI2tNDH9+/9pRFF1FL9ZflXcAv9bZD465JLNoQVTnq2XuEbx2EEQ==} + /@nomicfoundation/ignition-ui@0.15.0: + resolution: {integrity: sha512-RBvvQ0e8RcEc/LoSzNTPVKZZ5vEwlmxt7PXG278+6DqCrOqxqmh6W9PtK/4mwwvnTeBqds+8j81jDf6vJbOVBQ==} dev: true /@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1: From cc90bbc24d762cee62554c01ffadd9d44a033423 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 14 Mar 2024 10:53:41 +0000 Subject: [PATCH 40/41] test: fix assert.isDefined issue Chai's proxy behaviour is causing an issue. A version bump fixed this previously but it has come back. I am switching to a simpler revert for now. --- packages/hardhat-toolbox/test/test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/hardhat-toolbox/test/test.ts b/packages/hardhat-toolbox/test/test.ts index 4b08055027..f2c16f4d4f 100644 --- a/packages/hardhat-toolbox/test/test.ts +++ b/packages/hardhat-toolbox/test/test.ts @@ -20,7 +20,12 @@ describe("hardhat-toolbox", function () { useEnvironment("with-gas-reporter-config"); it("Should not crash while loading the HRE", function () { - assert.isDefined(this.env, "The environment should be loaded"); + // TODO: bring back assert.isDefined + // asserts proxying is clashing, it seems to be version related + assert( + this.env !== undefined && this.env !== null, + "The environment should be loaded" + ); }); }); From 26720f80b6d110845b1348a7f5ea52936a67dac3 Mon Sep 17 00:00:00 2001 From: John Kane <john@kanej.me> Date: Thu, 14 Mar 2024 13:21:27 +0000 Subject: [PATCH 41/41] chore: bump edr version to 0.3.1 This will bring in bug fixes from EDR. --- packages/hardhat-core/package.json | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hardhat-core/package.json b/packages/hardhat-core/package.json index 3806d5e801..280dd18dca 100644 --- a/packages/hardhat-core/package.json +++ b/packages/hardhat-core/package.json @@ -107,7 +107,7 @@ "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "workspace:^0.3.0", + "@nomicfoundation/edr": "workspace:^0.3.1", "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-tx": "5.0.4", "@nomicfoundation/ethereumjs-util": "9.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 545eb58330..87833494d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -243,7 +243,7 @@ importers: specifier: ^4.0.0 version: 4.0.1 '@nomicfoundation/edr': - specifier: workspace:^0.3.0 + specifier: workspace:^0.3.1 version: link:../../crates/edr_napi '@nomicfoundation/ethereumjs-common': specifier: 4.0.4