-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
blockbook: integrate with bdk wallet
The new code is heavily inspired by the esplora integration and example crate maintained within the bdk repo [1, 2]. `bdk` depends on an older version of the `bitcoin` crate than the `blockbook` library. Where necessary we thus pass through a (de-)serialization boundary to create types of one version from the other. This is not possible through the implementation of suitable `From` traits due to Rust's orphan rules. The tested xpub stems from a previous blockbook test where we burned some satoshis. [1] https://github.com/bitcoindevkit/bdk/tree/3569acca0b3f3540e1f1a2278794eac4642a05e4/crates/esplora [2] https://github.com/bitcoindevkit/bdk/tree/master/example-crates/wallet_esplora_async
- Loading branch information
Showing
5 changed files
with
594 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use bdk::{ | ||
bitcoin::Network, | ||
wallet::{AddressIndex, Update}, | ||
Wallet, | ||
}; | ||
|
||
const STOP_GAP: u32 = 50; | ||
const PARALLEL_REQUESTS: usize = 5; | ||
|
||
/// Demonstrates the usage of a `Blockbook` client as a | ||
/// data backend for a `bdk` wallet. Here, we sync the | ||
/// balance of a watch-only xpub wallet. | ||
/// | ||
/// For more involved examples of how to use `bdk` wallets, see their | ||
/// [example crates](https://github.com/bitcoindevkit/bdk/tree/3569acca0b3f3540e1f1a2278794eac4642a05e4/example-crates). | ||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let blockbook_server = std::env::var("BLOCKBOOK_SERVER") | ||
.expect("please set the `BLOCKBOOK_SERVER` environment variable"); | ||
|
||
// https://www.blockchain.com/explorer/assets/btc/xpub/xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKrhko4egpiMZbpiaQL2jkwSB1icqYh2cfDfVxdx4df189oLKnC5fSwqPfgyP3hooxujYzAu3fDVmz | ||
let external_descriptor = "pkh(xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKrhko4egpiMZbpiaQL2jkwSB1icqYh2cfDfVxdx4df189oLKnC5fSwqPfgyP3hooxujYzAu3fDVmz/0/*)"; | ||
let internal_descriptor = "pkh(xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKrhko4egpiMZbpiaQL2jkwSB1icqYh2cfDfVxdx4df189oLKnC5fSwqPfgyP3hooxujYzAu3fDVmz/1/*)"; | ||
|
||
let mut wallet = Wallet::new_no_persist( | ||
external_descriptor, | ||
Some(internal_descriptor), | ||
Network::Bitcoin, | ||
)?; | ||
|
||
let address = wallet.get_address(AddressIndex::New); | ||
println!("Generated Address: {address}"); | ||
|
||
let balance = wallet.get_balance(); | ||
println!("Wallet balance before syncing: {} sats", balance.total()); | ||
|
||
println!("Syncing..."); | ||
let client = blockbook::Client::new(blockbook_server.parse().unwrap()) | ||
.await | ||
.unwrap(); | ||
|
||
let (update_graph, last_active_indices) = client | ||
.scan_txs_with_keychains( | ||
wallet.spks_of_all_keychains(), | ||
&Network::Bitcoin, | ||
None, | ||
None, | ||
STOP_GAP, | ||
PARALLEL_REQUESTS, | ||
) | ||
.await?; | ||
let prev_tip = wallet.latest_checkpoint(); | ||
let missing_heights = update_graph.missing_heights(wallet.local_chain()); | ||
let chain_update = client.update_local_chain(prev_tip, missing_heights).await?; | ||
let update = Update { | ||
last_active_indices, | ||
graph: update_graph, | ||
chain: Some(chain_update), | ||
}; | ||
wallet.apply_update(update)?; | ||
wallet.commit()?; | ||
|
||
let balance = wallet.get_balance(); | ||
println!("Wallet balance after syncing: {} sats", balance.total()); | ||
Ok(()) | ||
} |
Oops, something went wrong.