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