mostro_client/cli/
add_invoice.rs

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