alloy-flashblocks 0.1.0

Stream Base L2 flashblocks and query preconfirmation state using Alloy.
Documentation
//! Example: Wait for transaction preconfirmation
//!
//! Demonstrates the preconfirmation flow on Base Sepolia:
//! 1. Send a transaction
//! 2. Wait for preconfirmation (~200ms)
//!
//! Run with:
//!   PRIVATE_KEY=0x... cargo run --example preconfirmation

use alloy::{
    network::{EthereumWallet, TransactionBuilder},
    primitives::U256,
    providers::{Provider, ProviderBuilder},
    signers::local::PrivateKeySigner,
};
use alloy_flashblocks::FlashblocksProviderExt;
use eyre::{eyre, Result};
use std::time::Instant;

const RPC_URL: &str = "https://sepolia-preconf.base.org";

#[tokio::main]
async fn main() -> Result<()> {
    // Load private key from environment
    let pk = std::env::var("PRIVATE_KEY")
        .map_err(|_| eyre!("PRIVATE_KEY env var not set"))?;

    let signer: PrivateKeySigner = pk.parse()?;
    let wallet = EthereumWallet::from(signer.clone());
    let address = signer.address();

    println!("Using address: {}", address);

    // Build provider with wallet
    let provider = ProviderBuilder::new()
        .wallet(wallet)
        .connect_http(RPC_URL.parse()?);

    // Check balance
    let balance = provider.get_balance(address).await?;
    println!("Balance: {} wei", balance);

    // Build transaction: send 200 gwei to ourselves
    let tx = alloy::rpc::types::TransactionRequest::default()
        .with_to(address)
        .with_value(U256::from(200_000_000_000u64)); // 200 gwei

    // Send transaction
    let start = Instant::now();
    let pending = provider.send_transaction(tx).await?;
    let tx_hash = *pending.tx_hash();
    println!("\nSent tx: {}", tx_hash);
    println!("Send took: {:?}", start.elapsed());

    // Wait for preconfirmation
    println!("\nWaiting for preconfirmation...");
    let preconf_start = Instant::now();
    let preconf_receipt = provider.wait_for_preconfirmation(tx_hash).await?;
    let preconf_time = preconf_start.elapsed();

    println!("Preconfirmed in {:?}", preconf_time);
    println!("  Block: {:?}", preconf_receipt.block_number);
    println!("  Status: {:?}", preconf_receipt.status());
    println!("  Gas used: {}", preconf_receipt.gas_used);
    println!("  Effective gas price: {:?}", preconf_receipt.effective_gas_price);

    // Verify is_preconfirmed returns true
    let is_preconf = provider.is_preconfirmed(tx_hash).await?;
    println!("  is_preconfirmed: {}", is_preconf);

    println!("\nTotal time from send to preconfirmation: {:?}", start.elapsed());

    Ok(())
}