From 996134514745ed22656e70248f1010d84a33713f Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 5 Dec 2024 00:26:28 +0200 Subject: [PATCH 1/8] work --- src/backend_task/core/mod.rs | 22 +++- src/ui/identities/identities_screen.rs | 9 ++ src/ui/identities/mod.rs | 1 + .../update_identity_payout_address.rs | 108 ++++++++++++++++++ src/ui/mod.rs | 17 +++ 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 src/ui/identities/update_identity_payout_address.rs diff --git a/src/backend_task/core/mod.rs b/src/backend_task/core/mod.rs index faa3c1e51..42476b11d 100644 --- a/src/backend_task/core/mod.rs +++ b/src/backend_task/core/mod.rs @@ -5,10 +5,13 @@ use crate::backend_task::BackendTaskSuccessResult; use crate::config::Config; use crate::context::AppContext; use crate::model::wallet::Wallet; -use dash_sdk::dashcore_rpc::RpcApi; +use dash_sdk::dashcore_rpc::{dashcore, RpcApi}; use dash_sdk::dashcore_rpc::{Auth, Client}; use dash_sdk::dpp::dashcore::{Address, ChainLock, Network, OutPoint, Transaction, TxOut}; use std::sync::{Arc, RwLock}; +use dash_sdk::dashcore_rpc::dashcore::address::Payload; +use dash_sdk::dashcore_rpc::dashcore::hashes::{hash160, Hash}; +use dash_sdk::dashcore_rpc::dashcore::PubkeyHash; #[derive(Debug, Clone)] pub(crate) enum CoreTask { @@ -16,6 +19,7 @@ pub(crate) enum CoreTask { GetBestChainLocks, RefreshWalletInfo(Arc>), StartDashQT(Network, Option, bool), + ProRegUpdateTx(String, Address, Address), } impl PartialEq for CoreTask { fn eq(&self, other: &Self) -> bool { @@ -24,6 +28,7 @@ impl PartialEq for CoreTask { (CoreTask::GetBestChainLocks, CoreTask::GetBestChainLocks) => true, (CoreTask::RefreshWalletInfo(_), CoreTask::RefreshWalletInfo(_)) => true, (CoreTask::StartDashQT(_, _, _), CoreTask::StartDashQT(_, _, _)) => true, + (CoreTask::ProRegUpdateTx(_, _, _), CoreTask::ProRegUpdateTx(_, _, _)) => true, _ => false, } } @@ -34,10 +39,12 @@ pub(crate) enum CoreItem { ReceivedAvailableUTXOTransaction(Transaction, Vec<(OutPoint, TxOut, Address)>), ChainLock(ChainLock, Network), ChainLocks(Option, Option), // Mainnet, Testnet + ProRegUpdateTx(String), } impl AppContext { pub async fn run_core_task(&self, task: CoreTask) -> Result { + match task { CoreTask::GetBestChainLock => self .core_client @@ -75,7 +82,7 @@ impl AppContext { mainnet_config.core_rpc_password.to_string(), ), ) - .map_err(|_| "Failed to create mainnet client".to_string())?; + .map_err(|_| "Failed to create mainnet client".to_string())?; mainnet_client.get_best_chain_lock().map_err(|e| { format!( "Failed to get best chain lock for mainnet: {}", @@ -99,7 +106,7 @@ impl AppContext { testnet_config.core_rpc_password.to_string(), ), ) - .map_err(|_| "Failed to create testnet client".to_string())?; + .map_err(|_| "Failed to create testnet client".to_string())?; testnet_client.get_best_chain_lock().map_err(|e| { format!( "Failed to get best chain lock for testnet: {}", @@ -135,6 +142,15 @@ impl AppContext { .start_dash_qt(network, custom_dash_qt, overwrite_dash_conf) .map_err(|e| e.to_string()) .map(|_| BackendTaskSuccessResult::None), + CoreTask::ProRegUpdateTx(pro_tx_hash, voting_address, payout_address) => self + .core_client + .get_protx_update_registrar(pro_tx_hash.as_str(), "", payout_address, voting_address, None) + .map(|pro_tx_hash| { + BackendTaskSuccessResult::CoreItem(CoreItem::ProRegUpdateTx( + pro_tx_hash.to_string(), + )) + }) + .map_err(|e| e.to_string()) } } } diff --git a/src/ui/identities/identities_screen.rs b/src/ui/identities/identities_screen.rs index a81c962be..9add26d35 100644 --- a/src/ui/identities/identities_screen.rs +++ b/src/ui/identities/identities_screen.rs @@ -32,6 +32,7 @@ use egui_extras::{Column, TableBuilder}; use std::collections::HashMap; use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; +use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; pub struct IdentitiesScreen { pub identities: Arc>>, @@ -454,6 +455,14 @@ impl IdentitiesScreen { ), )); } + if ui.button("Update Payout Address").clicked() { + action = AppAction::AddScreen(Screen::UpdatePayoutAddressScreen( + UpdateIdentityPayoutScreen::new( + qualified_identity.clone(), + &self.app_context, + ), + )); + } }); row.col(|ui| { ui.horizontal(|ui| { diff --git a/src/ui/identities/mod.rs b/src/ui/identities/mod.rs index dabe88c8c..84063c0e5 100644 --- a/src/ui/identities/mod.rs +++ b/src/ui/identities/mod.rs @@ -6,3 +6,4 @@ pub mod keys; pub mod register_dpns_name_screen; pub mod top_up_identity_screen; pub mod withdraw_from_identity_screen; +pub mod update_identity_payout_address; diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs new file mode 100644 index 000000000..7daa0c8ee --- /dev/null +++ b/src/ui/identities/update_identity_payout_address.rs @@ -0,0 +1,108 @@ +use crate::app::AppAction; +use crate::context::AppContext; +use crate::model::qualified_identity::{IdentityType, QualifiedIdentity}; +use crate::ui::components::top_panel::add_top_panel; +use crate::ui::{MessageType, Screen, ScreenLike}; +use dash_sdk::dpp::identity::accessors::IdentityGettersV0; +use eframe::egui::Context; +use std::sync::Arc; +use dash_sdk::dashcore_rpc::dashcore::PrivateKey; +use dash_sdk::dpp::identity::{KeyType, Purpose, SecurityLevel}; +use egui::TextBuffer; + +pub struct UpdateIdentityPayoutScreen { + pub app_context: Arc, + pub identity: QualifiedIdentity, + payout_address_private_key_input: String, + error_message: Option, +} + +impl UpdateIdentityPayoutScreen { + pub fn new(identity: QualifiedIdentity, app_context: &Arc) -> Self { + Self { + app_context: app_context.clone(), + identity, + payout_address_private_key_input: String::new(), + error_message: None, + } + } + + fn verify_key_input( + untrimmed_private_key: String, + type_key: &str, + ) -> Result, String> { + let private_key = untrimmed_private_key.trim().to_string(); + match private_key.len() { + 64 => { + // hex + match hex::decode(private_key.as_str()) { + Ok(decoded) => Ok(Some(decoded.try_into().unwrap())), + Err(_) => Err(format!( + "{} key is the size of a hex key but isn't hex", + type_key + )), + } + } + 51 | 52 => { + // wif + match PrivateKey::from_wif(private_key.as_str()) { + Ok(key) => Ok(Some(key.inner.secret_bytes())), + Err(_) => Err(format!( + "{} key is the length of a WIF key but is invalid", + type_key + )), + } + } + 0 => Ok(None), + _ => Err(format!("{} key is of incorrect size", type_key)), + } + } +} + +impl ScreenLike for UpdateIdentityPayoutScreen { + fn display_message(&mut self, message: &str, message_type: MessageType) { + + } + + /// Renders the UI components for the withdrawal screen + fn ui(&mut self, ctx: &Context) -> AppAction { + let mut action = add_top_panel( + ctx, + &self.app_context, + vec![ + ("Identities", AppAction::GoToMainScreen), + ("Update Payout Address", AppAction::None), + ], + vec![], + ); + + egui::CentralPanel::default().show(ctx, |ui| { + if (self.identity.identity_type == IdentityType::User) { + ui.heading("Updating Payout Address for User identities is not allowed.".to_string()); + } + else { + ui.heading("Update Payout Address".to_string()); + } + + //let owner_key = self.identity.identity.get_first_public_key_matching(Purpose::OWNER, SecurityLevel::full_range().into(), KeyType::all_key_types().into(), false); + let payout_address_private_key_input = &mut self.payout_address_private_key_input; + ui.horizontal(|ui| { + ui.label("Payout Address Private Key:"); + ui.text_edit_singleline(payout_address_private_key_input); + }); + + if ui.button("Update Payout Address").clicked() { + match Self::verify_key_input(payout_address_private_key_input.clone(), "test".as_str()) { + Ok(value) => { + println!("Success"); + } + Err(error) => { + eprintln!("Error: {}", error); + } + } + } + }); + + action + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 9a3513a62..eee69bcd4 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -31,6 +31,8 @@ use std::hash::Hash; use std::sync::Arc; use tool_screens::transition_visualizer_screen::TransitionVisualizerScreen; use wallet::add_new_wallet_screen::AddNewWalletScreen; +use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; +use crate::ui::Screen::UpdatePayoutAddressScreen; pub mod components; pub mod document_query_screen; @@ -123,6 +125,7 @@ pub enum ScreenType { AddNewWallet, AddExistingIdentity, TransitionVisualizer, + UpdatePayoutAddress(QualifiedIdentity), WithdrawalScreen(QualifiedIdentity), TransferScreen(QualifiedIdentity), AddKeyScreen(QualifiedIdentity), @@ -179,6 +182,9 @@ impl ScreenType { ScreenType::TransitionVisualizer => { Screen::TransitionVisualizerScreen(TransitionVisualizerScreen::new(app_context)) } + ScreenType::UpdatePayoutAddress(identity) => { + Screen::UpdatePayoutAddressScreen(UpdateIdentityPayoutScreen::new(identity.clone(), app_context)) + } ScreenType::WithdrawalScreen(identity) => { Screen::WithdrawalScreen(WithdrawalScreen::new(identity.clone(), app_context)) } @@ -222,6 +228,7 @@ pub enum Screen { KeyInfoScreen(KeyInfoScreen), KeysScreen(KeysScreen), RegisterDpnsNameScreen(RegisterDpnsNameScreen), + UpdatePayoutAddressScreen(UpdateIdentityPayoutScreen), WithdrawalScreen(WithdrawalScreen), TopUpIdentityScreen(TopUpIdentityScreen), TransferScreen(TransferScreen), @@ -249,6 +256,7 @@ impl Screen { Screen::AddNewIdentityScreen(screen) => screen.app_context = app_context, Screen::RegisterDpnsNameScreen(screen) => screen.app_context = app_context, Screen::AddNewWalletScreen(screen) => screen.app_context = app_context, + Screen::UpdatePayoutAddressScreen(screen) => screen.app_context = app_context, Screen::TransferScreen(screen) => screen.app_context = app_context, Screen::TopUpIdentityScreen(screen) => screen.app_context = app_context, Screen::WalletsBalancesScreen(screen) => screen.app_context = app_context, @@ -333,6 +341,7 @@ impl Screen { Screen::TransferScreen(screen) => ScreenType::TransferScreen(screen.identity.clone()), Screen::WalletsBalancesScreen(_) => ScreenType::WalletsBalances, Screen::WithdrawsStatusScreen(_) => ScreenType::WithdrawsStatus, + Screen::UpdatePayoutAddressScreen(screen) => ScreenType::UpdatePayoutAddress(screen.identity.clone()), Screen::ImportWalletScreen(_) => ScreenType::ImportWallet, Screen::ProofLogScreen(_) => ScreenType::ProofLog, } @@ -361,6 +370,7 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.refresh(), Screen::WalletsBalancesScreen(screen) => screen.refresh(), Screen::ProofLogScreen(screen) => screen.refresh(), + Screen::UpdatePayoutAddressScreen(screen) => screen.refresh(), } } @@ -385,6 +395,7 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.refresh_on_arrival(), Screen::WalletsBalancesScreen(screen) => screen.refresh_on_arrival(), Screen::ProofLogScreen(screen) => screen.refresh_on_arrival(), + Screen::UpdatePayoutAddressScreen(screen) => screen.refresh_on_arrival(), } } @@ -409,6 +420,7 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.ui(ctx), Screen::WalletsBalancesScreen(screen) => screen.ui(ctx), Screen::ProofLogScreen(screen) => screen.ui(ctx), + Screen::UpdatePayoutAddressScreen(screen) => screen.ui(ctx), } } @@ -439,6 +451,7 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.display_message(message, message_type), Screen::WalletsBalancesScreen(screen) => screen.display_message(message, message_type), Screen::ProofLogScreen(screen) => screen.display_message(message, message_type), + Screen::UpdatePayoutAddressScreen(screen) => screen.display_message(message, message_type), } } @@ -501,6 +514,9 @@ impl ScreenLike for Screen { Screen::ProofLogScreen(screen) => { screen.display_task_result(backend_task_success_result) } + Screen::UpdatePayoutAddressScreen(screen) => { + screen.display_task_result(backend_task_success_result.clone()) + } } } @@ -525,6 +541,7 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.pop_on_success(), Screen::WalletsBalancesScreen(screen) => screen.pop_on_success(), Screen::ProofLogScreen(screen) => screen.pop_on_success(), + Screen::UpdatePayoutAddressScreen(screen) => screen.pop_on_success(), } } } From 7b86a8c3955c5e48ec20b5904e62f805539a02b4 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 5 Dec 2024 14:54:03 +0200 Subject: [PATCH 2/8] more work --- .../update_identity_payout_address.rs | 125 ++++++++++++++++-- 1 file changed, 114 insertions(+), 11 deletions(-) diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index 7daa0c8ee..e5a5a9a73 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -5,23 +5,37 @@ use crate::ui::components::top_panel::add_top_panel; use crate::ui::{MessageType, Screen, ScreenLike}; use dash_sdk::dpp::identity::accessors::IdentityGettersV0; use eframe::egui::Context; -use std::sync::Arc; -use dash_sdk::dashcore_rpc::dashcore::PrivateKey; +use std::sync::{Arc, RwLock}; +use std::sync::atomic::Ordering; +use std::time::{SystemTime, UNIX_EPOCH}; +use dash_sdk::dashcore_rpc::dashcore::{Address, PrivateKey}; use dash_sdk::dpp::identity::{KeyType, Purpose, SecurityLevel}; -use egui::TextBuffer; +use egui::{ComboBox, TextBuffer, Ui}; +use tracing_subscriber::fmt::format; +use crate::backend_task::BackendTask; +use crate::backend_task::identity::IdentityTask; +use crate::model::wallet::Wallet; +use crate::ui::identities::add_existing_identity_screen::AddIdentityStatus; pub struct UpdateIdentityPayoutScreen { pub app_context: Arc, pub identity: QualifiedIdentity, + selected_wallet: Option>>, payout_address_private_key_input: String, error_message: Option, + //selected_address: String, + selected_address: Option
, } impl UpdateIdentityPayoutScreen { pub fn new(identity: QualifiedIdentity, app_context: &Arc) -> Self { + let selected_wallet = None; Self { app_context: app_context.clone(), identity, + selected_wallet, + //selected_address: String::default(), + selected_address: None, payout_address_private_key_input: String::new(), error_message: None, } @@ -57,6 +71,86 @@ impl UpdateIdentityPayoutScreen { _ => Err(format!("{} key is of incorrect size", type_key)), } } + + fn render_wallet_selection(&mut self, ui: &mut Ui) { + ui.horizontal(|ui| { + if self.app_context.has_wallet.load(Ordering::Relaxed) { + let wallets = &self.app_context.wallets.read().unwrap(); + let wallet_aliases: Vec = wallets + .values() + .map(|wallet| { + wallet + .read() + .unwrap() + .alias + .clone() + .unwrap_or_else(|| "Unnamed Wallet".to_string()) + }) + .collect(); + + let selected_wallet_alias = self + .selected_wallet + .as_ref() + .and_then(|wallet| wallet.read().ok()?.alias.clone()) + .unwrap_or_else(|| "Select".to_string()); + + // Display the ComboBox for wallet selection + ComboBox::from_label("") + .selected_text(selected_wallet_alias.clone()) + .show_ui(ui, |ui| { + for (idx, wallet) in wallets.values().enumerate() { + let wallet_alias = wallet_aliases[idx].clone(); + + let is_selected = self + .selected_wallet + .as_ref() + .map_or(false, |selected| Arc::ptr_eq(selected, wallet)); + + if ui + .selectable_label(is_selected, wallet_alias.clone()) + .clicked() + { + // Update the selected wallet + self.selected_wallet = Some(wallet.clone()); + } + } + }); + + ui.add_space(20.0); + } else { + ui.label("No wallets available."); + } + }); + } + + fn render_selected_wallet_addresses(&mut self, ctx: &Context, ui: &mut Ui) { + if let Some(selected_wallet) = &self.selected_wallet { + // Acquire a read lock + let wallet = selected_wallet.read().unwrap(); + ui.label("Select an Address:"); + ComboBox::from_label("") + .selected_text( + self.selected_address + .as_ref() // Get a reference to the Option
+ .map(|address| address.to_string()) // Convert Address to String + .unwrap_or_else(|| "".to_string()), // Use default "" if None + ) + .show_ui(ui, |ui| { + for (_, address_info) in &wallet.watched_addresses { + if ui.selectable_value(&mut self.selected_address, Some(address_info.clone().address), address_info.clone().address.to_string()).clicked() { + } + } + }); + if let Some(selected_address) = &self.selected_address { + ui.label(format!("Selected Address: {} with ", selected_address.to_string())); + if let Some(value) = wallet.address_balances.get(&selected_address) { + ui.label(format!("Balance {} DASH", value)); + } else { + ui.label("Balance NOT FOUND DASH".to_string()); + } + } + } + } } impl ScreenLike for UpdateIdentityPayoutScreen { @@ -76,7 +170,7 @@ impl ScreenLike for UpdateIdentityPayoutScreen { vec![], ); - egui::CentralPanel::default().show(ctx, |ui| { + egui::CentralPanel::default().show(ctx, |mut ui| { if (self.identity.identity_type == IdentityType::User) { ui.heading("Updating Payout Address for User identities is not allowed.".to_string()); } @@ -84,23 +178,32 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ui.heading("Update Payout Address".to_string()); } - //let owner_key = self.identity.identity.get_first_public_key_matching(Purpose::OWNER, SecurityLevel::full_range().into(), KeyType::all_key_types().into(), false); - let payout_address_private_key_input = &mut self.payout_address_private_key_input; - ui.horizontal(|ui| { - ui.label("Payout Address Private Key:"); - ui.text_edit_singleline(payout_address_private_key_input); - }); + let loaded_wallet = self.app_context.has_wallet.load(Ordering::Relaxed); + if ( loaded_wallet) { + //println!("Loaded wallet"); + self.render_wallet_selection(&mut ui); + if self.selected_wallet.is_some() { + self.render_selected_wallet_addresses(ctx, &mut ui); + } + } + else { + //print!("No loaded wallet"); + } +/* if ui.button("Update Payout Address").clicked() { match Self::verify_key_input(payout_address_private_key_input.clone(), "test".as_str()) { Ok(value) => { - println!("Success"); + + } Err(error) => { eprintln!("Error: {}", error); } } } + + */ }); action From 0a1bb030c2ae08fd571af86c2eff89e0cf96b97d Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 5 Dec 2024 16:43:09 +0200 Subject: [PATCH 3/8] more work --- src/backend_task/core/mod.rs | 1 - .../update_identity_payout_address.rs | 192 +++++++++--------- 2 files changed, 99 insertions(+), 94 deletions(-) diff --git a/src/backend_task/core/mod.rs b/src/backend_task/core/mod.rs index 42476b11d..2411860b8 100644 --- a/src/backend_task/core/mod.rs +++ b/src/backend_task/core/mod.rs @@ -44,7 +44,6 @@ pub(crate) enum CoreItem { impl AppContext { pub async fn run_core_task(&self, task: CoreTask) -> Result { - match task { CoreTask::GetBestChainLock => self .core_client diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index e5a5a9a73..2448b1c64 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -2,29 +2,25 @@ use crate::app::AppAction; use crate::context::AppContext; use crate::model::qualified_identity::{IdentityType, QualifiedIdentity}; use crate::ui::components::top_panel::add_top_panel; -use crate::ui::{MessageType, Screen, ScreenLike}; +use crate::ui::{MessageType, ScreenLike}; use dash_sdk::dpp::identity::accessors::IdentityGettersV0; use eframe::egui::Context; use std::sync::{Arc, RwLock}; use std::sync::atomic::Ordering; -use std::time::{SystemTime, UNIX_EPOCH}; -use dash_sdk::dashcore_rpc::dashcore::{Address, PrivateKey}; -use dash_sdk::dpp::identity::{KeyType, Purpose, SecurityLevel}; -use egui::{ComboBox, TextBuffer, Ui}; -use tracing_subscriber::fmt::format; +use dash_sdk::dashcore_rpc::dashcore::Address; +use dash_sdk::dpp::platform_value::string_encoding::Encoding; +use egui::{ComboBox, Ui}; use crate::backend_task::BackendTask; -use crate::backend_task::identity::IdentityTask; +use crate::backend_task::core::CoreTask; use crate::model::wallet::Wallet; -use crate::ui::identities::add_existing_identity_screen::AddIdentityStatus; pub struct UpdateIdentityPayoutScreen { pub app_context: Arc, pub identity: QualifiedIdentity, selected_wallet: Option>>, - payout_address_private_key_input: String, + selected_payout_address: Option
, + selected_funding_address: Option
, error_message: Option, - //selected_address: String, - selected_address: Option
, } impl UpdateIdentityPayoutScreen { @@ -34,44 +30,12 @@ impl UpdateIdentityPayoutScreen { app_context: app_context.clone(), identity, selected_wallet, - //selected_address: String::default(), - selected_address: None, - payout_address_private_key_input: String::new(), + selected_payout_address: None, + selected_funding_address: None, error_message: None, } } - fn verify_key_input( - untrimmed_private_key: String, - type_key: &str, - ) -> Result, String> { - let private_key = untrimmed_private_key.trim().to_string(); - match private_key.len() { - 64 => { - // hex - match hex::decode(private_key.as_str()) { - Ok(decoded) => Ok(Some(decoded.try_into().unwrap())), - Err(_) => Err(format!( - "{} key is the size of a hex key but isn't hex", - type_key - )), - } - } - 51 | 52 => { - // wif - match PrivateKey::from_wif(private_key.as_str()) { - Ok(key) => Ok(Some(key.inner.secret_bytes())), - Err(_) => Err(format!( - "{} key is the length of a WIF key but is invalid", - type_key - )), - } - } - 0 => Ok(None), - _ => Err(format!("{} key is of incorrect size", type_key)), - } - } - fn render_wallet_selection(&mut self, ui: &mut Ui) { ui.horizontal(|ui| { if self.app_context.has_wallet.load(Ordering::Relaxed) { @@ -100,12 +64,10 @@ impl UpdateIdentityPayoutScreen { .show_ui(ui, |ui| { for (idx, wallet) in wallets.values().enumerate() { let wallet_alias = wallet_aliases[idx].clone(); - let is_selected = self .selected_wallet .as_ref() .map_or(false, |selected| Arc::ptr_eq(selected, wallet)); - if ui .selectable_label(is_selected, wallet_alias.clone()) .clicked() @@ -123,30 +85,67 @@ impl UpdateIdentityPayoutScreen { }); } - fn render_selected_wallet_addresses(&mut self, ctx: &Context, ui: &mut Ui) { + fn render_selected_wallet_payout_addresses(&mut self, ctx: &Context, ui: &mut Ui) { if let Some(selected_wallet) = &self.selected_wallet { // Acquire a read lock let wallet = selected_wallet.read().unwrap(); - ui.label("Select an Address:"); - ComboBox::from_label("") - .selected_text( - self.selected_address - .as_ref() // Get a reference to the Option
- .map(|address| address.to_string()) // Convert Address to String - .unwrap_or_else(|| "".to_string()), // Use default "" if None - ) - .show_ui(ui, |ui| { - for (_, address_info) in &wallet.watched_addresses { - if ui.selectable_value(&mut self.selected_address, Some(address_info.clone().address), address_info.clone().address.to_string()).clicked() { + ui.add_space(20.0); + ui.heading("Select a Payout Address:"); + ui.add_space(5.0); + ui.push_id("payout_combo_id", |ui| { + ComboBox::from_label("") + .selected_text( + self.selected_payout_address + .as_ref() // Get a reference to the Option
+ .map(|address| address.to_string()) // Convert Address to String + .unwrap_or_else(|| "".to_string()), // Use default "" if None + ) + .show_ui(ui, |ui| { + for (address, _) in &wallet.known_addresses { + if ui.selectable_value(&mut self.selected_payout_address, Some(address.clone()), address.to_string()).clicked() {} } - } - }); - if let Some(selected_address) = &self.selected_address { - ui.label(format!("Selected Address: {} with ", selected_address.to_string())); + }); + }); + ui.add_space(20.0); + if let Some(selected_address) = &self.selected_payout_address { + if let Some(value) = wallet.address_balances.get(&selected_address) { + ui.label(format!("Selected Address has a balance of {} DASH", value)); + } else { + // TODO: Why sometimes balance is not found? + //ui.label("Balance NOT FOUND DASH".to_string()); + } + } + } + } + + fn render_selected_wallet_funding_addresses(&mut self, ctx: &Context, ui: &mut Ui) { + if let Some(selected_wallet) = &self.selected_wallet { + // Acquire a read lock + let wallet = selected_wallet.read().unwrap(); + ui.add_space(20.0); + ui.heading("Select a Funding Address:"); + ui.add_space(5.0); + ui.push_id("funding_combo_id", |ui| { + ComboBox::from_label("") + .selected_text( + self.selected_funding_address + .as_ref() // Get a reference to the Option
+ .map(|address| address.to_string()) // Convert Address to String + .unwrap_or_else(|| "".to_string()), // Use default "" if None + ) + .show_ui(ui, |ui| { + for (address, _) in &wallet.known_addresses { + if ui.selectable_value(&mut self.selected_funding_address, Some(address.clone()), address.to_string()).clicked() {} + } + }); + }); + ui.add_space(20.0); + if let Some(selected_address) = &self.selected_funding_address { if let Some(value) = wallet.address_balances.get(&selected_address) { - ui.label(format!("Balance {} DASH", value)); + ui.label(format!("Selected Address has a balance of {} DASH", value)); } else { - ui.label("Balance NOT FOUND DASH".to_string()); + // TODO: Why sometimes balance is not found? + //ui.label("Balance NOT FOUND DASH".to_string()); } } } @@ -154,8 +153,10 @@ impl UpdateIdentityPayoutScreen { } impl ScreenLike for UpdateIdentityPayoutScreen { - fn display_message(&mut self, message: &str, message_type: MessageType) { - + fn display_message(&mut self, message: &str, _message_type: MessageType) { + if _message_type == MessageType::Error { + self.error_message = Some(message.to_string()); + } } /// Renders the UI components for the withdrawal screen @@ -173,37 +174,42 @@ impl ScreenLike for UpdateIdentityPayoutScreen { egui::CentralPanel::default().show(ctx, |mut ui| { if (self.identity.identity_type == IdentityType::User) { ui.heading("Updating Payout Address for User identities is not allowed.".to_string()); + //return; } - else { - ui.heading("Update Payout Address".to_string()); - } - - let loaded_wallet = self.app_context.has_wallet.load(Ordering::Relaxed); - if ( loaded_wallet) { - //println!("Loaded wallet"); - self.render_wallet_selection(&mut ui); - - if self.selected_wallet.is_some() { - self.render_selected_wallet_addresses(ctx, &mut ui); - } + if (!self.app_context.has_wallet.load(Ordering::Relaxed)) { + ui.heading("Load a Wallet in order to continue.".to_string()); + //return; } - else { - //print!("No loaded wallet"); - } -/* - if ui.button("Update Payout Address").clicked() { - match Self::verify_key_input(payout_address_private_key_input.clone(), "test".as_str()) { - Ok(value) => { - - - } - Err(error) => { - eprintln!("Error: {}", error); + ui.heading("Update Payout Address".to_string()); + ui.add_space(20.0); + + ui.heading("Load Address from wallet".to_string()); + self.render_wallet_selection(&mut ui); + + if self.selected_wallet.is_some() { + self.render_selected_wallet_payout_addresses(ctx, &mut ui); + if self.selected_payout_address.is_some() { + self.render_selected_wallet_funding_addresses(ctx, &mut ui); + if self.selected_funding_address.is_some() { + ui.add_space(20.0); + ui.colored_label(egui::Color32::ORANGE, "The owner key of the Masternode/Evonode must be known to your wallet."); + ui.add_space(20.0); + if ui.button("Update Payout Address").clicked() { + action |= AppAction::BackendTask(BackendTask::CoreTask( + CoreTask::ProRegUpdateTx( + self.identity.identity.id().to_string(Encoding::Hex), + self.selected_payout_address.clone().unwrap(), + self.selected_funding_address.clone().unwrap() + ) + )); + } + if self.error_message.is_some() { + ui.add_space(20.0); + ui.colored_label(egui::Color32::RED, self.error_message.as_ref().unwrap()); + } } } } - - */ }); action From cd231d60fbfa7de33aef869fab1769bb0890a62a Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 5 Dec 2024 16:43:33 +0200 Subject: [PATCH 4/8] fmt --- src/backend_task/core/mod.rs | 20 ++++--- src/ui/identities/identities_screen.rs | 2 +- src/ui/identities/mod.rs | 2 +- .../update_identity_payout_address.rs | 52 +++++++++++++------ src/ui/mod.rs | 18 ++++--- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/backend_task/core/mod.rs b/src/backend_task/core/mod.rs index 2411860b8..5ba48b074 100644 --- a/src/backend_task/core/mod.rs +++ b/src/backend_task/core/mod.rs @@ -5,13 +5,13 @@ use crate::backend_task::BackendTaskSuccessResult; use crate::config::Config; use crate::context::AppContext; use crate::model::wallet::Wallet; +use dash_sdk::dashcore_rpc::dashcore::address::Payload; +use dash_sdk::dashcore_rpc::dashcore::hashes::{hash160, Hash}; +use dash_sdk::dashcore_rpc::dashcore::PubkeyHash; use dash_sdk::dashcore_rpc::{dashcore, RpcApi}; use dash_sdk::dashcore_rpc::{Auth, Client}; use dash_sdk::dpp::dashcore::{Address, ChainLock, Network, OutPoint, Transaction, TxOut}; use std::sync::{Arc, RwLock}; -use dash_sdk::dashcore_rpc::dashcore::address::Payload; -use dash_sdk::dashcore_rpc::dashcore::hashes::{hash160, Hash}; -use dash_sdk::dashcore_rpc::dashcore::PubkeyHash; #[derive(Debug, Clone)] pub(crate) enum CoreTask { @@ -81,7 +81,7 @@ impl AppContext { mainnet_config.core_rpc_password.to_string(), ), ) - .map_err(|_| "Failed to create mainnet client".to_string())?; + .map_err(|_| "Failed to create mainnet client".to_string())?; mainnet_client.get_best_chain_lock().map_err(|e| { format!( "Failed to get best chain lock for mainnet: {}", @@ -105,7 +105,7 @@ impl AppContext { testnet_config.core_rpc_password.to_string(), ), ) - .map_err(|_| "Failed to create testnet client".to_string())?; + .map_err(|_| "Failed to create testnet client".to_string())?; testnet_client.get_best_chain_lock().map_err(|e| { format!( "Failed to get best chain lock for testnet: {}", @@ -143,13 +143,19 @@ impl AppContext { .map(|_| BackendTaskSuccessResult::None), CoreTask::ProRegUpdateTx(pro_tx_hash, voting_address, payout_address) => self .core_client - .get_protx_update_registrar(pro_tx_hash.as_str(), "", payout_address, voting_address, None) + .get_protx_update_registrar( + pro_tx_hash.as_str(), + "", + payout_address, + voting_address, + None, + ) .map(|pro_tx_hash| { BackendTaskSuccessResult::CoreItem(CoreItem::ProRegUpdateTx( pro_tx_hash.to_string(), )) }) - .map_err(|e| e.to_string()) + .map_err(|e| e.to_string()), } } } diff --git a/src/ui/identities/identities_screen.rs b/src/ui/identities/identities_screen.rs index 9add26d35..54cce15ef 100644 --- a/src/ui/identities/identities_screen.rs +++ b/src/ui/identities/identities_screen.rs @@ -16,6 +16,7 @@ use crate::ui::components::top_panel::add_top_panel; use crate::ui::identities::keys::add_key_screen::AddKeyScreen; use crate::ui::identities::keys::key_info_screen::KeyInfoScreen; use crate::ui::identities::top_up_identity_screen::TopUpIdentityScreen; +use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; use crate::ui::transfers::TransferScreen; use crate::ui::{RootScreenType, Screen, ScreenLike, ScreenType}; use dash_sdk::dpp::identity::accessors::IdentityGettersV0; @@ -32,7 +33,6 @@ use egui_extras::{Column, TableBuilder}; use std::collections::HashMap; use std::sync::atomic::Ordering; use std::sync::{Arc, Mutex}; -use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; pub struct IdentitiesScreen { pub identities: Arc>>, diff --git a/src/ui/identities/mod.rs b/src/ui/identities/mod.rs index 84063c0e5..fb9b49413 100644 --- a/src/ui/identities/mod.rs +++ b/src/ui/identities/mod.rs @@ -5,5 +5,5 @@ pub mod identities_screen; pub mod keys; pub mod register_dpns_name_screen; pub mod top_up_identity_screen; -pub mod withdraw_from_identity_screen; pub mod update_identity_payout_address; +pub mod withdraw_from_identity_screen; diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index 2448b1c64..7a9e006b1 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -1,18 +1,18 @@ use crate::app::AppAction; +use crate::backend_task::core::CoreTask; +use crate::backend_task::BackendTask; use crate::context::AppContext; use crate::model::qualified_identity::{IdentityType, QualifiedIdentity}; +use crate::model::wallet::Wallet; use crate::ui::components::top_panel::add_top_panel; use crate::ui::{MessageType, ScreenLike}; -use dash_sdk::dpp::identity::accessors::IdentityGettersV0; -use eframe::egui::Context; -use std::sync::{Arc, RwLock}; -use std::sync::atomic::Ordering; use dash_sdk::dashcore_rpc::dashcore::Address; +use dash_sdk::dpp::identity::accessors::IdentityGettersV0; use dash_sdk::dpp::platform_value::string_encoding::Encoding; +use eframe::egui::Context; use egui::{ComboBox, Ui}; -use crate::backend_task::BackendTask; -use crate::backend_task::core::CoreTask; -use crate::model::wallet::Wallet; +use std::sync::atomic::Ordering; +use std::sync::{Arc, RwLock}; pub struct UpdateIdentityPayoutScreen { pub app_context: Arc, @@ -102,7 +102,14 @@ impl UpdateIdentityPayoutScreen { ) .show_ui(ui, |ui| { for (address, _) in &wallet.known_addresses { - if ui.selectable_value(&mut self.selected_payout_address, Some(address.clone()), address.to_string()).clicked() {} + if ui + .selectable_value( + &mut self.selected_payout_address, + Some(address.clone()), + address.to_string(), + ) + .clicked() + {} } }); }); @@ -135,7 +142,14 @@ impl UpdateIdentityPayoutScreen { ) .show_ui(ui, |ui| { for (address, _) in &wallet.known_addresses { - if ui.selectable_value(&mut self.selected_funding_address, Some(address.clone()), address.to_string()).clicked() {} + if ui + .selectable_value( + &mut self.selected_funding_address, + Some(address.clone()), + address.to_string(), + ) + .clicked() + {} } }); }); @@ -173,7 +187,9 @@ impl ScreenLike for UpdateIdentityPayoutScreen { egui::CentralPanel::default().show(ctx, |mut ui| { if (self.identity.identity_type == IdentityType::User) { - ui.heading("Updating Payout Address for User identities is not allowed.".to_string()); + ui.heading( + "Updating Payout Address for User identities is not allowed.".to_string(), + ); //return; } if (!self.app_context.has_wallet.load(Ordering::Relaxed)) { @@ -192,26 +208,32 @@ impl ScreenLike for UpdateIdentityPayoutScreen { self.render_selected_wallet_funding_addresses(ctx, &mut ui); if self.selected_funding_address.is_some() { ui.add_space(20.0); - ui.colored_label(egui::Color32::ORANGE, "The owner key of the Masternode/Evonode must be known to your wallet."); + ui.colored_label( + egui::Color32::ORANGE, + "The owner key of the Masternode/Evonode must be known to your wallet.", + ); ui.add_space(20.0); if ui.button("Update Payout Address").clicked() { action |= AppAction::BackendTask(BackendTask::CoreTask( CoreTask::ProRegUpdateTx( self.identity.identity.id().to_string(Encoding::Hex), self.selected_payout_address.clone().unwrap(), - self.selected_funding_address.clone().unwrap() - ) + self.selected_funding_address.clone().unwrap(), + ), )); } if self.error_message.is_some() { ui.add_space(20.0); - ui.colored_label(egui::Color32::RED, self.error_message.as_ref().unwrap()); + ui.colored_label( + egui::Color32::RED, + self.error_message.as_ref().unwrap(), + ); } } } } }); - + action } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index eee69bcd4..57f7e50ff 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -11,6 +11,7 @@ use crate::ui::identities::keys::add_key_screen::AddKeyScreen; use crate::ui::identities::keys::key_info_screen::KeyInfoScreen; use crate::ui::identities::keys::keys_screen::KeysScreen; use crate::ui::identities::top_up_identity_screen::TopUpIdentityScreen; +use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; use crate::ui::identities::withdraw_from_identity_screen::WithdrawalScreen; use crate::ui::network_chooser_screen::NetworkChooserScreen; use crate::ui::tool_screens::proof_log_screen::ProofLogScreen; @@ -18,6 +19,7 @@ use crate::ui::transfers::TransferScreen; use crate::ui::wallet::import_wallet_screen::ImportWalletScreen; use crate::ui::wallet::wallets_screen::WalletsBalancesScreen; use crate::ui::withdrawal_statuses_screen::WithdrawsStatusScreen; +use crate::ui::Screen::UpdatePayoutAddressScreen; use dash_sdk::dpp::identity::Identity; use dash_sdk::dpp::prelude::IdentityPublicKey; use dpns_contested_names_screen::DPNSSubscreen; @@ -31,8 +33,6 @@ use std::hash::Hash; use std::sync::Arc; use tool_screens::transition_visualizer_screen::TransitionVisualizerScreen; use wallet::add_new_wallet_screen::AddNewWalletScreen; -use crate::ui::identities::update_identity_payout_address::UpdateIdentityPayoutScreen; -use crate::ui::Screen::UpdatePayoutAddressScreen; pub mod components; pub mod document_query_screen; @@ -182,9 +182,9 @@ impl ScreenType { ScreenType::TransitionVisualizer => { Screen::TransitionVisualizerScreen(TransitionVisualizerScreen::new(app_context)) } - ScreenType::UpdatePayoutAddress(identity) => { - Screen::UpdatePayoutAddressScreen(UpdateIdentityPayoutScreen::new(identity.clone(), app_context)) - } + ScreenType::UpdatePayoutAddress(identity) => Screen::UpdatePayoutAddressScreen( + UpdateIdentityPayoutScreen::new(identity.clone(), app_context), + ), ScreenType::WithdrawalScreen(identity) => { Screen::WithdrawalScreen(WithdrawalScreen::new(identity.clone(), app_context)) } @@ -341,7 +341,9 @@ impl Screen { Screen::TransferScreen(screen) => ScreenType::TransferScreen(screen.identity.clone()), Screen::WalletsBalancesScreen(_) => ScreenType::WalletsBalances, Screen::WithdrawsStatusScreen(_) => ScreenType::WithdrawsStatus, - Screen::UpdatePayoutAddressScreen(screen) => ScreenType::UpdatePayoutAddress(screen.identity.clone()), + Screen::UpdatePayoutAddressScreen(screen) => { + ScreenType::UpdatePayoutAddress(screen.identity.clone()) + } Screen::ImportWalletScreen(_) => ScreenType::ImportWallet, Screen::ProofLogScreen(_) => ScreenType::ProofLog, } @@ -451,7 +453,9 @@ impl ScreenLike for Screen { Screen::NetworkChooserScreen(screen) => screen.display_message(message, message_type), Screen::WalletsBalancesScreen(screen) => screen.display_message(message, message_type), Screen::ProofLogScreen(screen) => screen.display_message(message, message_type), - Screen::UpdatePayoutAddressScreen(screen) => screen.display_message(message, message_type), + Screen::UpdatePayoutAddressScreen(screen) => { + screen.display_message(message, message_type) + } } } From 549e555bd43495ab7ed2cbac8475fe29730e1660 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Thu, 5 Dec 2024 16:45:03 +0200 Subject: [PATCH 5/8] fix --- src/ui/identities/update_identity_payout_address.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index 7a9e006b1..cace27e95 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -190,11 +190,11 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ui.heading( "Updating Payout Address for User identities is not allowed.".to_string(), ); - //return; + return; } if (!self.app_context.has_wallet.load(Ordering::Relaxed)) { ui.heading("Load a Wallet in order to continue.".to_string()); - //return; + return; } ui.heading("Update Payout Address".to_string()); ui.add_space(20.0); From 944a2cd2fb92d4bf13a1ef1da83996175a07a9c5 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Mon, 9 Dec 2024 16:41:39 +0700 Subject: [PATCH 6/8] fix: move button to Actions column and only display for masternodes --- src/ui/identities/identities_screen.rs | 96 ++++++++++++++------------ 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/src/ui/identities/identities_screen.rs b/src/ui/identities/identities_screen.rs index 54cce15ef..3d61f41fa 100644 --- a/src/ui/identities/identities_screen.rs +++ b/src/ui/identities/identities_screen.rs @@ -429,57 +429,63 @@ impl IdentitiesScreen { )); }}); }); - row.col(|ui| { - Self::show_balance(ui, qualified_identity); - if ui.button("Withdraw").clicked() { - action = AppAction::AddScreen( - Screen::WithdrawalScreen(WithdrawalScreen::new( - qualified_identity.clone(), - &self.app_context, - )), - ); - } - if ui.button("Top up").clicked() { - action = AppAction::AddScreen( - Screen::TopUpIdentityScreen(TopUpIdentityScreen::new( - qualified_identity.clone(), - &self.app_context, - )), - ); - } - if ui.button("Transfer").clicked() { - action = AppAction::AddScreen(Screen::TransferScreen( - TransferScreen::new( - qualified_identity.clone(), - &self.app_context, - ), - )); - } - if ui.button("Update Payout Address").clicked() { - action = AppAction::AddScreen(Screen::UpdatePayoutAddressScreen( - UpdateIdentityPayoutScreen::new( - qualified_identity.clone(), - &self.app_context, - ), - )); - } - }); row.col(|ui| { ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 10.0; + Self::show_balance(ui, qualified_identity); ui.spacing_mut().item_spacing.x = 3.0; - - if ui.button("Refresh").clicked() { - action = - AppAction::BackendTask(BackendTask::IdentityTask( - IdentityTask::RefreshIdentity( + if ui.button("Withdraw").clicked() { + action = AppAction::AddScreen( + Screen::WithdrawalScreen(WithdrawalScreen::new( qualified_identity.clone(), + &self.app_context, + )), + ); + } + if ui.button("Top up").clicked() { + action = AppAction::AddScreen( + Screen::TopUpIdentityScreen(TopUpIdentityScreen::new( + qualified_identity.clone(), + &self.app_context, + )), + ); + } + if ui.button("Transfer").clicked() { + action = AppAction::AddScreen(Screen::TransferScreen( + TransferScreen::new( + qualified_identity.clone(), + &self.app_context, ), )); - } - if ui.button("Remove").clicked() { - self.identity_to_remove = - Some(qualified_identity.clone()); - }}); + } + }); + }); + row.col(|ui| { + ui.horizontal(|ui| { + ui.spacing_mut().item_spacing.x = 3.0; + if ui.button("Refresh").clicked() { + action = + AppAction::BackendTask(BackendTask::IdentityTask( + IdentityTask::RefreshIdentity( + qualified_identity.clone(), + ), + )); + } + if ui.button("Remove").clicked() { + self.identity_to_remove = + Some(qualified_identity.clone()); + } + if qualified_identity.identity_type != IdentityType::User { + if ui.button("Update Payout Address").clicked() { + action = AppAction::AddScreen(Screen::UpdatePayoutAddressScreen( + UpdateIdentityPayoutScreen::new( + qualified_identity.clone(), + &self.app_context, + ), + )); + } + } + }); }); }); } From ffbc1706fd9a2fa81bf86bd93ad01e771b894710 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Tue, 10 Dec 2024 13:41:47 +0200 Subject: [PATCH 7/8] suggestions --- .../update_identity_payout_address.rs | 132 ++++++++++++++++-- 1 file changed, 117 insertions(+), 15 deletions(-) diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index cace27e95..836270895 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -13,6 +13,16 @@ use eframe::egui::Context; use egui::{ComboBox, Ui}; use std::sync::atomic::Ordering; use std::sync::{Arc, RwLock}; +use std::time::{SystemTime, UNIX_EPOCH}; +use dash_sdk::dpp::identity::TimestampMillis; +use crate::ui::components::wallet_unlock::ScreenWithWalletUnlock; + +pub enum UpdateIdentityPayoutStatus { + NotStarted, + WaitingForResult(TimestampMillis), + ErrorMessage(String), + Complete, +} pub struct UpdateIdentityPayoutScreen { pub app_context: Arc, @@ -20,6 +30,9 @@ pub struct UpdateIdentityPayoutScreen { selected_wallet: Option>>, selected_payout_address: Option
, selected_funding_address: Option
, + update_payout_status: UpdateIdentityPayoutStatus, + wallet_password: String, + show_password: bool, error_message: Option, } @@ -33,6 +46,9 @@ impl UpdateIdentityPayoutScreen { selected_payout_address: None, selected_funding_address: None, error_message: None, + update_payout_status: UpdateIdentityPayoutStatus::NotStarted, + wallet_password: String::new(), + show_password: false, } } @@ -85,7 +101,7 @@ impl UpdateIdentityPayoutScreen { }); } - fn render_selected_wallet_payout_addresses(&mut self, ctx: &Context, ui: &mut Ui) { + fn render_selected_wallet_payout_addresses(&mut self, ui: &mut Ui) { if let Some(selected_wallet) = &self.selected_wallet { // Acquire a read lock let wallet = selected_wallet.read().unwrap(); @@ -125,7 +141,7 @@ impl UpdateIdentityPayoutScreen { } } - fn render_selected_wallet_funding_addresses(&mut self, ctx: &Context, ui: &mut Ui) { + fn render_selected_wallet_funding_addresses(&mut self, ui: &mut Ui) { if let Some(selected_wallet) = &self.selected_wallet { // Acquire a read lock let wallet = selected_wallet.read().unwrap(); @@ -167,9 +183,15 @@ impl UpdateIdentityPayoutScreen { } impl ScreenLike for UpdateIdentityPayoutScreen { - fn display_message(&mut self, message: &str, _message_type: MessageType) { - if _message_type == MessageType::Error { - self.error_message = Some(message.to_string()); + fn display_message(&mut self, message: &str, message_type: MessageType) { + match message_type { + MessageType::Success => { + self.update_payout_status = UpdateIdentityPayoutStatus::Complete; + } + MessageType::Info => {} + MessageType::Error => { + self.update_payout_status = UpdateIdentityPayoutStatus::ErrorMessage(message.to_string()); + } } } @@ -186,13 +208,13 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ); egui::CentralPanel::default().show(ctx, |mut ui| { - if (self.identity.identity_type == IdentityType::User) { + if self.identity.identity_type == IdentityType::User { ui.heading( "Updating Payout Address for User identities is not allowed.".to_string(), ); return; } - if (!self.app_context.has_wallet.load(Ordering::Relaxed)) { + if !self.app_context.has_wallet.load(Ordering::Relaxed) { ui.heading("Load a Wallet in order to continue.".to_string()); return; } @@ -202,10 +224,16 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ui.heading("Load Address from wallet".to_string()); self.render_wallet_selection(&mut ui); + let (needed_unlock, just_unlocked) = self.render_wallet_unlock_if_needed(ui); + + if needed_unlock && !just_unlocked { + return; + } + if self.selected_wallet.is_some() { - self.render_selected_wallet_payout_addresses(ctx, &mut ui); + self.render_selected_wallet_payout_addresses(&mut ui); if self.selected_payout_address.is_some() { - self.render_selected_wallet_funding_addresses(ctx, &mut ui); + self.render_selected_wallet_funding_addresses(&mut ui); if self.selected_funding_address.is_some() { ui.add_space(20.0); ui.colored_label( @@ -214,6 +242,12 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ); ui.add_space(20.0); if ui.button("Update Payout Address").clicked() { + // Set the status to waiting and capture the current time + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + self.update_payout_status = UpdateIdentityPayoutStatus::WaitingForResult(now); action |= AppAction::BackendTask(BackendTask::CoreTask( CoreTask::ProRegUpdateTx( self.identity.identity.id().to_string(Encoding::Hex), @@ -222,12 +256,50 @@ impl ScreenLike for UpdateIdentityPayoutScreen { ), )); } - if self.error_message.is_some() { - ui.add_space(20.0); - ui.colored_label( - egui::Color32::RED, - self.error_message.as_ref().unwrap(), - ); + + // Handle registration status messages + match &self.update_payout_status { + UpdateIdentityPayoutStatus::NotStarted => { + // Do nothing + } + UpdateIdentityPayoutStatus::WaitingForResult(start_time) => { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + let elapsed_seconds = now - start_time; + + let display_time = if elapsed_seconds < 60 { + format!( + "{} second{}", + elapsed_seconds, + if elapsed_seconds == 1 { "" } else { "s" } + ) + } else { + let minutes = elapsed_seconds / 60; + let seconds = elapsed_seconds % 60; + format!( + "{} minute{} and {} second{}", + minutes, + if minutes == 1 { "" } else { "s" }, + seconds, + if seconds == 1 { "" } else { "s" } + ) + }; + + ui.add_space(20.0); + ui.label(format!( + "Waiting... Time taken so far: {}", + display_time + )); + } + UpdateIdentityPayoutStatus::ErrorMessage(msg) => { + ui.add_space(20.0); + ui.colored_label(egui::Color32::RED, format!("Error: {}", msg)); + } + UpdateIdentityPayoutStatus::Complete => { + action = AppAction::PopScreenAndRefresh; + } } } } @@ -237,3 +309,33 @@ impl ScreenLike for UpdateIdentityPayoutScreen { action } } + +impl ScreenWithWalletUnlock for UpdateIdentityPayoutScreen { + fn selected_wallet_ref(&self) -> &Option>> { + &self.selected_wallet + } + + fn wallet_password_ref(&self) -> &String { + &self.wallet_password + } + + fn wallet_password_mut(&mut self) -> &mut String { + &mut self.wallet_password + } + + fn show_password(&self) -> bool { + self.show_password + } + + fn show_password_mut(&mut self) -> &mut bool { + &mut self.show_password + } + + fn set_error_message(&mut self, error_message: Option) { + self.error_message = error_message; + } + + fn error_message(&self) -> Option<&String> { + self.error_message.as_ref() + } +} From e4c299f71cf23d5a5d2b715c785b8ba968061187 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Thu, 12 Dec 2024 14:52:58 +0700 Subject: [PATCH 8/8] feat: success screen --- .../update_identity_payout_address.rs | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/ui/identities/update_identity_payout_address.rs b/src/ui/identities/update_identity_payout_address.rs index 836270895..a409dcc48 100644 --- a/src/ui/identities/update_identity_payout_address.rs +++ b/src/ui/identities/update_identity_payout_address.rs @@ -5,17 +5,17 @@ use crate::context::AppContext; use crate::model::qualified_identity::{IdentityType, QualifiedIdentity}; use crate::model::wallet::Wallet; use crate::ui::components::top_panel::add_top_panel; +use crate::ui::components::wallet_unlock::ScreenWithWalletUnlock; use crate::ui::{MessageType, ScreenLike}; use dash_sdk::dashcore_rpc::dashcore::Address; use dash_sdk::dpp::identity::accessors::IdentityGettersV0; +use dash_sdk::dpp::identity::TimestampMillis; use dash_sdk::dpp::platform_value::string_encoding::Encoding; use eframe::egui::Context; use egui::{ComboBox, Ui}; use std::sync::atomic::Ordering; use std::sync::{Arc, RwLock}; use std::time::{SystemTime, UNIX_EPOCH}; -use dash_sdk::dpp::identity::TimestampMillis; -use crate::ui::components::wallet_unlock::ScreenWithWalletUnlock; pub enum UpdateIdentityPayoutStatus { NotStarted, @@ -180,6 +180,27 @@ impl UpdateIdentityPayoutScreen { } } } + + fn show_success(&self, ui: &mut Ui) -> AppAction { + let mut action = AppAction::None; + + // Center the content vertically and horizontally + ui.vertical_centered(|ui| { + ui.add_space(50.0); + + ui.heading("🎉"); + ui.heading("Successfully updated payout address."); + + ui.add_space(20.0); + + if ui.button("Go back to Identities Screen").clicked() { + // Handle navigation back to the identities screen + action = AppAction::PopScreenAndRefresh; + } + }); + + action + } } impl ScreenLike for UpdateIdentityPayoutScreen { @@ -190,7 +211,8 @@ impl ScreenLike for UpdateIdentityPayoutScreen { } MessageType::Info => {} MessageType::Error => { - self.update_payout_status = UpdateIdentityPayoutStatus::ErrorMessage(message.to_string()); + self.update_payout_status = + UpdateIdentityPayoutStatus::ErrorMessage(message.to_string()); } } } @@ -247,7 +269,8 @@ impl ScreenLike for UpdateIdentityPayoutScreen { .duration_since(UNIX_EPOCH) .expect("Time went backwards") .as_secs(); - self.update_payout_status = UpdateIdentityPayoutStatus::WaitingForResult(now); + self.update_payout_status = + UpdateIdentityPayoutStatus::WaitingForResult(now); action |= AppAction::BackendTask(BackendTask::CoreTask( CoreTask::ProRegUpdateTx( self.identity.identity.id().to_string(Encoding::Hex), @@ -288,17 +311,14 @@ impl ScreenLike for UpdateIdentityPayoutScreen { }; ui.add_space(20.0); - ui.label(format!( - "Waiting... Time taken so far: {}", - display_time - )); + ui.label(format!("Waiting... Time taken so far: {}", display_time)); } UpdateIdentityPayoutStatus::ErrorMessage(msg) => { ui.add_space(20.0); ui.colored_label(egui::Color32::RED, format!("Error: {}", msg)); } UpdateIdentityPayoutStatus::Complete => { - action = AppAction::PopScreenAndRefresh; + action = self.show_success(ui); } } }