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

validation-matchers.mddocs/

0

# Data Validation

1

2

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

3

4

## Capabilities

5

6

### Hex String Equality

7

8

Tests if two hex strings are equal, handling case differences and 0x prefix variations.

9

10

```typescript { .api }

11

/**

12

* Tests hex string equality with normalization

13

* @param other - The hex string to compare against

14

* @returns void - assertion passes or throws

15

*/

16

hexEqual(other: string): void;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { expect } from "chai";

23

24

// Test hex string equality (case insensitive)

25

expect("0xabcdef").to.hexEqual("0xABCDEF");

26

expect("0x123456").to.hexEqual("0x123456");

27

28

// Works with or without 0x prefix

29

expect("abcdef").to.hexEqual("0xABCDEF");

30

expect("0x123456").to.hexEqual("123456");

31

32

// Test inequality

33

expect("0xabc123").to.not.hexEqual("0xdef456");

34

35

// Usage with contract addresses

36

const contractAddress = await contract.getAddress();

37

expect(contractAddress).to.hexEqual("0x742d35Cc6634C0532925a3b8D3d9C24cB2B05cC");

38

39

// Compare transaction hashes

40

const tx = await contract.someFunction();

41

expect(tx.hash).to.hexEqual(expectedHash);

42

```

43

44

### Ethereum Address Validation

45

46

Tests if a value is a valid Ethereum address format.

47

48

```typescript { .api }

49

/**

50

* Tests if value is a valid Ethereum address

51

* @returns void - assertion passes or throws

52

*/

53

properAddress: void;

54

```

55

56

**Usage Examples:**

57

58

```typescript

59

// Test valid addresses

60

expect("0x742d35Cc6634C0532925a3b8D3d9C24c").to.be.properAddress;

61

expect("0x0000000000000000000000000000000000000000").to.be.properAddress; // Zero address

62

expect("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF").to.be.properAddress; // Mixed case

63

64

// Test invalid addresses

65

expect("0x123").to.not.be.properAddress; // Too short

66

expect("0xGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG").to.not.be.properAddress; // Invalid hex

67

expect("123456789012345678901234567890123456789012").to.not.be.properAddress; // No 0x prefix

68

expect("").to.not.be.properAddress; // Empty string

69

70

// Usage with dynamic addresses

71

const signerAddress = await signer.getAddress();

72

expect(signerAddress).to.be.properAddress;

73

74

const contractAddress = await ethers.getContractFactory("MyContract").then(f => f.deploy()).then(c => c.getAddress());

75

expect(contractAddress).to.be.properAddress;

76

```

77

78

### Private Key Validation

79

80

Tests if a value is a valid Ethereum private key format.

81

82

```typescript { .api }

83

/**

84

* Tests if value is a valid Ethereum private key

85

* @returns void - assertion passes or throws

86

*/

87

properPrivateKey: void;

88

```

89

90

**Usage Examples:**

91

92

```typescript

93

// Test valid private keys (64 hex characters)

94

expect("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").to.be.properPrivateKey;

95

expect("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").to.be.properPrivateKey; // Without 0x

96

97

// Test invalid private keys

98

expect("0x123").to.not.be.properPrivateKey; // Too short

99

expect("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdefg").to.not.be.properPrivateKey; // Invalid hex

100

expect("").to.not.be.properPrivateKey; // Empty string

101

102

// Usage in testing scenarios

103

const wallet = ethers.Wallet.createRandom();

104

expect(wallet.privateKey).to.be.properPrivateKey;

105

106

// Validate generated keys

107

const generatedKey = generatePrivateKey(); // Your key generation function

108

expect(generatedKey).to.be.properPrivateKey;

109

```

110

111

### Hex String Length Validation

112

113

Tests if a value is a valid hex string of a specific length.

114

115

```typescript { .api }

116

/**

117

* Tests if value is valid hex string of specific length

118

* @param length - Expected length in bytes (not hex characters)

119

* @returns void - assertion passes or throws

120

*/

121

properHex(length: number): void;

122

```

123

124

**Usage Examples:**

125

126

```typescript

127

// Test specific hex lengths (length is in bytes, not characters)

128

expect("0x1234").to.be.properHex(2); // 2 bytes = 4 hex characters

129

expect("0xabcdef123456").to.be.properHex(6); // 6 bytes = 12 hex characters

130

expect("0x" + "ff".repeat(32)).to.be.properHex(32); // 32 bytes = 64 hex characters

131

132

// Works without 0x prefix

133

expect("1234").to.be.properHex(2);

134

expect("abcdef123456").to.be.properHex(6);

135

136

// Test invalid lengths

137

expect("0x1234").to.not.be.properHex(3); // Wrong length

138

expect("0x123").to.not.be.properHex(2); // Odd number of hex characters

139

expect("0xGGGG").to.not.be.properHex(2); // Invalid hex characters

140

141

// Common Ethereum use cases

142

expect(transactionHash).to.be.properHex(32); // Transaction hashes are 32 bytes

143

expect(blockHash).to.be.properHex(32); // Block hashes are 32 bytes

144

expect(signature.r).to.be.properHex(32); // Signature components are 32 bytes

145

expect(signature.s).to.be.properHex(32);

146

147

// Smart contract testing

148

const merkleRoot = await contract.getMerkleRoot();

149

expect(merkleRoot).to.be.properHex(32); // Merkle roots are typically 32 bytes

150

151

const nonce = await contract.getNonce(user);

152

expect(ethers.toBeHex(nonce, 8)).to.be.properHex(8); // 8-byte nonce

153

```

154

155

## Advanced Validation Patterns

156

157

### Combined Validations

158

159

```typescript

160

// Validate address format and non-zero

161

const deployedAddress = await contract.getAddress();

162

expect(deployedAddress).to.be.properAddress;

163

expect(deployedAddress).to.not.hexEqual("0x0000000000000000000000000000000000000000");

164

165

// Validate transaction hash format

166

const tx = await contract.someFunction();

167

expect(tx.hash).to.be.properHex(32);

168

expect(tx.hash).to.match(/^0x[0-9a-fA-F]{64}$/); // Additional regex validation

169

```

170

171

### Data Structure Validation

172

173

```typescript

174

// Validate signature components

175

interface Signature {

176

r: string;

177

s: string;

178

v: number;

179

}

180

181

function validateSignature(sig: Signature) {

182

expect(sig.r).to.be.properHex(32);

183

expect(sig.s).to.be.properHex(32);

184

expect(sig.v).to.be.oneOf([27, 28]); // Standard Chai matcher

185

}

186

187

// Validate multi-field data

188

const accountData = await contract.getAccount(user);

189

expect(accountData.owner).to.be.properAddress;

190

expect(accountData.nonce).to.be.properHex(8);

191

expect(accountData.balance).to.be.properHex(32);

192

```

193

194

### Error Messages

195

196

The validation matchers provide clear error messages:

197

198

```typescript

199

// Address validation error: "Expected '0x123' to be a proper address"

200

// Private key error: "Expected '0x123' to be a proper private key"

201

// Hex length error: "Expected '0x1234' to be proper hex of length 4, but got length 2"

202

// Hex equality error: "Expected '0xabc' to equal '0xdef'"

203

```

204

205

## Input Handling

206

207

### Case Sensitivity

208

209

```typescript

210

// Hex equality is case insensitive

211

expect("0xabcdef").to.hexEqual("0xABCDEF"); // ✅ Passes

212

213

// Address validation accepts mixed case

214

expect("0xaBcDeF1234567890AbCdEf1234567890AbCdEf12").to.be.properAddress; // ✅ Passes

215

```

216

217

### Prefix Handling

218

219

```typescript

220

// All matchers handle 0x prefix gracefully

221

expect("abcdef").to.hexEqual("0xABCDEF"); // ✅ Passes

222

expect("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").to.be.properPrivateKey; // ✅ Passes

223

expect("1234").to.be.properHex(2); // ✅ Passes

224

```

225

226

## Integration with Ethers.js

227

228

These matchers work seamlessly with ethers.js objects:

229

230

```typescript

231

// Works with ethers Wallet objects

232

const wallet = ethers.Wallet.createRandom();

233

expect(await wallet.getAddress()).to.be.properAddress;

234

expect(wallet.privateKey).to.be.properPrivateKey;

235

236

// Works with Contract objects

237

const contract = await ethers.getContractFactory("MyContract").then(f => f.deploy());

238

expect(await contract.getAddress()).to.be.properAddress;

239

240

// Works with transaction objects

241

const tx = await contract.someFunction();

242

expect(tx.hash).to.be.properHex(32);

243

```