transaction-decoder 0.1.13

A CLI tool for decoding EVM transactions
Documentation
use alloy::{dyn_abi::DynSolValue, hex};
use colored::Colorize;
use semver::Version;

/// Checks if a newer version of this crate is available and notifies the user.
pub async fn check_for_updates() {
    let crate_name = env!("CARGO_PKG_NAME");
    let current_version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();

    let url = format!("https://crates.io/api/v1/crates/{}", crate_name);

    let client = reqwest::Client::builder()
        .user_agent("transaction-decoder (rad:z2zJ3dFpEWM4fea4KDaRpNqxJG48v)")
        .build()
        .unwrap();

    if let Ok(response) = client.get(&url).send().await {
        if let Ok(json) = response.json::<serde_json::Value>().await {
            if let Some(latest_str) = json["crate"]["max_version"].as_str() {
                if let Ok(latest_version) = Version::parse(latest_str) {
                    if latest_version > current_version {
                        println!(
                            "{}: A new version ({}) is available! You are using {}.\nRun {} to upgrade.",
                            "Update available".yellow(),
                            latest_version.to_string().purple(),
                            current_version.to_string().purple(),
                            "cargo install transaction-decoder --force".green()
                        );
                    }
                }
            }
        }
    }
}

pub fn draw_gas_circle(used: u128, limit: u128) -> String {
    let percent = (used as f64 / limit as f64) * 100.00;
    let filled_segments = (percent / 10.00).round() as usize;
    let total_segments = 10;

    let filled = "".repeat(filled_segments);
    let empty = "".repeat(total_segments - filled_segments);

    format!("[{}]", format!("{filled}{empty}"))
}

pub fn format_dynsol_value(val: &DynSolValue) -> String {
    match val {
        DynSolValue::Bytes(bytes) => format!("0x{}", hex::encode(bytes)),
        DynSolValue::FixedBytes(word, _) => format!("0x{}", hex::encode(word)),
        DynSolValue::Tuple(inner) => {
            let items: Vec<String> = inner.iter().map(format_dynsol_value).collect();
            format!("({})", items.join(", "))
        }
        DynSolValue::Array(arr) => {
            let items: Vec<String> = arr.iter().map(format_dynsol_value).collect();
            format!("[{}]", items.join(", "))
        }
        DynSolValue::Uint(uint, _) => format!("{}", uint.to_string()),
        DynSolValue::Bool(val) => format!("{}", val.to_string()),
        DynSolValue::Address(val) => format!("{}", val.to_string()),
        other => format!("{:?}", other),
    }
}