mostro_client/cli/
take_sell.rs1use anyhow::Result;
2use lnurl::lightning_address::LightningAddress;
3use mostro_core::error::CantDoReason;
4use mostro_core::message::{Action, Message, Payload};
5use nostr_sdk::prelude::*;
6use std::str::FromStr;
7use uuid::Uuid;
8
9use crate::db::{connect, Order, User};
10use crate::lightning::is_valid_invoice;
11use crate::util::send_message_sync;
12
13#[allow(clippy::too_many_arguments)]
14pub async fn execute_take_sell(
15 order_id: &Uuid,
16 invoice: &Option<String>,
17 amount: Option<u32>,
18 identity_keys: &Keys,
19 trade_keys: &Keys,
20 trade_index: i64,
21 mostro_key: PublicKey,
22 client: &Client,
23) -> Result<()> {
24 println!(
25 "Request of take sell order {} from mostro pubId {}",
26 order_id,
27 mostro_key.clone()
28 );
29
30 let payload = match invoice {
31 Some(inv) => {
32 let initial_payload = match LightningAddress::from_str(&inv) {
33 Ok(_) => Payload::PaymentRequest(None, inv.to_string(), None),
34 Err(_) => match is_valid_invoice(&inv) {
35 Ok(i) => Payload::PaymentRequest(None, i.to_string(), None),
36 Err(e) => {
37 println!("{}", e);
38 Payload::PaymentRequest(None, inv.to_string(), None) }
40 },
41 };
42
43 match amount {
44 Some(amt) => match initial_payload {
45 Payload::PaymentRequest(a, b, _) => {
46 Payload::PaymentRequest(a, b, Some(amt as i64))
47 }
48 payload => payload,
49 },
50 None => initial_payload,
51 }
52 }
53 None => amount
54 .map(|amt| Payload::Amount(amt.into()))
55 .unwrap_or(Payload::Amount(0)),
56 };
57
58 let request_id = Uuid::new_v4().as_u128() as u64;
59 let take_sell_message = Message::new_order(
61 Some(*order_id),
62 Some(request_id),
63 Some(trade_index),
64 Action::TakeSell,
65 Some(payload),
66 );
67
68 let dm = send_message_sync(
69 client,
70 Some(identity_keys),
71 trade_keys,
72 mostro_key,
73 take_sell_message,
74 true,
75 false,
76 )
77 .await?;
78 let pool = connect().await?;
79
80 let order = dm.iter().find_map(|el| {
81 let message = el.0.get_inner_message_kind();
82 if message.request_id == Some(request_id) {
83 match message.action {
84 Action::AddInvoice => {
85 if let Some(Payload::Order(order)) = message.payload.as_ref() {
86 println!(
87 "Please add a lightning invoice with amount of {}",
88 order.amount
89 );
90 return Some(order.clone());
91 }
92 }
93 Action::CantDo => {
94 if let Some(Payload::CantDo(Some(cant_do_reason))) = &message.payload {
95 match cant_do_reason {
96 CantDoReason::OutOfRangeFiatAmount | CantDoReason::OutOfRangeSatsAmount => {
97 println!("Error: Amount is outside the allowed range. Please check the order's min/max limits.");
98 }
99 _ => {
100 println!("Unknown reason: {:?}", message.payload);
101 }
102 }
103 } else {
104 println!("Unknown reason: {:?}", message.payload);
105 return None;
106 }
107 }
108 _ => {
109 println!("Unknown action: {:?}", message.action);
110 return None;
111 }
112 }
113 }
114 None
115 });
116 if let Some(o) = order {
117 if let Ok(order) = Order::new(&pool, o, trade_keys, Some(request_id as i64)).await {
118 if let Some(order_id) = order.id {
119 println!("Order {} created", order_id);
120 } else {
121 println!("Warning: The newly created order has no ID.");
122 }
123 match User::get(&pool).await {
125 Ok(mut user) => {
126 user.set_last_trade_index(trade_index);
127 if let Err(e) = user.save(&pool).await {
128 println!("Failed to update user: {}", e);
129 }
130 }
131 Err(e) => println!("Failed to get user: {}", e),
132 }
133 }
134 }
135
136 Ok(())
137}