arb-sequencer-network 0.5.0

Network-layer types for the Arbitrum sequencer feed protocol
Documentation
use std::str::FromStr;

use alloy_core::hex::FromHex;
use alloy_primitives::{Address, FixedBytes, U256};
use serde::*;
use serde_json::Value;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
    pub version: u8,
    pub messages: Option<Vec<BroadcastFeedMessage>>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BroadcastFeedMessage {
    pub sequence_number: u64,
    #[serde(rename = "message")]
    pub message_with_meta_data: MessageWithMetadata,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MessageWithMetadata {
    #[serde(rename = "message")]
    pub l1_incoming_message: L1IncomingMessage,
    pub delayed_messages_read: u64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BatchDataStats {
    #[serde(rename = "Length")]
    pub length: u64,
    #[serde(rename = "NonZeros")]
    pub non_zeros: u64,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct L1IncomingMessage {
    pub header: Header,
    #[serde(rename = "l2Msg")]
    pub l2msg: String,
    #[serde(rename = "batchGasCost")]
    pub legacy_batch_gas_cost: Option<u64>,
    #[serde(rename = "batchDataTokens")]
    pub batch_data_stats: Option<BatchDataStats>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Header {
    pub kind: u8,
    pub sender: String,
    pub block_number: u64,
    pub timestamp: u64,
    pub request_id: Value,
    pub base_fee_l1: Value,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct L1Header {
    pub kind: u8,
    pub block_number: u64,
    pub timestamp: u64,
    pub request_id: Option<FixedBytes<32>>,
    pub base_fee_l1: Option<U256>,
    pub poster: Address,
    pub delayed_messages_read: u64,
}
impl L1Header {
    pub fn from_header(header: &Header, delayed_messages_read: u64) -> Result<Self, String> {
        let poster = Address::from_str(&header.sender)
            .map_err(|e| format!("failed to parse poster address: {}", e))?;
        let request_id_str = header.request_id.as_str();
        let request_id = match request_id_str {
            Some(s) => {
                let bytes = <[u8; 32]>::from_hex(s.trim_start_matches("0x"))
                    .map_err(|e| format!("failed to parse request_id hex string '{}': {}", s, e))?;
                Some(FixedBytes::from(bytes))
            }
            None => None,
        };
        let base_fee_l1_u64 = header.base_fee_l1.as_u64();
        let base_fee_l1 = base_fee_l1_u64.map(|x| U256::from(x));
        Ok(L1Header {
            kind: header.kind,
            block_number: header.block_number,
            timestamp: header.timestamp,
            request_id,
            base_fee_l1,
            poster,
            delayed_messages_read,
        })
    }
}

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageType {
    L2Message = 3,
    EndOfBlock = 6,
    L2FundedByL1 = 7,
    RollupEvent = 8,
    SubmitRetryable = 9,
    BatchForGasEstimation = 10,
    Initialize = 11,
    EthDeposit = 12,
    BatchPostingReport = 13,
    Invalid = 0xFF,
}
impl MessageType {
    pub fn from_u8(value: u8) -> Self {
        match value {
            3 => MessageType::L2Message,
            6 => MessageType::EndOfBlock,
            7 => MessageType::L2FundedByL1,
            8 => MessageType::RollupEvent,
            9 => MessageType::SubmitRetryable,
            10 => MessageType::BatchForGasEstimation,
            11 => MessageType::Initialize,
            12 => MessageType::EthDeposit,
            13 => MessageType::BatchPostingReport,
            _ => MessageType::Invalid,
        }
    }
    #[allow(dead_code)]
    pub fn to_u8(&self) -> u8 {
        match self {
            MessageType::L2Message => 3,
            MessageType::EndOfBlock => 6,
            MessageType::L2FundedByL1 => 7,
            MessageType::RollupEvent => 8,
            MessageType::SubmitRetryable => 9,
            MessageType::BatchForGasEstimation => 10,
            MessageType::Initialize => 11,
            MessageType::EthDeposit => 12,
            MessageType::BatchPostingReport => 13,
            MessageType::Invalid => 0xFF,
        }
    }
}