1use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6use super::LNBitsEndpoint;
7
8#[derive(Debug, Deserialize)]
10pub struct CreateInvoiceResponse {
11 payment_hash: String,
13 bolt11: String,
15}
16
17impl CreateInvoiceResponse {
18 pub fn payment_hash(&self) -> &str {
20 &self.payment_hash
21 }
22
23 pub fn bolt11(&self) -> &str {
25 &self.bolt11
26 }
27}
28
29#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize)]
31pub struct PayInvoiceResponse {
32 pub payment_hash: String,
34}
35
36#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
38pub struct CreateInvoiceRequest {
39 pub amount: u64,
41 pub unit: String,
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub memo: Option<String>,
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub expiry: Option<u64>,
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub internal: Option<bool>,
52 pub out: bool,
54}
55
56#[derive(Debug, Clone, PartialEq, Deserialize)]
58pub struct DecodeInvoiceResponse {
59 pub payment_hash: String,
61 pub amount_msat: i64,
63 pub description: String,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub description_hash: Option<String>,
68 pub payee: String,
70 pub date: i64,
72 pub expiry: f64,
74 pub secret: String,
76 pub route_hints: Vec<String>,
78 pub min_final_cltv_expiry: i64,
80}
81
82impl crate::LNBitsClient {
83 pub async fn create_invoice(
85 &self,
86 params: &CreateInvoiceRequest,
87 ) -> Result<CreateInvoiceResponse> {
88 let body = self
89 .make_post(
90 LNBitsEndpoint::Payments,
91 crate::api::LNBitsRequestKey::InvoiceRead,
92 &serde_json::to_string(¶ms)?,
93 )
94 .await?;
95
96 match serde_json::from_str(&body) {
97 Ok(res) => Ok(res),
98 Err(_) => {
99 log::error!("Api error response on invoice creation");
100 log::error!("{}", body);
101 bail!("Could not create invoice")
102 }
103 }
104 }
105
106 pub async fn pay_invoice(
108 &self,
109 bolt11: &str,
110 _amount_sats: Option<u64>,
111 ) -> Result<PayInvoiceResponse> {
112 let body = self
113 .make_post(
114 LNBitsEndpoint::Payments,
115 crate::api::LNBitsRequestKey::Admin,
116 &serde_json::to_string(&serde_json::json!({ "out": true, "bolt11": bolt11 }))?,
117 )
118 .await?;
119
120 match serde_json::from_str(&body) {
121 Ok(res) => Ok(res),
122 Err(_) => {
123 log::error!("Api error response on paying invoice");
124 log::error!("{}", body);
125 bail!("Could not pay invoice")
126 }
127 }
128 }
129
130 pub async fn decode_invoice(&self, invoice: &str) -> Result<DecodeInvoiceResponse> {
132 let body = self
133 .make_post(
134 LNBitsEndpoint::PaymentsDecode,
135 crate::api::LNBitsRequestKey::Admin,
136 &serde_json::to_string(&serde_json::json!({ "data": invoice }))?,
137 )
138 .await?;
139
140 match serde_json::from_str(&body) {
141 Ok(res) => Ok(res),
142 Err(_) => {
143 log::error!("Api error response decode invoice");
144 log::error!("{}", body);
145 bail!("Could not decode invoice")
146 }
147 }
148 }
149
150 pub async fn is_invoice_paid(&self, payment_hash: &str) -> Result<bool> {
152 let body = self
153 .make_get(
154 LNBitsEndpoint::PaymentHash(payment_hash.to_string()),
155 crate::api::LNBitsRequestKey::Admin,
156 )
157 .await?;
158
159 let invoice_result: serde_json::Value = serde_json::from_str(&body)?;
160 Ok(invoice_result["paid"].as_bool().unwrap_or(false))
161 }
162}