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    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
168        let secp = Secp256k1::new();
169        let descriptor_secret_key = &self.0;
170        match descriptor_secret_key {
171            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
172            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
173                let derived_xprv = descriptor_x_key
174                    .xkey
175                    .derive_priv(&secp, &path.0)
176                    .map_err(DescriptorKeyError::from)?;
177                let key_source = match descriptor_x_key.origin.clone() {
178                    Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(&path.0)),
179                    None => (descriptor_x_key.xkey.fingerprint(&secp), path.0.clone()),
180                };
181                let derived_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
182                    origin: Some(key_source),
183                    xkey: derived_xprv,
184                    derivation_path: BdkDerivationPath::default(),
185                    wildcard: descriptor_x_key.wildcard,
186                });
187                Ok(Arc::new(Self(derived_descriptor_secret_key)))
188            }
189            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
190        }
191    }
192
193    /// Extend the descriptor secret key by the derivation path.
194    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
195        let descriptor_secret_key = &self.0;
196        match descriptor_secret_key {
197            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
198            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
199                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
200                let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
201                    origin: descriptor_x_key.origin.clone(),
202                    xkey: descriptor_x_key.xkey,
203                    derivation_path: extended_path,
204                    wildcard: descriptor_x_key.wildcard,
205                });
206                Ok(Arc::new(Self(extended_descriptor_secret_key)))
207            }
208            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
209        }
210    }
211
212    /// Add a wildcard derivation step (unhardened `*` or hardened `*h`) to this extended private key.
213    ///
214    /// If the key already has the same wildcard type, it is returned unchanged. Returns an error
215    /// if the key is not a single xprv, or if the key already has a wildcard of a different type.
216    pub fn add_wildcard(
217        &self,
218        wildcard_type: WildcardType,
219    ) -> Result<Arc<Self>, DescriptorKeyError> {
220        let descriptor_secret_key = &self.0;
221        match descriptor_secret_key {
222            BdkDescriptorSecretKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
223            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
224                let same_wildcard = (descriptor_x_key.wildcard == Wildcard::Unhardened
225                    && wildcard_type == WildcardType::Unhardened)
226                    || (descriptor_x_key.wildcard == Wildcard::Hardened
227                        && wildcard_type == WildcardType::Hardened);
228
229                // If there is a wildcard already present and it's of the same type as the one requested,
230                // return the same DescriptorSecretKey
231                if same_wildcard {
232                    let descriptor_secret_key_with_wildcard =
233                        BdkDescriptorSecretKey::XPrv(DescriptorXKey {
234                            origin: descriptor_x_key.origin.clone(),
235                            xkey: descriptor_x_key.xkey,
236                            derivation_path: descriptor_x_key.derivation_path.clone(),
237                            wildcard: descriptor_x_key.wildcard,
238                        });
239                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
240                } else if descriptor_x_key.wildcard == Wildcard::None {
241                    // If the descriptor doesn't have a wildcard, add the requested wildcard
242                    let descriptor_secret_key_with_wildcard =
243                        BdkDescriptorSecretKey::XPrv(DescriptorXKey {
244                            origin: descriptor_x_key.origin.clone(),
245                            xkey: descriptor_x_key.xkey,
246                            derivation_path: descriptor_x_key.derivation_path.clone(),
247                            wildcard: wildcard_type.into(),
248                        });
249                    Ok(Arc::new(Self(descriptor_secret_key_with_wildcard)))
250                } else {
251                    // If the descriptor already has a wildcard of a different type, return an error
252                    Err(DescriptorKeyError::CannotChangeWildcardType)
253                }
254            }
255            BdkDescriptorSecretKey::MultiXPrv(_) => Err(DescriptorKeyError::InvalidKeyType),
256        }
257    }
258
259    /// Return the descriptor public key corresponding to this secret.
260    pub fn as_public(&self) -> Arc<DescriptorPublicKey> {
261        let secp = Secp256k1::new();
262        let descriptor_public_key = self.0.to_public(&secp).unwrap();
263        Arc::new(DescriptorPublicKey(descriptor_public_key))
264    }
265
266    /// Return the bytes of this descriptor secret key.
267    pub fn secret_bytes(&self) -> Vec<u8> {
268        let inner = &self.0;
269        let secret_bytes: Vec<u8> = match inner {
270            BdkDescriptorSecretKey::Single(single_key) => {
271                single_key.key.inner.secret_bytes().to_vec()
272            }
273            BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
274                descriptor_x_key.xkey.private_key.secret_bytes().to_vec()
275            }
276            BdkDescriptorSecretKey::MultiXPrv(descriptor_multi_x_key) => descriptor_multi_x_key
277                .xkey
278                .private_key
279                .secret_bytes()
280                .to_vec(),
281        };
282
283        secret_bytes
284    }
285}
286
287impl Display for DescriptorSecretKey {
288    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289        self.0.fmt(f)
290    }
291}
292
293/// A descriptor public key.
294#[derive(Debug, uniffi::Object)]
295#[uniffi::export(Debug, Display)]
296pub struct DescriptorPublicKey(pub(crate) BdkDescriptorPublicKey);
297
298#[uniffi::export]
299impl DescriptorPublicKey {
300    /// Attempt to parse a string as a descriptor public key.
301    #[uniffi::constructor]
302    pub fn from_string(public_key: String) -> Result<Self, DescriptorKeyError> {
303        let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str())
304            .map_err(DescriptorKeyError::from)?;
305        Ok(Self(descriptor_public_key))
306    }
307
308    /// Derive the descriptor public key at the given derivation path.
309    pub fn derive(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
310        let secp = Secp256k1::new();
311        let descriptor_public_key = &self.0;
312        match descriptor_public_key {
313            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
314            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
315                let derived_xpub = descriptor_x_key
316                    .xkey
317                    .derive_pub(&secp, &path.0)
318                    .map_err(DescriptorKeyError::from)?;
319                let key_source = match descriptor_x_key.origin.clone() {
320                    Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(&path.0)),
321                    None => (descriptor_x_key.xkey.fingerprint(), path.0.clone()),
322                };
323                let derived_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
324                    origin: Some(key_source),
325                    xkey: derived_xpub,
326                    derivation_path: BdkDerivationPath::default(),
327                    wildcard: descriptor_x_key.wildcard,
328                });
329                Ok(Arc::new(Self(derived_descriptor_public_key)))
330            }
331            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
332        }
333    }
334
335    /// Extend the descriptor public key by the given derivation path.
336    pub fn extend(&self, path: &DerivationPath) -> Result<Arc<Self>, DescriptorKeyError> {
337        let descriptor_public_key = &self.0;
338        match descriptor_public_key {
339            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
340            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
341                let extended_path = descriptor_x_key.derivation_path.extend(&path.0);
342                let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
343                    origin: descriptor_x_key.origin.clone(),
344                    xkey: descriptor_x_key.xkey,
345                    derivation_path: extended_path,
346                    wildcard: descriptor_x_key.wildcard,
347                });
348                Ok(Arc::new(Self(extended_descriptor_public_key)))
349            }
350            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
351        }
352    }
353
354    /// Add an unhardened wildcard derivation step (`*`) to this extended public key.
355    ///
356    /// Public keys only support unhardened wildcards since xpubs cannot derive hardened children.
357    /// If the key already has an unhardened wildcard, it is returned unchanged. Returns an error
358    /// if the key is not a single xpub, or if the key already has a hardened wildcard.
359    pub fn add_wildcard(&self) -> Result<Arc<Self>, DescriptorKeyError> {
360        let descriptor_public_key = &self.0;
361        match descriptor_public_key {
362            BdkDescriptorPublicKey::Single(_) => Err(DescriptorKeyError::InvalidKeyType),
363            BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
364                // If there is a wildcard already present and it's unhardened,
365                // return the same DescriptorPublicKey
366                if descriptor_x_key.wildcard == Wildcard::Unhardened {
367                    let descriptor_public_key_with_wildcard =
368                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
369                            origin: descriptor_x_key.origin.clone(),
370                            xkey: descriptor_x_key.xkey,
371                            derivation_path: descriptor_x_key.derivation_path.clone(),
372                            wildcard: Wildcard::Unhardened,
373                        });
374                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
375                } else if descriptor_x_key.wildcard == Wildcard::None {
376                    // If the descriptor doesn't have a wildcard, add an Unhardened wildcard
377                    let descriptor_public_key_with_wildcard =
378                        BdkDescriptorPublicKey::XPub(DescriptorXKey {
379                            origin: descriptor_x_key.origin.clone(),
380                            xkey: descriptor_x_key.xkey,
381                            derivation_path: descriptor_x_key.derivation_path.clone(),
382                            wildcard: Wildcard::Unhardened,
383                        });
384                    Ok(Arc::new(Self(descriptor_public_key_with_wildcard)))
385                } else {
386                    // 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
387                    Err(DescriptorKeyError::CannotChangeWildcardType)
388                }
389            }
390            BdkDescriptorPublicKey::MultiXPub(_) => Err(DescriptorKeyError::InvalidKeyType),
391        }
392    }
393
394    /// Whether or not this key has multiple derivation paths.
395    pub fn is_multipath(&self) -> bool {
396        self.0.is_multipath()
397    }
398
399    /// The fingerprint of the master key associated with this key, `0x00000000` if none.
400    pub fn master_fingerprint(&self) -> String {
401        self.0.master_fingerprint().to_string()
402    }
403}
404
405impl Display for DescriptorPublicKey {
406    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
407        self.0.fmt(f)
408    }
409}