phoenixd_rs/
invoice.rs

1//! Handle invoice
2
3use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6use crate::Phoenixd;
7
8/// Invoice Request
9#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct InvoiceRequest {
12    /// Correlation ID
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub external_id: Option<String>,
15    /// Invoice description
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub description: Option<String>,
18    /// description Hash
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub description_hash: Option<String>,
21    /// Invoice Amount in sats
22    pub amount_sat: u64,
23    /// webhook Url
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub webhook_url: Option<String>,
26}
27
28/// Invoice Response
29#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
30#[serde(rename_all = "camelCase")]
31pub struct InvoiceResponse {
32    /// Invoice Amount in sat
33    pub amount_sat: u64,
34    /// Payment Hash
35    pub payment_hash: String,
36    /// Bolt11
37    pub serialized: String,
38}
39
40/// Find Incoming Response
41#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
42#[serde(rename_all = "camelCase")]
43pub struct GetIncomingInvoiceResponse {
44    /// Payment Hash
45    pub payment_hash: String,
46    /// Preimage
47    pub preimage: String,
48    /// External Id
49    pub external_id: Option<String>,
50    /// Description
51    pub description: String,
52    /// Bolt11 invoice
53    pub invoice: String,
54    /// Paid flag
55    pub is_paid: bool,
56    /// Sats received
57    pub received_sat: u64,
58    /// Fees
59    pub fees: u64,
60    /// Completed at
61    pub completed_at: Option<u64>,
62    /// Time created
63    pub created_at: u64,
64}
65
66impl Phoenixd {
67    /// Create Invoice
68    pub async fn create_invoice(&self, invoice_request: InvoiceRequest) -> Result<InvoiceResponse> {
69        let url = self.api_url.join("/createinvoice")?;
70
71        let res = self
72            .make_post(url, Some(serde_json::to_value(invoice_request)?))
73            .await?;
74
75        match serde_json::from_value(res.clone()) {
76            Ok(res) => Ok(res),
77            Err(_) => {
78                log::error!("Api error response on invoice creation");
79                log::error!("{}", res);
80                bail!("Could not create invoice")
81            }
82        }
83    }
84
85    /// Find incoming invoice
86    pub async fn get_incoming_invoice(
87        &self,
88        payment_hash: &str,
89    ) -> Result<GetIncomingInvoiceResponse> {
90        let url = self
91            .api_url
92            .join(&format!("payments/incoming/{}", payment_hash))?;
93
94        let res = self.make_get(url).await?;
95
96        match serde_json::from_value(res.clone()) {
97            Ok(res) => Ok(res),
98            Err(err) => {
99                log::error!("Api error response on find invoice");
100                log::error!("{}", err);
101                log::error!("{}", res);
102                bail!("Could not find incoming invoice")
103            }
104        }
105    }
106}