mostro_client/cli/
add_invoice.rs

1use crate::db::connect;
2use crate::util::send_message_sync;
3use crate::{db::Order, lightning::is_valid_invoice};
4use anyhow::Result;
5use lnurl::lightning_address::LightningAddress;
6use mostro_core::prelude::*;
7use nostr_sdk::prelude::*;
8use std::str::FromStr;
9use uuid::Uuid;
10
11pub async fn execute_add_invoice(
12    order_id: &Uuid,
13    invoice: &str,
14    identity_keys: &Keys,
15    mostro_key: PublicKey,
16    client: &Client,
17) -> Result<()> {
18    let pool = connect().await?;
19    let mut order = Order::get_by_id(&pool, &order_id.to_string()).await?;
20    let trade_keys = order
21        .trade_keys
22        .clone()
23        .ok_or(anyhow::anyhow!("Missing trade keys"))?;
24    let trade_keys = Keys::parse(&trade_keys)?;
25
26    println!(
27        "Sending a lightning invoice {} to mostro pubId {}",
28        order_id, mostro_key
29    );
30    // Check invoice string
31    let ln_addr = LightningAddress::from_str(invoice);
32    let payload = if ln_addr.is_ok() {
33        Some(Payload::PaymentRequest(None, invoice.to_string(), None))
34    } else {
35        match is_valid_invoice(invoice) {
36            Ok(i) => Some(Payload::PaymentRequest(None, i.to_string(), None)),
37            Err(e) => {
38                println!("Invalid invoice: {}", e);
39                None
40            }
41        }
42    };
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    let dm = send_message_sync(
54        client,
55        Some(identity_keys),
56        &trade_keys,
57        mostro_key,
58        add_invoice_message,
59        true,
60        false,
61    )
62    .await?;
63
64    dm.iter().for_each(|el| {
65        let message = el.0.get_inner_message_kind();
66        if message.request_id == Some(request_id) && message.action == Action::WaitingSellerToPay {
67            println!("Now we should wait for the seller to pay the invoice");
68        }
69    });
70    match order
71        .set_status(Status::WaitingPayment.to_string())
72        .save(&pool)
73        .await
74    {
75        Ok(_) => println!("Order status updated"),
76        Err(e) => println!("Failed to update order status: {}", e),
77    }
78
79    Ok(())
80}