0
# Transaction Utilities
1
2
The transaction utilities provide helper functions for transaction building, formatting, validation, type detection, and processing workflows to simplify complex transaction operations.
3
4
## Transaction Building and Formatting
5
6
### transactionBuilder
7
8
Builds a complete transaction object with proper defaults and validation.
9
10
```typescript { .api }
11
function transactionBuilder(options: TransactionBuilderOptions): Transaction;
12
13
interface TransactionBuilderOptions {
14
from: Address;
15
to?: Address;
16
value?: Numbers;
17
data?: Bytes;
18
gas?: Numbers;
19
gasPrice?: Numbers;
20
maxFeePerGas?: Numbers;
21
maxPriorityFeePerGas?: Numbers;
22
nonce?: Numbers;
23
type?: Numbers;
24
accessList?: AccessList;
25
chainId?: Numbers;
26
}
27
```
28
29
**Usage Example:**
30
```typescript
31
import { transactionBuilder } from "web3-eth";
32
33
// Build a simple transfer transaction
34
const transaction = transactionBuilder({
35
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
36
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
37
value: "1000000000000000000" // 1 ETH
38
});
39
40
console.log("Built transaction:", transaction);
41
42
// Build EIP-1559 transaction with full options
43
const eip1559Transaction = transactionBuilder({
44
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
45
to: "0x1234567890123456789012345678901234567890",
46
value: "500000000000000000",
47
data: "0xa9059cbb000000000000000000000000...", // contract call data
48
maxFeePerGas: "30000000000",
49
maxPriorityFeePerGas: "2000000000",
50
type: 2, // EIP-1559
51
accessList: []
52
});
53
```
54
55
### formatTransaction
56
57
Formats transaction objects according to specified data format requirements.
58
59
```typescript { .api }
60
function formatTransaction(transaction: Transaction, returnFormat: DataFormat): FormattedTransaction;
61
```
62
63
**Usage Example:**
64
```typescript
65
import { formatTransaction, DEFAULT_RETURN_FORMAT } from "web3-eth";
66
67
const rawTransaction = {
68
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
69
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
70
value: "0xde0b6b3a7640000", // hex
71
gas: "0x5208" // hex
72
};
73
74
// Format with different return formats
75
const formattedTx = formatTransaction(rawTransaction, {
76
number: "NUMBER_NUMBER", // Convert hex numbers to decimal
77
bytes: "BYTES_HEX" // Keep bytes as hex strings
78
});
79
80
console.log("Formatted transaction:", formattedTx);
81
// Result: { from: "0x742...", to: "0x8ba...", value: 1000000000000000000, gas: 21000 }
82
```
83
84
## Transaction Type Detection
85
86
### detectTransactionType
87
88
Automatically detects the transaction type based on its properties.
89
90
```typescript { .api }
91
function detectTransactionType(transaction: Transaction): TransactionType;
92
93
type TransactionType = "0x0" | "0x1" | "0x2"; // Legacy, EIP-2930, EIP-1559
94
```
95
96
**Usage Example:**
97
```typescript
98
import { detectTransactionType } from "web3-eth";
99
100
// Legacy transaction
101
const legacyTx = {
102
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
103
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
104
value: "1000000000000000000",
105
gasPrice: "20000000000"
106
};
107
console.log("Legacy type:", detectTransactionType(legacyTx)); // "0x0"
108
109
// EIP-2930 transaction (with access list)
110
const eip2930Tx = {
111
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
112
to: "0x1234567890123456789012345678901234567890",
113
gasPrice: "20000000000",
114
accessList: []
115
};
116
console.log("EIP-2930 type:", detectTransactionType(eip2930Tx)); // "0x1"
117
118
// EIP-1559 transaction
119
const eip1559Tx = {
120
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
121
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
122
maxFeePerGas: "30000000000",
123
maxPriorityFeePerGas: "2000000000"
124
};
125
console.log("EIP-1559 type:", detectTransactionType(eip1559Tx)); // "0x2"
126
```
127
128
## Transaction Preparation
129
130
### prepareTransactionForSigning
131
132
Prepares a transaction for signing by filling in missing fields and validating parameters.
133
134
```typescript { .api }
135
function prepareTransactionForSigning(
136
transaction: Transaction,
137
web3Context: Web3Context,
138
privateKey?: HexString,
139
fillGasPrice?: boolean
140
): Promise<Transaction>;
141
```
142
143
**Usage Example:**
144
```typescript
145
import { prepareTransactionForSigning } from "web3-eth";
146
147
// Prepare incomplete transaction
148
const incompleteTransaction = {
149
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
150
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
151
value: "1000000000000000000"
152
// Missing: nonce, gas, gasPrice/fees, chainId
153
};
154
155
// Prepare for signing (fills missing fields)
156
const preparedTx = await prepareTransactionForSigning(
157
incompleteTransaction,
158
eth, // Web3Eth instance
159
undefined, // privateKey (optional)
160
true // fillGasPrice
161
);
162
163
console.log("Prepared transaction:", preparedTx);
164
// Now includes: nonce, gas estimate, gas pricing, chainId
165
```
166
167
## Address Resolution
168
169
### getTransactionFromOrToAttr
170
171
Resolves from/to addresses when using wallet indices instead of addresses.
172
173
```typescript { .api }
174
function getTransactionFromOrToAttr(
175
attr: "from" | "to",
176
web3Context: Web3Context
177
): Promise<Address>;
178
```
179
180
**Usage Example:**
181
```typescript
182
import { getTransactionFromOrToAttr } from "web3-eth";
183
184
// Transaction using wallet indices
185
const transactionWithIndices = {
186
from: 0, // Use first account in wallet
187
to: 1, // Use second account in wallet
188
value: "1000000000000000000"
189
};
190
191
// Resolve actual addresses
192
const fromAddress = await getTransactionFromOrToAttr("from", eth);
193
const toAddress = await getTransactionFromOrToAttr("to", eth);
194
195
const resolvedTransaction = {
196
...transactionWithIndices,
197
from: fromAddress,
198
to: toAddress
199
};
200
```
201
202
## Transaction Processing
203
204
### waitForTransactionReceipt
205
206
Waits for a transaction to be mined and returns its receipt with configurable confirmation requirements.
207
208
```typescript { .api }
209
function waitForTransactionReceipt(
210
web3Context: Web3Context,
211
transactionHash: HexString32Bytes,
212
returnFormat?: DataFormat,
213
options?: TransactionReceiptOptions
214
): Promise<TransactionReceipt>;
215
216
interface TransactionReceiptOptions {
217
transactionConfirmationBlocks?: Numbers;
218
transactionBlockTimeout?: Numbers;
219
transactionReceiptPollingInterval?: Numbers;
220
}
221
```
222
223
**Usage Example:**
224
```typescript
225
import { waitForTransactionReceipt } from "web3-eth";
226
227
// Send transaction and get hash
228
const txHash = "0xabcdef1234567890...";
229
230
// Wait with default settings
231
const receipt = await waitForTransactionReceipt(eth, txHash);
232
console.log("Transaction mined:", receipt.status === "0x1" ? "Success" : "Failed");
233
234
// Wait with custom confirmation requirements
235
const confirmedReceipt = await waitForTransactionReceipt(
236
eth,
237
txHash,
238
DEFAULT_RETURN_FORMAT,
239
{
240
transactionConfirmationBlocks: 3, // Wait for 3 confirmations
241
transactionBlockTimeout: 100, // Timeout after 100 blocks
242
transactionReceiptPollingInterval: 2000 // Poll every 2 seconds
243
}
244
);
245
246
console.log(`Transaction confirmed with ${confirmedReceipt.confirmations} confirmations`);
247
```
248
249
### trySendTransaction
250
251
Sends a transaction with automatic retry logic and comprehensive error handling.
252
253
```typescript { .api }
254
function trySendTransaction(
255
web3Context: Web3Context,
256
transaction: Transaction,
257
returnFormat?: DataFormat,
258
options?: SendTransactionOptions
259
): Promise<TransactionReceipt>;
260
```
261
262
**Usage Example:**
263
```typescript
264
import { trySendTransaction } from "web3-eth";
265
266
// Send transaction with retry logic
267
try {
268
const receipt = await trySendTransaction(
269
eth,
270
{
271
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
272
to: "0x8ba1f109551bD432803012645Hac136c1c1b6c5E",
273
value: "1000000000000000000"
274
},
275
DEFAULT_RETURN_FORMAT,
276
{
277
transactionConfirmationBlocks: 2,
278
transactionBlockTimeout: 50
279
}
280
);
281
282
console.log("Transaction successful:", receipt.transactionHash);
283
} catch (error) {
284
console.error("Failed to send transaction after retries:", error);
285
}
286
```
287
288
## Advanced Transaction Helpers
289
290
### SendTxHelper
291
292
A comprehensive helper class for managing complex transaction sending workflows.
293
294
```typescript { .api }
295
class SendTxHelper {
296
constructor(web3Context: Web3Context);
297
298
// Methods for transaction processing workflow
299
checkRevertBeforeSend(transaction: Transaction): Promise<void>;
300
signAndSend(transaction: Transaction): Promise<TransactionReceipt>;
301
handleTransaction(transaction: Transaction, options?: SendTransactionOptions): Promise<TransactionReceipt>;
302
}
303
```
304
305
**Usage Example:**
306
```typescript
307
import { SendTxHelper } from "web3-eth";
308
309
const txHelper = new SendTxHelper(eth);
310
311
// Use helper for complex transaction workflow
312
try {
313
const receipt = await txHelper.handleTransaction({
314
from: "0x742d35Cc6634C0532925a3b8D7389Fc3C1b6c5E",
315
to: "0x1234567890123456789012345678901234567890",
316
data: "0xa9059cbb000000000000000000000000..." // contract call
317
}, {
318
transactionConfirmationBlocks: 3,
319
ignoreGasPricing: false
320
});
321
322
console.log("Complex transaction completed:", receipt);
323
} catch (error) {
324
console.error("Transaction workflow failed:", error);
325
}
326
```
327
328
## Transaction Validation and Analysis
329
330
### Validation Helpers
331
332
```typescript
333
// Validate transaction before sending
334
function validateTransaction(transaction: Transaction): { valid: boolean; errors: string[] } {
335
const errors: string[] = [];
336
337
if (!transaction.from) {
338
errors.push("Missing 'from' address");
339
}
340
341
if (!transaction.to && !transaction.data) {
342
errors.push("Transaction must have 'to' address or 'data' for contract creation");
343
}
344
345
if (transaction.value && Number(transaction.value) < 0) {
346
errors.push("Transaction value cannot be negative");
347
}
348
349
if (transaction.gas && Number(transaction.gas) <= 0) {
350
errors.push("Gas limit must be positive");
351
}
352
353
// EIP-1559 validation
354
if (transaction.maxFeePerGas && transaction.maxPriorityFeePerGas) {
355
if (Number(transaction.maxPriorityFeePerGas) > Number(transaction.maxFeePerGas)) {
356
errors.push("Max priority fee cannot exceed max fee per gas");
357
}
358
}
359
360
return { valid: errors.length === 0, errors };
361
}
362
363
// Estimate transaction cost
364
async function estimateTransactionCost(transaction: Transaction): Promise<TransactionCostEstimate> {
365
const gasEstimate = await eth.estimateGas(transaction);
366
const feeData = await eth.getFeeData();
367
368
let maxCost: bigint;
369
let expectedCost: bigint;
370
371
if (transaction.maxFeePerGas) {
372
// EIP-1559 transaction
373
maxCost = BigInt(gasEstimate) * BigInt(transaction.maxFeePerGas);
374
expectedCost = BigInt(gasEstimate) * (BigInt(feeData.maxFeePerGas || 0) + BigInt(transaction.maxPriorityFeePerGas || 0));
375
} else {
376
// Legacy transaction
377
const gasPrice = transaction.gasPrice || feeData.gasPrice || "20000000000";
378
maxCost = expectedCost = BigInt(gasEstimate) * BigInt(gasPrice);
379
}
380
381
return {
382
gasEstimate: gasEstimate.toString(),
383
maxCostWei: maxCost.toString(),
384
expectedCostWei: expectedCost.toString(),
385
maxCostEth: (Number(maxCost) / 1e18).toFixed(6),
386
expectedCostEth: (Number(expectedCost) / 1e18).toFixed(6)
387
};
388
}
389
```
390
391
## Core Types
392
393
```typescript { .api }
394
interface TransactionBuilderOptions {
395
from: Address;
396
to?: Address;
397
value?: Numbers;
398
data?: Bytes;
399
gas?: Numbers;
400
gasPrice?: Numbers;
401
maxFeePerGas?: Numbers;
402
maxPriorityFeePerGas?: Numbers;
403
nonce?: Numbers;
404
type?: Numbers;
405
accessList?: AccessList;
406
chainId?: Numbers;
407
}
408
409
interface TransactionReceiptOptions {
410
transactionConfirmationBlocks?: Numbers;
411
transactionBlockTimeout?: Numbers;
412
transactionReceiptPollingInterval?: Numbers;
413
}
414
415
interface SendTransactionOptions<ResolveType = TransactionReceipt> {
416
ignoreGasPricing?: boolean;
417
transactionConfirmationBlocks?: Numbers;
418
transactionBlockTimeout?: Numbers;
419
transactionConfirmationPollingInterval?: Numbers;
420
transactionReceiptPollingInterval?: Numbers;
421
transactionSendTimeout?: Numbers;
422
ignoreFillingGasLimit?: boolean;
423
contractAbi?: AbilityType;
424
}
425
426
interface FormattedTransaction extends Transaction {
427
// Transaction with values formatted according to DataFormat
428
}
429
430
interface TransactionCostEstimate {
431
gasEstimate: string;
432
maxCostWei: string;
433
expectedCostWei: string;
434
maxCostEth: string;
435
expectedCostEth: string;
436
}
437
438
type TransactionType = "0x0" | "0x1" | "0x2"; // Legacy, EIP-2930, EIP-1559
439
type Address = HexString20Bytes;
440
type Numbers = HexString | number | bigint;
441
type Bytes = HexString;
442
type HexString32Bytes = string;
443
444
interface DataFormat {
445
number: NumberFormat;
446
bytes: BytesFormat;
447
}
448
```