From 4da52405a4f09b5b7452ae56d9a08eb7f9ba0590 Mon Sep 17 00:00:00 2001 From: aaravm Date: Fri, 12 Jul 2024 16:28:06 +0530 Subject: [PATCH] loading wallet to import UTXO's --- taptrade-cli-demo/coordinator/Cargo.lock | 38 +++++- taptrade-cli-demo/coordinator/Cargo.toml | 2 +- .../src/coordinator/create_taproot.rs | 119 +++++++++++------- 3 files changed, 109 insertions(+), 50 deletions(-) diff --git a/taptrade-cli-demo/coordinator/Cargo.lock b/taptrade-cli-demo/coordinator/Cargo.lock index 9cf41bf..b03bf75 100644 --- a/taptrade-cli-demo/coordinator/Cargo.lock +++ b/taptrade-cli-demo/coordinator/Cargo.lock @@ -288,6 +288,17 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "bitcoin" version = "0.30.2" @@ -353,6 +364,12 @@ dependencies = [ "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]] name = "bitcoin_hashes" version = "0.12.0" @@ -456,7 +473,7 @@ dependencies = [ "anyhow", "axum", "bdk", - "bitcoin 0.32.2", + "bitcoin 0.29.2", "dotenv", "env_logger", "futures-util", @@ -1886,6 +1903,16 @@ dependencies = [ "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]] name = "secp256k1" version = "0.27.0" @@ -1908,6 +1935,15 @@ dependencies = [ "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]] name = "secp256k1-sys" version = "0.8.1" diff --git a/taptrade-cli-demo/coordinator/Cargo.toml b/taptrade-cli-demo/coordinator/Cargo.toml index ca649d0..1eae80f 100644 --- a/taptrade-cli-demo/coordinator/Cargo.toml +++ b/taptrade-cli-demo/coordinator/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0.86" -bitcoin = "0.32.2" +bitcoin = "0.29.0" miniscript = "12.0.0" axum = { version = "0.7.5", features = ["tokio", "json"] } # "use-esplora-async", "async-interface", for async esplora diff --git a/taptrade-cli-demo/coordinator/src/coordinator/create_taproot.rs b/taptrade-cli-demo/coordinator/src/coordinator/create_taproot.rs index 358a0ba..a05154a 100644 --- a/taptrade-cli-demo/coordinator/src/coordinator/create_taproot.rs +++ b/taptrade-cli-demo/coordinator/src/coordinator/create_taproot.rs @@ -1,31 +1,36 @@ +use anyhow::Context; /// This module contains functions related to creating and broadcasting Taproot transactions. /// 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 /// descriptor, and handle the case when the taker is unresponsive. use bdk::bitcoin::address::NetworkUnchecked; +use bdk::bitcoin::bip32::ExtendedPrivKey; use bdk::bitcoin::psbt::PartiallySignedTransaction; use bdk::bitcoin::secp256k1::Secp256k1; -use bdk::blockchain::EsploraBlockchain; +use bdk::blockchain::{ElectrumBlockchain, EsploraBlockchain}; use bdk::database::MemoryDatabase; use bdk::descriptor::Descriptor; +use bdk::electrum_client::Client; use bdk::miniscript::descriptor::TapTree; use bdk::miniscript::policy::Concrete; use bdk::miniscript::psbt::PsbtExt; +use bdk::template::Bip86; use bdk::wallet::AddressIndex; -use bdk::SignOptions; +use bdk::{sled, SignOptions}; use bdk::{FeeRate, KeychainKind, SyncOptions, Wallet}; -use bitcoin::address::NetworkChecked; use bitcoin::Address; use std::collections::BTreeMap; +use std::env; use std::str::FromStr; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use log::debug; -use bdk::bitcoin::PublicKey; +use bdk::bitcoin::{PublicKey, ScriptBuf}; use log::info; // use bdk::miniscript::DummyKey; use bdk::miniscript::Tap; + /// 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. pub async fn combine_and_broadcast() -> Result<(), Box> { @@ -103,56 +108,74 @@ async fn create_script( Ok(descriptor) } -// /// the provided keys, and `create_psbt`, which creates a PSBT from the descriptor -// /// Figure out how to put UTXO's +#[derive(Clone)] +pub struct CoordinatorWallet { + pub wallet: Arc>>, + pub backend: Arc, +} + +pub fn init_coordinator_wallet(wallet_xprv: &str) -> Result, Box> { + 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)-> Result<(PartiallySignedTransaction), Box> { -// let descriptor_str = descriptor.to_string(); // Step 2 and 3 -// // Step 1: Create a BDK wallet -// let wallet = Wallet::new( -// // TODO: insert your descriptor here -// // "tr(youshouldputyourdescriptorhere)", -// &descriptor_str, -// None, -// bdk::bitcoin::Network::Testnet, -// MemoryDatabase::new() -// )?; +pub async fn create_psbt(descriptor: Descriptor){ + let coordinator_wallet= init_coordinator_wallet("xprv9xom13daMHDPvuivoBnceYvuhPHS6EHZZcND9nN3qvnRw8xM8Jrr24KHnARuReaX1G7PAyYxvkqTRdfhjC9MvQFPbQCXfJwiDiEfbFNSWd4"); -// // Step 2: Print the first address -// info!( -// "Deposit funds here: {:?}", -// 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 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 + // let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20); + // wallet.sync(&blockchain, SyncOptions::default())?; + // info!("{:#?}", wallet.get_balance()?); -// // Step 4: Print balance -// let blockchain = EsploraBlockchain::new("https://blockstream.info/testnet/api", 20); -// wallet.sync(&blockchain, SyncOptions::default())?; -// info!("{:#?}", wallet.get_balance()?); + // let maker_utxos = vec![/* UTXO details here */]; + // let taker_utxos = vec![/* UTXO details here */]; -// let maker_utxos = vec![/* UTXO details here */]; -// let taker_utxos = vec![/* UTXO details here */]; + // // Recipient address (where funds will be sent) + // let faucet_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?; -// //TODO: Change type to NetworkChecked -// // Recipient address (where funds will be sent) -// let recipient_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?; + // // let address = get_address_from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?; + // let address_str = "tb1qqw8ledhkhezru0rwj7acpker8srtcs28sng0d6"; + + // let mut tx_builder = wallet.build_tx(); + // tx_builder + // .add_utxos(&maker_utxos)? + // .add_utxos(&taker_utxos)? + // .drain_wallet() + // .drain_to(ScriptBuf::from(faucet_address.script_pubkey().to_owned())) + // .fee_rate(FeeRate::from_sat_per_vb(3.0)) + // .policy_path(BTreeMap::new(), KeychainKind::External); -// // Build the PSBT -// let mut tx_builder = wallet.build_tx(); -// tx_builder -// .add_utxos(&maker_utxos)? -// .add_utxos(&taker_utxos)? -// .drain_wallet() -// .drain_to(recipient_address.script_pubkey()) -// .fee_rate(FeeRate::from_sat_per_vb(3.0)) -// .policy_path(BTreeMap::new(), KeychainKind::External); - -// let (psbt, tx_details) = tx_builder.finish()?; -// debug!("PSBT: {:?}", psbt); -// Ok(psbt) -// } + // let (psbt, tx_details) = tx_builder.finish()?; + // debug!("PSBT: {:?}", psbt); + // Ok(psbt) + +} // /// The `taker_unresponsive` function handles the case when the taker is unresponsive and // /// the coordinator needs to sign the PSBT using an alternative path.