diff --git a/rusk-wallet/src/bin/interactive.rs b/rusk-wallet/src/bin/interactive.rs index f33fd833f1..c908ab5282 100644 --- a/rusk-wallet/src/bin/interactive.rs +++ b/rusk-wallet/src/bin/interactive.rs @@ -73,34 +73,50 @@ pub(crate) async fn run_loop( addr: wallet.bls_public_key(addr.index()?), }; + let is_synced = wallet.is_synced().await?; + loop { // get balance for this address prompt::hide_cursor()?; - let phoenix_bal = wallet.get_phoenix_balance(&addr).await?; let moonlight_bal = wallet.get_moonlight_balance(&moonlight).await?; - let spendable = phoenix_bal.spendable.into(); - let total: Dusk = phoenix_bal.value.into(); + let phoenix_bal = wallet.get_phoenix_balance(&addr).await?; + let phoenix_spendable = phoenix_bal.spendable.into(); + let phoenix_total: Dusk = phoenix_bal.value.into(); prompt::hide_cursor()?; // display address information println!(); println!(); - println!("{0: <20} - Total: {moonlight_bal}", "Moonlight Balance"); + if is_synced { + println!( + "{0: <20} - Total: {moonlight_bal}", + "Moonlight Balance", + ); + } println!("{0: <20} {moonlight}", "Moonlight Address"); println!(); - println!("{0: <20} - Spendable: {spendable}", "Phoenix Balance",); - println!("{0: <20} - Total: {total}", ""); + if is_synced { + println!( + "{0: <20} - Spendable: {phoenix_spendable}", + "Phoenix Balance", + ); + println!("{0: <20} - Total: {phoenix_total}", "",); + } println!("{0: <20} {addr}", "Phoenix Address"); println!(); // request operation to perform let op = match wallet.is_online().await { - true => { - menu_op(addr.clone(), spendable, moonlight_bal, settings) - } + true => menu_op( + addr.clone(), + phoenix_spendable, + moonlight_bal, + settings, + is_synced, + ), false => menu_op_offline(addr.clone(), settings), }; @@ -417,10 +433,11 @@ fn menu_op( phoenix_balance: Dusk, moonlight_balance: Dusk, settings: &Settings, + is_synced: bool, ) -> anyhow::Result { use CommandMenuItem as CMI; - let cmd_menu = Menu::new() + let mut cmd_menu = Menu::new() .add(CMI::StakeInfo, "Check Existing Stake") .add(CMI::PhoenixTransactions, "Phoenix Transactions") .add(CMI::MoonlightTransactions, "Moonlight Transactions") @@ -431,8 +448,21 @@ fn menu_op( .add(CMI::Back, "Back") .separator(); + let msg = if !is_synced { + cmd_menu = Menu::new() + .add(CMI::StakeInfo, "Check Existing Stake") + .add(CMI::Export, "Export provisioner key-pair") + .separator() + .add(CMI::Back, "Back") + .separator(); + + "The wallet is still syncing. Please come back to display new information." + } else { + "What do you like to do?" + }; + let q = Question::select("theme") - .message("What would you like to do?") + .message(msg) .choices(cmd_menu.clone()) .build(); diff --git a/rusk-wallet/src/clients.rs b/rusk-wallet/src/clients.rs index 748a118205..1c13018b38 100644 --- a/rusk-wallet/src/clients.rs +++ b/rusk-wallet/src/clients.rs @@ -348,6 +348,25 @@ impl State { Ok(branch) } + /// Queries the transfer contract for the number of notes. + pub async fn fetch_num_notes(&self) -> Result { + let status = self.status; + status("Fetching latest note position..."); + + let data = self + .client + .contract_query::<_, _, { u64::SIZE }>( + TRANSFER_CONTRACT, + "num_notes", + &(), + ) + .await?; + + let res: u64 = rkyv::from_bytes(&data).map_err(|_| Error::Rkyv)?; + + Ok(res) + } + pub fn close(&mut self) { // UNWRAP: its okay to panic here because we're closing the database // if there's an error we want an exception to happen diff --git a/rusk-wallet/src/wallet.rs b/rusk-wallet/src/wallet.rs index d15935fdbe..ce74ebff18 100644 --- a/rusk-wallet/src/wallet.rs +++ b/rusk-wallet/src/wallet.rs @@ -1151,6 +1151,15 @@ impl Wallet { } } + /// Check if the wallet is synced + pub async fn is_synced(&mut self) -> Result { + let state = self.state()?; + let db_pos = state.cache().last_pos()?.unwrap_or(0); + let network_last_pos = state.fetch_num_notes().await? - 1; + + Ok(network_last_pos == db_pos) + } + /// Close the wallet and zeroize the seed pub fn close(&mut self) { self.store.inner_mut().zeroize();