bdkffi/
keys.rs

1use crate::bitcoin::{ChildNumber, NetworkKind};
2use crate::error::{Bip32Error, Bip39Error, DescriptorKeyError};
3use crate::{impl_from_core_type, impl_into_core_type};
4
5use bdk_wallet::bitcoin::bip32::ChildNumber as BdkChildNumber;
6use bdk_wallet::bitcoin::bip32::DerivationPath as BdkDerivationPath;
7use bdk_wallet::bitcoin::key::Secp256k1;
8use bdk_wallet::bitcoin::secp256k1::rand;
9use bdk_wallet::bitcoin::secp256k1::rand::Rng;
10use bdk_wallet::keys::bip39::WordCount;
11use bdk_wallet::keys::bip39::{Language, Mnemonic as BdkMnemonic};
12use bdk_wallet::keys::{
13    DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
14    DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
15};
16use bdk_wallet::miniscript::descriptor::{DescriptorXKey, Wildcard};
17use bdk_wallet::miniscript::BareCtx;
18
19use crate::types::WildcardType;
20use std::convert::TryFrom;
21use std::fmt::Display;
22use std::str::FromStr;
23use std::sync::Arc;
24
25/// A mnemonic seed phrase to recover a BIP-32 wallet.
26#[derive(uniffi::Object)]
27#[uniffi::export(Display)]
28pub struct Mnemonic(BdkMnemonic);
29
30#[uniffi::export]
31impl Mnemonic {
32    /// Generate a mnemonic given a word count.
33    #[uniffi::constructor]
34    pub fn new(word_count: WordCount) -> Self {
35        let mut rng = rand::thread_rng();
36        let mut entropy = [0u8; 32];
37        rng.fill(&mut entropy);
38
39        let generated_key: GeneratedKey<_, BareCtx> =
40            BdkMnemonic::generate_with_entropy((word_count, Language::English), entropy).unwrap();
41        let mnemonic = BdkMnemonic::parse_in(Language::English, generated_key.to_string()).unwrap();
42        Mnemonic(mnemonic)
43    }
44
45    /// Parse a string as a mnemonic seed phrase.
46    #[uniffi::constructor]
47    pub fn from_string(mnemonic: String) -> Result<Self, Bip39Error> {
48        BdkMnemonic::from_str(&mnemonic)
49            .map(Mnemonic)
50            .map_err(Bip39Error::from)
51    }
52
53    /// Construct a mnemonic from caller-provided entropy.
54    ///
55    /// This function does not generate entropy. Callers must provide cryptographically secure
56    /// entropy; weak entropy can result in loss of funds.
57    #[uniffi::constructor]
58    pub fn from_entropy(entropy: Vec<u8>) -> Result<Self, Bip39Error> {
59        BdkMnemonic::from_entropy(entropy.as_slice())
60            .map(Mnemonic)
61            .map_err(Bip39Error::from)
62    }
63}
64
65impl Display for Mnemonic {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "{}", self.0)
68    }
69}
70
71/// A BIP-32 derivation path.
72#[derive(Clone, Debug, uniffi::Object)]
73#[uniffi::export(Display)]
74pub struct DerivationPath(pub(crate) BdkDerivationPath);
75
76#[uniffi::export]
77impl DerivationPath {
78    /// Parse a string as a BIP-32 derivation path.
79    #[uniffi::constructor]
80    pub fn new(path: String) -> Result<Self, Bip32Error> {
81        BdkDerivationPath::from_str(&path)
82            .map(DerivationPath)
83            .map_err(Bip32Error::from)
84    }
85
86    /// Returns derivation path for a master key (i.e. empty derivation path)
87    #[uniffi::constructor]
88    pub fn master() -> Arc<Self> {
89        Arc::new(BdkDerivationPath::master().into())
90    }
91
92    /// Returns whether derivation path represents master key (i.e. it's length
93    /// is empty). True for `m` path.
94    pub fn is_master(&self) -> bool {
95        self.0.is_master()
96    }
97
98    /// Returns length of the derivation path
99    pub fn len(&self) -> u64 {
100        self.0.len() as u64
101    }
102
103    /// Returns `true` if the derivation path is empty
104    pub fn is_empty(&self) -> bool {
105        self.0.is_empty()
106    }
107
108    /// Create a new DerivationPath that is a child of this one.
109    pub fn child(&self, child_number: ChildNumber) -> Result<Arc<Self>, Bip32Error> {
110        let validated_child_number = BdkChildNumber::try_from(child_number)?;
111        Ok(Arc::new(self.0.child(validated_child_number).into()))
112    }
113
114    /// Concatenate `self` with `path` and return the resulting new path.
115    pub fn extend(&self, other: &DerivationPath) -> Arc<Self> {
116        let extended_path = self.0.extend(&other.0);
117        Arc::new(DerivationPath(extended_path))
118    }
119
120    /// Returns the derivation path as a vector of u32 integers.
121    /// Unhardened elements are copied as is.
122    /// 0x80000000 is added to the hardened elements.
123    pub fn to_u32_vec(&self) -> Vec<u32> {
124        self.0.to_u32_vec()
125    }
126}
127
128impl Display for DerivationPath {
129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        write!(f, "{}", self.0)
131    }
132}
133
134impl_from_core_type!(BdkDerivationPath, DerivationPath);
135impl_into_core_type!(DerivationPath, BdkDerivationPath);
136
137/// The descriptor secret key, either a single private key or an xprv.
138#[derive(Debug, uniffi::Object)]
139#[uniffi::export(Debug, Display)]
140pub struct DescriptorSecretKey(pub(crate) BdkDescriptorSecretKey);
141
142#[uniffi::export]
143impl DescriptorSecretKey {
144    /// Construct a secret descriptor key using a mnemonic.
145    #[uniffi::constructor]
146    pub fn new(network_kind: NetworkKind, mnemonic: &Mnemonic, password: Option<String>) -> Self {
147        let mnemonic = mnemonic.0.clone();
148        let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
149        let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
150            origin: None,
151            xkey: xkey.into_xprv(network_kind).unwrap(),
152            derivation_path: BdkDerivationPath::master(),
153            wildcard: Wildcard::None,
154        });
155        Self(descriptor_secret_key)
156    }
157
158    /// Attempt to parse a string as a descriptor secret key.
159    #[uniffi::constructor]
160    pub fn from_string(private_key: String) -> Result<Self, DescriptorKeyError> {
161        let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str())
162            .map_err(DescriptorKeyError::from)?;
163        Ok(Self(descriptor_secret_key))
164    }
165
166    /// Derive a descriptor secret key at a given derivation path.
167    ///
168    /// Any derivation path already recorded on this key (for example from `extend()` or from
169    /// parsing a key such as `xprv.../84h/1h/0h`) is applied first, so the result is the key at
170    /// `<existing path>/<path>`.
171    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
172        let secp = Secp256k1::new();
173        let descriptor_secret_key = &self.0;
174        match descriptor_secret_key {
175            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
176            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
177                // Apply any derivation path already recorded on the key (from `extend()` or
178                // `from_string()`) before the requested path, so it is not silently discarded.
179                let full_path = descriptor_x_key.derivation_path.extend(&path.0);
180                let derived_xprv = descriptor_x_key
181                    .xkey
182                    .derive_priv(&secp, &full_path)
183                    .map_err(DescriptorKeyError::from)?;
184                let key_source = match descriptor_x_key.origin.clone() {
185                    Some((fingerprint, origin_path)) => {
186                        (fingerprint, origin_path.extend(&full_path))
187                    }
188                    None => (descriptor_x_key.xkey.fingerprint(&secp), full_path),
189                };
190                let derived_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
191                    origin: Some(key_source),
192                    xkey: derived_xprv,
193                    derivation_path: BdkDerivationPath::default(),
194                    wildcard: descriptor_x_key.wildcard,
195                });
196                Ok(Arc::new(Self(derived_descriptor_secret_key)))
197            }
198            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
199        }
200    }
201
202    /// Extend the descriptor secret key by the derivation path.
203    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
204        let descriptor_secret_key = &self.0;
205        match descriptor_secret_key {
206            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
207            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
208                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
209                let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
210                    origin: descriptor_x_key.origin.clone(),
211                    xkey: descriptor_x_key.xkey,
212                    derivation_path: extended_path,
213                    wildcard: descriptor_x_key.wildcard,
214                });
215                Ok(Arc::new(Self(extended_descriptor_secret_key)))
216            }
217            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
218        }
219    }
220
221    /// Add a wildcard derivation step (unhardened `*` or hardened `*h`) to this extended private key.
222    ///
223    /// If the key already has the same wildcard type, it is returned unchanged. Returns an error
224    /// if the key is not a single xprv, or if the key already has a wildcard of a different type.
225    pub fn add_wildcard(
226        &self,
227        wildcard_type: WildcardType,
228    ) -> Result<Arc<Self>, DescriptorKeyError> {
229        let descriptor_secret_key = &self.0;
230        match descriptor_secret_key {
231            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
232            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
233                let same_wildcard = (descriptor_x_key.wildcard == Wildcard::Unhardened
234                    && wildcard_type == WildcardType::Unhardened)
235                    || (descriptor_x_key.wildcard == Wildcard::Hardened
236                        && wildcard_type == WildcardType::Hardened);
237
238                // If there is a wildcard already present and it's of the same type as the one requested,
239                // return the same DescriptorSecretKey
240                if same_wildcard {
241                    let descriptor_secret_key_with_wildcard =
242                        BdkDescriptorSecretKey::XPrv(DescriptorXKey {
243                            origin: descriptor_x_key.origin.clone(),
244                            xkey: descriptor_x_key.xkey,
245                            derivation_path: descriptor_x_key.derivation_path.clone(),
246                            wildcard: descriptor_x_key.wildcard,
247                        });
248                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
249                } else if descriptor_x_key.wildcard == Wildcard::None {
250                    // If the descriptor doesn't have a wildcard, add the requested wildcard
251                    let descriptor_secret_key_with_wildcard =
252                        BdkDescriptorSecretKey::XPrv(DescriptorXKey {
253                            origin: descriptor_x_key.origin.clone(),
254                            xkey: descriptor_x_key.xkey,
255                            derivation_path: descriptor_x_key.derivation_path.clone(),
256                            wildcard: wildcard_type.into(),
257                        });
258                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
259                } else {
260                    // If the descriptor already has a wildcard of a different type, return an error
261                    Err(DescriptorKeyError::CannotChangeWildcardType)
262                }
263            }
264            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
265        }
266    }
267
268    /// Return the descriptor public key corresponding to this secret.
269    pub fn as_public(&self) -> Arc<DescriptorPublicKey> {
270        let secp = Secp256k1::new();
271        let descriptor_public_key = self.0.to_public(&secp).unwrap();
272        Arc::new(DescriptorPublicKey(descriptor_public_key))
273    }
274
275    /// Return the bytes of this descriptor secret key.
276    ///
277    /// For an extended private key, the key is derived along the derivation path it carries
278    /// before its bytes are returned.
279    ///
280    /// A key carrying a wildcard (`*` or `*h`) or a multipath key (one with a step such as
281    /// `<0;1>`) names a family of keys rather than a single key, so an empty vector is returned
282    /// for it. An empty vector is also returned if the derivation would exceed the maximum BIP-32
283    /// depth.
284    pub fn secret_bytes(&self) -> Vec<u8> {
285        let secp = Secp256k1::new();
286        let inner = &self.0;
287        let secret_bytes: Vec<u8> = match inner {
288            BdkDescriptorSecretKey::Single(single_key) => {
289                single_key.key.inner.secret_bytes().to_vec()
290            }
291            BdkDescriptorSecretKey::XPrv(descriptor_x_key)
292                if descriptor_x_key.wildcard == Wildcard::None =>
293            {
294                descriptor_x_key
295                    .xkey
296                    .derive_priv(&secp, &descriptor_x_key.derivation_path)
297                    .map(|derived| derived.private_key.secret_bytes().to_vec())
298                    .unwrap_or_default()
299            }
300            BdkDescriptorSecretKey::XPrv(_) | BdkDescriptorSecretKey::MultiXPrv(_) => Vec::new(),
301        };
302
303        secret_bytes
304    }
305}
306
307impl Display for DescriptorSecretKey {
308    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
309        self.0.fmt(f)
310    }
311}
312
313/// A descriptor public key.
314#[derive(Debug, uniffi::Object)]
315#[uniffi::export(Debug, Display)]
316pub struct DescriptorPublicKey(pub(crate) BdkDescriptorPublicKey);
317
318#[uniffi::export]
319impl DescriptorPublicKey {
320    /// Attempt to parse a string as a descriptor public key.
321    #[uniffi::constructor]
322    pub fn from_string(public_key: String) -> Result<Self, DescriptorKeyError> {
323        let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str())
324            .map_err(DescriptorKeyError::from)?;
325        Ok(Self(descriptor_public_key))
326    }
327
328    /// Derive the descriptor public key at the given derivation path.
329    ///
330    /// Any derivation path already recorded on this key (for example from `extend()` or from
331    /// parsing a key such as `xpub.../0`) is applied first, so the result is the key at
332    /// `<existing path>/<path>`.
333    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
334        let secp = Secp256k1::new();
335        let descriptor_public_key = &self.0;
336        match descriptor_public_key {
337            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
338            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
339                // Apply any derivation path already recorded on the key (from `extend()` or
340                // `from_string()`) before the requested path, so it is not silently discarded.
341                let full_path = descriptor_x_key.derivation_path.extend(&path.0);
342                let derived_xpub = descriptor_x_key
343                    .xkey
344                    .derive_pub(&secp, &full_path)
345                    .map_err(DescriptorKeyError::from)?;
346                let key_source = match descriptor_x_key.origin.clone() {
347                    Some((fingerprint, origin_path)) => {
348                        (fingerprint, origin_path.extend(&full_path))
349                    }
350                    None => (descriptor_x_key.xkey.fingerprint(), full_path),
351                };
352                let derived_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
353                    origin: Some(key_source),
354                    xkey: derived_xpub,
355                    derivation_path: BdkDerivationPath::default(),
356                    wildcard: descriptor_x_key.wildcard,
357                });
358                Ok(Arc::new(Self(derived_descriptor_public_key)))
359            }
360            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
361        }
362    }
363
364    /// Extend the descriptor public key by the given derivation path.
365    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
366        let descriptor_public_key = &self.0;
367        match descriptor_public_key {
368            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
369            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
370                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
371                let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
372                    origin: descriptor_x_key.origin.clone(),
373                    xkey: descriptor_x_key.xkey,
374                    derivation_path: extended_path,
375                    wildcard: descriptor_x_key.wildcard,
376                });
377                Ok(Arc::new(Self(extended_descriptor_public_key)))
378            }
379            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
380        }
381    }
382
383    /// Add an unhardened wildcard derivation step (`*`) to this extended public key.
384    ///
385    /// Public keys only support unhardened wildcards since xpubs cannot derive hardened children.
386    /// If the key already has an unhardened wildcard, it is returned unchanged. Returns an error
387    /// if the key is not a single xpub, or if the key already has a hardened wildcard.
388    pub fn add_wildcard(&self) -> Result<Arc<Self>, DescriptorKeyError> {
389        let descriptor_public_key = &self.0;
390        match descriptor_public_key {
391            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
392            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
393                // If there is a wildcard already present and it's unhardened,
394                // return the same DescriptorPublicKey
395                if descriptor_x_key.wildcard == Wildcard::Unhardened {
396                    let descriptor_public_key_with_wildcard =
397                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
398                            origin: descriptor_x_key.origin.clone(),
399                            xkey: descriptor_x_key.xkey,
400                            derivation_path: descriptor_x_key.derivation_path.clone(),
401                            wildcard: Wildcard::Unhardened,
402                        });
403                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
404                } else if descriptor_x_key.wildcard == Wildcard::None {
405                    // If the descriptor doesn't have a wildcard, add an Unhardened wildcard
406                    let descriptor_public_key_with_wildcard =
407                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
408                            origin: descriptor_x_key.origin.clone(),
409                            xkey: descriptor_x_key.xkey,
410                            derivation_path: descriptor_x_key.derivation_path.clone(),
411                            wildcard: Wildcard::Unhardened,
412                        });
413                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
414                } else {
415                    // If the descriptor already has a wildcard and it's hardened, return an error, because (1) we don't want to allow changing the wildcard, and (2) extended public keys cannot derived hardened children
416                    Err(DescriptorKeyError::CannotChangeWildcardType)
417                }
418            }
419            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
420        }
421    }
422
423    /// Whether or not this key has multiple derivation paths.
424    pub fn is_multipath(&self) -> bool {
425        self.0.is_multipath()
426    }
427
428    /// The fingerprint of the master key associated with this key, `0x00000000` if none.
429    pub fn master_fingerprint(&self) -> String {
430        self.0.master_fingerprint().to_string()
431    }
432}
433
434impl Display for DescriptorPublicKey {
435    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
436        self.0.fmt(f)
437    }
438}