diff --git a/gui/src/app/cache.rs b/gui/src/app/cache.rs index 146afeba..693fc8ca 100644 --- a/gui/src/app/cache.rs +++ b/gui/src/app/cache.rs @@ -1,8 +1,20 @@ use crate::daemon::model::{Coin, SpendTx}; +use minisafe::miniscript::bitcoin::Network; -#[derive(Default)] pub struct Cache { + pub network: Network, pub blockheight: i32, pub coins: Vec, pub spend_txs: Vec, } + +impl std::default::Default for Cache { + fn default() -> Self { + Self { + network: Network::Bitcoin, + blockheight: 0, + coins: Vec::new(), + spend_txs: Vec::new(), + } + } +} diff --git a/gui/src/app/state/spend/detail.rs b/gui/src/app/state/spend/detail.rs index e3388ae2..a1e01de8 100644 --- a/gui/src/app/state/spend/detail.rs +++ b/gui/src/app/state/spend/detail.rs @@ -91,12 +91,13 @@ impl SpendTxState { } } - pub fn view<'a>(&'a self, _cache: &'a Cache) -> Element<'a, view::Message> { + pub fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> { detail::spend_view( self.action.warning(), &self.tx, self.action.view(), self.saved, + cache.network, ) } } diff --git a/gui/src/app/view/spend/detail.rs b/gui/src/app/view/spend/detail.rs index 5fdf2e49..dd72aed3 100644 --- a/gui/src/app/view/spend/detail.rs +++ b/gui/src/app/view/spend/detail.rs @@ -3,14 +3,17 @@ use iced::{ Alignment, Length, }; -use minisafe::miniscript::bitcoin::util::bip32::Fingerprint; +use minisafe::miniscript::bitcoin::{ + util::{bip32::Fingerprint, psbt::Psbt}, + Address, Amount, Network, +}; use crate::{ app::{ error::Error, view::{message::*, modal_section, warning::warn, ModalSectionStyle}, }, - daemon::model::{SpendStatus, SpendTx}, + daemon::model::{Coin, SpendStatus, SpendTx}, hw::HardwareWallet, ui::{ color, @@ -28,6 +31,7 @@ pub fn spend_view<'a, T: Into>>( tx: &SpendTx, action: T, show_delete: bool, + network: Network, ) -> Element<'a, Message> { spend_modal( show_delete, @@ -35,7 +39,13 @@ pub fn spend_view<'a, T: Into>>( column() .spacing(20) .push(spend_overview_view(tx)) - .push(action), + .push(action) + .push(inputs_and_outputs_view( + &tx.coins, + &tx.psbt, + network, + tx.change_index, + )), ) } @@ -225,6 +235,82 @@ fn spend_overview_view<'a>(tx: &SpendTx) -> Element<'a, Message> { .into() } +fn inputs_and_outputs_view<'a>( + coins: &[Coin], + psbt: &Psbt, + network: Network, + change_index: Option, +) -> Element<'a, Message> { + column() + .push( + row() + .spacing(10) + .push( + column() + .spacing(10) + .push(text("Spent coins:").bold()) + .push(coins.iter().fold(column().spacing(10), |col, coin| { + col.push( + card::simple( + column() + .width(Length::Fill) + .push(text(&format!("{} BTC", coin.amount.to_btc())).bold()) + .push(text(&format!("{}", coin.outpoint)).small()), + ) + .width(Length::Fill), + ) + })) + .width(Length::FillPortion(1)), + ) + .push( + column() + .spacing(10) + .push(text("Recipients:").bold()) + .push(psbt.unsigned_tx.output.iter().enumerate().fold( + column().spacing(10), + |col, (i, output)| { + col.push( + card::simple( + column() + .width(Length::Fill) + .push( + text(&format!( + "{} BTC", + Amount::from_sat(output.value).to_btc() + )) + .bold(), + ) + .push( + text(&format!( + "{}", + Address::from_script( + &output.script_pubkey, + network + ) + .unwrap() + )) + .small(), + ) + .push_maybe(if Some(i) == change_index { + Some( + container(text("Change")) + .padding(5) + .style(badge::PillStyle::Success), + ) + } else { + None + }), + ) + .width(Length::Fill), + ) + }, + )) + .width(Length::FillPortion(1)), + ), + ) + .into() +} + pub fn sign_action<'a>( hws: &[HardwareWallet], processing: bool, diff --git a/gui/src/main.rs b/gui/src/main.rs index c0980818..a5cafea8 100644 --- a/gui/src/main.rs +++ b/gui/src/main.rs @@ -163,6 +163,7 @@ impl Application for GUI { (State::Loader(loader), Message::Load(msg)) => { if let loader::Message::Synced(info, coins, spend_txs, minisafed) = *msg { let cache = Cache { + network: minisafed.config().bitcoin_config.network, blockheight: info.blockheight, coins, spend_txs,