or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdnetwork-helpers.mdplugin-configuration.md

network-helpers.mddocs/

0

# Network Helpers

1

2

Network helpers provide comprehensive blockchain testing utilities for fixture management, time manipulation, account impersonation, and network state control. These utilities are re-exported from `@nomicfoundation/hardhat-network-helpers` for convenient access.

3

4

## Capabilities

5

6

### Fixture Management

7

8

Efficient test setup using blockchain snapshots for consistent test environments.

9

10

```typescript { .api }

11

/**

12

* Executes fixture function and creates blockchain snapshots for efficient test setup

13

* Subsequent calls with the same fixture restore the blockchain to the snapshot

14

* @param fixture - Named function that returns a promise with test setup data

15

* @returns Promise resolving to the fixture data

16

* @throws FixtureAnonymousFunctionError if fixture is an anonymous function

17

* @throws FixtureSnapshotError if snapshot restoration fails

18

*/

19

function loadFixture<T>(fixture: Fixture<T>): Promise<T>;

20

21

/**

22

* Clears all existing snapshots from memory

23

* Use when you need to reset all cached fixture states

24

*/

25

function clearSnapshots(): Promise<void>;

26

27

type Fixture<T> = () => Promise<T>;

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers";

34

import { ethers } from "hardhat";

35

36

describe("Token Contract", function () {

37

// ✅ Correct: Named function

38

async function deployTokenFixture() {

39

const [owner, addr1, addr2] = await ethers.getSigners();

40

const Token = await ethers.getContractFactory("Token");

41

const token = await Token.deploy();

42

return { token, owner, addr1, addr2 };

43

}

44

45

it("should transfer tokens between accounts", async function () {

46

// First call executes fixture and takes snapshot

47

const { token, owner, addr1 } = await loadFixture(deployTokenFixture);

48

49

await token.transfer(addr1.address, 50);

50

expect(await token.balanceOf(addr1.address)).to.equal(50);

51

});

52

53

it("should handle multiple transfers", async function () {

54

// Second call restores blockchain to snapshot, no re-execution

55

const { token, owner, addr1, addr2 } = await loadFixture(deployTokenFixture);

56

57

await token.transfer(addr1.address, 30);

58

await token.transfer(addr2.address, 20);

59

expect(await token.balanceOf(addr1.address)).to.equal(30);

60

});

61

});

62

63

// ❌ Incorrect: Anonymous function will execute every time

64

// await loadFixture(async () => { ... });

65

```

66

67

### Time Manipulation

68

69

Control blockchain time and block progression for testing time-dependent contracts.

70

71

```typescript { .api }

72

namespace time {

73

/**

74

* Get the timestamp of the latest block

75

* @returns Promise resolving to the latest block timestamp in seconds

76

*/

77

function latest(): Promise<number>;

78

79

/**

80

* Get the block number of the latest block

81

* @returns Promise resolving to the latest block number

82

*/

83

function latestBlock(): Promise<number>;

84

85

/**

86

* Increase the time of the next block by the given number of seconds

87

* Does not mine a new block - use mine() to apply the time change

88

* @param seconds - Number of seconds to increase time by

89

*/

90

function increase(seconds: number): Promise<void>;

91

92

/**

93

* Set the time of the next block to the given timestamp

94

* Does not mine a new block - use mine() to apply the time change

95

* @param timestamp - Target timestamp in seconds since epoch

96

*/

97

function increaseTo(timestamp: number): Promise<void>;

98

99

/**

100

* Mine a single block, advancing the block number by 1

101

* Applies any pending time changes from increase() or increaseTo()

102

*/

103

function advanceBlock(): Promise<void>;

104

105

/**

106

* Mine blocks until reaching the target block number

107

* @param blockNumber - Target block number to reach

108

*/

109

function advanceBlockTo(blockNumber: number): Promise<void>;

110

111

/**

112

* Set the timestamp for the next block that will be mined

113

* @param timestamp - Target timestamp in seconds since epoch

114

*/

115

function setNextBlockTimestamp(timestamp: number): Promise<void>;

116

}

117

```

118

119

**Time Duration Helpers:**

120

121

```typescript { .api }

122

namespace time.duration {

123

/** Convert milliseconds to duration value */

124

function millis(amount: number): number;

125

/** Convert seconds to duration value */

126

function seconds(amount: number): number;

127

/** Convert minutes to duration value */

128

function minutes(amount: number): number;

129

/** Convert hours to duration value */

130

function hours(amount: number): number;

131

/** Convert days to duration value */

132

function days(amount: number): number;

133

/** Convert weeks to duration value */

134

function weeks(amount: number): number;

135

/** Convert years to duration value */

136

function years(amount: number): number;

137

}

138

```

139

140

**Usage Examples:**

141

142

```typescript

143

import { time, mine } from "@nomicfoundation/hardhat-toolbox/network-helpers";

144

145

describe("TimeLock Contract", function () {

146

it("should unlock after time period", async function () {

147

const { timeLock } = await loadFixture(deployTimeLockFixture);

148

149

// Get current time and set unlock time

150

const currentTime = await time.latest();

151

const unlockTime = currentTime + time.duration.days(30);

152

153

// Try to unlock immediately (should fail)

154

await expect(timeLock.unlock()).to.be.revertedWith("Still locked");

155

156

// Advance time to unlock period

157

await time.increaseTo(unlockTime);

158

await mine(); // Apply the time change

159

160

// Now unlock should work

161

await expect(timeLock.unlock()).not.to.be.reverted;

162

});

163

164

it("should handle multiple time advances", async function () {

165

const { timeLock } = await loadFixture(deployTimeLockFixture);

166

167

// Advance time in steps

168

await time.increase(time.duration.days(10));

169

await mine();

170

171

await time.increase(time.duration.days(15));

172

await mine();

173

174

await time.increase(time.duration.days(10)); // Total: 35 days

175

await mine();

176

177

await expect(timeLock.unlock()).not.to.be.reverted;

178

});

179

});

180

```

181

182

### Block Mining

183

184

Control block mining and transaction processing for testing block-dependent logic.

185

186

```typescript { .api }

187

/**

188

* Mine one or more blocks

189

* @param blocks - Number of blocks to mine (default: 1)

190

*/

191

function mine(blocks?: number): Promise<void>;

192

193

/**

194

* Mine blocks until reaching the target block number

195

* @param blockNumber - Target block number to reach

196

*/

197

function mineUpTo(blockNumber: number): Promise<void>;

198

199

/**

200

* Drop a pending transaction from the mempool

201

* Useful for testing transaction failure scenarios

202

* @param txHash - Hash of the transaction to drop

203

*/

204

function dropTransaction(txHash: string): Promise<void>;

205

```

206

207

**Usage Examples:**

208

209

```typescript

210

import { mine, mineUpTo, time } from "@nomicfoundation/hardhat-toolbox/network-helpers";

211

212

describe("Auction Contract", function () {

213

it("should end auction after block deadline", async function () {

214

const { auction } = await loadFixture(deployAuctionFixture);

215

216

const currentBlock = await time.latestBlock();

217

const endBlock = currentBlock + 100;

218

219

// Place some bids

220

await auction.placeBid({ value: ethers.parseEther("1") });

221

222

// Mine to just before end

223

await mineUpTo(endBlock - 1);

224

await expect(auction.placeBid({ value: ethers.parseEther("2") })).not.to.be.reverted;

225

226

// Mine past end block

227

await mine(2);

228

await expect(auction.placeBid({ value: ethers.parseEther("3") }))

229

.to.be.revertedWith("Auction ended");

230

});

231

});

232

```

233

234

### Account Impersonation

235

236

Impersonate any account for testing interactions with existing contracts and accounts.

237

238

```typescript { .api }

239

/**

240

* Start impersonating an account

241

* Allows sending transactions from that account without private key

242

* @param address - Address of the account to impersonate

243

*/

244

function impersonateAccount(address: string): Promise<void>;

245

246

/**

247

* Stop impersonating an account

248

* @param address - Address of the account to stop impersonating

249

*/

250

function stopImpersonatingAccount(address: string): Promise<void>;

251

252

/**

253

* Set the balance of an account

254

* @param address - Account address

255

* @param balance - New balance in wei (use ethers.parseEther for ether amounts)

256

*/

257

function setBalance(address: string, balance: bigint): Promise<void>;

258

259

/**

260

* Set the nonce of an account

261

* @param address - Account address

262

* @param nonce - New nonce value

263

*/

264

function setNonce(address: string, nonce: number): Promise<void>;

265

```

266

267

**Usage Examples:**

268

269

```typescript

270

import {

271

impersonateAccount,

272

stopImpersonatingAccount,

273

setBalance

274

} from "@nomicfoundation/hardhat-toolbox/network-helpers";

275

import { ethers } from "hardhat";

276

277

describe("DAO Governance", function () {

278

it("should allow whale to vote", async function () {

279

const { dao, governanceToken } = await loadFixture(deployDAOFixture);

280

281

// Impersonate a large token holder

282

const whaleAddress = "0x742d35Cc6635C0532925a3b8D7389b18A68Ff0cd";

283

await impersonateAccount(whaleAddress);

284

285

// Give the whale some ETH for gas fees

286

await setBalance(whaleAddress, ethers.parseEther("10"));

287

288

// Get signer for the impersonated account

289

const whaleSigner = await ethers.getSigner(whaleAddress);

290

291

// Vote using the whale's tokens

292

await dao.connect(whaleSigner).vote(1, true);

293

294

// Verify the vote was counted

295

const proposal = await dao.proposals(1);

296

expect(proposal.votesFor).to.be.gt(0);

297

298

// Stop impersonating

299

await stopImpersonatingAccount(whaleAddress);

300

});

301

});

302

```

303

304

### State Manipulation

305

306

Directly manipulate blockchain state for testing edge cases and complex scenarios.

307

308

```typescript { .api }

309

/**

310

* Get storage value at a specific slot for a contract

311

* @param address - Contract address

312

* @param position - Storage slot position (hex string)

313

* @returns Storage value as hex string

314

*/

315

function getStorageAt(address: string, position: string): Promise<string>;

316

317

/**

318

* Set storage value at a specific slot for a contract

319

* @param address - Contract address

320

* @param position - Storage slot position (hex string)

321

* @param value - New storage value (hex string)

322

*/

323

function setStorageAt(address: string, position: string, value: string): Promise<void>;

324

325

/**

326

* Set the contract code at an address

327

* @param address - Address to set code at

328

* @param code - Contract bytecode (hex string)

329

*/

330

function setCode(address: string, code: string): Promise<void>;

331

```

332

333

**Usage Examples:**

334

335

```typescript

336

import { setStorageAt, getStorageAt } from "@nomicfoundation/hardhat-toolbox/network-helpers";

337

338

describe("Storage Manipulation", function () {

339

it("should modify contract storage directly", async function () {

340

const { token } = await loadFixture(deployTokenFixture);

341

342

// Modify total supply directly (assuming it's at slot 0)

343

const newSupply = ethers.parseEther("1000000");

344

await setStorageAt(

345

token.target,

346

"0x0", // Storage slot 0

347

ethers.toBeHex(newSupply, 32) // Convert to 32-byte hex

348

);

349

350

// Verify the change

351

expect(await token.totalSupply()).to.equal(newSupply);

352

});

353

});

354

```

355

356

### Network Configuration

357

358

Control network-level settings and behavior.

359

360

```typescript { .api }

361

/**

362

* Set the block gas limit for subsequent blocks

363

* @param gasLimit - New gas limit for blocks

364

*/

365

function setBlockGasLimit(gasLimit: number): Promise<void>;

366

367

/**

368

* Set the coinbase address (block miner address)

369

* @param address - New coinbase address

370

*/

371

function setCoinbase(address: string): Promise<void>;

372

373

/**

374

* Set the prevRandao value for the next block

375

* @param randao - New prevRandao value (hex string)

376

*/

377

function setPrevRandao(randao: string): Promise<void>;

378

379

/**

380

* Set the base fee per gas for the next block

381

* @param baseFee - New base fee in wei

382

*/

383

function setNextBlockBaseFeePerGas(baseFee: bigint): Promise<void>;

384

```

385

386

### Snapshot Management

387

388

Advanced snapshot functionality for complex test scenarios.

389

390

```typescript { .api }

391

/**

392

* Take a snapshot of the current blockchain state

393

* @returns SnapshotRestorer object with restore capability

394

*/

395

function takeSnapshot(): Promise<SnapshotRestorer>;

396

397

/**

398

* Reset the blockchain to a clean state

399

* @param forking - Optional forking configuration to reset to a specific block

400

*/

401

function reset(forking?: {

402

jsonRpcUrl: string;

403

blockNumber?: number;

404

}): Promise<void>;

405

406

interface SnapshotRestorer {

407

/** Unique identifier for this snapshot */

408

snapshotId: string;

409

/** Restore blockchain state to this snapshot */

410

restore(): Promise<void>;

411

}

412

```

413

414

**Usage Examples:**

415

416

```typescript

417

import { takeSnapshot, reset } from "@nomicfoundation/hardhat-toolbox/network-helpers";

418

419

describe("Complex Test Suite", function () {

420

let snapshot: SnapshotRestorer;

421

422

beforeEach(async function () {

423

// Take snapshot before each test

424

snapshot = await takeSnapshot();

425

});

426

427

afterEach(async function () {

428

// Restore to snapshot after each test

429

await snapshot.restore();

430

});

431

432

it("should handle complex interactions", async function () {

433

// Test implementation that modifies state

434

// State will be restored automatically

435

});

436

});

437

```

438

439

## Error Types

440

441

```typescript { .api }

442

/** Thrown when loadFixture is called with an anonymous function */

443

class FixtureAnonymousFunctionError extends Error {

444

constructor();

445

}

446

447

/** Thrown when snapshot restoration fails */

448

class FixtureSnapshotError extends Error {

449

constructor(cause: InvalidSnapshotError);

450

}

451

452

/** Thrown when trying to restore an invalid snapshot */

453

class InvalidSnapshotError extends Error {

454

constructor(snapshotId: string);

455

}

456

```