or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbalance-tracking.mdconstants-utilities.mdevent-testing.mdindex.mdrevert-testing.mdtime-manipulation.md

balance-tracking.mddocs/

0

# Balance Tracking

1

2

Elegant balance change tracking for Ethereum accounts with support for fee calculation and multiple units. Perfect for testing payment flows and gas cost analysis.

3

4

## Capabilities

5

6

### Current Balance

7

8

Get the current balance of an Ethereum account in the specified unit.

9

10

```javascript { .api }

11

/**

12

* Get the current balance of an account

13

* @param {string} account - Ethereum address to check

14

* @param {string} unit - Unit for the balance ('wei', 'ether', etc.)

15

* @returns {Promise<BN>} - Account balance as BigNumber

16

*/

17

async function balance.current(account, unit = 'wei');

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const { balance, BN } = require('@openzeppelin/test-helpers');

24

25

// Get balance in wei (default)

26

const balanceWei = await balance.current(userAddress);

27

console.log(balanceWei.toString()); // "1000000000000000000"

28

29

// Get balance in ether

30

const balanceEther = await balance.current(userAddress, 'ether');

31

console.log(balanceEther.toString()); // "1"

32

33

// Compare balances

34

const expected = new BN('1000000000000000000');

35

expect(balanceWei).to.be.bignumber.equal(expected);

36

```

37

38

### Balance Tracker

39

40

Create a balance tracker for monitoring balance changes over time with fee calculation support.

41

42

```javascript { .api }

43

/**

44

* Create a balance tracker for an account

45

* @param {string} owner - Ethereum address to track

46

* @param {string} unit - Unit for balance tracking ('wei', 'ether', etc.)

47

* @returns {Promise<BalanceTracker>} - Balance tracker instance

48

*/

49

async function balance.tracker(owner, unit = 'wei');

50

51

interface BalanceTracker {

52

/**

53

* Get the current tracked balance

54

* @param {string} unit - Optional unit override

55

* @returns {Promise<BN>} - Current balance

56

*/

57

get(unit?): Promise<BN>;

58

59

/**

60

* Get the balance change since last check

61

* @param {string} unit - Optional unit override

62

* @returns {Promise<BN>} - Balance delta (positive for increase, negative for decrease)

63

*/

64

delta(unit?): Promise<BN>;

65

66

/**

67

* Get the balance change and fees paid since last check

68

* @param {string} unit - Optional unit override

69

* @returns {Promise<{delta: BN, fees: BN}>} - Balance delta and fees paid

70

*/

71

deltaWithFees(unit?): Promise<{ delta: BN, fees: BN }>;

72

}

73

```

74

75

**Usage Examples:**

76

77

```javascript

78

// Create balance tracker

79

const tracker = await balance.tracker(userAddress);

80

81

// Get initial balance

82

const initial = await tracker.get();

83

console.log('Initial balance:', initial.toString());

84

85

// Perform some transactions

86

await token.transfer(recipient, amount, { from: userAddress });

87

await myContract.someFunction({ from: userAddress });

88

89

// Check balance change

90

const delta = await tracker.delta();

91

console.log('Balance change:', delta.toString());

92

93

// Check balance change with fees

94

const { delta: balanceDelta, fees } = await tracker.deltaWithFees();

95

console.log('Balance delta:', balanceDelta.toString());

96

console.log('Fees paid:', fees.toString());

97

```

98

99

### Advanced Balance Tracking

100

101

```javascript

102

const { balance, ether, BN } = require('@openzeppelin/test-helpers');

103

104

contract('PaymentContract', function ([owner, user, recipient]) {

105

it('should track payment and fees correctly', async function () {

106

// Create tracker for user

107

const userTracker = await balance.tracker(user, 'ether');

108

109

// Send payment transaction

110

await this.paymentContract.sendPayment(

111

recipient,

112

ether('0.5'),

113

{ from: user, value: ether('0.5') }

114

);

115

116

// Check balance change including gas fees

117

const { delta, fees } = await userTracker.deltaWithFees('ether');

118

119

// User should have spent 0.5 ether plus gas fees

120

expect(delta).to.be.bignumber.equal(new BN('0').sub(new BN('0.5')));

121

expect(fees).to.be.bignumber.greaterThan(new BN('0'));

122

123

console.log(`Payment: -0.5 ether`);

124

console.log(`Gas fees: -${fees.toString()} ether`);

125

console.log(`Total spent: ${delta.abs().toString()} ether`);

126

});

127

128

it('should track multiple transactions', async function () {

129

const tracker = await balance.tracker(user);

130

131

// Multiple transactions

132

await this.contract.function1({ from: user });

133

const delta1 = await tracker.delta();

134

135

await this.contract.function2({ from: user });

136

const delta2 = await tracker.delta();

137

138

await this.contract.function3({ from: user });

139

const delta3 = await tracker.delta();

140

141

console.log('Transaction 1 cost:', delta1.toString());

142

console.log('Transaction 2 cost:', delta2.toString());

143

console.log('Transaction 3 cost:', delta3.toString());

144

});

145

});

146

```

147

148

## Unit Support

149

150

Balance tracking supports all web3.js units:

151

152

- `'wei'` (default)

153

- `'kwei'` / `'babbage'` / `'femtoether'`

154

- `'mwei'` / `'lovelace'` / `'picoether'`

155

- `'gwei'` / `'shannon'` / `'nanoether'` / `'nano'`

156

- `'szabo'` / `'microether'` / `'micro'`

157

- `'finney'` / `'milliether'` / `'milli'`

158

- `'ether'`

159

- `'kether'` / `'grand'`

160

- `'mether'`

161

- `'gether'`

162

- `'tether'`

163

164

## Fee Calculation

165

166

The `deltaWithFees` method calculates gas fees by:

167

168

1. Tracking block numbers between balance checks

169

2. Examining all transactions in intermediate blocks

170

3. Identifying transactions sent from the tracked account

171

4. Calculating `gasUsed * gasPrice` for each transaction

172

5. Summing total fees paid

173

174

**Note**: Fee calculation requires access to transaction receipts and may be slow for accounts with many transactions.

175

176

## Error Handling

177

178

```javascript

179

// Handle insufficient balance scenarios

180

try {

181

const delta = await tracker.delta();

182

if (delta.isNeg()) {

183

console.log('Account spent:', delta.abs().toString(), 'wei');

184

}

185

} catch (error) {

186

console.error('Balance tracking failed:', error.message);

187

}

188

```