mostro_client/cli/
send_msg.rs

1use crate::db::{Order, User};
2use crate::util::send_message_sync;
3use crate::{cli::Commands, db::connect};
4
5use anyhow::Result;
6use log::info;
7use mostro_core::message::{Action, Message, Payload};
8use nostr_sdk::prelude::*;
9use std::process;
10use uuid::Uuid;
11
12pub async fn execute_send_msg(
13    command: Commands,
14    order_id: Option<Uuid>,
15    identity_keys: Option<&Keys>,
16    mostro_key: PublicKey,
17    client: &Client,
18    text: Option<&str>,
19) -> Result<()> {
20    // Get desised action based on command from CLI
21    let requested_action = match command {
22        Commands::FiatSent { order_id: _ } => Action::FiatSent,
23        Commands::Release { order_id: _ } => Action::Release,
24        Commands::Cancel { order_id: _ } => Action::Cancel,
25        Commands::Dispute { order_id: _ } => Action::Dispute,
26        Commands::AdmCancel { order_id: _ } => Action::AdminCancel,
27        Commands::AdmSettle { order_id: _ } => Action::AdminSettle,
28        Commands::AdmAddSolver { npubkey: _ } => Action::AdminAddSolver,
29        _ => {
30            println!("Not a valid command!");
31            process::exit(0);
32        }
33    };
34
35    println!(
36        "Sending {} command for order {:?} to mostro pubId {}",
37        requested_action,
38        order_id,
39        mostro_key.clone()
40    );
41    let mut payload = None;
42    if let Some(t) = text {
43        payload = Some(Payload::TextMessage(t.to_string()));
44    }
45    let request_id = Uuid::new_v4().as_u128() as u64;
46
47    // Create message
48    let message = Message::new_order(order_id, Some(request_id), None, requested_action, payload);
49    info!("Sending message: {:#?}", message);
50
51    let pool = connect().await?;
52    let order = Order::get_by_id(&pool, &order_id.unwrap().to_string()).await;
53    match order {
54        Ok(order) => {
55            if let Some(trade_keys_str) = order.trade_keys {
56                let trade_keys = Keys::parse(&trade_keys_str)?;
57                let dm = send_message_sync(
58                    client,
59                    identity_keys,
60                    &trade_keys,
61                    mostro_key,
62                    message,
63                    true,
64                    false,
65                )
66                .await?;
67                let new_order = dm
68                    .iter()
69                    .find_map(|el| {
70                        let message = el.0.get_inner_message_kind();
71                        if message.request_id == Some(request_id) {
72                            match message.action {
73                                Action::NewOrder => {
74                                    if let Some(Payload::Order(order)) = message.payload.as_ref() {
75                                        return Some(order);
76                                    }
77                                }
78                                _ => {
79                                    return None;
80                                }
81                            }
82                        }
83                        None
84                    })
85                    .or_else(|| {
86                        println!("Error: No matching order found in response");
87                        None
88                    });
89
90                if let Some(order) = new_order {
91                    println!("Order id {} created", order.id.unwrap());
92                    // Create order in db
93                    let pool = connect().await?;
94                    let (trade_keys, trade_index) = User::get_next_trade_keys(&pool).await?;
95                    let db_order =
96                        Order::new(&pool, order.clone(), &trade_keys, Some(request_id as i64))
97                            .await
98                            .map_err(|e| anyhow::anyhow!("Failed to create DB order: {:?}", e))?;
99                    let _ = db_order.id.clone().ok_or(anyhow::anyhow!(
100                        "Failed getting new order from Mostro. Missing order id"
101                    ))?;
102                    // Update last trade index
103                    match User::get(&pool).await {
104                        Ok(mut user) => {
105                            user.set_last_trade_index(trade_index);
106                            if let Err(e) = user.save(&pool).await {
107                                println!("Failed to update user: {}", e);
108                            }
109                        }
110                        Err(e) => println!("Failed to get user: {}", e),
111                    }
112                    // Now we send a message to Mostro letting it know the trade key and
113                    // trade index for this new order
114                    let message = Message::new_order(
115                        Some(order.id.unwrap()),
116                        None,
117                        Some(trade_index),
118                        Action::TradePubkey,
119                        None,
120                    );
121                    let _ = send_message_sync(
122                        client,
123                        identity_keys,
124                        &trade_keys,
125                        mostro_key,
126                        message,
127                        false,
128                        false,
129                    )
130                    .await?;
131                }
132            } else {
133                println!("Error: Missing trade keys for order {}", order_id.unwrap());
134            }
135        }
136        Err(e) => {
137            println!("Error: {}", e);
138        }
139    }
140
141    Ok(())
142}