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.
Looking for Contributors! This Skill needs an implementation.Contributing a Skill involves:
- Writing a reference implementation with full functionality
- Adding comprehensive tests
- Writing documentation with usage examples
See the ethers-provider Skill for an example of a complete Skill implementation.Interested? Open an issue or PR at github.com/evmts/voltaire.
Skill — Copyable reference implementation. Use as-is or customize. See Skills Philosophy.
Real-time Ethereum subscriptions over WebSocket. Subscribe to new blocks, pending transactions, and log events without polling.
Why WebSocket?
HTTP providers poll for updates. WebSocket providers receive push notifications:
// HTTP - polling (inefficient)
setInterval(async () => {
const block = await httpProvider.getBlockNumber();
}, 12000);
// WebSocket - push (efficient)
wsProvider.subscribe('newHeads', (block) => {
console.log('New block:', block.number);
});
WebSocket is essential for:
- Real-time trading UIs
- Live transaction feeds
- Instant event notifications
- Mempool monitoring
Planned Implementation
Basic Subscriptions
const provider = WebSocketProvider('wss://eth-mainnet.g.alchemy.com/v2/KEY');
// Subscribe to new blocks
const unsubBlocks = await provider.subscribe('newHeads', (block) => {
console.log('Block:', block.number, 'Hash:', block.hash);
});
// Subscribe to pending transactions
const unsubPending = await provider.subscribe('newPendingTransactions', (txHash) => {
console.log('Pending tx:', txHash);
});
// Subscribe to logs (events)
const unsubLogs = await provider.subscribe('logs', {
address: USDC_ADDRESS,
topics: [TRANSFER_TOPIC]
}, (log) => {
console.log('Transfer:', log);
});
// Cleanup
unsubBlocks();
unsubPending();
unsubLogs();
Async Iterator Pattern
// Use for-await for cleaner code
for await (const block of provider.blocks()) {
console.log('Block:', block.number);
if (shouldStop) break;
}
// Filter specific events
for await (const log of provider.logs({ address: USDC })) {
const decoded = decodeTransferLog(log);
console.log(`${decoded.from} -> ${decoded.to}: ${decoded.value}`);
}
Reconnection Handling
const provider = WebSocketProvider({
url: 'wss://...',
reconnect: {
auto: true,
maxAttempts: 10,
delay: 1000,
maxDelay: 30000,
},
onReconnect: () => {
console.log('Reconnected, resubscribing...');
},
onDisconnect: (error) => {
console.log('Disconnected:', error);
}
});
Subscription Management
// Get active subscriptions
const subs = provider.getSubscriptions();
// [{ id: '0x1', type: 'newHeads' }, ...]
// Unsubscribe all
await provider.unsubscribeAll();
// Check connection status
provider.isConnected(); // true/false
Use Cases
Live Price Feed
const provider = WebSocketProvider('wss://...');
// Watch Uniswap V3 pool for price updates
await provider.subscribe('logs', {
address: UNISWAP_POOL,
topics: [SWAP_TOPIC]
}, (log) => {
const { sqrtPriceX96 } = decodeSwapLog(log);
const price = calculatePrice(sqrtPriceX96);
updatePriceDisplay(price);
});
Transaction Confirmation
async function waitForConfirmation(txHash, confirmations = 1) {
let confirmedBlock = null;
for await (const block of provider.blocks()) {
if (!confirmedBlock) {
const receipt = await provider.getTransactionReceipt(txHash);
if (receipt) confirmedBlock = receipt.blockNumber;
}
if (confirmedBlock && block.number >= confirmedBlock + confirmations) {
return { confirmed: true, confirmations };
}
}
}
Mempool Monitoring
// Watch for pending transactions to specific address
await provider.subscribe('newPendingTransactions', async (txHash) => {
const tx = await provider.getTransaction(txHash);
if (tx?.to === MY_CONTRACT) {
console.log('Incoming tx:', tx);
}
});