Compare commits
19 Commits
v0.12.0
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6f736609f | ||
|
|
5cb0726780 | ||
|
|
8781599740 | ||
|
|
ee8b992f8b | ||
|
|
a2e26f1b57 | ||
|
|
5f5744e897 | ||
|
|
e106136227 | ||
|
|
b638039655 | ||
|
|
7e085a86dd | ||
|
|
59f795f176 | ||
|
|
2da10382e7 | ||
|
|
6d18502733 | ||
|
|
81b263f235 | ||
|
|
2f38d3e526 | ||
|
|
2ee125655b | ||
|
|
22c39b7b78 | ||
|
|
18f1107c41 | ||
|
|
763bcc22ab | ||
|
|
8c21bcf40a |
4
.github/workflows/cont_integration.yml
vendored
4
.github/workflows/cont_integration.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
rust:
|
rust:
|
||||||
- 1.53.0 # STABLE
|
- 1.56.0 # STABLE
|
||||||
- 1.46.0 # MSRV
|
- 1.46.0 # MSRV
|
||||||
features:
|
features:
|
||||||
- default
|
- default
|
||||||
@@ -135,7 +135,7 @@ jobs:
|
|||||||
- run: sudo apt-get update || exit 1
|
- run: sudo apt-get update || exit 1
|
||||||
- run: sudo apt-get install -y libclang-common-10-dev clang-10 libc6-dev-i386 || exit 1
|
- run: sudo apt-get install -y libclang-common-10-dev clang-10 libc6-dev-i386 || exit 1
|
||||||
- name: Set default toolchain
|
- name: Set default toolchain
|
||||||
run: rustup default 1.53.0 # STABLE
|
run: rustup default 1.56.0 # STABLE
|
||||||
- name: Set profile
|
- name: Set profile
|
||||||
run: rustup set profile minimal
|
run: rustup set profile minimal
|
||||||
- name: Add target wasm32
|
- name: Add target wasm32
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [v0.13.0] - [v0.12.0]
|
||||||
|
|
||||||
|
- Exposed `get_tx()` method from `Database` to `Wallet`.
|
||||||
|
|
||||||
## [v0.12.0] - [v0.11.0]
|
## [v0.12.0] - [v0.11.0]
|
||||||
|
|
||||||
@@ -384,4 +387,5 @@ final transaction is created by calling `finish` on the builder.
|
|||||||
[v0.9.0]: https://github.com/bitcoindevkit/bdk/compare/v0.8.0...v0.9.0
|
[v0.9.0]: https://github.com/bitcoindevkit/bdk/compare/v0.8.0...v0.9.0
|
||||||
[v0.10.0]: https://github.com/bitcoindevkit/bdk/compare/v0.9.0...v0.10.0
|
[v0.10.0]: https://github.com/bitcoindevkit/bdk/compare/v0.9.0...v0.10.0
|
||||||
[v0.11.0]: https://github.com/bitcoindevkit/bdk/compare/v0.10.0...v0.11.0
|
[v0.11.0]: https://github.com/bitcoindevkit/bdk/compare/v0.10.0...v0.11.0
|
||||||
[v0.12.0]: https://github.com/bitcoindevkit/bdk/compare/v0.11.0...v0.12.0
|
[v0.12.0]: https://github.com/bitcoindevkit/bdk/compare/v0.11.0...v0.12.0
|
||||||
|
[v0.13.0]: https://github.com/bitcoindevkit/bdk/compare/v0.12.0...v0.13.0
|
||||||
22
Cargo.toml
22
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bdk"
|
name = "bdk"
|
||||||
version = "0.12.0"
|
version = "0.13.1-dev"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Alekos Filini <alekos.filini@gmail.com>", "Riccardo Casatta <riccardo@casatta.it>"]
|
authors = ["Alekos Filini <alekos.filini@gmail.com>", "Riccardo Casatta <riccardo@casatta.it>"]
|
||||||
homepage = "https://bitcoindevkit.org"
|
homepage = "https://bitcoindevkit.org"
|
||||||
@@ -24,8 +24,9 @@ rand = "^0.7"
|
|||||||
sled = { version = "0.34", optional = true }
|
sled = { version = "0.34", optional = true }
|
||||||
electrum-client = { version = "0.8", optional = true }
|
electrum-client = { version = "0.8", optional = true }
|
||||||
rusqlite = { version = "0.25.3", optional = true }
|
rusqlite = { version = "0.25.3", optional = true }
|
||||||
|
ahash = { version = "=0.7.4", optional = true }
|
||||||
reqwest = { version = "0.11", optional = true, features = ["json"] }
|
reqwest = { version = "0.11", optional = true, features = ["json"] }
|
||||||
ureq = { version = "2.1", features = ["json"], optional = true }
|
ureq = { version = "~2.2.0", features = ["json"], optional = true }
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
async-trait = { version = "0.1", optional = true }
|
async-trait = { version = "0.1", optional = true }
|
||||||
rocksdb = { version = "0.14", default-features = false, features = ["snappy"], optional = true }
|
rocksdb = { version = "0.14", default-features = false, features = ["snappy"], optional = true }
|
||||||
@@ -37,11 +38,14 @@ lazy_static = { version = "1.4", optional = true }
|
|||||||
# MSRV is 1.46, to fix this until we update our MSRV or replace the tiny-bip39
|
# MSRV is 1.46, to fix this until we update our MSRV or replace the tiny-bip39
|
||||||
# dependency https://github.com/bitcoindevkit/bdk/issues/399 we can only use an older version
|
# dependency https://github.com/bitcoindevkit/bdk/issues/399 we can only use an older version
|
||||||
tiny-bip39 = { version = "< 0.8", optional = true }
|
tiny-bip39 = { version = "< 0.8", optional = true }
|
||||||
|
# backtrace > 0.3.61 includes object v0.27 which doesn't compile on 1.46. this is used by
|
||||||
|
# tiny-bip39
|
||||||
|
backtrace = { version = "=0.3.61", optional = true }
|
||||||
|
|
||||||
bitcoinconsensus = { version = "0.19.0-3", optional = true }
|
bitcoinconsensus = { version = "0.19.0-3", optional = true }
|
||||||
|
|
||||||
# Needed by bdk_blockchain_tests macro
|
# Needed by bdk_blockchain_tests macro
|
||||||
core-rpc = { version = "0.14", optional = true }
|
bitcoincore-rpc = { version = "0.14", optional = true }
|
||||||
|
|
||||||
# Platform-specific dependencies
|
# Platform-specific dependencies
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
@@ -57,12 +61,12 @@ minimal = []
|
|||||||
compiler = ["miniscript/compiler"]
|
compiler = ["miniscript/compiler"]
|
||||||
verify = ["bitcoinconsensus"]
|
verify = ["bitcoinconsensus"]
|
||||||
default = ["key-value-db", "electrum"]
|
default = ["key-value-db", "electrum"]
|
||||||
sqlite = ["rusqlite"]
|
sqlite = ["rusqlite", "ahash"]
|
||||||
compact_filters = ["rocksdb", "socks", "lazy_static", "cc"]
|
compact_filters = ["rocksdb", "socks", "lazy_static", "cc"]
|
||||||
key-value-db = ["sled"]
|
key-value-db = ["sled"]
|
||||||
all-keys = ["keys-bip39"]
|
all-keys = ["keys-bip39"]
|
||||||
keys-bip39 = ["tiny-bip39"]
|
keys-bip39 = ["tiny-bip39", "backtrace"]
|
||||||
rpc = ["core-rpc"]
|
rpc = ["bitcoincore-rpc"]
|
||||||
|
|
||||||
# We currently provide mulitple implementations of `Blockchain`, all are
|
# We currently provide mulitple implementations of `Blockchain`, all are
|
||||||
# blocking except for the `EsploraBlockchain` which can be either async or
|
# blocking except for the `EsploraBlockchain` which can be either async or
|
||||||
@@ -87,7 +91,7 @@ esplora = []
|
|||||||
|
|
||||||
|
|
||||||
# Debug/Test features
|
# Debug/Test features
|
||||||
test-blockchains = ["core-rpc", "electrum-client"]
|
test-blockchains = ["bitcoincore-rpc", "electrum-client"]
|
||||||
test-electrum = ["electrum", "electrsd/electrs_0_8_10", "test-blockchains"]
|
test-electrum = ["electrum", "electrsd/electrs_0_8_10", "test-blockchains"]
|
||||||
test-rpc = ["rpc", "electrsd/electrs_0_8_10", "test-blockchains"]
|
test-rpc = ["rpc", "electrsd/electrs_0_8_10", "test-blockchains"]
|
||||||
test-esplora = ["electrsd/legacy", "electrsd/esplora_a33e97e1", "test-blockchains"]
|
test-esplora = ["electrsd/legacy", "electrsd/esplora_a33e97e1", "test-blockchains"]
|
||||||
@@ -97,7 +101,7 @@ test-md-docs = ["electrum"]
|
|||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
env_logger = "0.7"
|
env_logger = "0.7"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
electrsd = { version= "0.10", features = ["trigger", "bitcoind_0_21_1"] }
|
electrsd = { version= "0.12", features = ["trigger", "bitcoind_0_21_1"] }
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "address_validator"
|
name = "address_validator"
|
||||||
@@ -113,6 +117,6 @@ required-features = ["compiler"]
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["macros"]
|
members = ["macros"]
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["compiler", "electrum", "esplora", "ureq", "compact_filters", "rpc", "key-value-db", "all-keys", "verify"]
|
features = ["compiler", "electrum", "esplora", "ureq", "compact_filters", "rpc", "key-value-db", "sqlite", "all-keys", "verify"]
|
||||||
# defines the configuration attribute `docsrs`
|
# defines the configuration attribute `docsrs`
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Pre-`v1.0.0` our "major" releases only affect the "minor" semver value. Accordin
|
|||||||
11. Publish **all** the updated crates to crates.io.
|
11. Publish **all** the updated crates to crates.io.
|
||||||
12. Make a new commit to bump the version value to `x.y.(z+1)-dev`. The message should be "Bump version to x.y.(z+1)-dev".
|
12. Make a new commit to bump the version value to `x.y.(z+1)-dev`. The message should be "Bump version to x.y.(z+1)-dev".
|
||||||
13. Merge the release branch back into `master`.
|
13. Merge the release branch back into `master`.
|
||||||
14. If the `master` branch contains any unreleased changes to the `bdk-macros`, `bdk-testutils`, or `bdk-testutils-macros` crates, change the `bdk` Cargo.toml `[dev-dependencies]` to point to the local path (ie. `bdk-testutils-macros = { path = "./testutils-macros"}`)
|
14. If the `master` branch contains any unreleased changes to the `bdk-macros` crate, change the `bdk` Cargo.toml `[dependencies]` to point to the local path (ie. `bdk-macros = { path = "./macros"}`)
|
||||||
15. Create the release on GitHub: go to "tags", click on the dots on the right and select "Create Release". Then set the title to `vx.y.z` and write down some brief release notes.
|
15. Create the release on GitHub: go to "tags", click on the dots on the right and select "Create Release". Then set the title to `vx.y.z` and write down some brief release notes.
|
||||||
16. Make sure the new release shows up on crates.io and that the docs are built correctly on docs.rs.
|
16. Make sure the new release shows up on crates.io and that the docs are built correctly on docs.rs.
|
||||||
17. Announce the release on Twitter, Discord and Telegram.
|
17. Announce the release on Twitter, Discord and Telegram.
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let policy_str = matches.value_of("POLICY").unwrap();
|
let policy_str = matches.value_of("POLICY").unwrap();
|
||||||
info!("Compiling policy: {}", policy_str);
|
info!("Compiling policy: {}", policy_str);
|
||||||
|
|
||||||
let policy = Concrete::<String>::from_str(&policy_str)?;
|
let policy = Concrete::<String>::from_str(policy_str)?;
|
||||||
|
|
||||||
let descriptor = match matches.value_of("TYPE").unwrap() {
|
let descriptor = match matches.value_of("TYPE").unwrap() {
|
||||||
"sh" => Descriptor::new_sh(policy.compile()?)?,
|
"sh" => Descriptor::new_sh(policy.compile()?)?,
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ impl Blockchain for CompactFiltersBlockchain {
|
|||||||
let total_cost = headers_cost + filters_cost + PROCESS_BLOCKS_COST;
|
let total_cost = headers_cost + filters_cost + PROCESS_BLOCKS_COST;
|
||||||
|
|
||||||
if let Some(snapshot) = sync::sync_headers(
|
if let Some(snapshot) = sync::sync_headers(
|
||||||
Arc::clone(&first_peer),
|
Arc::clone(first_peer),
|
||||||
Arc::clone(&self.headers),
|
Arc::clone(&self.headers),
|
||||||
|new_height| {
|
|new_height| {
|
||||||
let local_headers_cost =
|
let local_headers_cost =
|
||||||
@@ -275,7 +275,7 @@ impl Blockchain for CompactFiltersBlockchain {
|
|||||||
let buried_height = synced_height.saturating_sub(sync::BURIED_CONFIRMATIONS);
|
let buried_height = synced_height.saturating_sub(sync::BURIED_CONFIRMATIONS);
|
||||||
info!("Synced headers to height: {}", synced_height);
|
info!("Synced headers to height: {}", synced_height);
|
||||||
|
|
||||||
cf_sync.prepare_sync(Arc::clone(&first_peer))?;
|
cf_sync.prepare_sync(Arc::clone(first_peer))?;
|
||||||
|
|
||||||
let all_scripts = Arc::new(
|
let all_scripts = Arc::new(
|
||||||
database
|
database
|
||||||
@@ -294,7 +294,7 @@ impl Blockchain for CompactFiltersBlockchain {
|
|||||||
let mut threads = Vec::with_capacity(self.peers.len());
|
let mut threads = Vec::with_capacity(self.peers.len());
|
||||||
for peer in &self.peers {
|
for peer in &self.peers {
|
||||||
let cf_sync = Arc::clone(&cf_sync);
|
let cf_sync = Arc::clone(&cf_sync);
|
||||||
let peer = Arc::clone(&peer);
|
let peer = Arc::clone(peer);
|
||||||
let headers = Arc::clone(&self.headers);
|
let headers = Arc::clone(&self.headers);
|
||||||
let all_scripts = Arc::clone(&all_scripts);
|
let all_scripts = Arc::clone(&all_scripts);
|
||||||
let last_synced_block = Arc::clone(&last_synced_block);
|
let last_synced_block = Arc::clone(&last_synced_block);
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ impl Peer {
|
|||||||
let message_resp = {
|
let message_resp = {
|
||||||
let mut lock = responses.write().unwrap();
|
let mut lock = responses.write().unwrap();
|
||||||
let message_resp = lock.entry(wait_for).or_default();
|
let message_resp = lock.entry(wait_for).or_default();
|
||||||
Arc::clone(&message_resp)
|
Arc::clone(message_resp)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (lock, cvar) = &*message_resp;
|
let (lock, cvar) = &*message_resp;
|
||||||
@@ -379,7 +379,7 @@ impl Peer {
|
|||||||
let message_resp = {
|
let message_resp = {
|
||||||
let mut lock = reader_thread_responses.write().unwrap();
|
let mut lock = reader_thread_responses.write().unwrap();
|
||||||
let message_resp = lock.entry(in_message.cmd()).or_default();
|
let message_resp = lock.entry(in_message.cmd()).or_default();
|
||||||
Arc::clone(&message_resp)
|
Arc::clone(message_resp)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (lock, cvar) = &*message_resp;
|
let (lock, cvar) = &*message_resp;
|
||||||
|
|||||||
@@ -760,7 +760,7 @@ impl CfStore {
|
|||||||
let cf_headers: Vec<FilterHeader> = filter_hashes
|
let cf_headers: Vec<FilterHeader> = filter_hashes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.scan(checkpoint, |prev_header, filter_hash| {
|
.scan(checkpoint, |prev_header, filter_hash| {
|
||||||
let filter_header = filter_hash.filter_header(&prev_header);
|
let filter_header = filter_hash.filter_header(prev_header);
|
||||||
*prev_header = filter_header;
|
*prev_header = filter_header;
|
||||||
|
|
||||||
Some(filter_header)
|
Some(filter_header)
|
||||||
@@ -801,7 +801,7 @@ impl CfStore {
|
|||||||
.zip(headers.into_iter())
|
.zip(headers.into_iter())
|
||||||
.scan(checkpoint, |prev_header, ((_, filter_content), header)| {
|
.scan(checkpoint, |prev_header, ((_, filter_content), header)| {
|
||||||
let filter = BlockFilter::new(&filter_content);
|
let filter = BlockFilter::new(&filter_content);
|
||||||
if header != filter.filter_header(&prev_header) {
|
if header != filter.filter_header(prev_header) {
|
||||||
return Some(Err(CompactFiltersError::InvalidFilter));
|
return Some(Err(CompactFiltersError::InvalidFilter));
|
||||||
}
|
}
|
||||||
*prev_header = header;
|
*prev_header = header;
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ impl CfSync {
|
|||||||
let block_hash = self.headers_store.get_block_hash(height)?.unwrap();
|
let block_hash = self.headers_store.get_block_hash(height)?.unwrap();
|
||||||
|
|
||||||
// TODO: also download random blocks?
|
// TODO: also download random blocks?
|
||||||
if process(&block_hash, &BlockFilter::new(&filter))? {
|
if process(&block_hash, &BlockFilter::new(filter))? {
|
||||||
log::debug!("Downloading block {}", block_hash);
|
log::debug!("Downloading block {}", block_hash);
|
||||||
|
|
||||||
let block = peer
|
let block = peer
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ use crate::database::{BatchDatabase, DatabaseUtils};
|
|||||||
use crate::descriptor::{get_checksum, IntoWalletDescriptor};
|
use crate::descriptor::{get_checksum, IntoWalletDescriptor};
|
||||||
use crate::wallet::utils::SecpCtx;
|
use crate::wallet::utils::SecpCtx;
|
||||||
use crate::{ConfirmationTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
|
use crate::{ConfirmationTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
|
||||||
use core_rpc::json::{
|
use bitcoincore_rpc::json::{
|
||||||
GetAddressInfoResultLabel, ImportMultiOptions, ImportMultiRequest,
|
GetAddressInfoResultLabel, ImportMultiOptions, ImportMultiRequest,
|
||||||
ImportMultiRequestScriptPubkey, ImportMultiRescanSince,
|
ImportMultiRequestScriptPubkey, ImportMultiRescanSince,
|
||||||
};
|
};
|
||||||
use core_rpc::jsonrpc::serde_json::Value;
|
use bitcoincore_rpc::jsonrpc::serde_json::Value;
|
||||||
use core_rpc::Auth as RpcAuth;
|
use bitcoincore_rpc::Auth as RpcAuth;
|
||||||
use core_rpc::{Client, RpcApi};
|
use bitcoincore_rpc::{Client, RpcApi};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
@@ -82,9 +82,9 @@ pub struct RpcConfig {
|
|||||||
pub skip_blocks: Option<u32>,
|
pub skip_blocks: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This struct is equivalent to [core_rpc::Auth] but it implements [serde::Serialize]
|
/// This struct is equivalent to [bitcoincore_rpc::Auth] but it implements [serde::Serialize]
|
||||||
/// To be removed once upstream equivalent is implementing Serialize (json serialization format
|
/// To be removed once upstream equivalent is implementing Serialize (json serialization format
|
||||||
/// should be the same) https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/181
|
/// should be the same), see [rust-bitcoincore-rpc/pull/181](https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/181)
|
||||||
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
@@ -156,7 +156,7 @@ impl Blockchain for RpcBlockchain {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|s| ImportMultiRequest {
|
.map(|s| ImportMultiRequest {
|
||||||
timestamp: ImportMultiRescanSince::Timestamp(0),
|
timestamp: ImportMultiRescanSince::Timestamp(0),
|
||||||
script_pubkey: Some(ImportMultiRequestScriptPubkey::Script(&s)),
|
script_pubkey: Some(ImportMultiRequestScriptPubkey::Script(s)),
|
||||||
watchonly: Some(true),
|
watchonly: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
@@ -238,7 +238,7 @@ impl Blockchain for RpcBlockchain {
|
|||||||
txid, confirmation_time
|
txid, confirmation_time
|
||||||
);
|
);
|
||||||
known_tx.confirmation_time = confirmation_time;
|
known_tx.confirmation_time = confirmation_time;
|
||||||
db.set_tx(&known_tx)?;
|
db.set_tx(known_tx)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//TODO check there is already the raw tx in db?
|
//TODO check there is already the raw tx in db?
|
||||||
@@ -427,13 +427,13 @@ where
|
|||||||
{
|
{
|
||||||
//TODO check descriptors contains only public keys
|
//TODO check descriptors contains only public keys
|
||||||
let descriptor = descriptor
|
let descriptor = descriptor
|
||||||
.into_wallet_descriptor(&secp, network)?
|
.into_wallet_descriptor(secp, network)?
|
||||||
.0
|
.0
|
||||||
.to_string();
|
.to_string();
|
||||||
let mut wallet_name = get_checksum(&descriptor[..descriptor.find('#').unwrap()])?;
|
let mut wallet_name = get_checksum(&descriptor[..descriptor.find('#').unwrap()])?;
|
||||||
if let Some(change_descriptor) = change_descriptor {
|
if let Some(change_descriptor) = change_descriptor {
|
||||||
let change_descriptor = change_descriptor
|
let change_descriptor = change_descriptor
|
||||||
.into_wallet_descriptor(&secp, network)?
|
.into_wallet_descriptor(secp, network)?
|
||||||
.0
|
.0
|
||||||
.to_string();
|
.to_string();
|
||||||
wallet_name.push_str(
|
wallet_name.push_str(
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
//! This module defines an in-memory database type called [`MemoryDatabase`] that is based on a
|
//! This module defines an in-memory database type called [`MemoryDatabase`] that is based on a
|
||||||
//! [`BTreeMap`].
|
//! [`BTreeMap`].
|
||||||
|
|
||||||
|
use std::any::Any;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::ops::Bound::{Excluded, Included};
|
use std::ops::Bound::{Excluded, Included};
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ fn after(key: &[u8]) -> Vec<u8> {
|
|||||||
/// [`database`]: crate::database
|
/// [`database`]: crate::database
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct MemoryDatabase {
|
pub struct MemoryDatabase {
|
||||||
map: BTreeMap<Vec<u8>, Box<dyn std::any::Any>>,
|
map: BTreeMap<Vec<u8>, Box<dyn Any + Send + Sync>>,
|
||||||
deleted_keys: Vec<Vec<u8>>,
|
deleted_keys: Vec<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ pub enum Error {
|
|||||||
Sled(sled::Error),
|
Sled(sled::Error),
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
/// Rpc client error
|
/// Rpc client error
|
||||||
Rpc(core_rpc::Error),
|
Rpc(bitcoincore_rpc::Error),
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
/// Rusqlite client error
|
/// Rusqlite client error
|
||||||
Rusqlite(rusqlite::Error),
|
Rusqlite(rusqlite::Error),
|
||||||
@@ -196,7 +196,7 @@ impl_error!(electrum_client::Error, Electrum);
|
|||||||
#[cfg(feature = "key-value-db")]
|
#[cfg(feature = "key-value-db")]
|
||||||
impl_error!(sled::Error, Sled);
|
impl_error!(sled::Error, Sled);
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
impl_error!(core_rpc::Error, Rpc);
|
impl_error!(bitcoincore_rpc::Error, Rpc);
|
||||||
#[cfg(feature = "sqlite")]
|
#[cfg(feature = "sqlite")]
|
||||||
impl_error!(rusqlite::Error, Rusqlite);
|
impl_error!(rusqlite::Error, Rusqlite);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub type MnemonicWithPassphrase = (Mnemonic, Option<String>);
|
|||||||
#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))]
|
||||||
impl<Ctx: ScriptContext> DerivableKey<Ctx> for Seed {
|
impl<Ctx: ScriptContext> DerivableKey<Ctx> for Seed {
|
||||||
fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
|
fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
|
||||||
Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, &self.as_bytes())?.into())
|
Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, self.as_bytes())?.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_descriptor_key(
|
fn into_descriptor_key(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
//! interact with the bitcoin P2P network.
|
//! interact with the bitcoin P2P network.
|
||||||
//!
|
//!
|
||||||
//! ```toml
|
//! ```toml
|
||||||
//! bdk = "0.12.0"
|
//! bdk = "0.13.0"
|
||||||
//! ```
|
//! ```
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "electrum",
|
feature = "electrum",
|
||||||
@@ -236,7 +236,7 @@ extern crate bdk_macros;
|
|||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
pub extern crate core_rpc;
|
pub extern crate bitcoincore_rpc;
|
||||||
|
|
||||||
#[cfg(feature = "electrum")]
|
#[cfg(feature = "electrum")]
|
||||||
pub extern crate electrum_client;
|
pub extern crate electrum_client;
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ use bitcoin::consensus::encode::{deserialize, serialize};
|
|||||||
use bitcoin::hashes::hex::{FromHex, ToHex};
|
use bitcoin::hashes::hex::{FromHex, ToHex};
|
||||||
use bitcoin::hashes::sha256d;
|
use bitcoin::hashes::sha256d;
|
||||||
use bitcoin::{Address, Amount, Script, Transaction, Txid};
|
use bitcoin::{Address, Amount, Script, Transaction, Txid};
|
||||||
|
pub use bitcoincore_rpc::bitcoincore_rpc_json::AddressType;
|
||||||
|
pub use bitcoincore_rpc::{Auth, Client as RpcClient, RpcApi};
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
pub use core_rpc::core_rpc_json::AddressType;
|
|
||||||
pub use core_rpc::{Auth, Client as RpcClient, RpcApi};
|
|
||||||
use electrsd::bitcoind::BitcoinD;
|
use electrsd::bitcoind::BitcoinD;
|
||||||
use electrsd::{bitcoind, Conf, ElectrsD};
|
use electrsd::{bitcoind, ElectrsD};
|
||||||
pub use electrum_client::{Client as ElectrumClient, ElectrumApi};
|
pub use electrum_client::{Client as ElectrumClient, ElectrumApi};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, log_enabled, trace, Level};
|
use log::{debug, error, info, log_enabled, trace, Level};
|
||||||
@@ -24,19 +24,15 @@ pub struct TestClient {
|
|||||||
impl TestClient {
|
impl TestClient {
|
||||||
pub fn new(bitcoind_exe: String, electrs_exe: String) -> Self {
|
pub fn new(bitcoind_exe: String, electrs_exe: String) -> Self {
|
||||||
debug!("launching {} and {}", &bitcoind_exe, &electrs_exe);
|
debug!("launching {} and {}", &bitcoind_exe, &electrs_exe);
|
||||||
let conf = bitcoind::Conf {
|
|
||||||
view_stdout: log_enabled!(Level::Debug),
|
let mut conf = bitcoind::Conf::default();
|
||||||
..Default::default()
|
conf.view_stdout = log_enabled!(Level::Debug);
|
||||||
};
|
|
||||||
let bitcoind = BitcoinD::with_conf(bitcoind_exe, &conf).unwrap();
|
let bitcoind = BitcoinD::with_conf(bitcoind_exe, &conf).unwrap();
|
||||||
|
|
||||||
let http_enabled = cfg!(feature = "test-esplora");
|
let mut conf = electrsd::Conf::default();
|
||||||
|
conf.view_stderr = log_enabled!(Level::Debug);
|
||||||
|
conf.http_enabled = cfg!(feature = "test-esplora");
|
||||||
|
|
||||||
let conf = Conf {
|
|
||||||
http_enabled,
|
|
||||||
view_stderr: log_enabled!(Level::Debug),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &conf).unwrap();
|
let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &conf).unwrap();
|
||||||
|
|
||||||
let node_address = bitcoind.client.get_new_address(None, None).unwrap();
|
let node_address = bitcoind.client.get_new_address(None, None).unwrap();
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ where
|
|||||||
|
|
||||||
/// Return the list of unspent outputs of this wallet
|
/// Return the list of unspent outputs of this wallet
|
||||||
///
|
///
|
||||||
/// Note that this methods only operate on the internal database, which first needs to be
|
/// Note that this method only operates on the internal database, which first needs to be
|
||||||
/// [`Wallet::sync`] manually.
|
/// [`Wallet::sync`] manually.
|
||||||
pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
|
pub fn list_unspent(&self) -> Result<Vec<LocalUtxo>, Error> {
|
||||||
self.database.borrow().iter_utxos()
|
self.database.borrow().iter_utxos()
|
||||||
@@ -335,6 +335,21 @@ where
|
|||||||
self.database.borrow().get_utxo(&outpoint)
|
self.database.borrow().get_utxo(&outpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a single transactions made and received by the wallet
|
||||||
|
///
|
||||||
|
/// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
|
||||||
|
/// `include_raw` is `true`.
|
||||||
|
///
|
||||||
|
/// Note that this method only operates on the internal database, which first needs to be
|
||||||
|
/// [`Wallet::sync`] manually.
|
||||||
|
pub fn get_tx(
|
||||||
|
&self,
|
||||||
|
txid: &Txid,
|
||||||
|
include_raw: bool,
|
||||||
|
) -> Result<Option<TransactionDetails>, Error> {
|
||||||
|
self.database.borrow().get_tx(txid, include_raw)
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the list of transactions made and received by the wallet
|
/// Return the list of transactions made and received by the wallet
|
||||||
///
|
///
|
||||||
/// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
|
/// Optionally fill the [`TransactionDetails::transaction`] field with the raw transaction if
|
||||||
|
|||||||
Reference in New Issue
Block a user