diff --git a/taptrade-cli-demo/trader/src/communication/api.rs b/taptrade-cli-demo/trader/src/communication/api.rs index 7ec80a8..9f9caea 100644 --- a/taptrade-cli-demo/trader/src/communication/api.rs +++ b/taptrade-cli-demo/trader/src/communication/api.rs @@ -21,7 +21,7 @@ pub struct BondRequirementResponse { // maker step 2 // (submission of signed bond and other data neccessary to coordinate the trade) -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct BondSubmissionRequest { pub robohash_hex: String, pub signed_bond_hex: String, // signed bond transaction, hex encoded @@ -67,3 +67,9 @@ pub struct PublicOffer { pub struct PublicOffers { pub offers: Option>, // don't include offers var in return json if no offers are available } + +#[derive(Debug, Serialize)] +pub struct RequestOfferPsbt { + pub offer: PublicOffer, + pub trade_data: BondSubmissionRequest, +} diff --git a/taptrade-cli-demo/trader/src/communication/mod.rs b/taptrade-cli-demo/trader/src/communication/mod.rs index 825534b..15788a8 100644 --- a/taptrade-cli-demo/trader/src/communication/mod.rs +++ b/taptrade-cli-demo/trader/src/communication/mod.rs @@ -56,24 +56,34 @@ impl BondRequirementResponse { } impl BondSubmissionRequest { - pub fn send( + pub fn prepare_bond_request( + bond: &PartiallySignedTransaction, + payout_address: &AddressInfo, + musig_data: &mut MuSigData, + trader_config: &TraderSettings, + ) -> Result { + let signed_bond_hex = serialize_hex(&bond.to_owned().extract_tx()); + let musig_pub_nonce_hex = hex::encode(musig_data.nonce.get_pub_for_sharing()?.serialize()); + let musig_pubkey_hex = hex::encode(musig_data.public_key.0.serialize()); + + let request = BondSubmissionRequest { + robohash_hex: trader_config.robosats_robohash_hex.clone(), + signed_bond_hex, + payout_address: payout_address.address.to_string(), + musig_pub_nonce_hex, + musig_pubkey_hex, + }; + Ok(request) + } + + pub fn send_maker( robohash_hex: &String, bond: &PartiallySignedTransaction, musig_data: &mut MuSigData, payout_address: &AddressInfo, trader_setup: &TraderSettings, ) -> Result { - let signed_bond_hex = serialize_hex(&bond.to_owned().extract_tx()); - let musig_pub_nonce_hex = hex::encode(musig_data.nonce.get_pub_for_sharing()?.serialize()); - let musig_pubkey_hex = hex::encode(musig_data.public_key.0.serialize()); - let request = BondSubmissionRequest { - robohash_hex: robohash_hex.clone(), - signed_bond_hex, - payout_address: payout_address.address.to_string(), - musig_pub_nonce_hex, - musig_pubkey_hex, - }; - + let request = Self::prepare_bond_request(bond, payout_address, musig_data, trader_setup)?; let client = reqwest::blocking::Client::new(); let res = client .post(format!( diff --git a/taptrade-cli-demo/trader/src/communication/taker_requests.rs b/taptrade-cli-demo/trader/src/communication/taker_requests.rs index 93a3167..d730eb7 100644 --- a/taptrade-cli-demo/trader/src/communication/taker_requests.rs +++ b/taptrade-cli-demo/trader/src/communication/taker_requests.rs @@ -56,3 +56,26 @@ impl PublicOffer { Ok(res) } } + +impl OfferTakenRequest { + pub fn taker_request( + bond: &Bond, + mut musig_data: &MuSigData, + taker_config: &TraderSettings, + ) -> Result { + let request = RequestOfferPsbt { + offer: + }; + + let client = reqwest::blocking::Client::new(); + let res = client + .post(format!( + "{}{}", + taker_config.coordinator_endpoint, "/submit-taker-bond" + )) + .json(self) + .send()? + .json::()?; + Ok(res) + } +} diff --git a/taptrade-cli-demo/trader/src/trading/maker_utils.rs b/taptrade-cli-demo/trader/src/trading/maker_utils.rs index 2b981f3..0b8d960 100644 --- a/taptrade-cli-demo/trader/src/trading/maker_utils.rs +++ b/taptrade-cli-demo/trader/src/trading/maker_utils.rs @@ -15,7 +15,7 @@ impl ActiveOffer { // }; let (bond, mut musig_data, payout_address) = - Self::onchain_assembly(trading_wallet, &offer_conditions, maker_config)?; + trading_wallet.trade_onchain_assembly(&offer_conditions, maker_config)?; let submission_result = BondSubmissionRequest::send( &maker_config.robosats_robohash_hex, &bond, diff --git a/taptrade-cli-demo/trader/src/trading/mod.rs b/taptrade-cli-demo/trader/src/trading/mod.rs index fe76967..af073dd 100644 --- a/taptrade-cli-demo/trader/src/trading/mod.rs +++ b/taptrade-cli-demo/trader/src/trading/mod.rs @@ -43,6 +43,9 @@ pub fn run_taker(taker_config: &TraderSettings) -> Result<()> { available_offers = PublicOffers::fetch(taker_config)?; } let selected_offer: &PublicOffer = available_offers.ask_user_to_select()?; + let accepted_offer = ActiveOffer::take(&wallet, taker_config, selected_offer)?; + + accepted_offer.wait_on_maker(); Ok(()) } diff --git a/taptrade-cli-demo/trader/src/trading/taker_utils.rs b/taptrade-cli-demo/trader/src/trading/taker_utils.rs index 28622e7..0c365ac 100644 --- a/taptrade-cli-demo/trader/src/trading/taker_utils.rs +++ b/taptrade-cli-demo/trader/src/trading/taker_utils.rs @@ -9,6 +9,12 @@ impl ActiveOffer { ) -> Result { let bond_conditions: BondRequirementResponse = offer.take(taker_config)?; let (bond, mut musig_data, payout_address) = - Self::onchain_assembly(trading_wallet, &bond_conditions, taker_config)?; + trading_wallet.trade_onchain_assembly(&bond_conditions, taker_config)?; + // let trading_psbt = + } + + pub fn wait_on_maker(&self) -> Result<()> { + // tbd + Ok(()) } } diff --git a/taptrade-cli-demo/trader/src/trading/utils.rs b/taptrade-cli-demo/trader/src/trading/utils.rs index f9c128d..0c73f6b 100644 --- a/taptrade-cli-demo/trader/src/trading/utils.rs +++ b/taptrade-cli-demo/trader/src/trading/utils.rs @@ -9,20 +9,3 @@ pub struct ActiveOffer { pub used_bond: PartiallySignedTransaction, pub expected_payout_address: AddressInfo, } - -impl ActiveOffer { - pub fn onchain_assembly( - trading_wallet: &TradingWallet, - offer_conditions: &BondRequirementResponse, - trader_config: &TraderSettings, - ) -> Result<(PartiallySignedTransaction, MuSigData, AddressInfo)> { - let trading_wallet = &trading_wallet.wallet; - let bond = Bond::assemble(trading_wallet, &offer_conditions, trader_config)?; - let payout_address: AddressInfo = - trading_wallet.get_address(bdk::wallet::AddressIndex::LastUnused)?; - let mut musig_data = - MuSigData::create(&trader_config.wallet_xprv, trading_wallet.secp_ctx())?; - - Ok((bond, musig_data, payout_address)) - } -} diff --git a/taptrade-cli-demo/trader/src/wallet/bond.rs b/taptrade-cli-demo/trader/src/wallet/bond.rs index 75534e0..4952199 100644 --- a/taptrade-cli-demo/trader/src/wallet/bond.rs +++ b/taptrade-cli-demo/trader/src/wallet/bond.rs @@ -10,7 +10,7 @@ use bdk::{ use serde::de::value; use std::str::FromStr; -use crate::communication::api::OfferCreationResponse; +use crate::communication::api::BondRequirementResponse; use crate::wallet::TraderSettings; pub struct Outpoint { @@ -26,7 +26,7 @@ pub struct Bond { impl Bond { pub fn assemble( wallet: &Wallet, - bond_target: &OfferCreationResponse, + bond_target: &BondRequirementResponse, trader_input: &TraderSettings, ) -> Result { // parse bond locking address as Address struct and verify network is testnet diff --git a/taptrade-cli-demo/trader/src/wallet/mod.rs b/taptrade-cli-demo/trader/src/wallet/mod.rs index 44b15ac..68c1e7b 100644 --- a/taptrade-cli-demo/trader/src/wallet/mod.rs +++ b/taptrade-cli-demo/trader/src/wallet/mod.rs @@ -2,19 +2,21 @@ pub mod bond; pub mod musig2; pub mod wallet_utils; -use crate::cli::TraderSettings; +use crate::{cli::TraderSettings, communication::api::BondRequirementResponse}; use anyhow::Result; -use bdk::bitcoin::{bip32::ExtendedPrivKey, Network}; -use bdk::blockchain::ElectrumBlockchain; -use bdk::database::MemoryDatabase; -use bdk::electrum_client::Client; use bdk::{ - bitcoin, + bitcoin::{self, bip32::ExtendedPrivKey, psbt::PartiallySignedTransaction, Network}, + blockchain::ElectrumBlockchain, + database::MemoryDatabase, + electrum_client::Client, keys::DescriptorPublicKey, miniscript::Descriptor, template::{Bip86, DescriptorTemplate}, + wallet::AddressInfo, KeychainKind, SyncOptions, Wallet, }; +use bond::Bond; +use musig2::MuSigData; use std::str::FromStr; use wallet_utils::get_seed; @@ -54,4 +56,20 @@ impl TradingWallet { dbg!("Balance: {} SAT", wallet.get_balance()?); Ok(TradingWallet { wallet, backend }) } + + // assemble bond and generate musig data for passed trade + pub fn trade_onchain_assembly( + &self, + offer_conditions: &BondRequirementResponse, + trader_config: &TraderSettings, + ) -> Result<(PartiallySignedTransaction, MuSigData, AddressInfo)> { + let trading_wallet = self.wallet; + let bond = Bond::assemble(&self.wallet, &offer_conditions, trader_config)?; + let payout_address: AddressInfo = + trading_wallet.get_address(bdk::wallet::AddressIndex::LastUnused)?; + let mut musig_data = + MuSigData::create(&trader_config.wallet_xprv, trading_wallet.secp_ctx())?; + + Ok((bond, musig_data, payout_address)) + } }