Skip to content

Commit 327952d

Browse files
authored
Merge pull request #11 from NomicFoundation/add-configuring-the-compiler-guide
Merge new changes
2 parents 2453a12 + d8c2382 commit 327952d

File tree

3 files changed

+402
-0
lines changed

3 files changed

+402
-0
lines changed

src/content/hardhat3-alpha/learn-more/_dirinfo.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ order:
77
href: /alpha-limitations
88
- title: Configuring the compiler
99
href: /configuring-the-compiler
10+
- title: Writing Solidity tests
11+
href: /writing-solidity-tests
12+
- title: Using viem
13+
href: /using-viem
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# How to use viem with Hardhat
2+
3+
[viem](https://viem.sh/) is a modern, type-safe library that lets you deploy contracts, manage accounts, read chain state, and more. It's the library we recommend for interacting with Ethereum. You can integrate viem with Hardhat by using the `hardhat-viem` plugin.
4+
5+
## Setup
6+
7+
If you have already initialized a viem-based project using `hardhat --init`, you don’t need to do anything else.
8+
9+
If you want to add the plugin manually:
10+
11+
1. Install the plugin:
12+
13+
```bash
14+
npm install --save-dev @nomicfoundation/hardhat-viem@next
15+
```
16+
17+
2. Add it to the list of plugins in your Hardhat configuration:
18+
19+
```tsx
20+
import hardhatViem from "@nomicfoundation/hardhat-viem";
21+
22+
const config: HardhatUserConfig = {
23+
plugins: [
24+
hardhatViem,
25+
// ...other plugins...
26+
],
27+
// ...other config...
28+
};
29+
30+
export default config;
31+
```
32+
33+
## Connecting to networks
34+
35+
In Hardhat, you interact with networks using _network connections_. You can create connections with the network manager, which you can import directly from Hardhat:
36+
37+
```tsx
38+
import { network } from "hardhat";
39+
40+
const connection = await network.connect("mainnet");
41+
```
42+
43+
Plugins can extend the network connections with new functionality. The `hardhat-viem` plugin adds a `viem` object to each connection, which provides helpers to interact with the network you are connected to:
44+
45+
```tsx
46+
const { viem } = await network.connect("mainnet");
47+
48+
const publicClient = await viem.getPublicClient();
49+
console.log("Latest block number:", await publicClient.getBlockNumber());
50+
```
51+
52+
## Using viem clients
53+
54+
Viem groups functionality in [clients](https://viem.sh/docs/clients/intro). The `hardhat-viem` plugin helps you create them more easily.
55+
56+
You can create a [public client](https://viem.sh/docs/clients/public) using the `getPublicClient` method:
57+
58+
```tsx
59+
const { viem } = await network.connect();
60+
61+
const publicClient = await viem.getPublicClient();
62+
63+
console.log("Latest block number:", await publicClient.getBlockNumber());
64+
```
65+
66+
Use the `getWalletClients` function to obtain [wallet clients](https://viem.sh/docs/clients/wallet). It returns an array of wallet clients, one for each account set up in the Hardhat config:
67+
68+
```tsx
69+
const [senderClient, receiverClient] = await viem.getWalletClients();
70+
71+
await senderClient.sendTransaction({
72+
to: receiverClient.account.address,
73+
value: 10n ** 18n,
74+
});
75+
```
76+
77+
Finally, if you are connecting to a Hardhat network, you can call `getTestClient` to get a [test client](https://viem.sh/docs/clients/test):
78+
79+
```tsx
80+
const testClient = await viem.getTestClient();
81+
82+
await testClient.mine({
83+
blocks: 10,
84+
});
85+
```
86+
87+
## Deploying and interacting with contracts
88+
89+
`hardhat-viem` includes a `deployContract` function that lets you deploy contracts defined in the project. This function returns a viem [contract instance](https://viem.sh/docs/contract/getContract) of the deployed contract:
90+
91+
```tsx
92+
import { network } from "hardhat";
93+
94+
const { viem } = await network.connect();
95+
const counter = await viem.deployContract("Counter");
96+
97+
await counter.write.inc();
98+
99+
console.log("Counter value:", await counter.read.x());
100+
```
101+
102+
If the constructor takes parameters, you can pass them as the second argument:
103+
104+
```tsx
105+
const initialValue = 10n;
106+
const counter = await viem.deployContract("Counter", [initialValue]);
107+
```
108+
109+
By default, contracts are deployed from the first account defined in the Hardhat configuration, but you can specify a different one:
110+
111+
```tsx
112+
const [wallet1, wallet2] = await viem.getWalletClients();
113+
114+
const counter = await viem.deployContract("Counter", [10n], {
115+
client: {
116+
wallet: wallet2,
117+
},
118+
});
119+
```
120+
121+
The `deployContract` function waits until the contract is deployed. If you just want to send the deployment without waiting until it’s mined, you can use `sendDeploymentTransaction`:
122+
123+
```tsx
124+
const deploymentTx = await viem.sendDeploymentTransaction("Counter", [10n], {
125+
client: {
126+
wallet: wallet2,
127+
},
128+
});
129+
```
130+
131+
All the previous examples deploy a new contract instance, but sometimes you need to interact with an already deployed contract. In those cases, you can use the `getContractAt` function:
132+
133+
```tsx
134+
const counterAddress = "0x1234567890123456789012345678901234567890";
135+
const counter = await viem.getContractAt("Counter", counterAddress);
136+
```
137+
138+
### Using contracts from an npm dependency
139+
140+
You can also use a contract defined in an npm dependency with `hardhat-viem`.
141+
142+
To do this, you need to configure Hardhat to compile the contract and generate artifacts for it. This will allow you to use the `hardhat-viem` helpers to interact with it, just like with any other contract defined in your project.
143+
144+
To learn how to do it, please read [this guide](./configuring-the-compiler.md#generating-artifacts-from-dependencies).
145+
146+
## Type-safe contract interactions
147+
148+
Viem has powerful typing capabilities, triggering compilation errors when you make mistakes like using the wrong type in a function argument or sending value to a non-payable function:
149+
150+
```tsx
151+
// doesn't compile if getItem expects a number but receives a string:
152+
await contract.read.getItem(["3"]);
153+
154+
// doesn't compile if setItem is not payable:
155+
await contract.write.setItem([3, "three"], {
156+
value: 1000n,
157+
});
158+
```
159+
160+
When using viem on its own, you need to pass an ABI to get contract instances with properly inferred types. The `hardhat-viem` plugin handles this automatically when you use helpers like `deployContract` or `getContractAt`.
161+
162+
### Troubleshooting contract type errors
163+
164+
Contract types are updated when the project is compiled. If you are getting a compilation error that you don’t expect, make sure you’ve run `hardhat compile`.
165+
166+
Note that VSCode may not always pick up the type updates automatically. If you are still getting unexpected TypeScript errors after compiling the project, open the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and run `TypeScript: Reload Project`.
167+
168+
## Using viem as a module
169+
170+
The `viem` object in the connection only includes functionality added by the `hardhat-viem` plugin. To use viem’s own functionality, import it from the `viem` module:
171+
172+
```tsx
173+
import { keccak256 } from "viem";
174+
import { network } from "hardhat";
175+
176+
const { viem } = await network.connect();
177+
```
178+
179+
Keep in mind that you can get a name clash if you use a namespace import:
180+
181+
```tsx
182+
import * as viem from "viem";
183+
import { network } from "hardhat";
184+
185+
// this is an error because viem is already declared
186+
const { viem } = await network.connect();
187+
```
188+
189+
One way to work around this problem is to use a different name for the Hardhat viem object:
190+
191+
```tsx
192+
const { viem: hhViem } = await network.connect();
193+
194+
const publicClient = await hhViem.getPublicClient();
195+
```

0 commit comments

Comments
 (0)