@@ -22,10 +22,14 @@ pub mod slip77;
2222
2323use std:: fmt;
2424
25+ use bitcoin:: bip32;
2526use elements:: secp256k1_zkp;
2627
2728use crate :: descriptor:: checksum:: { desc_checksum, verify_checksum} ;
28- use crate :: descriptor:: { DescriptorSecretKey , DescriptorPublicKey } ;
29+ use crate :: descriptor:: {
30+ ConversionError , DefiniteDescriptorKey , DescriptorSecretKey , DescriptorPublicKey ,
31+ DescriptorXKey , Wildcard
32+ } ;
2933use crate :: expression:: FromTree ;
3034use crate :: extensions:: { CovExtArgs , CovenantExt , Extension , ParseableExt } ;
3135use crate :: { expression, Error , MiniscriptKey , ToPublicKey } ;
@@ -82,6 +86,51 @@ impl<Pk: MiniscriptKey, T: Extension> Descriptor<Pk, T> {
8286 }
8387}
8488
89+ impl < T : Extension + ParseableExt > Descriptor < DescriptorPublicKey , T > {
90+ /// Replaces all wildcards (i.e. `/*`) in the descriptor and the descriptor blinding key
91+ /// with a particular derivation index, turning it into a *definite* descriptor.
92+ ///
93+ /// # Errors
94+ /// - If index ≥ 2^31
95+ pub fn at_derivation_index ( & self , index : u32 ) -> Result < Descriptor < DefiniteDescriptorKey , T > , ConversionError > {
96+ let definite_key = match self . key . clone ( ) {
97+ Key :: Slip77 ( k) => Key :: Slip77 ( k) ,
98+ Key :: Bare ( k) => Key :: Bare ( k. at_derivation_index ( index) ?. into_descriptor_public_key ( ) ) ,
99+ Key :: View ( k) => Key :: View ( match k {
100+ // Consider implementing DescriptorSecretKey::at_derivation_index
101+ DescriptorSecretKey :: Single ( _) => k,
102+ DescriptorSecretKey :: XPrv ( xprv) => {
103+ let derivation_path = match xprv. wildcard {
104+ Wildcard :: None => xprv. derivation_path ,
105+ Wildcard :: Unhardened => xprv. derivation_path . into_child (
106+ bip32:: ChildNumber :: from_normal_idx ( index)
107+ . ok ( )
108+ . ok_or ( ConversionError :: HardenedChild ) ?,
109+ ) ,
110+ Wildcard :: Hardened => xprv. derivation_path . into_child (
111+ bip32:: ChildNumber :: from_hardened_idx ( index)
112+ . ok ( )
113+ . ok_or ( ConversionError :: HardenedChild ) ?,
114+ ) ,
115+ } ;
116+ DescriptorSecretKey :: XPrv ( DescriptorXKey {
117+ origin : xprv. origin ,
118+ xkey : xprv. xkey ,
119+ derivation_path,
120+ wildcard : Wildcard :: None ,
121+ } )
122+ } ,
123+ DescriptorSecretKey :: MultiXPrv ( _) => return Err ( ConversionError :: MultiKey ) ,
124+ } ) ,
125+ } ;
126+ let definite_descriptor = self . descriptor . at_derivation_index ( index) ?;
127+ Ok ( Descriptor {
128+ key : definite_key,
129+ descriptor : definite_descriptor,
130+ } )
131+ }
132+ }
133+
85134impl < Pk : MiniscriptKey + ToPublicKey , T : Extension + ParseableExt > Descriptor < Pk , T > {
86135 /// Obtains the unblinded address for this descriptor.
87136 pub fn unconfidential_address (
0 commit comments