From ef57aaba3203a7b04b7dc2a09a01930a4477d18f Mon Sep 17 00:00:00 2001 From: Felix <51097237+f321x@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:49:19 +0000 Subject: [PATCH] generate descriptors --- taptrade-cli-demo/trader/.env | 7 +++ taptrade-cli-demo/trader/Cargo.lock | 7 +++ taptrade-cli-demo/trader/Cargo.toml | 1 + taptrade-cli-demo/trader/src/cli/mod.rs | 48 +++++++++++++++++-- taptrade-cli-demo/trader/src/main.rs | 1 + taptrade-cli-demo/trader/src/trading/mod.rs | 6 ++- taptrade-cli-demo/trader/src/wallet/bond.rs | 0 taptrade-cli-demo/trader/src/wallet/mod.rs | 53 ++++++++++++++++++++- 8 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 taptrade-cli-demo/trader/.env create mode 100644 taptrade-cli-demo/trader/src/wallet/bond.rs diff --git a/taptrade-cli-demo/trader/.env b/taptrade-cli-demo/trader/.env new file mode 100644 index 0000000..6fee24c --- /dev/null +++ b/taptrade-cli-demo/trader/.env @@ -0,0 +1,7 @@ +ELECTRUM_ENDPOINT="ssl://mempool.space:40002" # testnet 4 electrum server +COORDINATOR_ENDPOINT="http://127.0.0.1:9999" +ROBOHASH_BASE91="o!kfNkee;RF?m6FT87:1bjASE2/(1NFTnR;ILmHB<1p/vP%STz~IWolNDJa.#PmTI)sfBk+Gs!,(w8M" # "robot21" +TRADE_TYPE="buy" +PAYOUT_ADDRESS="tb1pxg64k0729s327n7u4n34vcmjxg42phvjykyt3f0xvcs3x5xfdxgqpt5sql" +BOND_RATIO=5 +FUNDED_WALLET_DESCRIPTOR="tr([3ed82ea5/86h/1h/0h]tpubDCi4JkK1113yExq1Jc42fFYkWt4cfXMSnv47kz6HrU3giqpY6Cu19jc7uXgj5szMyiUnRD4tC8R9mBHLNZw1cKttySbAUEDAYo7bQGSi625/<0;1>/*)#fh3av2m4" # sparrow wallet taproot wallet descriptor diff --git a/taptrade-cli-demo/trader/Cargo.lock b/taptrade-cli-demo/trader/Cargo.lock index 9b9c3fa..b7cf97f 100644 --- a/taptrade-cli-demo/trader/Cargo.lock +++ b/taptrade-cli-demo/trader/Cargo.lock @@ -363,6 +363,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "electrum-client" version = "0.18.0" @@ -1501,6 +1507,7 @@ dependencies = [ "base91", "bdk", "clap", + "dotenv", "reqwest", "serde", "sha2", diff --git a/taptrade-cli-demo/trader/Cargo.toml b/taptrade-cli-demo/trader/Cargo.toml index 0d457e9..b79df8d 100644 --- a/taptrade-cli-demo/trader/Cargo.toml +++ b/taptrade-cli-demo/trader/Cargo.toml @@ -8,6 +8,7 @@ anyhow = "1.0.86" base91 = "0.1.0" bdk = "0.29.0" clap = { version = "4.5.4", features = ["derive", "cargo"] } +dotenv = "0.15.0" reqwest = { version = "0.12.4", features = ["blocking", "json"] } serde = "1.0.203" sha2 = "0.10.8" diff --git a/taptrade-cli-demo/trader/src/cli/mod.rs b/taptrade-cli-demo/trader/src/cli/mod.rs index 0155a6a..4eb4876 100755 --- a/taptrade-cli-demo/trader/src/cli/mod.rs +++ b/taptrade-cli-demo/trader/src/cli/mod.rs @@ -1,6 +1,9 @@ use std::io::{self, Write}; use anyhow::{anyhow, Result}; use sha2::{Sha256, Digest}; +use std::env; + +use crate::wallet::{generate_descriptor_wallet, WalletDescriptors}; #[derive(Debug)] pub struct Coordinator; @@ -19,6 +22,7 @@ pub struct TraderSettings { pub trade_type: OfferType, pub payout_address: String, pub bond_ratio: u8, + pub funded_wallet_descriptor: WalletDescriptors, } #[derive(Debug)] @@ -53,8 +57,11 @@ impl CliSettings { buffer.trim().to_string() } - fn get_trade_type() -> OfferType { - let trade_type = Self::get_user_input("Do you want to buy or sell satoshis: "); + fn get_trade_type(trade_type: Option) -> OfferType { + let trade_type = match trade_type { + Some(value) => value, + None => Self::get_user_input("Do you want to buy or sell satoshis: "), + }; match trade_type.as_str() { "buy" => OfferType::Buy(Self::get_user_input("How many satoshi do you want to buy: ").parse().unwrap()), "sell" => OfferType::Sell(Self::get_user_input("How many satoshi do you want to sell: ").parse().unwrap()), @@ -66,22 +73,53 @@ impl CliSettings { let electrum_endpoint = Self::get_user_input("Enter electrum endpoint: "); let coordinator_endpoint = Self::get_user_input("Enter coordinator endpoint: "); let robosats_robohash_base91 = bytes_to_base91(&hash256(&Self::get_user_input("Enter your robosats robot key: "))); - let trade_type = Self::get_trade_type(); + let trade_type: OfferType = Self::get_trade_type(None); let payout_address = Self::get_user_input("Enter a payout address for refunded bonds or your trade payout: "); // bdk can be used for validation let bond_ratio: u8 = Self::get_user_input("Enter bond ration in [2, 50]%: ").parse()?; + let funded_wallet_descriptor = Self::get_wallet_descriptors(Some(Self::get_user_input("Enter funded testnet wallet descriptor: ")))?; Ok(TraderSettings { electrum_endpoint, coordinator_endpoint, robosats_robohash_base91, trade_type, payout_address, - bond_ratio + bond_ratio, + funded_wallet_descriptor + }) + } + + fn get_wallet_descriptors(cli_input: Option) -> Result { + if let Some(user_input) = cli_input { + if !(user_input.is_empty()) { + return Ok(WalletDescriptors { + descriptor: user_input, + change_descriptor: None + }); + } + }; + generate_descriptor_wallet() + } + + fn load_from_env() -> Result { + dotenv::from_filename(".env")?; + Ok(TraderSettings { + electrum_endpoint: env::var("ELECTRUM_ENDPOINT")?, + coordinator_endpoint: env::var("COORDINATOR_ENDPOINT")?, + robosats_robohash_base91: env::var("ROBOHASH_BASE91")?, + trade_type: Self::get_trade_type(Some(env::var("TRADE_TYPE")?)), + payout_address: env::var("PAYOUT_ADDRESS")?, + bond_ratio: env::var("BOND_RATIO")?.parse()?, + funded_wallet_descriptor: Self::get_wallet_descriptors(Some(env::var("FUNDED_WALLET_DESCRIPTOR")?))?, }) } pub fn parse_cli_args() -> Result { let mode = Self::get_user_input("Enter mode, 'taker' or 'maker': "); - let trader_settings = Self::get_trader_settings()?; + let trader_settings = match Self::get_user_input("Load from .env (y/N): ").trim() { + "y" => Self::load_from_env()?, + "N" => Self::get_trader_settings()?, + _ => return Err(anyhow!("Not a valid input!")), + }; match mode.to_lowercase().as_str() { "maker" => Ok(Self::Maker(trader_settings)), "taker" => Ok(Self::Taker(trader_settings)), diff --git a/taptrade-cli-demo/trader/src/main.rs b/taptrade-cli-demo/trader/src/main.rs index 01d18b9..2c7087b 100644 --- a/taptrade-cli-demo/trader/src/main.rs +++ b/taptrade-cli-demo/trader/src/main.rs @@ -2,6 +2,7 @@ mod cli; mod communication; mod trading; +mod wallet; use core::panic; diff --git a/taptrade-cli-demo/trader/src/trading/mod.rs b/taptrade-cli-demo/trader/src/trading/mod.rs index 728a843..1ec23cf 100644 --- a/taptrade-cli-demo/trader/src/trading/mod.rs +++ b/taptrade-cli-demo/trader/src/trading/mod.rs @@ -4,10 +4,12 @@ use anyhow::Result; use crate::cli::TraderSettings; use crate::communication::api::OfferCreationResponse; +use crate::wallet::load_wallet; + pub fn run_maker(maker_config: &TraderSettings) -> Result<()> { - let offer_conditions = OfferCreationResponse::fetch(maker_config)?; - + // let offer_conditions = OfferCreationResponse::fetch(maker_config)?; + load_wallet(maker_config)?; // maker_utils::maker(offer_conditions, maker_config) Ok(()) diff --git a/taptrade-cli-demo/trader/src/wallet/bond.rs b/taptrade-cli-demo/trader/src/wallet/bond.rs new file mode 100644 index 0000000..e69de29 diff --git a/taptrade-cli-demo/trader/src/wallet/mod.rs b/taptrade-cli-demo/trader/src/wallet/mod.rs index d72f4ba..f83ce67 100644 --- a/taptrade-cli-demo/trader/src/wallet/mod.rs +++ b/taptrade-cli-demo/trader/src/wallet/mod.rs @@ -1 +1,52 @@ -// create bdk wallet +mod bond; + +use bdk::{Wallet, KeychainKind, SyncOptions, bitcoin, template::{Bip86, DescriptorTemplate}}; +use bdk::database::MemoryDatabase; +use bdk::blockchain::ElectrumBlockchain; +use bdk::bitcoin::{Network, secp256k1::rand::{self, RngCore}, bip32::ExtendedPrivKey}; +use bdk::electrum_client::Client; +use anyhow::Result; +use crate::cli::TraderSettings; + +// https://github.com/bitcoindevkit/book-of-bdk + +#[derive(Debug)] +pub struct WalletDescriptors { + pub descriptor: String, + pub change_descriptor: Option +} + +pub fn generate_descriptor_wallet() -> Result { + let mut seed: [u8; 32] = [0u8; 32]; + rand::thread_rng().fill_bytes(&mut seed); // verify this is secure randomness! + + let network: Network = Network::Testnet; + let xprv: ExtendedPrivKey = ExtendedPrivKey::new_master(network, &seed)?; + let (descriptor, key_map, _) = Bip86(xprv, KeychainKind::External).build(network).unwrap(); + let (change_descriptor, change_key_map, _) = Bip86(xprv, KeychainKind::Internal).build(network)?; + let descriptors = WalletDescriptors { + descriptor: descriptor.to_string_with_secret(&key_map), + change_descriptor: Some(change_descriptor.to_string_with_secret(&change_key_map)), + }; + dbg!("Generated wallet descriptors: ", &descriptors); + Ok(descriptors) +} + +pub fn load_wallet(trader_config: &TraderSettings) -> Result<()> { + // let client = Client::new(&trader_config.electrum_endpoint)?; + + + // let blockchain = ElectrumBlockchain::from(client); + // let wallet = Wallet::new( + // trader_config.funded_wallet_descriptor.as_str(), + // None, + // bitcoin::Network::Testnet, + // MemoryDatabase::default(), // non-permanent storage + // )?; + // panic!("yeet"); + // wallet.sync(&blockchain, SyncOptions::default())?; + + // println!("Descriptor balance: {} SAT", wallet.get_balance()?); + // panic!("yeet"); + Ok(()) +}