Compare commits

...

9 Commits

Author SHA1 Message Date
thunderbiscuit
60f1aef3e0
chore: bump jvm lib to 0.31.1 2024-04-19 18:42:43 -04:00
thunderbiscuit
7490d8d8b6
chore: bump android lib to 0.31.1 2024-04-19 17:57:35 -04:00
Matthew
5d71773e7f
chore: bump library version from 0.31.0 to 0.31.1 2024-03-26 09:51:05 -05:00
Matthew
ebde685f06
fix: update bdk-swift framework info.plist for xcode 15.3 reqs 2024-03-18 13:36:20 -05:00
thunderbiscuit
8d1ecd1d8c
Update libraries to official release versions 2024-01-17 14:34:30 -05:00
thunderbiscuit
25a48e0565
feat: add is_valid_for_network method on address type 2024-01-17 11:12:24 -05:00
thunderbiscuit
b305f8f44e
feat: upgrade API to match bdk 0.29 2024-01-16 19:38:21 -05:00
thunderbiscuit
ef080130bf
chore: pin uniffi to version 0.23.0 2024-01-10 16:17:23 -05:00
thunderbiscuit
e798e1573f
chore: update bdk to version 0.29.0 2024-01-10 16:16:58 -05:00
16 changed files with 370 additions and 214 deletions

144
Cargo.lock generated
View File

@ -157,27 +157,18 @@ version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
[[package]]
name = "base64-compat"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7"
dependencies = [
"byteorder",
]
[[package]]
name = "bdk"
version = "0.28.2"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15adb2017ab6437b6704a779ab8bbefe857612f5af9d84b677a1767f965e099"
checksum = "2fc1fc1a92e0943bfbcd6eb7d32c1b2a79f2f1357eb1e2eee9d7f36d6d7ca44a"
dependencies = [
"ahash 0.7.6",
"async-trait",
"bdk-macros",
"bip39",
"bitcoin",
"bitcoincore-rpc",
"core-rpc",
"electrum-client",
"esplora-client",
"getrandom",
@ -194,7 +185,7 @@ dependencies = [
[[package]]
name = "bdk-ffi"
version = "0.30.0"
version = "0.31.1"
dependencies = [
"assert_matches",
"bdk",
@ -233,55 +224,52 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
dependencies = [
"bitcoin_hashes",
"bitcoin_hashes 0.11.0",
"serde",
"unicode-normalization",
]
[[package]]
name = "bitcoin"
version = "0.29.2"
version = "0.30.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3"
checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462"
dependencies = [
"base64 0.13.1",
"bech32",
"bitcoin_hashes",
"bitcoin-private",
"bitcoin_hashes 0.12.0",
"hex_lit",
"secp256k1",
"serde",
]
[[package]]
name = "bitcoin-internals"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f9997f8650dd818369931b5672a18dbef95324d0513aa99aae758de8ce86e5b"
[[package]]
name = "bitcoin-private"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
[[package]]
name = "bitcoin_hashes"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
dependencies = [
"serde",
]
[[package]]
name = "bitcoincore-rpc"
version = "0.16.0"
name = "bitcoin_hashes"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca"
checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
dependencies = [
"bitcoincore-rpc-json",
"jsonrpc",
"log",
"bitcoin-private",
"serde",
"serde_json",
]
[[package]]
name = "bitcoincore-rpc-json"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c231bea28e314879c5aef240f6052e8a72a369e3c9f9b20d9bfbb33ad18029b2"
dependencies = [
"bitcoin",
"serde",
"serde_json",
]
[[package]]
@ -394,6 +382,32 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "core-rpc"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d77079e1b71c2778d6e1daf191adadcd4ff5ec3ccad8298a79061d865b235b"
dependencies = [
"bitcoin-private",
"core-rpc-json",
"jsonrpc",
"log",
"serde",
"serde_json",
]
[[package]]
name = "core-rpc-json"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581898ed9a83f31c64731b1d8ca2dfffcfec14edf1635afacd5234cddbde3a41"
dependencies = [
"bitcoin",
"bitcoin-private",
"serde",
"serde_json",
]
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -427,15 +441,16 @@ dependencies = [
[[package]]
name = "electrum-client"
version = "0.12.1"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8e1e1e452aef3ee772d19cc6272ef642f22ce0f4a9fb715ffe98010934e2ae1"
checksum = "6bc133f1c8d829d254f013f946653cbeb2b08674b960146361d1e9b67733ad19"
dependencies = [
"bitcoin",
"bitcoin-private",
"byteorder",
"libc",
"log",
"rustls 0.20.9",
"rustls",
"serde",
"serde_json",
"webpki",
@ -445,11 +460,12 @@ dependencies = [
[[package]]
name = "esplora-client"
version = "0.4.0"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "847e59bd6ee1c3f2bdf217118ee3640b97a1b1d8becb55771e67e533b87da66f"
checksum = "0cb1f7f2489cce83bc3bd92784f9ba5271eeb6e729b975895fc541f78cbfcdca"
dependencies = [
"bitcoin",
"bitcoin-internals",
"log",
"serde",
"ureq",
@ -585,6 +601,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hex_lit"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
[[package]]
name = "idna"
version = "0.4.0"
@ -631,13 +653,12 @@ dependencies = [
[[package]]
name = "jsonrpc"
version = "0.12.1"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8"
checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639"
dependencies = [
"base64-compat",
"base64 0.13.1",
"serde",
"serde_derive",
"serde_json",
]
@ -713,11 +734,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniscript"
version = "9.0.2"
version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5b106477a0709e2da253e5559ba4ab20a272f8577f1eefff72f3a905b5d35f5"
checksum = "1eb102b66b2127a872dbcc73095b7b47aeb9d92f7b03c2b2298253ffc82c7594"
dependencies = [
"bitcoin",
"bitcoin-private",
"serde",
]
@ -938,18 +960,6 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustls"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "rustls"
version = "0.21.7"
@ -1026,11 +1036,11 @@ dependencies = [
[[package]]
name = "secp256k1"
version = "0.24.3"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62"
checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
dependencies = [
"bitcoin_hashes",
"bitcoin_hashes 0.12.0",
"rand",
"secp256k1-sys",
"serde",
@ -1038,9 +1048,9 @@ dependencies = [
[[package]]
name = "secp256k1-sys"
version = "0.6.1"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b"
checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
dependencies = [
"cc",
]
@ -1412,7 +1422,7 @@ dependencies = [
"flate2",
"log",
"once_cell",
"rustls 0.21.7",
"rustls",
"rustls-webpki 0.100.2",
"serde",
"serde_json",

View File

@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
android.enableJetifier=true
kotlin.code.style=official
libraryVersion=0.31.0-SNAPSHOT
libraryVersion=0.31.1

View File

@ -1,6 +1,6 @@
[package]
name = "bdk-ffi"
version = "0.30.0"
version = "0.31.1"
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
edition = "2018"
license = "MIT OR Apache-2.0"
@ -17,12 +17,12 @@ path = "uniffi-bindgen.rs"
default = ["uniffi/cli"]
[dependencies]
bdk = { version = "0.28.2", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
uniffi = { version = "0.23.0" }
bdk = { version = "0.29.0", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
uniffi = { version = "=0.23.0" }
[build-dependencies]
uniffi = { version = "0.23.0", features = ["build"] }
uniffi = { version = "=0.23.0", features = ["build"] }
[dev-dependencies]
uniffi = { version = "0.23.0", features = ["bindgen-tests"] }
uniffi = { version = "=0.23.0", features = ["bindgen-tests"] }
assert_matches = "1.5.0"

View File

@ -46,6 +46,7 @@ enum BdkError {
"Sled",
"Rusqlite",
"Rpc",
"HardenedIndex"
};
dictionary AddressInfo {
@ -361,7 +362,7 @@ interface TxBuilder {
interface BumpFeeTxBuilder {
constructor(string txid, float new_fee_rate);
BumpFeeTxBuilder allow_shrinking(string address);
BumpFeeTxBuilder allow_shrinking(Script script_pubkey);
BumpFeeTxBuilder enable_rbf();
@ -455,7 +456,7 @@ interface Descriptor {
interface Address {
[Throws=BdkError]
constructor(string address);
constructor(string address, Network network);
[Name=from_script, Throws=BdkError]
constructor(Script script, Network network);
@ -468,14 +469,16 @@ interface Address {
string to_qr_uri();
boolean is_valid_for_network(Network network);
string as_string();
};
[Enum]
interface Payload {
PubkeyHash(sequence<u8> pubkey_hash);
PubkeyHash(string pubkey_hash);
ScriptHash(sequence<u8> script_hash);
ScriptHash(string script_hash);
WitnessProgram(WitnessVersion version, sequence<u8> program);
};

View File

@ -1,6 +1,6 @@
// use crate::BlockchainConfig;
use crate::Network;
use crate::{BdkError, Transaction};
use bdk::bitcoin::Network;
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
use bdk::blockchain::rpc::Auth as BdkAuth;
use bdk::blockchain::rpc::RpcSyncParams as BdkRpcSyncParams;
@ -45,7 +45,7 @@ impl Blockchain {
BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig {
url: config.url,
auth: config.auth.into(),
network: config.network,
network: config.network.into(),
wallet_name: config.wallet_name,
sync_params: config.sync_params.map(|p| p.into()),
}),

View File

@ -1,10 +1,11 @@
use crate::Network;
use crate::{BdkError, DescriptorPublicKey, DescriptorSecretKey};
use bdk::bitcoin::bip32::Fingerprint;
use bdk::bitcoin::secp256k1::Secp256k1;
use bdk::bitcoin::util::bip32::Fingerprint;
use bdk::bitcoin::Network;
use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor};
use bdk::keys::{
DescriptorPublicKey as BdkDescriptorPublicKey, DescriptorSecretKey as BdkDescriptorSecretKey,
KeyMap,
};
use bdk::template::{
Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, Bip86, Bip86Public,
@ -23,7 +24,8 @@ pub(crate) struct Descriptor {
impl Descriptor {
pub(crate) fn new(descriptor: String, network: Network) -> Result<Self, BdkError> {
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,
@ -40,8 +42,9 @@ impl Descriptor {
match derivable_key {
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,
@ -50,6 +53,9 @@ impl Descriptor {
BdkDescriptorSecretKey::Single(_) => {
unreachable!()
}
BdkDescriptorSecretKey::MultiXPrv(_) => {
unreachable!()
}
}
}
@ -67,7 +73,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())
.unwrap();
Self {
@ -78,6 +84,9 @@ impl Descriptor {
BdkDescriptorPublicKey::Single(_) => {
unreachable!()
}
BdkDescriptorPublicKey::MultiXPub(_) => {
unreachable!()
}
}
}
@ -91,8 +100,9 @@ impl Descriptor {
match derivable_key {
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,
@ -101,6 +111,9 @@ impl Descriptor {
BdkDescriptorSecretKey::Single(_) => {
unreachable!()
}
BdkDescriptorSecretKey::MultiXPrv(_) => {
unreachable!()
}
}
}
@ -118,7 +131,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())
.unwrap();
Self {
@ -129,6 +142,9 @@ impl Descriptor {
BdkDescriptorPublicKey::Single(_) => {
unreachable!()
}
BdkDescriptorPublicKey::MultiXPub(_) => {
unreachable!()
}
}
}
@ -142,8 +158,9 @@ impl Descriptor {
match derivable_key {
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,
@ -152,6 +169,9 @@ impl Descriptor {
BdkDescriptorSecretKey::Single(_) => {
unreachable!()
}
BdkDescriptorSecretKey::MultiXPrv(_) => {
unreachable!()
}
}
}
@ -169,7 +189,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())
.unwrap();
Self {
@ -180,6 +200,9 @@ impl Descriptor {
BdkDescriptorPublicKey::Single(_) => {
unreachable!()
}
BdkDescriptorPublicKey::MultiXPub(_) => {
unreachable!()
}
}
}
@ -193,8 +216,9 @@ impl Descriptor {
match derivable_key {
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,
@ -203,6 +227,9 @@ impl Descriptor {
BdkDescriptorSecretKey::Single(_) => {
unreachable!()
}
BdkDescriptorSecretKey::MultiXPrv(_) => {
unreachable!()
}
}
}
@ -220,7 +247,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())
.unwrap();
Self {
@ -231,6 +258,9 @@ impl Descriptor {
BdkDescriptorPublicKey::Single(_) => {
unreachable!()
}
BdkDescriptorPublicKey::MultiXPub(_) => {
unreachable!()
}
}
}

View File

@ -1,14 +1,14 @@
use crate::BdkError;
use crate::Network;
use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath;
use bdk::bitcoin::secp256k1::Secp256k1;
use bdk::bitcoin::util::bip32::DerivationPath as BdkDerivationPath;
use bdk::bitcoin::Network;
use bdk::descriptor::DescriptorXKey;
use bdk::keys::bip39::{Language, Mnemonic as BdkMnemonic, WordCount};
use bdk::keys::{
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
};
use bdk::miniscript::descriptor::{DescriptorXKey, Wildcard};
use bdk::miniscript::BareCtx;
use std::ops::Deref;
use std::str::FromStr;
@ -75,9 +75,9 @@ 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: bdk::descriptor::Wildcard::Unhardened,
wildcard: Wildcard::Unhardened,
});
Self {
inner: descriptor_secret_key,
@ -116,6 +116,9 @@ impl DescriptorSecretKey {
BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic(
"Cannot derive from a single key".to_string(),
)),
BdkDescriptorSecretKey::MultiXPrv(_) => Err(BdkError::Generic(
"Cannot derive from a multi key".to_string(),
)),
}
}
@ -138,6 +141,9 @@ impl DescriptorSecretKey {
BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic(
"Cannot extend from a single key".to_string(),
)),
BdkDescriptorSecretKey::MultiXPrv(_) => Err(BdkError::Generic(
"Cannot extend from a multi key".to_string(),
)),
}
}
@ -152,13 +158,16 @@ impl DescriptorSecretKey {
/// Get the private key as bytes.
pub(crate) fn secret_bytes(&self) -> Vec<u8> {
let inner = &self.inner;
let secret_bytes: Vec<u8> = match inner.deref() {
let secret_bytes: Vec<u8> = match inner {
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
descriptor_x_key.xkey.private_key.secret_bytes().to_vec()
}
BdkDescriptorSecretKey::Single(_) => {
unreachable!()
}
BdkDescriptorSecretKey::MultiXPrv(_) => {
unreachable!()
}
};
secret_bytes
@ -188,7 +197,7 @@ impl DescriptorPublicKey {
let descriptor_public_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_public_key.deref() {
match descriptor_public_key {
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?;
let key_source = match descriptor_x_key.origin.clone() {
@ -208,13 +217,16 @@ impl DescriptorPublicKey {
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
"Cannot derive from a single key".to_string(),
)),
BdkDescriptorPublicKey::MultiXPub(_) => Err(BdkError::Generic(
"Cannot derive from a multi key".to_string(),
)),
}
}
pub(crate) fn extend(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
let descriptor_public_key = &self.inner;
let path = path.inner_mutex.lock().unwrap().deref().clone();
match descriptor_public_key.deref() {
match descriptor_public_key {
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
let extended_path = descriptor_x_key.derivation_path.extend(path);
let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
@ -230,6 +242,9 @@ impl DescriptorPublicKey {
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
"Cannot extend from a single key".to_string(),
)),
BdkDescriptorPublicKey::MultiXPub(_) => Err(BdkError::Generic(
"Cannot extend from a multi key".to_string(),
)),
}
}
@ -245,8 +260,7 @@ impl DescriptorPublicKey {
mod test {
use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
use crate::BdkError;
use bdk::bitcoin::hashes::hex::ToHex;
use bdk::bitcoin::Network;
use crate::Network;
use std::sync::Arc;
fn get_inner() -> DescriptorSecretKey {
@ -358,14 +372,4 @@ mod test {
let derived_dpk = &derive_dpk(&master_dpk, "m/84h/1h/0h");
assert!(derived_dpk.is_err());
}
#[test]
fn test_retrieve_master_secret_key() {
let master_dpk = get_inner();
let master_private_key = master_dpk.secret_bytes().to_hex();
assert_eq!(
master_private_key,
"e93315d6ce401eb4db803a56232f0ed3e69b053774e6047df54f1bd00e5ea936"
)
}
}

View File

@ -15,17 +15,19 @@ use crate::keys::{DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
use crate::psbt::PartiallySignedTransaction;
use crate::wallet::SignOptions;
use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet};
use bdk::bitcoin::blockdata::script::Script as BdkScript;
use bdk::bitcoin::address::{NetworkUnchecked, Payload as BdkPayload, WitnessVersion};
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
use bdk::bitcoin::blockdata::transaction::TxIn as BdkTxIn;
use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut;
use bdk::bitcoin::consensus::encode::serialize;
use bdk::bitcoin::consensus::Decodable;
use bdk::bitcoin::psbt::serialize::Serialize;
use bdk::bitcoin::util::address::{Payload as BdkPayload, WitnessVersion};
use bdk::bitcoin::network::constants::Network as BdkNetwork;
use bdk::bitcoin::{
Address as BdkAddress, Network, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid,
Address as BdkAddress, OutPoint as BdkOutPoint, Transaction as BdkTransaction, Txid,
};
use bdk::blockchain::Progress as BdkProgress;
use bdk::database::any::{SledDbConfiguration, SqliteDbConfiguration};
use bdk::database::any::SledDbConfiguration;
use bdk::database::any::SqliteDbConfiguration;
use bdk::keys::bip39::WordCount;
use bdk::wallet::AddressIndex as BdkAddressIndex;
use bdk::wallet::AddressInfo as BdkAddressInfo;
@ -41,6 +43,26 @@ use std::sync::Arc;
uniffi::include_scaffolding!("bdk");
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Script(pub(crate) BdkScriptBuf);
impl Script {
pub fn new(raw_output_script: Vec<u8>) -> Self {
let script: BdkScriptBuf = raw_output_script.into();
Script(script)
}
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}
}
impl From<BdkScriptBuf> for Script {
fn from(script: BdkScriptBuf) -> Self {
Script(script)
}
}
/// A output script and an amount of satoshis.
pub struct ScriptAmount {
pub script: Arc<Script>,
@ -202,9 +224,7 @@ impl From<&BdkTxOut> for TxOut {
fn from(tx_out: &BdkTxOut) -> Self {
TxOut {
value: tx_out.value,
script_pubkey: Arc::new(Script {
inner: tx_out.script_pubkey.clone(),
}),
script_pubkey: Arc::new(Script(tx_out.script_pubkey.clone())),
}
}
}
@ -225,9 +245,7 @@ impl From<BdkLocalUtxo> for LocalUtxo {
},
txout: TxOut {
value: local_utxo.txout.value,
script_pubkey: Arc::new(Script {
inner: local_utxo.txout.script_pubkey,
}),
script_pubkey: Arc::new(Script(local_utxo.txout.script_pubkey)),
},
keychain: local_utxo.keychain,
is_spent: local_utxo.is_spent,
@ -274,9 +292,7 @@ impl From<&BdkTxIn> for TxIn {
txid: tx_in.previous_output.txid.to_string(),
vout: tx_in.previous_output.vout,
},
script_sig: Arc::new(Script {
inner: tx_in.script_sig.clone(),
}),
script_sig: Arc::new(Script(tx_in.script_sig.clone())),
sequence: tx_in.sequence.0,
witness: tx_in.witness.to_vec(),
}
@ -301,7 +317,7 @@ impl Transaction {
}
fn weight(&self) -> u64 {
self.inner.weight() as u64
self.inner.weight().to_wu()
}
fn size(&self) -> u64 {
@ -313,7 +329,7 @@ impl Transaction {
}
fn serialize(&self) -> Vec<u8> {
self.inner.serialize()
serialize(&self.inner)
}
fn is_coin_base(&self) -> bool {
@ -333,7 +349,7 @@ impl Transaction {
}
fn lock_time(&self) -> u32 {
self.inner.lock_time.0
self.inner.lock_time.to_consensus_u32()
}
fn input(&self) -> Vec<TxIn> {
@ -358,15 +374,23 @@ pub struct Address {
}
impl Address {
fn new(address: String) -> Result<Self, BdkError> {
BdkAddress::from_str(address.as_str())
.map(|a| Address { inner: a })
.map_err(|e| BdkError::Generic(e.to_string()))
pub fn new(address: String, network: Network) -> Result<Self, BdkError> {
let parsed_address = address
.parse::<bdk::bitcoin::Address<NetworkUnchecked>>()
.map_err(|e| BdkError::Generic(e.to_string()))?;
let network_checked_address = parsed_address
.require_network(network.into())
.map_err(|e| BdkError::Generic(e.to_string()))?;
Ok(Address {
inner: network_checked_address,
})
}
/// alternative constructor
fn from_script(script: Arc<Script>, network: Network) -> Result<Self, BdkError> {
BdkAddress::from_script(&script.inner, network)
BdkAddress::from_script(&script.0, network.into())
.map(|a| Address { inner: a })
.map_err(|e| BdkError::Generic(e.to_string()))
}
@ -374,32 +398,40 @@ impl Address {
fn payload(&self) -> Payload {
match &self.inner.payload.clone() {
BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
pubkey_hash: pubkey_hash.to_vec(),
pubkey_hash: pubkey_hash.to_string(),
},
BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
script_hash: script_hash.to_vec(),
script_hash: script_hash.to_string(),
},
BdkPayload::WitnessProgram { version, program } => Payload::WitnessProgram {
version: *version,
program: program.clone(),
BdkPayload::WitnessProgram(witness_program) => Payload::WitnessProgram {
version: witness_program.version(),
program: Vec::from(witness_program.program().as_bytes()),
},
_ => panic!("Unsupported address payload type"),
}
}
fn network(&self) -> Network {
self.inner.network
self.inner.network.into()
}
fn script_pubkey(&self) -> Arc<Script> {
Arc::new(Script {
inner: self.inner.script_pubkey(),
})
Arc::new(Script(self.inner.script_pubkey()))
}
fn to_qr_uri(&self) -> String {
self.inner.to_qr_uri()
}
pub fn is_valid_for_network(&self, network: Network) -> bool {
let address_str = self.inner.to_string();
if let Ok(unchecked_address) = address_str.parse::<BdkAddress<NetworkUnchecked>>() {
unchecked_address.is_valid_for_network(network.into())
} else {
false
}
}
fn as_string(&self) -> String {
self.inner.to_string()
}
@ -415,9 +447,9 @@ impl From<BdkAddress> for Address {
#[derive(Debug)]
pub enum Payload {
/// P2PKH address.
PubkeyHash { pubkey_hash: Vec<u8> },
PubkeyHash { pubkey_hash: String },
/// P2SH address.
ScriptHash { script_hash: Vec<u8> },
ScriptHash { script_hash: String },
/// Segwit address.
WitnessProgram {
/// The witness program version.
@ -427,29 +459,6 @@ pub enum Payload {
},
}
/// A Bitcoin script.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Script {
inner: BdkScript,
}
impl Script {
fn new(raw_output_script: Vec<u8>) -> Self {
let script: BdkScript = BdkScript::from(raw_output_script);
Script { inner: script }
}
fn to_bytes(&self) -> Vec<u8> {
self.inner.to_bytes()
}
}
impl From<BdkScript> for Script {
fn from(bdk_script: BdkScript) -> Self {
Script { inner: bdk_script }
}
}
#[derive(Clone, Debug)]
enum RbfValue {
Default,
@ -463,6 +472,37 @@ pub struct TxBuilderResult {
pub transaction_details: TransactionDetails,
}
#[derive(PartialEq, Debug)]
pub enum Network {
Bitcoin,
Testnet,
Signet,
Regtest,
}
impl From<Network> for BdkNetwork {
fn from(network: Network) -> Self {
match network {
Network::Bitcoin => BdkNetwork::Bitcoin,
Network::Testnet => BdkNetwork::Testnet,
Network::Signet => BdkNetwork::Signet,
Network::Regtest => BdkNetwork::Regtest,
}
}
}
impl From<BdkNetwork> for Network {
fn from(network: BdkNetwork) -> Self {
match network {
BdkNetwork::Bitcoin => Network::Bitcoin,
BdkNetwork::Testnet => Network::Testnet,
BdkNetwork::Signet => Network::Signet,
BdkNetwork::Regtest => Network::Regtest,
_ => panic!("Network {} not supported", network),
}
}
}
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.
@ -470,30 +510,33 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
// crate.
#[cfg(test)]
mod test {
use super::Transaction;
use crate::Network::Regtest;
use crate::{Address, Payload};
use assert_matches::assert_matches;
use bdk::bitcoin::address::WitnessVersion;
use bdk::bitcoin::hashes::hex::FromHex;
use bdk::bitcoin::util::address::WitnessVersion;
use bdk::bitcoin::Network;
// Verify that bdk-ffi Transaction can be created from valid bytes and serialized back into the same bytes.
#[test]
fn test_transaction_serde() {
let test_tx_bytes = Vec::from_hex("020000000001031cfbc8f54fbfa4a33a30068841371f80dbfe166211242213188428f437445c91000000006a47304402206fbcec8d2d2e740d824d3d36cc345b37d9f65d665a99f5bd5c9e8d42270a03a8022013959632492332200c2908459547bf8dbf97c65ab1a28dec377d6f1d41d3d63e012103d7279dfb90ce17fe139ba60a7c41ddf605b25e1c07a4ddcb9dfef4e7d6710f48feffffff476222484f5e35b3f0e43f65fc76e21d8be7818dd6a989c160b1e5039b7835fc00000000171600140914414d3c94af70ac7e25407b0689e0baa10c77feffffffa83d954a62568bbc99cc644c62eb7383d7c2a2563041a0aeb891a6a4055895570000000017160014795d04cc2d4f31480d9a3710993fbd80d04301dffeffffff06fef72f000000000017a91476fd7035cd26f1a32a5ab979e056713aac25796887a5000f00000000001976a914b8332d502a529571c6af4be66399cd33379071c588ac3fda0500000000001976a914fc1d692f8de10ae33295f090bea5fe49527d975c88ac522e1b00000000001976a914808406b54d1044c429ac54c0e189b0d8061667e088ac6eb68501000000001976a914dfab6085f3a8fb3e6710206a5a959313c5618f4d88acbba20000000000001976a914eb3026552d7e3f3073457d0bee5d4757de48160d88ac0002483045022100bee24b63212939d33d513e767bc79300051f7a0d433c3fcf1e0e3bf03b9eb1d70220588dc45a9ce3a939103b4459ce47500b64e23ab118dfc03c9caa7d6bfc32b9c601210354fd80328da0f9ae6eef2b3a81f74f9a6f66761fadf96f1d1d22b1fd6845876402483045022100e29c7e3a5efc10da6269e5fc20b6a1cb8beb92130cc52c67e46ef40aaa5cac5f0220644dd1b049727d991aece98a105563416e10a5ac4221abac7d16931842d5c322012103960b87412d6e169f30e12106bdf70122aabb9eb61f455518322a18b920a4dfa887d30700").unwrap();
let new_tx_from_bytes = Transaction::new(test_tx_bytes.clone()).unwrap();
let serialized_tx_to_bytes = new_tx_from_bytes.serialize();
assert_eq!(test_tx_bytes, serialized_tx_to_bytes);
}
// #[test]
// fn test_transaction_serde() {
// let test_tx_bytes = Vec::from_hex("020000000001031cfbc8f54fbfa4a33a30068841371f80dbfe166211242213188428f437445c91000000006a47304402206fbcec8d2d2e740d824d3d36cc345b37d9f65d665a99f5bd5c9e8d42270a03a8022013959632492332200c2908459547bf8dbf97c65ab1a28dec377d6f1d41d3d63e012103d7279dfb90ce17fe139ba60a7c41ddf605b25e1c07a4ddcb9dfef4e7d6710f48feffffff476222484f5e35b3f0e43f65fc76e21d8be7818dd6a989c160b1e5039b7835fc00000000171600140914414d3c94af70ac7e25407b0689e0baa10c77feffffffa83d954a62568bbc99cc644c62eb7383d7c2a2563041a0aeb891a6a4055895570000000017160014795d04cc2d4f31480d9a3710993fbd80d04301dffeffffff06fef72f000000000017a91476fd7035cd26f1a32a5ab979e056713aac25796887a5000f00000000001976a914b8332d502a529571c6af4be66399cd33379071c588ac3fda0500000000001976a914fc1d692f8de10ae33295f090bea5fe49527d975c88ac522e1b00000000001976a914808406b54d1044c429ac54c0e189b0d8061667e088ac6eb68501000000001976a914dfab6085f3a8fb3e6710206a5a959313c5618f4d88acbba20000000000001976a914eb3026552d7e3f3073457d0bee5d4757de48160d88ac0002483045022100bee24b63212939d33d513e767bc79300051f7a0d433c3fcf1e0e3bf03b9eb1d70220588dc45a9ce3a939103b4459ce47500b64e23ab118dfc03c9caa7d6bfc32b9c601210354fd80328da0f9ae6eef2b3a81f74f9a6f66761fadf96f1d1d22b1fd6845876402483045022100e29c7e3a5efc10da6269e5fc20b6a1cb8beb92130cc52c67e46ef40aaa5cac5f0220644dd1b049727d991aece98a105563416e10a5ac4221abac7d16931842d5c322012103960b87412d6e169f30e12106bdf70122aabb9eb61f455518322a18b920a4dfa887d30700").unwrap();
// let new_tx_from_bytes = Transaction::new(test_tx_bytes.clone()).unwrap();
// let serialized_tx_to_bytes = new_tx_from_bytes.serialize();
// assert_eq!(test_tx_bytes, serialized_tx_to_bytes);
// }
// Verify that bdk-ffi Address.payload includes expected WitnessProgram variant, version and program bytes.
#[test]
fn test_address_witness_program() {
let address =
Address::new("bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv".to_string()).unwrap();
let address = Address::new(
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv".to_string(),
Network::Regtest.into(),
)
.unwrap();
let payload = address.payload();
assert_matches!(payload, Payload::WitnessProgram { version, program } => {
assert_eq!(version,WitnessVersion::V0);
assert_eq!(version, WitnessVersion::V0);
assert_eq!(program, Vec::from_hex("04a6545885dd87b8e147cd327f2e9db362b72346").unwrap());
});
assert_eq!(address.network(), Regtest);

View File

@ -1,5 +1,4 @@
use bdk::bitcoin::hashes::hex::ToHex;
use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
use bdk::bitcoin::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
use bdk::bitcoincore_rpc::jsonrpc::serde_json;
use bdk::psbt::PsbtUtils;
use std::ops::Deref;
@ -30,7 +29,7 @@ impl PartiallySignedTransaction {
pub(crate) fn txid(&self) -> String {
let tx = self.inner.lock().unwrap().clone().extract_tx();
let txid = tx.txid();
txid.to_hex()
txid.to_string()
}
/// Return the transaction.
@ -82,6 +81,7 @@ impl PartiallySignedTransaction {
#[cfg(test)]
mod test {
use crate::wallet::{TxBuilder, Wallet};
use crate::Network;
use bdk::wallet::get_funded_wallet;
use std::sync::Mutex;
@ -93,7 +93,7 @@ mod test {
inner_mutex: Mutex::new(funded_wallet),
};
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
let drain_to_script = crate::Address::new(drain_to_address)
let drain_to_script = crate::Address::new(drain_to_address, Network::Testnet)
.unwrap()
.script_pubkey();
@ -103,7 +103,7 @@ mod test {
.drain_to(drain_to_script.clone());
//dbg!(&tx_builder);
assert!(tx_builder.drain_wallet);
assert_eq!(tx_builder.drain_to, Some(drain_to_script.inner.clone()));
assert_eq!(tx_builder.drain_to, Some(drain_to_script.0.clone()));
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();

View File

@ -1,5 +1,6 @@
use bdk::bitcoin::blockdata::script::Script as BdkScript;
use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Sequence, Txid};
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
use bdk::bitcoin::script::PushBytesBuf;
use bdk::bitcoin::{OutPoint as BdkOutPoint, Sequence, Txid};
use bdk::database::any::AnyDatabase;
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
use bdk::wallet::tx_builder::ChangeSpendPolicy;
@ -8,6 +9,7 @@ use bdk::{
SyncOptions as BdkSyncOptions, Wallet as BdkWallet,
};
use std::collections::HashSet;
use std::convert::TryFrom;
use std::ops::Deref;
use std::str::FromStr;
use std::sync::{Arc, Mutex, MutexGuard};
@ -16,6 +18,7 @@ use crate::blockchain::Blockchain;
use crate::database::DatabaseConfig;
use crate::descriptor::Descriptor;
use crate::psbt::PartiallySignedTransaction;
use crate::Network;
use crate::{
AddressIndex, AddressInfo, Balance, BdkError, LocalUtxo, OutPoint, Progress, ProgressHolder,
RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
@ -50,7 +53,7 @@ impl Wallet {
let wallet_mutex = Mutex::new(BdkWallet::new(
&descriptor,
change_descriptor.as_ref(),
network,
network.into(),
database,
)?);
Ok(Wallet {
@ -64,12 +67,12 @@ impl Wallet {
/// Get the Bitcoin network the wallet is using.
pub(crate) fn network(&self) -> Network {
self.get_wallet().network()
self.get_wallet().network().into()
}
/// Return whether or not a script is part of this wallet (either internal or external).
pub(crate) fn is_mine(&self, script: Arc<Script>) -> Result<bool, BdkError> {
self.get_wallet().is_mine(&script.inner)
self.get_wallet().is_mine(&script.0)
}
/// Sync the internal database with the blockchain.
@ -240,7 +243,7 @@ impl From<SignOptions> for BdkSignOptions {
/// Each method on the TxBuilder returns an instance of a new TxBuilder with the option set/added.
#[derive(Clone, Debug)]
pub(crate) struct TxBuilder {
pub(crate) recipients: Vec<(BdkScript, u64)>,
pub(crate) recipients: Vec<(BdkScriptBuf, u64)>,
pub(crate) utxos: Vec<OutPoint>,
pub(crate) unspendable: HashSet<OutPoint>,
pub(crate) change_policy: ChangeSpendPolicy,
@ -248,7 +251,7 @@ pub(crate) struct TxBuilder {
pub(crate) fee_rate: Option<f32>,
pub(crate) fee_absolute: Option<u64>,
pub(crate) drain_wallet: bool,
pub(crate) drain_to: Option<BdkScript>,
pub(crate) drain_to: Option<BdkScriptBuf>,
pub(crate) rbf: Option<RbfValue>,
pub(crate) data: Vec<u8>,
}
@ -272,8 +275,8 @@ impl TxBuilder {
/// Add a recipient to the internal list.
pub(crate) fn add_recipient(&self, script: Arc<Script>, amount: u64) -> Arc<Self> {
let mut recipients: Vec<(BdkScript, u64)> = self.recipients.clone();
recipients.append(&mut vec![(script.inner.clone(), amount)]);
let mut recipients: Vec<(BdkScriptBuf, u64)> = self.recipients.clone();
recipients.append(&mut vec![(script.0.clone(), amount)]);
Arc::new(TxBuilder {
recipients,
..self.clone()
@ -283,7 +286,7 @@ impl TxBuilder {
pub(crate) fn set_recipients(&self, recipients: Vec<ScriptAmount>) -> Arc<Self> {
let recipients = recipients
.iter()
.map(|script_amount| (script_amount.script.inner.clone(), script_amount.amount))
.map(|script_amount| (script_amount.script.0.clone(), script_amount.amount))
.collect();
Arc::new(TxBuilder {
recipients,
@ -388,7 +391,7 @@ impl TxBuilder {
/// to allow this output to be reduced to pay for the extra fees.
pub(crate) fn drain_to(&self, script: Arc<Script>) -> Arc<Self> {
Arc::new(TxBuilder {
drain_to: Some(script.inner.clone()),
drain_to: Some(script.0.clone()),
..self.clone()
})
}
@ -463,7 +466,10 @@ impl TxBuilder {
}
}
if !&self.data.is_empty() {
tx_builder.add_data(self.data.as_slice());
let push_bytes = PushBytesBuf::try_from(self.data.clone()).map_err(|_| {
BdkError::Generic("Failed to convert data to PushBytes".to_string())
})?;
tx_builder.add_data(&push_bytes);
}
tx_builder
@ -482,7 +488,7 @@ impl TxBuilder {
pub(crate) struct BumpFeeTxBuilder {
pub(crate) txid: String,
pub(crate) fee_rate: f32,
pub(crate) allow_shrinking: Option<String>,
pub(crate) allow_shrinking: Option<Arc<Script>>,
pub(crate) rbf: Option<RbfValue>,
}
@ -501,9 +507,9 @@ impl BumpFeeTxBuilder {
/// shrink instead. Note that the output may shrink to below the dust limit and therefore be removed. If it is preserved
/// then it is currently not guaranteed to be in the same position as it was originally. Returns an error if script_pubkey
/// cant be found among the recipients of the transaction we are bumping.
pub(crate) fn allow_shrinking(&self, address: String) -> Arc<Self> {
pub(crate) fn allow_shrinking(&self, script_pubkey: Arc<Script>) -> Arc<Self> {
Arc::new(Self {
allow_shrinking: Some(address),
allow_shrinking: Some(script_pubkey),
..self.clone()
})
}
@ -536,10 +542,7 @@ impl BumpFeeTxBuilder {
let mut tx_builder = wallet.build_fee_bump(txid)?;
tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate));
if let Some(allow_shrinking) = &self.allow_shrinking {
let address = BdkAddress::from_str(allow_shrinking)
.map_err(|e| BdkError::Generic(e.to_string()))?;
let script = address.script_pubkey();
tx_builder.allow_shrinking(script)?;
tx_builder.allow_shrinking(allow_shrinking.0.clone())?;
}
if let Some(rbf) = &self.rbf {
match *rbf {
@ -569,9 +572,10 @@ mod test {
use crate::descriptor::Descriptor;
use crate::keys::{DescriptorSecretKey, Mnemonic};
use crate::wallet::{AddressIndex, TxBuilder, Wallet};
use crate::Network;
use crate::Script;
use assert_matches::assert_matches;
use bdk::bitcoin::{Address, Network};
use bdk::bitcoin::Address;
use bdk::wallet::get_funded_wallet;
use bdk::KeychainKind;
use std::str::FromStr;
@ -585,14 +589,14 @@ mod test {
inner_mutex: Mutex::new(funded_wallet),
};
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
let drain_to_script = crate::Address::new(drain_to_address)
let drain_to_script = crate::Address::new(drain_to_address, Network::Testnet)
.unwrap()
.script_pubkey();
let tx_builder = TxBuilder::new()
.drain_wallet()
.drain_to(drain_to_script.clone());
assert!(tx_builder.drain_wallet);
assert_eq!(tx_builder.drain_to, Some(drain_to_script.inner.clone()));
assert_eq!(tx_builder.drain_to, Some(drain_to_script.0.clone()));
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
let psbt = tx_builder_result.psbt.inner.lock().unwrap().clone();
@ -623,12 +627,14 @@ mod test {
.cloned()
.unwrap()
.script_pubkey,
Network::Testnet,
Network::Testnet.into(),
)
.unwrap();
assert_eq!(
output_address,
Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap()
Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")
.unwrap()
.assume_checked()
);
let output_value = psbt.unsigned_tx.output.get(0).cloned().unwrap().value;
assert_eq!(output_value, 49_890_u64); // input - fee

View File

@ -1,4 +1,4 @@
org.gradle.jvmargs=-Xmx1536m
android.enableJetifier=true
kotlin.code.style=official
libraryVersion=0.31.0-SNAPSHOT
libraryVersion=0.31.1

View File

@ -51,7 +51,7 @@ print(f"Wallet balance is: {balance.total}")
setup(
name="bdkpython",
version="0.31.0.dev0",
version="0.31.0",
description="The Python language bindings for the Bitcoin Development Kit",
long_description=LONG_DESCRIPTION,
long_description_content_type="text/markdown",

View File

@ -16,6 +16,8 @@
</array>
<key>SupportedPlatform</key>
<string>macos</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
@ -31,6 +33,8 @@
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
<key>MinimumOSVersion</key>
<string>15.0</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
@ -43,6 +47,8 @@
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>MinimumOSVersion</key>
<string>15.0</string>
</dict>
</array>
<key>CFBundlePackageType</key>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.bitcoindevkit.bdkFFI</string>
<key>CFBundleName</key>
<string>bdkFFI</string>
<key>CFBundleVersion</key>
<string>0.31.1</string>
<key>CFBundleShortVersionString</key>
<string>0.31.1</string>
<key>CFBundleExecutable</key>
<string>bdkFFI</string>
<key>MinimumOSVersion</key>
<string>100</string>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.bitcoindevkit.bdkFFI</string>
<key>CFBundleName</key>
<string>bdkFFI</string>
<key>CFBundleVersion</key>
<string>0.31.1</string>
<key>CFBundleShortVersionString</key>
<string>0.31.1</string>
<key>CFBundleExecutable</key>
<string>bdkFFI</string>
<key>MinimumOSVersion</key>
<string>15.0</string>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.bitcoindevkit.bdkFFI</string>
<key>CFBundleName</key>
<string>bdkFFI</string>
<key>CFBundleVersion</key>
<string>0.31.1</string>
<key>CFBundleShortVersionString</key>
<string>0.31.1</string>
<key>CFBundleExecutable</key>
<string>bdkFFI</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
</dict>
</plist>