Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
GasEstimate
GasEstimate represents the estimated gas required for a transaction, typically returned by eth_estimateGas RPC method. Always add buffer (20-30%) before using as gasLimit.
Type Definition
type GasEstimateType = bigint & { readonly [brand]: "GasEstimate" };
Branded bigint representing estimated gas (always non-negative).
Gas Estimation Flow
1. eth_estimateGas → minimum gas needed
2. Add buffer (20-30%) → account for variability
3. Set as gasLimit → transaction max gas
4. Execute → actual gasUsed ≤ gasLimit
5. Refund → (gasLimit - gasUsed) returned
API
Constructors
from(value)
Create GasEstimate from number, bigint, or string.
import { GasEstimate } from '@tevm/primitives';
// From eth_estimateGas response
const estimate = GasEstimate.from(rpcEstimate);
// From bigint
const est = GasEstimate.from(100_000n);
// From number
const est2 = GasEstimate.from(100000);
// From hex string
const est3 = GasEstimate.from("0x186a0");
Throws: InvalidFormatError if value is negative.
Conversions
toNumber(estimate)
Convert to number.
const estimate = GasEstimate.from(100_000n);
GasEstimate.toNumber(estimate); // 100000
toBigInt(estimate)
Convert to bigint (identity operation).
const estimate = GasEstimate.from(100_000n);
GasEstimate.toBigInt(estimate); // 100000n
toHex(estimate)
Convert to hex string.
const estimate = GasEstimate.from(100_000n);
GasEstimate.toHex(estimate); // "0x186a0"
Comparisons
equals(est1, est2)
Check equality.
GasEstimate.equals(100_000n, 100_000n); // true
GasEstimate.equals(100_000n, 120_000n); // false
compare(est1, est2)
Compare values (-1, 0, 1).
GasEstimate.compare(100_000n, 120_000n); // -1
GasEstimate.compare(100_000n, 100_000n); // 0
GasEstimate.compare(120_000n, 100_000n); // 1
Utilities
withBuffer(estimate, percentage)
Add percentage buffer to estimate.
const estimate = GasEstimate.from(100_000n);
// Add 20% buffer (recommended)
const buffered = GasEstimate.withBuffer(estimate, 20);
// 120,000n
// Add 30% buffer (conservative)
const safe = GasEstimate.withBuffer(estimate, 30);
// 130,000n
Recommended buffers:
- Standard: 20-25%
- Conservative: 30-40%
- Network congestion: 50%+
toGasLimit(estimate)
Convert to gas limit (typically after adding buffer).
const estimate = GasEstimate.from(100_000n);
const withBuffer = GasEstimate.withBuffer(estimate, 25);
const gasLimit = GasEstimate.toGasLimit(withBuffer);
// 125,000n - ready to use as transaction gasLimit
Usage Examples
Basic Estimation
import { GasEstimate } from '@tevm/primitives';
// Get estimate from RPC
const estimate = await provider.estimateGas({
to: '0x...',
data: '0x...',
});
const gasEstimate = GasEstimate.from(estimate);
console.log(`Estimated gas: ${GasEstimate.toNumber(gasEstimate)}`);
Add Buffer and Send Transaction
import { GasEstimate } from '@tevm/primitives';
// Estimate gas
const rawEstimate = await provider.estimateGas(tx);
const estimate = GasEstimate.from(rawEstimate);
// Add 25% buffer for safety
const withBuffer = GasEstimate.withBuffer(estimate, 25);
const gasLimit = GasEstimate.toGasLimit(withBuffer);
// Send transaction with buffered gas limit
const signedTx = await wallet.signTransaction({
...tx,
gasLimit,
});
await provider.sendTransaction(signedTx);
Compare Estimation Strategies
import { GasEstimate } from '@tevm/primitives';
const estimate = GasEstimate.from(100_000n);
const strategies = [
{ name: 'Standard', buffer: 20 },
{ name: 'Conservative', buffer: 30 },
{ name: 'Very Safe', buffer: 50 },
];
for (const { name, buffer } of strategies) {
const buffered = GasEstimate.withBuffer(estimate, buffer);
const limit = GasEstimate.toGasLimit(buffered);
console.log(`${name}: ${limit} gas`);
}
// Standard: 120000 gas
// Conservative: 130000 gas
// Very Safe: 150000 gas
Handle Network Congestion
import { GasEstimate } from '@tevm/primitives';
async function estimateWithCongestion(tx) {
const baseEstimate = await provider.estimateGas(tx);
const estimate = GasEstimate.from(baseEstimate);
// Check network congestion
const block = await provider.getBlock('latest');
const utilization = Number(block.gasUsed) / Number(block.gasLimit);
// Adjust buffer based on congestion
let buffer = 20; // Base 20%
if (utilization > 0.9) buffer = 50; // High congestion
else if (utilization > 0.7) buffer = 35; // Medium congestion
const withBuffer = GasEstimate.withBuffer(estimate, buffer);
return GasEstimate.toGasLimit(withBuffer);
}
Why Add Buffer?
eth_estimateGas returns the minimum gas needed under ideal conditions:
- State changes: Between estimation and execution, blockchain state may change
- Gas costs: Hard forks can change opcode gas costs
- Execution paths: Conditional logic may take different paths
- Rounding: EVM operations round up, estimation may round down
Without buffer: Transaction may fail with “out of gas” error.
With buffer: Transaction succeeds, excess gas refunded.
Estimation Strategies
Standard (20-25%)
Good for:
- Simple transfers
- Known contract calls
- Stable network conditions
const buffered = GasEstimate.withBuffer(estimate, 20);
Conservative (30-40%)
Good for:
- Complex contract interactions
- First-time contract calls
- Unknown execution paths
const buffered = GasEstimate.withBuffer(estimate, 35);
Very Safe (50%+)
Good for:
- Network congestion
- Critical transactions
- Maximum safety needed
const buffered = GasEstimate.withBuffer(estimate, 50);
Common Estimates
| Operation | Typical Estimate |
|---|
| ETH transfer | 21,000 |
| ERC20 transfer | 50,000-65,000 |
| Uniswap swap | 120,000-180,000 |
| NFT mint | 80,000-150,000 |
| Contract deploy | Varies widely |
EIPs
- EIP-150: Gas cost changes (1/64th rule)
- EIP-2929: Cold/warm storage access costs
- EIP-3529: Refund reduction (doesn’t affect estimation)
See Also