installer: add signer to participate wallet process
This commit is contained in:
parent
233f9b1886
commit
037c4d025d
@ -21,6 +21,7 @@ pub enum Message {
|
||||
Close,
|
||||
Reload,
|
||||
Select(usize),
|
||||
UseHotSigner,
|
||||
Installed(Result<PathBuf, Error>),
|
||||
Network(Network),
|
||||
DefineBitcoind(DefineBitcoind),
|
||||
@ -45,7 +46,6 @@ pub enum DefineDescriptor {
|
||||
HWXpubImported(Result<DescriptorPublicKey, Error>),
|
||||
XPubEdited(String),
|
||||
EditName,
|
||||
UseHotSigner,
|
||||
NameEdited(String),
|
||||
SequenceEdited(String),
|
||||
ThresholdEdited(bool, usize),
|
||||
|
||||
@ -658,7 +658,7 @@ impl DescriptorKeyModal for EditXpubModal {
|
||||
self.hws = Vec::new();
|
||||
return self.load();
|
||||
}
|
||||
Message::DefineDescriptor(message::DefineDescriptor::UseHotSigner) => {
|
||||
Message::UseHotSigner => {
|
||||
self.chosen_hw = None;
|
||||
self.chosen_signer = true;
|
||||
self.form_xpub.valid = true;
|
||||
@ -841,6 +841,12 @@ impl HardwareWalletXpubs {
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.error = None;
|
||||
self.next_account = ChildNumber::from_hardened_idx(0).unwrap();
|
||||
self.xpubs = Vec::new();
|
||||
}
|
||||
|
||||
fn select(&mut self, i: usize, network: Network) -> Command<Message> {
|
||||
if let HardwareWallet::Supported {
|
||||
device,
|
||||
@ -878,6 +884,42 @@ impl HardwareWalletXpubs {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SignerXpubs {
|
||||
signer: Arc<Signer>,
|
||||
xpubs: Vec<String>,
|
||||
next_account: ChildNumber,
|
||||
}
|
||||
|
||||
impl SignerXpubs {
|
||||
fn new(signer: Arc<Signer>) -> Self {
|
||||
Self {
|
||||
signer,
|
||||
xpubs: Vec::new(),
|
||||
next_account: ChildNumber::from_hardened_idx(0).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
self.xpubs = Vec::new();
|
||||
self.next_account = ChildNumber::from_hardened_idx(0).unwrap();
|
||||
}
|
||||
|
||||
fn select(&mut self, network: Network) {
|
||||
let derivation_path = generate_derivation_path(network, self.next_account);
|
||||
self.next_account = self.next_account.increment().unwrap();
|
||||
self.xpubs.push(format!(
|
||||
"[{}{}]{}/<0;1>/*",
|
||||
self.signer.fingerprint(),
|
||||
derivation_path.to_string().trim_start_matches('m'),
|
||||
self.signer.get_extended_pubkey(&derivation_path)
|
||||
));
|
||||
}
|
||||
|
||||
pub fn view(&self) -> Element<Message> {
|
||||
view::signer_xpubs(&self.xpubs)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ParticipateXpub {
|
||||
network: Network,
|
||||
network_valid: bool,
|
||||
@ -886,6 +928,7 @@ pub struct ParticipateXpub {
|
||||
shared: bool,
|
||||
|
||||
xpubs_hw: Vec<HardwareWalletXpubs>,
|
||||
xpubs_signer: SignerXpubs,
|
||||
}
|
||||
|
||||
impl ParticipateXpub {
|
||||
@ -896,8 +939,30 @@ impl ParticipateXpub {
|
||||
data_dir: None,
|
||||
xpubs_hw: Vec::new(),
|
||||
shared: false,
|
||||
xpubs_signer: SignerXpubs::new(Arc::new(Signer::generate(Network::Bitcoin).unwrap())),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_network(&mut self, network: Network) {
|
||||
if network != self.network {
|
||||
self.xpubs_hw.iter_mut().for_each(|hw| hw.reset());
|
||||
self.xpubs_signer.reset();
|
||||
}
|
||||
self.network = network;
|
||||
if let Some(signer) = Arc::get_mut(&mut self.xpubs_signer.signer) {
|
||||
signer.set_network(network);
|
||||
}
|
||||
if let Some(mut network_datadir) = self.data_dir.clone() {
|
||||
network_datadir.push(self.network.to_string());
|
||||
self.network_valid = !network_datadir.exists();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ParticipateXpub {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Step for ParticipateXpub {
|
||||
@ -906,10 +971,7 @@ impl Step for ParticipateXpub {
|
||||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::Network(network) => {
|
||||
self.network = network;
|
||||
let mut network_datadir = self.data_dir.clone().unwrap();
|
||||
network_datadir.push(self.network.to_string());
|
||||
self.network_valid = !network_datadir.exists();
|
||||
self.set_network(network);
|
||||
}
|
||||
Message::UserActionDone(shared) => self.shared = shared,
|
||||
Message::ImportXpub(i, res) => {
|
||||
@ -917,6 +979,9 @@ impl Step for ParticipateXpub {
|
||||
hw.update(res);
|
||||
}
|
||||
}
|
||||
Message::UseHotSigner => {
|
||||
self.xpubs_signer.select(self.network);
|
||||
}
|
||||
Message::Select(i) => {
|
||||
if let Some(hw) = self.xpubs_hw.get_mut(i) {
|
||||
return hw.select(i, self.network);
|
||||
@ -943,11 +1008,8 @@ impl Step for ParticipateXpub {
|
||||
}
|
||||
|
||||
fn load_context(&mut self, ctx: &Context) {
|
||||
self.network = ctx.bitcoin_config.network;
|
||||
self.data_dir = Some(ctx.data_dir.clone());
|
||||
let mut network_datadir = ctx.data_dir.clone();
|
||||
network_datadir.push(self.network.to_string());
|
||||
self.network_valid = !network_datadir.exists();
|
||||
self.set_network(ctx.bitcoin_config.network);
|
||||
}
|
||||
|
||||
fn load(&self) -> Command<Message> {
|
||||
@ -961,6 +1023,11 @@ impl Step for ParticipateXpub {
|
||||
ctx.bitcoin_config.network = self.network;
|
||||
// Drop connections to hardware wallets.
|
||||
self.xpubs_hw = Vec::new();
|
||||
if !self.xpubs_signer.xpubs.is_empty() {
|
||||
ctx.signer = Some(self.xpubs_signer.signer.clone());
|
||||
} else {
|
||||
ctx.signer = None;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@ -974,17 +1041,12 @@ impl Step for ParticipateXpub {
|
||||
.enumerate()
|
||||
.map(|(i, hw)| hw.view(i))
|
||||
.collect(),
|
||||
self.xpubs_signer.view(),
|
||||
self.shared,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ParticipateXpub {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParticipateXpub> for Box<dyn Step> {
|
||||
fn from(s: ParticipateXpub) -> Box<dyn Step> {
|
||||
Box::new(s)
|
||||
|
||||
@ -411,6 +411,76 @@ pub fn import_descriptor<'a>(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn signer_xpubs(xpubs: &Vec<String>) -> Element<Message> {
|
||||
Container::new(
|
||||
Column::new()
|
||||
.push(
|
||||
Button::new(
|
||||
Row::new().align_items(Alignment::Center).push(
|
||||
Column::new()
|
||||
.push(text("This computer").bold())
|
||||
.push(
|
||||
text("Derive a key from a mnemonic stored on this computer")
|
||||
.small(),
|
||||
)
|
||||
.spacing(5)
|
||||
.width(Length::Fill),
|
||||
),
|
||||
)
|
||||
.on_press(Message::UseHotSigner)
|
||||
.padding(10)
|
||||
.style(button::Style::TransparentBorder.into())
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push_maybe(if xpubs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(separation().width(Length::Fill))
|
||||
})
|
||||
.push_maybe(if xpubs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(xpubs.iter().fold(Column::new().padding(15), |col, xpub| {
|
||||
col.push(
|
||||
Row::new()
|
||||
.spacing(5)
|
||||
.align_items(Alignment::Center)
|
||||
.push(
|
||||
Container::new(
|
||||
Scrollable::new(Container::new(text(xpub).small()).padding(10))
|
||||
.horizontal_scroll(
|
||||
Properties::new().width(2).scroller_width(2),
|
||||
),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(
|
||||
Container::new(
|
||||
button::border(Some(icon::clipboard_icon()), "Copy")
|
||||
.on_press(Message::Clibpboard(xpub.clone()))
|
||||
.width(Length::Shrink),
|
||||
)
|
||||
.padding(10),
|
||||
),
|
||||
)
|
||||
}))
|
||||
})
|
||||
.push_maybe(if !xpubs.is_empty() {
|
||||
Some(
|
||||
Container::new(
|
||||
button::border(Some(icon::plus_icon()), "New public key")
|
||||
.on_press(Message::UseHotSigner),
|
||||
)
|
||||
.padding(10),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
)
|
||||
.style(card::SimpleCardStyle)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn hardware_wallet_xpubs<'a>(
|
||||
i: usize,
|
||||
xpubs: &'a Vec<String>,
|
||||
@ -531,13 +601,14 @@ pub fn hardware_wallet_xpubs<'a>(
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn participate_xpub(
|
||||
pub fn participate_xpub<'a>(
|
||||
progress: (usize, usize),
|
||||
network: bitcoin::Network,
|
||||
network_valid: bool,
|
||||
hws: Vec<Element<Message>>,
|
||||
hws: Vec<Element<'a, Message>>,
|
||||
signer: Element<'a, Message>,
|
||||
shared: bool,
|
||||
) -> Element<Message> {
|
||||
) -> Element<'a, Message> {
|
||||
let row_network = Row::new()
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
@ -583,6 +654,7 @@ pub fn participate_xpub(
|
||||
)
|
||||
.spacing(10)
|
||||
.push(Column::with_children(hws).spacing(10))
|
||||
.push(signer)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.push(Checkbox::new(
|
||||
@ -1138,7 +1210,7 @@ pub fn edit_key_modal<'a>(
|
||||
.spacing(5)
|
||||
.push(text("This computer").bold())
|
||||
.push(
|
||||
text("Derive a key from a mnemonic stored on the computer").small(),
|
||||
text("Derive a key from a mnemonic stored on this computer").small(),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
@ -1150,9 +1222,7 @@ pub fn edit_key_modal<'a>(
|
||||
.spacing(10),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.on_press(Message::DefineDescriptor(
|
||||
message::DefineDescriptor::UseHotSigner,
|
||||
))
|
||||
.on_press(Message::UseHotSigner)
|
||||
.style(button::Style::Border.into()),
|
||||
)
|
||||
.width(Length::Fill),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user