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
```