seedelf_cli/
display.rs

1use crate::constants::{Config, get_config};
2use crate::koios::{contains_policy_id, credential_utxos, extract_bytes_with_logging, tip};
3use blstrs::Scalar;
4use colored::Colorize;
5
6pub async fn block_number_and_time(network_flag: bool) {
7    match tip(network_flag).await {
8        Ok(tips) => {
9            if let Some(tip) = tips.first() {
10                println!(
11                    "\n{} {}\n{} {}",
12                    "Block Number:".bold().bright_blue(),
13                    tip.block_no.to_string().yellow(),
14                    "Time:".bold().bright_blue(),
15                    tip.block_time.to_string().yellow()
16                );
17            }
18        }
19        Err(err) => {
20            eprintln!(
21                "Failed to fetch blockchain tip: {}\nWait a few moments and try again.",
22                err
23            );
24        }
25    }
26}
27
28pub fn preprod_text(network_flag: bool) {
29    if network_flag {
30        println!("{}", "\nRunning On The Pre-Production Network".cyan());
31    }
32}
33
34pub async fn all_seedelfs(sk: Scalar, network_flag: bool, variant: u64) {
35    let mut seedelfs: Vec<String> = Vec::new();
36
37    let config: Config = get_config(variant, network_flag).unwrap_or_else(|| {
38        eprintln!("Error: Invalid Variant");
39        std::process::exit(1);
40    });
41
42    match credential_utxos(config.contract.wallet_contract_hash, network_flag).await {
43        Ok(utxos) => {
44            for utxo in utxos {
45                // Extract bytes
46                if let Some(inline_datum) = extract_bytes_with_logging(&utxo.inline_datum) {
47                    // utxo must be owned by this secret scaler
48                    if inline_datum.is_owned(sk) {
49                        // its owned but lets not count the seedelf in the balance
50                        if contains_policy_id(&utxo.asset_list, config.contract.seedelf_policy_id) {
51                            let asset_name: &String = utxo
52                                .asset_list
53                                .as_ref()
54                                .and_then(|vec| {
55                                    vec.iter()
56                                        .find(|asset| {
57                                            asset.policy_id == config.contract.seedelf_policy_id
58                                        })
59                                        .map(|asset| &asset.asset_name)
60                                })
61                                .unwrap();
62                            seedelfs.push(asset_name.to_string());
63                        }
64                    }
65                }
66            }
67        }
68        Err(err) => {
69            eprintln!(
70                "Failed to fetch UTxOs: {}\nWait a few moments and try again.",
71                err
72            );
73        }
74    }
75    if !seedelfs.is_empty() {
76        println!("{}", "\nCurrent Seedelf:\n".bright_green());
77        for seedelf in seedelfs {
78            println!("\nSeedelf: {}", seedelf.white());
79            seedelf_label(seedelf);
80        }
81    }
82}
83
84pub fn seedelf_label(seedelf: String) {
85    let substring: String = seedelf[8..38].to_string();
86    let label: String = hex_to_ascii(&substring).unwrap();
87    if !label.starts_with('.') {
88        let cleaned: String = label.chars().filter(|&c| c != '.').collect();
89        println!("Label: {}", cleaned.bright_yellow())
90    }
91}
92
93pub fn hex_to_ascii(hex: &str) -> Result<String, &'static str> {
94    // Ensure the length of the hex string is even
95    if hex.len() % 2 != 0 {
96        return Err("Hex string must have an even length");
97    }
98
99    let ascii = (0..hex.len())
100        .step_by(2)
101        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16))
102        .collect::<Result<Vec<_>, _>>()
103        .map_err(|_| "Invalid hex string")?
104        .into_iter()
105        .map(|b| {
106            if b.is_ascii_graphic() || b.is_ascii_whitespace() {
107                char::from(b)
108            } else {
109                '.'
110            }
111        })
112        .map(|c| {
113            if c == '\n' || c == '\r' || c == '\t' {
114                '.'
115            } else {
116                c
117            }
118        }) // Replace control characters
119        .collect::<String>();
120
121    Ok(ascii)
122}