mostro_client/cli/
add_invoice.rs

1use crate::parser::common::{
2    create_emoji_field_row, create_field_value_header, create_standard_table,
3};
4use crate::util::{print_dm_events, send_dm, wait_for_dm};
5use crate::{cli::Context, db::Order, lightning::is_valid_invoice};
6use anyhow::Result;
7use lnurl::lightning_address::LightningAddress;
8use mostro_core::prelude::*;
9use nostr_sdk::prelude::*;
10use std::str::FromStr;
11use uuid::Uuid;
12
13pub async fn execute_add_invoice(order_id: &Uuid, invoice: &str, ctx: &Context) -> Result<()> {
14    // Get order from order id
15    let order = Order::get_by_id(&ctx.pool, &order_id.to_string()).await?;
16    // Get trade keys of specific order
17    let trade_keys = order
18        .trade_keys
19        .clone()
20        .ok_or(anyhow::anyhow!("Missing trade keys"))?;
21
22    let order_trade_keys = Keys::parse(&trade_keys)?;
23
24    println!("⚡ Add Lightning Invoice");
25    println!("═══════════════════════════════════════");
26
27    let mut table = create_standard_table();
28    table.set_header(create_field_value_header());
29    table.add_row(create_emoji_field_row(
30        "📋 ",
31        "Order ID",
32        &order_id.to_string(),
33    ));
34    table.add_row(create_emoji_field_row(
35        "🔑 ",
36        "Trade Keys",
37        &order_trade_keys.public_key().to_hex(),
38    ));
39    table.add_row(create_emoji_field_row(
40        "🎯 ",
41        "Target",
42        &ctx.mostro_pubkey.to_string(),
43    ));
44    println!("{table}");
45    println!("💡 Sending lightning invoice to Mostro...\n");
46    // Check invoice string
47    let ln_addr = LightningAddress::from_str(invoice);
48    let payload = if ln_addr.is_ok() {
49        Some(Payload::PaymentRequest(None, invoice.to_string(), None))
50    } else {
51        match is_valid_invoice(invoice) {
52            Ok(i) => Some(Payload::PaymentRequest(None, i.to_string(), None)),
53            Err(e) => {
54                return Err(anyhow::anyhow!("Invalid invoice: {}", e));
55            }
56        }
57    };
58
59    // Create request id
60    let request_id = Uuid::new_v4().as_u128() as u64;
61    // Create AddInvoice message
62    let add_invoice_message = Message::new_order(
63        Some(*order_id),
64        Some(request_id),
65        None,
66        Action::AddInvoice,
67        payload,
68    );
69
70    // Serialize the message
71    let message_json = add_invoice_message
72        .as_json()
73        .map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
74
75    // Send the DM
76    let sent_message = send_dm(
77        &ctx.client,
78        Some(&ctx.identity_keys),
79        &order_trade_keys,
80        &ctx.mostro_pubkey,
81        message_json,
82        None,
83        false,
84    );
85
86    // Wait for the DM to be sent from mostro
87    let recv_event = wait_for_dm(ctx, Some(&order_trade_keys), sent_message).await?;
88
89    // Parse the incoming DM
90    print_dm_events(recv_event, request_id, ctx, Some(&order_trade_keys)).await?;
91
92    Ok(())
93}