1use crate::bitcoin::DescriptorId;
2use crate::bitcoin::DescriptorType;
3use crate::bitcoin::{Address, NetworkKind};
4use crate::error::DescriptorError;
5use crate::error::MiniscriptError;
6use crate::keys::DescriptorPublicKey;
7use crate::keys::DescriptorSecretKey;
8use crate::types::KeychainKind;
9
10use bdk_wallet::bitcoin::bip32::Fingerprint;
11use bdk_wallet::bitcoin::key::Secp256k1;
12use bdk_wallet::bitcoin::Network;
13use bdk_wallet::chain::DescriptorExt;
14use bdk_wallet::descriptor::{ExtendedDescriptor, IntoWalletDescriptor};
15use bdk_wallet::keys::DescriptorPublicKey as BdkDescriptorPublicKey;
16use bdk_wallet::keys::{DescriptorSecretKey as BdkDescriptorSecretKey, KeyMap};
17use bdk_wallet::miniscript::descriptor::{ConversionError, TapTree};
18use bdk_wallet::miniscript::Descriptor as BdkDescriptor;
19use bdk_wallet::miniscript::Miniscript as BdkMiniscript;
20use bdk_wallet::template::{
21 Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, Bip86, Bip86Public,
22 DescriptorTemplate,
23};
24
25use std::fmt::Display;
26use std::str::FromStr;
27use std::sync::Arc;
28
29#[derive(Debug, uniffi::Object)]
31#[uniffi::export(Debug, Display)]
32pub struct Descriptor {
33 pub extended_descriptor: ExtendedDescriptor,
34 pub key_map: KeyMap,
35}
36
37#[uniffi::export]
38impl Descriptor {
39 #[uniffi::constructor]
41 pub fn new(descriptor: String, network_kind: NetworkKind) -> Result<Self, DescriptorError> {
42 let secp = Secp256k1::new();
43 let (extended_descriptor, key_map) =
44 descriptor.into_wallet_descriptor(&secp, network_kind)?;
45 Ok(Self {
46 extended_descriptor,
47 key_map,
48 })
49 }
50
51 #[uniffi::constructor]
53 pub fn new_bip44(
54 secret_key: &DescriptorSecretKey,
55 keychain_kind: KeychainKind,
56 network_kind: NetworkKind,
57 ) -> Self {
58 let derivable_key = &secret_key.0;
59
60 match derivable_key {
61 BdkDescriptorSecretKey::Single(_) => {
62 unreachable!()
63 }
64 BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
65 let derivable_key = descriptor_x_key.xkey;
66 let (extended_descriptor, key_map, _) = Bip44(derivable_key, keychain_kind)
67 .build(network_kind)
68 .unwrap();
69 Self {
70 extended_descriptor,
71 key_map,
72 }
73 }
74 BdkDescriptorSecretKey::MultiXPrv(_) => {
75 unreachable!()
76 }
77 }
78 }
79
80 #[uniffi::constructor]
82 pub fn new_bip44_public(
83 public_key: &DescriptorPublicKey,
84 fingerprint: String,
85 keychain_kind: KeychainKind,
86 network_kind: NetworkKind,
87 ) -> Result<Self, DescriptorError> {
88 let fingerprint = Fingerprint::from_str(fingerprint.as_str()).map_err(|error| {
89 DescriptorError::Bip32 {
90 error_message: error.to_string(),
91 }
92 })?;
93 let derivable_key = &public_key.0;
94
95 match derivable_key {
96 BdkDescriptorPublicKey::Single(_) => {
97 unreachable!()
98 }
99 BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
100 let derivable_key = descriptor_x_key.xkey;
101 let (extended_descriptor, key_map, _) =
102 Bip44Public(derivable_key, fingerprint, keychain_kind)
103 .build(network_kind)
104 .map_err(DescriptorError::from)?;
105
106 Ok(Self {
107 extended_descriptor,
108 key_map,
109 })
110 }
111 BdkDescriptorPublicKey::MultiXPub(_) => {
112 unreachable!()
113 }
114 }
115 }
116
117 #[uniffi::constructor]
119 pub fn new_bip49(
120 secret_key: &DescriptorSecretKey,
121 keychain_kind: KeychainKind,
122 network_kind: NetworkKind,
123 ) -> Self {
124 let derivable_key = &secret_key.0;
125
126 match derivable_key {
127 BdkDescriptorSecretKey::Single(_) => {
128 unreachable!()
129 }
130 BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
131 let derivable_key = descriptor_x_key.xkey;
132 let (extended_descriptor, key_map, _) = Bip49(derivable_key, keychain_kind)
133 .build(network_kind)
134 .unwrap();
135 Self {
136 extended_descriptor,
137 key_map,
138 }
139 }
140 BdkDescriptorSecretKey::MultiXPrv(_) => {
141 unreachable!()
142 }
143 }
144 }
145
146 #[uniffi::constructor]
148 pub fn new_bip49_public(
149 public_key: &DescriptorPublicKey,
150 fingerprint: String,
151 keychain_kind: KeychainKind,
152 network_kind: NetworkKind,
153 ) -> Result<Self, DescriptorError> {
154 let fingerprint = Fingerprint::from_str(fingerprint.as_str()).map_err(|error| {
155 DescriptorError::Bip32 {
156 error_message: error.to_string(),
157 }
158 })?;
159 let derivable_key = &public_key.0;
160
161 match derivable_key {
162 BdkDescriptorPublicKey::Single(_) => {
163 unreachable!()
164 }
165 BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
166 let derivable_key = descriptor_x_key.xkey;
167 let (extended_descriptor, key_map, _) =
168 Bip49Public(derivable_key, fingerprint, keychain_kind)
169 .build(network_kind)
170 .map_err(DescriptorError::from)?;
171
172 Ok(Self {
173 extended_descriptor,
174 key_map,
175 })
176 }
177 BdkDescriptorPublicKey::MultiXPub(_) => {
178 unreachable!()
179 }
180 }
181 }
182
183 #[uniffi::constructor]
185 pub fn new_bip84(
186 secret_key: &DescriptorSecretKey,
187 keychain_kind: KeychainKind,
188 network_kind: NetworkKind,
189 ) -> Self {
190 let derivable_key = &secret_key.0;
191
192 match derivable_key {
193 BdkDescriptorSecretKey::Single(_) => {
194 unreachable!()
195 }
196 BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
197 let derivable_key = descriptor_x_key.xkey;
198 let (extended_descriptor, key_map, _) = Bip84(derivable_key, keychain_kind)
199 .build(network_kind)
200 .unwrap();
201 Self {
202 extended_descriptor,
203 key_map,
204 }
205 }
206 BdkDescriptorSecretKey::MultiXPrv(_) => {
207 unreachable!()
208 }
209 }
210 }
211
212 #[uniffi::constructor]
214 pub fn new_bip84_public(
215 public_key: &DescriptorPublicKey,
216 fingerprint: String,
217 keychain_kind: KeychainKind,
218 network_kind: NetworkKind,
219 ) -> Result<Self, DescriptorError> {
220 let fingerprint = Fingerprint::from_str(fingerprint.as_str()).map_err(|error| {
221 DescriptorError::Bip32 {
222 error_message: error.to_string(),
223 }
224 })?;
225 let derivable_key = &public_key.0;
226
227 match derivable_key {
228 BdkDescriptorPublicKey::Single(_) => {
229 unreachable!()
230 }
231 BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
232 let derivable_key = descriptor_x_key.xkey;
233 let (extended_descriptor, key_map, _) =
234 Bip84Public(derivable_key, fingerprint, keychain_kind)
235 .build(network_kind)
236 .map_err(DescriptorError::from)?;
237
238 Ok(Self {
239 extended_descriptor,
240 key_map,
241 })
242 }
243 BdkDescriptorPublicKey::MultiXPub(_) => {
244 unreachable!()
245 }
246 }
247 }
248
249 #[uniffi::constructor]
251 pub fn new_bip86(
252 secret_key: &DescriptorSecretKey,
253 keychain_kind: KeychainKind,
254 network_kind: NetworkKind,
255 ) -> Self {
256 let derivable_key = &secret_key.0;
257
258 match derivable_key {
259 BdkDescriptorSecretKey::Single(_) => {
260 unreachable!()
261 }
262 BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
263 let derivable_key = descriptor_x_key.xkey;
264 let (extended_descriptor, key_map, _) = Bip86(derivable_key, keychain_kind)
265 .build(network_kind)
266 .unwrap();
267 Self {
268 extended_descriptor,
269 key_map,
270 }
271 }
272 BdkDescriptorSecretKey::MultiXPrv(_) => {
273 unreachable!()
274 }
275 }
276 }
277
278 #[uniffi::constructor]
280 pub fn new_bip86_public(
281 public_key: &DescriptorPublicKey,
282 fingerprint: String,
283 keychain_kind: KeychainKind,
284 network_kind: NetworkKind,
285 ) -> Result<Self, DescriptorError> {
286 let fingerprint = Fingerprint::from_str(fingerprint.as_str()).map_err(|error| {
287 DescriptorError::Bip32 {
288 error_message: error.to_string(),
289 }
290 })?;
291 let derivable_key = &public_key.0;
292
293 match derivable_key {
294 BdkDescriptorPublicKey::Single(_) => {
295 unreachable!()
296 }
297 BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
298 let derivable_key = descriptor_x_key.xkey;
299 let (extended_descriptor, key_map, _) =
300 Bip86Public(derivable_key, fingerprint, keychain_kind)
301 .build(network_kind)
302 .map_err(DescriptorError::from)?;
303
304 Ok(Self {
305 extended_descriptor,
306 key_map,
307 })
308 }
309 BdkDescriptorPublicKey::MultiXPub(_) => {
310 unreachable!()
311 }
312 }
313 }
314
315 #[uniffi::constructor]
318 pub fn new_wsh_sortedmulti(k: u32, pks: Vec<String>) -> Result<Self, DescriptorError> {
319 let bdk_pks: Vec<BdkDescriptorPublicKey> = pks
320 .iter()
321 .map(|pk| {
322 BdkDescriptorPublicKey::from_str(pk).map_err(|e| DescriptorError::Key {
323 error_message: e.to_string(),
324 })
325 })
326 .collect::<Result<Vec<BdkDescriptorPublicKey>, DescriptorError>>()?;
327 let miniscript_descriptor =
328 match bdk_wallet::miniscript::Descriptor::new_wsh_sortedmulti(k as usize, bdk_pks) {
329 Ok(descriptor) => descriptor,
330 Err(e) => {
331 return Err(DescriptorError::Miniscript {
332 error_message: e.to_string(),
333 })
334 }
335 };
336 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
337
338 Ok(Self {
339 extended_descriptor,
340 key_map: KeyMap::new(),
341 })
342 }
343
344 #[uniffi::constructor]
347 pub fn new_sh_sortedmulti(k: u32, pks: Vec<String>) -> Result<Self, DescriptorError> {
348 let bdk_pks: Vec<BdkDescriptorPublicKey> = pks
349 .iter()
350 .map(|pk| {
351 BdkDescriptorPublicKey::from_str(pk).map_err(|e| DescriptorError::Key {
352 error_message: e.to_string(),
353 })
354 })
355 .collect::<Result<Vec<BdkDescriptorPublicKey>, DescriptorError>>()?;
356 let miniscript_descriptor =
357 match bdk_wallet::miniscript::Descriptor::new_sh_sortedmulti(k as usize, bdk_pks) {
358 Ok(descriptor) => descriptor,
359 Err(e) => {
360 return Err(DescriptorError::Miniscript {
361 error_message: e.to_string(),
362 })
363 }
364 };
365 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
366
367 Ok(Self {
368 extended_descriptor,
369 key_map: KeyMap::new(),
370 })
371 }
372
373 #[uniffi::constructor]
376 pub fn new_sh_wsh_sortedmulti(k: u32, pks: Vec<String>) -> Result<Self, DescriptorError> {
377 let bdk_pks: Vec<BdkDescriptorPublicKey> = pks
378 .iter()
379 .map(|pk| {
380 BdkDescriptorPublicKey::from_str(pk).map_err(|e| DescriptorError::Key {
381 error_message: e.to_string(),
382 })
383 })
384 .collect::<Result<Vec<BdkDescriptorPublicKey>, DescriptorError>>()?;
385 let miniscript_descriptor =
386 match bdk_wallet::miniscript::Descriptor::new_sh_wsh_sortedmulti(k as usize, bdk_pks) {
387 Ok(descriptor) => descriptor,
388 Err(e) => {
389 return Err(DescriptorError::Miniscript {
390 error_message: e.to_string(),
391 })
392 }
393 };
394 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
395
396 Ok(Self {
397 extended_descriptor,
398 key_map: KeyMap::new(),
399 })
400 }
401
402 #[uniffi::constructor]
404 pub fn new_pk(pk: String) -> Result<Self, DescriptorError> {
405 let key = BdkDescriptorPublicKey::from_str(&pk).map_err(|e| DescriptorError::Key {
406 error_message: e.to_string(),
407 })?;
408
409 let miniscript_descriptor = bdk_wallet::miniscript::Descriptor::new_pk(key);
410 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
411
412 Ok(Self {
413 extended_descriptor,
414 key_map: KeyMap::new(),
415 })
416 }
417
418 #[uniffi::constructor]
420 pub fn new_pkh(pk: String) -> Result<Self, DescriptorError> {
421 let key = BdkDescriptorPublicKey::from_str(&pk).map_err(|e| DescriptorError::Key {
422 error_message: e.to_string(),
423 })?;
424
425 let miniscript_descriptor = match bdk_wallet::miniscript::Descriptor::new_pkh(key) {
426 Ok(descriptor) => descriptor,
427 Err(e) => {
428 return Err(DescriptorError::Miniscript {
429 error_message: e.to_string(),
430 })
431 }
432 };
433 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
434
435 Ok(Self {
436 extended_descriptor,
437 key_map: KeyMap::new(),
438 })
439 }
440
441 #[uniffi::constructor]
443 pub fn new_wpkh(pk: String) -> Result<Self, DescriptorError> {
444 let key = BdkDescriptorPublicKey::from_str(&pk).map_err(|e| DescriptorError::Key {
445 error_message: e.to_string(),
446 })?;
447
448 let miniscript_descriptor = match bdk_wallet::miniscript::Descriptor::new_wpkh(key) {
449 Ok(descriptor) => descriptor,
450 Err(e) => {
451 return Err(DescriptorError::Miniscript {
452 error_message: e.to_string(),
453 })
454 }
455 };
456 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
457
458 Ok(Self {
459 extended_descriptor,
460 key_map: KeyMap::new(),
461 })
462 }
463
464 #[uniffi::constructor]
466 pub fn new_sh_wpkh(pk: String) -> Result<Self, DescriptorError> {
467 let key = BdkDescriptorPublicKey::from_str(&pk).map_err(|e| DescriptorError::Key {
468 error_message: e.to_string(),
469 })?;
470
471 let miniscript_descriptor = match bdk_wallet::miniscript::Descriptor::new_sh_wpkh(key) {
472 Ok(descriptor) => descriptor,
473 Err(e) => {
474 return Err(DescriptorError::Miniscript {
475 error_message: e.to_string(),
476 })
477 }
478 };
479 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
480
481 Ok(Self {
482 extended_descriptor,
483 key_map: KeyMap::new(),
484 })
485 }
486
487 #[uniffi::constructor]
490 pub fn new_wsh(mini_script: String) -> Result<Self, DescriptorError> {
491 let parsed_miniscript = match BdkMiniscript::from_str(&mini_script) {
492 Ok(miniscript) => miniscript,
493 Err(e) => {
494 return Err(DescriptorError::Miniscript {
495 error_message: e.to_string(),
496 });
497 }
498 };
499
500 let miniscript_descriptor =
501 match bdk_wallet::miniscript::Descriptor::new_wsh(parsed_miniscript) {
502 Ok(descriptor) => descriptor,
503 Err(e) => {
504 return Err(DescriptorError::Miniscript {
505 error_message: e.to_string(),
506 })
507 }
508 };
509 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
510
511 Ok(Self {
512 extended_descriptor,
513 key_map: KeyMap::new(),
514 })
515 }
516
517 #[uniffi::constructor]
520 pub fn new_sh_wsh(mini_script: String) -> Result<Self, DescriptorError> {
521 let parsed_miniscript = match BdkMiniscript::from_str(&mini_script) {
522 Ok(miniscript) => miniscript,
523 Err(e) => {
524 return Err(DescriptorError::Miniscript {
525 error_message: e.to_string(),
526 });
527 }
528 };
529
530 let miniscript_descriptor =
531 match bdk_wallet::miniscript::Descriptor::new_sh_wsh(parsed_miniscript) {
532 Ok(descriptor) => descriptor,
533 Err(e) => {
534 return Err(DescriptorError::Miniscript {
535 error_message: e.to_string(),
536 })
537 }
538 };
539 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
540
541 Ok(Self {
542 extended_descriptor,
543 key_map: KeyMap::new(),
544 })
545 }
546
547 #[uniffi::constructor]
549 pub fn new_sh(mini_script: String) -> Result<Self, DescriptorError> {
550 let parsed_miniscript = match BdkMiniscript::from_str(&mini_script) {
551 Ok(miniscript) => miniscript,
552 Err(e) => {
553 return Err(DescriptorError::Miniscript {
554 error_message: e.to_string(),
555 });
556 }
557 };
558
559 let miniscript_descriptor =
560 match bdk_wallet::miniscript::Descriptor::new_sh(parsed_miniscript) {
561 Ok(descriptor) => descriptor,
562 Err(e) => {
563 return Err(DescriptorError::Miniscript {
564 error_message: e.to_string(),
565 })
566 }
567 };
568 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
569
570 Ok(Self {
571 extended_descriptor,
572 key_map: KeyMap::new(),
573 })
574 }
575
576 #[uniffi::constructor]
579 pub fn new_bare(mini_script: String) -> Result<Self, DescriptorError> {
580 let parsed_miniscript = match BdkMiniscript::from_str(&mini_script) {
581 Ok(miniscript) => miniscript,
582 Err(e) => {
583 return Err(DescriptorError::Miniscript {
584 error_message: e.to_string(),
585 });
586 }
587 };
588
589 let miniscript_descriptor =
590 match bdk_wallet::miniscript::Descriptor::new_bare(parsed_miniscript) {
591 Ok(descriptor) => descriptor,
592 Err(e) => {
593 return Err(DescriptorError::Miniscript {
594 error_message: e.to_string(),
595 })
596 }
597 };
598 let extended_descriptor = ExtendedDescriptor::from(miniscript_descriptor);
599
600 Ok(Self {
601 extended_descriptor,
602 key_map: KeyMap::new(),
603 })
604 }
605
606 #[uniffi::constructor]
608 pub fn new_sh_with_wpkh(wpkh: String) -> Result<Self, DescriptorError> {
609 let descriptor = BdkDescriptor::<BdkDescriptorPublicKey>::from_str(&wpkh).map_err(|e| {
610 DescriptorError::Miniscript {
611 error_message: e.to_string(),
612 }
613 })?;
614
615 if let BdkDescriptor::Wpkh(wpkh_inner) = descriptor {
616 let sh_with_wpkh = bdk_wallet::miniscript::Descriptor::new_sh_with_wpkh(wpkh_inner);
617 Ok(Self {
618 extended_descriptor: ExtendedDescriptor::from(sh_with_wpkh),
619 key_map: KeyMap::new(),
620 })
621 } else {
622 Err(DescriptorError::Miniscript {
623 error_message: "Provided descriptor is not a valid wpkh descriptor".to_string(),
624 })
625 }
626 }
627
628 #[uniffi::constructor]
630 pub fn new_sh_with_wsh(wsh: String) -> Result<Self, DescriptorError> {
631 let descriptor = BdkDescriptor::<BdkDescriptorPublicKey>::from_str(&wsh).map_err(|e| {
632 DescriptorError::Miniscript {
633 error_message: e.to_string(),
634 }
635 })?;
636
637 if let BdkDescriptor::Wsh(wsh_inner) = descriptor {
638 let sh_with_wsh = bdk_wallet::miniscript::Descriptor::new_sh_with_wsh(wsh_inner);
639 Ok(Self {
640 extended_descriptor: ExtendedDescriptor::from(sh_with_wsh),
641 key_map: KeyMap::new(),
642 })
643 } else {
644 Err(DescriptorError::Miniscript {
645 error_message: "Provided descriptor is not a valid wsh descriptor".to_string(),
646 })
647 }
648 }
649
650 #[uniffi::constructor]
653 pub fn new_tr(key: String, script: Option<String>) -> Result<Self, DescriptorError> {
654 let key = BdkDescriptorPublicKey::from_str(&key).map_err(|e| DescriptorError::Key {
655 error_message: e.to_string(),
656 })?;
657 let tap_tree = match script {
658 Some(s) => {
659 let ms_tap =
660 BdkMiniscript::from_str(&s).map_err(|e| DescriptorError::Miniscript {
661 error_message: e.to_string(),
662 })?;
663
664 Some(TapTree::Leaf(Arc::new(ms_tap)))
665 }
666 None => None,
667 };
668
669 let descriptor =
670 bdk_wallet::miniscript::Descriptor::new_tr(key, tap_tree).map_err(|e| {
671 DescriptorError::Miniscript {
672 error_message: e.to_string(),
673 }
674 })?;
675 Ok(Self {
676 extended_descriptor: ExtendedDescriptor::from(descriptor),
677 key_map: KeyMap::new(),
678 })
679 }
680
681 pub fn as_public(&self) -> Arc<Self> {
683 Arc::new(Self {
684 extended_descriptor: self.extended_descriptor.clone(),
685 key_map: KeyMap::new(),
686 })
687 }
688
689 pub fn to_string_with_secret(&self) -> String {
691 let descriptor = &self.extended_descriptor;
692 let key_map = &self.key_map;
693 descriptor.to_string_with_secret(key_map)
694 }
695
696 pub fn is_multipath(&self) -> bool {
698 self.extended_descriptor.is_multipath()
699 }
700
701 pub fn descriptor_id(&self) -> Arc<DescriptorId> {
703 let d_id = self.extended_descriptor.descriptor_id();
704 Arc::new(DescriptorId(d_id.0))
705 }
706
707 pub fn to_single_descriptors(&self) -> Result<Vec<Arc<Descriptor>>, MiniscriptError> {
709 self.extended_descriptor
710 .clone()
711 .into_single_descriptors()
712 .map_err(MiniscriptError::from)
713 .map(|descriptors| {
714 descriptors
715 .into_iter()
716 .map(|desc| {
717 Arc::new(Descriptor {
718 extended_descriptor: desc,
719 key_map: self.key_map.clone(),
720 })
721 })
722 .collect()
723 })
724 }
725
726 pub fn max_weight_to_satisfy(&self) -> Result<u64, DescriptorError> {
729 let weight = self
730 .extended_descriptor
731 .max_weight_to_satisfy()
732 .map_err(|e| DescriptorError::Miniscript {
733 error_message: e.to_string(),
734 })?;
735 Ok(weight.to_wu())
736 }
737
738 pub fn desc_type(&self) -> DescriptorType {
739 self.extended_descriptor.desc_type()
740 }
741
742 pub fn derive_address(
743 &self,
744 index: u32,
745 network: Network,
746 ) -> Result<Arc<Address>, DescriptorError> {
747 if self.extended_descriptor.is_multipath() {
748 return Err(DescriptorError::MultiPath);
749 }
750
751 let derived_descriptor = self
752 .extended_descriptor
753 .at_derivation_index(index)
754 .map_err(|error| match error {
755 ConversionError::HardenedChild => DescriptorError::HardenedDerivationXpub,
756 ConversionError::MultiKey => DescriptorError::MultiPath,
757 })?;
758
759 let address = derived_descriptor
760 .address(network)
761 .map_err(|error| DescriptorError::Miniscript {
762 error_message: error.to_string(),
763 })?
764 .into();
765
766 Ok(Arc::new(address))
767 }
768
769 pub fn has_wildcard(&self) -> bool {
771 self.extended_descriptor.has_wildcard()
772 }
773
774 pub fn sanity_check(&self) -> Result<(), DescriptorError> {
784 self.extended_descriptor
785 .sanity_check()
786 .map_err(|e| DescriptorError::Miniscript {
787 error_message: e.to_string(),
788 })
789 }
790}
791
792impl Display for Descriptor {
793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
794 write!(f, "{}", self.extended_descriptor)
795 }
796}