loading wallet to import UTXO's

This commit is contained in:
aaravm
2024-07-12 16:28:06 +05:30
parent b56380d448
commit 4da52405a4
3 changed files with 109 additions and 50 deletions

View File

@ -288,6 +288,17 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
[[package]]
name = "bitcoin"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3"
dependencies = [
"bech32 0.9.1",
"bitcoin_hashes 0.11.0",
"secp256k1 0.24.3",
]
[[package]] [[package]]
name = "bitcoin" name = "bitcoin"
version = "0.30.2" version = "0.30.2"
@ -353,6 +364,12 @@ dependencies = [
"bitcoin-internals 0.3.0", "bitcoin-internals 0.3.0",
] ]
[[package]]
name = "bitcoin_hashes"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
[[package]] [[package]]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.12.0" version = "0.12.0"
@ -456,7 +473,7 @@ dependencies = [
"anyhow", "anyhow",
"axum", "axum",
"bdk", "bdk",
"bitcoin 0.32.2", "bitcoin 0.29.2",
"dotenv", "dotenv",
"env_logger", "env_logger",
"futures-util", "futures-util",
@ -1886,6 +1903,16 @@ dependencies = [
"untrusted", "untrusted",
] ]
[[package]]
name = "secp256k1"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62"
dependencies = [
"bitcoin_hashes 0.11.0",
"secp256k1-sys 0.6.1",
]
[[package]] [[package]]
name = "secp256k1" name = "secp256k1"
version = "0.27.0" version = "0.27.0"
@ -1908,6 +1935,15 @@ dependencies = [
"secp256k1-sys 0.10.0", "secp256k1-sys 0.10.0",
] ]
[[package]]
name = "secp256k1-sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "secp256k1-sys" name = "secp256k1-sys"
version = "0.8.1" version = "0.8.1"

View File

@ -5,7 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.86" anyhow = "1.0.86"
bitcoin = "0.32.2" bitcoin = "0.29.0"
miniscript = "12.0.0" miniscript = "12.0.0"
axum = { version = "0.7.5", features = ["tokio", "json"] } axum = { version = "0.7.5", features = ["tokio", "json"] }
# "use-esplora-async", "async-interface", for async esplora # "use-esplora-async", "async-interface", for async esplora

View File

@ -1,31 +1,36 @@
use anyhow::Context;
/// This module contains functions related to creating and broadcasting Taproot transactions. /// This module contains functions related to creating and broadcasting Taproot transactions.
/// It includes functions to combine and broadcast the partially signed transactions (PSBTs) /// It includes functions to combine and broadcast the partially signed transactions (PSBTs)
/// from multiple participants, create a Taproot script descriptor, create a PSBT from the /// from multiple participants, create a Taproot script descriptor, create a PSBT from the
/// descriptor, and handle the case when the taker is unresponsive. /// descriptor, and handle the case when the taker is unresponsive.
use bdk::bitcoin::address::NetworkUnchecked; use bdk::bitcoin::address::NetworkUnchecked;
use bdk::bitcoin::bip32::ExtendedPrivKey;
use bdk::bitcoin::psbt::PartiallySignedTransaction; use bdk::bitcoin::psbt::PartiallySignedTransaction;
use bdk::bitcoin::secp256k1::Secp256k1; use bdk::bitcoin::secp256k1::Secp256k1;
use bdk::blockchain::EsploraBlockchain; use bdk::blockchain::{ElectrumBlockchain, EsploraBlockchain};
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::descriptor::Descriptor; use bdk::descriptor::Descriptor;
use bdk::electrum_client::Client;
use bdk::miniscript::descriptor::TapTree; use bdk::miniscript::descriptor::TapTree;
use bdk::miniscript::policy::Concrete; use bdk::miniscript::policy::Concrete;
use bdk::miniscript::psbt::PsbtExt; use bdk::miniscript::psbt::PsbtExt;
use bdk::template::Bip86;
use bdk::wallet::AddressIndex; use bdk::wallet::AddressIndex;
use bdk::SignOptions; use bdk::{sled, SignOptions};
use bdk::{FeeRate, KeychainKind, SyncOptions, Wallet}; use bdk::{FeeRate, KeychainKind, SyncOptions, Wallet};
use bitcoin::address::NetworkChecked;
use bitcoin::Address; use bitcoin::Address;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::env;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::{Arc, Mutex};
use log::debug; use log::debug;
use bdk::bitcoin::PublicKey; use bdk::bitcoin::{PublicKey, ScriptBuf};
use log::info; use log::info;
// use bdk::miniscript::DummyKey; // use bdk::miniscript::DummyKey;
use bdk::miniscript::Tap; use bdk::miniscript::Tap;
/// The main function in this module is `combine_and_broadcast`, which combines the PSBTs /// The main function in this module is `combine_and_broadcast`, which combines the PSBTs
/// from the maker and taker, finalizes the transaction, and broadcasts it on the blockchain. /// from the maker and taker, finalizes the transaction, and broadcasts it on the blockchain.
pub async fn combine_and_broadcast() -> Result<(), Box<dyn std::error::Error>> { pub async fn combine_and_broadcast() -> Result<(), Box<dyn std::error::Error>> {
@ -103,29 +108,45 @@ async fn create_script(
Ok(descriptor) Ok(descriptor)
} }
// /// the provided keys, and `create_psbt`, which creates a PSBT from the descriptor #[derive(Clone)]
// /// Figure out how to put UTXO's pub struct CoordinatorWallet<D: bdk::database::BatchDatabase> {
pub wallet: Arc<Mutex<Wallet<D>>>,
pub backend: Arc<ElectrumBlockchain>,
}
pub fn init_coordinator_wallet(wallet_xprv: &str) -> Result<CoordinatorWallet<sled::Tree>, Box<dyn std::error::Error>> {
let wallet_xprv = ExtendedPrivKey::from_str(wallet_xprv)?;
let backend = ElectrumBlockchain::from(Client::new(
&env::var("ELECTRUM_BACKEND")
.context("Parsing ELECTRUM_BACKEND from .env failed, is it set?")?,
)?);
// let backend = EsploraBlockchain::new(&env::var("ESPLORA_BACKEND")?, 1000);
let sled_db = sled::open(env::var("BDK_DB_PATH")?)?.open_tree("default_wallet")?;
let wallet = Wallet::new(
Bip86(wallet_xprv, KeychainKind::External),
Some(Bip86(wallet_xprv, KeychainKind::Internal)),
bdk::bitcoin::Network::Testnet,
sled_db,
)?;
wallet
.sync(&backend, SyncOptions::default())
.context("Connection to electrum server failed.")?; // we could also use Esplora to make this async
dbg!(wallet.get_balance()?);
Ok(CoordinatorWallet {
wallet: Arc::new(Mutex::new(wallet)),
backend: Arc::new(backend),
})
}
/// the provided keys, and `create_psbt`, which creates a PSBT from the descriptor
/// Figure out how to put UTXO's
// pub async fn create_psbt(descriptor: Descriptor<String>)-> Result<(PartiallySignedTransaction), Box<dyn std::error::Error>> { // pub async fn create_psbt(descriptor: Descriptor<String>)-> Result<(PartiallySignedTransaction), Box<dyn std::error::Error>> {
// let descriptor_str = descriptor.to_string(); // Step 2 and 3 pub async fn create_psbt(descriptor: Descriptor<String>){
// // Step 1: Create a BDK wallet let coordinator_wallet= init_coordinator_wallet("xprv9xom13daMHDPvuivoBnceYvuhPHS6EHZZcND9nN3qvnRw8xM8Jrr24KHnARuReaX1G7PAyYxvkqTRdfhjC9MvQFPbQCXfJwiDiEfbFNSWd4");
// let wallet = Wallet::new(
// // TODO: insert your descriptor here
// // "tr(youshouldputyourdescriptorhere)",
// &descriptor_str,
// None,
// bdk::bitcoin::Network::Testnet,
// MemoryDatabase::new()
// )?;
// // Step 2: Print the first address // Step 3: Deposit funds
// info!( // Use some testnet faucet, such as https://bitcoinfaucet.uo1.net/send.php
// "Deposit funds here: {:?}", // https://coinfaucet.eu/en/btc-testnet4/
// wallet.get_address(AddressIndex::New)?
// );
// // Step 3: Deposit funds
// // Use some testnet faucet, such as https://bitcoinfaucet.uo1.net/send.php
// // https://coinfaucet.eu/en/btc-testnet4/
// // Step 4: Print balance // // Step 4: Print balance
// let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20); // let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20);
@ -135,24 +156,26 @@ async fn create_script(
// let maker_utxos = vec![/* UTXO details here */]; // let maker_utxos = vec![/* UTXO details here */];
// let taker_utxos = vec![/* UTXO details here */]; // let taker_utxos = vec![/* UTXO details here */];
// //TODO: Change type to NetworkChecked
// // Recipient address (where funds will be sent) // // Recipient address (where funds will be sent)
// let recipient_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?; // let faucet_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?;
// // let address = get_address_from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?;
// let address_str = "tb1qqw8ledhkhezru0rwj7acpker8srtcs28sng0d6";
// // Build the PSBT
// let mut tx_builder = wallet.build_tx(); // let mut tx_builder = wallet.build_tx();
// tx_builder // tx_builder
// .add_utxos(&maker_utxos)? // .add_utxos(&maker_utxos)?
// .add_utxos(&taker_utxos)? // .add_utxos(&taker_utxos)?
// .drain_wallet() // .drain_wallet()
// .drain_to(recipient_address.script_pubkey()) // .drain_to(ScriptBuf::from(faucet_address.script_pubkey().to_owned()))
// .fee_rate(FeeRate::from_sat_per_vb(3.0)) // .fee_rate(FeeRate::from_sat_per_vb(3.0))
// .policy_path(BTreeMap::new(), KeychainKind::External); // .policy_path(BTreeMap::new(), KeychainKind::External);
// let (psbt, tx_details) = tx_builder.finish()?; // let (psbt, tx_details) = tx_builder.finish()?;
// debug!("PSBT: {:?}", psbt); // debug!("PSBT: {:?}", psbt);
// Ok(psbt) // Ok(psbt)
// }
}
// /// The `taker_unresponsive` function handles the case when the taker is unresponsive and // /// The `taker_unresponsive` function handles the case when the taker is unresponsive and
// /// the coordinator needs to sign the PSBT using an alternative path. // /// the coordinator needs to sign the PSBT using an alternative path.