mostro_client/cli/
take_order.rs1use anyhow::Result;
2use lnurl::lightning_address::LightningAddress;
3use mostro_core::prelude::*;
4use std::str::FromStr;
5use uuid::Uuid;
6
7use crate::cli::Context;
8use crate::lightning::is_valid_invoice;
9use crate::parser::common::{
10 create_emoji_field_row, create_field_value_header, create_standard_table,
11};
12use crate::util::{print_dm_events, send_dm, wait_for_dm};
13
14fn create_take_order_payload(
16 action: Action,
17 invoice: &Option<String>,
18 amount: Option<u32>,
19) -> Result<Option<Payload>> {
20 match action {
21 Action::TakeBuy => Ok(amount.map(|amt: u32| Payload::Amount(amt as i64))),
22 Action::TakeSell => Ok(Some(match invoice {
23 Some(inv) => {
24 let initial_payload = match LightningAddress::from_str(inv) {
25 Ok(_) => Payload::PaymentRequest(None, inv.to_string(), None),
26 Err(_) => match is_valid_invoice(inv) {
27 Ok(i) => Payload::PaymentRequest(None, i.to_string(), None),
28 Err(e) => {
29 println!("{}", e);
30 Payload::PaymentRequest(None, inv.to_string(), None)
31 }
32 },
33 };
34
35 match amount {
36 Some(amt) => match initial_payload {
37 Payload::PaymentRequest(a, b, _) => {
38 Payload::PaymentRequest(a, b, Some(amt as i64))
39 }
40 payload => payload,
41 },
42 None => initial_payload,
43 }
44 }
45 None => amount
46 .map(|amt| Payload::Amount(amt.into()))
47 .unwrap_or(Payload::Amount(0)),
48 })),
49 _ => Err(anyhow::anyhow!("Invalid action for take order")),
50 }
51}
52
53#[allow(clippy::too_many_arguments)]
55pub async fn execute_take_order(
56 order_id: &Uuid,
57 action: Action,
58 invoice: &Option<String>,
59 amount: Option<u32>,
60 ctx: &Context,
61) -> Result<()> {
62 let action_name = match action {
63 Action::TakeBuy => "take buy",
64 Action::TakeSell => "take sell",
65 _ => return Err(anyhow::anyhow!("Invalid action for take order")),
66 };
67
68 println!("🛒 Take Order");
69 println!("═══════════════════════════════════════");
70 let mut table = create_standard_table();
71 table.set_header(create_field_value_header());
72 table.add_row(create_emoji_field_row("📈 ", "Action", action_name));
73 table.add_row(create_emoji_field_row(
74 "📋 ",
75 "Order ID",
76 &order_id.to_string(),
77 ));
78 if let Some(inv) = invoice {
79 table.add_row(create_emoji_field_row("⚡ ", "Invoice", inv));
80 }
81 if let Some(amt) = amount {
82 table.add_row(create_emoji_field_row(
83 "💰 ",
84 "Amount (sats)",
85 &amt.to_string(),
86 ));
87 }
88 table.add_row(create_emoji_field_row(
89 "🎯 ",
90 "Mostro PubKey",
91 &ctx.mostro_pubkey.to_string(),
92 ));
93 println!("{table}");
94 println!("💡 Taking order from Mostro...\n");
95
96 let payload = create_take_order_payload(action.clone(), invoice, amount)?;
98
99 let request_id = Uuid::new_v4().as_u128() as u64;
101
102 let take_order_message = Message::new_order(
104 Some(*order_id),
105 Some(request_id),
106 Some(ctx.trade_index),
107 action.clone(),
108 payload,
109 );
110
111 println!("📤 Sending Message");
113 println!("─────────────────────────────────────");
114 println!("🔢 Trade Index: {}", ctx.trade_index);
115 println!("🔑 Trade Keys: {}", ctx.trade_keys.public_key().to_hex());
116 println!("💡 Sending DM to Mostro...");
117 println!();
118
119 let message_json = take_order_message
120 .as_json()
121 .map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
122
123 let sent_message = send_dm(
126 &ctx.client,
127 Some(&ctx.identity_keys),
128 &ctx.trade_keys,
129 &ctx.mostro_pubkey,
130 message_json,
131 None,
132 false,
133 );
134
135 let recv_event = wait_for_dm(ctx, None, sent_message).await?;
137
138 print_dm_events(recv_event, request_id, ctx, None).await?;
140
141 Ok(())
142}