Skip to content

Commit 3efa761

Browse files
committed
gui(spend): display warnings for draft PSBTs
1 parent a34070d commit 3efa761

File tree

3 files changed

+42
-20
lines changed

3 files changed

+42
-20
lines changed

gui/src/app/message.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub enum Message {
2929
Coins(Result<Vec<Coin>, Error>),
3030
Labels(Result<HashMap<String, String>, Error>),
3131
SpendTxs(Result<Vec<SpendTx>, Error>),
32-
Psbt(Result<Psbt, Error>),
32+
Psbt(Result<(Psbt, Vec<String>), Error>),
3333
Recovery(Result<SpendTx, Error>),
3434
Signed(Fingerprint, Result<Psbt, Error>),
3535
WalletRegistered(Result<Fingerprint, Error>),

gui/src/app/state/spend/step.rs

+25-19
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub struct TransactionDraft {
3232
network: Network,
3333
inputs: Vec<Coin>,
3434
recipients: Vec<Recipient>,
35-
generated: Option<Psbt>,
35+
generated: Option<(Psbt, Vec<String>)>,
3636
batch_label: Option<String>,
3737
labels: HashMap<String, String>,
3838
}
@@ -83,7 +83,7 @@ pub struct DefineSpend {
8383
batch_label: form::Value<String>,
8484
amount_left_to_select: Option<Amount>,
8585
feerate: form::Value<String>,
86-
generated: Option<Psbt>,
86+
generated: Option<(Psbt, Vec<String>)>,
8787
warning: Option<Error>,
8888
}
8989

@@ -384,7 +384,9 @@ impl Step for DefineSpend {
384384
.create_spend_tx(&inputs, &outputs, feerate_vb)
385385
.map_err(|e| e.into())
386386
.and_then(|res| match res {
387-
CreateSpendResult::Success { psbt, .. } => Ok(psbt),
387+
CreateSpendResult::Success { psbt, warnings } => {
388+
Ok((psbt, warnings))
389+
}
388390
CreateSpendResult::InsufficientFunds { missing } => {
389391
Err(SpendCreationError::CoinSelection(
390392
liana::spend::InsufficientFunds { missing },
@@ -438,7 +440,7 @@ impl Step for DefineSpend {
438440
.filter_map(|(coin, selected)| if *selected { Some(coin) } else { None })
439441
.cloned()
440442
.collect();
441-
if let Some(psbt) = &self.generated {
443+
if let Some((psbt, _)) = &self.generated {
442444
draft.labels = self.coins_labels.clone();
443445
for (i, output) in psbt.unsigned_tx.output.iter().enumerate() {
444446
if let Some(label) = self
@@ -583,7 +585,7 @@ impl Recipient {
583585

584586
pub struct SaveSpend {
585587
wallet: Arc<Wallet>,
586-
spend: Option<psbt::PsbtState>,
588+
spend: Option<(psbt::PsbtState, Vec<String>)>,
587589
curve: secp256k1::Secp256k1<secp256k1::VerifyOnly>,
588590
}
589591

@@ -599,7 +601,7 @@ impl SaveSpend {
599601

600602
impl Step for SaveSpend {
601603
fn load(&mut self, draft: &TransactionDraft) {
602-
let psbt = draft.generated.clone().unwrap();
604+
let (psbt, warnings) = draft.generated.clone().unwrap();
603605
let mut tx = SpendTx::new(
604606
None,
605607
psbt,
@@ -623,12 +625,15 @@ impl Step for SaveSpend {
623625
}
624626
}
625627

626-
self.spend = Some(psbt::PsbtState::new(self.wallet.clone(), tx, false));
628+
self.spend = Some((
629+
psbt::PsbtState::new(self.wallet.clone(), tx, false),
630+
warnings,
631+
));
627632
}
628633

629634
fn subscription(&self) -> Subscription<Message> {
630-
if let Some(spend) = &self.spend {
631-
spend.subscription()
635+
if let Some((psbt_state, _)) = &self.spend {
636+
psbt_state.subscription()
632637
} else {
633638
Subscription::none()
634639
}
@@ -640,26 +645,27 @@ impl Step for SaveSpend {
640645
cache: &Cache,
641646
message: Message,
642647
) -> Command<Message> {
643-
if let Some(spend) = &mut self.spend {
644-
spend.update(daemon, cache, message)
648+
if let Some((psbt_state, _)) = &mut self.spend {
649+
psbt_state.update(daemon, cache, message)
645650
} else {
646651
Command::none()
647652
}
648653
}
649654

650655
fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> {
651-
let spend = self.spend.as_ref().unwrap();
656+
let (psbt_state, warnings) = self.spend.as_ref().unwrap();
652657
let content = view::spend::spend_view(
653658
cache,
654-
&spend.tx,
655-
spend.saved,
656-
&spend.desc_policy,
657-
&spend.wallet.keys_aliases,
658-
spend.labels_edited.cache(),
659+
&psbt_state.tx,
660+
warnings,
661+
psbt_state.saved,
662+
&psbt_state.desc_policy,
663+
&psbt_state.wallet.keys_aliases,
664+
psbt_state.labels_edited.cache(),
659665
cache.network,
660-
spend.warning.as_ref(),
666+
psbt_state.warning.as_ref(),
661667
);
662-
if let Some(action) = &spend.action {
668+
if let Some(action) = &psbt_state.action {
663669
action.as_ref().view(content)
664670
} else {
665671
content

gui/src/app/view/spend/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::{
3333
pub fn spend_view<'a>(
3434
cache: &'a Cache,
3535
tx: &'a SpendTx,
36+
spend_warnings: &'a Vec<String>,
3637
saved: bool,
3738
desc_info: &'a LianaPolicy,
3839
key_aliases: &'a HashMap<Fingerprint, String>,
@@ -48,6 +49,21 @@ pub fn spend_view<'a>(
4849
.spacing(20)
4950
.push(Container::new(h3("Send")).width(Length::Fill))
5051
.push(psbt::spend_header(tx, labels_editing))
52+
.push_maybe(if spend_warnings.is_empty() || saved {
53+
None
54+
} else {
55+
Some(spend_warnings.iter().fold(
56+
Column::new().padding(15).spacing(5),
57+
|col, warning| {
58+
col.push(
59+
Row::new()
60+
.spacing(5)
61+
.push(icon::warning_icon().style(color::ORANGE))
62+
.push(text(warning).style(color::ORANGE)),
63+
)
64+
},
65+
))
66+
})
5167
.push(psbt::spend_overview_view(tx, desc_info, key_aliases))
5268
.push(
5369
Column::new()

0 commit comments

Comments
 (0)