Hardhat plugin that integrates Web3.js 1.x into the Hardhat development environment
npx @tessl/cli install tessl/npm-nomiclabs--hardhat-web3@2.1.00
# Hardhat Web3 Plugin
1
2
Hardhat Web3 Plugin integrates Web3.js 1.x into the Hardhat development environment. This plugin extends the Hardhat Runtime Environment with both the Web3 module and an initialized Web3 instance connected to the selected network, enabling developers to use familiar Web3.js APIs within Hardhat tasks, scripts, and tests.
3
4
## Package Information
5
6
- **Package Name**: @nomiclabs/hardhat-web3
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install --save-dev @nomiclabs/hardhat-web3 web3@^1.0.0-beta.36`
10
11
## Core Imports
12
13
The plugin is imported by requiring or importing it in your Hardhat configuration file:
14
15
```javascript
16
require("@nomiclabs/hardhat-web3");
17
```
18
19
For TypeScript:
20
21
```typescript
22
import "@nomiclabs/hardhat-web3";
23
```
24
25
For direct access to provider adapter components:
26
27
```typescript
28
import {
29
JsonRpcRequest,
30
JsonRpcResponse,
31
Web3HTTPProviderAdapter,
32
} from "@nomiclabs/hardhat-web3/dist/src/web3-provider-adapter";
33
```
34
35
## Basic Usage
36
37
After importing the plugin in your hardhat.config.js or hardhat.config.ts, Web3.js becomes available through the Hardhat Runtime Environment:
38
39
```javascript
40
require("@nomiclabs/hardhat-web3");
41
42
// Access Web3 in tasks
43
task("accounts", "Prints accounts", async (_, { web3 }) => {
44
console.log(await web3.eth.getAccounts());
45
});
46
47
// Access Web3 in scripts
48
async function main() {
49
const accounts = await hre.web3.eth.getAccounts();
50
console.log("Available accounts:", accounts);
51
52
const balance = await hre.web3.eth.getBalance(accounts[0]);
53
console.log("Balance:", hre.web3.utils.fromWei(balance, 'ether'), "ETH");
54
}
55
```
56
57
## Architecture
58
59
The plugin uses Hardhat's extension mechanism to add Web3.js functionality:
60
61
- **Environment Extension**: Uses `extendEnvironment()` to extend the Hardhat Runtime Environment
62
- **Lazy Loading**: Implements lazy loading for both the Web3 module and instance using Hardhat's plugin utilities
63
- **Provider Adapter**: Bridges Hardhat's internal provider to Web3.js's expected provider interface
64
- **Type Safety**: Provides TypeScript definitions for the extended runtime environment
65
66
## Capabilities
67
68
### Web3 Module Access
69
70
Provides access to the Web3.js constructor through the Hardhat Runtime Environment.
71
72
```typescript { .api }
73
interface HardhatRuntimeEnvironment {
74
Web3: typeof Web3;
75
}
76
```
77
78
The `Web3` property gives you access to the Web3.js constructor, allowing you to create new Web3 instances if needed.
79
80
### Web3 Instance Access
81
82
Provides a pre-configured Web3.js instance connected to the selected Hardhat network.
83
84
```typescript { .api }
85
interface HardhatRuntimeEnvironment {
86
web3: Web3;
87
}
88
```
89
90
The `web3` property provides an already initialized Web3 instance that automatically connects to whatever network is configured in Hardhat (localhost, mainnet, testnet, etc.).
91
92
### Provider Adapter
93
94
The plugin includes a provider adapter that bridges Hardhat's internal provider to Web3.js. While primarily used internally by the plugin, these components are also exported and can be imported directly if needed.
95
96
```typescript { .api }
97
// From hardhat/types
98
interface EthereumProvider {
99
send(method: string, params?: any[]): Promise<any>;
100
}
101
102
interface JsonRpcRequest {
103
jsonrpc: string;
104
method: string;
105
params: any[];
106
id: number;
107
}
108
109
interface JsonRpcResponse {
110
jsonrpc: string;
111
id: number;
112
result?: any;
113
error?: {
114
code: number;
115
message: string;
116
data?: any;
117
};
118
}
119
120
class Web3HTTPProviderAdapter {
121
constructor(provider: EthereumProvider);
122
123
send(
124
payload: JsonRpcRequest,
125
callback: (error: Error | null, response?: JsonRpcResponse) => void
126
): void;
127
128
send(
129
payload: JsonRpcRequest[],
130
callback: (error: Error | null, response?: JsonRpcResponse[]) => void
131
): void;
132
133
isConnected(): boolean;
134
}
135
```
136
137
The `Web3HTTPProviderAdapter` class adapts Hardhat's Ethereum provider interface to work with Web3.js. It supports both single and batch JSON-RPC requests and provides proper error handling.
138
139
## Usage Examples
140
141
### In Tasks
142
143
```javascript
144
task("balance", "Get account balance")
145
.addParam("account", "The account's address")
146
.setAction(async (taskArgs, { web3 }) => {
147
const balance = await web3.eth.getBalance(taskArgs.account);
148
console.log(web3.utils.fromWei(balance, 'ether'), "ETH");
149
});
150
```
151
152
### In Scripts
153
154
```javascript
155
// scripts/deploy.js
156
async function main() {
157
const [deployer] = await hre.web3.eth.getAccounts();
158
159
console.log("Deploying contracts with account:", deployer);
160
161
const balance = await hre.web3.eth.getBalance(deployer);
162
console.log("Account balance:", hre.web3.utils.fromWei(balance, 'ether'), "ETH");
163
164
// Deploy contract using Web3
165
const contract = new hre.web3.eth.Contract(abi);
166
const deployedContract = await contract.deploy({
167
data: bytecode,
168
arguments: []
169
}).send({
170
from: deployer,
171
gas: 1500000,
172
gasPrice: '30000000000'
173
});
174
175
console.log("Contract deployed at:", deployedContract.options.address);
176
}
177
```
178
179
### In Tests
180
181
```javascript
182
describe("MyContract", function () {
183
it("Should deploy and work correctly", async function () {
184
const accounts = await web3.eth.getAccounts();
185
const owner = accounts[0];
186
187
const contract = new web3.eth.Contract(abi);
188
const deployedContract = await contract.deploy({
189
data: bytecode
190
}).send({
191
from: owner,
192
gas: 1500000
193
});
194
195
expect(deployedContract.options.address).to.not.be.empty;
196
});
197
});
198
```
199
200
### Creating Custom Web3 Instances
201
202
```javascript
203
async function customWeb3Example() {
204
// Access the Web3 constructor
205
const CustomWeb3 = hre.Web3;
206
207
// Create a custom instance with different provider
208
const customWeb3 = new CustomWeb3('https://mainnet.infura.io/v3/YOUR_KEY');
209
210
// Use the custom instance
211
const blockNumber = await customWeb3.eth.getBlockNumber();
212
console.log("Current block:", blockNumber);
213
}
214
```
215
216
## Types
217
218
The plugin extends the Hardhat Runtime Environment with Web3.js types:
219
220
```typescript { .api }
221
declare module "hardhat/types/runtime" {
222
interface HardhatRuntimeEnvironment {
223
Web3: typeof Web3;
224
web3: Web3;
225
}
226
}
227
```
228
229
## Error Handling
230
231
The provider adapter handles JSON-RPC errors by wrapping them in the proper response format:
232
233
- Preserves original error codes and messages
234
- Includes stack traces and error names in error data
235
- Gracefully handles missing error codes (defaults to 404)
236
- Supports error handling for both single and batch requests