Sync a Wallet with Esplora
Syncing with Esplora uses what we refer to as SPK-based syncing (see our Full Scan vs Sync page for more information on this).
The workflow for a full scan or sync consists of a 3-step process:
- Ask the wallet for the data structure required.
- Pass it to your blockchain client and request a full scan or sync.
- The client returns an update, which you then apply to the wallet.
This workflow ensures that the wallet structure is not blocked while the syncing operation is performed.
Add required bdk dependencies to your Cargo.toml file
Cargo.toml |
---|
| [dependencies]
bdk_wallet = { version = "1.0.0" }
bdk_esplora = { version = "0.20.1", features = ["blocking"] }
anyhow = "1"
|
Create and sync the wallet
main.rs |
---|
| use anyhow::Error;
use bdk_esplora::esplora_client::Builder;
use bdk_esplora::{esplora_client, EsploraExt};
use bdk_wallet::bitcoin::Network;
use bdk_wallet::chain::spk_client::{
FullScanRequestBuilder, FullScanResponse, SyncRequestBuilder, SyncResponse,
};
use bdk_wallet::AddressInfo;
use bdk_wallet::KeychainKind;
use bdk_wallet::Wallet;
const STOP_GAP: usize = 50;
const PARALLEL_REQUESTS: usize = 1;
const EXTERNAL_DESCRIPTOR: &str = "tr(tprv8ZgxMBicQKsPdrjwWCyXqqJ4YqcyG4DmKtjjsRt29v1PtD3r3PuFJAjWytzcvSTKnZAGAkPSmnrdnuHWxCAwy3i1iPhrtKAfXRH7dVCNGp6/86'/1'/0'/0/*)#g9xn7wf9";
const INTERNAL_DESCRIPTOR: &str = "tr(tprv8ZgxMBicQKsPdrjwWCyXqqJ4YqcyG4DmKtjjsRt29v1PtD3r3PuFJAjWytzcvSTKnZAGAkPSmnrdnuHWxCAwy3i1iPhrtKAfXRH7dVCNGp6/86'/1'/0'/1/*)#e3rjrmea";
fn main() -> Result<(), Error> {
let mut wallet: Wallet = Wallet::create(EXTERNAL_DESCRIPTOR, INTERNAL_DESCRIPTOR)
.network(Network::Signet)
.create_wallet_no_persist()?;
let address: AddressInfo = wallet.reveal_next_address(KeychainKind::External);
println!(
"Generated address {} at index {}",
address.address, address.index
);
// Create the Esplora client
let client: esplora_client::BlockingClient =
Builder::new("http://signet.bitcoindevkit.net").build_blocking();
// Full scan the wallet
let full_scan_request: FullScanRequestBuilder<KeychainKind> = wallet.start_full_scan();
let full_scan_response: FullScanResponse<KeychainKind> =
client.full_scan(full_scan_request, STOP_GAP, PARALLEL_REQUESTS)?;
// Apply the full scan response to the wallet
wallet.apply_update(full_scan_response)?;
// Sync the wallet
let sync_request: SyncRequestBuilder<(KeychainKind, u32)> =
wallet.start_sync_with_revealed_spks();
let sync_response: SyncResponse = client.sync(sync_request, PARALLEL_REQUESTS)?;
// Apply the sync response to the wallet
wallet.apply_update(sync_response)?;
let balance = wallet.balance();
println!("Wallet balance: {} sat", balance.total().to_sat());
Ok(())
}
|