From 0b20c1d723e1a36a99cabe440cc1d041dda5f8b1 Mon Sep 17 00:00:00 2001 From: f321x Date: Mon, 24 Jun 2024 08:57:06 +0000 Subject: [PATCH] trade confirmation --- .../trader/src/communication/api.rs | 9 +++++- .../trader/src/communication/mod.rs | 30 ++++++++++++++++++- taptrade-cli-demo/trader/src/trading/mod.rs | 25 ++++++++++++---- .../trader/src/trading/taker_utils.rs | 14 --------- taptrade-cli-demo/trader/src/trading/utils.rs | 26 ++++++++++++++-- 5 files changed, 80 insertions(+), 24 deletions(-) diff --git a/taptrade-cli-demo/trader/src/communication/api.rs b/taptrade-cli-demo/trader/src/communication/api.rs index 2f61dd2..b15c53c 100644 --- a/taptrade-cli-demo/trader/src/communication/api.rs +++ b/taptrade-cli-demo/trader/src/communication/api.rs @@ -22,7 +22,7 @@ pub struct BondRequirementResponse { // maker step 2 // (submission of signed bond and other data neccessary to coordinate the trade) #[derive(Serialize, Debug)] -pub struct BondSubmissionRequest { +pub struct BondSubmissionRequest { pub robohash_hex: String, pub signed_bond_hex: String, // signed bond transaction, hex encoded pub payout_address: String, // does this make sense here? @@ -93,3 +93,10 @@ pub struct IsOfferReadyRequest { pub robohash_hex: String, pub offer_id_hex: String, } + +// request posted by both parties when the trade obligations +#[derive(Debug, Serialize)] +pub struct TradeObligationsSatisfied { + pub robohash_hex: String, + pub offer_id_hex: String, +} diff --git a/taptrade-cli-demo/trader/src/communication/mod.rs b/taptrade-cli-demo/trader/src/communication/mod.rs index 5896f58..016596d 100644 --- a/taptrade-cli-demo/trader/src/communication/mod.rs +++ b/taptrade-cli-demo/trader/src/communication/mod.rs @@ -9,7 +9,7 @@ use crate::{ use anyhow::{anyhow, Result}; use api::{ BondRequirementResponse, BondSubmissionRequest, OfferTakenRequest, OfferTakenResponse, - OrderActivatedResponse, OrderRequest, PsbtSubmissionRequest, + OrderActivatedResponse, OrderRequest, PsbtSubmissionRequest, TradeObligationsSatisfied, }; use bdk::bitcoin::consensus::encode::serialize_hex; use bdk::{ @@ -155,3 +155,31 @@ impl PsbtSubmissionRequest { Ok(()) } } + +impl TradeObligationsSatisfied { + // if the trader is satisfied he can submit this to signal the coordinator readiness to close the trade + // if the other party also submits this the coordinator can initiate the closing transaction, otherwise + // escrow has to be initiated + pub fn submit(offer_id_hex: &String, trader_config: &TraderSettings) -> Result<()> { + let request = TradeObligationsSatisfied { + robohash_hex: trader_config.robosats_robohash_hex.clone(), + offer_id_hex: offer_id_hex.clone(), + }; + + let client = reqwest::blocking::Client::new(); + let res = client + .post(format!( + "{}{}", + trader_config.coordinator_endpoint, "/submit-obligation-confirmation" + )) + .json(&request) + .send()?; + if res.status() != 200 { + return Err(anyhow!( + "Submitting trade obligations confirmation failed. Status: {}", + res.status() + )); + } + Ok(()) + } +} diff --git a/taptrade-cli-demo/trader/src/trading/mod.rs b/taptrade-cli-demo/trader/src/trading/mod.rs index 14fabc2..9056d64 100644 --- a/taptrade-cli-demo/trader/src/trading/mod.rs +++ b/taptrade-cli-demo/trader/src/trading/mod.rs @@ -8,6 +8,7 @@ use crate::{ communication::api::{ BondRequirementResponse, BondSubmissionRequest, IsOfferReadyRequest, OfferTakenRequest, OfferTakenResponse, PsbtSubmissionRequest, PublicOffer, PublicOffers, + TradeObligationsSatisfied, }, wallet::{ bond::Bond, @@ -43,7 +44,14 @@ pub fn run_maker(maker_config: &TraderSettings) -> Result<()> { // wait for confirmation offer.wait_on_trade_ready_confirmation(maker_config)?; - + if offer.fiat_confirmation_cli_input(maker_config)? { + TradeObligationsSatisfied::submit(&offer.offer_id_hex, maker_config)?; + println!("Waiting for other party to confirm the trade."); + // poll for other party + } else { + println!("Trade failed."); + panic!("Escrow to be implemented!"); + } Ok(()) } @@ -59,11 +67,16 @@ pub fn run_taker(taker_config: &TraderSettings) -> Result<()> { let selected_offer: &PublicOffer = available_offers.ask_user_to_select()?; // take selected offer and wait for maker to sign his input to the ecrow transaction - let accepted_offer = ActiveOffer::take(&wallet, taker_config, selected_offer)? - .wait_on_trade_ready_confirmation(taker_config)? - .wait_on_fiat_confirmation_cli_input()?; - - // .wait_on_maker_confirmation(); // here we wait for the maker to confirm the reciept of the fiat. We could go into escrow here. + let accepted_offer = ActiveOffer::take(&wallet, taker_config, selected_offer)?; + accepted_offer.wait_on_trade_ready_confirmation(taker_config)?; + if accepted_offer.fiat_confirmation_cli_input(taker_config)? { + TradeObligationsSatisfied::submit(&accepted_offer.offer_id_hex, taker_config)?; + println!("Waiting for other party to confirm the trade."); + // poll for other party + } else { + println!("Trade failed."); + panic!("Escrow to be implemented!"); + } Ok(()) } diff --git a/taptrade-cli-demo/trader/src/trading/taker_utils.rs b/taptrade-cli-demo/trader/src/trading/taker_utils.rs index 2aff2c9..b267186 100644 --- a/taptrade-cli-demo/trader/src/trading/taker_utils.rs +++ b/taptrade-cli-demo/trader/src/trading/taker_utils.rs @@ -49,18 +49,4 @@ impl ActiveOffer { escrow_psbt: Some(escrow_contract_psbt), }) } - - pub fn wait_on_fiat_confirmation_cli_input(&self) -> Result<&Self> { - // let user confirm in CLI that the fiat payment has been sent/received - println!("The escrow is now locked and the fiat exchange can begin safely."); - loop { - println!("Please confirm that the fiat payment has been sent/received. (y/N)"); - let mut input = String::new(); - std::io::stdin().read_line(&mut input)?; - if input.trim().to_lowercase() == "y" { - break; - } - } - Ok(self) - } } diff --git a/taptrade-cli-demo/trader/src/trading/utils.rs b/taptrade-cli-demo/trader/src/trading/utils.rs index f5ab2ef..eb483a3 100644 --- a/taptrade-cli-demo/trader/src/trading/utils.rs +++ b/taptrade-cli-demo/trader/src/trading/utils.rs @@ -12,8 +12,30 @@ pub struct ActiveOffer { impl ActiveOffer { // polls till the other party signed the trade transaction and it got confirmed. // once the coordinator signals OfferReady the fiat exchange can begin - pub fn wait_on_trade_ready_confirmation(self, trader_config: &TraderSettings) -> Result { + pub fn wait_on_trade_ready_confirmation( + &self, + trader_config: &TraderSettings, + ) -> Result<&Self> { IsOfferReadyRequest::poll(trader_config, &self)?; - Ok(self) + Ok(&self) + } + + pub fn fiat_confirmation_cli_input(&self, trade_settings: &TraderSettings) -> Result { + // let user confirm in CLI that the fiat payment has been sent/received + println!("The escrow is now locked and the fiat exchange can begin safely."); + if trade_settings.trade_type.is_buy_order() { + println!("Please confirm that the fiat payment has been sent or go into mediation in case of problems. (y/M)"); + } else { + println!("Please confirm that the fiat payment has been received or go into mediation in case of problems. (y/M)"); + } + loop { + let mut input = String::new(); + std::io::stdin().read_line(&mut input)?; + if input.trim().to_lowercase() == "y" { + return Ok(true); + } else if input.trim() == "M" { + return Ok(false); + } + } } }