From a9dfdd8f9b1de6a136bcf5dbb0e1c83b1c151714 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 5 Jan 2024 13:57:10 +0100 Subject: [PATCH 1/2] descriptor: support WPKH descriptors --- cli/src/args.rs | 10 ++++++++-- src/descriptor.rs | 21 +++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/cli/src/args.rs b/cli/src/args.rs index 0ebf6ae..32be798 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -22,28 +22,34 @@ #![allow(clippy::needless_update)] // Caused by the From derivation macro use bp_util::{Config, DescriptorOpts}; -use bpstd::XpubDerivable; +use bpstd::{Wpkh, XpubDerivable}; use rgb_rt::{Resolver, ResolverError, RgbDescr, Runtime, RuntimeError, TapretKey}; use crate::Command; #[derive(Args, Clone, PartialEq, Eq, Debug)] +#[group()] pub struct DescrRgbOpts { /// Use tapret(KEY) descriptor as wallet. #[arg(long, global = true)] pub tapret_key_only: Option, + + /// Use wpkh(KEY) descriptor as wallet. + #[arg(long, global = true)] + pub wpkh: Option, } impl DescriptorOpts for DescrRgbOpts { type Descr = RgbDescr; - fn is_some(&self) -> bool { self.tapret_key_only.is_some() } + fn is_some(&self) -> bool { self.tapret_key_only.is_some() || self.wpkh.is_some() } fn descriptor(&self) -> Option { self.tapret_key_only .clone() .map(TapretKey::from) .map(TapretKey::into) + .or(self.wpkh.clone().map(Wpkh::from).map(Wpkh::into)) } } diff --git a/src/descriptor.rs b/src/descriptor.rs index f46442d..8aacb18 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -33,7 +33,7 @@ use bpstd::{ TapTree, Terminal, XOnlyPk, XpubDerivable, XpubSpec, }; use commit_verify::CommitVerify; -use descriptors::{Descriptor, SpkClass, StdDescr, TrKey}; +use descriptors::{Descriptor, SpkClass, StdDescr, TrKey, Wpkh}; use indexmap::IndexMap; #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)] @@ -229,11 +229,13 @@ impl DescriptorRgb for TapretKey { crate = "serde_crate", rename_all = "camelCase", bound( - serialize = "S::XOnly: serde::Serialize", - deserialize = "S::XOnly: serde::Deserialize<'de>" + serialize = "S::Compr: serde::Serialize, S::XOnly: serde::Serialize", + deserialize = "S::Compr: serde::Deserialize<'de>, S::XOnly: serde::Deserialize<'de>" ) )] pub enum RgbDescr { + #[from] + Wpkh(Wpkh), #[from] TapretKey(TapretKey), } @@ -241,18 +243,21 @@ pub enum RgbDescr { impl Derive for RgbDescr { fn default_keychain(&self) -> Keychain { match self { + RgbDescr::Wpkh(d) => d.default_keychain(), RgbDescr::TapretKey(d) => d.default_keychain(), } } fn keychains(&self) -> BTreeSet { match self { + RgbDescr::Wpkh(d) => d.keychains(), RgbDescr::TapretKey(d) => d.keychains(), } } fn derive(&self, change: impl Into, index: impl Into) -> DerivedScript { match self { + RgbDescr::Wpkh(d) => d.derive(change, index), RgbDescr::TapretKey(d) => d.derive(change, index), } } @@ -267,12 +272,14 @@ where Self: Derive fn class(&self) -> SpkClass { match self { + RgbDescr::Wpkh(d) => d.class(), RgbDescr::TapretKey(d) => d.class(), } } fn keys(&self) -> Self::KeyIter<'_> { match self { + RgbDescr::Wpkh(d) => d.keys().collect::>(), RgbDescr::TapretKey(d) => d.keys().collect::>(), } .into_iter() @@ -280,12 +287,14 @@ where Self: Derive fn vars(&self) -> Self::VarIter<'_> { match self { + RgbDescr::Wpkh(d) => d.vars(), RgbDescr::TapretKey(d) => d.vars(), } } fn xpubs(&self) -> Self::XpubIter<'_> { match self { + RgbDescr::Wpkh(d) => d.xpubs().collect::>(), RgbDescr::TapretKey(d) => d.xpubs().collect::>(), } .into_iter() @@ -293,12 +302,14 @@ where Self: Derive fn compr_keyset(&self, terminal: Terminal) -> IndexMap { match self { + RgbDescr::Wpkh(d) => d.compr_keyset(terminal), RgbDescr::TapretKey(d) => d.compr_keyset(terminal), } } fn xonly_keyset(&self, terminal: Terminal) -> IndexMap { match self { + RgbDescr::Wpkh(d) => d.xonly_keyset(terminal), RgbDescr::TapretKey(d) => d.xonly_keyset(terminal), } } @@ -310,6 +321,7 @@ where Self: Derive { fn seal_close_method(&self) -> CloseMethod { match self { + RgbDescr::Wpkh(_) => CloseMethod::OpretFirst, RgbDescr::TapretKey(d) => d.seal_close_method(), } } @@ -320,6 +332,7 @@ where Self: Derive tweak: TapretCommitment, ) -> Result<(), TapTweakAlreadyAssigned> { match self { + RgbDescr::Wpkh(_) => panic!("adding tapret tweak to non-taproot descriptor"), RgbDescr::TapretKey(d) => d.add_tapret_tweak(terminal, tweak), } } @@ -328,7 +341,7 @@ where Self: Derive impl From for RgbDescr { fn from(descr: StdDescr) -> Self { match descr { - StdDescr::Wpkh(_) => todo!(), + StdDescr::Wpkh(wpkh) => RgbDescr::Wpkh(wpkh), StdDescr::TrKey(tr) => RgbDescr::TapretKey(tr.into()), _ => todo!(), } From 0c38656b5c1b83411472af2a86cddc58cb99d35c Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 5 Jan 2024 14:00:12 +0100 Subject: [PATCH 2/2] descriptor: make RGB descriptor type non-exhaustive --- src/descriptor.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/descriptor.rs b/src/descriptor.rs index 8aacb18..75107e2 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -233,6 +233,7 @@ impl DescriptorRgb for TapretKey { deserialize = "S::Compr: serde::Deserialize<'de>, S::XOnly: serde::Deserialize<'de>" ) )] +#[non_exhaustive] pub enum RgbDescr { #[from] Wpkh(Wpkh),