installer: add backup descriptor step

This commit is contained in:
edouard 2022-11-25 16:08:15 +01:00
parent b260ac4208
commit 8348ad1afa
6 changed files with 86 additions and 7 deletions

View File

@ -8,6 +8,7 @@ use crate::hw::HardwareWallet;
pub enum Message {
CreateWallet,
ImportWallet,
BackupDone(bool),
Event(iced_native::Event),
Exit(PathBuf),
Clibpboard(String),

View File

@ -1,5 +1,6 @@
mod config;
mod message;
mod prompt;
mod step;
mod view;
@ -17,8 +18,8 @@ use crate::{
pub use message::Message;
use step::{
Context, DefineBitcoind, DefineDescriptor, Final, ImportDescriptor, RegisterDescriptor, Step,
Welcome,
BackupDescriptor, Context, DefineBitcoind, DefineDescriptor, Final, ImportDescriptor,
RegisterDescriptor, Step, Welcome,
};
pub struct Installer {
@ -101,6 +102,7 @@ impl Installer {
self.steps = vec![
Welcome::default().into(),
DefineDescriptor::new().into(),
BackupDescriptor::default().into(),
RegisterDescriptor::default().into(),
DefineBitcoind::new().into(),
Final::new().into(),

View File

@ -0,0 +1,2 @@
pub const BACKUP_DESCRIPTOR_MESSAGE: &str = "The descriptor is necessary to recover your funds.\nThe backup of your key (via mnemonics, sometimes called 'seed words') is not enough.\nPlease make sure you have backed up both your private key and your descriptor.";
pub const BACKUP_DESCRIPTOR_HELP: &str = "In Bitcoin, the coins are locked using a Script (related to the 'address'). In order to recover your funds you need both to know the Scripts you have participated in (your 'addresses'), and be able to sign a transaction that spends from those. For the ability to sign you backup your private key, this is your mnemonics ('seed words'). For finding the coins that belongs to you you backup a template of your Script ( / 'addresses'), this is your descriptor. Note however the descriptor needs not be as securely stored as the private key. A thief that steals your descriptor but not your private key will not be able to steal your funds.";

View File

@ -503,3 +503,31 @@ impl From<RegisterDescriptor> for Box<dyn Step> {
Box::new(s)
}
}
#[derive(Default)]
pub struct BackupDescriptor {
done: bool,
descriptor: Option<MultipathDescriptor>,
}
impl Step for BackupDescriptor {
fn update(&mut self, message: Message) -> Command<Message> {
if let Message::BackupDone(done) = message {
self.done = done;
}
Command::none()
}
fn load_context(&mut self, ctx: &Context) {
self.descriptor = ctx.descriptor.clone();
}
fn view(&self) -> Element<Message> {
let desc = self.descriptor.as_ref().unwrap();
view::backup_descriptor(desc.to_string(), self.done)
}
}
impl From<BackupDescriptor> for Box<dyn Step> {
fn from(s: BackupDescriptor) -> Box<dyn Step> {
Box::new(s)
}
}

View File

@ -1,5 +1,5 @@
mod descriptor;
pub use descriptor::{DefineDescriptor, ImportDescriptor, RegisterDescriptor};
pub use descriptor::{BackupDescriptor, DefineDescriptor, ImportDescriptor, RegisterDescriptor};
use std::path::PathBuf;
use std::str::FromStr;

View File

@ -1,4 +1,4 @@
use iced::widget::{Button, Column, Container, PickList, Row, Scrollable};
use iced::widget::{Button, Checkbox, Column, Container, PickList, Row, Scrollable};
use iced::{Alignment, Element, Length};
use liana::miniscript::bitcoin;
@ -217,9 +217,9 @@ pub fn define_descriptor<'a>(
.spacing(20),
)
.push(
if !user_xpub.value.is_empty()
|| !heir_xpub.value.is_empty()
|| !sequence.value.is_empty()
if user_xpub.value.is_empty()
&& heir_xpub.value.is_empty()
&& sequence.value.is_empty()
{
button::primary(None, "Next").width(Length::Units(200))
} else {
@ -364,6 +364,52 @@ pub fn register_descriptor<'a>(
)
}
pub fn backup_descriptor<'a>(descriptor: String, done: bool) -> Element<'a, Message> {
layout(
Column::new()
.push(
text("Did you backup your wallet descriptor ?")
.bold()
.size(50),
)
.push(text(super::prompt::BACKUP_DESCRIPTOR_MESSAGE))
.push(card::simple(
Column::new()
.push(text("The descriptor:").small().bold())
.push(text(descriptor.clone()).small())
.push(
Row::new().push(Column::new().width(Length::Fill)).push(
button::transparent_border(Some(icon::clipboard_icon()), "Copy")
.on_press(Message::Clibpboard(descriptor)),
),
)
.spacing(10),
))
.push(Checkbox::new(
done,
"I have backed up my descriptor",
Message::BackupDone,
))
.push(if done {
button::primary(None, "Next")
.on_press(Message::Next)
.width(Length::Units(200))
} else {
button::primary(None, "Next").width(Length::Units(200))
})
.push(
Column::new()
.push(text("Help:").bold())
.push(text(super::prompt::BACKUP_DESCRIPTOR_HELP).small()),
)
.width(Length::Fill)
.height(Length::Fill)
.padding(100)
.spacing(50)
.align_items(Alignment::Center),
)
}
pub fn define_bitcoin<'a>(
address: &form::Value<String>,
cookie_path: &form::Value<String>,