mostro_client/cli/
send_msg.rs1use crate::cli::{Commands, Context};
2use crate::db::{Order, User};
3use crate::util::{print_dm_events, send_dm, wait_for_dm};
4
5use anyhow::Result;
6use mostro_core::prelude::*;
7use nostr_sdk::prelude::*;
8use uuid::Uuid;
9
10pub async fn execute_send_msg(
11 command: Commands,
12 order_id: Option<Uuid>,
13 ctx: &Context,
14 text: Option<&str>,
15) -> Result<()> {
16 let requested_action = match command {
18 Commands::FiatSent { .. } => Action::FiatSent,
19 Commands::Release { .. } => Action::Release,
20 Commands::Cancel { .. } => Action::Cancel,
21 Commands::Dispute { .. } => Action::Dispute,
22 Commands::AdmCancel { .. } => Action::AdminCancel,
23 Commands::AdmSettle { .. } => Action::AdminSettle,
24 Commands::AdmAddSolver { .. } => Action::AdminAddSolver,
25 _ => {
26 return Err(anyhow::anyhow!("Invalid command for send msg"));
27 }
28 };
29
30 println!(
32 "Sending {} command for order {} to mostro pubId {}",
33 requested_action,
34 order_id.unwrap(),
35 ctx.mostro_pubkey
36 );
37
38 let payload = match requested_action {
40 Action::FiatSent | Action::Release => create_next_trade_payload(ctx, &order_id).await?,
41 _ => text.map(|t| Payload::TextMessage(t.to_string())),
42 };
43 if let Some(Payload::NextTrade(_, trade_index)) = &payload {
45 match User::get(&ctx.pool).await {
47 Ok(mut user) => {
48 user.set_last_trade_index(*trade_index as i64);
49 if let Err(e) = user.save(&ctx.pool).await {
50 println!("Failed to update user: {}", e);
51 }
52 }
53 Err(e) => println!("Failed to get user: {}", e),
54 }
55 }
56
57 let request_id = Uuid::new_v4().as_u128() as u64;
59
60 let message = Message::new_order(order_id, Some(request_id), None, requested_action, payload);
62
63 if let Some(order_id) = order_id {
64 let order = Order::get_by_id(&ctx.pool, &order_id.to_string()).await?;
65
66 if let Some(trade_keys_str) = order.trade_keys.clone() {
67 let trade_keys = Keys::parse(&trade_keys_str)?;
68
69 let message_json = message
71 .as_json()
72 .map_err(|e| anyhow::anyhow!("Failed to serialize message: {e}"))?;
73
74 let sent_message = send_dm(
76 &ctx.client,
77 Some(&ctx.identity_keys),
78 &trade_keys,
79 &ctx.mostro_pubkey,
80 message_json,
81 None,
82 false,
83 );
84
85 let recv_event = wait_for_dm(ctx, Some(&trade_keys), sent_message).await?;
87
88 print_dm_events(recv_event, request_id, ctx, Some(&trade_keys)).await?;
90 }
91 }
92 Ok(())
93}
94
95async fn create_next_trade_payload(
96 ctx: &Context,
97 order_id: &Option<Uuid>,
98) -> Result<Option<Payload>> {
99 if let Some(order_id) = order_id {
100 let order = Order::get_by_id(&ctx.pool, &order_id.to_string()).await?;
101
102 if let (Some(_), Some(min_amount), Some(max_amount)) =
103 (order.is_mine, order.min_amount, order.max_amount)
104 {
105 if max_amount - order.fiat_amount >= min_amount {
106 let (trade_keys, trade_index) = User::get_next_trade_keys(&ctx.pool).await?;
107 return Ok(Some(Payload::NextTrade(
108 trade_keys.public_key().to_string(),
109 trade_index.try_into()?,
110 )));
111 }
112 }
113 }
114 Ok(None)
115}