feat: bump rust libraries to alpha 13

This commit is contained in:
thunderbiscuit 2024-06-24 10:15:30 -04:00
parent 92aeeab436
commit f66f8417cf
No known key found for this signature in database
GPG Key ID: 88253696EB836462
10 changed files with 438 additions and 655 deletions

220
bdk-ffi/Cargo.lock generated
View File

@ -128,6 +128,16 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "base58ck"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f"
dependencies = [
"bitcoin-internals 0.3.0",
"bitcoin_hashes 0.14.0",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.12.3" version = "0.12.3"
@ -165,37 +175,27 @@ dependencies = [
"bdk_esplora", "bdk_esplora",
"bdk_sqlite", "bdk_sqlite",
"bdk_wallet", "bdk_wallet",
"bitcoin-internals", "bitcoin-internals 0.2.0",
"thiserror", "thiserror",
"uniffi", "uniffi",
] ]
[[package]] [[package]]
name = "bdk_bitcoind_rpc" name = "bdk_bitcoind_rpc"
version = "0.10.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 = "54fe9410002d5c350b59145ed0b18af1bb81521e7d62515defe539a450e20551" checksum = "ae8b85b7f47af08bb41d6fb9301c9de8ad937a4d506ba0d9920b094fd48d8fbb"
dependencies = [ dependencies = [
"bdk_chain 0.14.0", "bdk_chain",
"bitcoin", "bitcoin",
"bitcoincore-rpc", "bitcoincore-rpc",
] ]
[[package]] [[package]]
name = "bdk_chain" name = "bdk_chain"
version = "0.14.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "440ec5b1c8911f126b540e05c98493b699b497a3cb90c5e9c5eee21cdd8d1e01" checksum = "163b064557cee078e8ee5dd2c88944204506f7b2b1524f78e8fcba38c346da7b"
dependencies = [
"bitcoin",
"miniscript",
]
[[package]]
name = "bdk_chain"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c601c4dc7e6c3efa538a0afbb43b964cefab9a9b5e8f352fa0ca38145448a5e7"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"miniscript", "miniscript",
@ -204,43 +204,31 @@ dependencies = [
[[package]] [[package]]
name = "bdk_electrum" name = "bdk_electrum"
version = "0.14.0" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/thunderbiscuit/bdk/?branch=feature/electrum-client-ring-feature#31ddf1b4b600e9bf10e622cb0dee7ff158439b48"
checksum = "28906275aeb1f71dc32045670f06c8a26fb17cc62151a99f7425d258f4bda589"
dependencies = [ dependencies = [
"bdk_chain 0.15.0", "bdk_chain",
"electrum-client", "electrum-client",
] ]
[[package]] [[package]]
name = "bdk_esplora" name = "bdk_esplora"
version = "0.14.0" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b2409ff6b35fc69e864bc6986731e024ccd70bd325183f8ffff1590d9895d1" checksum = "089babab213bbb32518bad79a7313ebb4c85a52c18c8b558402dfa810c27de3f"
dependencies = [ dependencies = [
"bdk_chain 0.15.0", "bdk_chain",
"esplora-client", "esplora-client",
] "miniscript",
[[package]]
name = "bdk_persist"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41528569e8507f078143526c72bdee75f93f17d3b028cb7d88b4889278973e7d"
dependencies = [
"anyhow",
"bdk_chain 0.15.0",
] ]
[[package]] [[package]]
name = "bdk_sqlite" name = "bdk_sqlite"
version = "0.1.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b665413b2c5d5151dbb9cb6a855ccbbc26fdb6143f22faf2deea4e8c61fc33e6" checksum = "0926dc5778fb3c5afaf7def9ed9b9c9d9fe9e3ba499e09cb816d3de43211be71"
dependencies = [ dependencies = [
"anyhow", "bdk_chain",
"bdk_chain 0.15.0",
"bdk_persist",
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
@ -248,13 +236,11 @@ dependencies = [
[[package]] [[package]]
name = "bdk_wallet" name = "bdk_wallet"
version = "1.0.0-alpha.12" version = "1.0.0-alpha.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f830d1a9a090b5837d3813aff8b90888e04b72bf2704b29796e1bab439c86255" checksum = "2926afdbfc54ebf7df2caa51af5be4435b90c01c6fbe5578b51b7c2c0a264bd9"
dependencies = [ dependencies = [
"anyhow", "bdk_chain",
"bdk_chain 0.15.0",
"bdk_persist",
"bip39", "bip39",
"bitcoin", "bitcoin",
"getrandom", "getrandom",
@ -267,9 +253,9 @@ dependencies = [
[[package]] [[package]]
name = "bech32" name = "bech32"
version = "0.10.0-beta" 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 = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
[[package]] [[package]]
name = "bincode" name = "bincode"
@ -293,15 +279,18 @@ dependencies = [
[[package]] [[package]]
name = "bitcoin" name = "bitcoin"
version = "0.31.2" version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae" checksum = "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6"
dependencies = [ dependencies = [
"base58ck",
"base64 0.21.7", "base64 0.21.7",
"bech32", "bech32",
"bitcoin-internals", "bitcoin-internals 0.3.0",
"bitcoin_hashes 0.13.0", "bitcoin-io",
"hex-conservative 0.1.2", "bitcoin-units",
"bitcoin_hashes 0.14.0",
"hex-conservative",
"hex_lit", "hex_lit",
"secp256k1", "secp256k1",
"serde", "serde",
@ -312,10 +301,32 @@ name = "bitcoin-internals"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb"
[[package]]
name = "bitcoin-internals"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "bitcoin-io"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56"
[[package]]
name = "bitcoin-units"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb54da0b28892f3c52203a7191534033e051b6f4b52bc15480681b57b7e036f5"
dependencies = [
"bitcoin-internals 0.3.0",
"serde",
]
[[package]] [[package]]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.11.0" version = "0.11.0"
@ -324,20 +335,20 @@ checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
[[package]] [[package]]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.13.0" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
dependencies = [ dependencies = [
"bitcoin-internals", "bitcoin-io",
"hex-conservative 0.1.2", "hex-conservative",
"serde", "serde",
] ]
[[package]] [[package]]
name = "bitcoincore-rpc" name = "bitcoincore-rpc"
version = "0.18.0" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eb70725a621848c83b3809913d5314c0d20ca84877d99dd909504b564edab00" checksum = "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee"
dependencies = [ dependencies = [
"bitcoincore-rpc-json", "bitcoincore-rpc-json",
"jsonrpc", "jsonrpc",
@ -348,9 +359,9 @@ dependencies = [
[[package]] [[package]]
name = "bitcoincore-rpc-json" name = "bitcoincore-rpc-json"
version = "0.18.0" version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "856ffbee2e492c23bca715d72ea34aae80d58400f2bda26a82015d6bc2ec3662" checksum = "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"serde", "serde",
@ -473,15 +484,14 @@ checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]] [[package]]
name = "electrum-client" name = "electrum-client"
version = "0.19.0" version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/thunderbiscuit/rust-electrum-client/?branch=feature/ring-feature#7576e1b6d1f298d270526d740b8508923f3fb790"
checksum = "89008f106be6f303695522f2f4c1f28b40c3e8367ed8b3bb227f1f882cb52cc2"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"byteorder", "byteorder",
"libc", "libc",
"log", "log",
"rustls", "rustls 0.23.10",
"serde", "serde",
"serde_json", "serde_json",
"webpki-roots", "webpki-roots",
@ -490,12 +500,12 @@ dependencies = [
[[package]] [[package]]
name = "esplora-client" name = "esplora-client"
version = "0.7.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a73e879128c5fcb38abaf0ec53e3310947c6e7b61ce0f1b4cd7a0b8ea1ab0389" checksum = "69c6d27ef4ff21019edd98aa92199757e10a88065bbfcef6bb750ca6ec5e4a45"
dependencies = [ dependencies = [
"bitcoin", "bitcoin",
"hex-conservative 0.2.1", "hex-conservative",
"log", "log",
"minreq", "minreq",
"serde", "serde",
@ -574,12 +584,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex-conservative"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20"
[[package]] [[package]]
name = "hex-conservative" name = "hex-conservative"
version = "0.2.1" version = "0.2.1"
@ -618,11 +622,12 @@ dependencies = [
[[package]] [[package]]
name = "jsonrpc" name = "jsonrpc"
version = "0.14.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 = "8128f36b47411cd3f044be8c1f5cc0c9e24d1d1bfdc45f0a57897b32513053f2" checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf"
dependencies = [ dependencies = [
"base64 0.13.1", "base64 0.13.1",
"minreq",
"serde", "serde",
"serde_json", "serde_json",
] ]
@ -652,9 +657,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "mime" name = "mime"
@ -680,13 +685,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniscript" name = "miniscript"
version = "11.0.0" version = "12.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86a23dd3ad145a980e231185d114399f25a0a307d2cd918010ddda6334323df9" checksum = "b59c67956fd276ceec0cf194fbf80754ef4d88a496d5cf5e4fdf33561466183d"
dependencies = [ dependencies = [
"bech32", "bech32",
"bitcoin", "bitcoin",
"bitcoin-internals",
"serde", "serde",
] ]
@ -699,8 +703,8 @@ dependencies = [
"base64 0.12.3", "base64 0.12.3",
"log", "log",
"once_cell", "once_cell",
"rustls", "rustls 0.21.12",
"rustls-webpki", "rustls-webpki 0.101.7",
"serde", "serde",
"serde_json", "serde_json",
"webpki-roots", "webpki-roots",
@ -831,10 +835,31 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [ dependencies = [
"log", "log",
"ring", "ring",
"rustls-webpki", "rustls-webpki 0.101.7",
"sct", "sct",
] ]
[[package]]
name = "rustls"
version = "0.23.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki 0.102.4",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.101.7" version = "0.101.7"
@ -845,6 +870,17 @@ dependencies = [
"untrusted", "untrusted",
] ]
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.18"
@ -883,11 +919,11 @@ dependencies = [
[[package]] [[package]]
name = "secp256k1" name = "secp256k1"
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 = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3"
dependencies = [ dependencies = [
"bitcoin_hashes 0.13.0", "bitcoin_hashes 0.14.0",
"rand", "rand",
"secp256k1-sys", "secp256k1-sys",
"serde", "serde",
@ -895,9 +931,9 @@ dependencies = [
[[package]] [[package]]
name = "secp256k1-sys" name = "secp256k1-sys"
version = "0.9.2" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b"
dependencies = [ dependencies = [
"cc", "cc",
] ]
@ -978,6 +1014,12 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d0208408ba0c3df17ed26eb06992cb1a1268d41b2c0e12e65203fbe3972cee5"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.66" version = "2.0.66"
@ -1410,3 +1452,9 @@ dependencies = [
"quote", "quote",
"syn", "syn",
] ]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"

View File

@ -18,14 +18,17 @@ path = "uniffi-bindgen.rs"
default = ["uniffi/cli"] default = ["uniffi/cli"]
[dependencies] [dependencies]
bdk_wallet = { version = "1.0.0-alpha.12", features = ["all-keys", "keys-bip39"] } bdk_wallet = { version = "1.0.0-alpha.13", features = ["all-keys", "keys-bip39"] }
bdk_esplora = { version = "0.14.0", default-features = false, features = ["std", "blocking", "blocking-https-rustls"] } bdk_esplora = { version = "0.15.0", default-features = false, features = ["std", "blocking", "blocking-https-rustls"] }
bdk_electrum = { version = "0.14.0" } # NOTE: This is a temporary workaround to use the electrum-client with the use-rustls-ring feature. It points to a fork
bdk_sqlite = { version = "0.1.0" } # of bdk in which the bdk_electrum library uses the electrum-client with the use-rustls-ring feature.
bdk_bitcoind_rpc = { version = "0.10.0" } bdk_electrum = { git = "https://github.com/thunderbiscuit/bdk/", package = "bdk_electrum", branch = "feature/electrum-client-ring-feature" }
# bdk_electrum = { version = "0.15.0" }
bdk_sqlite = { version = "0.2.0" }
bdk_bitcoind_rpc = { version = "0.12.0" }
bitcoin-internals = { version = "0.2.0", features = ["alloc"] }
uniffi = { version = "=0.28.0" } uniffi = { version = "=0.28.0" }
bitcoin-internals = { version = "0.2.0", features = ["alloc"] }
thiserror = "1.0.58" thiserror = "1.0.58"
[build-dependencies] [build-dependencies]

View File

@ -5,16 +5,17 @@ namespace bdk {};
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
[Error] [Error]
interface AddressError { interface AddressParseError {
Base58(); Base58();
Bech32(); Bech32();
WitnessVersion(string error_message); WitnessVersion(string error_message);
WitnessProgram(string error_message); WitnessProgram(string error_message);
UncompressedPubkey(); UnknownHrp();
ExcessiveScriptSize(); LegacyAddressTooLong();
UnrecognizedScript(); InvalidBase58PayloadLength();
NetworkValidation(Network required, Network found, string address); InvalidLegacyPrefix();
OtherAddressErr(); NetworkValidation();
OtherAddressParseErr();
}; };
[Error] [Error]
@ -44,7 +45,7 @@ interface Bip39Error {
[Error] [Error]
interface CalculateFeeError { interface CalculateFeeError {
MissingTxOut(sequence<OutPoint> out_points); MissingTxOut(sequence<OutPoint> out_points);
NegativeFee(i64 fee); NegativeFee(string amount);
}; };
[Error] [Error]
@ -55,7 +56,6 @@ interface CannotConnectError {
[Error] [Error]
interface CreateTxError { interface CreateTxError {
Descriptor(string error_message); Descriptor(string error_message);
Persist(string error_message);
Policy(string error_message); Policy(string error_message);
SpendingPolicyRequired(string kind); SpendingPolicyRequired(string kind);
Version0(); Version0();
@ -63,7 +63,7 @@ interface CreateTxError {
LockTime(string requested, string required); LockTime(string requested, string required);
RbfSequence(); RbfSequence();
RbfSequenceCsv(string rbf, string csv); RbfSequenceCsv(string rbf, string csv);
FeeTooLow(u64 required); FeeTooLow(string required);
FeeRateTooLow(string required); FeeRateTooLow(string required);
NoUtxosSelected(); NoUtxosSelected();
OutputBelowDustLimit(u64 index); OutputBelowDustLimit(u64 index);
@ -92,6 +92,7 @@ interface DescriptorError {
Pk(string error_message); Pk(string error_message);
Miniscript(string error_message); Miniscript(string error_message);
Hex(string error_message); Hex(string error_message);
ExternalAndInternalAreTheSame();
}; };
[Error] [Error]
@ -152,16 +153,21 @@ enum FeeRateError {
"ArithmeticOverflow" "ArithmeticOverflow"
}; };
[Error]
interface FromScriptError {
UnrecognizedScript();
WitnessProgram(string error_message);
WitnessVersion(string error_message);
OtherFromScriptErr();
};
[Error] [Error]
interface ParseAmountError { interface ParseAmountError {
Negative(); OutOfRange();
TooBig();
TooPrecise(); TooPrecise();
InvalidFormat(); MissingDigits();
InputTooLarge(); InputTooLarge();
InvalidCharacter(string error_message); InvalidCharacter(string error_message);
UnknownDenomination(string error_message);
PossiblyConfusingDenomination(string error_message);
OtherParseAmountErr(); OtherParseAmountErr();
}; };
@ -231,7 +237,9 @@ interface SignerError {
MissingHdKeypath(); MissingHdKeypath();
NonStandardSighash(); NonStandardSighash();
InvalidSighash(); InvalidSighash();
SighashError(string error_message); SighashP2wpkh(string error_message);
SighashTaproot(string error_message);
TxInputsIndexError(string error_message);
MiniscriptPsbt(string error_message); MiniscriptPsbt(string error_message);
External(string error_message); External(string error_message);
}; };
@ -260,19 +268,14 @@ interface TxidParseError {
[Error] [Error]
interface WalletCreationError { interface WalletCreationError {
Io(string error_message); Descriptor(string error_message);
InvalidMagicBytes(sequence<u8> got, sequence<u8> expected);
Descriptor();
Persist(string error_message);
NotInitialized();
LoadedGenesisDoesNotMatch(string expected, string got); LoadedGenesisDoesNotMatch(string expected, string got);
LoadedNetworkDoesNotMatch(Network expected, Network? got); LoadedNetworkDoesNotMatch(Network expected, Network? got);
LoadedDescriptorDoesNotMatch(string got, KeychainKind keychain); LoadedDescriptorDoesNotMatch(string got, KeychainKind keychain);
Sqlite(string error_message);
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// bdk crate - types module // bdk_wallet crate - types module
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
enum KeychainKind { enum KeychainKind {
@ -343,8 +346,10 @@ interface FullScanScriptInspector {
void inspect(KeychainKind keychain, u32 index, Script script); void inspect(KeychainKind keychain, u32 index, Script script);
}; };
interface ChangeSet {};
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// bdk crate - wallet module // bdk_wallet crate - wallet module
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
enum ChangeSpendPolicy { enum ChangeSpendPolicy {
@ -355,24 +360,20 @@ enum ChangeSpendPolicy {
interface Wallet { interface Wallet {
[Throws=WalletCreationError] [Throws=WalletCreationError]
constructor(Descriptor descriptor, Descriptor? change_descriptor, string persistence_backend_path, Network network); constructor(Descriptor descriptor, Descriptor change_descriptor, Network network);
[Name=new_no_persist, Throws=DescriptorError] // [Name=new_or_load, Throws=WalletCreationError]
constructor(Descriptor descriptor, Descriptor? change_descriptor, Network network); // constructor(Descriptor descriptor, Descriptor change_descriptor, Network network);
[Throws=PersistenceError]
AddressInfo reveal_next_address(KeychainKind keychain); AddressInfo reveal_next_address(KeychainKind keychain);
Network network(); Network network();
Balance get_balance(); Balance balance();
[Throws=CannotConnectError] [Throws=CannotConnectError]
void apply_update(Update update); void apply_update(Update update);
[Throws=PersistenceError]
boolean commit();
boolean is_mine([ByRef] Script script); boolean is_mine([ByRef] Script script);
[Throws=SignerError] [Throws=SignerError]
@ -386,7 +387,7 @@ interface Wallet {
CanonicalTx? get_tx(string txid); CanonicalTx? get_tx(string txid);
[Throws=CalculateFeeError] [Throws=CalculateFeeError]
u64 calculate_fee([ByRef] Transaction tx); Amount calculate_fee([ByRef] Transaction tx);
[Throws=CalculateFeeError] [Throws=CalculateFeeError]
FeeRate calculate_fee_rate([ByRef] Transaction tx); FeeRate calculate_fee_rate([ByRef] Transaction tx);
@ -398,6 +399,8 @@ interface Wallet {
FullScanRequest start_full_scan(); FullScanRequest start_full_scan();
SyncRequest start_sync_with_revealed_spks(); SyncRequest start_sync_with_revealed_spks();
ChangeSet? take_staged();
}; };
interface Update {}; interface Update {};
@ -450,6 +453,18 @@ interface BumpFeeTxBuilder {
Psbt finish([ByRef] Wallet wallet); Psbt finish([ByRef] Wallet wallet);
}; };
// ------------------------------------------------------------------------
// bdk_sqlite crate
// ------------------------------------------------------------------------
interface SqliteStore {
[Throws=SqliteError]
constructor(string path);
[Throws=SqliteError]
void write([ByRef] ChangeSet change_set);
};
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// bdk crate - descriptor module // bdk crate - descriptor module
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -584,7 +599,7 @@ dictionary SentAndReceivedValues {
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// bdk crate - bitcoin re-exports // bdk_wallet crate - bitcoin re-exports
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
interface Script { interface Script {
@ -611,14 +626,12 @@ enum WordCount {
[Traits=(Display)] [Traits=(Display)]
interface Address { interface Address {
[Throws=AddressError] [Throws=AddressParseError]
constructor(string address, Network network); constructor(string address, Network network);
[Name=from_script, Throws=AddressError] [Name=from_script, Throws=FromScriptError]
constructor(Script script, Network network); constructor(Script script, Network network);
Network network();
Script script_pubkey(); Script script_pubkey();
string to_qr_uri(); string to_qr_uri();
@ -630,7 +643,7 @@ interface Transaction {
[Throws=TransactionError] [Throws=TransactionError]
constructor(sequence<u8> transaction_bytes); constructor(sequence<u8> transaction_bytes);
string txid(); string compute_txid();
u64 total_size(); u64 total_size();

View File

@ -1,5 +1,6 @@
use crate::error::{AddressError, FeeRateError, PsbtError, PsbtParseError, TransactionError}; use crate::error::{
use std::fmt::Display; AddressParseError, FeeRateError, FromScriptError, PsbtError, PsbtParseError, TransactionError,
};
use bdk_bitcoind_rpc::bitcoincore_rpc::jsonrpc::serde_json; use bdk_bitcoind_rpc::bitcoincore_rpc::jsonrpc::serde_json;
use bdk_wallet::bitcoin::address::{NetworkChecked, NetworkUnchecked}; use bdk_wallet::bitcoin::address::{NetworkChecked, NetworkUnchecked};
@ -8,6 +9,7 @@ use bdk_wallet::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
use bdk_wallet::bitcoin::blockdata::transaction::TxOut as BdkTxOut; use bdk_wallet::bitcoin::blockdata::transaction::TxOut as BdkTxOut;
use bdk_wallet::bitcoin::consensus::encode::serialize; use bdk_wallet::bitcoin::consensus::encode::serialize;
use bdk_wallet::bitcoin::consensus::Decodable; use bdk_wallet::bitcoin::consensus::Decodable;
use bdk_wallet::bitcoin::io::Cursor;
use bdk_wallet::bitcoin::psbt::ExtractTxError; use bdk_wallet::bitcoin::psbt::ExtractTxError;
use bdk_wallet::bitcoin::Address as BdkAddress; use bdk_wallet::bitcoin::Address as BdkAddress;
use bdk_wallet::bitcoin::Amount as BdkAmount; use bdk_wallet::bitcoin::Amount as BdkAmount;
@ -19,7 +21,7 @@ use bdk_wallet::bitcoin::Transaction as BdkTransaction;
use bdk_wallet::bitcoin::TxIn as BdkTxIn; use bdk_wallet::bitcoin::TxIn as BdkTxIn;
use bdk_wallet::bitcoin::Txid; use bdk_wallet::bitcoin::Txid;
use std::io::Cursor; use std::fmt::Display;
use std::ops::Deref; use std::ops::Deref;
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -82,23 +84,19 @@ impl From<BdkScriptBuf> for Script {
pub struct Address(BdkAddress<NetworkChecked>); pub struct Address(BdkAddress<NetworkChecked>);
impl Address { impl Address {
pub fn new(address: String, network: Network) -> Result<Self, AddressError> { pub fn new(address: String, network: Network) -> Result<Self, AddressParseError> {
let parsed_address = address.parse::<bdk_wallet::bitcoin::Address<NetworkUnchecked>>()?; let parsed_address = address.parse::<bdk_wallet::bitcoin::Address<NetworkUnchecked>>()?;
let network_checked_address = parsed_address.require_network(network)?; let network_checked_address = parsed_address.require_network(network)?;
Ok(Address(network_checked_address)) Ok(Address(network_checked_address))
} }
pub fn from_script(script: Arc<Script>, network: Network) -> Result<Self, AddressError> { pub fn from_script(script: Arc<Script>, network: Network) -> Result<Self, FromScriptError> {
let address = BdkAddress::from_script(&script.0.clone(), network)?; let address = BdkAddress::from_script(&script.0.clone(), network)?;
Ok(Address(address)) Ok(Address(address))
} }
pub fn network(&self) -> Network {
*self.0.network()
}
pub fn script_pubkey(&self) -> Arc<Script> { pub fn script_pubkey(&self) -> Arc<Script> {
Arc::new(Script(self.0.script_pubkey())) Arc::new(Script(self.0.script_pubkey()))
} }
@ -145,8 +143,8 @@ impl Transaction {
Ok(Transaction(tx)) Ok(Transaction(tx))
} }
pub fn txid(&self) -> String { pub fn compute_txid(&self) -> String {
self.0.txid().to_string() self.0.compute_txid().to_string()
} }
pub fn weight(&self) -> u64 { pub fn weight(&self) -> u64 {
@ -374,11 +372,6 @@ mod tests {
docs_address_testnet.is_valid_for_network(Network::Regtest), docs_address_testnet.is_valid_for_network(Network::Regtest),
"Address should be valid for Regtest" "Address should be valid for Regtest"
); );
assert_ne!(
docs_address_testnet.network(),
Network::Bitcoin,
"Address should not be parsed as Bitcoin"
);
let docs_address_mainnet_str = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf"; let docs_address_mainnet_str = "32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf";
let docs_address_mainnet = let docs_address_mainnet =
@ -387,21 +380,6 @@ mod tests {
docs_address_mainnet.is_valid_for_network(Network::Bitcoin), docs_address_mainnet.is_valid_for_network(Network::Bitcoin),
"Address should be valid for Bitcoin" "Address should be valid for Bitcoin"
); );
assert_ne!(
docs_address_mainnet.network(),
Network::Testnet,
"Address should not be valid for Testnet"
);
assert_ne!(
docs_address_mainnet.network(),
Network::Signet,
"Address should not be valid for Signet"
);
assert_ne!(
docs_address_mainnet.network(),
Network::Regtest,
"Address should not be valid for Regtest"
);
// ====Bech32==== // ====Bech32====

View File

@ -3,8 +3,8 @@ use crate::error::ElectrumError;
use crate::types::{FullScanRequest, SyncRequest}; use crate::types::{FullScanRequest, SyncRequest};
use crate::wallet::Update; use crate::wallet::Update;
use bdk_electrum::electrum_client::{Client as BdkBlockingClient, ElectrumApi}; use bdk_electrum::BdkElectrumClient as BdkBdkElectrumClient;
use bdk_electrum::{ElectrumExt, ElectrumFullScanResult, ElectrumSyncResult}; use bdk_electrum::{ElectrumFullScanResult, ElectrumSyncResult};
use bdk_wallet::bitcoin::Transaction as BdkTransaction; use bdk_wallet::bitcoin::Transaction as BdkTransaction;
use bdk_wallet::chain::spk_client::FullScanRequest as BdkFullScanRequest; use bdk_wallet::chain::spk_client::FullScanRequest as BdkFullScanRequest;
use bdk_wallet::chain::spk_client::FullScanResult as BdkFullScanResult; use bdk_wallet::chain::spk_client::FullScanResult as BdkFullScanResult;
@ -16,11 +16,16 @@ use bdk_wallet::KeychainKind;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
pub struct ElectrumClient(BdkBlockingClient); // NOTE: We are keeping our naming convention where the alias of the inner type is the Rust type
// prefixed with `Bdk`. In this case the inner type is `BdkElectrumClient`, so the alias is
// funnily enough named `BdkBdkElectrumClient`.
pub struct ElectrumClient(BdkBdkElectrumClient<bdk_electrum::electrum_client::Client>);
impl ElectrumClient { impl ElectrumClient {
pub fn new(url: String) -> Result<Self, ElectrumError> { pub fn new(url: String) -> Result<Self, ElectrumError> {
let client = BdkBlockingClient::new(url.as_str())?; let inner_client: bdk_electrum::electrum_client::Client =
bdk_electrum::electrum_client::Client::new(url.as_str())?;
let client = BdkBdkElectrumClient::new(inner_client);
Ok(Self(client)) Ok(Self(client))
} }

View File

@ -1,12 +1,12 @@
use crate::bitcoin::OutPoint; use crate::bitcoin::OutPoint;
use crate::Network; use crate::Network;
use bdk_bitcoind_rpc::bitcoincore_rpc::bitcoin::address::ParseError;
use bdk_electrum::electrum_client::Error as BdkElectrumError; use bdk_electrum::electrum_client::Error as BdkElectrumError;
use bdk_esplora::esplora_client::{Error as BdkEsploraError, Error}; use bdk_esplora::esplora_client::{Error as BdkEsploraError, Error};
use bdk_sqlite::rusqlite::Error as BdkRusqliteError;
use bdk_sqlite::Error as BdkSqliteError; use bdk_sqlite::Error as BdkSqliteError;
use bdk_wallet::bitcoin::address::Error as BdkAddressError; use bdk_wallet::bitcoin::address::FromScriptError as BdkFromScriptError;
use bdk_wallet::bitcoin::address::ParseError; use bdk_wallet::bitcoin::address::ParseError as BdkParseError;
use bdk_wallet::bitcoin::amount::ParseAmountError as BdkParseAmountError; use bdk_wallet::bitcoin::amount::ParseAmountError as BdkParseAmountError;
use bdk_wallet::bitcoin::bip32::Error as BdkBip32Error; use bdk_wallet::bitcoin::bip32::Error as BdkBip32Error;
use bdk_wallet::bitcoin::consensus::encode::Error as BdkEncodeError; use bdk_wallet::bitcoin::consensus::encode::Error as BdkEncodeError;
@ -22,7 +22,7 @@ use bdk_wallet::wallet::error::BuildFeeBumpError;
use bdk_wallet::wallet::error::CreateTxError as BdkCreateTxError; use bdk_wallet::wallet::error::CreateTxError as BdkCreateTxError;
use bdk_wallet::wallet::signer::SignerError as BdkSignerError; use bdk_wallet::wallet::signer::SignerError as BdkSignerError;
use bdk_wallet::wallet::tx_builder::AddUtxoError; use bdk_wallet::wallet::tx_builder::AddUtxoError;
use bdk_wallet::wallet::NewOrLoadError; use bdk_wallet::wallet::{NewError, NewOrLoadError};
use bdk_wallet::KeychainKind; use bdk_wallet::KeychainKind;
use bitcoin_internals::hex::display::DisplayHex; use bitcoin_internals::hex::display::DisplayHex;
@ -33,7 +33,7 @@ use std::convert::TryInto;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum AddressError { pub enum AddressParseError {
#[error("base58 address encoding error")] #[error("base58 address encoding error")]
Base58, Base58,
@ -46,25 +46,24 @@ pub enum AddressError {
#[error("witness program error: {error_message}")] #[error("witness program error: {error_message}")]
WitnessProgram { error_message: String }, WitnessProgram { error_message: String },
#[error("an uncompressed pubkey was used where it is not allowed")] #[error("tried to parse an unknown hrp")]
UncompressedPubkey, UnknownHrp,
#[error("script size exceed 520 bytes")] #[error("legacy address base58 string")]
ExcessiveScriptSize, LegacyAddressTooLong,
#[error("script is not p2pkh, p2sh, or witness program")] #[error("legacy address base58 data")]
UnrecognizedScript, InvalidBase58PayloadLength,
#[error("address {address} is not valid on {required}")] #[error("segwit address bech32 string")]
NetworkValidation { InvalidLegacyPrefix,
required: Network,
found: Network,
address: String,
},
// This is required because the bdk::bitcoin::address::Error is non-exhaustive #[error("validation error")]
#[error("other address error")] NetworkValidation,
OtherAddressErr,
// This error is required because the bdk::bitcoin::address::ParseError is non-exhaustive
#[error("other address parse error")]
OtherAddressParseErr,
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -126,8 +125,8 @@ pub enum CalculateFeeError {
#[error("missing transaction output: {out_points:?}")] #[error("missing transaction output: {out_points:?}")]
MissingTxOut { out_points: Vec<OutPoint> }, MissingTxOut { out_points: Vec<OutPoint> },
#[error("negative fee value: {fee}")] #[error("negative fee value: {amount}")]
NegativeFee { fee: i64 }, NegativeFee { amount: String },
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -141,9 +140,6 @@ pub enum CreateTxError {
#[error("descriptor error: {error_message}")] #[error("descriptor error: {error_message}")]
Descriptor { error_message: String }, Descriptor { error_message: String },
#[error("persistence failure: {error_message}")]
Persist { error_message: String },
#[error("policy error: {error_message}")] #[error("policy error: {error_message}")]
Policy { error_message: String }, Policy { error_message: String },
@ -165,8 +161,8 @@ pub enum CreateTxError {
#[error("rbf sequence: {rbf}, csv sequence: {csv}")] #[error("rbf sequence: {rbf}, csv sequence: {csv}")]
RbfSequenceCsv { rbf: String, csv: String }, RbfSequenceCsv { rbf: String, csv: String },
#[error("fee too low: {required} sat required")] #[error("fee too low: required {required}")]
FeeTooLow { required: u64 }, FeeTooLow { required: String },
#[error("fee rate too low: {required}")] #[error("fee rate too low: {required}")]
FeeRateTooLow { required: String }, FeeRateTooLow { required: String },
@ -242,6 +238,9 @@ pub enum DescriptorError {
#[error("hex decoding error: {error_message}")] #[error("hex decoding error: {error_message}")]
Hex { error_message: String }, Hex { error_message: String },
#[error("external and internal descriptors are the same")]
ExternalAndInternalAreTheSame,
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -375,6 +374,22 @@ pub enum FeeRateError {
ArithmeticOverflow, ArithmeticOverflow,
} }
#[derive(Debug, thiserror::Error)]
pub enum FromScriptError {
#[error("script is not a p2pkh, p2sh or witness program")]
UnrecognizedScript,
#[error("witness program error: {error_message}")]
WitnessProgram { error_message: String },
#[error("witness version construction error: {error_message}")]
WitnessVersion { error_message: String },
// This error is required because the bdk::bitcoin::address::FromScriptError is non-exhaustive
#[error("other from script error")]
OtherFromScriptErr,
}
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum InspectError { pub enum InspectError {
#[error("the request has already been consumed")] #[error("the request has already been consumed")]
@ -383,30 +398,21 @@ pub enum InspectError {
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum ParseAmountError { pub enum ParseAmountError {
#[error("amount is negative")] #[error("amount out of range")]
Negative, OutOfRange,
#[error("amount is too large")] #[error("amount has a too high precision")]
TooBig,
#[error("amount is too precise")]
TooPrecise, TooPrecise,
#[error("invalid amount format")] #[error("the input has too few digits")]
InvalidFormat, MissingDigits,
#[error("input is too large")] #[error("the input is too large")]
InputTooLarge, InputTooLarge,
#[error("invalid character: {error_message}")] #[error("invalid character: {error_message}")]
InvalidCharacter { error_message: String }, InvalidCharacter { error_message: String },
#[error("unknown denomination: {error_message}")]
UnknownDenomination { error_message: String },
#[error("possibly confusing denomination: {error_message}")]
PossiblyConfusingDenomination { error_message: String },
// Has to handle non-exhaustive // Has to handle non-exhaustive
#[error("unknown parse amount error")] #[error("unknown parse amount error")]
OtherParseAmountErr, OtherParseAmountErr,
@ -566,8 +572,14 @@ pub enum SignerError {
#[error("invalid sighash type provided")] #[error("invalid sighash type provided")]
InvalidSighash, InvalidSighash,
#[error("error with sighash computation: {error_message}")] #[error("error while computing the hash to sign a P2WPKH input: {error_message}")]
SighashError { error_message: String }, SighashP2wpkh { error_message: String },
#[error("error while computing the hash to sign a taproot input: {error_message}")]
SighashTaproot { error_message: String },
#[error("Error while computing the hash, out of bounds access on the transaction inputs: {error_message}")]
TxInputsIndexError { error_message: String },
#[error("miniscript psbt error: {error_message}")] #[error("miniscript psbt error: {error_message}")]
MiniscriptPsbt { error_message: String }, MiniscriptPsbt { error_message: String },
@ -578,8 +590,8 @@ pub enum SignerError {
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum SqliteError { pub enum SqliteError {
// This error is renamed from Network to InvalidNetwork to avoid conflict with the Network enum // NOTE: This error is renamed from Network to InvalidNetwork to avoid conflict with the Network
// in uniffi. // enum in uniffi.
#[error("invalid network, cannot change the one already stored in the database")] #[error("invalid network, cannot change the one already stored in the database")]
InvalidNetwork { expected: Network, given: Network }, InvalidNetwork { expected: Network, given: Network },
@ -618,24 +630,14 @@ pub enum TxidParseError {
InvalidTxid { txid: String }, InvalidTxid { txid: String },
} }
// This error combines the Rust bdk::wallet::NewOrLoadError and bdk_wallet::rusqlite::Error // This error combines the Rust bdk_wallet::wallet::NewError and bdk_wallet::wallet::NewOrLoadError
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum WalletCreationError { pub enum WalletCreationError {
#[error("io error trying to read file: {error_message}")] // From NewError and NewOrLoadError
Io { error_message: String }, #[error("error with descriptor: {error_message}")]
Descriptor { error_message: String },
#[error("file has invalid magic bytes: expected={expected:?} got={got:?}")]
InvalidMagicBytes { got: Vec<u8>, expected: Vec<u8> },
#[error("error with descriptor")]
Descriptor,
#[error("failed to either write to or load from persistence, {error_message}")]
Persist { error_message: String },
#[error("wallet is not initialized, persistence backend is empty")]
NotInitialized,
// From NewOrLoadError
#[error("loaded genesis hash '{got}' does not match the expected one '{expected}'")] #[error("loaded genesis hash '{got}' does not match the expected one '{expected}'")]
LoadedGenesisDoesNotMatch { expected: String, got: String }, LoadedGenesisDoesNotMatch { expected: String, got: String },
@ -647,41 +649,12 @@ pub enum WalletCreationError {
#[error("loaded descriptor '{got}' does not match what was provided '{keychain:?}'")] #[error("loaded descriptor '{got}' does not match what was provided '{keychain:?}'")]
LoadedDescriptorDoesNotMatch { got: String, keychain: KeychainKind }, LoadedDescriptorDoesNotMatch { got: String, keychain: KeychainKind },
#[error("error with sqlite persistence: {error_message}")]
Sqlite { error_message: String },
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// error conversions // error conversions
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl From<BdkAddressError> for AddressError {
fn from(error: BdkAddressError) -> Self {
match error {
BdkAddressError::WitnessVersion(error_message) => AddressError::WitnessVersion {
error_message: error_message.to_string(),
},
BdkAddressError::WitnessProgram(e) => AddressError::WitnessProgram {
error_message: e.to_string(),
},
BdkAddressError::UncompressedPubkey => AddressError::UncompressedPubkey,
BdkAddressError::ExcessiveScriptSize => AddressError::ExcessiveScriptSize,
BdkAddressError::UnrecognizedScript => AddressError::UnrecognizedScript,
BdkAddressError::NetworkValidation {
required,
found,
address,
} => AddressError::NetworkValidation {
required,
found,
address: format!("{:?}", address),
},
_ => AddressError::OtherAddressErr,
}
}
}
impl From<BdkElectrumError> for ElectrumError { impl From<BdkElectrumError> for ElectrumError {
fn from(error: BdkElectrumError) -> Self { fn from(error: BdkElectrumError) -> Self {
match error { match error {
@ -727,18 +700,25 @@ impl From<BdkElectrumError> for ElectrumError {
} }
} }
impl From<ParseError> for AddressError { impl From<BdkParseError> for AddressParseError {
fn from(error: ParseError) -> Self { fn from(error: BdkParseError) -> Self {
match error { match error {
ParseError::Base58(_) => AddressError::Base58, BdkParseError::Base58(_) => AddressParseError::Base58,
ParseError::Bech32(_) => AddressError::Bech32, BdkParseError::Bech32(_) => AddressParseError::Bech32,
ParseError::WitnessVersion(e) => AddressError::WitnessVersion { BdkParseError::WitnessVersion(e) => AddressParseError::WitnessVersion {
error_message: e.to_string(), error_message: e.to_string(),
}, },
ParseError::WitnessProgram(e) => AddressError::WitnessProgram { BdkParseError::WitnessProgram(e) => AddressParseError::WitnessProgram {
error_message: e.to_string(), error_message: e.to_string(),
}, },
_ => AddressError::OtherAddressErr, ParseError::UnknownHrp(_) => AddressParseError::UnknownHrp,
ParseError::LegacyAddressTooLong(_) => AddressParseError::LegacyAddressTooLong,
ParseError::InvalidBase58PayloadLength(_) => {
AddressParseError::InvalidBase58PayloadLength
}
ParseError::InvalidLegacyPrefix(_) => AddressParseError::InvalidLegacyPrefix,
ParseError::NetworkValidation(_) => AddressParseError::NetworkValidation,
_ => AddressParseError::OtherAddressParseErr,
} }
} }
} }
@ -803,7 +783,9 @@ impl From<BdkCalculateFeeError> for CalculateFeeError {
BdkCalculateFeeError::MissingTxOut(out_points) => CalculateFeeError::MissingTxOut { BdkCalculateFeeError::MissingTxOut(out_points) => CalculateFeeError::MissingTxOut {
out_points: out_points.iter().map(|op| op.into()).collect(), out_points: out_points.iter().map(|op| op.into()).collect(),
}, },
BdkCalculateFeeError::NegativeFee(fee) => CalculateFeeError::NegativeFee { fee }, BdkCalculateFeeError::NegativeFee(signed_amount) => CalculateFeeError::NegativeFee {
amount: signed_amount.to_string(),
},
} }
} }
} }
@ -822,9 +804,9 @@ impl From<BdkCreateTxError> for CreateTxError {
BdkCreateTxError::Descriptor(e) => CreateTxError::Descriptor { BdkCreateTxError::Descriptor(e) => CreateTxError::Descriptor {
error_message: e.to_string(), error_message: e.to_string(),
}, },
BdkCreateTxError::Persist(e) => CreateTxError::Persist { // BdkCreateTxError::Persist(e) => CreateTxError::Persist {
error_message: e.to_string(), // error_message: e.to_string(),
}, // },
BdkCreateTxError::Policy(e) => CreateTxError::Policy { BdkCreateTxError::Policy(e) => CreateTxError::Policy {
error_message: e.to_string(), error_message: e.to_string(),
}, },
@ -847,7 +829,9 @@ impl From<BdkCreateTxError> for CreateTxError {
rbf: rbf.to_string(), rbf: rbf.to_string(),
csv: csv.to_string(), csv: csv.to_string(),
}, },
BdkCreateTxError::FeeTooLow { required } => CreateTxError::FeeTooLow { required }, BdkCreateTxError::FeeTooLow { required } => CreateTxError::FeeTooLow {
required: required.to_string(),
},
BdkCreateTxError::FeeRateTooLow { required } => CreateTxError::FeeRateTooLow { BdkCreateTxError::FeeRateTooLow { required } => CreateTxError::FeeRateTooLow {
required: required.to_string(), required: required.to_string(),
}, },
@ -855,13 +839,13 @@ impl From<BdkCreateTxError> for CreateTxError {
BdkCreateTxError::OutputBelowDustLimit(index) => CreateTxError::OutputBelowDustLimit { BdkCreateTxError::OutputBelowDustLimit(index) => CreateTxError::OutputBelowDustLimit {
index: index as u64, index: index as u64,
}, },
BdkCreateTxError::ChangePolicyDescriptor => CreateTxError::ChangePolicyDescriptor, // BdkCreateTxError::ChangePolicyDescriptor => CreateTxError::ChangePolicyDescriptor,
BdkCreateTxError::CoinSelection(e) => CreateTxError::CoinSelection { BdkCreateTxError::CoinSelection(e) => CreateTxError::CoinSelection {
error_message: e.to_string(), error_message: e.to_string(),
}, },
BdkCreateTxError::InsufficientFunds { needed, available } => { // BdkCreateTxError::InsufficientFunds { needed, available } => {
CreateTxError::InsufficientFunds { needed, available } // CreateTxError::InsufficientFunds { needed, available }
} // }
BdkCreateTxError::NoRecipients => CreateTxError::NoRecipients, BdkCreateTxError::NoRecipients => CreateTxError::NoRecipients,
BdkCreateTxError::Psbt(e) => CreateTxError::Psbt { BdkCreateTxError::Psbt(e) => CreateTxError::Psbt {
error_message: e.to_string(), error_message: e.to_string(),
@ -949,6 +933,9 @@ impl From<BdkDescriptorError> for DescriptorError {
BdkDescriptorError::Hex(e) => DescriptorError::Hex { BdkDescriptorError::Hex(e) => DescriptorError::Hex {
error_message: e.to_string(), error_message: e.to_string(),
}, },
BdkDescriptorError::ExternalAndInternalAreTheSame => {
DescriptorError::ExternalAndInternalAreTheSame
}
} }
} }
} }
@ -1061,23 +1048,31 @@ impl From<BdkExtractTxError> for ExtractTxError {
} }
} }
impl From<BdkFromScriptError> for FromScriptError {
fn from(error: BdkFromScriptError) -> Self {
match error {
BdkFromScriptError::UnrecognizedScript => FromScriptError::UnrecognizedScript,
BdkFromScriptError::WitnessProgram(e) => FromScriptError::WitnessProgram {
error_message: e.to_string(),
},
BdkFromScriptError::WitnessVersion(e) => FromScriptError::WitnessVersion {
error_message: e.to_string(),
},
_ => FromScriptError::OtherFromScriptErr,
}
}
}
impl From<BdkParseAmountError> for ParseAmountError { impl From<BdkParseAmountError> for ParseAmountError {
fn from(error: BdkParseAmountError) -> Self { fn from(error: BdkParseAmountError) -> Self {
match error { match error {
BdkParseAmountError::Negative => ParseAmountError::Negative, BdkParseAmountError::OutOfRange(_) => ParseAmountError::OutOfRange,
BdkParseAmountError::TooBig => ParseAmountError::TooBig, BdkParseAmountError::TooPrecise(_) => ParseAmountError::TooPrecise,
BdkParseAmountError::InvalidFormat => ParseAmountError::InvalidFormat, BdkParseAmountError::MissingDigits(_) => ParseAmountError::MissingDigits,
BdkParseAmountError::TooPrecise => ParseAmountError::TooPrecise, BdkParseAmountError::InputTooLarge(_) => ParseAmountError::InputTooLarge,
BdkParseAmountError::InputTooLarge => ParseAmountError::InputTooLarge,
BdkParseAmountError::InvalidCharacter(c) => ParseAmountError::InvalidCharacter { BdkParseAmountError::InvalidCharacter(c) => ParseAmountError::InvalidCharacter {
error_message: c.to_string(), error_message: c.to_string(),
}, },
BdkParseAmountError::UnknownDenomination(s) => {
ParseAmountError::UnknownDenomination { error_message: s }
}
BdkParseAmountError::PossiblyConfusingDenomination(s) => {
ParseAmountError::PossiblyConfusingDenomination { error_message: s }
}
_ => ParseAmountError::OtherParseAmountErr, _ => ParseAmountError::OtherParseAmountErr,
} }
} }
@ -1189,11 +1184,17 @@ impl From<BdkSignerError> for SignerError {
BdkSignerError::MissingHdKeypath => SignerError::MissingHdKeypath, BdkSignerError::MissingHdKeypath => SignerError::MissingHdKeypath,
BdkSignerError::NonStandardSighash => SignerError::NonStandardSighash, BdkSignerError::NonStandardSighash => SignerError::NonStandardSighash,
BdkSignerError::InvalidSighash => SignerError::InvalidSighash, BdkSignerError::InvalidSighash => SignerError::InvalidSighash,
BdkSignerError::SighashError(e) => SignerError::SighashError { BdkSignerError::SighashP2wpkh(e) => SignerError::SighashP2wpkh {
error_message: e.to_string(),
},
BdkSignerError::SighashTaproot(e) => SignerError::SighashTaproot {
error_message: e.to_string(),
},
BdkSignerError::TxInputsIndexError(e) => SignerError::TxInputsIndexError {
error_message: e.to_string(), error_message: e.to_string(),
}, },
BdkSignerError::MiniscriptPsbt(e) => SignerError::MiniscriptPsbt { BdkSignerError::MiniscriptPsbt(e) => SignerError::MiniscriptPsbt {
error_message: format!("{:?}", e), error_message: e.to_string(),
}, },
BdkSignerError::External(e) => SignerError::External { error_message: e }, BdkSignerError::External(e) => SignerError::External { error_message: e },
} }
@ -1223,14 +1224,6 @@ impl From<BdkEncodeError> for TransactionError {
} }
} }
impl From<BdkRusqliteError> for WalletCreationError {
fn from(error: BdkRusqliteError) -> Self {
WalletCreationError::Sqlite {
error_message: error.to_string(),
}
}
}
impl From<BdkSqliteError> for SqliteError { impl From<BdkSqliteError> for SqliteError {
fn from(error: BdkSqliteError) -> Self { fn from(error: BdkSqliteError) -> Self {
match error { match error {
@ -1244,14 +1237,28 @@ impl From<BdkSqliteError> for SqliteError {
} }
} }
impl From<bdk_sqlite::rusqlite::Error> for SqliteError {
fn from(error: bdk_sqlite::rusqlite::Error) -> Self {
SqliteError::Sqlite {
rusqlite_error: error.to_string(),
}
}
}
impl From<NewError> for WalletCreationError {
fn from(error: NewError) -> Self {
WalletCreationError::Descriptor {
error_message: error.to_string(),
}
}
}
impl From<NewOrLoadError> for WalletCreationError { impl From<NewOrLoadError> for WalletCreationError {
fn from(error: NewOrLoadError) -> Self { fn from(error: NewOrLoadError) -> Self {
match error { match error {
NewOrLoadError::Descriptor(_) => WalletCreationError::Descriptor, NewOrLoadError::Descriptor(e) => WalletCreationError::Descriptor {
NewOrLoadError::Persist(e) => WalletCreationError::Persist {
error_message: e.to_string(), error_message: e.to_string(),
}, },
NewOrLoadError::NotInitialized => WalletCreationError::NotInitialized,
NewOrLoadError::LoadedGenesisDoesNotMatch { expected, got } => { NewOrLoadError::LoadedGenesisDoesNotMatch { expected, got } => {
WalletCreationError::LoadedGenesisDoesNotMatch { WalletCreationError::LoadedGenesisDoesNotMatch {
expected: expected.to_string(), expected: expected.to_string(),
@ -1278,61 +1285,11 @@ impl From<NewOrLoadError> for WalletCreationError {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::error::{ use crate::error::{
AddressError, Bip32Error, Bip39Error, CannotConnectError, CreateTxError, DescriptorError, Bip32Error, Bip39Error, CannotConnectError, DescriptorError, DescriptorKeyError,
DescriptorKeyError, ElectrumError, EsploraError, ExtractTxError, FeeRateError, ElectrumError, EsploraError, ExtractTxError, FeeRateError, InspectError, PersistenceError,
InspectError, ParseAmountError, PersistenceError, PsbtError, PsbtParseError, PsbtError, PsbtParseError, TransactionError, TxidParseError,
TransactionError, TxidParseError, WalletCreationError,
}; };
use crate::CalculateFeeError;
use crate::OutPoint;
use crate::SignerError; use crate::SignerError;
use bdk_wallet::bitcoin::Network;
use bdk_wallet::KeychainKind;
#[test]
fn test_error_address() {
let cases = vec![
(AddressError::Base58, "base58 address encoding error"),
(AddressError::Bech32, "bech32 address encoding error"),
(
AddressError::WitnessVersion {
error_message: "version error".to_string(),
},
"witness version conversion/parsing error: version error",
),
(
AddressError::WitnessProgram {
error_message: "program error".to_string(),
},
"witness program error: program error",
),
(
AddressError::UncompressedPubkey,
"an uncompressed pubkey was used where it is not allowed",
),
(
AddressError::ExcessiveScriptSize,
"script size exceed 520 bytes",
),
(
AddressError::UnrecognizedScript,
"script is not p2pkh, p2sh, or witness program",
),
(
AddressError::NetworkValidation {
required: Network::Bitcoin,
found: Network::Testnet,
address: "1BitcoinEaterAddressDontSendf59kuE".to_string(),
},
"address 1BitcoinEaterAddressDontSendf59kuE is not valid on bitcoin",
),
(AddressError::OtherAddressErr, "other address error"),
];
for (error, expected_message) in cases {
assert_eq!(error.to_string(), expected_message);
}
}
#[test] #[test]
fn test_error_bip32() { fn test_error_bip32() {
@ -1427,42 +1384,6 @@ mod test {
} }
} }
#[test]
fn test_error_calculate_fee() {
let out_points: Vec<OutPoint> = vec![
OutPoint {
txid: "0000000000000000000000000000000000000000000000000000000000000001"
.to_string(),
vout: 0,
},
OutPoint {
txid: "0000000000000000000000000000000000000000000000000000000000000002"
.to_string(),
vout: 1,
},
];
let cases = vec![
(
CalculateFeeError::MissingTxOut {
out_points: out_points.clone(),
},
format!(
"missing transaction output: [{:?}, {:?}]",
out_points[0], out_points[1]
),
),
(
CalculateFeeError::NegativeFee { fee: -100 },
"negative fee value: -100".to_string(),
),
];
for (error, expected_message) in cases {
assert_eq!(error.to_string(), expected_message);
}
}
#[test] #[test]
fn test_error_cannot_connect() { fn test_error_cannot_connect() {
let error = CannotConnectError::Include { height: 42 }; let error = CannotConnectError::Include { height: 42 };
@ -1470,126 +1391,6 @@ mod test {
assert_eq!(format!("{}", error), "cannot include height: 42"); assert_eq!(format!("{}", error), "cannot include height: 42");
} }
#[test]
fn test_error_create_tx() {
let cases = vec![
(
CreateTxError::Descriptor {
error_message: "Descriptor failure".to_string(),
},
"descriptor error: Descriptor failure",
),
(
CreateTxError::Persist {
error_message: "Persistence error".to_string(),
},
"persistence failure: Persistence error",
),
(
CreateTxError::Policy {
error_message: "Policy violation".to_string(),
},
"policy error: Policy violation",
),
(
CreateTxError::SpendingPolicyRequired {
kind: "multisig".to_string(),
},
"spending policy required for multisig",
),
(CreateTxError::Version0, "unsupported version 0"),
(CreateTxError::Version1Csv, "unsupported version 1 with csv"),
(
CreateTxError::LockTime {
requested: "today".to_string(),
required: "tomorrow".to_string(),
},
"lock time conflict: requested today, but required tomorrow",
),
(
CreateTxError::RbfSequence,
"transaction requires rbf sequence number",
),
(
CreateTxError::RbfSequenceCsv {
rbf: "123".to_string(),
csv: "456".to_string(),
},
"rbf sequence: 123, csv sequence: 456",
),
(
CreateTxError::FeeTooLow { required: 1000 },
"fee too low: 1000 sat required",
),
(
CreateTxError::FeeRateTooLow {
required: "5 sat/vB".to_string(),
},
"fee rate too low: 5 sat/vB",
),
(
CreateTxError::NoUtxosSelected,
"no utxos selected for the transaction",
),
(
CreateTxError::OutputBelowDustLimit { index: 2 },
"output value below dust limit at index 2",
),
(
CreateTxError::ChangePolicyDescriptor,
"change policy descriptor error",
),
(
CreateTxError::CoinSelection {
error_message: "No suitable outputs".to_string(),
},
"coin selection failed: No suitable outputs",
),
(
CreateTxError::InsufficientFunds {
needed: 5000,
available: 3000,
},
"insufficient funds: needed 5000 sat, available 3000 sat",
),
(CreateTxError::NoRecipients, "transaction has no recipients"),
(
CreateTxError::Psbt {
error_message: "PSBT creation failed".to_string(),
},
"psbt creation error: PSBT creation failed",
),
(
CreateTxError::MissingKeyOrigin {
key: "xpub...".to_string(),
},
"missing key origin for: xpub...",
),
(
CreateTxError::UnknownUtxo {
outpoint: "outpoint123".to_string(),
},
"reference to an unknown utxo: outpoint123",
),
(
CreateTxError::MissingNonWitnessUtxo {
outpoint: "outpoint456".to_string(),
},
"missing non-witness utxo for outpoint: outpoint456",
),
(
CreateTxError::MiniscriptPsbt {
error_message: "Miniscript error".to_string(),
},
"miniscript psbt error: Miniscript error",
),
];
for (error, expected_message) in cases {
assert_eq!(error.to_string(), expected_message);
}
}
#[test] #[test]
fn test_error_descriptor() { fn test_error_descriptor() {
let cases = vec![ let cases = vec![
@ -1883,43 +1684,6 @@ mod test {
} }
} }
#[test]
fn test_error_parse_amount() {
let cases = vec![
(ParseAmountError::Negative, "amount is negative"),
(ParseAmountError::TooBig, "amount is too large"),
(ParseAmountError::TooPrecise, "amount is too precise"),
(ParseAmountError::InvalidFormat, "invalid amount format"),
(ParseAmountError::InputTooLarge, "input is too large"),
(
ParseAmountError::InvalidCharacter {
error_message: "invalid char".to_string(),
},
"invalid character: invalid char",
),
(
ParseAmountError::UnknownDenomination {
error_message: "unknown denom".to_string(),
},
"unknown denomination: unknown denom",
),
(
ParseAmountError::PossiblyConfusingDenomination {
error_message: "confusing denom".to_string(),
},
"possibly confusing denomination: confusing denom",
),
(
ParseAmountError::OtherParseAmountErr,
"unknown parse amount error",
),
];
for (error, expected_message) in cases {
assert_eq!(error.to_string(), expected_message);
}
}
#[test] #[test]
fn test_persistence_error() { fn test_persistence_error() {
let cases = vec![ let cases = vec![
@ -2134,12 +1898,6 @@ mod test {
"non-standard sighash type used", "non-standard sighash type used",
), ),
(SignerError::InvalidSighash, "invalid sighash type provided"), (SignerError::InvalidSighash, "invalid sighash type provided"),
(
SignerError::SighashError {
error_message: "dummy error".into(),
},
"error with sighash computation: dummy error",
),
( (
SignerError::MiniscriptPsbt { SignerError::MiniscriptPsbt {
error_message: "psbt issue".into(), error_message: "psbt issue".into(),
@ -2204,62 +1962,4 @@ mod test {
assert_eq!(error.to_string(), expected_message); assert_eq!(error.to_string(), expected_message);
} }
} }
#[test]
fn test_error_wallet_creation() {
let errors = vec![
(
WalletCreationError::Io {
error_message: "io error".to_string(),
},
"io error trying to read file: io error".to_string(),
),
(
WalletCreationError::InvalidMagicBytes {
got: vec![1, 2, 3, 4],
expected: vec![4, 3, 2, 1],
},
"file has invalid magic bytes: expected=[4, 3, 2, 1] got=[1, 2, 3, 4]".to_string(),
),
(
WalletCreationError::Descriptor,
"error with descriptor".to_string(),
),
(
WalletCreationError::Persist {
error_message: "persistence error".to_string(),
},
"failed to either write to or load from persistence, persistence error".to_string(),
),
(
WalletCreationError::NotInitialized,
"wallet is not initialized, persistence backend is empty".to_string(),
),
(
WalletCreationError::LoadedGenesisDoesNotMatch {
expected: "abc".to_string(),
got: "def".to_string(),
},
"loaded genesis hash 'def' does not match the expected one 'abc'".to_string(),
),
(
WalletCreationError::LoadedNetworkDoesNotMatch {
expected: Network::Bitcoin,
got: Some(Network::Testnet),
},
"loaded network type is not bitcoin, got Some(Testnet)".to_string(),
),
(
WalletCreationError::LoadedDescriptorDoesNotMatch {
got: "def".to_string(),
keychain: KeychainKind::External,
},
"loaded descriptor 'def' does not match what was provided 'External'".to_string(),
),
];
for (error, expected) in errors {
assert_eq!(error.to_string(), expected);
}
}
} }

View File

@ -4,6 +4,7 @@ mod electrum;
mod error; mod error;
mod esplora; mod esplora;
mod keys; mod keys;
mod store;
mod types; mod types;
mod wallet; mod wallet;
@ -18,7 +19,7 @@ use crate::bitcoin::TxIn;
use crate::bitcoin::TxOut; use crate::bitcoin::TxOut;
use crate::descriptor::Descriptor; use crate::descriptor::Descriptor;
use crate::electrum::ElectrumClient; use crate::electrum::ElectrumClient;
use crate::error::AddressError; use crate::error::AddressParseError;
use crate::error::Bip32Error; use crate::error::Bip32Error;
use crate::error::Bip39Error; use crate::error::Bip39Error;
use crate::error::CalculateFeeError; use crate::error::CalculateFeeError;
@ -30,6 +31,7 @@ use crate::error::ElectrumError;
use crate::error::EsploraError; use crate::error::EsploraError;
use crate::error::ExtractTxError; use crate::error::ExtractTxError;
use crate::error::FeeRateError; use crate::error::FeeRateError;
use crate::error::FromScriptError;
use crate::error::InspectError; use crate::error::InspectError;
use crate::error::ParseAmountError; use crate::error::ParseAmountError;
use crate::error::PersistenceError; use crate::error::PersistenceError;
@ -45,10 +47,12 @@ use crate::keys::DerivationPath;
use crate::keys::DescriptorPublicKey; use crate::keys::DescriptorPublicKey;
use crate::keys::DescriptorSecretKey; use crate::keys::DescriptorSecretKey;
use crate::keys::Mnemonic; use crate::keys::Mnemonic;
use crate::store::SqliteStore;
use crate::types::AddressInfo; use crate::types::AddressInfo;
use crate::types::Balance; use crate::types::Balance;
use crate::types::CanonicalTx; use crate::types::CanonicalTx;
use crate::types::ChainPosition; use crate::types::ChainPosition;
use crate::types::ChangeSet;
use crate::types::FullScanRequest; use crate::types::FullScanRequest;
use crate::types::FullScanScriptInspector; use crate::types::FullScanScriptInspector;
use crate::types::LocalOutput; use crate::types::LocalOutput;

39
bdk-ffi/src/store.rs Normal file
View File

@ -0,0 +1,39 @@
use crate::error::SqliteError;
use crate::types::ChangeSet;
use bdk_sqlite::rusqlite::Connection;
use bdk_sqlite::{Store as BdkSqliteStore, Store};
use bdk_wallet::chain::ConfirmationTimeHeightAnchor;
use bdk_wallet::KeychainKind;
use std::sync::{Mutex, MutexGuard};
pub struct SqliteStore {
inner_mutex: Mutex<BdkSqliteStore<KeychainKind, ConfirmationTimeHeightAnchor>>,
}
impl SqliteStore {
pub fn new(path: String) -> Result<Self, SqliteError> {
let connection = Connection::open(path)?;
let db = Store::new(connection)?;
Ok(Self {
inner_mutex: Mutex::new(db),
})
}
pub(crate) fn get_store(
&self,
) -> MutexGuard<BdkSqliteStore<KeychainKind, ConfirmationTimeHeightAnchor>> {
self.inner_mutex.lock().expect("sqlite store")
}
// pub fn read(&self) -> Result<Option<CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>, Error> {
// self.0.read().map_err(SqliteError::from)
// }
pub fn write(&self, changeset: &ChangeSet) -> Result<(), SqliteError> {
self.get_store()
.write(&changeset.0)
.map_err(SqliteError::from)
}
}

View File

@ -13,6 +13,7 @@ use bdk_wallet::wallet::Balance as BdkBalance;
use bdk_wallet::KeychainKind; use bdk_wallet::KeychainKind;
use bdk_wallet::LocalOutput as BdkLocalOutput; use bdk_wallet::LocalOutput as BdkLocalOutput;
use bdk_electrum::bdk_chain::CombinedChangeSet;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -86,6 +87,14 @@ impl From<BdkBalance> for Balance {
} }
} }
pub struct ChangeSet(pub(crate) CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>);
impl From<CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>> for ChangeSet {
fn from(change_set: CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>) -> Self {
ChangeSet(change_set)
}
}
pub struct LocalOutput { pub struct LocalOutput {
pub outpoint: OutPoint, pub outpoint: OutPoint,
pub txout: TxOut, pub txout: TxOut,

View File

@ -2,20 +2,20 @@ use crate::bitcoin::Amount;
use crate::bitcoin::{FeeRate, OutPoint, Psbt, Script, Transaction}; use crate::bitcoin::{FeeRate, OutPoint, Psbt, Script, Transaction};
use crate::descriptor::Descriptor; use crate::descriptor::Descriptor;
use crate::error::{ use crate::error::{
CalculateFeeError, CannotConnectError, CreateTxError, DescriptorError, PersistenceError, CalculateFeeError, CannotConnectError, CreateTxError, SignerError, TxidParseError,
SignerError, TxidParseError, WalletCreationError, WalletCreationError,
}; };
use crate::types::{ use crate::types::{
AddressInfo, Balance, CanonicalTx, FullScanRequest, LocalOutput, ScriptAmount, SyncRequest, AddressInfo, Balance, CanonicalTx, ChangeSet, FullScanRequest, LocalOutput, ScriptAmount,
SyncRequest,
}; };
use bdk_sqlite::rusqlite::Connection;
use bdk_sqlite::Store;
use bdk_wallet::bitcoin::amount::Amount as BdkAmount; use bdk_wallet::bitcoin::amount::Amount as BdkAmount;
use bdk_wallet::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf; use bdk_wallet::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
use bdk_wallet::bitcoin::Network; use bdk_wallet::bitcoin::Network;
use bdk_wallet::bitcoin::Psbt as BdkPsbt; use bdk_wallet::bitcoin::Psbt as BdkPsbt;
use bdk_wallet::bitcoin::{OutPoint as BdkOutPoint, Sequence, Txid}; use bdk_wallet::bitcoin::{OutPoint as BdkOutPoint, Sequence, Txid};
// use bdk_wallet::chain::{CombinedChangeSet, ConfirmationTimeHeightAnchor};
use bdk_wallet::wallet::tx_builder::ChangeSpendPolicy; use bdk_wallet::wallet::tx_builder::ChangeSpendPolicy;
use bdk_wallet::wallet::Update as BdkUpdate; use bdk_wallet::wallet::Update as BdkUpdate;
use bdk_wallet::Wallet as BdkWallet; use bdk_wallet::Wallet as BdkWallet;
@ -32,53 +32,37 @@ pub struct Wallet {
impl Wallet { impl Wallet {
pub fn new( pub fn new(
descriptor: Arc<Descriptor>, descriptor: Arc<Descriptor>,
change_descriptor: Option<Arc<Descriptor>>, change_descriptor: Arc<Descriptor>,
persistence_backend_path: String,
network: Network, network: Network,
) -> Result<Self, WalletCreationError> { ) -> Result<Self, WalletCreationError> {
let descriptor = descriptor.to_string_with_secret(); let descriptor = descriptor.to_string_with_secret();
let change_descriptor = change_descriptor.map(|d| d.to_string_with_secret()); let change_descriptor = change_descriptor.to_string_with_secret();
let connection = Connection::open(persistence_backend_path)?; let wallet: BdkWallet = BdkWallet::new(&descriptor, &change_descriptor, network)?;
let db = Store::new(connection)?;
let wallet: BdkWallet =
BdkWallet::new_or_load(&descriptor, change_descriptor.as_ref(), db, network)?;
Ok(Wallet { Ok(Wallet {
inner_mutex: Mutex::new(wallet), inner_mutex: Mutex::new(wallet),
}) })
} }
pub fn new_no_persist( // pub fn new_or_load(
descriptor: Arc<Descriptor>, // descriptor: Arc<Descriptor>,
change_descriptor: Option<Arc<Descriptor>>, // change_descriptor: Option<Arc<Descriptor>>,
network: Network, // change_set: Option<CombinedChangeSet<KeychainKind, ConfirmationTimeHeightAnchor>>,
) -> Result<Self, DescriptorError> { // network: Network,
let descriptor = descriptor.to_string_with_secret(); // ) -> Result<Self, WalletCreationError> {
let change_descriptor = change_descriptor.map(|d| d.to_string_with_secret()); // let descriptor = descriptor.to_string_with_secret();
// let change_descriptor = change_descriptor.to_string_with_secret();
let wallet: BdkWallet = // let wallet: BdkWallet = BdkWallet::new_or_load(&descriptor, &change_descriptor, network)?;
BdkWallet::new_no_persist(&descriptor, change_descriptor.as_ref(), network)?; //
// Ok(Wallet { inner_mutex: Mutex::new(wallet) })
Ok(Wallet { // }
inner_mutex: Mutex::new(wallet),
})
}
pub(crate) fn get_wallet(&self) -> MutexGuard<BdkWallet> { pub(crate) fn get_wallet(&self) -> MutexGuard<BdkWallet> {
self.inner_mutex.lock().expect("wallet") self.inner_mutex.lock().expect("wallet")
} }
pub fn reveal_next_address( pub fn reveal_next_address(&self, keychain_kind: KeychainKind) -> AddressInfo {
&self, self.get_wallet().reveal_next_address(keychain_kind).into()
keychain_kind: KeychainKind,
) -> Result<AddressInfo, PersistenceError> {
self.get_wallet()
.reveal_next_address(keychain_kind)
.map(|address_info| address_info.into())
.map_err(|e| PersistenceError::Write {
error_message: e.to_string(),
})
} }
pub fn apply_update(&self, update: Arc<Update>) -> Result<(), CannotConnectError> { pub fn apply_update(&self, update: Arc<Update>) -> Result<(), CannotConnectError> {
@ -87,20 +71,12 @@ impl Wallet {
.map_err(CannotConnectError::from) .map_err(CannotConnectError::from)
} }
pub fn commit(&self) -> Result<bool, PersistenceError> {
self.get_wallet()
.commit()
.map_err(|e| PersistenceError::Write {
error_message: e.to_string(),
})
}
pub fn network(&self) -> Network { pub fn network(&self) -> Network {
self.get_wallet().network() self.get_wallet().network()
} }
pub fn get_balance(&self) -> Balance { pub fn balance(&self) -> Balance {
let bdk_balance = self.get_wallet().get_balance(); let bdk_balance = self.get_wallet().balance();
Balance::from(bdk_balance) Balance::from(bdk_balance)
} }
@ -140,9 +116,11 @@ impl Wallet {
Ok(self.get_wallet().get_tx(txid).map(|tx| tx.into())) Ok(self.get_wallet().get_tx(txid).map(|tx| tx.into()))
} }
pub fn calculate_fee(&self, tx: &Transaction) -> Result<u64, CalculateFeeError> { pub fn calculate_fee(&self, tx: &Transaction) -> Result<Arc<Amount>, CalculateFeeError> {
self.get_wallet() self.get_wallet()
.calculate_fee(&tx.into()) .calculate_fee(&tx.into())
.map(Amount::from)
.map(Arc::new)
.map_err(|e| e.into()) .map_err(|e| e.into())
} }
@ -170,6 +148,12 @@ impl Wallet {
let request = self.get_wallet().start_sync_with_revealed_spks(); let request = self.get_wallet().start_sync_with_revealed_spks();
Arc::new(SyncRequest(Mutex::new(Some(request)))) Arc::new(SyncRequest(Mutex::new(Some(request))))
} }
pub fn take_staged(&self) -> Option<Arc<ChangeSet>> {
self.get_wallet()
.take_staged()
.map(|change_set| Arc::new(change_set.into()))
}
} }
pub struct SentAndReceivedValues { pub struct SentAndReceivedValues {