Skip to content

Latest commit

 

History

88 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SequencerClient

A Rust library for reading and parsing messages from the Arbitrum sequencer feed into typed transactions.

Features

Supported Transaction Types

Standard L2 Transactions:

  • Legacy transactions
  • EIP-2930 transactions (access lists)
  • EIP-1559 transactions (dynamic fees)
  • EIP-7702 transactions (set code)

Arbitrum-Specific Transactions:

  • ETH deposits (TxDeposit)
  • Retryable tickets (SubmitRetryableTx)
  • Batch posting reports (internal transaction type)

Key Capabilities

  • Multiple parallel WebSocket connections for improved throughput
  • Automatic reconnection on connection failures
  • Out-of-order message buffering and reordering
  • Recursive parsing of nested batch transactions
  • Stream-based API using Rust async streams

Motivation

Listening to the sequencer feed is faster than subscribing to RPC logs (ofc it won't work if you do actually need logs since the sequencer just emits transactions). Most existing libraries skip batch transactions, which make up approximately 80% of all transactions on Arbitrum. This library handles all transaction types including batched transactions.

Usage

Installation

Add to your Cargo.toml:

[dependencies]
sequencer_client = "0.4"

Basic Example

use futures_util::stream::StreamExt;
use sequencer_client::reader::SequencerReader;
use arb_sequencer_consensus::transactions::ArbTxEnvelope;

#[tokio::main]
async fn main() {
    // Install a default crypto provider (required)
    rustls::crypto::aws_lc_rs::default_provider()
        .install_default()
        .expect("Failed to install rustls crypto provider");

    // Connect to the Arbitrum One sequencer feed
    let url = "wss://arb1-feed.arbitrum.io/feed";
    let chain_id = 42161; // Arbitrum One
    let connections = 10; // Number of parallel WebSocket connections

    let reader = SequencerReader::new(url, chain_id, connections).await;
    let mut stream = reader.into_stream();

    // Process messages from the stream
    while let Some(msg_result) = stream.next().await {
        match msg_result {
            Ok(msg) => {
                println!("Sequence: {}, Transactions: {}",
                    msg.sequence_number,
                    msg.txs.len()
                );

                // Access individual transactions
                for tx in msg.txs {
                    match tx {
                        ArbTxEnvelope::Legacy(tx) => {
                            println!("Legacy tx: {}", tx.tx_hash());
                        }
                        ArbTxEnvelope::Eip1559(tx) => {
                            println!("EIP-1559 tx: {}", tx.tx_hash());
                        }
                        ArbTxEnvelope::DepositTx(tx) => {
                            println!("Deposit from: {}", tx.from());
                        }
                        ArbTxEnvelope::SubmitRetryableTx(tx) => {
                            println!("Retryable ticket from: {}", tx.from());
                        }
                        _ => {}
                    }
                }
            }
            Err(e) => {
                eprintln!("Error: {}", e);
            }
        }
    }
}

SequencerMessage Structure

Each message from the stream contains:

  • sequence_number: The sequential message number from the feed
  • txs: Vector of parsed transactions (Vec<ArbTxEnvelope>)
  • is_last_in_block: Whether this is the last message in a block
  • timestamp: Message timestamp from the L1 header
  • received_at: Local instant when the message was received
  • l1_header: L1 header information

API Notes

Required Setup:

  • You must install a default crypto provider before creating a SequencerReader
  • Recommended: rustls::crypto::aws_lc_rs::default_provider().install_default()

Connection Parameters:

  • url: WebSocket endpoint (e.g., wss://arb1-feed.arbitrum.io/feed)
  • chain_id: Network chain ID (42161 for Arbitrum One, 42170 for Arbitrum Nova)
  • connections: Number of parallel WebSocket connections (recommended: less than 10)

Stream Behavior:

  • Messages are automatically reordered if received out of sequence
  • Connections automatically reconnect on failure
  • Duplicate messages are filtered out
  • The stream yields Result<SequencerMessage> items

About the Type System

This library uses two internal crates for Arbitrum-specific types:

arb_sequencer_consensus: Contains consensus-layer types for Arbitrum transactions, including deposit transactions, retryable tickets, and batch posting reports. These types extend the standard Alloy transaction types to support Arbitrum's unique transaction formats.

arb_sequencer_network: Contains network-layer types for the sequencer feed protocol, including message parsing and WebSocket communication structures.

About

Library to read the arbitrum sequencer feed with built in transaction parsing

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages