From 6255703bbb15a1378614dae0561ddec25f3bf7ec Mon Sep 17 00:00:00 2001 From: Uncle Stretch Date: Fri, 6 Dec 2024 17:13:25 +0300 Subject: [PATCH] get real balances for each one in address book Signed-off-by: Uncle Stretch --- src/components/wallet/accounts.rs | 10 ++- src/components/wallet/address_book.rs | 123 ++++++++++++++++++++------ 2 files changed, 102 insertions(+), 31 deletions(-) diff --git a/src/components/wallet/accounts.rs b/src/components/wallet/accounts.rs index b556d09..06733cf 100644 --- a/src/components/wallet/accounts.rs +++ b/src/components/wallet/accounts.rs @@ -387,10 +387,12 @@ impl Component for Accounts { Action::NewAccount(name) => self.create_new_account(name), Action::UpdateAccountName(new_name) => self.rename_account(new_name), Action::BalanceResponse(account_id, balance) => { - let _ = self.balances.insert(account_id, balance); - if let Some(index) = self.table_state.selected() { - if self.wallet_keys[index].account_id == account_id { - self.set_balance_active(index); + if self.wallet_keys.iter().any(|wallet| wallet.account_id == account_id) { + let _ = self.balances.insert(account_id, balance); + if let Some(index) = self.table_state.selected() { + if self.wallet_keys[index].account_id == account_id { + self.set_balance_active(index); + } } } }, diff --git a/src/components/wallet/address_book.rs b/src/components/wallet/address_book.rs index 41c1d86..dce1d1b 100644 --- a/src/components/wallet/address_book.rs +++ b/src/components/wallet/address_book.rs @@ -12,22 +12,35 @@ use ratatui::{ widgets::{Block, ScrollbarState, Row, Table, TableState}, Frame }; -use subxt::ext::sp_core::crypto::{ByteArray, Ss58Codec, Ss58AddressFormat, AccountId32}; +use subxt::ext::sp_core::crypto::{ + ByteArray, Ss58Codec, Ss58AddressFormat, AccountId32, +}; use tokio::sync::mpsc::UnboundedSender; +use std::sync::mpsc::Sender; use super::{Component, PartialComponent, CurrentTab}; -use crate::types::ActionLevel; +use crate::types::{ActionLevel, SystemAccount}; +use crate::widgets::DotSpinner; use crate::{ action::Action, config::Config, palette::StylePalette, }; +struct BookRecord { + name: String, + address: String, + account_id: [u8; 32], + seed: String, +} + pub struct AddressBook { is_active: bool, action_tx: Option>, + network_tx: Option>, address_book_file: PathBuf, - address_book: Vec<(String, String, AccountId32, String)>, + address_book: Vec, + balances: std::collections::HashMap<[u8; 32], SystemAccount>, scroll_state: ScrollbarState, table_state: TableState, palette: StylePalette, @@ -44,8 +57,10 @@ impl AddressBook { Self { is_active: false, action_tx: None, + network_tx: None, address_book_file: Default::default(), - address_book: Vec::new(), + address_book: Default::default(), + balances: Default::default(), scroll_state: ScrollbarState::new(0), table_state: TableState::new(), palette: StylePalette::default(), @@ -55,7 +70,13 @@ impl AddressBook { fn save_to_file(&mut self) { let mut file = File::create(&self.address_book_file).unwrap(); for wallet in self.address_book.iter() { - writeln!(file, "{}:0x{}", wallet.0, &wallet.3).unwrap(); + writeln!(file, "{}:0x{}", wallet.name, &wallet.seed).unwrap(); + } + } + + fn send_balance_request(&mut self, account_id: [u8; 32], remove: bool) { + if let Some(action_tx) = &self.network_tx { + let _ = action_tx.send(Action::BalanceRequest(account_id, remove)); } } @@ -70,17 +91,22 @@ impl AddressBook { let (name, seed) = line.split_at(line_split_at); let seed_str = &seed[3..]; - let seed: [u8; 32] = hex::decode(seed_str) + let account_id: [u8; 32] = hex::decode(seed_str) .expect("stored seed is valid hex string; qed") .as_slice() .try_into() .expect("stored seed is valid length; qed"); - let account_id = AccountId32::from(seed); - let address = AccountId32::from(seed.clone()) + let address = AccountId32::from(account_id) .to_ss58check_with_version(Ss58AddressFormat::custom(1996)); - self.address_book.push((name.to_string(), address, account_id, seed_str.to_string())); + self.address_book.push(BookRecord { + name: name.to_string(), + address, + account_id, + seed: seed_str.to_string(), + }); + self.send_balance_request(account_id, false); } if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::WalletLog( @@ -114,10 +140,16 @@ impl AddressBook { .as_slice() .try_into() .expect("stored seed is valid length; qed"); - let chad_account_id = AccountId32::from(chad_account_id); - let address = AccountId32::from(chad_account_id.clone()) + let address = AccountId32::from(chad_account_id) .to_ss58check_with_version(Ss58AddressFormat::custom(1996)); - self.address_book.push((chad_info.0.to_string(), address, chad_account_id, chad_info.1.to_string())); + + self.address_book.push(BookRecord { + name: chad_info.0.to_string(), + address, + account_id: chad_account_id, + seed: chad_info.1.to_string(), + }); + self.send_balance_request(chad_account_id, false); }); if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::WalletLog( @@ -133,14 +165,14 @@ impl AddressBook { fn rename_record(&mut self, new_name: String) { if let Some(index) = self.table_state.selected() { - let old_name = self.address_book[index].0.clone(); + let old_name = self.address_book[index].name.clone(); if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::WalletLog( format!("record renamed from {} to {}", &old_name, &new_name), ActionLevel::Info, )); } - self.address_book[index].0 = new_name; + self.address_book[index].name = new_name; self.save_to_file(); } } @@ -165,10 +197,19 @@ impl AddressBook { } let seed_vec = account_id.to_raw_vec(); + let mut account_id = [0u8; 32]; + account_id.copy_from_slice(&seed_vec); let seed_str = hex::encode(seed_vec); - self.address_book.push((name, address, account_id, seed_str)); + + self.address_book.push(BookRecord { + name, + address, + account_id, + seed: seed_str, + }); self.save_to_file(); self.last_row(); + self.send_balance_request(account_id, false); }, Err(_) => if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::WalletLog( @@ -184,7 +225,7 @@ impl AddressBook { if let Some(index) = self.table_state.selected() { if let Some(action_tx) = &self.action_tx { let _ = action_tx.send(Action::RenameAddressBookRecord( - self.address_book[index].0.clone() + self.address_book[index].name.clone() )); } } @@ -264,6 +305,16 @@ impl AddressBook { self.table_state.select(Some(i)); self.scroll_state = self.scroll_state.position(i); } + + fn prepare_u128(&self, maybe_value: Option, ticker: Option<&str>, after: usize) -> String { + match maybe_value { + Some(value) => { + let value = value as f64 / 10f64.powi(18); + format!("{:.after$}{}", value, ticker.unwrap_or_default()) + }, + None => DotSpinner::default().to_string(), + } + } } impl PartialComponent for AddressBook { @@ -276,6 +327,15 @@ impl PartialComponent for AddressBook { } impl Component for AddressBook { + fn register_network_handler(&mut self, tx: Sender) -> Result<()> { + self.network_tx = Some(tx); + Ok(()) + } + fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { + self.action_tx = Some(tx); + Ok(()) + } + fn register_config_handler(&mut self, config: Config) -> Result<()> { if let Some(style) = config.styles.get(&crate::app::Mode::Wallet) { self.palette.with_normal_style(style.get("normal_style").copied()); @@ -295,17 +355,17 @@ impl Component for AddressBook { Ok(()) } - fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { - self.action_tx = Some(tx); - Ok(()) - } - fn update(&mut self, action: Action) -> Result> { match action { Action::UpdateAddressBookRecord(new_name) => self.rename_record(new_name), Action::NewAddressBookRecord(name, address) => self.add_new_record(name, address), + Action::BalanceResponse(account_id, balance) => { + if self.address_book.iter().any(|record| record.account_id == account_id) { + let _ = self.balances.insert(account_id, balance); + } + }, _ => {} }; Ok(None) @@ -334,15 +394,24 @@ impl Component for AddressBook { let table = Table::new( self.address_book .iter() - .map(|info| Row::new(vec![ - Cell::from(Text::from(info.0.clone()).alignment(Alignment::Left)), - Cell::from(Text::from(info.1.clone()).alignment(Alignment::Center)), - Cell::from(Text::from("31 CSPR".to_string()).alignment(Alignment::Right)), - ])), + .map(|info| { + let balance = self.balances + .get(&info.account_id) + .map(|inner_balance| { + inner_balance.free + .saturating_add(inner_balance.reserved) + .saturating_add(inner_balance.frozen) + }); + Row::new(vec![ + Cell::from(Text::from(info.name.clone()).alignment(Alignment::Left)), + Cell::from(Text::from(info.address.clone()).alignment(Alignment::Center)), + Cell::from(Text::from(self.prepare_u128(balance, Some(" CSPR"), 2)).alignment(Alignment::Right)), + ]) + }), [ Constraint::Min(5), Constraint::Max(51), - Constraint::Min(10), + Constraint::Min(11), ], ) .style(self.palette.create_basic_style(false))