Compare commits
9 Commits
frost
...
release/0.
Author | SHA1 | Date | |
---|---|---|---|
|
60f1aef3e0 | ||
|
7490d8d8b6 | ||
|
5d71773e7f | ||
|
ebde685f06 | ||
|
8d1ecd1d8c | ||
|
25a48e0565 | ||
|
b305f8f44e | ||
|
ef080130bf | ||
|
e798e1573f |
144
Cargo.lock
generated
144
Cargo.lock
generated
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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()),
|
||||
}),
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
/// can’t 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
|
||||
|
@ -1,4 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
android.enableJetifier=true
|
||||
kotlin.code.style=official
|
||||
libraryVersion=0.31.0-SNAPSHOT
|
||||
libraryVersion=0.31.1
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user