This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.
Utils
Voltaire provides a collection of generic utilities essential for building robust Ethereum applications. These utilities handle common patterns like retry logic, rate limiting, polling, timeouts, and batch processing.
Why Utils?
Ethereum applications face unique challenges:
- Transient failures: RPC nodes may be temporarily unavailable or rate-limited
- Async operations: Transactions and state changes require polling for confirmation
- Rate limits: Public RPC endpoints enforce strict rate limits
- Long operations: Block production and transaction confirmation take time
- Batch optimization: Multiple similar requests can be batched for efficiency
These utilities provide battle-tested solutions to these challenges.
Available Utilities
Retry with Exponential Backoff
Automatically retry failed operations with exponential backoff and jitter.
import { retryWithBackoff } from '@tevm/voltaire/utils';
const blockNumber = await retryWithBackoff(
() => provider.eth_blockNumber(),
{
maxRetries: 5,
initialDelay: 1000,
factor: 2,
jitter: true
}
);
Learn more →
Rate Limiting
Throttle, debounce, and rate-limit function calls.
import { RateLimiter } from '@tevm/voltaire/utils';
const limiter = new RateLimiter({
maxRequests: 10,
interval: 1000,
strategy: 'queue'
});
const balance = await limiter.execute(
() => provider.eth_getBalance(address)
);
Learn more →
Polling
Poll operations until they succeed or timeout, with optional backoff.
import { pollForReceipt } from '@tevm/voltaire/utils';
const receipt = await pollForReceipt(
txHash,
(hash) => provider.eth_getTransactionReceipt(hash),
{ timeout: 120000 }
);
Learn more →
Timeout
Add timeouts to promises and async operations.
import { withTimeout } from '@tevm/voltaire/utils';
const result = await withTimeout(
provider.eth_call({ to, data }),
{ ms: 5000, message: 'Call timeout' }
);
Learn more →
Batch Processing
Automatically batch similar operations for efficiency.
import { BatchQueue } from '@tevm/voltaire/utils';
const queue = new BatchQueue({
maxBatchSize: 50,
maxWaitTime: 100,
processBatch: async (addresses) => {
return Promise.all(
addresses.map(addr => provider.eth_getBalance(addr))
);
}
});
const balance = await queue.add(address);
Learn more →
Installation
Utils are included with Voltaire. No additional dependencies required.
npm install @tevm/voltaire
# or
bun add @tevm/voltaire
Design Principles
Vanilla TypeScript
All utilities use standard Promise-based APIs. No framework dependencies.
Type Safe
Full TypeScript support with generic types for maximum type safety.
Tree Shakeable
Import only what you need. Each utility is independently importable.
Zero Runtime Overhead
Minimal abstractions. Direct, efficient implementations.
Common Patterns
Resilient RPC Calls
Combine retry and timeout for robust RPC calls:
import { retryWithBackoff, withTimeout } from '@tevm/voltaire/utils';
const resilientCall = async <T>(fn: () => Promise<T>): Promise<T> => {
return retryWithBackoff(
() => withTimeout(fn(), { ms: 10000 }),
{
maxRetries: 3,
shouldRetry: (error) => {
// Don't retry on timeout
return error.name !== 'TimeoutError';
}
}
);
};
const blockNumber = await resilientCall(
() => provider.eth_blockNumber()
);
Rate-Limited Batch Processing
Combine rate limiting and batching:
import { RateLimiter, BatchQueue } from '@tevm/voltaire/utils';
const limiter = new RateLimiter({
maxRequests: 10,
interval: 1000
});
const queue = new BatchQueue({
maxBatchSize: 50,
maxWaitTime: 100,
processBatch: async (addresses) => {
return limiter.execute(() =>
Promise.all(
addresses.map(addr => provider.eth_getBalance(addr))
)
);
}
});
Poll with Timeout and Retry
Combine polling, timeout, and retry:
import { poll, withTimeout, retryWithBackoff } from '@tevm/voltaire/utils';
const waitForBlock = async (blockNumber: bigint): Promise<Block> => {
return withTimeout(
poll(
() => retryWithBackoff(
() => provider.eth_getBlockByNumber(blockNumber)
),
{
interval: 1000,
validate: (block) => block !== null
}
),
{ ms: 60000 }
);
};
Next Steps