alloy-flashblocks 0.1.0

Stream Base L2 flashblocks and query preconfirmation state using Alloy.
Documentation
# Alloy Flashblocks

Stream Base L2 flashblocks and query preconfirmation state using [Alloy].

Flashblocks are ~200ms preconfirmations on Base. Instead of waiting ~2 seconds
for block finalization, you get transaction feedback in ~200ms.

[Alloy]: https://github.com/alloy-rs/alloy

## Installation

```toml
[dependencies]
alloy-flashblocks = "0.1.0"
```

## Features

This crate provides the [`FlashblocksProviderExt`] extension trait with:

- **Streaming**: `watch_flashblocks()` - stream pending block updates
- **State queries**: Query balances, nonces, simulate calls against flashblock state
- **Preconfirmation helpers**: Wait for transaction preconfirmation (~200ms feedback)

## Usage

### Stream Flashblocks

```rust,ignore
use alloy::providers::ProviderBuilder;
use alloy_flashblocks::FlashblocksProviderExt;
use futures_util::StreamExt;

let provider = ProviderBuilder::new()
    .connect_http("https://mainnet-preconf.base.org".parse()?);

let mut stream = provider.watch_flashblocks().into_stream();

while let Some(block) = stream.next().await {
    println!("Block {} | {} txs", block.header.number, block.transactions.len());
}
```

### Query Flashblock State

Query balances, nonces, and simulate calls against the current flashblock state
(including preconfirmed transactions):

```rust,ignore
use alloy::providers::ProviderBuilder;
use alloy_flashblocks::FlashblocksProviderExt;

let provider = ProviderBuilder::new()
    .connect_http("https://mainnet-preconf.base.org".parse()?);

// Get current flashblock
let block = provider.flashblock().await?;

// Query balance including preconfirmed txs
let balance = provider.flashblock_balance(address).await?;

// Query nonce for next tx (accounts for pending txs)
let nonce = provider.flashblock_nonce(address).await?;

// Simulate a call against flashblock state
let result = provider.flashblock_call(&tx).await?;

// Estimate gas against flashblock state
let gas = provider.flashblock_estimate_gas(&tx).await?;

// Get logs up to flashblock
let logs = provider.flashblock_logs(filter).await?;
```

### Wait for Preconfirmation

Get ~200ms feedback on transaction inclusion instead of waiting ~2s for block finalization:

```rust,ignore
use alloy::providers::ProviderBuilder;
use alloy_flashblocks::FlashblocksProviderExt;

let provider = ProviderBuilder::new()
    .wallet(wallet)
    .connect_http("https://sepolia-preconf.base.org".parse()?);

// Send transaction
let pending = provider.send_transaction(tx).await?;
let tx_hash = *pending.tx_hash();

// Wait for preconfirmation (~200ms)
let receipt = provider.wait_for_preconfirmation(tx_hash).await?;
println!("Preconfirmed! Status: {:?}", receipt.status());

// Or just check if preconfirmed
let is_preconf = provider.is_preconfirmed(tx_hash).await?;
```

## RPC Endpoints

| Network | Endpoint |
|---------|----------|
| Base Mainnet | `https://mainnet-preconf.base.org` |
| Base Sepolia | `https://sepolia-preconf.base.org` |

## API Reference

### Streaming

| Method | Description |
|--------|-------------|
| `watch_flashblocks()` | Stream pending block updates (polls every 120ms) |

### State Queries

All methods query against pending/flashblock state:

| Method | Description |
|--------|-------------|
| `flashblock()` | Get current flashblock |
| `flashblock_balance(addr)` | Balance including preconfirmed txs |
| `flashblock_nonce(addr)` | Nonce for sending next tx |
| `flashblock_call(&tx)` | Simulate call against flashblock state |
| `flashblock_estimate_gas(&tx)` | Gas estimate against flashblock |
| `flashblock_logs(filter)` | Logs up to flashblock |
| `flashblock_simulate(&payload)` | Multi-call simulation |

### Preconfirmation Helpers

| Method | Description |
|--------|-------------|
| `wait_for_preconfirmation(tx_hash)` | Poll until tx is preconfirmed |
| `is_preconfirmed(tx_hash)` | Check if tx has receipt |

## How It Works

The poller calls `eth_getBlockByNumber("pending")` every 120ms against a
flashblocks-enabled RPC endpoint and yields new blocks when the block hash changes.

Base's sequencer emits flashblocks every ~200ms, providing near-instant
preconfirmation of transaction inclusion.

## License

MIT

## Credits

- [Alloy]https://github.com/alloy-rs/alloy
- [Base Flashblocks]https://docs.base.org/chain/flashblocks

[`FlashblocksProviderExt`]: https://docs.rs/alloy-flashblocks/latest/alloy_flashblocks/trait.FlashblocksProviderExt.html