or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

argument-utilities.mdbalance-matchers.mdbignumber-support.mdevent-matchers.mdindex.mdpanic-codes.mdrevert-matchers.mdvalidation-matchers.md

index.mddocs/

0

# Hardhat Chai Matchers

1

2

Hardhat Chai Matchers extends the Chai assertion library with Ethereum-specific capabilities for smart contract testing. It provides specialized matchers for testing transaction reverts, event emissions, balance changes, and Ethereum-specific data validation, making smart contract tests more readable and comprehensive.

3

4

## Package Information

5

6

- **Package Name**: @nomicfoundation/hardhat-chai-matchers

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install --save-dev @nomicfoundation/hardhat-chai-matchers`

10

11

## Core Imports

12

13

```typescript

14

// Import the plugin in your Hardhat configuration

15

require("@nomicfoundation/hardhat-chai-matchers");

16

17

// Import utilities for argument matching

18

import { anyValue, anyUint } from "@nomicfoundation/hardhat-chai-matchers/withArgs";

19

20

// Import panic codes for revert testing

21

import { PANIC_CODES } from "@nomicfoundation/hardhat-chai-matchers/panic";

22

```

23

24

## Basic Usage

25

26

```typescript

27

import { expect } from "chai";

28

import { ethers } from "hardhat";

29

30

// After importing the plugin, new matchers are available on Chai expectations

31

describe("Token Contract", function () {

32

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

33

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

34

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

35

const token = await Token.deploy(1000000);

36

37

// Test successful transfer and event emission

38

await expect(token.transfer(recipient.address, 1000))

39

.to.emit(token, "Transfer")

40

.withArgs(owner.address, recipient.address, 1000);

41

42

// Test balance changes

43

await expect(token.transfer(recipient.address, 500))

44

.to.changeTokenBalance(token, recipient, 500);

45

});

46

47

it("should handle reverts", async function () {

48

// Test transaction reverts with specific reasons

49

await expect(token.transfer(ethers.ZeroAddress, 1000))

50

.to.be.revertedWith("Cannot transfer to zero address");

51

52

// Test custom error reverts

53

await expect(token.transferFrom(owner.address, recipient.address, 1000))

54

.to.be.revertedWithCustomError(token, "InsufficientAllowance");

55

});

56

});

57

```

58

59

## Architecture

60

61

Hardhat Chai Matchers is built around extending Chai's assertion interface with Ethereum-specific matchers:

62

63

- **Chai Extensions**: All matchers extend the global Chai.Assertion interface via TypeScript declaration merging

64

- **Async Matchers**: Most matchers return AsyncAssertion promises for testing transaction results

65

- **Chainable Interface**: Some matchers like `.emit()` and `.revertedWithCustomError()` support chaining with `.withArgs()`

66

- **Integration Layer**: Seamless integration with Hardhat, ethers.js, and Chai testing framework

67

68

## Capabilities

69

70

### Transaction Revert Testing

71

72

Comprehensive matchers for testing different types of transaction failures including generic reverts, reason strings, custom errors, and panic conditions.

73

74

```typescript { .api }

75

interface Assertion {

76

reverted: AsyncAssertion;

77

revertedWith(reason: string | RegExp): AsyncAssertion;

78

revertedWithoutReason(): AsyncAssertion;

79

revertedWithPanic(code?: any): AsyncAssertion;

80

revertedWithCustomError(contract: { interface: any }, customErrorName: string): CustomErrorAssertion;

81

}

82

```

83

84

[Transaction Revert Testing](./revert-matchers.md)

85

86

### Event Emission Testing

87

88

Matchers for verifying that transactions emit specific events with expected arguments, supporting complex event validation scenarios.

89

90

```typescript { .api }

91

interface Assertion {

92

emit(contract: any, eventName: string): EmitAssertion;

93

}

94

95

interface EmitAssertion extends AsyncAssertion {

96

withArgs(...args: any[]): AsyncAssertion;

97

}

98

```

99

100

[Event Emission Testing](./event-matchers.md)

101

102

### Balance Change Testing

103

104

Matchers for testing ETH and ERC-20 token balance changes during transaction execution, supporting both single and multiple account scenarios.

105

106

```typescript { .api }

107

interface Assertion {

108

changeEtherBalance(account: any, balance: any, options?: any): AsyncAssertion;

109

changeEtherBalances(accounts: any[], balances: any[] | ((changes: bigint[]) => boolean), options?: any): AsyncAssertion;

110

changeTokenBalance(token: any, account: any, balance: any): AsyncAssertion;

111

changeTokenBalances(token: any, accounts: any[], balances: any[] | ((changes: bigint[]) => boolean)): AsyncAssertion;

112

}

113

```

114

115

[Balance Change Testing](./balance-matchers.md)

116

117

### Data Validation

118

119

Matchers for validating Ethereum-specific data formats including addresses, private keys, and hex strings.

120

121

```typescript { .api }

122

interface Assertion {

123

hexEqual(other: string): void;

124

properPrivateKey: void;

125

properAddress: void;

126

properHex(length: number): void;

127

}

128

```

129

130

[Data Validation](./validation-matchers.md)

131

132

### Argument Matching Utilities

133

134

Helper functions for flexible argument matching in event and error testing scenarios.

135

136

```typescript { .api }

137

function anyValue(): boolean;

138

function anyUint(i: any): boolean;

139

```

140

141

[Argument Matching Utilities](./argument-utilities.md)

142

143

### BigNumber Support

144

145

Enhanced comparison operators that support ethers BigInt and other BigNumber types alongside regular JavaScript numbers.

146

147

```typescript { .api }

148

interface NumericComparison {

149

within(start: any, finish: any, message?: string): Assertion;

150

}

151

152

// Enhanced operators: equal, above, below, least, most, closeTo

153

// All support BigInt/BigNumber comparisons automatically

154

```

155

156

[BigNumber Support](./bignumber-support.md)

157

158

### Panic Codes

159

160

Constants and utilities for testing Solidity panic conditions and arithmetic errors.

161

162

```typescript { .api }

163

const PANIC_CODES: {

164

ASSERTION_ERROR: 0x1;

165

ARITHMETIC_OVERFLOW: 0x11;

166

DIVISION_BY_ZERO: 0x12;

167

ENUM_CONVERSION_OUT_OF_BOUNDS: 0x21;

168

INCORRECTLY_ENCODED_STORAGE_BYTE_ARRAY: 0x22;

169

POP_ON_EMPTY_ARRAY: 0x31;

170

ARRAY_ACCESS_OUT_OF_BOUNDS: 0x32;

171

TOO_MUCH_MEMORY_ALLOCATED: 0x41;

172

ZERO_INITIALIZED_VARIABLE: 0x51;

173

};

174

```

175

176

[Panic Codes](./panic-codes.md)

177

178

## Types

179

180

```typescript { .api }

181

interface AsyncAssertion extends Assertion, Promise<void> {}

182

183

interface EmitAssertion extends AsyncAssertion {

184

withArgs(...args: any[]): AsyncAssertion;

185

}

186

187

interface CustomErrorAssertion extends AsyncAssertion {

188

withArgs(...args: any[]): AsyncAssertion;

189

}

190

```