diff --git a/src/app.rs b/src/app.rs index 2bd35596..b520d002 100644 --- a/src/app.rs +++ b/src/app.rs @@ -15,6 +15,7 @@ pub mod rate_user; // User reputation system pub mod release; // Release of held funds pub mod take_buy; // Taking buy orders pub mod take_sell; // Taking sell orders +pub mod trade_pubkey; // Trade pubkey action // Import action handlers from submodules use crate::app::add_invoice::add_invoice_action; @@ -30,7 +31,7 @@ use crate::app::rate_user::update_user_reputation_action; use crate::app::release::release_action; use crate::app::take_buy::take_buy_action; use crate::app::take_sell::take_sell_action; - +use crate::app::trade_pubkey::trade_pubkey_action; use crate::db::update_user_trade_index; // Core functionality imports use crate::db::add_new_user; @@ -72,7 +73,7 @@ async fn check_trade_index(pool: &Pool, event: &UnwrappedGift, msg: &Mes // Only process actions related to trading if !matches!( message_kind.action, - Action::NewOrder | Action::TakeBuy | Action::TakeSell + Action::NewOrder | Action::TakeBuy | Action::TakeSell | Action::TradePubkey ) { return; } @@ -191,6 +192,7 @@ async fn handle_message_action( Action::AdminSettle => admin_settle_action(msg, event, my_keys, pool, ln_client).await, Action::AdminAddSolver => admin_add_solver_action(msg, event, my_keys, pool).await, Action::AdminTakeDispute => admin_take_dispute_action(msg, event, pool).await, + Action::TradePubkey => trade_pubkey_action(msg, event, pool).await, _ => { tracing::info!("Received message with action {:?}", action); diff --git a/src/app/trade_pubkey.rs b/src/app/trade_pubkey.rs new file mode 100644 index 00000000..aa829826 --- /dev/null +++ b/src/app/trade_pubkey.rs @@ -0,0 +1,73 @@ +use crate::util::{send_cant_do_msg, send_new_order_msg}; + +use anyhow::{Error, Result}; +use mostro_core::message::{Action, CantDoReason, Message}; +use mostro_core::order::{Order, Status}; +use nostr::nips::nip59::UnwrappedGift; +use nostr_sdk::prelude::*; +use sqlx::{Pool, Sqlite}; +use sqlx_crud::Crud; +use tracing::error; + +pub async fn trade_pubkey_action( + msg: Message, + event: &UnwrappedGift, + pool: &Pool, +) -> Result<()> { + // Get request id + let request_id = msg.get_inner_message_kind().request_id; + + let order_id = if let Some(order_id) = msg.get_inner_message_kind().id { + order_id + } else { + return Err(Error::msg("No order id")); + }; + let mut order = match Order::by_id(pool, order_id).await? { + Some(order) => order, + None => { + error!("Order Id {order_id} not found!"); + return Ok(()); + } + }; + // Send to user a DM with the error + if order.status != Status::Pending.to_string() { + send_cant_do_msg( + request_id, + Some(order.id), + Some(CantDoReason::NotAllowedByStatus), + &event.rumor.pubkey, + ) + .await; + + return Ok(()); + } + + match ( + order.master_buyer_pubkey.as_ref(), + order.master_seller_pubkey.as_ref(), + ) { + (Some(master_buyer_pubkey), _) if master_buyer_pubkey == &event.sender.to_string() => { + order.buyer_pubkey = Some(event.rumor.pubkey.to_string()); + } + (_, Some(master_seller_pubkey)) if master_seller_pubkey == &event.sender.to_string() => { + order.seller_pubkey = Some(event.rumor.pubkey.to_string()); + } + _ => return Err(Error::msg("Invalid pubkey")), + }; + order.creator_pubkey = event.rumor.pubkey.to_string(); + + // We a message to the seller + send_new_order_msg( + request_id, + Some(order.id), + Action::TradePubkey, + None, + &event.rumor.pubkey, + None, + ) + .await; + + order.update(pool).await?; + + Ok(()) +}