diff --git a/core/src/core.rs b/core/src/core.rs index 62379dc..21c8481 100644 --- a/core/src/core.rs +++ b/core/src/core.rs @@ -48,7 +48,7 @@ pub struct Core { pub device: Device, pub market: Option, - pub servers : Arc>, + pub servers: Arc>, pub debug: bool, } @@ -180,7 +180,7 @@ impl Core { device: Device::default(), market: None, - servers : parse_default_servers().clone(), + servers: parse_default_servers().clone(), debug: false, }; @@ -744,22 +744,24 @@ impl Core { } CoreWallet::AccountDeactivation { ids: _ } => {} CoreWallet::AccountActivation { ids: _ } => {} - CoreWallet::AccountCreate { account_descriptor } => { - let account = Account::from(account_descriptor); - self.account_collection - .as_mut() - .expect("account collection") - .push_unchecked(account.clone()); - let device = self.device().clone(); - self.get_mut::() - .select(Some(account.clone()), device); - self.select::(); - - let wallet = self.wallet().clone(); - spawn(async move { - wallet.accounts_activate(Some(vec![account.id()])).await?; - Ok(()) - }); + CoreWallet::AccountCreate { + account_descriptor: _, + } => { + // let account = Account::from(account_descriptor); + // self.account_collection + // .as_mut() + // .expect("account collection") + // .push_unchecked(account.clone()); + // let device = self.device().clone(); + // self.get_mut::() + // .select(Some(account.clone()), device); + // // self.select::(); + + // let wallet = self.wallet().clone(); + // spawn(async move { + // wallet.accounts_activate(Some(vec![account.id()])).await?; + // Ok(()) + // }); } CoreWallet::AccountUpdate { account_descriptor } => { let account_id = account_descriptor.account_id(); @@ -968,6 +970,27 @@ impl Core { Ok(()) } + pub fn handle_account_creation(&mut self, account_descriptor: AccountDescriptor) -> Account { + let account = Account::from(account_descriptor); + self.account_collection + .as_mut() + .expect("account collection") + .push_unchecked(account.clone()); + let device = self.device().clone(); + self.get_mut::() + .select(Some(account.clone()), device); + // self.select::(); + + let account_id = account.id(); + let wallet = self.wallet().clone(); + spawn(async move { + wallet.accounts_activate(Some(vec![account_id])).await?; + Ok(()) + }); + + account + } + fn handle_keyboard_events( &mut self, key: Key, @@ -1028,13 +1051,8 @@ impl Core { let runtime = self.runtime.clone(); spawn(async move { let server_list = load_servers().await?; - runtime - .send(Events::ServerList { - server_list, - }) - .await?; + runtime.send(Events::ServerList { server_list }).await?; Ok(()) }); } - } diff --git a/core/src/egui/mnemonic.rs b/core/src/egui/mnemonic.rs index 2c68fff..28b5b9c 100644 --- a/core/src/egui/mnemonic.rs +++ b/core/src/egui/mnemonic.rs @@ -29,13 +29,24 @@ impl<'render> MnemonicPresenter<'render> { initiate a private key recovery." } - pub fn render(&mut self, ui: &mut Ui) { + pub fn warning(&self) -> &'static str { + "This wallet will never ask you for this mnemonic phrase unless you manually \ + initiate a private key recovery." + } + + pub fn render(&mut self, ui: &mut Ui, caption: Option>) { ui.vertical_centered(|ui| { ui.label( RichText::new("Never share your mnemonic with anyone!") .color(theme_color().alert_color), ); - ui.separator(); + // ui.separator(); + ui.label(" "); + + if let Some(caption) = caption { + ui.label(caption.into()); + } + ui.label(" "); }); diff --git a/core/src/egui/theme/color.rs b/core/src/egui/theme/color.rs index dbbd12f..bc4d82a 100644 --- a/core/src/egui/theme/color.rs +++ b/core/src/egui/theme/color.rs @@ -100,7 +100,7 @@ impl ThemeColor { qr_background: Color32::from_rgba(0, 0, 0, 0), qr_foreground: Color32::WHITE, selection_background_color: Color32::from_rgb(40, 153, 132), - selection_text_color: Color32::from_rgb(220,220,220), + selection_text_color: Color32::from_rgb(220, 220, 220), progress_color: Color32::from_rgb(71, 105, 97), transaction_incoming: Color32::from_rgb(162, 245, 187), @@ -168,7 +168,7 @@ impl ThemeColor { qr_background: Color32::from_rgba(255, 255, 255, 0), qr_foreground: Color32::BLACK, selection_background_color: Color32::from_rgb(165, 201, 197), - selection_text_color: Color32::from_rgb(20,20,20), + selection_text_color: Color32::from_rgb(20, 20, 20), progress_color: Color32::from_rgb(165, 201, 197), transaction_incoming: Color32::from_rgb(15, 77, 35), diff --git a/core/src/events.rs b/core/src/events.rs index 66f691c..f5b2cd5 100644 --- a/core/src/events.rs +++ b/core/src/events.rs @@ -18,7 +18,7 @@ pub enum Events { }, Error(Box), ServerList { - server_list : Arc>, + server_list: Arc>, }, WalletList { wallet_list: Arc>, diff --git a/core/src/imports.rs b/core/src/imports.rs index 943742e..1ee7750 100644 --- a/core/src/imports.rs +++ b/core/src/imports.rs @@ -74,7 +74,7 @@ pub use crate::primitives::{ }; pub use crate::result::Result; pub use crate::runtime::{runtime, spawn, spawn_with_result, Payload, Runtime, Service}; -pub use crate::servers::{Server,load_servers}; +pub use crate::servers::{load_servers, Server}; pub use crate::settings::{ KaspadNodeKind, NetworkInterfaceConfig, NetworkInterfaceKind, NodeSettings, RpcConfig, Settings, UserInterfaceSettings, diff --git a/core/src/lib.rs b/core/src/lib.rs index 0c8589d..987d1ff 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -23,9 +23,9 @@ pub mod notifications; pub mod primitives; pub mod result; pub mod runtime; +pub mod servers; pub mod settings; pub mod state; pub mod status; -pub mod servers; pub mod sync; pub mod utils; diff --git a/core/src/modules/account_create.rs b/core/src/modules/account_create.rs index b66a285..c164a3d 100644 --- a/core/src/modules/account_create.rs +++ b/core/src/modules/account_create.rs @@ -368,15 +368,36 @@ impl ModuleT for AccountCreate { if let Some(result) = account_create_result.take() { match result { - Ok(_descriptor) => { + Ok(account_descriptor) => { println!("Account created successfully"); // let account = Account::from(descriptor); // core.account_collection.as_mut().expect("account collection").push_unchecked(account.clone()); // core.get_mut::().select(Some(account)); // core.select::(); + + + // let account = Account::from(account_descriptor); + // core.account_collection + // .as_mut() + // .expect("account collection") + // .push_unchecked(account.clone()); + // let device = core.device().clone(); + // core.get_mut::() + // .select(Some(account.clone()), device); + // // self.select::(); + + // let wallet = core.wallet().clone(); + // spawn(async move { + // wallet.accounts_activate(Some(vec![account.id()])).await?; + // Ok(()) + // }); + + core.handle_account_creation(account_descriptor); + // - RESET STATE self.state = State::Start; + } Err(err) => { println!("Account creation error: {}", err); diff --git a/core/src/modules/account_manager/mod.rs b/core/src/modules/account_manager/mod.rs index 80c28bd..27a5235 100644 --- a/core/src/modules/account_manager/mod.rs +++ b/core/src/modules/account_manager/mod.rs @@ -293,6 +293,10 @@ impl AccountManager { Panel::new(self) .with_body(|_this, ui| { ui.label("Please create an account"); + ui.label(""); + if ui.large_button("Create Account").clicked() { + core.select::(); + } }).render(ui); } else if account_collection.len() == 1 { self.select(Some(account_collection.first().unwrap().clone()), core.device().clone()); diff --git a/core/src/modules/donations.rs b/core/src/modules/donations.rs index 06407e4..95e6edb 100644 --- a/core/src/modules/donations.rs +++ b/core/src/modules/donations.rs @@ -21,7 +21,7 @@ impl Donations { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { let uri = format!("bytes://{}-{}.svg", Self::ADDRESS, theme_color().name); - let qr = render_qrcode(&Self::ADDRESS, 128, 128); + let qr = render_qrcode(Self::ADDRESS, 128, 128); entry.insert((uri, qr.as_bytes().to_vec().into())) }, }; @@ -76,17 +76,17 @@ impl ModuleT for Donations { ui.label(" "); - if ui - .add(Label::new(format!("{} {CLIPBOARD_TEXT}", format_address_string(Self::ADDRESS, Some(12)))).sense(Sense::click())) - .on_hover_ui_at_pointer(|ui|{ - ui.vertical(|ui|{ - ui.label("Click to copy the donation address to clipboard".to_string()); - }); - }) - .clicked() { - ui.output_mut(|o| o.copied_text = Self::ADDRESS.to_owned()); - runtime().notify(UserNotification::info(format!("{CLIPBOARD_TEXT} {}", i18n("Copied to clipboard"))).short()) - } + let response = ui.add(Label::new(format!("{} {CLIPBOARD_TEXT}", format_address_string(Self::ADDRESS, Some(12)))).sense(Sense::click())) + .on_hover_ui_at_pointer(|ui|{ + ui.vertical(|ui|{ + ui.label("Click to copy the donation address to clipboard".to_string()); + }); + }); + + if response.clicked() { + ui.output_mut(|o| o.copied_text = Self::ADDRESS.to_owned()); + runtime().notify(UserNotification::info(format!("{CLIPBOARD_TEXT} {}", i18n("Copied to clipboard"))).short()) + } ui.label(" "); diff --git a/core/src/modules/metrics.rs b/core/src/modules/metrics.rs index 888e4ce..c52fda3 100644 --- a/core/src/modules/metrics.rs +++ b/core/src/modules/metrics.rs @@ -163,16 +163,12 @@ impl ModuleT for Metrics { }); }); - if graph_range_from != core.settings.user_interface.metrics.graph_range_from { - if graph_range_from.abs_diff(graph_range_to) < 15 { - graph_range_to = graph_range_from + 15; - } + if graph_range_from != core.settings.user_interface.metrics.graph_range_from && graph_range_from.abs_diff(graph_range_to) < 15{ + graph_range_to = graph_range_from + 15; } - if graph_range_to != core.settings.user_interface.metrics.graph_range_to { - if graph_range_to.abs_diff(graph_range_from) < 15 { - graph_range_from = graph_range_to - 15; - } + if graph_range_to != core.settings.user_interface.metrics.graph_range_to && graph_range_to.abs_diff(graph_range_from) < 15 { + graph_range_from = graph_range_to - 15; } if graph_range_from.abs_diff(graph_range_to) < 15 { @@ -285,8 +281,8 @@ impl Metrics { let graph_data = { let metrics_data = self.runtime.metrics_service().metrics_data(); let data = metrics_data.get(&metric).unwrap(); - let mut start = range.start.clamp(METRICS_SAMPLES_START, 0).abs() as usize; - let mut end = range.end.clamp(METRICS_SAMPLES_START, 0).abs() as usize; + let mut start = range.start.clamp(METRICS_SAMPLES_START, 0).unsigned_abs(); + let mut end = range.end.clamp(METRICS_SAMPLES_START, 0).unsigned_abs(); if start > data.len() { start = data.len(); } diff --git a/core/src/modules/testing.rs b/core/src/modules/testing.rs index 2d12f80..caed893 100644 --- a/core/src/modules/testing.rs +++ b/core/src/modules/testing.rs @@ -88,7 +88,7 @@ impl ModuleT for Testing { ui.vertical_centered(|ui|{ ui.label("Hello World"); }); - MnemonicPresenter::new(phrase, &mut self.mnemonic_presenter_context).render(ui); + MnemonicPresenter::new(phrase, &mut self.mnemonic_presenter_context).render(ui, Some("Testing")); ui.vertical_centered(|ui|{ ui.label("Goodbye World"); }); diff --git a/core/src/modules/wallet_create.rs b/core/src/modules/wallet_create.rs index ae37295..10f86d6 100644 --- a/core/src/modules/wallet_create.rs +++ b/core/src/modules/wallet_create.rs @@ -31,8 +31,8 @@ pub enum State { CreateWalletConfirm, CreateWallet, WalletError(Arc), - PresentMnemonic(Arc), - ConfirmMnemonic(Arc), + PresentMnemonic(String), + ConfirmMnemonic(String), Finish, } @@ -710,10 +710,9 @@ impl ModuleT for WalletCreate { .render(ui); let args = self.context.clone(); - let wallet_create_result = Payload::,AccountDescriptor)>>::new("wallet_create_result"); + let wallet_create_result = Payload::>::new("wallet_create_result"); if !wallet_create_result.is_pending() { - // TODO CREATE WALLET ! let wallet = self.runtime.wallet().clone(); spawn_with_result(&wallet_create_result, async move { @@ -735,7 +734,6 @@ impl ModuleT for WalletCreate { args.wallet_filename.is_not_empty().then_some(args.wallet_filename), EncryptionKind::XChaCha20Poly1305, args.enable_phishing_hint.then_some(args.phishing_hint.into()), - // wallet_secret.clone(), false ); @@ -743,16 +741,10 @@ impl ModuleT for WalletCreate { let mnemonic = Mnemonic::random(args.word_count, Language::default())?; let mnemonic_phrase_string = mnemonic.phrase_string(); - // let account_kind = AccountKind::Bip32; - let prv_key_data_args = PrvKeyDataCreateArgs::new( None, payment_secret.clone(), mnemonic_phrase_string.clone(), - // mnemonic.phrase_string(), - //payment_secret.clone(), - // - TODO - // WordCount::Words12.into(), ); let prv_key_data_id = wallet.clone().prv_key_data_create(wallet_secret.clone(), prv_key_data_args).await?; @@ -762,33 +754,27 @@ impl ModuleT for WalletCreate { payment_secret.clone(), args.account_name.is_not_empty().then_some(args.account_name), None, - // account_kind, - // wallet_secret.clone(), - // payment_secret.clone(), ); let account_descriptor = wallet.clone().accounts_create(wallet_secret.clone(), account_create_args).await?; - + wallet.clone().flush(wallet_secret).await?; - // let WalletCreateResponse { mnemonic, wallet_descriptor: _, account_descriptor, storage_descriptor: _ } = - // wallet.wallet_create(wallet_secret, wallet_args, prv_key_data_args, account_args).await?; - Ok((Arc::new(mnemonic_phrase_string), account_descriptor)) + Ok((mnemonic_phrase_string, account_descriptor)) }); } if let Some(result) = wallet_create_result.take() { match result { - Ok((mnemonic,account)) => { + Ok((mnemonic,account_descriptor)) => { self.context.zeroize(); - - println!("Wallet created successfully"); + let account = core.handle_account_creation(account_descriptor); self.state = State::PresentMnemonic(mnemonic); let device = core.device().clone(); - core.get_mut::().select(Some(account.into()), device); + core.get_mut::().select(Some(account), device); } Err(err) => { - println!("Wallet creation error: {}", err); + log_error!("Wallet creation error: {}", err); self.state = State::WalletError(Arc::new(err)); } } @@ -815,31 +801,39 @@ impl ModuleT for WalletCreate { .render(ui); } - State::PresentMnemonic(mnemonic) => { - let phrase = (*mnemonic).clone(); + State::PresentMnemonic(mut mnemonic) => { + + let mut finish = false; Panel::new(self) .with_caption("Private Key Mnemonic") .with_body(|this,ui| { - let mut mnemonic_presenter = MnemonicPresenter::new(phrase.as_str(), &mut this.context.mnemonic_presenter_context); - - ui.label(RichText::new(i18n(mnemonic_presenter.notice())).size(14.)); - ui.label(" "); - ui.label(RichText::new("Never share your mnemonic with anyone!").color(Color32::LIGHT_RED)); - ui.label(" "); - ui.label("Your default wallet private key mnemonic is:"); - ui.label(" "); + let mut mnemonic_presenter = MnemonicPresenter::new(mnemonic.as_str(), &mut this.context.mnemonic_presenter_context); - mnemonic_presenter.render(ui); + ui.horizontal_wrapped(|ui| { + ui.label(RichText::new(i18n(mnemonic_presenter.notice())).size(14.)); + ui.label(RichText::new(i18n(mnemonic_presenter.warning())).size(14.).color(theme_color().warning_color)); + }); + ui.label(""); + ui.label(RichText::new("Never share your mnemonic with anyone!").color(Color32::LIGHT_RED)); + ui.label(""); + mnemonic_presenter.render(ui, Some("Your default wallet private key mnemonic is:")); + ui.label(""); }) - .with_footer(|this,ui| { - if ui.add_sized(editor_size, egui::Button::new("Continue")).clicked() { - this.state = State::ConfirmMnemonic(mnemonic); + .with_footer(|_this,ui| { + if ui.large_button_enabled(true, "Continue").clicked() { + finish = true; } }) .render(ui); + + if finish { + // this.state = State::ConfirmMnemonic(mnemonic); + mnemonic.zeroize(); + self.state = State::Finish; + } } @@ -852,6 +846,9 @@ impl ModuleT for WalletCreate { .with_header(|_this,ui| { ui.label("Please validate your mnemonic"); }) + .with_body(|_this,_ui| { + // TODO + }) .with_footer(move |this,ui| { if ui.add_sized(editor_size, egui::Button::new("Continue")).clicked() { this.state = State::Finish; diff --git a/core/src/runtime/services/update_monitor.rs b/core/src/runtime/services/update_monitor.rs index 5b99fd0..5e1d8b8 100644 --- a/core/src/runtime/services/update_monitor.rs +++ b/core/src/runtime/services/update_monitor.rs @@ -59,7 +59,7 @@ impl Service for UpdateMonitorService { if !self.is_enabled.load(Ordering::Relaxed) { continue; } - + let _ = check_version().await; }, msg = this.as_ref().service_events.receiver.recv().fuse() => { diff --git a/core/src/servers.rs b/core/src/servers.rs index db340bb..9755ccb 100644 --- a/core/src/servers.rs +++ b/core/src/servers.rs @@ -2,24 +2,24 @@ use crate::imports::*; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Server { - pub name : Option, - pub location : Option, - pub protocol : String, - pub network : Vec, - pub port : Option, - pub address : String, + pub name: Option, + pub location: Option, + pub protocol: String, + pub network: Vec, + pub port: Option, + pub address: String, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ServerConfig { - server : Vec, + server: Vec, } -fn try_parse_servers(toml : &str) -> Result>> { +fn try_parse_servers(toml: &str) -> Result>> { Ok(toml::from_str::(toml)?.server.into()) } -fn parse_servers(toml : &str) -> Arc> { +fn parse_servers(toml: &str) -> Arc> { match try_parse_servers(toml) { Ok(servers) => servers, Err(e) => { @@ -30,17 +30,15 @@ fn parse_servers(toml : &str) -> Arc> { } else { log_error!("Error parsing Servers.toml: {}", e); vec![].into() - } - } + } + } } } } pub fn parse_default_servers() -> &'static Arc> { static EMBEDDED_SERVERS: OnceLock>> = OnceLock::new(); - EMBEDDED_SERVERS.get_or_init(|| { - parse_servers(include_str!("../../Servers.toml")) - }) + EMBEDDED_SERVERS.get_or_init(|| parse_servers(include_str!("../../Servers.toml"))) } pub async fn load_servers() -> Result>> { diff --git a/core/src/settings.rs b/core/src/settings.rs index 67015be..60c8bc1 100644 --- a/core/src/settings.rs +++ b/core/src/settings.rs @@ -171,8 +171,6 @@ impl std::fmt::Display for NetworkInterfaceConfig { } } - - #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum NodeConnectionConfigKind { diff --git a/resources/i18n/i18n.json b/resources/i18n/i18n.json index d57abf6..46089e9 100644 --- a/resources/i18n/i18n.json +++ b/resources/i18n/i18n.json @@ -19,8 +19,8 @@ "sv": "Swedish", "fi": "Finnish", "es": "EspaƱol", - "lt": "Lithuanian", "uk": "Ukrainian", + "lt": "Lithuanian", "af": "Afrikaans", "et": "Esti", "en": "English", @@ -62,22 +62,23 @@ "nl": {}, "vi": {}, "fil": {}, + "lt": {}, "pa": {}, "fa": {}, "sv": {}, "fi": {}, "es": {}, "uk": {}, - "lt": {}, "af": {}, "et": {}, "en": { "Very weak": "Very weak", - "Activate custom daemon arguments": "Activate custom daemon arguments", + "Address:": "Address:", "Change": "Change", "Mainnet (Main Kaspa network)": "Mainnet (Main Kaspa network)", "Network Tx/s": "Network Tx/s", "Network Rx/s": "Network Rx/s", + "Your mnemonic phrase allows your to re-create your private key. The person who has access to this mnemonic will have full control of the Kaspa stored in it. Keep your mnemonic safe. Write it down and store it in a safe, preferably in a fire-resistant location. Do not store your mnemonic on this computer or a mobile device. This wallet will never ask you for this mnemonic phrase unless you manually initiate a private key recovery.": "Your mnemonic phrase allows your to re-create your private key. The person who has access to this mnemonic will have full control of the Kaspa stored in it. Keep your mnemonic safe. Write it down and store it in a safe, preferably in a fire-resistant location. Do not store your mnemonic on this computer or a mobile device. This wallet will never ask you for this mnemonic phrase unless you manually initiate a private key recovery.", "Market": "Market", "Submitted Blocks": "Submitted Blocks", "Credits": "Credits", @@ -95,7 +96,6 @@ "Show Grid": "Show Grid", "None": "None", "Enables custom arguments for the Rusty Kaspa daemon": "Enables custom arguments for the Rusty Kaspa daemon", - "Enable screen capture": "Enable screen capture", "Type": "Type", "Memory": "Memory", "Blocks": "Blocks", @@ -165,10 +165,10 @@ "Good": "Good", "Secret is too weak": "Secret is too weak", "DAA": "DAA", - "Network": "Network", + "Signature Type": "Signature Type", "Time Offset:": "Time Offset:", "Net Rx/s": "Net Rx/s", - "Signature Type": "Signature Type", + "Network": "Network", "gRPC Tx": "gRPC Tx", "Dependencies": "Dependencies", "Active p2p Peers": "Active p2p Peers", @@ -205,6 +205,7 @@ "Net Tx/s": "Net Tx/s", "Storage Read": "Storage Read", "Network Peers": "Network Peers", + "gRPC Tx/s": "gRPC Tx/s", "wRPC JSON Rx/s": "wRPC JSON Rx/s", "Screen Capture": "Screen Capture", "gRPC User Rx/s": "gRPC User Rx/s", @@ -226,9 +227,11 @@ "wRPC Borsh Tx": "wRPC Borsh Tx", "Mempool": "Mempool", "wRPC Borsh Rx": "wRPC Borsh Rx", + "Enable screen capture": "Enable screen capture", "Protocol:": "Protocol:", "Transactions": "Transactions", "Allow Custom Rusty Kaspa Daemon Arguments": "Allow Custom Rusty Kaspa Daemon Arguments", + "Activate custom daemon arguments": "Activate custom daemon arguments", "gRPC User Tx/s": "gRPC User Tx/s", "wRPC JSON Tx/s": "wRPC JSON Tx/s", "Virt Parents": "Virt Parents", @@ -259,7 +262,6 @@ "Key Perf.": "Key Perf.", "Processed Dependencies": "Processed Dependencies", "Bandwidth": "Bandwidth", - "gRPC Tx/s": "gRPC Tx/s", "Total Rx": "Total Rx", "Rust Wallet SDK": "Rust Wallet SDK", "Enables features currently in development": "Enables features currently in development", @@ -278,8 +280,7 @@ "Stor Read": "Stor Read", "Database Blocks": "Database Blocks", "Past Median Time": "Past Median Time", - "Headers": "Headers", - "Address:": "Address:" + "Headers": "Headers" }, "el": {}, "it": {},