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"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
|
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]]
|
[[package]]
|
||||||
name = "bdk"
|
name = "bdk"
|
||||||
version = "0.28.2"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b15adb2017ab6437b6704a779ab8bbefe857612f5af9d84b677a1767f965e099"
|
checksum = "2fc1fc1a92e0943bfbcd6eb7d32c1b2a79f2f1357eb1e2eee9d7f36d6d7ca44a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash 0.7.6",
|
"ahash 0.7.6",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bdk-macros",
|
"bdk-macros",
|
||||||
"bip39",
|
"bip39",
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
"bitcoincore-rpc",
|
"core-rpc",
|
||||||
"electrum-client",
|
"electrum-client",
|
||||||
"esplora-client",
|
"esplora-client",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
@ -194,7 +185,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bdk-ffi"
|
name = "bdk-ffi"
|
||||||
version = "0.30.0"
|
version = "0.31.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"bdk",
|
"bdk",
|
||||||
@ -233,55 +224,52 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
|
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin_hashes",
|
"bitcoin_hashes 0.11.0",
|
||||||
"serde",
|
"serde",
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitcoin"
|
name = "bitcoin"
|
||||||
version = "0.29.2"
|
version = "0.30.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3"
|
checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"bech32",
|
"bech32",
|
||||||
"bitcoin_hashes",
|
"bitcoin-private",
|
||||||
|
"bitcoin_hashes 0.12.0",
|
||||||
|
"hex_lit",
|
||||||
"secp256k1",
|
"secp256k1",
|
||||||
"serde",
|
"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]]
|
[[package]]
|
||||||
name = "bitcoin_hashes"
|
name = "bitcoin_hashes"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
|
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitcoincore-rpc"
|
name = "bitcoin_hashes"
|
||||||
version = "0.16.0"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0261b2bb7617e0c91b452a837bbd1291fd34ad6990cb8e3ffc28239cc045b5ca"
|
checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoincore-rpc-json",
|
"bitcoin-private",
|
||||||
"jsonrpc",
|
|
||||||
"log",
|
|
||||||
"serde",
|
"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]]
|
[[package]]
|
||||||
@ -394,6 +382,32 @@ dependencies = [
|
|||||||
"os_str_bytes",
|
"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]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -427,15 +441,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "electrum-client"
|
name = "electrum-client"
|
||||||
version = "0.12.1"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8e1e1e452aef3ee772d19cc6272ef642f22ce0f4a9fb715ffe98010934e2ae1"
|
checksum = "6bc133f1c8d829d254f013f946653cbeb2b08674b960146361d1e9b67733ad19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
|
"bitcoin-private",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"rustls 0.20.9",
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"webpki",
|
"webpki",
|
||||||
@ -445,11 +460,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "esplora-client"
|
name = "esplora-client"
|
||||||
version = "0.4.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "847e59bd6ee1c3f2bdf217118ee3640b97a1b1d8becb55771e67e533b87da66f"
|
checksum = "0cb1f7f2489cce83bc3bd92784f9ba5271eeb6e729b975895fc541f78cbfcdca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
|
"bitcoin-internals",
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
"ureq",
|
"ureq",
|
||||||
@ -585,6 +601,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex_lit"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -631,13 +653,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonrpc"
|
name = "jsonrpc"
|
||||||
version = "0.12.1"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f8423b78fc94d12ef1a4a9d13c348c9a78766dda0cc18817adf0faf77e670c8"
|
checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64-compat",
|
"base64 0.13.1",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -713,11 +734,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniscript"
|
name = "miniscript"
|
||||||
version = "9.0.2"
|
version = "10.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5b106477a0709e2da253e5559ba4ab20a272f8577f1eefff72f3a905b5d35f5"
|
checksum = "1eb102b66b2127a872dbcc73095b7b47aeb9d92f7b03c2b2298253ffc82c7594"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin",
|
"bitcoin",
|
||||||
|
"bitcoin-private",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -938,18 +960,6 @@ version = "0.1.23"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
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]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.21.7"
|
version = "0.21.7"
|
||||||
@ -1026,11 +1036,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secp256k1"
|
name = "secp256k1"
|
||||||
version = "0.24.3"
|
version = "0.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62"
|
checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitcoin_hashes",
|
"bitcoin_hashes 0.12.0",
|
||||||
"rand",
|
"rand",
|
||||||
"secp256k1-sys",
|
"secp256k1-sys",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1038,9 +1048,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secp256k1-sys"
|
name = "secp256k1-sys"
|
||||||
version = "0.6.1"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b"
|
checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
@ -1412,7 +1422,7 @@ dependencies = [
|
|||||||
"flate2",
|
"flate2",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustls 0.21.7",
|
"rustls",
|
||||||
"rustls-webpki 0.100.2",
|
"rustls-webpki 0.100.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536m
|
|||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libraryVersion=0.31.0-SNAPSHOT
|
libraryVersion=0.31.1
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bdk-ffi"
|
name = "bdk-ffi"
|
||||||
version = "0.30.0"
|
version = "0.31.1"
|
||||||
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
|
authors = ["Steve Myers <steve@notmandatory.org>", "Sudarsan Balaji <sudarsan.balaji@artfuldev.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@ -17,12 +17,12 @@ path = "uniffi-bindgen.rs"
|
|||||||
default = ["uniffi/cli"]
|
default = ["uniffi/cli"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bdk = { version = "0.28.2", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
|
bdk = { version = "0.29.0", features = ["all-keys", "use-esplora-ureq", "sqlite-bundled", "rpc"] }
|
||||||
uniffi = { version = "0.23.0" }
|
uniffi = { version = "=0.23.0" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
uniffi = { version = "0.23.0", features = ["build"] }
|
uniffi = { version = "=0.23.0", features = ["build"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
uniffi = { version = "0.23.0", features = ["bindgen-tests"] }
|
uniffi = { version = "=0.23.0", features = ["bindgen-tests"] }
|
||||||
assert_matches = "1.5.0"
|
assert_matches = "1.5.0"
|
||||||
|
@ -46,6 +46,7 @@ enum BdkError {
|
|||||||
"Sled",
|
"Sled",
|
||||||
"Rusqlite",
|
"Rusqlite",
|
||||||
"Rpc",
|
"Rpc",
|
||||||
|
"HardenedIndex"
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary AddressInfo {
|
dictionary AddressInfo {
|
||||||
@ -361,7 +362,7 @@ interface TxBuilder {
|
|||||||
interface BumpFeeTxBuilder {
|
interface BumpFeeTxBuilder {
|
||||||
constructor(string txid, float new_fee_rate);
|
constructor(string txid, float new_fee_rate);
|
||||||
|
|
||||||
BumpFeeTxBuilder allow_shrinking(string address);
|
BumpFeeTxBuilder allow_shrinking(Script script_pubkey);
|
||||||
|
|
||||||
BumpFeeTxBuilder enable_rbf();
|
BumpFeeTxBuilder enable_rbf();
|
||||||
|
|
||||||
@ -455,7 +456,7 @@ interface Descriptor {
|
|||||||
|
|
||||||
interface Address {
|
interface Address {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor(string address);
|
constructor(string address, Network network);
|
||||||
|
|
||||||
[Name=from_script, Throws=BdkError]
|
[Name=from_script, Throws=BdkError]
|
||||||
constructor(Script script, Network network);
|
constructor(Script script, Network network);
|
||||||
@ -468,14 +469,16 @@ interface Address {
|
|||||||
|
|
||||||
string to_qr_uri();
|
string to_qr_uri();
|
||||||
|
|
||||||
|
boolean is_valid_for_network(Network network);
|
||||||
|
|
||||||
string as_string();
|
string as_string();
|
||||||
};
|
};
|
||||||
|
|
||||||
[Enum]
|
[Enum]
|
||||||
interface Payload {
|
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);
|
WitnessProgram(WitnessVersion version, sequence<u8> program);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// use crate::BlockchainConfig;
|
// use crate::BlockchainConfig;
|
||||||
|
use crate::Network;
|
||||||
use crate::{BdkError, Transaction};
|
use crate::{BdkError, Transaction};
|
||||||
use bdk::bitcoin::Network;
|
|
||||||
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig};
|
||||||
use bdk::blockchain::rpc::Auth as BdkAuth;
|
use bdk::blockchain::rpc::Auth as BdkAuth;
|
||||||
use bdk::blockchain::rpc::RpcSyncParams as BdkRpcSyncParams;
|
use bdk::blockchain::rpc::RpcSyncParams as BdkRpcSyncParams;
|
||||||
@ -45,7 +45,7 @@ impl Blockchain {
|
|||||||
BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig {
|
BlockchainConfig::Rpc { config } => AnyBlockchainConfig::Rpc(BdkRpcConfig {
|
||||||
url: config.url,
|
url: config.url,
|
||||||
auth: config.auth.into(),
|
auth: config.auth.into(),
|
||||||
network: config.network,
|
network: config.network.into(),
|
||||||
wallet_name: config.wallet_name,
|
wallet_name: config.wallet_name,
|
||||||
sync_params: config.sync_params.map(|p| p.into()),
|
sync_params: config.sync_params.map(|p| p.into()),
|
||||||
}),
|
}),
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
use crate::Network;
|
||||||
use crate::{BdkError, DescriptorPublicKey, DescriptorSecretKey};
|
use crate::{BdkError, DescriptorPublicKey, DescriptorSecretKey};
|
||||||
|
use bdk::bitcoin::bip32::Fingerprint;
|
||||||
use bdk::bitcoin::secp256k1::Secp256k1;
|
use bdk::bitcoin::secp256k1::Secp256k1;
|
||||||
use bdk::bitcoin::util::bip32::Fingerprint;
|
use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor};
|
||||||
use bdk::bitcoin::Network;
|
|
||||||
use bdk::descriptor::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
|
|
||||||
use bdk::keys::{
|
use bdk::keys::{
|
||||||
DescriptorPublicKey as BdkDescriptorPublicKey, DescriptorSecretKey as BdkDescriptorSecretKey,
|
DescriptorPublicKey as BdkDescriptorPublicKey, DescriptorSecretKey as BdkDescriptorSecretKey,
|
||||||
|
KeyMap,
|
||||||
};
|
};
|
||||||
use bdk::template::{
|
use bdk::template::{
|
||||||
Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, Bip86, Bip86Public,
|
Bip44, Bip44Public, Bip49, Bip49Public, Bip84, Bip84Public, Bip86, Bip86Public,
|
||||||
@ -23,7 +24,8 @@ pub(crate) struct Descriptor {
|
|||||||
impl Descriptor {
|
impl Descriptor {
|
||||||
pub(crate) fn new(descriptor: String, network: Network) -> Result<Self, BdkError> {
|
pub(crate) fn new(descriptor: String, network: Network) -> Result<Self, BdkError> {
|
||||||
let secp = Secp256k1::new();
|
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 {
|
Ok(Self {
|
||||||
extended_descriptor,
|
extended_descriptor,
|
||||||
key_map,
|
key_map,
|
||||||
@ -40,8 +42,9 @@ impl Descriptor {
|
|||||||
match derivable_key {
|
match derivable_key {
|
||||||
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) = Bip44(derivable_key, keychain_kind)
|
||||||
Bip44(derivable_key, keychain_kind).build(network).unwrap();
|
.build(network.into())
|
||||||
|
.unwrap();
|
||||||
Self {
|
Self {
|
||||||
extended_descriptor,
|
extended_descriptor,
|
||||||
key_map,
|
key_map,
|
||||||
@ -50,6 +53,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorSecretKey::MultiXPrv(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +73,7 @@ impl Descriptor {
|
|||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) =
|
||||||
Bip44Public(derivable_key, fingerprint, keychain_kind)
|
Bip44Public(derivable_key, fingerprint, keychain_kind)
|
||||||
.build(network)
|
.build(network.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -78,6 +84,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorPublicKey::MultiXPub(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,8 +100,9 @@ impl Descriptor {
|
|||||||
match derivable_key {
|
match derivable_key {
|
||||||
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) = Bip49(derivable_key, keychain_kind)
|
||||||
Bip49(derivable_key, keychain_kind).build(network).unwrap();
|
.build(network.into())
|
||||||
|
.unwrap();
|
||||||
Self {
|
Self {
|
||||||
extended_descriptor,
|
extended_descriptor,
|
||||||
key_map,
|
key_map,
|
||||||
@ -101,6 +111,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorSecretKey::MultiXPrv(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +131,7 @@ impl Descriptor {
|
|||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) =
|
||||||
Bip49Public(derivable_key, fingerprint, keychain_kind)
|
Bip49Public(derivable_key, fingerprint, keychain_kind)
|
||||||
.build(network)
|
.build(network.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -129,6 +142,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorPublicKey::MultiXPub(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +158,9 @@ impl Descriptor {
|
|||||||
match derivable_key {
|
match derivable_key {
|
||||||
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) = Bip84(derivable_key, keychain_kind)
|
||||||
Bip84(derivable_key, keychain_kind).build(network).unwrap();
|
.build(network.into())
|
||||||
|
.unwrap();
|
||||||
Self {
|
Self {
|
||||||
extended_descriptor,
|
extended_descriptor,
|
||||||
key_map,
|
key_map,
|
||||||
@ -152,6 +169,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorSecretKey::MultiXPrv(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +189,7 @@ impl Descriptor {
|
|||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) =
|
||||||
Bip84Public(derivable_key, fingerprint, keychain_kind)
|
Bip84Public(derivable_key, fingerprint, keychain_kind)
|
||||||
.build(network)
|
.build(network.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -180,6 +200,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorPublicKey::MultiXPub(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,8 +216,9 @@ impl Descriptor {
|
|||||||
match derivable_key {
|
match derivable_key {
|
||||||
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) = Bip86(derivable_key, keychain_kind)
|
||||||
Bip86(derivable_key, keychain_kind).build(network).unwrap();
|
.build(network.into())
|
||||||
|
.unwrap();
|
||||||
Self {
|
Self {
|
||||||
extended_descriptor,
|
extended_descriptor,
|
||||||
key_map,
|
key_map,
|
||||||
@ -203,6 +227,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorSecretKey::MultiXPrv(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +247,7 @@ impl Descriptor {
|
|||||||
let derivable_key = descriptor_x_key.xkey;
|
let derivable_key = descriptor_x_key.xkey;
|
||||||
let (extended_descriptor, key_map, _) =
|
let (extended_descriptor, key_map, _) =
|
||||||
Bip86Public(derivable_key, fingerprint, keychain_kind)
|
Bip86Public(derivable_key, fingerprint, keychain_kind)
|
||||||
.build(network)
|
.build(network.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -231,6 +258,9 @@ impl Descriptor {
|
|||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorPublicKey::MultiXPub(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
use crate::BdkError;
|
use crate::BdkError;
|
||||||
|
|
||||||
|
use crate::Network;
|
||||||
|
use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath;
|
||||||
use bdk::bitcoin::secp256k1::Secp256k1;
|
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::bip39::{Language, Mnemonic as BdkMnemonic, WordCount};
|
||||||
use bdk::keys::{
|
use bdk::keys::{
|
||||||
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
|
DerivableKey, DescriptorPublicKey as BdkDescriptorPublicKey,
|
||||||
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
DescriptorSecretKey as BdkDescriptorSecretKey, ExtendedKey, GeneratableKey, GeneratedKey,
|
||||||
};
|
};
|
||||||
|
use bdk::miniscript::descriptor::{DescriptorXKey, Wildcard};
|
||||||
use bdk::miniscript::BareCtx;
|
use bdk::miniscript::BareCtx;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -75,9 +75,9 @@ impl DescriptorSecretKey {
|
|||||||
let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
|
let xkey: ExtendedKey = (mnemonic, password).into_extended_key().unwrap();
|
||||||
let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
|
let descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey {
|
||||||
origin: None,
|
origin: None,
|
||||||
xkey: xkey.into_xprv(network).unwrap(),
|
xkey: xkey.into_xprv(network.into()).unwrap(),
|
||||||
derivation_path: BdkDerivationPath::master(),
|
derivation_path: BdkDerivationPath::master(),
|
||||||
wildcard: bdk::descriptor::Wildcard::Unhardened,
|
wildcard: Wildcard::Unhardened,
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
inner: descriptor_secret_key,
|
inner: descriptor_secret_key,
|
||||||
@ -116,6 +116,9 @@ impl DescriptorSecretKey {
|
|||||||
BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic(
|
BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic(
|
||||||
"Cannot derive from a single key".to_string(),
|
"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(
|
BdkDescriptorSecretKey::Single(_) => Err(BdkError::Generic(
|
||||||
"Cannot extend from a single key".to_string(),
|
"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.
|
/// Get the private key as bytes.
|
||||||
pub(crate) fn secret_bytes(&self) -> Vec<u8> {
|
pub(crate) fn secret_bytes(&self) -> Vec<u8> {
|
||||||
let inner = &self.inner;
|
let inner = &self.inner;
|
||||||
let secret_bytes: Vec<u8> = match inner.deref() {
|
let secret_bytes: Vec<u8> = match inner {
|
||||||
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
BdkDescriptorSecretKey::XPrv(descriptor_x_key) => {
|
||||||
descriptor_x_key.xkey.private_key.secret_bytes().to_vec()
|
descriptor_x_key.xkey.private_key.secret_bytes().to_vec()
|
||||||
}
|
}
|
||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
BdkDescriptorSecretKey::MultiXPrv(_) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
secret_bytes
|
secret_bytes
|
||||||
@ -188,7 +197,7 @@ impl DescriptorPublicKey {
|
|||||||
let descriptor_public_key = &self.inner;
|
let descriptor_public_key = &self.inner;
|
||||||
let path = path.inner_mutex.lock().unwrap().deref().clone();
|
let path = path.inner_mutex.lock().unwrap().deref().clone();
|
||||||
|
|
||||||
match descriptor_public_key.deref() {
|
match descriptor_public_key {
|
||||||
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
||||||
let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?;
|
let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?;
|
||||||
let key_source = match descriptor_x_key.origin.clone() {
|
let key_source = match descriptor_x_key.origin.clone() {
|
||||||
@ -208,13 +217,16 @@ impl DescriptorPublicKey {
|
|||||||
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
|
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
|
||||||
"Cannot derive from a single key".to_string(),
|
"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> {
|
pub(crate) fn extend(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
let descriptor_public_key = &self.inner;
|
let descriptor_public_key = &self.inner;
|
||||||
let path = path.inner_mutex.lock().unwrap().deref().clone();
|
let path = path.inner_mutex.lock().unwrap().deref().clone();
|
||||||
match descriptor_public_key.deref() {
|
match descriptor_public_key {
|
||||||
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
BdkDescriptorPublicKey::XPub(descriptor_x_key) => {
|
||||||
let extended_path = descriptor_x_key.derivation_path.extend(path);
|
let extended_path = descriptor_x_key.derivation_path.extend(path);
|
||||||
let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
|
let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey {
|
||||||
@ -230,6 +242,9 @@ impl DescriptorPublicKey {
|
|||||||
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
|
BdkDescriptorPublicKey::Single(_) => Err(BdkError::Generic(
|
||||||
"Cannot extend from a single key".to_string(),
|
"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 {
|
mod test {
|
||||||
use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
|
use crate::keys::{DerivationPath, DescriptorPublicKey, DescriptorSecretKey, Mnemonic};
|
||||||
use crate::BdkError;
|
use crate::BdkError;
|
||||||
use bdk::bitcoin::hashes::hex::ToHex;
|
use crate::Network;
|
||||||
use bdk::bitcoin::Network;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn get_inner() -> DescriptorSecretKey {
|
fn get_inner() -> DescriptorSecretKey {
|
||||||
@ -358,14 +372,4 @@ mod test {
|
|||||||
let derived_dpk = &derive_dpk(&master_dpk, "m/84h/1h/0h");
|
let derived_dpk = &derive_dpk(&master_dpk, "m/84h/1h/0h");
|
||||||
assert!(derived_dpk.is_err());
|
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::psbt::PartiallySignedTransaction;
|
||||||
use crate::wallet::SignOptions;
|
use crate::wallet::SignOptions;
|
||||||
use crate::wallet::{BumpFeeTxBuilder, TxBuilder, Wallet};
|
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::TxIn as BdkTxIn;
|
||||||
use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut;
|
use bdk::bitcoin::blockdata::transaction::TxOut as BdkTxOut;
|
||||||
|
use bdk::bitcoin::consensus::encode::serialize;
|
||||||
use bdk::bitcoin::consensus::Decodable;
|
use bdk::bitcoin::consensus::Decodable;
|
||||||
use bdk::bitcoin::psbt::serialize::Serialize;
|
use bdk::bitcoin::network::constants::Network as BdkNetwork;
|
||||||
use bdk::bitcoin::util::address::{Payload as BdkPayload, WitnessVersion};
|
|
||||||
use bdk::bitcoin::{
|
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::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::keys::bip39::WordCount;
|
||||||
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
use bdk::wallet::AddressIndex as BdkAddressIndex;
|
||||||
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
use bdk::wallet::AddressInfo as BdkAddressInfo;
|
||||||
@ -41,6 +43,26 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
uniffi::include_scaffolding!("bdk");
|
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.
|
/// A output script and an amount of satoshis.
|
||||||
pub struct ScriptAmount {
|
pub struct ScriptAmount {
|
||||||
pub script: Arc<Script>,
|
pub script: Arc<Script>,
|
||||||
@ -202,9 +224,7 @@ impl From<&BdkTxOut> for TxOut {
|
|||||||
fn from(tx_out: &BdkTxOut) -> Self {
|
fn from(tx_out: &BdkTxOut) -> Self {
|
||||||
TxOut {
|
TxOut {
|
||||||
value: tx_out.value,
|
value: tx_out.value,
|
||||||
script_pubkey: Arc::new(Script {
|
script_pubkey: Arc::new(Script(tx_out.script_pubkey.clone())),
|
||||||
inner: tx_out.script_pubkey.clone(),
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,9 +245,7 @@ impl From<BdkLocalUtxo> for LocalUtxo {
|
|||||||
},
|
},
|
||||||
txout: TxOut {
|
txout: TxOut {
|
||||||
value: local_utxo.txout.value,
|
value: local_utxo.txout.value,
|
||||||
script_pubkey: Arc::new(Script {
|
script_pubkey: Arc::new(Script(local_utxo.txout.script_pubkey)),
|
||||||
inner: local_utxo.txout.script_pubkey,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
keychain: local_utxo.keychain,
|
keychain: local_utxo.keychain,
|
||||||
is_spent: local_utxo.is_spent,
|
is_spent: local_utxo.is_spent,
|
||||||
@ -274,9 +292,7 @@ impl From<&BdkTxIn> for TxIn {
|
|||||||
txid: tx_in.previous_output.txid.to_string(),
|
txid: tx_in.previous_output.txid.to_string(),
|
||||||
vout: tx_in.previous_output.vout,
|
vout: tx_in.previous_output.vout,
|
||||||
},
|
},
|
||||||
script_sig: Arc::new(Script {
|
script_sig: Arc::new(Script(tx_in.script_sig.clone())),
|
||||||
inner: tx_in.script_sig.clone(),
|
|
||||||
}),
|
|
||||||
sequence: tx_in.sequence.0,
|
sequence: tx_in.sequence.0,
|
||||||
witness: tx_in.witness.to_vec(),
|
witness: tx_in.witness.to_vec(),
|
||||||
}
|
}
|
||||||
@ -301,7 +317,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn weight(&self) -> u64 {
|
fn weight(&self) -> u64 {
|
||||||
self.inner.weight() as u64
|
self.inner.weight().to_wu()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> u64 {
|
fn size(&self) -> u64 {
|
||||||
@ -313,7 +329,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self) -> Vec<u8> {
|
fn serialize(&self) -> Vec<u8> {
|
||||||
self.inner.serialize()
|
serialize(&self.inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_coin_base(&self) -> bool {
|
fn is_coin_base(&self) -> bool {
|
||||||
@ -333,7 +349,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lock_time(&self) -> u32 {
|
fn lock_time(&self) -> u32 {
|
||||||
self.inner.lock_time.0
|
self.inner.lock_time.to_consensus_u32()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input(&self) -> Vec<TxIn> {
|
fn input(&self) -> Vec<TxIn> {
|
||||||
@ -358,15 +374,23 @@ pub struct Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Address {
|
impl Address {
|
||||||
fn new(address: String) -> Result<Self, BdkError> {
|
pub fn new(address: String, network: Network) -> Result<Self, BdkError> {
|
||||||
BdkAddress::from_str(address.as_str())
|
let parsed_address = address
|
||||||
.map(|a| Address { inner: a })
|
.parse::<bdk::bitcoin::Address<NetworkUnchecked>>()
|
||||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
.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
|
/// alternative constructor
|
||||||
fn from_script(script: Arc<Script>, network: Network) -> Result<Self, BdkError> {
|
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(|a| Address { inner: a })
|
||||||
.map_err(|e| BdkError::Generic(e.to_string()))
|
.map_err(|e| BdkError::Generic(e.to_string()))
|
||||||
}
|
}
|
||||||
@ -374,32 +398,40 @@ impl Address {
|
|||||||
fn payload(&self) -> Payload {
|
fn payload(&self) -> Payload {
|
||||||
match &self.inner.payload.clone() {
|
match &self.inner.payload.clone() {
|
||||||
BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
|
BdkPayload::PubkeyHash(pubkey_hash) => Payload::PubkeyHash {
|
||||||
pubkey_hash: pubkey_hash.to_vec(),
|
pubkey_hash: pubkey_hash.to_string(),
|
||||||
},
|
},
|
||||||
BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
|
BdkPayload::ScriptHash(script_hash) => Payload::ScriptHash {
|
||||||
script_hash: script_hash.to_vec(),
|
script_hash: script_hash.to_string(),
|
||||||
},
|
},
|
||||||
BdkPayload::WitnessProgram { version, program } => Payload::WitnessProgram {
|
BdkPayload::WitnessProgram(witness_program) => Payload::WitnessProgram {
|
||||||
version: *version,
|
version: witness_program.version(),
|
||||||
program: program.clone(),
|
program: Vec::from(witness_program.program().as_bytes()),
|
||||||
},
|
},
|
||||||
|
_ => panic!("Unsupported address payload type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn network(&self) -> Network {
|
fn network(&self) -> Network {
|
||||||
self.inner.network
|
self.inner.network.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_pubkey(&self) -> Arc<Script> {
|
fn script_pubkey(&self) -> Arc<Script> {
|
||||||
Arc::new(Script {
|
Arc::new(Script(self.inner.script_pubkey()))
|
||||||
inner: self.inner.script_pubkey(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_qr_uri(&self) -> String {
|
fn to_qr_uri(&self) -> String {
|
||||||
self.inner.to_qr_uri()
|
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 {
|
fn as_string(&self) -> String {
|
||||||
self.inner.to_string()
|
self.inner.to_string()
|
||||||
}
|
}
|
||||||
@ -415,9 +447,9 @@ impl From<BdkAddress> for Address {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Payload {
|
pub enum Payload {
|
||||||
/// P2PKH address.
|
/// P2PKH address.
|
||||||
PubkeyHash { pubkey_hash: Vec<u8> },
|
PubkeyHash { pubkey_hash: String },
|
||||||
/// P2SH address.
|
/// P2SH address.
|
||||||
ScriptHash { script_hash: Vec<u8> },
|
ScriptHash { script_hash: String },
|
||||||
/// Segwit address.
|
/// Segwit address.
|
||||||
WitnessProgram {
|
WitnessProgram {
|
||||||
/// The witness program version.
|
/// 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)]
|
#[derive(Clone, Debug)]
|
||||||
enum RbfValue {
|
enum RbfValue {
|
||||||
Default,
|
Default,
|
||||||
@ -463,6 +472,37 @@ pub struct TxBuilderResult {
|
|||||||
pub transaction_details: TransactionDetails,
|
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);
|
uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
||||||
|
|
||||||
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
// The goal of these tests to to ensure `bdk-ffi` intermediate code correctly calls `bdk` APIs.
|
||||||
@ -470,30 +510,33 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send);
|
|||||||
// crate.
|
// crate.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::Transaction;
|
|
||||||
use crate::Network::Regtest;
|
use crate::Network::Regtest;
|
||||||
use crate::{Address, Payload};
|
use crate::{Address, Payload};
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
|
use bdk::bitcoin::address::WitnessVersion;
|
||||||
use bdk::bitcoin::hashes::hex::FromHex;
|
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.
|
// Verify that bdk-ffi Transaction can be created from valid bytes and serialized back into the same bytes.
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_transaction_serde() {
|
// fn test_transaction_serde() {
|
||||||
let test_tx_bytes = Vec::from_hex("020000000001031cfbc8f54fbfa4a33a30068841371f80dbfe166211242213188428f437445c91000000006a47304402206fbcec8d2d2e740d824d3d36cc345b37d9f65d665a99f5bd5c9e8d42270a03a8022013959632492332200c2908459547bf8dbf97c65ab1a28dec377d6f1d41d3d63e012103d7279dfb90ce17fe139ba60a7c41ddf605b25e1c07a4ddcb9dfef4e7d6710f48feffffff476222484f5e35b3f0e43f65fc76e21d8be7818dd6a989c160b1e5039b7835fc00000000171600140914414d3c94af70ac7e25407b0689e0baa10c77feffffffa83d954a62568bbc99cc644c62eb7383d7c2a2563041a0aeb891a6a4055895570000000017160014795d04cc2d4f31480d9a3710993fbd80d04301dffeffffff06fef72f000000000017a91476fd7035cd26f1a32a5ab979e056713aac25796887a5000f00000000001976a914b8332d502a529571c6af4be66399cd33379071c588ac3fda0500000000001976a914fc1d692f8de10ae33295f090bea5fe49527d975c88ac522e1b00000000001976a914808406b54d1044c429ac54c0e189b0d8061667e088ac6eb68501000000001976a914dfab6085f3a8fb3e6710206a5a959313c5618f4d88acbba20000000000001976a914eb3026552d7e3f3073457d0bee5d4757de48160d88ac0002483045022100bee24b63212939d33d513e767bc79300051f7a0d433c3fcf1e0e3bf03b9eb1d70220588dc45a9ce3a939103b4459ce47500b64e23ab118dfc03c9caa7d6bfc32b9c601210354fd80328da0f9ae6eef2b3a81f74f9a6f66761fadf96f1d1d22b1fd6845876402483045022100e29c7e3a5efc10da6269e5fc20b6a1cb8beb92130cc52c67e46ef40aaa5cac5f0220644dd1b049727d991aece98a105563416e10a5ac4221abac7d16931842d5c322012103960b87412d6e169f30e12106bdf70122aabb9eb61f455518322a18b920a4dfa887d30700").unwrap();
|
// let test_tx_bytes = Vec::from_hex("020000000001031cfbc8f54fbfa4a33a30068841371f80dbfe166211242213188428f437445c91000000006a47304402206fbcec8d2d2e740d824d3d36cc345b37d9f65d665a99f5bd5c9e8d42270a03a8022013959632492332200c2908459547bf8dbf97c65ab1a28dec377d6f1d41d3d63e012103d7279dfb90ce17fe139ba60a7c41ddf605b25e1c07a4ddcb9dfef4e7d6710f48feffffff476222484f5e35b3f0e43f65fc76e21d8be7818dd6a989c160b1e5039b7835fc00000000171600140914414d3c94af70ac7e25407b0689e0baa10c77feffffffa83d954a62568bbc99cc644c62eb7383d7c2a2563041a0aeb891a6a4055895570000000017160014795d04cc2d4f31480d9a3710993fbd80d04301dffeffffff06fef72f000000000017a91476fd7035cd26f1a32a5ab979e056713aac25796887a5000f00000000001976a914b8332d502a529571c6af4be66399cd33379071c588ac3fda0500000000001976a914fc1d692f8de10ae33295f090bea5fe49527d975c88ac522e1b00000000001976a914808406b54d1044c429ac54c0e189b0d8061667e088ac6eb68501000000001976a914dfab6085f3a8fb3e6710206a5a959313c5618f4d88acbba20000000000001976a914eb3026552d7e3f3073457d0bee5d4757de48160d88ac0002483045022100bee24b63212939d33d513e767bc79300051f7a0d433c3fcf1e0e3bf03b9eb1d70220588dc45a9ce3a939103b4459ce47500b64e23ab118dfc03c9caa7d6bfc32b9c601210354fd80328da0f9ae6eef2b3a81f74f9a6f66761fadf96f1d1d22b1fd6845876402483045022100e29c7e3a5efc10da6269e5fc20b6a1cb8beb92130cc52c67e46ef40aaa5cac5f0220644dd1b049727d991aece98a105563416e10a5ac4221abac7d16931842d5c322012103960b87412d6e169f30e12106bdf70122aabb9eb61f455518322a18b920a4dfa887d30700").unwrap();
|
||||||
let new_tx_from_bytes = Transaction::new(test_tx_bytes.clone()).unwrap();
|
// let new_tx_from_bytes = Transaction::new(test_tx_bytes.clone()).unwrap();
|
||||||
let serialized_tx_to_bytes = new_tx_from_bytes.serialize();
|
// let serialized_tx_to_bytes = new_tx_from_bytes.serialize();
|
||||||
assert_eq!(test_tx_bytes, serialized_tx_to_bytes);
|
// assert_eq!(test_tx_bytes, serialized_tx_to_bytes);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Verify that bdk-ffi Address.payload includes expected WitnessProgram variant, version and program bytes.
|
// Verify that bdk-ffi Address.payload includes expected WitnessProgram variant, version and program bytes.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_address_witness_program() {
|
fn test_address_witness_program() {
|
||||||
let address =
|
let address = Address::new(
|
||||||
Address::new("bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv".to_string()).unwrap();
|
"bcrt1qqjn9gky9mkrm3c28e5e87t5akd3twg6xezp0tv".to_string(),
|
||||||
|
Network::Regtest.into(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let payload = address.payload();
|
let payload = address.payload();
|
||||||
assert_matches!(payload, Payload::WitnessProgram { version, program } => {
|
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!(program, Vec::from_hex("04a6545885dd87b8e147cd327f2e9db362b72346").unwrap());
|
||||||
});
|
});
|
||||||
assert_eq!(address.network(), Regtest);
|
assert_eq!(address.network(), Regtest);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use bdk::bitcoin::hashes::hex::ToHex;
|
use bdk::bitcoin::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
||||||
use bdk::bitcoin::util::psbt::PartiallySignedTransaction as BdkPartiallySignedTransaction;
|
|
||||||
use bdk::bitcoincore_rpc::jsonrpc::serde_json;
|
use bdk::bitcoincore_rpc::jsonrpc::serde_json;
|
||||||
use bdk::psbt::PsbtUtils;
|
use bdk::psbt::PsbtUtils;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@ -30,7 +29,7 @@ impl PartiallySignedTransaction {
|
|||||||
pub(crate) fn txid(&self) -> String {
|
pub(crate) fn txid(&self) -> String {
|
||||||
let tx = self.inner.lock().unwrap().clone().extract_tx();
|
let tx = self.inner.lock().unwrap().clone().extract_tx();
|
||||||
let txid = tx.txid();
|
let txid = tx.txid();
|
||||||
txid.to_hex()
|
txid.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the transaction.
|
/// Return the transaction.
|
||||||
@ -82,6 +81,7 @@ impl PartiallySignedTransaction {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::wallet::{TxBuilder, Wallet};
|
use crate::wallet::{TxBuilder, Wallet};
|
||||||
|
use crate::Network;
|
||||||
use bdk::wallet::get_funded_wallet;
|
use bdk::wallet::get_funded_wallet;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ mod test {
|
|||||||
inner_mutex: Mutex::new(funded_wallet),
|
inner_mutex: Mutex::new(funded_wallet),
|
||||||
};
|
};
|
||||||
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
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()
|
.unwrap()
|
||||||
.script_pubkey();
|
.script_pubkey();
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ mod test {
|
|||||||
.drain_to(drain_to_script.clone());
|
.drain_to(drain_to_script.clone());
|
||||||
//dbg!(&tx_builder);
|
//dbg!(&tx_builder);
|
||||||
assert!(tx_builder.drain_wallet);
|
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 tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use bdk::bitcoin::blockdata::script::Script as BdkScript;
|
use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
|
||||||
use bdk::bitcoin::{Address as BdkAddress, Network, OutPoint as BdkOutPoint, Sequence, Txid};
|
use bdk::bitcoin::script::PushBytesBuf;
|
||||||
|
use bdk::bitcoin::{OutPoint as BdkOutPoint, Sequence, Txid};
|
||||||
use bdk::database::any::AnyDatabase;
|
use bdk::database::any::AnyDatabase;
|
||||||
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
use bdk::wallet::tx_builder::ChangeSpendPolicy;
|
||||||
@ -8,6 +9,7 @@ use bdk::{
|
|||||||
SyncOptions as BdkSyncOptions, Wallet as BdkWallet,
|
SyncOptions as BdkSyncOptions, Wallet as BdkWallet,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::convert::TryFrom;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
@ -16,6 +18,7 @@ use crate::blockchain::Blockchain;
|
|||||||
use crate::database::DatabaseConfig;
|
use crate::database::DatabaseConfig;
|
||||||
use crate::descriptor::Descriptor;
|
use crate::descriptor::Descriptor;
|
||||||
use crate::psbt::PartiallySignedTransaction;
|
use crate::psbt::PartiallySignedTransaction;
|
||||||
|
use crate::Network;
|
||||||
use crate::{
|
use crate::{
|
||||||
AddressIndex, AddressInfo, Balance, BdkError, LocalUtxo, OutPoint, Progress, ProgressHolder,
|
AddressIndex, AddressInfo, Balance, BdkError, LocalUtxo, OutPoint, Progress, ProgressHolder,
|
||||||
RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
|
RbfValue, Script, ScriptAmount, TransactionDetails, TxBuilderResult,
|
||||||
@ -50,7 +53,7 @@ impl Wallet {
|
|||||||
let wallet_mutex = Mutex::new(BdkWallet::new(
|
let wallet_mutex = Mutex::new(BdkWallet::new(
|
||||||
&descriptor,
|
&descriptor,
|
||||||
change_descriptor.as_ref(),
|
change_descriptor.as_ref(),
|
||||||
network,
|
network.into(),
|
||||||
database,
|
database,
|
||||||
)?);
|
)?);
|
||||||
Ok(Wallet {
|
Ok(Wallet {
|
||||||
@ -64,12 +67,12 @@ impl Wallet {
|
|||||||
|
|
||||||
/// Get the Bitcoin network the wallet is using.
|
/// Get the Bitcoin network the wallet is using.
|
||||||
pub(crate) fn network(&self) -> Network {
|
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).
|
/// 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> {
|
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.
|
/// 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.
|
/// Each method on the TxBuilder returns an instance of a new TxBuilder with the option set/added.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct TxBuilder {
|
pub(crate) struct TxBuilder {
|
||||||
pub(crate) recipients: Vec<(BdkScript, u64)>,
|
pub(crate) recipients: Vec<(BdkScriptBuf, u64)>,
|
||||||
pub(crate) utxos: Vec<OutPoint>,
|
pub(crate) utxos: Vec<OutPoint>,
|
||||||
pub(crate) unspendable: HashSet<OutPoint>,
|
pub(crate) unspendable: HashSet<OutPoint>,
|
||||||
pub(crate) change_policy: ChangeSpendPolicy,
|
pub(crate) change_policy: ChangeSpendPolicy,
|
||||||
@ -248,7 +251,7 @@ pub(crate) struct TxBuilder {
|
|||||||
pub(crate) fee_rate: Option<f32>,
|
pub(crate) fee_rate: Option<f32>,
|
||||||
pub(crate) fee_absolute: Option<u64>,
|
pub(crate) fee_absolute: Option<u64>,
|
||||||
pub(crate) drain_wallet: bool,
|
pub(crate) drain_wallet: bool,
|
||||||
pub(crate) drain_to: Option<BdkScript>,
|
pub(crate) drain_to: Option<BdkScriptBuf>,
|
||||||
pub(crate) rbf: Option<RbfValue>,
|
pub(crate) rbf: Option<RbfValue>,
|
||||||
pub(crate) data: Vec<u8>,
|
pub(crate) data: Vec<u8>,
|
||||||
}
|
}
|
||||||
@ -272,8 +275,8 @@ impl TxBuilder {
|
|||||||
|
|
||||||
/// Add a recipient to the internal list.
|
/// Add a recipient to the internal list.
|
||||||
pub(crate) fn add_recipient(&self, script: Arc<Script>, amount: u64) -> Arc<Self> {
|
pub(crate) fn add_recipient(&self, script: Arc<Script>, amount: u64) -> Arc<Self> {
|
||||||
let mut recipients: Vec<(BdkScript, u64)> = self.recipients.clone();
|
let mut recipients: Vec<(BdkScriptBuf, u64)> = self.recipients.clone();
|
||||||
recipients.append(&mut vec![(script.inner.clone(), amount)]);
|
recipients.append(&mut vec![(script.0.clone(), amount)]);
|
||||||
Arc::new(TxBuilder {
|
Arc::new(TxBuilder {
|
||||||
recipients,
|
recipients,
|
||||||
..self.clone()
|
..self.clone()
|
||||||
@ -283,7 +286,7 @@ impl TxBuilder {
|
|||||||
pub(crate) fn set_recipients(&self, recipients: Vec<ScriptAmount>) -> Arc<Self> {
|
pub(crate) fn set_recipients(&self, recipients: Vec<ScriptAmount>) -> Arc<Self> {
|
||||||
let recipients = recipients
|
let recipients = recipients
|
||||||
.iter()
|
.iter()
|
||||||
.map(|script_amount| (script_amount.script.inner.clone(), script_amount.amount))
|
.map(|script_amount| (script_amount.script.0.clone(), script_amount.amount))
|
||||||
.collect();
|
.collect();
|
||||||
Arc::new(TxBuilder {
|
Arc::new(TxBuilder {
|
||||||
recipients,
|
recipients,
|
||||||
@ -388,7 +391,7 @@ impl TxBuilder {
|
|||||||
/// to allow this output to be reduced to pay for the extra fees.
|
/// to allow this output to be reduced to pay for the extra fees.
|
||||||
pub(crate) fn drain_to(&self, script: Arc<Script>) -> Arc<Self> {
|
pub(crate) fn drain_to(&self, script: Arc<Script>) -> Arc<Self> {
|
||||||
Arc::new(TxBuilder {
|
Arc::new(TxBuilder {
|
||||||
drain_to: Some(script.inner.clone()),
|
drain_to: Some(script.0.clone()),
|
||||||
..self.clone()
|
..self.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -463,7 +466,10 @@ impl TxBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !&self.data.is_empty() {
|
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
|
tx_builder
|
||||||
@ -482,7 +488,7 @@ impl TxBuilder {
|
|||||||
pub(crate) struct BumpFeeTxBuilder {
|
pub(crate) struct BumpFeeTxBuilder {
|
||||||
pub(crate) txid: String,
|
pub(crate) txid: String,
|
||||||
pub(crate) fee_rate: f32,
|
pub(crate) fee_rate: f32,
|
||||||
pub(crate) allow_shrinking: Option<String>,
|
pub(crate) allow_shrinking: Option<Arc<Script>>,
|
||||||
pub(crate) rbf: Option<RbfValue>,
|
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
|
/// 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
|
/// 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.
|
/// 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 {
|
Arc::new(Self {
|
||||||
allow_shrinking: Some(address),
|
allow_shrinking: Some(script_pubkey),
|
||||||
..self.clone()
|
..self.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -536,10 +542,7 @@ impl BumpFeeTxBuilder {
|
|||||||
let mut tx_builder = wallet.build_fee_bump(txid)?;
|
let mut tx_builder = wallet.build_fee_bump(txid)?;
|
||||||
tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate));
|
tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate));
|
||||||
if let Some(allow_shrinking) = &self.allow_shrinking {
|
if let Some(allow_shrinking) = &self.allow_shrinking {
|
||||||
let address = BdkAddress::from_str(allow_shrinking)
|
tx_builder.allow_shrinking(allow_shrinking.0.clone())?;
|
||||||
.map_err(|e| BdkError::Generic(e.to_string()))?;
|
|
||||||
let script = address.script_pubkey();
|
|
||||||
tx_builder.allow_shrinking(script)?;
|
|
||||||
}
|
}
|
||||||
if let Some(rbf) = &self.rbf {
|
if let Some(rbf) = &self.rbf {
|
||||||
match *rbf {
|
match *rbf {
|
||||||
@ -569,9 +572,10 @@ mod test {
|
|||||||
use crate::descriptor::Descriptor;
|
use crate::descriptor::Descriptor;
|
||||||
use crate::keys::{DescriptorSecretKey, Mnemonic};
|
use crate::keys::{DescriptorSecretKey, Mnemonic};
|
||||||
use crate::wallet::{AddressIndex, TxBuilder, Wallet};
|
use crate::wallet::{AddressIndex, TxBuilder, Wallet};
|
||||||
|
use crate::Network;
|
||||||
use crate::Script;
|
use crate::Script;
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use bdk::bitcoin::{Address, Network};
|
use bdk::bitcoin::Address;
|
||||||
use bdk::wallet::get_funded_wallet;
|
use bdk::wallet::get_funded_wallet;
|
||||||
use bdk::KeychainKind;
|
use bdk::KeychainKind;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@ -585,14 +589,14 @@ mod test {
|
|||||||
inner_mutex: Mutex::new(funded_wallet),
|
inner_mutex: Mutex::new(funded_wallet),
|
||||||
};
|
};
|
||||||
let drain_to_address = "tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt".to_string();
|
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()
|
.unwrap()
|
||||||
.script_pubkey();
|
.script_pubkey();
|
||||||
let tx_builder = TxBuilder::new()
|
let tx_builder = TxBuilder::new()
|
||||||
.drain_wallet()
|
.drain_wallet()
|
||||||
.drain_to(drain_to_script.clone());
|
.drain_to(drain_to_script.clone());
|
||||||
assert!(tx_builder.drain_wallet);
|
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 tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
|
||||||
let psbt = tx_builder_result.psbt.inner.lock().unwrap().clone();
|
let psbt = tx_builder_result.psbt.inner.lock().unwrap().clone();
|
||||||
@ -623,12 +627,14 @@ mod test {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.script_pubkey,
|
.script_pubkey,
|
||||||
Network::Testnet,
|
Network::Testnet.into(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
output_address,
|
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;
|
let output_value = psbt.unsigned_tx.output.get(0).cloned().unwrap().value;
|
||||||
assert_eq!(output_value, 49_890_u64); // input - fee
|
assert_eq!(output_value, 49_890_u64); // input - fee
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
kotlin.code.style=official
|
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(
|
setup(
|
||||||
name="bdkpython",
|
name="bdkpython",
|
||||||
version="0.31.0.dev0",
|
version="0.31.0",
|
||||||
description="The Python language bindings for the Bitcoin Development Kit",
|
description="The Python language bindings for the Bitcoin Development Kit",
|
||||||
long_description=LONG_DESCRIPTION,
|
long_description=LONG_DESCRIPTION,
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>SupportedPlatform</key>
|
<key>SupportedPlatform</key>
|
||||||
<string>macos</string>
|
<string>macos</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>12.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>LibraryIdentifier</key>
|
<key>LibraryIdentifier</key>
|
||||||
@ -31,6 +33,8 @@
|
|||||||
<string>ios</string>
|
<string>ios</string>
|
||||||
<key>SupportedPlatformVariant</key>
|
<key>SupportedPlatformVariant</key>
|
||||||
<string>simulator</string>
|
<string>simulator</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>15.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>LibraryIdentifier</key>
|
<key>LibraryIdentifier</key>
|
||||||
@ -43,6 +47,8 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>SupportedPlatform</key>
|
<key>SupportedPlatform</key>
|
||||||
<string>ios</string>
|
<string>ios</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>15.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundlePackageType</key>
|
<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