Added interfaces DescriptorSecretKey and DescriptorPublicKey
This commit is contained in:
parent
4977cb6d68
commit
58fea6b205
23
src/bdk.udl
23
src/bdk.udl
@ -250,3 +250,26 @@ interface DerivationPath {
|
|||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string path);
|
constructor(string path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface DescriptorSecretKey {
|
||||||
|
[Throws=BdkError]
|
||||||
|
constructor(Network network, string mnemonic, string? password);
|
||||||
|
|
||||||
|
[Throws=BdkError]
|
||||||
|
DescriptorSecretKey derive(DerivationPath path);
|
||||||
|
|
||||||
|
DescriptorSecretKey extend(DerivationPath path);
|
||||||
|
|
||||||
|
DescriptorPublicKey as_public();
|
||||||
|
|
||||||
|
string as_string();
|
||||||
|
};
|
||||||
|
|
||||||
|
interface DescriptorPublicKey {
|
||||||
|
[Throws=BdkError]
|
||||||
|
DescriptorPublicKey derive(DerivationPath path);
|
||||||
|
|
||||||
|
DescriptorPublicKey extend(DerivationPath path);
|
||||||
|
|
||||||
|
string as_string();
|
||||||
|
};
|
146
src/lib.rs
146
src/lib.rs
@ -1,7 +1,7 @@
|
|||||||
use bdk::bitcoin::hashes::hex::ToHex;
|
use bdk::bitcoin::hashes::hex::ToHex;
|
||||||
use bdk::bitcoin::secp256k1::Secp256k1;
|
use bdk::bitcoin::secp256k1::Secp256k1;
|
||||||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
|
|
||||||
use bdk::bitcoin::util::bip32::DerivationPath as BdkDerivationPath;
|
use bdk::bitcoin::util::bip32::DerivationPath as BdkDerivationPath;
|
||||||
|
use bdk::bitcoin::util::psbt::PartiallySignedTransaction;
|
||||||
use bdk::bitcoin::{Address, Network, OutPoint as BdkOutPoint, Script, Txid};
|
use bdk::bitcoin::{Address, Network, OutPoint as BdkOutPoint, Script, Txid};
|
||||||
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
||||||
use bdk::blockchain::{
|
use bdk::blockchain::{
|
||||||
@ -10,8 +10,12 @@ use bdk::blockchain::{
|
|||||||
use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress};
|
use bdk::blockchain::{Blockchain as BdkBlockchain, Progress as BdkProgress};
|
||||||
use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration};
|
use bdk::database::any::{AnyDatabase, SledDbConfiguration, SqliteDbConfiguration};
|
||||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
|
use bdk::descriptor::DescriptorXKey;
|
||||||
use bdk::keys::bip39::{Language, Mnemonic, WordCount};
|
use bdk::keys::bip39::{Language, Mnemonic, WordCount};
|
||||||
use bdk::keys::{DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey};
|
use bdk::keys::{
|
||||||
|
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
|
||||||
|
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
||||||
|
};
|
||||||
use bdk::miniscript::BareCtx;
|
use bdk::miniscript::BareCtx;
|
||||||
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
||||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||||
@ -648,6 +652,144 @@ impl DerivationPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DescriptorSecretKey {
|
||||||
|
descriptor_secret_key_mutex: Mutex<BdkDescriptorSecretKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DescriptorSecretKey {
|
||||||
|
fn new(network: Network, mnemonic: String, password: Option<String>) -> Result<Self, BdkError> {
|
||||||
|
let mnemonic = Mnemonic::parse_in(Language::English, mnemonic)
|
||||||
|
.map_err(|e| BdkError::Generic(e.to_string()))?;
|
||||||
|
let xkey: ExtendedKey = (mnemonic, password).into_extended_key()?;
|
||||||
|
let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
|
||||||
|
origin: None,
|
||||||
|
xkey: xkey.into_xprv(network).unwrap(),
|
||||||
|
derivation_path: BdkDerivationPath::master(),
|
||||||
|
wildcard: bdk::descriptor::Wildcard::Unhardened,
|
||||||
|
});
|
||||||
|
Ok(Self {
|
||||||
|
descriptor_secret_key_mutex: Mutex::new(descriptor_secret_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap();
|
||||||
|
let path = path.derivation_path_mutex.lock().unwrap().deref().clone();
|
||||||
|
let descriptor_x_key = match descriptor_secret_key.deref() {
|
||||||
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => Some(descriptor_x_key),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
let derived_xprv = descriptor_x_key.xkey.derive_priv(&secp, &path)?;
|
||||||
|
let key_source = match descriptor_x_key.origin.clone() {
|
||||||
|
Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)),
|
||||||
|
None => (descriptor_x_key.xkey.fingerprint(&secp), path),
|
||||||
|
};
|
||||||
|
let derived_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
|
||||||
|
origin: Some(key_source),
|
||||||
|
xkey: derived_xprv,
|
||||||
|
derivation_path: BdkDerivationPath::default(),
|
||||||
|
wildcard: descriptor_x_key.wildcard,
|
||||||
|
});
|
||||||
|
Ok(Arc::new(Self {
|
||||||
|
descriptor_secret_key_mutex: Mutex::new(derived_descriptor_secret_key),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> {
|
||||||
|
let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap();
|
||||||
|
let path = path.derivation_path_mutex.lock().unwrap().deref().clone();
|
||||||
|
let descriptor_x_key = match descriptor_secret_key.deref() {
|
||||||
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => Some(descriptor_x_key),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
let extended_path = descriptor_x_key.derivation_path.extend(path);
|
||||||
|
let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
|
||||||
|
origin: descriptor_x_key.origin.clone(),
|
||||||
|
xkey: descriptor_x_key.xkey,
|
||||||
|
derivation_path: extended_path,
|
||||||
|
wildcard: descriptor_x_key.wildcard,
|
||||||
|
});
|
||||||
|
Arc::new(Self {
|
||||||
|
descriptor_secret_key_mutex: Mutex::new(extended_descriptor_secret_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_public(&self) -> Arc<DescriptorPublicKey> {
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let descriptor_public_key = self
|
||||||
|
.descriptor_secret_key_mutex
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.as_public(&secp)
|
||||||
|
.unwrap();
|
||||||
|
Arc::new(DescriptorPublicKey {
|
||||||
|
descriptor_public_key_mutex: Mutex::new(descriptor_public_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_string(&self) -> String {
|
||||||
|
self.descriptor_secret_key_mutex.lock().unwrap().to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DescriptorPublicKey {
|
||||||
|
descriptor_public_key_mutex: Mutex<BdkDescriptorPublicKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DescriptorPublicKey {
|
||||||
|
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
|
let secp = Secp256k1::new();
|
||||||
|
let descriptor_public_key = self.descriptor_public_key_mutex.lock().unwrap();
|
||||||
|
let path = path.derivation_path_mutex.lock().unwrap().deref().clone();
|
||||||
|
let descriptor_x_key = match descriptor_public_key.deref() {
|
||||||
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => Some(descriptor_x_key),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?;
|
||||||
|
let key_source = match descriptor_x_key.origin.clone() {
|
||||||
|
Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)),
|
||||||
|
None => (descriptor_x_key.xkey.fingerprint(), path),
|
||||||
|
};
|
||||||
|
let derived_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
|
||||||
|
origin: Some(key_source),
|
||||||
|
xkey: derived_xpub,
|
||||||
|
derivation_path: BdkDerivationPath::default(),
|
||||||
|
wildcard: descriptor_x_key.wildcard,
|
||||||
|
});
|
||||||
|
Ok(Arc::new(Self {
|
||||||
|
descriptor_public_key_mutex: Mutex::new(derived_descriptor_public_key),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> {
|
||||||
|
let descriptor_secret_key = self.descriptor_public_key_mutex.lock().unwrap();
|
||||||
|
let path = path.derivation_path_mutex.lock().unwrap().deref().clone();
|
||||||
|
let descriptor_x_key = match descriptor_secret_key.deref() {
|
||||||
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => Some(descriptor_x_key),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
let extended_path = descriptor_x_key.derivation_path.extend(path);
|
||||||
|
let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
|
||||||
|
origin: descriptor_x_key.origin.clone(),
|
||||||
|
xkey: descriptor_x_key.xkey,
|
||||||
|
derivation_path: extended_path,
|
||||||
|
wildcard: descriptor_x_key.wildcard,
|
||||||
|
});
|
||||||
|
Arc::new(Self {
|
||||||
|
descriptor_public_key_mutex: Mutex::new(extended_descriptor_public_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_string(&self) -> String {
|
||||||
|
self.descriptor_public_key_mutex.lock().unwrap().to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
||||||
|
|
||||||
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user