import: implement wallet_from_backup()

This commit is contained in:
pythcoiner 2025-03-12 13:07:38 +01:00
parent 03476de35a
commit aa53c3e44e
No known key found for this signature in database
GPG Key ID: C1048AEEDF303B88
2 changed files with 93 additions and 2 deletions

View File

@ -49,6 +49,7 @@ impl ExportModal {
ImportExportType::ImportPsbt => "Import PSBT",
ImportExportType::ImportDescriptor => "Import Descriptor",
ImportExportType::ImportBackup(..) => "Restore Backup",
ImportExportType::WalletFromBackup => "Import existing wallet from backup",
}
}
@ -71,9 +72,12 @@ impl ExportModal {
ImportExportType::ImportPsbt => "psbt.psbt".into(),
ImportExportType::ImportDescriptor => "descriptor.descriptor".into(),
ImportExportType::ExportLabels => format!("liana-labels-{date}.jsonl"),
ImportExportType::ExportBackup(_) | ImportExportType::ImportBackup(_, _) => {
ImportExportType::ExportBackup(_) => {
format!("liana-backup-{date}.json")
}
ImportExportType::WalletFromBackup | ImportExportType::ImportBackup(_, _) => {
"liana-backup.json".to_string()
}
}
}
@ -132,6 +136,7 @@ impl ExportModal {
ImportExportMessage::UpdateAliases(map.clone()).into()
});
}
Progress::WalletFromBackup(_) => {}
},
ImportExportMessage::TimedOut => {
self.stop(ImportExportState::TimedOut);

View File

@ -16,7 +16,7 @@ use async_hwi::bitbox::api::btc::Fingerprint;
use chrono::{DateTime, Duration, Utc};
use liana::{
descriptors::LianaDescriptor,
miniscript::bitcoin::{Amount, Psbt, Txid},
miniscript::bitcoin::{Amount, Network, Psbt, Txid},
};
use lianad::{
bip329::{error::ExportError, Labels},
@ -195,6 +195,7 @@ pub enum ImportExportType {
ExportLabels,
ImportPsbt,
ImportDescriptor,
WalletFromBackup,
}
impl ImportExportType {
@ -207,6 +208,7 @@ impl ImportExportType {
| ImportExportType::ExportLabels => "Export successful!",
ImportExportType::ImportBackup(_, _)
| ImportExportType::ImportPsbt
| ImportExportType::WalletFromBackup
| ImportExportType::ImportDescriptor => "Import successful",
}
}
@ -270,6 +272,14 @@ pub enum Progress {
LabelsConflict(SyncSender<bool>),
KeyAliasesConflict(SyncSender<bool>),
UpdateAliases(HashMap<Fingerprint, settings::KeySetting>),
WalletFromBackup(
(
LianaDescriptor,
Network,
HashMap<Fingerprint, String>,
Backup,
),
),
}
pub struct Export {
@ -305,6 +315,7 @@ impl Export {
path: PathBuf,
) {
match export_type {
ImportExportType::WalletFromBackup => wallet_from_backup(sender, path).await,
ImportExportType::Transactions => export_transactions(sender, daemon, path).await,
ImportExportType::ExportPsbt(str) => export_string(sender, path, str),
ImportExportType::Descriptor(descriptor) => export_descriptor(sender, path, descriptor),
@ -1021,6 +1032,81 @@ impl From<DaemonError> for RestoreBackupError {
}
}
/// Create a wallet from a backup
/// - load backup from file
/// - extract descriptor
/// - extract network
/// - extract aliases
pub async fn wallet_from_backup(sender: Sender<Progress>, path: PathBuf) {
// Load backup from file
let mut file = open_file_read!(path, sender);
let mut backup_str = String::new();
if let Err(e) = file.read_to_string(&mut backup_str) {
send_error!(sender, e.into());
return;
}
let backup: Result<Backup, _> = serde_json::from_str(&backup_str);
let backup = match backup {
Ok(psbt) => psbt,
Err(e) => {
send_error!(sender, Error::BackupImport(format!("{:?}", e)));
return;
}
};
let network = backup.network;
let account = match backup.accounts.len() {
0 => {
send_error!(
sender,
Error::BackupImport("There is no account in the backup!".into())
);
return;
}
1 => backup.accounts.first().expect("already checked"),
_ => {
send_error!(
sender,
Error::BackupImport(
"Liana is actually not supporting import of backup with several accounts!"
.into()
)
);
return;
}
};
let descriptor = match LianaDescriptor::from_str(&account.descriptor) {
Ok(d) => d,
Err(_) => {
send_error!(
sender,
Error::BackupImport(
"The backup descriptor is not a valid Liana descriptor!".into()
)
);
return;
}
};
let mut aliases: HashMap<Fingerprint, String> = HashMap::new();
for (k, v) in &account.keys {
if let Some(alias) = &v.alias {
aliases.insert(*k, alias.clone());
}
}
send_progress!(
sender,
WalletFromBackup((descriptor, network, aliases, backup))
);
send_progress!(sender, Progress(100.0));
send_progress!(sender, Ended);
}
#[allow(unused)]
/// Import backup data if wallet created from a backup
/// - check if networks matches