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        // TODO 4: I DON'T KNOW IF THIS IS A DECENT WAY TO GENERATE ENTROPY PLEASE CONFIRM
36        let mut rng = rand::thread_rng();
37        let mut entropy = [0u8; 32];
38        rng.fill(&mut entropy);
39
40        let generated_key: GeneratedKey<_, BareCtx> =
41            BdkMnemonic::generate_with_entropy((word_count, Language::English), entropy).unwrap();
42        let mnemonic = BdkMnemonic::parse_in(Language::English, generated_key.to_string()).unwrap();
43        Mnemonic(mnemonic)
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 given an array of bytes. Note that using weak entropy will result in a loss
54    /// of funds. To ensure the entropy is generated properly, read about your operating
55    /// system specific ways to generate secure random numbers.
56    #[uniffi::constructor]
57    pub fn from_entropy(entropy: Vec<u8>) -> Result<Self, Bip39Error> {
58        BdkMnemonic::from_entropy(entropy.as_slice())
59            .map(Mnemonic)
60            .map_err(Bip39Error::from)
61    }
62}
63
64impl Display for Mnemonic {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        write!(f, "{}", self.0)
67    }
68}
69
70/// A BIP-32 derivation path.
71#[derive(Clone, Debug, uniffi::Object)]
72#[uniffi::export(Display)]
73pub struct DerivationPath(pub(crate) BdkDerivationPath);
74
75#[uniffi::export]
76impl DerivationPath {
77    /// Parse a string as a BIP-32 derivation path.
78    #[uniffi::constructor]
79    pub fn new(path: String) -> Result<Self, Bip32Error> {
80        BdkDerivationPath::from_str(&path)
81            .map(DerivationPath)
82            .map_err(Bip32Error::from)
83    }
84
85    /// Returns derivation path for a master key (i.e. empty derivation path)
86    #[uniffi::constructor]
87    pub fn master() -> Arc<Self> {
88        Arc::new(BdkDerivationPath::master().into())
89    }
90
91    /// Returns whether derivation path represents master key (i.e. it's length
92    /// is empty). True for `m` path.
93    pub fn is_master(&self) -> bool {
94        self.0.is_master()
95    }
96
97    /// Returns length of the derivation path
98    pub fn len(&self) -> u64 {
99        self.0.len() as u64
100    }
101
102    /// Returns `true` if the derivation path is empty
103    pub fn is_empty(&self) -> bool {
104        self.0.is_empty()
105    }
106
107    /// Create a new DerivationPath that is a child of this one.
108    pub fn child(&self, child_number: ChildNumber) -> Result<Arc<Self>, Bip32Error> {
109        let validated_child_number = BdkChildNumber::try_from(child_number)?;
110        Ok(Arc::new(self.0.child(validated_child_number).into()))
111    }
112
113    /// Concatenate `self` with `path` and return the resulting new path.
114    pub fn extend(&self, other: &DerivationPath) -> Arc<Self> {
115        let extended_path = self.0.extend(&other.0);
116        Arc::new(DerivationPath(extended_path))
117    }
118
119    /// Returns the derivation path as a vector of u32 integers.
120    /// Unhardened elements are copied as is.
121    /// 0x80000000 is added to the hardened elements.
122    pub fn to_u32_vec(&self) -> Vec<u32> {
123        self.0.to_u32_vec()
124    }
125}
126
127impl Display for DerivationPath {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        write!(f, "{}", self.0)
130    }
131}
132
133impl_from_core_type!(BdkDerivationPath, DerivationPath);
134impl_into_core_type!(DerivationPath, BdkDerivationPath);
135
136/// The descriptor secret key, either a single private key or an xprv.
137#[derive(Debug, uniffi::Object)]
138#[uniffi::export(Debug, Display)]
139pub struct DescriptorSecretKey(pub(crate) BdkDescriptorSecretKey);
140
141#[uniffi::export]
142impl DescriptorSecretKey {
143    /// Construct a secret descriptor key using a mnemonic.
144    #[uniffi::constructor]
145    pub fn new(network_kind: NetworkKind, mnemonic: &Mnemonic, password: Option<String>) -> Self {
146        let mnemonic = mnemonic.0.clone();
147        let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
148        let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
149            origin: None,
150            xkey: xkey.into_xprv(network_kind).unwrap(),
151            derivation_path: BdkDerivationPath::master(),
152            wildcard: Wildcard::None,
153        });
154        Self(descriptor_secret_key)
155    }
156
157    /// Attempt to parse a string as a descriptor secret key.
158    #[uniffi::constructor]
159    pub fn from_string(private_key: String) -> Result<Self, DescriptorKeyError> {
160        let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str())
161            .map_err(DescriptorKeyError::from)?;
162        Ok(Self(descriptor_secret_key))
163    }
164
165    /// Derive a descriptor secret key at a given derivation path.
166    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
167        let secp = Secp256k1::new();
168        let descriptor_secret_key = &self.0;
169        match descriptor_secret_key {
170            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
171            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
172                let derived_xprv = descriptor_x_key
173                    .xkey
174                    .derive_priv(&secp, &path.0)
175                    .map_err(DescriptorKeyError::from)?;
176                let key_source = match descriptor_x_key.origin.clone() {
177                    Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(&path.0)),
178                    None => (descriptor_x_key.xkey.fingerprint(&secp), path.0.clone()),
179                };
180                let derived_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
181                    origin: Some(key_source),
182                    xkey: derived_xprv,
183                    derivation_path: BdkDerivationPath::default(),
184                    wildcard: descriptor_x_key.wildcard,
185                });
186                Ok(Arc::new(Self(derived_descriptor_secret_key)))
187            }
188            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
189        }
190    }
191
192    /// Extend the descriptor secret key by the derivation path.
193    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
194        let descriptor_secret_key = &self.0;
195        match descriptor_secret_key {
196            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
197            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
198                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
199                let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
200                    origin: descriptor_x_key.origin.clone(),
201                    xkey: descriptor_x_key.xkey,
202                    derivation_path: extended_path,
203                    wildcard: descriptor_x_key.wildcard,
204                });
205                Ok(Arc::new(Self(extended_descriptor_secret_key)))
206            }
207            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
208        }
209    }
210
211    /// Add a wildcard derivation step (unhardened `*` or hardened `*h`) to this extended private key.
212    ///
213    /// If the key already has the same wildcard type, it is returned unchanged. Returns an error
214    /// if the key is not a single xprv, or if the key already has a wildcard of a different type.
215    pub fn add_wildcard(
216        &self,
217        wildcard_type: WildcardType,
218    ) -> Result<Arc<Self>, DescriptorKeyError> {
219        let descriptor_secret_key = &self.0;
220        match descriptor_secret_key {
221            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
222            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
223                let same_wildcard = (descriptor_x_key.wildcard == Wildcard::Unhardened
224                    && wildcard_type == WildcardType::Unhardened)
225                    || (descriptor_x_key.wildcard == Wildcard::Hardened
226                        && wildcard_type == WildcardType::Hardened);
227
228                // If there is a wildcard already present and it's of the same type as the one requested,
229                // return the same DescriptorSecretKey
230                if same_wildcard {
231                    let descriptor_secret_key_with_wildcard =
232                        BdkDescriptorSecretKey::XPrv(DescriptorXKey {
233                            origin: descriptor_x_key.origin.clone(),
234                            xkey: descriptor_x_key.xkey,
235                            derivation_path: descriptor_x_key.derivation_path.clone(),
236                            wildcard: descriptor_x_key.wildcard,
237                        });
238                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
239                } else if descriptor_x_key.wildcard == Wildcard::None {
240                    // If the descriptor doesn't have a wildcard, add the requested 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: wildcard_type.into(),
247                        });
248                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
249                } else {
250                    // If the descriptor already has a wildcard of a different type, return an error
251                    Err(DescriptorKeyError::CannotChangeWildcardType)
252                }
253            }
254            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
255        }
256    }
257
258    /// Return the descriptor public key corresponding to this secret.
259    pub fn as_public(&self) -> Arc<DescriptorPublicKey> {
260        let secp = Secp256k1::new();
261        let descriptor_public_key = self.0.to_public(&secp).unwrap();
262        Arc::new(DescriptorPublicKey(descriptor_public_key))
263    }
264
265    /// Return the bytes of this descriptor secret key.
266    pub fn secret_bytes(&self) -> Vec<u8> {
267        let inner = &self.0;
268        let secret_bytes: Vec<u8> = match inner {
269            BdkDescriptorSecretKey::Single(_) => {
270                unreachable!()
271            }
272            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
273                descriptor_x_key.xkey.private_key.secret_bytes().to_vec()
274            }
275            BdkDescriptorSecretKey::MultiXPrv(_) => {
276                unreachable!()
277            }
278        };
279
280        secret_bytes
281    }
282}
283
284impl Display for DescriptorSecretKey {
285    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286        self.0.fmt(f)
287    }
288}
289
290/// A descriptor public key.
291#[derive(Debug, uniffi::Object)]
292#[uniffi::export(Debug, Display)]
293pub struct DescriptorPublicKey(pub(crate) BdkDescriptorPublicKey);
294
295#[uniffi::export]
296impl DescriptorPublicKey {
297    /// Attempt to parse a string as a descriptor public key.
298    #[uniffi::constructor]
299    pub fn from_string(public_key: String) -> Result<Self, DescriptorKeyError> {
300        let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str())
301            .map_err(DescriptorKeyError::from)?;
302        Ok(Self(descriptor_public_key))
303    }
304
305    /// Derive the descriptor public key at the given derivation path.
306    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
307        let secp = Secp256k1::new();
308        let descriptor_public_key = &self.0;
309        match descriptor_public_key {
310            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
311            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
312                let derived_xpub = descriptor_x_key
313                    .xkey
314                    .derive_pub(&secp, &path.0)
315                    .map_err(DescriptorKeyError::from)?;
316                let key_source = match descriptor_x_key.origin.clone() {
317                    Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(&path.0)),
318                    None => (descriptor_x_key.xkey.fingerprint(), path.0.clone()),
319                };
320                let derived_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
321                    origin: Some(key_source),
322                    xkey: derived_xpub,
323                    derivation_path: BdkDerivationPath::default(),
324                    wildcard: descriptor_x_key.wildcard,
325                });
326                Ok(Arc::new(Self(derived_descriptor_public_key)))
327            }
328            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
329        }
330    }
331
332    /// Extend the descriptor public key by the given derivation path.
333    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
334        let descriptor_public_key = &self.0;
335        match descriptor_public_key {
336            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
337            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
338                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
339                let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
340                    origin: descriptor_x_key.origin.clone(),
341                    xkey: descriptor_x_key.xkey,
342                    derivation_path: extended_path,
343                    wildcard: descriptor_x_key.wildcard,
344                });
345                Ok(Arc::new(Self(extended_descriptor_public_key)))
346            }
347            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
348        }
349    }
350
351    /// Add an unhardened wildcard derivation step (`*`) to this extended public key.
352    ///
353    /// Public keys only support unhardened wildcards since xpubs cannot derive hardened children.
354    /// If the key already has an unhardened wildcard, it is returned unchanged. Returns an error
355    /// if the key is not a single xpub, or if the key already has a hardened wildcard.
356    pub fn add_wildcard(&self) -> Result<Arc<Self>, DescriptorKeyError> {
357        let descriptor_public_key = &self.0;
358        match descriptor_public_key {
359            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
360            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
361                // If there is a wildcard already present and it's unhardened,
362                // return the same DescriptorPublicKey
363                if descriptor_x_key.wildcard == Wildcard::Unhardened {
364                    let descriptor_public_key_with_wildcard =
365                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
366                            origin: descriptor_x_key.origin.clone(),
367                            xkey: descriptor_x_key.xkey,
368                            derivation_path: descriptor_x_key.derivation_path.clone(),
369                            wildcard: Wildcard::Unhardened,
370                        });
371                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
372                } else if descriptor_x_key.wildcard == Wildcard::None {
373                    // If the descriptor doesn't have a wildcard, add an Unhardened wildcard
374                    let descriptor_public_key_with_wildcard =
375                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
376                            origin: descriptor_x_key.origin.clone(),
377                            xkey: descriptor_x_key.xkey,
378                            derivation_path: descriptor_x_key.derivation_path.clone(),
379                            wildcard: Wildcard::Unhardened,
380                        });
381                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
382                } else {
383                    // 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
384                    Err(DescriptorKeyError::CannotChangeWildcardType)
385                }
386            }
387            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
388        }
389    }
390
391    /// Whether or not this key has multiple derivation paths.
392    pub fn is_multipath(&self) -> bool {
393        self.0.is_multipath()
394    }
395
396    /// The fingerprint of the master key associated with this key, `0x00000000` if none.
397    pub fn master_fingerprint(&self) -> String {
398        self.0.master_fingerprint().to_string()
399    }
400}
401
402impl Display for DescriptorPublicKey {
403    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
404        self.0.fmt(f)
405    }
406}