From 39df428117484b447258cf697b1ea3fb48082e42 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Tue, 30 Apr 2024 11:21:44 +0100 Subject: Improve wallet descriptor support --- src/wallets.rs | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/wallets.rs b/src/wallets.rs index 9ee702c..b7b6886 100644 --- a/src/wallets.rs +++ b/src/wallets.rs @@ -14,6 +14,7 @@ use bdk::{ KeychainKind, SyncOptions, TransactionDetails, Wallet, }; use log::{debug, error, warn}; +use regex::Regex; use serde::Deserialize; use crate::blockchain::{get_blockchain, ElectrumConfig}; @@ -48,11 +49,11 @@ impl XpubSpec { } } -#[derive(Deserialize, Debug, Hash)] +#[derive(Deserialize, Debug, Hash, Clone)] pub struct DescriptorsSpec { name: String, - primary: String, - change: Option, + descriptor: String, + change_descriptor: Option, } impl DescriptorsSpec { @@ -62,12 +63,12 @@ impl DescriptorsSpec { s.finish().to_string() } - pub fn primary(&self) -> &str { - &self.primary + pub fn descriptor(&self) -> &str { + &self.descriptor } - pub fn change(&self) -> Option<&String> { - self.change.as_ref() + pub fn change_descriptor(&self) -> Option<&str> { + self.change_descriptor.as_deref() } pub fn name(&self) -> &str { @@ -75,6 +76,23 @@ impl DescriptorsSpec { } } +fn handle_multipart_descritor(desc_spec: &DescriptorsSpec) -> Result { + if !desc_spec.descriptor().contains("<0;1>") { + return Ok(desc_spec.clone()); + } + + let desc_no_checksum = Regex::new("#[A-Za-z0-9]+$")?.replace(desc_spec.descriptor(), ""); + + let desc = desc_no_checksum.replace("<0;1>", "0"); + let change_desc = desc_no_checksum.replace("<0;1>", "1"); + + Ok(DescriptorsSpec { + name: desc_spec.name().to_string(), + descriptor: desc, + change_descriptor: Some(change_desc), + }) +} + #[derive(Deserialize, Debug)] #[serde(untagged)] pub enum WalletConfig { @@ -136,9 +154,10 @@ fn get_descriptors_wallet( network: Network, ) -> Result> { let sled = sled::open(get_cache_dir(&descriptors_spec.get_hash()))?.open_tree("wallet")?; + let desc_spec_no_multi = handle_multipart_descritor(descriptors_spec)?; Wallet::new( - descriptors_spec.primary(), - descriptors_spec.change().map(String::as_ref), + desc_spec_no_multi.descriptor(), + desc_spec_no_multi.change_descriptor(), network, sled, ) -- cgit v1.2.3-70-g09d2