use anyhow::{bail, Result};
use serde::{Deserialize, Serialize};
use super::LNBitsEndpoint;
#[derive(Debug, Deserialize)]
pub struct CreateInvoiceResponse {
payment_hash: String,
bolt11: String,
}
impl CreateInvoiceResponse {
pub fn payment_hash(&self) -> &str {
&self.payment_hash
}
pub fn bolt11(&self) -> &str {
&self.bolt11
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize)]
pub struct PayInvoiceResponse {
pub payment_hash: String,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct CreateInvoiceRequest {
pub amount: u64,
pub unit: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expiry: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub internal: Option<bool>,
pub out: bool,
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct DecodeInvoiceResponse {
pub payment_hash: String,
pub amount_msat: i64,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description_hash: Option<String>,
pub payee: String,
pub date: i64,
pub expiry: f64,
pub secret: String,
pub route_hints: Vec<String>,
pub min_final_cltv_expiry: i64,
}
impl crate::LNBitsClient {
pub async fn create_invoice(
&self,
params: &CreateInvoiceRequest,
) -> Result<CreateInvoiceResponse> {
let body = self
.make_post(
LNBitsEndpoint::Payments,
crate::api::LNBitsRequestKey::InvoiceRead,
&serde_json::to_string(¶ms)?,
)
.await?;
match serde_json::from_str(&body) {
Ok(res) => Ok(res),
Err(_) => {
log::error!("Api error response on invoice creation");
log::error!("{}", body);
bail!("Could not create invoice")
}
}
}
pub async fn pay_invoice(
&self,
bolt11: &str,
_amount_sats: Option<u64>,
) -> Result<PayInvoiceResponse> {
let body = self
.make_post(
LNBitsEndpoint::Payments,
crate::api::LNBitsRequestKey::Admin,
&serde_json::to_string(&serde_json::json!({ "out": true, "bolt11": bolt11 }))?,
)
.await?;
match serde_json::from_str(&body) {
Ok(res) => Ok(res),
Err(_) => {
log::error!("Api error response on paying invoice");
log::error!("{}", body);
bail!("Could not pay invoice")
}
}
}
pub async fn decode_invoice(&self, invoice: &str) -> Result<DecodeInvoiceResponse> {
let body = self
.make_post(
LNBitsEndpoint::PaymentsDecode,
crate::api::LNBitsRequestKey::Admin,
&serde_json::to_string(&serde_json::json!({ "data": invoice }))?,
)
.await?;
match serde_json::from_str(&body) {
Ok(res) => Ok(res),
Err(_) => {
log::error!("Api error response decode invoice");
log::error!("{}", body);
bail!("Could not decode invoice")
}
}
}
pub async fn is_invoice_paid(&self, payment_hash: &str) -> Result<bool> {
let body = self
.make_get(
LNBitsEndpoint::PaymentHash(payment_hash.to_string()),
crate::api::LNBitsRequestKey::Admin,
)
.await?;
let invoice_result: serde_json::Value = serde_json::from_str(&body)?;
Ok(invoice_result["paid"].as_bool().unwrap_or(false))
}
}