diff --git a/bdk-ffi/Cargo.lock b/bdk-ffi/Cargo.lock index 1c534061..9dc68e4a 100644 --- a/bdk-ffi/Cargo.lock +++ b/bdk-ffi/Cargo.lock @@ -119,7 +119,7 @@ dependencies = [ [[package]] name = "bdk-ffi" -version = "2.3.0-alpha.0" +version = "3.0.0-rc.1" dependencies = [ "assert_matches", "bdk_electrum", @@ -177,8 +177,7 @@ dependencies = [ [[package]] name = "bdk_kyoto" version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f35b9f8b3aa8c4647bec7a92b050c496742d955e0ac1edcb4e7c2deabf63c54" +source = "git+https://github.com/reez/bdk-kyoto?branch=rc1#7303e1e2d2d944a7ba2b13bcc3d92c605b0f1afa" dependencies = [ "bdk_wallet", "bip157", @@ -186,9 +185,9 @@ dependencies = [ [[package]] name = "bdk_wallet" -version = "2.3.0" +version = "3.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03f1e31ccc562f600981f747d2262b84428cbff52c9c9cdf14d15fb15bd2286" +checksum = "70031c96c223c780525f4b9c52813e4f5bd8000a5712aac3248d00838af1e436" dependencies = [ "bdk_chain", "bip39", @@ -207,13 +206,14 @@ checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "bip157" -version = "0.3.4" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88df5c18baaea9be4219679afbd4fc26491606f89f6ecdaffcdcabd67635b07b" +checksum = "8af7987396c76633777e335345347395cd383b46bd95c1534691ab717859482e" dependencies = [ "bip324", "bitcoin", "bitcoin-address-book", + "bitcoin_hashes 0.20.0", "tokio", ] @@ -269,6 +269,15 @@ dependencies = [ "bitcoin", ] +[[package]] +name = "bitcoin-consensus-encoding" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d7ca3dc8ff835693ad73bf1596240c06f974a31eeb3f611aaedf855f1f2725" +dependencies = [ + "bitcoin-internals 0.5.0", +] + [[package]] name = "bitcoin-internals" version = "0.3.0" @@ -284,6 +293,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a90bbbfa552b49101a230fb2668f3f9ef968c81e6f83cf577e1d4b80f689e1aa" +[[package]] +name = "bitcoin-internals" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a30a22d1f112dde8e16be7b45c63645dc165cef254f835b3e1e9553e485cfa64" + [[package]] name = "bitcoin-io" version = "0.1.4" @@ -330,6 +345,17 @@ dependencies = [ "hex-conservative 0.3.2", ] +[[package]] +name = "bitcoin_hashes" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8a45c2b41c457a9a9e4670422fcbdf109afb3b22bc920b4045e8bdfd788a3d" +dependencies = [ + "bitcoin-consensus-encoding", + "bitcoin-internals 0.5.0", + "hex-conservative 0.3.2", +] + [[package]] name = "bitflags" version = "2.11.0" diff --git a/bdk-ffi/Cargo.toml b/bdk-ffi/Cargo.toml index 662ffe67..05d5f714 100644 --- a/bdk-ffi/Cargo.toml +++ b/bdk-ffi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bdk-ffi" -version = "2.4.0-alpha.0" +version = "3.0.0-rc.1" homepage = "https://bitcoindevkit.org" repository = "https://github.com/bitcoindevkit/bdk" edition = "2018" @@ -15,10 +15,10 @@ name = "uniffi-bindgen" path = "uniffi-bindgen.rs" [dependencies] -bdk_wallet = { version = "2.3.0", features = ["all-keys", "keys-bip39", "rusqlite"] } +bdk_wallet = { version = "=3.0.0-rc.1", features = ["all-keys", "keys-bip39", "rusqlite"] } bdk_esplora = { version = "0.22.1", default-features = false, features = ["std", "blocking", "blocking-https-rustls"] } bdk_electrum = { version = "0.23.2", default-features = false, features = ["use-rustls-ring"] } -bdk_kyoto = { version = "0.15.4" } +bdk_kyoto = { git = "https://github.com/reez/bdk-kyoto", branch = "rc1" } uniffi = { version = "=0.30.0", features = ["cli"]} thiserror = "2.0.17" diff --git a/bdk-ffi/src/descriptor.rs b/bdk-ffi/src/descriptor.rs index db705391..f4e84f89 100644 --- a/bdk-ffi/src/descriptor.rs +++ b/bdk-ffi/src/descriptor.rs @@ -38,7 +38,8 @@ impl Descriptor { #[uniffi::constructor] pub fn new(descriptor: String, network: Network) -> Result { let secp = Secp256k1::new(); - let (extended_descriptor, key_map) = descriptor.into_wallet_descriptor(&secp, network)?; + let (extended_descriptor, key_map) = + descriptor.into_wallet_descriptor(&secp, network.into())?; Ok(Self { extended_descriptor, key_map, @@ -60,8 +61,9 @@ impl Descriptor { } BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip44(derivable_key, keychain_kind).build(network).unwrap(); + let (extended_descriptor, key_map, _) = Bip44(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -96,7 +98,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip44Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .map_err(DescriptorError::from)?; Ok(Self { @@ -125,8 +127,9 @@ impl Descriptor { } BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip49(derivable_key, keychain_kind).build(network).unwrap(); + let (extended_descriptor, key_map, _) = Bip49(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -161,7 +164,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip49Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .map_err(DescriptorError::from)?; Ok(Self { @@ -190,8 +193,9 @@ impl Descriptor { } BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip84(derivable_key, keychain_kind).build(network).unwrap(); + let (extended_descriptor, key_map, _) = Bip84(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -226,7 +230,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip84Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .map_err(DescriptorError::from)?; Ok(Self { @@ -255,8 +259,9 @@ impl Descriptor { } BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { let derivable_key = descriptor_x_key.xkey; - let (extended_descriptor, key_map, _) = - Bip86(derivable_key, keychain_kind).build(network).unwrap(); + let (extended_descriptor, key_map, _) = Bip86(derivable_key, keychain_kind) + .build(network.into()) + .unwrap(); Self { extended_descriptor, key_map, @@ -291,7 +296,7 @@ impl Descriptor { let derivable_key = descriptor_x_key.xkey; let (extended_descriptor, key_map, _) = Bip86Public(derivable_key, fingerprint, keychain_kind) - .build(network) + .build(network.into()) .map_err(DescriptorError::from)?; Ok(Self { diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 10b6d8b1..f64a614b 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -1561,7 +1561,7 @@ impl From for SignerError { BdkSignerError::MissingKey => SignerError::MissingKey, BdkSignerError::InvalidKey => SignerError::InvalidKey, BdkSignerError::UserCanceled => SignerError::UserCanceled, - BdkSignerError::InputIndexOutOfRange => SignerError::InputIndexOutOfRange, + BdkSignerError::InputIndexOutOfRange(_) => SignerError::InputIndexOutOfRange, BdkSignerError::MissingNonWitnessUtxo => SignerError::MissingNonWitnessUtxo, BdkSignerError::InvalidNonWitnessUtxo => SignerError::InvalidNonWitnessUtxo, BdkSignerError::MissingWitnessUtxo => SignerError::MissingWitnessUtxo, diff --git a/bdk-ffi/src/keys.rs b/bdk-ffi/src/keys.rs index 34bdf0b1..0cc904a3 100644 --- a/bdk-ffi/src/keys.rs +++ b/bdk-ffi/src/keys.rs @@ -147,7 +147,7 @@ impl DescriptorSecretKey { let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap(); let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { origin: None, - xkey: xkey.into_xprv(network).unwrap(), + xkey: xkey.into_xprv(network.into()).unwrap(), derivation_path: BdkDerivationPath::master(), wildcard: Wildcard::Unhardened, }); diff --git a/bdk-ffi/src/kyoto.rs b/bdk-ffi/src/kyoto.rs index 2323e94d..18c6cb05 100644 --- a/bdk-ffi/src/kyoto.rs +++ b/bdk-ffi/src/kyoto.rs @@ -7,7 +7,6 @@ use bdk_kyoto::bip157::ServiceFlags; use bdk_kyoto::builder::Builder as BDKCbfBuilder; use bdk_kyoto::builder::BuilderExt; use bdk_kyoto::HeaderCheckpoint; -use bdk_kyoto::LightClient as BDKLightClient; use bdk_kyoto::Receiver; use bdk_kyoto::RejectReason; use bdk_kyoto::Requester; @@ -16,7 +15,7 @@ use bdk_kyoto::UnboundedReceiver; use bdk_kyoto::UpdateSubscriber; use bdk_kyoto::Warning as Warn; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; @@ -238,18 +237,15 @@ impl CbfBuilder { if let Some(proxy) = &self.socks5_proxy { let port = proxy.port; let addr = proxy.address.inner; - builder = builder.socks5_proxy((addr, port)); + builder = builder.socks5_proxy(SocketAddr::new(addr, port)); } - let BDKLightClient { - requester, - info_subscriber, - warning_subscriber, - update_subscriber, - node, - } = builder + let (client, logging, update_subscriber) = builder .build_with_wallet(&wallet, scan_type) - .expect("networks match by definition"); + .expect("networks match by definition") + .subscribe(); + let (client, node) = client.managed_start(); + let requester = client.requester(); let node = CbfNode { node: std::sync::Mutex::new(Some(node)), @@ -257,8 +253,8 @@ impl CbfBuilder { let client = CbfClient { sender: Arc::new(requester), - info_rx: Mutex::new(info_subscriber), - warning_rx: Mutex::new(warning_subscriber), + info_rx: Mutex::new(logging.info_subscriber), + warning_rx: Mutex::new(logging.warning_subscriber), update_rx: Mutex::new(update_subscriber), }; @@ -308,7 +304,7 @@ impl CbfClient { pub async fn broadcast(&self, transaction: &Transaction) -> Result, CbfError> { let tx = transaction.into(); self.sender - .broadcast_random(tx) + .broadcast_tx(tx) .await .map_err(From::from) .map(|wtxid| Arc::new(Wtxid(wtxid))) diff --git a/bdk-ffi/src/types.rs b/bdk-ffi/src/types.rs index f432988a..903f2917 100644 --- a/bdk-ffi/src/types.rs +++ b/bdk-ffi/src/types.rs @@ -23,13 +23,13 @@ use bdk_wallet::descriptor::policy::{ Condition as BdkCondition, PkOrF as BdkPkOrF, Policy as BdkPolicy, Satisfaction as BdkSatisfaction, SatisfiableItem as BdkSatisfiableItem, }; -use bdk_wallet::event::WalletEvent as BdkWalletEvent; #[allow(deprecated)] use bdk_wallet::signer::{SignOptions as BdkSignOptions, TapLeavesOptions}; use bdk_wallet::AddressInfo as BdkAddressInfo; use bdk_wallet::Balance as BdkBalance; use bdk_wallet::LocalOutput as BdkLocalOutput; use bdk_wallet::Update as BdkUpdate; +use bdk_wallet::WalletEvent as BdkWalletEvent; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::convert::TryFrom; @@ -1314,6 +1314,7 @@ impl From for bdk_wallet::ChangeSet { local_chain, tx_graph, indexer, + locked_outpoints: Default::default(), } } } diff --git a/bdk-ffi/src/wallet.rs b/bdk-ffi/src/wallet.rs index 47da506c..0140901d 100644 --- a/bdk-ffi/src/wallet.rs +++ b/bdk-ffi/src/wallet.rs @@ -205,13 +205,6 @@ impl Wallet { }) } - /// Informs the wallet that you no longer intend to broadcast a tx that was built from it. - /// - /// This frees up the change address used when creating the tx for use in future transactions. - pub fn cancel_tx(&self, tx: &Transaction) { - self.get_wallet().cancel_tx(&tx.into()) - } - /// Returns the utxo owned by this wallet corresponding to `outpoint` if it exists in the /// wallet's database. pub fn get_utxo(&self, op: OutPoint) -> Option { @@ -348,6 +341,29 @@ impl Wallet { ) } + /// Apply relevant unconfirmed transactions to the wallet and returns events. + /// + /// See [`apply_unconfirmed_txs`] for more information. + /// + /// See [`apply_update_events`] for more information on the returned [`WalletEvent`]s. + /// + /// [`apply_unconfirmed_txs`]: Self::apply_unconfirmed_txs + /// [`apply_update_events`]: Self::apply_update_events + pub fn apply_unconfirmed_txs_events( + &self, + unconfirmed_txs: Vec, + ) -> Vec { + self.get_wallet() + .apply_unconfirmed_txs_events( + unconfirmed_txs + .into_iter() + .map(|utx| (Arc::new(utx.tx.as_ref().into()), utx.last_seen)), + ) + .into_iter() + .map(|event| event.into()) + .collect() + } + /// Apply transactions that have been evicted from the mempool. /// Transactions may be evicted for paying too-low fee, or for being malformed. /// Irrelevant transactions are ignored. @@ -361,6 +377,27 @@ impl Wallet { ); } + /// Apply evictions of the given transaction IDs with their associated timestamps and returns + /// events. + /// + /// See [`apply_evicted_txs`] for more information. + /// + /// See [`apply_update_events`] for more information on the returned [`WalletEvent`]s. + /// + /// [`apply_evicted_txs`]: Self::apply_evicted_txs + /// [`apply_update_events`]: Self::apply_update_events + pub fn apply_evicted_txs_events(&self, evicted_txs: Vec) -> Vec { + self.get_wallet() + .apply_evicted_txs_events( + evicted_txs + .into_iter() + .map(|etx| (etx.txid.0, etx.evicted_at)), + ) + .into_iter() + .map(|event| event.into()) + .collect() + } + /// The derivation index of this wallet. It will return `None` if it has not derived any addresses. /// Otherwise, it will return the index of the highest address it has derived. pub fn derivation_index(&self, keychain: KeychainKind) -> Option { @@ -605,6 +642,14 @@ impl Wallet { self.get_wallet().latest_checkpoint().block_id().into() } + /// Get all the checkpoints the wallet is currently storing indexed by height. + pub fn checkpoints(&self) -> Vec { + self.get_wallet() + .checkpoints() + .map(|checkpoint| checkpoint.block_id().into()) + .collect() + } + /// Get the [`TxDetails`] of a wallet transaction. pub fn tx_details(&self, txid: Arc) -> Option { self.get_wallet()