]> Untitled Git - bdk/commitdiff
add `esplora_backend` example.
authorw0xlt <woltx@protonmail.com>
Wed, 3 Aug 2022 16:12:25 +0000 (13:12 -0300)
committerw0xlt <woltx@protonmail.com>
Tue, 1 Nov 2022 22:59:55 +0000 (19:59 -0300)
Cargo.toml
examples/esplora_backend_asynchronous.rs [new file with mode: 0644]
examples/esplora_backend_synchronous.rs [new file with mode: 0644]

index a01e2148a56f479fecebda09b4bbd0ae666ce9bb..4cd9dbaf39476e40fa28a1235e70544059ea588d 100644 (file)
@@ -41,7 +41,7 @@ bitcoincore-rpc = { version = "0.16", optional = true }
 
 # Platform-specific dependencies
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
-tokio = { version = "1", features = ["rt"] }
+tokio = { version = "1", features = ["rt", "macros"] }
 
 [target.'cfg(target_arch = "wasm32")'.dependencies]
 getrandom = "0.2"
@@ -143,6 +143,16 @@ name = "electrum_backend"
 path = "examples/electrum_backend.rs"
 required-features = ["electrum"]
 
+[[example]]
+name = "esplora_backend_synchronous"
+path = "examples/esplora_backend_synchronous.rs"
+required-features = ["use-esplora-ureq"]
+
+[[example]]
+name = "esplora_backend_asynchronous"
+path = "examples/esplora_backend_asynchronous.rs"
+required-features = ["use-esplora-reqwest", "reqwest-default-tls", "async-interface"]
+
 [workspace]
 members = ["macros"]
 [package.metadata.docs.rs]
diff --git a/examples/esplora_backend_asynchronous.rs b/examples/esplora_backend_asynchronous.rs
new file mode 100644 (file)
index 0000000..4aa149b
--- /dev/null
@@ -0,0 +1,93 @@
+use std::str::FromStr;
+
+use bdk::blockchain::Blockchain;
+use bdk::{
+    blockchain::esplora::EsploraBlockchain,
+    database::MemoryDatabase,
+    template::Bip84,
+    wallet::{export::FullyNodedExport, AddressIndex},
+    KeychainKind, SyncOptions, Wallet,
+};
+use bitcoin::{
+    util::bip32::{self, ExtendedPrivKey},
+    Network,
+};
+
+pub mod utils;
+
+use crate::utils::tx::build_signed_tx;
+
+/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server,
+/// using non blocking asynchronous calls with `reqwest`.
+/// If enough amount is available, this will send a transaction to an address.
+/// Otherwise, this will display a wallet address to receive funds.
+///
+/// This can be run with `cargo run --no-default-features --features="use-esplora-reqwest, reqwest-default-tls, async-interface" --example esplora_backend_asynchronous`
+/// in the root folder.
+#[tokio::main(flavor = "current_thread")]
+async fn main() {
+    let network = Network::Signet;
+
+    let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
+
+    let esplora_url = "https://explorer.bc-2.jp/api";
+
+    run(&network, esplora_url, xpriv).await;
+}
+
+fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
+    Wallet::new(
+        Bip84(*xpriv, KeychainKind::External),
+        Some(Bip84(*xpriv, KeychainKind::Internal)),
+        *network,
+        MemoryDatabase::default(),
+    )
+    .unwrap()
+}
+
+async fn run(network: &Network, esplora_url: &str, xpriv: &str) {
+    let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
+
+    let blockchain = EsploraBlockchain::new(esplora_url, 20);
+
+    let wallet = create_wallet(network, &xpriv);
+
+    wallet
+        .sync(&blockchain, SyncOptions::default())
+        .await
+        .unwrap();
+
+    let address = wallet.get_address(AddressIndex::New).unwrap().address;
+
+    println!("address: {}", address);
+
+    let balance = wallet.get_balance().unwrap();
+
+    println!("Available coins in BDK wallet : {} sats", balance);
+
+    if balance.confirmed > 10500 {
+        // the wallet sends the amount to itself.
+        let recipient_address = wallet
+            .get_address(AddressIndex::New)
+            .unwrap()
+            .address
+            .to_string();
+
+        let amount = 9359;
+
+        let tx = build_signed_tx(&wallet, &recipient_address, amount);
+
+        let _ = blockchain.broadcast(&tx);
+
+        println!("tx id: {}", tx.txid());
+    } else {
+        println!("Insufficient Funds. Fund the wallet with the address above");
+    }
+
+    let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
+        .map_err(ToString::to_string)
+        .map_err(bdk::Error::Generic)
+        .unwrap();
+
+    println!("------\nWallet Backup: {}", export.to_string());
+}
diff --git a/examples/esplora_backend_synchronous.rs b/examples/esplora_backend_synchronous.rs
new file mode 100644 (file)
index 0000000..31907f8
--- /dev/null
@@ -0,0 +1,89 @@
+use std::str::FromStr;
+
+use bdk::blockchain::Blockchain;
+use bdk::{
+    blockchain::esplora::EsploraBlockchain,
+    database::MemoryDatabase,
+    template::Bip84,
+    wallet::{export::FullyNodedExport, AddressIndex},
+    KeychainKind, SyncOptions, Wallet,
+};
+use bitcoin::{
+    util::bip32::{self, ExtendedPrivKey},
+    Network,
+};
+
+pub mod utils;
+
+use crate::utils::tx::build_signed_tx;
+
+/// This will create a wallet from an xpriv and get the balance by connecting to an Esplora server,
+/// using blocking calls with `ureq`.
+/// If enough amount is available, this will send a transaction to an address.
+/// Otherwise, this will display a wallet address to receive funds.
+///
+/// This can be run with `cargo run --features=use-esplora-ureq --example esplora_backend_synchronous`
+/// in the root folder.
+fn main() {
+    let network = Network::Signet;
+
+    let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
+
+    let esplora_url = "https://explorer.bc-2.jp/api";
+
+    run(&network, esplora_url, xpriv);
+}
+
+fn create_wallet(network: &Network, xpriv: &ExtendedPrivKey) -> Wallet<MemoryDatabase> {
+    Wallet::new(
+        Bip84(*xpriv, KeychainKind::External),
+        Some(Bip84(*xpriv, KeychainKind::Internal)),
+        *network,
+        MemoryDatabase::default(),
+    )
+    .unwrap()
+}
+
+fn run(network: &Network, esplora_url: &str, xpriv: &str) {
+    let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
+
+    let blockchain = EsploraBlockchain::new(esplora_url, 20);
+
+    let wallet = create_wallet(network, &xpriv);
+
+    wallet.sync(&blockchain, SyncOptions::default()).unwrap();
+
+    let address = wallet.get_address(AddressIndex::New).unwrap().address;
+
+    println!("address: {}", address);
+
+    let balance = wallet.get_balance().unwrap();
+
+    println!("Available coins in BDK wallet : {} sats", balance);
+
+    if balance.confirmed > 10500 {
+        // the wallet sends the amount to itself.
+        let recipient_address = wallet
+            .get_address(AddressIndex::New)
+            .unwrap()
+            .address
+            .to_string();
+
+        let amount = 9359;
+
+        let tx = build_signed_tx(&wallet, &recipient_address, amount);
+
+        blockchain.broadcast(&tx).unwrap();
+
+        println!("tx id: {}", tx.txid());
+    } else {
+        println!("Insufficient Funds. Fund the wallet with the address above");
+    }
+
+    let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
+        .map_err(ToString::to_string)
+        .map_err(bdk::Error::Generic)
+        .unwrap();
+
+    println!("------\nWallet Backup: {}", export.to_string());
+}