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