1use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6use crate::Phoenixd;
7
8#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct InvoiceRequest {
12 #[serde(skip_serializing_if = "Option::is_none")]
14 pub external_id: Option<String>,
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub description: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub description_hash: Option<String>,
21 pub amount_sat: u64,
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub webhook_url: Option<String>,
26}
27
28#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
30#[serde(rename_all = "camelCase")]
31pub struct InvoiceResponse {
32 pub amount_sat: u64,
34 pub payment_hash: String,
36 pub serialized: String,
38}
39
40#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
42#[serde(rename_all = "camelCase")]
43pub struct GetIncomingInvoiceResponse {
44 pub payment_hash: String,
46 pub preimage: String,
48 pub external_id: Option<String>,
50 pub description: String,
52 pub invoice: String,
54 pub is_paid: bool,
56 pub received_sat: u64,
58 pub fees: u64,
60 pub completed_at: Option<u64>,
62 pub created_at: u64,
64}
65
66impl Phoenixd {
67 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 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}