eth-etl-core 0.1.0

Core types and utilities for Ethereum ETL
Documentation
use serde::{Deserialize, Serialize};

/// Ethereum transaction with EIP-1559 and EIP-4844 support
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EthTransaction {
    #[serde(rename = "type", default = "default_transaction_type")]
    pub item_type: String,
    pub hash: String,
    pub nonce: u64,
    pub block_hash: String,
    pub block_number: u64,
    pub block_timestamp: u64,
    pub transaction_index: u64,
    pub from_address: String,
    pub to_address: Option<String>,
    pub value: String,
    pub gas: u64,
    pub gas_price: Option<u64>,
    pub input: String,
    /// Transaction type (0=legacy, 1=access list, 2=EIP-1559, 3=blob)
    pub transaction_type: Option<u64>,
    /// EIP-1559 max fee per gas
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_fee_per_gas: Option<u64>,
    /// EIP-1559 max priority fee per gas
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_priority_fee_per_gas: Option<u64>,
    /// EIP-4844 max fee per blob gas
    #[serde(skip_serializing_if = "Option::is_none")]
    pub max_fee_per_blob_gas: Option<u64>,
    /// EIP-4844 blob versioned hashes
    #[serde(skip_serializing_if = "Vec::is_empty", default)]
    pub blob_versioned_hashes: Vec<String>,
}

fn default_transaction_type() -> String {
    "transaction".to_string()
}

impl EthTransaction {
    /// Get CSV headers for transaction export
    pub fn csv_headers() -> &'static [&'static str] {
        &[
            "hash",
            "nonce",
            "block_hash",
            "block_number",
            "block_timestamp",
            "transaction_index",
            "from_address",
            "to_address",
            "value",
            "gas",
            "gas_price",
            "input",
            "transaction_type",
            "max_fee_per_gas",
            "max_priority_fee_per_gas",
            "max_fee_per_blob_gas",
            "blob_versioned_hashes",
        ]
    }

    /// Convert to CSV row
    pub fn to_csv_row(&self) -> Vec<String> {
        vec![
            self.hash.clone(),
            self.nonce.to_string(),
            self.block_hash.clone(),
            self.block_number.to_string(),
            self.block_timestamp.to_string(),
            self.transaction_index.to_string(),
            self.from_address.clone(),
            self.to_address.clone().unwrap_or_default(),
            self.value.clone(),
            self.gas.to_string(),
            self.gas_price.map(|v| v.to_string()).unwrap_or_default(),
            self.input.clone(),
            self.transaction_type
                .map(|v| v.to_string())
                .unwrap_or_default(),
            self.max_fee_per_gas
                .map(|v| v.to_string())
                .unwrap_or_default(),
            self.max_priority_fee_per_gas
                .map(|v| v.to_string())
                .unwrap_or_default(),
            self.max_fee_per_blob_gas
                .map(|v| v.to_string())
                .unwrap_or_default(),
            self.blob_versioned_hashes.join(","),
        ]
    }
}