Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a2b6a40

Browse files
committedSep 7, 2022
add esplora_backend example.
1 parent 8215494 commit a2b6a40

File tree

3 files changed

+190
-1
lines changed

3 files changed

+190
-1
lines changed
 

‎Cargo.toml

+11-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ bitcoincore-rpc = { version = "0.15", optional = true }
4343

4444
# Platform-specific dependencies
4545
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
46-
tokio = { version = "1", features = ["rt"] }
46+
tokio = { version = "1", features = ["rt", "macros"] }
4747

4848
[target.'cfg(target_arch = "wasm32")'.dependencies]
4949
async-trait = "0.1"
@@ -124,6 +124,16 @@ name = "electrum_backend"
124124
path = "examples/electrum_backend.rs"
125125
required-features = ["electrum"]
126126

127+
[[example]]
128+
name = "esplora_backend_synchronous"
129+
path = "examples/esplora_backend_synchronous.rs"
130+
required-features = ["use-esplora-ureq"]
131+
132+
[[example]]
133+
name = "esplora_backend_asynchronous"
134+
path = "examples/esplora_backend_asynchronous.rs"
135+
required-features = ["use-esplora-reqwest", "reqwest-default-tls"]
136+
127137
[workspace]
128138
members = ["macros"]
129139
[package.metadata.docs.rs]
+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use std::str::FromStr;
2+
3+
use bdk::blockchain::Blockchain;
4+
use bdk::{
5+
blockchain::esplora::EsploraBlockchain,
6+
database::MemoryDatabase,
7+
template::Bip84,
8+
wallet::{export::FullyNodedExport, AddressIndex},
9+
KeychainKind, SyncOptions, Wallet,
10+
};
11+
use bitcoin::{
12+
util::bip32::{self, ExtendedPrivKey},
13+
Network,
14+
};
15+
16+
pub mod utils;
17+
18+
use crate::utils::tx::build_signed_tx;
19+
20+
use bdk_macros::await_or_block;
21+
22+
/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server.
23+
/// If enough amount is available, this will send a transaction to an address.
24+
/// Otherwise, this will display a wallet address to receive funds.
25+
///
26+
/// This can be run with `cargo run --no-default-features --features="use-esplora-reqwest, reqwest-default-tls, async-interface" --example esplora_backend_asynchronous`
27+
/// in the root folder.
28+
#[tokio::main(flavor = "current_thread")]
29+
async fn main() {
30+
let network = Network::Signet;
31+
32+
let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
33+
34+
let esplora_url = "https://explorer.bc-2.jp/api";
35+
36+
run(&network, esplora_url, xpriv).await;
37+
}
38+
39+
fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
40+
Wallet::new(
41+
Bip84(*xpriv, KeychainKind::External),
42+
Some(Bip84(*xpriv, KeychainKind::Internal)),
43+
*network,
44+
MemoryDatabase::default(),
45+
)
46+
.unwrap()
47+
}
48+
49+
async fn run(network: &Network, esplora_url: &str, xpriv: &str) {
50+
let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
51+
52+
let blockchain = EsploraBlockchain::new(esplora_url, 20);
53+
54+
let wallet = create_wallet(network, &xpriv);
55+
56+
await_or_block!(wallet.sync(&blockchain, SyncOptions::default())).unwrap();
57+
58+
let address = wallet.get_address(AddressIndex::New).unwrap().address;
59+
60+
println!("address: {}", address);
61+
62+
let balance = wallet.get_balance().unwrap();
63+
64+
println!("Available coins in BDK wallet : {} sats", balance);
65+
66+
if balance.confirmed > 10500 {
67+
// the wallet sends the amount to itself.
68+
let recipient_address = wallet
69+
.get_address(AddressIndex::New)
70+
.unwrap()
71+
.address
72+
.to_string();
73+
74+
let amount = 9359;
75+
76+
let tx = build_signed_tx(&wallet, &recipient_address, amount);
77+
78+
let _ = blockchain.broadcast(&tx);
79+
80+
println!("tx id: {}", tx.txid());
81+
} else {
82+
println!("Insufficient Funds. Fund the wallet with the address above");
83+
}
84+
85+
let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
86+
.map_err(ToString::to_string)
87+
.map_err(bdk::Error::Generic)
88+
.unwrap();
89+
90+
println!("------\nWallet Backup: {}", export.to_string());
91+
}
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::str::FromStr;
2+
3+
use bdk::blockchain::Blockchain;
4+
use bdk::{
5+
blockchain::esplora::EsploraBlockchain,
6+
database::MemoryDatabase,
7+
template::Bip84,
8+
wallet::{export::FullyNodedExport, AddressIndex},
9+
KeychainKind, SyncOptions, Wallet,
10+
};
11+
use bitcoin::{
12+
util::bip32::{self, ExtendedPrivKey},
13+
Network,
14+
};
15+
16+
pub mod utils;
17+
18+
use crate::utils::tx::build_signed_tx;
19+
20+
/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server.
21+
/// If enough amount is available, this will send a transaction to an address.
22+
/// Otherwise, this will display a wallet address to receive funds.
23+
///
24+
/// This can be run with `cargo run --features=use-esplora-ureq --example esplora_backend_synchronous`
25+
/// in the root folder.
26+
fn main() {
27+
let network = Network::Signet;
28+
29+
let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
30+
31+
let esplora_url = "https://explorer.bc-2.jp/api";
32+
33+
run(&network, esplora_url, xpriv);
34+
}
35+
36+
fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
37+
Wallet::new(
38+
Bip84(*xpriv, KeychainKind::External),
39+
Some(Bip84(*xpriv, KeychainKind::Internal)),
40+
*network,
41+
MemoryDatabase::default(),
42+
)
43+
.unwrap()
44+
}
45+
46+
fn run(network: &Network, esplora_url: &str, xpriv: &str) {
47+
let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
48+
49+
let blockchain = EsploraBlockchain::new(esplora_url, 20);
50+
51+
let wallet = create_wallet(network, &xpriv);
52+
53+
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
54+
55+
let address = wallet.get_address(AddressIndex::New).unwrap().address;
56+
57+
println!("address: {}", address);
58+
59+
let balance = wallet.get_balance().unwrap();
60+
61+
println!("Available coins in BDK wallet : {} sats", balance);
62+
63+
if balance.confirmed > 10500 {
64+
// the wallet sends the amount to itself.
65+
let recipient_address = wallet
66+
.get_address(AddressIndex::New)
67+
.unwrap()
68+
.address
69+
.to_string();
70+
71+
let amount = 9359;
72+
73+
let tx = build_signed_tx(&wallet, &recipient_address, amount);
74+
75+
blockchain.broadcast(&tx).unwrap();
76+
77+
println!("tx id: {}", tx.txid());
78+
} else {
79+
println!("Insufficient Funds. Fund the wallet with the address above");
80+
}
81+
82+
let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
83+
.map_err(ToString::to_string)
84+
.map_err(bdk::Error::Generic)
85+
.unwrap();
86+
87+
println!("------\nWallet Backup: {}", export.to_string());
88+
}

0 commit comments

Comments
 (0)
Please sign in to comment.