diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index 84a0b07d..3d70c893 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -122,7 +122,7 @@ interface Wallet { sequence transactions(); }; -interface PersistedWallet { +interface WalletPersisted { [Throws=TempFfiError] constructor(Descriptor descriptor, Descriptor? change_descriptor, string persistence_backend_path, Network network); diff --git a/bdk-ffi/src/bitcoin.rs b/bdk-ffi/src/bitcoin.rs index a5a38d77..7a266247 100644 --- a/bdk-ffi/src/bitcoin.rs +++ b/bdk-ffi/src/bitcoin.rs @@ -4,15 +4,15 @@ use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut; use bdk::bitcoin::consensus::Decodable; use bdk::bitcoin::network::constants::Network as BdkNetwork; use bdk::bitcoin::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction; -use bdk::bitcoin::{Address as BdkAddress}; +use bdk::bitcoin::Address as BdkAddress; use bdk::bitcoin::OutPoint as BdkOutPoint; use bdk::bitcoin::Transaction as BdkTransaction; use bdk::bitcoin::Txid; +use crate::error::TempFfiError; use std::io::Cursor; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use crate::error::TempFfiError; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Script(pub(crate) BdkScriptBuf); @@ -143,8 +143,8 @@ pub struct Transaction { impl Transaction { pub fn new(transaction_bytes: Vec) -> Result { let mut decoder = Cursor::new(transaction_bytes); - let tx: BdkTransaction = BdkTransaction::consensus_decode(&mut decoder) - .map_err(|_| TempFfiError::FfiError)?; + let tx: BdkTransaction = + BdkTransaction::consensus_decode(&mut decoder).map_err(|_| TempFfiError::FfiError)?; Ok(Transaction { inner: tx }) } diff --git a/bdk-ffi/src/descriptor.rs b/bdk-ffi/src/descriptor.rs index e318d6d5..42298ae8 100644 --- a/bdk-ffi/src/descriptor.rs +++ b/bdk-ffi/src/descriptor.rs @@ -279,10 +279,6 @@ impl Descriptor { #[cfg(test)] mod test { use crate::*; - use assert_matches::assert_matches; - - use bdk::descriptor::DescriptorError::Key; - use bdk::keys::KeyError::InvalidNetwork; fn get_descriptor_secret_key() -> DescriptorSecretKey { let mnemonic = Mnemonic::from_string("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string()).unwrap(); @@ -397,7 +393,7 @@ mod test { #[test] fn test_descriptor_from_string() { let descriptor1 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Testnet); - let descriptor2 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Bitcoin); + // let descriptor2 = Descriptor::new("wpkh(tprv8hwWMmPE4BVNxGdVt3HhEERZhondQvodUY7Ajyseyhudr4WabJqWKWLr4Wi2r26CDaNCQhhxEftEaNzz7dPGhWuKFU4VULesmhEfZYyBXdE/0/*)".to_string(), Network::Bitcoin); // Creating a Descriptor using an extended key that doesn't match the network provided will throw and InvalidNetwork Error assert!(descriptor1.is_ok()); // assert_matches!( diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 5a164ef1..a08f4bf7 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -1,14 +1,14 @@ -use core::fmt; -use std::convert::Infallible; use bdk::descriptor::DescriptorError; use bdk::wallet::error::{BuildFeeBumpError, CreateTxError}; -use bdk::wallet::{NewError, NewOrLoadError}; use bdk::wallet::tx_builder::{AddUtxoError, AllowShrinkingError}; +use bdk::wallet::{NewError, NewOrLoadError}; use bdk_file_store::{FileError, IterError}; +use core::fmt; +use std::convert::Infallible; #[derive(Debug, thiserror::Error)] pub enum TempFfiError { - FfiError + FfiError, } impl fmt::Display for TempFfiError { @@ -70,3 +70,9 @@ impl From> for TempFfiError { TempFfiError::FfiError } } + +impl From> for TempFfiError { + fn from(_: CreateTxError) -> Self { + TempFfiError::FfiError + } +} diff --git a/bdk-ffi/src/esplora.rs b/bdk-ffi/src/esplora.rs index 6c0d7955..f5078d5f 100644 --- a/bdk-ffi/src/esplora.rs +++ b/bdk-ffi/src/esplora.rs @@ -6,8 +6,8 @@ use bdk_esplora::esplora_client::{BlockingClient, Builder}; use bdk_esplora::EsploraExt; use crate::bitcoin::Transaction; -use std::sync::Arc; use crate::error::TempFfiError; +use std::sync::Arc; pub struct EsploraClient(BlockingClient); diff --git a/bdk-ffi/src/keys.rs b/bdk-ffi/src/keys.rs index b5850ed1..990b5a53 100644 --- a/bdk-ffi/src/keys.rs +++ b/bdk-ffi/src/keys.rs @@ -13,10 +13,10 @@ use bdk::keys::{ use bdk::miniscript::descriptor::{DescriptorXKey, Wildcard}; use bdk::miniscript::BareCtx; +use crate::error::TempFfiError; use std::ops::Deref; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use crate::error::TempFfiError; pub(crate) struct Mnemonic { inner: BdkMnemonic, @@ -248,9 +248,9 @@ impl DescriptorPublicKey { mod test { use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic}; // use bdk::bitcoin::hashes::hex::ToHex; + use crate::error::TempFfiError; use bdk::bitcoin::Network; use std::sync::Arc; - use crate::error::TempFfiError; fn get_inner() -> DescriptorSecretKey { let mnemonic = Mnemonic::from_string("chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string()).unwrap(); diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index 7fa11591..c9bdc06a 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -2,11 +2,11 @@ extern crate core; mod bitcoin; mod descriptor; +mod error; mod esplora; mod keys; mod types; mod wallet; -mod error; use crate::bitcoin::Address; use crate::bitcoin::Network; @@ -16,6 +16,7 @@ use crate::bitcoin::Script; use crate::bitcoin::Transaction; use crate::bitcoin::TxOut; use crate::descriptor::Descriptor; +use crate::error::TempFfiError; use crate::esplora::EsploraClient; use crate::keys::DerivationPath; use crate::keys::DescriptorPublicKey; @@ -31,8 +32,7 @@ use crate::wallet::SentAndReceivedValues; use crate::wallet::TxBuilder; use crate::wallet::Update; use crate::wallet::Wallet; -use crate::wallet::PersistedWallet; -use crate::error::TempFfiError; +use crate::wallet::WalletPersisted; use bdk::keys::bip39::WordCount; use bdk::wallet::tx_builder::ChangeSpendPolicy; diff --git a/bdk-ffi/src/wallet.rs b/bdk-ffi/src/wallet.rs index 9f4598dc..74d763d5 100644 --- a/bdk-ffi/src/wallet.rs +++ b/bdk-ffi/src/wallet.rs @@ -1,6 +1,6 @@ use crate::bitcoin::{OutPoint, PartiallySignedTransaction, Transaction}; use crate::descriptor::Descriptor; -use crate::types::{Balance}; +use crate::types::Balance; use crate::types::ScriptAmount; use crate::Script; use crate::{AddressIndex, AddressInfo, Network}; @@ -14,12 +14,12 @@ use bdk::FeeRate; use bdk::{SignOptions, Wallet as BdkWallet}; use bdk_file_store::Store; -// type BdkPersistedWallet<'a> = bdk::wallet::Wallet>; - +use crate::error::TempFfiError; use std::collections::HashSet; use std::str::FromStr; use std::sync::{Arc, Mutex, MutexGuard}; -use crate::error::TempFfiError; + +const MAGIC_BYTES: &[u8] = "bdkffi".as_bytes(); #[derive(Debug)] pub struct Wallet { @@ -27,15 +27,11 @@ pub struct Wallet { inner_mutex: Mutex, } - - -// TODO: I don't understand well these lifetime parameters yet -pub struct PersistedWallet { - inner_mutex: Mutex>>>, +pub struct WalletPersisted { + inner_mutex: Mutex>>, } -// TODO: I don't understand well these lifetime parameters yet -impl PersistedWallet { +impl WalletPersisted { pub fn new( descriptor: Arc, change_descriptor: Option>, @@ -44,70 +40,26 @@ impl PersistedWallet { ) -> Result { let descriptor = descriptor.as_string_private(); let change_descriptor = change_descriptor.map(|d| d.as_string_private()); - let db = Arc::new(Store::::open_or_create_new("testbdkffi".as_bytes(), persistence_backend_path))?; + let db = Store::::open_or_create_new(MAGIC_BYTES, persistence_backend_path)?; - let wallet: bdk::wallet::Wallet> = BdkWallet::new( - &descriptor, - change_descriptor.as_ref(), - db, - network.into(), - )?; + let wallet: bdk::wallet::Wallet> = + BdkWallet::new_or_load(&descriptor, change_descriptor.as_ref(), db, network.into())?; - Ok(PersistedWallet { + Ok(WalletPersisted { inner_mutex: Mutex::new(wallet), }) } - pub(crate) fn get_wallet(&self) -> MutexGuard>> { + pub(crate) fn get_wallet(&self) -> MutexGuard>> { self.inner_mutex.lock().expect("wallet") } pub fn get_address(&self, address_index: AddressIndex) -> AddressInfo { - self.get_wallet().try_get_address(address_index.into()).unwrap().into() + self.get_wallet() + .try_get_address(address_index.into()) + .unwrap() + .into() } - - // pub fn network(&self) -> Network { - // self.get_wallet().network().into() - // } - // - // pub fn get_internal_address(&self, address_index: AddressIndex) -> AddressInfo { - // self.get_wallet() - // .get_internal_address(address_index.into()) - // .into() - // } - // - // pub fn get_balance(&self) -> Balance { - // let bdk_balance: bdk::wallet::Balance = self.get_wallet().get_balance(); - // Balance::from(bdk_balance) - // } - // - // pub fn apply_update(&self, update: Arc) -> Result<(), TempFfiError> { - // self.get_wallet() - // .apply_update(update.0.clone()) - // .map_err(|e| TempFfiError::FfiError) - // } - // - // pub fn is_mine(&self, script: &Script) -> bool { - // // TODO: Both of the following lines work. Which is better? - // self.get_wallet().is_mine(&script.0) - // // self.get_wallet().is_mine(script.0.clone().as_script()) - // } - // - // pub(crate) fn sign( - // &self, - // psbt: Arc, - // // sign_options: Option, - // ) -> Result { - // let mut psbt = psbt.inner.lock().unwrap(); - // self.get_wallet() - // .sign(&mut psbt, SignOptions::default()) - // .map_err(|e| TempFfiError::FfiError) - // } - // - // pub fn sent_and_received(&self, tx: &Transaction) -> SentAndReceivedValues { - // let (sent, received): (u64, u64) = self.get_wallet().sent_and_received(&tx.clone().into()); - // SentAndReceivedValues { sent, received } - // } } impl Wallet { @@ -154,7 +106,7 @@ impl Wallet { pub fn apply_update(&self, update: Arc) -> Result<(), TempFfiError> { self.get_wallet() .apply_update(update.0.clone()) - .map_err(|e| TempFfiError::FfiError) + .map_err(|_| TempFfiError::FfiError) } pub fn is_mine(&self, script: &Script) -> bool { @@ -171,7 +123,7 @@ impl Wallet { let mut psbt = psbt.inner.lock().unwrap(); self.get_wallet() .sign(&mut psbt, SignOptions::default()) - .map_err(|e| TempFfiError::FfiError) + .map_err(|_| TempFfiError::FfiError) } pub fn sent_and_received(&self, tx: &Transaction) -> SentAndReceivedValues { @@ -638,8 +590,7 @@ impl BumpFeeTxBuilder { &self, wallet: &Wallet, ) -> Result, TempFfiError> { - let txid = - Txid::from_str(self.txid.as_str()).map_err(|e| TempFfiError::FfiError)?; + let txid = Txid::from_str(self.txid.as_str()).map_err(|_| TempFfiError::FfiError)?; let mut wallet = wallet.get_wallet(); let mut tx_builder = wallet.build_fee_bump(txid)?; tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate)); @@ -656,9 +607,8 @@ impl BumpFeeTxBuilder { } } } - let psbt: BdkPartiallySignedTransaction = tx_builder - .finish() - .map_err(|e| TempFfiError::FfiError)?; + let psbt: BdkPartiallySignedTransaction = + tx_builder.finish().map_err(|_| TempFfiError::FfiError)?; Ok(Arc::new(psbt.into())) }