@@ -22,10 +22,14 @@ pub mod slip77;
22
22
23
23
use std:: fmt;
24
24
25
+ use bitcoin:: bip32;
25
26
use elements:: secp256k1_zkp;
26
27
27
28
use 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
+ } ;
29
33
use crate :: expression:: FromTree ;
30
34
use crate :: extensions:: { CovExtArgs , CovenantExt , Extension , ParseableExt } ;
31
35
use crate :: { expression, Error , MiniscriptKey , ToPublicKey } ;
@@ -82,6 +86,51 @@ impl<Pk: MiniscriptKey, T: Extension> Descriptor<Pk, T> {
82
86
}
83
87
}
84
88
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
+
85
134
impl < Pk : MiniscriptKey + ToPublicKey , T : Extension + ParseableExt > Descriptor < Pk , T > {
86
135
/// Obtains the unblinded address for this descriptor.
87
136
pub fn unconfidential_address (
0 commit comments