Skip to content

Commit ef24341

Browse files
committed
installer: impl import encrypted backup/descriptor for liana-connect
1 parent 6135853 commit ef24341

File tree

1 file changed

+61
-41
lines changed

1 file changed

+61
-41
lines changed

liana-gui/src/installer/step/backend.rs

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
use crate::{
2+
decrypt::{Decrypt, DecryptModal},
3+
hw::HardwareWalletMessage,
4+
installer::step::import_descriptor::ImportDescriptorModal,
5+
};
16
use std::str::FromStr;
27

3-
use iced::{Subscription, Task};
8+
use iced::Task;
49

510
use liana::{descriptors::LianaDescriptor, miniscript::bitcoin::Network};
611
use liana_ui::{component::form, widget::Element};
@@ -25,6 +30,8 @@ use crate::{
2530
},
2631
};
2732

33+
use super::import_descriptor::BACKUP_NETWORK_NOT_MATCH;
34+
2835
pub struct ChooseBackend {
2936
network: Network,
3037
remote_backend_is_selected: bool,
@@ -451,7 +458,7 @@ pub struct ImportRemoteWallet {
451458
error: Option<String>,
452459
backend: context::RemoteBackend,
453460
wallets: Vec<api::Wallet>,
454-
modal: Option<ExportModal>,
461+
modal: ImportDescriptorModal,
455462
// wallet alias is stored here to be applied to context
456463
// and be modified in a following step
457464
wallet_alias: Option<String>,
@@ -468,7 +475,7 @@ impl ImportRemoteWallet {
468475
error: None,
469476
backend: context::RemoteBackend::Undefined,
470477
wallets: Vec::new(),
471-
modal: None,
478+
modal: ImportDescriptorModal::None,
472479
wallet_alias: None,
473480
}
474481
}
@@ -505,39 +512,65 @@ impl Step for ImportRemoteWallet {
505512
}
506513
// form value is set as valid each time it is edited.
507514
// Verification of the values is happening when the user click on Next button.
508-
fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task<Message> {
515+
fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task<Message> {
509516
match message {
510517
Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportDescriptorFromFile) => {
511-
let modal = ExportModal::new(None, ImportExportType::ImportDescriptor);
518+
let modal = ExportModal::new(None, ImportExportType::FromBackup);
512519
let launch = modal.launch(false);
513-
self.modal = Some(modal);
520+
self.modal = ImportDescriptorModal::Export(modal);
514521
return launch;
515522
}
516523
Message::ImportExport(ImportExportMessage::Path(p)) => {
517-
if let Some(modal) = self.modal.as_mut() {
518-
return modal.update(ImportExportMessage::Path(p));
524+
if self.modal.is_some() {
525+
return self
526+
.modal
527+
.update(Message::ImportExport(ImportExportMessage::Path(p)));
519528
}
520529
}
521-
Message::ImportExport(ImportExportMessage::Close) => self.modal = None,
522-
Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportExport(m)) => match m {
523-
ImportExportMessage::Close => self.modal = None,
524-
ImportExportMessage::Progress(Progress::Descriptor(d)) => {
525-
self.modal = None;
526-
return Task::batch([
527-
Task::done(Message::ImportRemoteWallet(
528-
message::ImportRemoteWallet::ImportDescriptor(d.to_string()),
529-
)),
530-
Task::done(Message::ImportRemoteWallet(
531-
message::ImportRemoteWallet::ConfirmDescriptor,
532-
)),
533-
]);
530+
Message::ImportExport(ImportExportMessage::Close) => {
531+
self.modal = ImportDescriptorModal::None
532+
}
533+
Message::ImportExport(ImportExportMessage::Progress(Progress::EncryptedFile(
534+
bytes,
535+
))) => {
536+
self.modal = ImportDescriptorModal::Decrypt(DecryptModal::new(bytes, self.network));
537+
}
538+
Message::ImportExport(m) => return self.modal.update(Message::ImportExport(m)),
539+
Message::HardwareWallets(HardwareWalletMessage::Update) => {
540+
if let ImportDescriptorModal::Decrypt(modal) = &mut self.modal {
541+
return modal.update_devices(hws).unwrap_or(Task::none());
534542
}
535-
m => {
536-
if let Some(modal) = self.modal.as_mut() {
537-
return modal.update(m);
543+
}
544+
Message::Decrypt(Decrypt::Close) => {
545+
if matches!(self.modal, ImportDescriptorModal::Decrypt(_)) {
546+
self.modal = ImportDescriptorModal::None;
547+
}
548+
}
549+
Message::Decrypt(Decrypt::Backup(mut backup)) => {
550+
let descriptor = backup.accounts.first().map(|acc| acc.descriptor.clone());
551+
if let Some(desc) = descriptor {
552+
let network_matches = if self.network == Network::Bitcoin {
553+
backup.network == Network::Bitcoin
554+
} else {
555+
backup.network != Network::Bitcoin
556+
};
557+
if network_matches {
558+
// NOTE: we need to overwrite w/ correct network for testnets
559+
// as non Mainnet keys / descriptor are parsed as Signet
560+
backup.network = self.network;
561+
562+
self.imported_descriptor.value = desc;
563+
self.modal = ImportDescriptorModal::None;
564+
return Task::perform(async {}, |_| Message::Next);
565+
} else {
566+
self.modal = ImportDescriptorModal::None;
567+
self.error = Some(BACKUP_NETWORK_NOT_MATCH.into());
538568
}
569+
} else {
570+
self.modal = ImportDescriptorModal::None;
571+
self.error = Some("Backup imported but descriptor missing!".into());
539572
}
540-
},
573+
}
541574
Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportDescriptor(desc)) => {
542575
self.imported_descriptor.value = desc;
543576
if !self.imported_descriptor.value.is_empty() {
@@ -679,17 +712,8 @@ impl Step for ImportRemoteWallet {
679712
Task::none()
680713
}
681714

682-
fn subscription(&self, _hws: &HardwareWallets) -> iced::Subscription<Message> {
683-
if let Some(modal) = &self.modal {
684-
if let Some(sub) = modal.subscription() {
685-
return sub.map(|m| {
686-
Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportExport(
687-
ImportExportMessage::Progress(m),
688-
))
689-
});
690-
}
691-
}
692-
Subscription::none()
715+
fn subscription(&self, hws: &HardwareWallets) -> iced::Subscription<Message> {
716+
self.modal.subscriptions(hws)
693717
}
694718

695719
fn apply(&mut self, ctx: &mut Context) -> bool {
@@ -725,11 +749,7 @@ impl Step for ImportRemoteWallet {
725749
.map(|w| (&w.name, w.metadata.wallet_alias.as_ref()))
726750
.collect(),
727751
);
728-
if let Some(modal) = &self.modal {
729-
modal.view(content)
730-
} else {
731-
content
732-
}
752+
self.modal.view(content)
733753
}
734754
}
735755

0 commit comments

Comments
 (0)