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