Skip to content

Commit

Permalink
feat: check wallet type on send + ui fixes (#6461)
Browse files Browse the repository at this point in the history
Description
---
Checks the wallet type on send in the wallet_lib
Adds various fixes for the console UI

Motivation and Context
---
Cleans up the Console wallet UI and makes it easier to use and only
display correct info.
  • Loading branch information
SWvheerden authored Aug 13, 2024
1 parent 4601530 commit 574fa1e
Show file tree
Hide file tree
Showing 16 changed files with 129 additions and 77 deletions.
12 changes: 6 additions & 6 deletions applications/minotari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ pub async fn command_runner(
println!();
},
PreMineSpendSessionInfo(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down Expand Up @@ -891,7 +891,7 @@ pub async fn command_runner(
println!();
},
PreMineSpendBackupUtxo(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down Expand Up @@ -931,7 +931,7 @@ pub async fn command_runner(
}
},
PreMineSpendPartyDetails(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down Expand Up @@ -1052,7 +1052,7 @@ pub async fn command_runner(
println!();
},
PreMineSpendEncumberAggregateUtxo(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down Expand Up @@ -1146,7 +1146,7 @@ pub async fn command_runner(
}
},
PreMineSpendInputOutputSigs(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down Expand Up @@ -1258,7 +1258,7 @@ pub async fn command_runner(
}
},
PreMineSpendAggregateTransaction(args) => {
match key_manager_service.get_wallet_type().await {
match *key_manager_service.get_wallet_type().await {
WalletType::Ledger(_) => {},
_ => {
eprintln!("\nError: Wallet type must be 'Ledger' to spend pre-mine outputs!\n");
Expand Down
2 changes: 1 addition & 1 deletion applications/minotari_console_wallet/src/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ pub async fn start_wallet(
wallet_mode: &WalletMode,
) -> Result<(), ExitError> {
// Verify ledger build if wallet type is Ledger
if let WalletType::Ledger(_) = wallet.key_manager_service.get_wallet_type().await {
if let WalletType::Ledger(_) = *wallet.key_manager_service.get_wallet_type().await {
#[cfg(not(feature = "ledger"))]
{
return Err(ExitError::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ impl<B: Backend> Component<B> for BaseNode {
let base_node_state = app_state.get_base_node_state();
if let Some(ref metadata) = base_node_state.chain_metadata {
let tip = metadata.best_block_height();
let scanned_height = app_state.get_wallet_scanned_height();
let scanned_height = match app_state.get_wallet_scanned_height() {
0 => "*",
v => &v.to_string(),
};

let synced = base_node_state.is_synced.unwrap_or_default();
let (tip_color, sync_text) = if synced {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl TransactionsTab {

if t.direction == TransactionDirection::Outbound {
column0_items.push(ListItem::new(Span::styled(
app_state.get_alias(&t.destination_address),
app_state.get_alias(t.destination_address.to_base58()),
Style::default().fg(text_color),
)));
let amount_style = if t.cancelled.is_some() {
Expand All @@ -123,7 +123,7 @@ impl TransactionsTab {
column1_items.push(ListItem::new(Span::styled(amount, amount_style)));
} else {
column0_items.push(ListItem::new(Span::styled(
app_state.get_alias(&t.source_address),
app_state.get_alias(t.source_address.to_base58()),
Style::default().fg(text_color),
)));
let amount_style = if t.cancelled.is_some() {
Expand Down Expand Up @@ -209,11 +209,18 @@ impl TransactionsTab {
for t in windowed_view {
let cancelled = t.cancelled.is_some();
let text_color = text_colors.get(&cancelled).unwrap_or(&Color::Reset).to_owned();

let address_text = match (&t.direction, &t.coinbase, &t.burn) {
(_, true, _) => "Mining reward",
(_, _, true) => "Burned output",
(TransactionDirection::Outbound, _, _) => &app_state.get_alias(t.destination_address.to_base58()),
_ => &app_state.get_alias(t.source_address.to_base58()),
};
column0_items.push(ListItem::new(Span::styled(
app_state.get_alias(address_text.to_string()),
Style::default().fg(text_color),
)));
if t.direction == TransactionDirection::Outbound {
column0_items.push(ListItem::new(Span::styled(
app_state.get_alias(&t.destination_address),
Style::default().fg(text_color),
)));
let amount_style = if t.cancelled.is_some() {
Style::default().fg(Color::Red).add_modifier(Modifier::DIM)
} else {
Expand All @@ -222,10 +229,6 @@ impl TransactionsTab {
let amount = format!("{}", t.amount);
column1_items.push(ListItem::new(Span::styled(amount, amount_style)));
} else {
column0_items.push(ListItem::new(Span::styled(
app_state.get_alias(&t.source_address),
Style::default().fg(text_color),
)));
let color = match (t.cancelled.is_some(), chain_height) {
// cancelled
(true, _) => Color::DarkGray,
Expand Down Expand Up @@ -289,10 +292,10 @@ impl TransactionsTab {
.split(area);

// Labels
let constraints = [Constraint::Length(1); 15];
let constraints = [Constraint::Length(1); 14];
let label_layout = Layout::default().constraints(constraints).split(columns[0]);

let tx_id = Span::styled("TxID:", Style::default().fg(Color::Magenta));
let excess_sig = Span::styled("Excess sig(nonce, sig):", Style::default().fg(Color::Magenta));
let source_address = Span::styled("Source Address:", Style::default().fg(Color::Magenta));
let destination_address = Span::styled("Destination address:", Style::default().fg(Color::Magenta));
let direction = Span::styled("Direction:", Style::default().fg(Color::Magenta));
Expand All @@ -302,14 +305,13 @@ impl TransactionsTab {
let message = Span::styled("Message:", Style::default().fg(Color::Magenta));
let imported_timestamp = Span::styled("Imported At (Local):", Style::default().fg(Color::Magenta));
let mined_timestamp = Span::styled("Mined At (Local):", Style::default().fg(Color::Magenta));
let excess = Span::styled("Excess:", Style::default().fg(Color::Magenta));
let confirmations = Span::styled("Confirmations:", Style::default().fg(Color::Magenta));
let mined_height = Span::styled("Mined Height:", Style::default().fg(Color::Magenta));
let maturity = Span::styled("Maturity:", Style::default().fg(Color::Magenta));
let payment_id = Span::styled("Payment Id:", Style::default().fg(Color::Magenta));

let trim = Wrap { trim: true };
let paragraph = Paragraph::new(tx_id).wrap(trim);
let paragraph = Paragraph::new(excess_sig).wrap(trim);
f.render_widget(paragraph, label_layout[0]);
let paragraph = Paragraph::new(source_address).wrap(trim);
f.render_widget(paragraph, label_layout[1]);
Expand All @@ -329,23 +331,21 @@ impl TransactionsTab {
f.render_widget(paragraph, label_layout[8]);
let paragraph = Paragraph::new(imported_timestamp).wrap(trim);
f.render_widget(paragraph, label_layout[9]);
let paragraph = Paragraph::new(excess).wrap(trim);
f.render_widget(paragraph, label_layout[10]);
let paragraph = Paragraph::new(confirmations).wrap(trim);
f.render_widget(paragraph, label_layout[11]);
f.render_widget(paragraph, label_layout[10]);
let paragraph = Paragraph::new(mined_height).wrap(trim);
f.render_widget(paragraph, label_layout[12]);
f.render_widget(paragraph, label_layout[11]);
let paragraph = Paragraph::new(maturity).wrap(trim);
f.render_widget(paragraph, label_layout[13]);
f.render_widget(paragraph, label_layout[12]);
let paragraph = Paragraph::new(payment_id).wrap(trim);
f.render_widget(paragraph, label_layout[14]);
f.render_widget(paragraph, label_layout[13]);

// Content
let required_confirmations = app_state.get_required_confirmations();
if let Some(tx) = self.detailed_transaction.as_ref() {
let constraints = [Constraint::Length(1); 15];
let constraints = [Constraint::Length(1); 14];
let content_layout = Layout::default().constraints(constraints).split(columns[1]);
let tx_id = Span::styled(format!("{}", tx.tx_id), Style::default().fg(Color::White));
let excess_sig = Span::styled(format!("({})", tx.excess_signature), Style::default().fg(Color::White));

let source_address =
if tx.status == TransactionStatus::Pending && tx.direction == TransactionDirection::Outbound {
Expand Down Expand Up @@ -406,7 +406,6 @@ impl TransactionsTab {
Style::default().fg(Color::White),
);

let excess = Span::styled(tx.excess_signature.as_str(), Style::default().fg(Color::White));
let confirmation_count = app_state.get_confirmations(tx.tx_id);
let confirmations_msg = if tx.status == TransactionStatus::MinedConfirmed && tx.cancelled.is_none() {
format!("{} required confirmations met", required_confirmations)
Expand Down Expand Up @@ -447,7 +446,7 @@ impl TransactionsTab {
};
let payment_id = Span::styled(payment_id, Style::default().fg(Color::White));

let paragraph = Paragraph::new(tx_id).wrap(trim);
let paragraph = Paragraph::new(excess_sig).wrap(trim);
f.render_widget(paragraph, content_layout[0]);
let paragraph = Paragraph::new(source_address).wrap(trim);
f.render_widget(paragraph, content_layout[1]);
Expand All @@ -467,16 +466,14 @@ impl TransactionsTab {
f.render_widget(paragraph, content_layout[8]);
let paragraph = Paragraph::new(imported_timestamp).wrap(trim);
f.render_widget(paragraph, content_layout[9]);
let paragraph = Paragraph::new(excess).wrap(trim);
f.render_widget(paragraph, content_layout[10]);
let paragraph = Paragraph::new(confirmations).wrap(trim);
f.render_widget(paragraph, content_layout[11]);
f.render_widget(paragraph, content_layout[10]);
let paragraph = Paragraph::new(mined_height).wrap(trim);
f.render_widget(paragraph, content_layout[12]);
f.render_widget(paragraph, content_layout[11]);
let paragraph = Paragraph::new(maturity).wrap(trim);
f.render_widget(paragraph, content_layout[13]);
f.render_widget(paragraph, content_layout[12]);
let paragraph = Paragraph::new(payment_id).wrap(trim);
f.render_widget(paragraph, content_layout[14]);
f.render_widget(paragraph, content_layout[13]);
}
}
}
Expand All @@ -489,7 +486,7 @@ impl<B: Backend> Component<B> for TransactionsTab {
Constraint::Length(3),
Constraint::Length(1),
Constraint::Min(9),
Constraint::Length(17),
Constraint::Length(16),
]
.as_ref(),
)
Expand Down
28 changes: 21 additions & 7 deletions applications/minotari_console_wallet/src/ui/state/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,10 @@ impl AppState {
}

// Return alias or pub key if the contact is not in the list.
pub fn get_alias(&self, address: &TariAddress) -> String {
let address_string = address.to_base58();
pub fn get_alias(&self, address_string: String) -> String {
if address_string == TariAddress::default().to_base58() {
return "Offline payment".to_string();
}

match self
.cached_data
Expand Down Expand Up @@ -1186,21 +1188,31 @@ pub struct CompletedTransactionInfo {
pub inputs_count: usize,
pub outputs_count: usize,
pub payment_id: Option<PaymentId>,
pub coinbase: bool,
pub burn: bool,
}

impl CompletedTransactionInfo {
pub fn from_completed_transaction(
tx: CompletedTransaction,
transaction_weighting: &TransactionWeight,
) -> Result<Self, TransactionError> {
let excess_signature = tx
.transaction
.first_kernel_excess_sig()
.map(|s| s.get_signature().to_hex())
.unwrap_or_default();
let excess_signature = format!(
"{},{}",
tx.transaction
.first_kernel_excess_sig()
.map(|s| s.get_signature().to_hex())
.unwrap_or_default(),
tx.transaction
.first_kernel_excess_sig()
.map(|s| s.get_public_nonce().to_hex())
.unwrap_or_default()
);
let weight = tx.transaction.calculate_weight(transaction_weighting)?;
let inputs_count = tx.transaction.body.inputs().len();
let outputs_count = tx.transaction.body.outputs().len();
let coinbase = tx.transaction.body.contains_coinbase();
let burn = tx.transaction.body.contains_burn();

Ok(Self {
tx_id: tx.tx_id,
Expand All @@ -1227,6 +1239,8 @@ impl CompletedTransactionInfo {
inputs_count,
outputs_count,
payment_id: tx.payment_id,
coinbase,
burn,
})
}
}
Expand Down
12 changes: 12 additions & 0 deletions base_layer/core/src/transactions/aggregated_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,18 @@ impl AggregateBody {
kernels: self.kernels.clone(),
}
}

// Searches though all outputs to see if it contains a burned feature flag
pub fn contains_burn(&self) -> bool {
self.outputs.iter().any(|k| k.features.output_type == OutputType::Burn)
}

// Searches though all outputs to see if it contains a coinbase feature flag
pub fn contains_coinbase(&self) -> bool {
self.outputs
.iter()
.any(|k| k.features.output_type == OutputType::Coinbase)
}
}

impl PartialEq for AggregateBody {
Expand Down
6 changes: 4 additions & 2 deletions base_layer/core/src/transactions/key_manager/initializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::sync::Arc;

use tari_common_types::{types::PublicKey, wallet_types::WalletType};
use tari_key_manager::{
cipher_seed::CipherSeed,
Expand All @@ -44,7 +46,7 @@ where T: KeyManagerBackend<PublicKey>
backend: Option<T>,
master_seed: CipherSeed,
crypto_factories: CryptoFactories,
wallet_type: WalletType,
wallet_type: Arc<WalletType>,
}

impl<T> TransactionKeyManagerInitializer<T>
Expand All @@ -55,7 +57,7 @@ where T: KeyManagerBackend<PublicKey> + 'static
backend: T,
master_seed: CipherSeed,
crypto_factories: CryptoFactories,
wallet_type: WalletType,
wallet_type: Arc<WalletType>,
) -> Self {
Self {
backend: Some(backend),
Expand Down
Loading

0 comments on commit 574fa1e

Please sign in to comment.