React Hooks for Ethereum providing reactive primitives for wallet connections, smart contract interactions, and blockchain data
—
Gas price monitoring and transaction fee estimation with support for EIP-1559 fee markets. This module provides comprehensive gas and fee estimation functionality for optimal transaction pricing and network cost management.
Hook to estimate gas required for a transaction before sending it.
/**
* Hook to estimate gas for transaction
* @param parameters - Gas estimation parameters
* @returns Estimated gas amount required for the transaction
*/
function useEstimateGas<config = Config, selectData = UseEstimateGasReturnType>(
parameters: UseEstimateGasParameters<config, selectData>
): UseEstimateGasReturnType<selectData>;
interface UseEstimateGasParameters<config = Config, selectData = UseEstimateGasReturnType> {
/** Recipient address */
to: Address;
/** Transaction value */
value?: bigint;
/** Transaction data */
data?: Hex;
/** Account to estimate from */
account?: Address;
/** Block number to estimate at */
blockNumber?: bigint;
blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Chain to use */
chainId?: config['chains'][number]['id'];
/** Gas price for estimation */
gasPrice?: bigint;
/** Max fee per gas */
maxFeePerGas?: bigint;
/** Max priority fee per gas */
maxPriorityFeePerGas?: bigint;
/** Nonce */
nonce?: number;
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
select?: (data: UseEstimateGasReturnType) => selectData;
};
}
type UseEstimateGasReturnType = bigint;Usage Example:
import { useEstimateGas, useSendTransaction } from "wagmi";
import { parseEther, formatGwei } from "viem";
function GasEstimationExample() {
const transactionParams = {
to: '0x742d35Cc6634C0532925a3b8D' as const,
value: parseEther('0.1'),
};
const { data: gasEstimate, isLoading } = useEstimateGas(transactionParams);
const { sendTransaction } = useSendTransaction();
const handleSend = () => {
sendTransaction({
...transactionParams,
gas: gasEstimate, // Use estimated gas
});
};
return (
<div>
{isLoading ? (
<p>Estimating gas...</p>
) : (
<div>
<p>Estimated gas: {gasEstimate?.toString()}</p>
<button onClick={handleSend}>Send with estimated gas</button>
</div>
)}
</div>
);
}Hook to get current network gas price for legacy transactions.
/**
* Hook to get current gas price
* @param parameters - Gas price query parameters
* @returns Current network gas price in wei
*/
function useGasPrice<config = Config, selectData = UseGasPriceReturnType>(
parameters?: UseGasPriceParameters<config, selectData>
): UseGasPriceReturnType<selectData>;
interface UseGasPriceParameters<config = Config, selectData = UseGasPriceReturnType> {
/** Chain to get gas price for */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
refetchInterval?: number;
select?: (data: UseGasPriceReturnType) => selectData;
};
}
type UseGasPriceReturnType = bigint;Hook to estimate fees per gas for EIP-1559 transactions (replaces legacy gas price).
/**
* Hook to estimate fees per gas (replaces useFeeData)
* @param parameters - Fee estimation parameters
* @returns Fee estimates for EIP-1559 transactions
*/
function useEstimateFeesPerGas<config = Config, selectData = UseEstimateFeesPerGasReturnType>(
parameters?: UseEstimateFeesPerGasParameters<config, selectData>
): UseEstimateFeesPerGasReturnType<selectData>;
interface UseEstimateFeesPerGasParameters<config = Config, selectData = UseEstimateFeesPerGasReturnType> {
/** Fee multiplier for priority adjustment */
formatUnits?: 'wei' | 'gwei';
/** Transaction type hint */
type?: 'legacy' | 'eip1559';
/** Chain to estimate fees for */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
refetchInterval?: number;
select?: (data: UseEstimateFeesPerGasReturnType) => selectData;
};
}
interface UseEstimateFeesPerGasReturnType {
/** Legacy gas price */
gasPrice?: bigint;
/** Max fee per gas (EIP-1559) */
maxFeePerGas?: bigint;
/** Max priority fee per gas (EIP-1559) */
maxPriorityFeePerGas?: bigint;
}Usage Example:
import { useEstimateFeesPerGas } from "wagmi";
import { formatGwei } from "viem";
function FeeEstimation() {
const { data: feeData, isLoading } = useEstimateFeesPerGas();
if (isLoading) return <div>Loading fee estimates...</div>;
return (
<div>
<h3>Current Fee Estimates</h3>
{feeData?.gasPrice && (
<p>Gas Price: {formatGwei(feeData.gasPrice)} gwei</p>
)}
{feeData?.maxFeePerGas && (
<p>Max Fee: {formatGwei(feeData.maxFeePerGas)} gwei</p>
)}
{feeData?.maxPriorityFeePerGas && (
<p>Max Priority Fee: {formatGwei(feeData.maxPriorityFeePerGas)} gwei</p>
)}
</div>
);
}Hook to estimate the maximum priority fee per gas for EIP-1559 transactions.
/**
* Hook to estimate max priority fee per gas
* @param parameters - Max priority fee estimation parameters
* @returns Estimated maximum priority fee per gas
*/
function useEstimateMaxPriorityFeePerGas<config = Config, selectData = UseEstimateMaxPriorityFeePerGasReturnType>(
parameters?: UseEstimateMaxPriorityFeePerGasParameters<config, selectData>
): UseEstimateMaxPriorityFeePerGasReturnType<selectData>;
interface UseEstimateMaxPriorityFeePerGasParameters<config = Config, selectData = UseEstimateMaxPriorityFeePerGasReturnType> {
/** Chain to estimate for */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
refetchInterval?: number;
select?: (data: UseEstimateMaxPriorityFeePerGasReturnType) => selectData;
};
}
type UseEstimateMaxPriorityFeePerGasReturnType = bigint;Hook to get historical fee data for analysis and prediction.
/**
* Hook to get fee history
* @param parameters - Fee history query parameters
* @returns Historical fee data for the specified block range
*/
function useFeeHistory<config = Config, selectData = UseFeeHistoryReturnType>(
parameters: UseFeeHistoryParameters<config, selectData>
): UseFeeHistoryReturnType<selectData>;
interface UseFeeHistoryParameters<config = Config, selectData = UseFeeHistoryReturnType> {
/** Number of blocks to fetch history for */
blockCount: number;
/** Newest block number or tag */
newestBlock?: bigint | 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';
/** Reward percentiles to calculate */
rewardPercentiles?: number[];
/** Chain to get history for */
chainId?: config['chains'][number]['id'];
config?: Config | config;
query?: {
enabled?: boolean;
staleTime?: number;
gcTime?: number;
select?: (data: UseFeeHistoryReturnType) => selectData;
};
}
interface UseFeeHistoryReturnType {
/** Base fee per gas for each block */
baseFeePerGas: bigint[];
/** Gas used ratio for each block */
gasUsedRatio: number[];
/** Oldest block number in the range */
oldestBlock: bigint;
/** Reward percentiles for each block */
reward?: bigint[][];
}Usage Example:
import { useFeeHistory } from "wagmi";
import { formatGwei } from "viem";
function FeeAnalytics() {
const { data: feeHistory, isLoading } = useFeeHistory({
blockCount: 10, // Last 10 blocks
rewardPercentiles: [25, 50, 75], // 25th, 50th, 75th percentiles
});
if (isLoading) return <div>Loading fee history...</div>;
const avgBaseFee = feeHistory?.baseFeePerGas.reduce((sum, fee) => sum + fee, 0n)
/ BigInt(feeHistory?.baseFeePerGas.length || 1);
return (
<div>
<h3>Fee Analytics</h3>
<p>Average Base Fee: {formatGwei(avgBaseFee || 0n)} gwei</p>
<p>Latest Block: {feeHistory?.oldestBlock.toString()}</p>
<h4>Recent Base Fees</h4>
{feeHistory?.baseFeePerGas.map((fee, i) => (
<div key={i}>
Block {(feeHistory.oldestBlock + BigInt(i)).toString()}: {formatGwei(fee)} gwei
</div>
))}
</div>
);
}import {
useEstimateFeesPerGas,
useFeeHistory,
useEstimateGas
} from "wagmi";
import { formatGwei, parseGwei } from "viem";
interface FeeSpeed {
name: string;
multiplier: number;
description: string;
}
const FEE_SPEEDS: FeeSpeed[] = [
{ name: 'Slow', multiplier: 0.9, description: '~5 min' },
{ name: 'Standard', multiplier: 1.0, description: '~2 min' },
{ name: 'Fast', multiplier: 1.1, description: '~30 sec' },
{ name: 'Urgent', multiplier: 1.25, description: '~15 sec' },
];
function DynamicFeeCalculator({
transactionParams
}: {
transactionParams: { to: Address; value?: bigint; data?: Hex }
}) {
const { data: currentFees } = useEstimateFeesPerGas();
const { data: gasEstimate } = useEstimateGas(transactionParams);
const { data: feeHistory } = useFeeHistory({
blockCount: 5,
rewardPercentiles: [10, 50, 90],
});
const calculateFeeOptions = () => {
if (!currentFees?.maxFeePerGas || !currentFees?.maxPriorityFeePerGas) {
return [];
}
return FEE_SPEEDS.map(speed => {
const maxPriorityFee = currentFees.maxPriorityFeePerGas! * BigInt(Math.floor(speed.multiplier * 100)) / 100n;
const maxFee = currentFees.maxFeePerGas! * BigInt(Math.floor(speed.multiplier * 100)) / 100n;
const estimatedCost = gasEstimate ? (gasEstimate * maxFee) : 0n;
return {
...speed,
maxFeePerGas: maxFee,
maxPriorityFeePerGas: maxPriorityFee,
estimatedCost,
};
});
};
const feeOptions = calculateFeeOptions();
return (
<div>
<h3>Transaction Fee Options</h3>
{feeOptions.map((option, i) => (
<div key={i} className="fee-option">
<h4>{option.name} ({option.description})</h4>
<p>Max Fee: {formatGwei(option.maxFeePerGas)} gwei</p>
<p>Priority Fee: {formatGwei(option.maxPriorityFeePerGas)} gwei</p>
{option.estimatedCost > 0n && (
<p>Est. Cost: {formatEther(option.estimatedCost)} ETH</p>
)}
</div>
))}
</div>
);
}import { useEstimateFeesPerGas, useGasPrice } from "wagmi";
import { formatGwei } from "viem";
import { useEffect, useState } from "react";
function FeeMonitor() {
const [feeHistory, setFeeHistory] = useState<bigint[]>([]);
const { data: currentFees } = useEstimateFeesPerGas({
query: { refetchInterval: 10000 } // Update every 10 seconds
});
const { data: gasPrice } = useGasPrice({
query: { refetchInterval: 10000 }
});
useEffect(() => {
if (currentFees?.maxFeePerGas) {
setFeeHistory(prev => [...prev.slice(-19), currentFees.maxFeePerGas!]);
}
}, [currentFees]);
const avgFee = feeHistory.length > 0
? feeHistory.reduce((sum, fee) => sum + fee, 0n) / BigInt(feeHistory.length)
: 0n;
const minFee = feeHistory.length > 0 ? feeHistory.reduce((min, fee) => fee < min ? fee : min) : 0n;
const maxFee = feeHistory.length > 0 ? feeHistory.reduce((max, fee) => fee > max ? fee : max) : 0n;
return (
<div className="fee-monitor">
<h3>Network Fee Monitor</h3>
<div className="current-fees">
<h4>Current Fees</h4>
{gasPrice && <p>Gas Price: {formatGwei(gasPrice)} gwei</p>}
{currentFees?.maxFeePerGas && (
<p>Max Fee: {formatGwei(currentFees.maxFeePerGas)} gwei</p>
)}
{currentFees?.maxPriorityFeePerGas && (
<p>Priority Fee: {formatGwei(currentFees.maxPriorityFeePerGas)} gwei</p>
)}
</div>
{feeHistory.length > 0 && (
<div className="fee-stats">
<h4>Fee Statistics (Last {feeHistory.length} updates)</h4>
<p>Average: {formatGwei(avgFee)} gwei</p>
<p>Min: {formatGwei(minFee)} gwei</p>
<p>Max: {formatGwei(maxFee)} gwei</p>
</div>
)}
</div>
);
}type Address = `0x${string}`;
type Hex = `0x${string}`;
interface GasEstimate {
/** Estimated gas units */
gas: bigint;
/** Estimated cost in wei */
cost: bigint;
}
interface FeeData {
/** Legacy gas price */
gasPrice?: bigint;
/** EIP-1559 max fee per gas */
maxFeePerGas?: bigint;
/** EIP-1559 max priority fee per gas */
maxPriorityFeePerGas?: bigint;
/** Last base fee per gas */
lastBaseFeePerGas?: bigint;
}
interface FeeSuggestion {
/** Suggested priority fee */
maxPriorityFeePerGas: bigint;
/** Suggested max fee */
maxFeePerGas: bigint;
/** Expected confirmation time */
estimatedTime: string;
/** Confidence level */
confidence: 'low' | 'medium' | 'high';
}Install with Tessl CLI
npx tessl i tessl/npm-wagmi