Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ derive_more = "1.0.0"
accesskit = "=0.16.1"
egui = { version = "0.29.1" }
egui_extras = "0.29.1"
rfd = "0.15.1"
qrcode = "0.14.1"
eframe = { version = "0.29.1", features = ["persistence"] }
strum = { version = "0.26.1", features = ["derive"] }
Expand Down
17 changes: 15 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl AppState {

let password_info = settings
.clone()
.map(|(_, _, password_info)| password_info)
.map(|(_, _, password_info, _, _)| password_info)
.flatten();

let mainnet_app_context =
Expand All @@ -150,10 +150,23 @@ impl AppState {
let mut proof_log_screen = ProofLogScreen::new(&mainnet_app_context);
let mut document_query_screen = DocumentQueryScreen::new(&mainnet_app_context);
let mut withdraws_status_screen = WithdrawsStatusScreen::new(&mainnet_app_context);

let (custom_dash_qt_path, overwrite_dash_conf) = match settings.clone() {
Some((.., db_custom_dash_qt_path, db_overwrite_dash_qt)) => {
(db_custom_dash_qt_path, db_overwrite_dash_qt)
}
_ => {
// Default values: Use system default path and overwrite conf
(None, true)
}
};

let mut network_chooser_screen = NetworkChooserScreen::new(
&mainnet_app_context,
testnet_app_context.as_ref(),
Network::Dash,
custom_dash_qt_path,
overwrite_dash_conf,
);

let mut wallets_balances_screen = WalletsBalancesScreen::new(&mainnet_app_context);
Expand All @@ -162,7 +175,7 @@ impl AppState {

let mut chosen_network = Network::Dash;

if let Some((network, screen_type, password_info)) = settings {
if let Some((network, screen_type, password_info, _, _)) = settings {
selected_main_screen = screen_type;
chosen_network = network;
if chosen_network == Network::Testnet && testnet_app_context.is_some() {
Expand Down
7 changes: 4 additions & 3 deletions src/backend_task/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ use std::sync::{Arc, RwLock};
pub(crate) enum CoreTask {
GetBestChainLock,
RefreshWalletInfo(Arc<RwLock<Wallet>>),
StartDashQT(Network),
StartDashQT(Network, Option<String>, bool),
Comment thread
ogabrielides marked this conversation as resolved.
}
impl PartialEq for CoreTask {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(CoreTask::GetBestChainLock, CoreTask::GetBestChainLock) => true,
(CoreTask::RefreshWalletInfo(_), CoreTask::RefreshWalletInfo(_)) => true,
(CoreTask::StartDashQT(_, _, _), CoreTask::StartDashQT(_, _, _)) => true,
_ => false,
}
}
Expand All @@ -44,8 +45,8 @@ impl AppContext {
})
.map_err(|e| e.to_string()),
CoreTask::RefreshWalletInfo(wallet) => self.refresh_wallet_info(wallet),
CoreTask::StartDashQT(network) => self
.start_dash_qt(network)
CoreTask::StartDashQT(network, custom_dash_qt, overwrite_dash_conf) => self
.start_dash_qt(network, custom_dash_qt, overwrite_dash_conf)
.map_err(|e| e.to_string())
.map(|_| BackendTaskSuccessResult::None),
}
Expand Down
55 changes: 33 additions & 22 deletions src/backend_task/core/start_dash_qt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@ use std::{env, io};

impl AppContext {
/// Function to start Dash QT based on the selected network
pub(super) fn start_dash_qt(&self, network: Network) -> io::Result<()> {
// Determine the path to Dash-Qt based on the operating system
let dash_qt_path: PathBuf = if cfg!(target_os = "macos") {
PathBuf::from("/Applications/Dash-Qt.app/Contents/MacOS/Dash-Qt")
} else if cfg!(target_os = "windows") {
// Retrieve the PROGRAMFILES environment variable and construct the path
let program_files = env::var("PROGRAMFILES")
.map(PathBuf::from)
.map_err(|e| io::Error::new(io::ErrorKind::NotFound, e))?;

program_files.join("DashCore\\dash-qt.exe")
} else {
PathBuf::from("/usr/local/bin/dash-qt") // Linux path
pub(super) fn start_dash_qt(
&self,
network: Network,
custom_dash_qt: Option<String>,
overwrite_dash_conf: bool,
) -> io::Result<()> {
let dash_qt_path = match custom_dash_qt {
Some(ref custom_path) => PathBuf::from(custom_path),
Comment thread
ogabrielides marked this conversation as resolved.
None => {
if cfg!(target_os = "macos") {
PathBuf::from("/Applications/Dash-Qt.app/Contents/MacOS/Dash-Qt")
} else if cfg!(target_os = "windows") {
// Retrieve the PROGRAMFILES environment variable or default to "C:\\Program Files"
let program_files = env::var("PROGRAMFILES")
.unwrap_or_else(|_| "C:\\Program Files".to_string());
PathBuf::from(program_files).join("DashCore\\dash-qt.exe")
} else {
PathBuf::from("/usr/local/bin/dash-qt") // Default Linux path
}
}
};

// Ensure the Dash-Qt binary path exists
Expand All @@ -43,16 +50,20 @@ impl AppContext {
}
};

// Construct the full path to the config file
let current_dir = env::current_dir()?;
let config_path = current_dir.join(config_file);
let mut command = Command::new(&dash_qt_path);
command.stdout(Stdio::null()).stderr(Stdio::null()); // Suppress output

if overwrite_dash_conf {
// Construct the full path to the config file
let current_dir = env::current_dir()?;
let config_path = current_dir.join(config_file);
command.arg(format!("-conf={}", config_path.display()));
} else if network == Network::Testnet {
command.arg("-testnet");
}

// Start Dash-Qt with the appropriate config
Command::new(&dash_qt_path)
.arg(format!("-conf={}", config_path.display()))
.stdout(Stdio::null()) // Optional: Suppress output
.stderr(Stdio::null())
.spawn()?; // Spawn the Dash-Qt process
// Spawn the Dash-Qt process
command.spawn()?;

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/core_zmq_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl CoreZMQListener {
.recv(&mut addr_msg, 0)
.expect("Failed to receive address message");

let data = event_msg.as_ref();
let data: &[u8] = event_msg.as_ref(); // Explicitly annotate the type
if data.len() >= 6 {
let event_number = u16::from_le_bytes([data[0], data[1]]);
let endpoint = addr_msg.as_str().unwrap_or("");
Expand Down
12 changes: 11 additions & 1 deletion src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,17 @@ impl AppContext {
}

/// Retrieves the current `RootScreenType` from the settings
pub fn get_settings(&self) -> Result<Option<(Network, RootScreenType, Option<PasswordInfo>)>> {
pub fn get_settings(
&self,
) -> Result<
Option<(
Network,
RootScreenType,
Option<PasswordInfo>,
Option<String>,
bool,
)>,
> {
self.db.get_settings()
}

Expand Down
8 changes: 7 additions & 1 deletion src/database/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use rusqlite::{params, Connection};
use std::fs;
use std::path::Path;

pub const DEFAULT_DB_VERSION: u16 = 2;
pub const DEFAULT_DB_VERSION: u16 = 3;

pub const DEFAULT_NETWORK: &str = "dash";

impl Database {
Expand Down Expand Up @@ -33,6 +34,9 @@ impl Database {

fn apply_version_changes(&self, version: u16) -> rusqlite::Result<()> {
match version {
3 => {
self.add_custom_dash_qt_columns()?;
}
2 => {
self.initialize_proof_log_table()?;
}
Expand Down Expand Up @@ -175,6 +179,8 @@ impl Database {
main_password_nonce BLOB,
network TEXT NOT NULL,
start_root_screen INTEGER NOT NULL,
custom_dash_qt_path TEXT,
overwrite_dash_conf INTEGER,
database_version INTEGER NOT NULL
)",
[],
Expand Down
54 changes: 51 additions & 3 deletions src/database/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::model::password_info::PasswordInfo;
use crate::ui::RootScreenType;
use dash_sdk::dpp::dashcore::Network;
use rusqlite::{params, Result};
use std::path::PathBuf;
use std::str::FromStr;

impl Database {
Expand Down Expand Up @@ -44,6 +45,35 @@ impl Database {
Ok(())
}

pub fn update_dash_core_execution_settings(
&self,
custom_dash_path: Option<String>,
overwrite_dash_conf: bool,
) -> Result<()> {
self.execute(
"UPDATE settings
SET custom_dash_qt_path = ?,
overwrite_dash_conf = ?
WHERE id = 1",
rusqlite::params![custom_dash_path, overwrite_dash_conf],
)?;

Ok(())
}

pub fn add_custom_dash_qt_columns(&self) -> Result<()> {
self.execute(
"ALTER TABLE settings ADD COLUMN custom_dash_qt_path TEXT DEFAULT NULL;",
(),
)?;
self.execute(
"ALTER TABLE settings ADD COLUMN overwrite_dash_conf INTEGER DEFAULT NULL;",
(),
)?;

Ok(())
}
Comment thread
ogabrielides marked this conversation as resolved.

/// Updates the database version in the settings table.
pub fn update_database_version(&self, new_version: u16) -> Result<()> {
// Ensure the database version is updated
Expand All @@ -58,18 +88,30 @@ impl Database {
}

/// Retrieves the settings from the database.
pub fn get_settings(&self) -> Result<Option<(Network, RootScreenType, Option<PasswordInfo>)>> {
pub fn get_settings(
&self,
) -> Result<
Option<(
Network,
RootScreenType,
Option<PasswordInfo>,
Option<String>,
bool,
)>,
> {
// Query the settings row
let conn = self.conn.lock().unwrap();
let mut stmt =
conn.prepare("SELECT network, start_root_screen, password_check, main_password_salt, main_password_nonce FROM settings WHERE id = 1")?;
conn.prepare("SELECT network, start_root_screen, password_check, main_password_salt, main_password_nonce, custom_dash_qt_path, overwrite_dash_conf FROM settings WHERE id = 1")?;

let result = stmt.query_row([], |row| {
let network: String = row.get(0)?;
let start_root_screen: u32 = row.get(1)?;
let password_check: Option<Vec<u8>> = row.get(2)?;
let main_password_salt: Option<Vec<u8>> = row.get(3)?;
let main_password_nonce: Option<Vec<u8>> = row.get(4)?;
let custom_dash_qt_path: Option<String> = row.get(5)?;
let overwrite_dash_conf: Option<bool> = row.get(6)?;

// Combine the password-related fields if all are present, otherwise set to None
let password_data = match (password_check, main_password_salt, main_password_nonce) {
Expand All @@ -89,7 +131,13 @@ impl Database {
let root_screen_type = RootScreenType::from_int(start_root_screen)
.ok_or_else(|| rusqlite::Error::InvalidQuery)?;

Ok((parsed_network, root_screen_type, password_data))
Ok((
parsed_network,
root_screen_type,
password_data,
custom_dash_qt_path,
overwrite_dash_conf.unwrap_or(true),
))
});

match result {
Expand Down
20 changes: 19 additions & 1 deletion src/ui/components/top_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,28 @@ fn add_connection_indicator(ui: &mut Ui, app_context: &Arc<AppContext>) -> AppAc
};
response.clone().on_hover_text(tooltip_text);

let settings = app_context
.db
.get_settings()
.expect("Failed to db get settings");
let (custom_dash_qt_path, overwrite_dash_conf) = match settings {
Some((.., db_custom_dash_qt_path, db_overwrite_dash_qt)) => {
(db_custom_dash_qt_path, db_overwrite_dash_qt)
}
_ => {
// Default values: Use system default path and overwrite conf
(None, true)
}
};

// Handle click to start DashQT if disconnected
if response.clicked() && !connected {
let network = app_context.network;
action |= AppAction::BackendTask(BackendTask::CoreTask(CoreTask::StartDashQT(network)));
action |= AppAction::BackendTask(BackendTask::CoreTask(CoreTask::StartDashQT(
network,
custom_dash_qt_path,
overwrite_dash_conf,
)));
}
});

Expand Down
Loading