Skip to content

Commit 4503dc5

Browse files
committed
add electrum_backend example.
1 parent 3644a45 commit 4503dc5

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ name = "rpcwallet"
116116
path = "examples/rpcwallet.rs"
117117
required-features = ["keys-bip39", "key-value-db", "rpc"]
118118

119+
[[example]]
120+
name = "electrum_backend"
121+
path = "examples/electrum_backend.rs"
122+
required-features = ["electrum"]
123+
119124
[workspace]
120125
members = ["macros"]
121126
[package.metadata.docs.rs]

examples/electrum_backend.rs

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::str::FromStr;
2+
3+
use bdk::bitcoin::Network;
4+
use bdk::bitcoin::util::bip32::ExtendedPrivKey;
5+
use bdk::blockchain::{ElectrumBlockchain, Blockchain};
6+
use bdk::database::MemoryDatabase;
7+
use bdk::template::Bip84;
8+
use bdk::wallet::export::{FullyNodedExport};
9+
use bdk::{KeychainKind, Wallet, SyncOptions};
10+
11+
use bdk::electrum_client::Client;
12+
use bdk::wallet::AddressIndex;
13+
use bitcoin::util::bip32;
14+
15+
pub mod utils;
16+
17+
use crate::utils::tx::build_signed_tx;
18+
19+
/// This will create a wallet from an xpriv and get the balance by connecting to an Electrum server.
20+
/// If enough amount is available, this will send a transaction to an address.
21+
/// Otherwise, this will display a wallet address to receive funds.
22+
///
23+
/// This can be run with `cargo run --example electrum_backend` in the root folder.
24+
fn main() {
25+
let network = Network::Testnet;
26+
27+
let xpriv = "tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy";
28+
"health lyrics appear aunt either wrist maple hover family episode seven maze";
29+
30+
let electrum_url = "ssl://electrum.blockstream.info:60002";
31+
32+
run(&network, electrum_url, xpriv);
33+
}
34+
35+
pub fn load_or_create_wallet(
36+
network: &Network,
37+
xpriv: &ExtendedPrivKey
38+
) -> Wallet<MemoryDatabase> {
39+
let wallet = Wallet::new(
40+
Bip84(*xpriv, KeychainKind::External),
41+
Some(Bip84(*xpriv, KeychainKind::Internal)),
42+
*network,
43+
MemoryDatabase::default()
44+
)
45+
.unwrap();
46+
47+
wallet
48+
}
49+
50+
pub fn run(network: &Network, electrum_url: &str, xpriv: &str) {
51+
let xpriv = bip32::ExtendedPrivKey::from_str(xpriv).unwrap();
52+
53+
// Apparently it works only with Electrs (not EletrumX)
54+
let blockchain = ElectrumBlockchain::from(Client::new(electrum_url).unwrap());
55+
56+
let wallet = load_or_create_wallet(&network, &xpriv);
57+
58+
wallet.sync(&blockchain, SyncOptions::default()).unwrap();
59+
60+
let address = wallet.get_address(AddressIndex::New).unwrap().address;
61+
62+
println!("address: {}", address);
63+
64+
let balance = wallet.get_balance().unwrap();
65+
66+
println!("balance: {}", balance);
67+
68+
if balance > 6500 {
69+
// the wallet sends the amount to itself.
70+
let recipient_address = wallet.get_address(AddressIndex::New).unwrap().address.to_string();
71+
72+
let amount = 5359;
73+
74+
let tx = build_signed_tx(&wallet, &recipient_address, amount);
75+
76+
blockchain.broadcast(&tx).unwrap();
77+
78+
println!("tx id: {}", tx.txid().to_string());
79+
} else {
80+
println!("Insufficient Funds. Fund the wallet with the address above");
81+
}
82+
83+
let export = FullyNodedExport::export_wallet(&wallet, "exported wallet", true)
84+
.map_err(ToString::to_string)
85+
.map_err(bdk::Error::Generic).unwrap();
86+
87+
println!("------\nWallet Backup: {}", export.to_string());
88+
}

examples/utils/mod.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
pub(crate) mod tx {
2+
3+
use std::str::FromStr;
4+
5+
use bdk::{database::BatchDatabase, Wallet, SignOptions};
6+
use bitcoin::{Transaction, Address};
7+
8+
pub fn build_signed_tx<D: BatchDatabase>(
9+
wallet: &Wallet<D>,
10+
recipient_address: &str,
11+
amount: u64,
12+
) -> Transaction {
13+
// Create a transaction builder
14+
let mut tx_builder = wallet.build_tx();
15+
16+
let to_address = Address::from_str(recipient_address).unwrap();
17+
18+
// Set recipient of the transaction
19+
tx_builder.set_recipients(vec![(to_address.script_pubkey(), amount)]);
20+
21+
// Finalise the transaction and extract PSBT
22+
let (mut psbt, _) = tx_builder.finish().unwrap();
23+
24+
// Sign the above psbt with signing option
25+
wallet.sign(&mut psbt, SignOptions::default()).unwrap();
26+
27+
// Extract the final transaction
28+
psbt.extract_tx()
29+
30+
}
31+
32+
}

0 commit comments

Comments
 (0)