bright_ln_models/
invoice.rs

1use base64::prelude::*;
2use serde::{Deserialize, Serialize};
3
4use super::OnchainAddressType;
5
6#[derive(Debug, thiserror::Error)]
7pub enum LndInvoiceError {
8    #[error("Base64Error: {0}")]
9    Base64Error(#[from] base64::DecodeError),
10    #[error("String Error: {0}")]
11    FormatError(#[from] std::fmt::Error),
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
15#[serde(rename_all = "UPPERCASE")]
16pub enum LndInvoiceState {
17    Open,
18    Settled,
19    Canceled,
20    Accepted,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
24pub struct LndPaymentInvoice {
25    pub r_hash: String,
26    pub payment_request: String,
27    pub add_index: String,
28    pub payment_addr: String,
29}
30impl std::str::FromStr for LndPaymentInvoice {
31    type Err = serde_json::Error;
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        serde_json::from_str(s)
34    }
35}
36impl TryFrom<LndPaymentInvoice> for String {
37    type Error = serde_json::Error;
38    fn try_from(value: LndPaymentInvoice) -> Result<Self, Self::Error> {
39        serde_json::to_string(&value)
40    }
41}
42impl LndPaymentInvoice {
43    /// Returns the `r_hash` as a base64 url safe string, by decoding the `base_64` string and then encoding it again
44    /// as base64 url safe
45    ///
46    /// # Errors
47    ///
48    /// Will return an error if the base64 string is not valid
49    pub fn r_hash_url_safe(&self) -> Result<String, base64::DecodeError> {
50        BASE64_STANDARD
51            .decode(&self.r_hash)
52            .map(|unsafe_str| BASE64_URL_SAFE.encode(unsafe_str))
53    }
54    /// Returns the `r_hash` as a hex string, by decoding the `base_64` string and then encoding it again
55    /// as hex
56    ///
57    /// # Errors
58    ///
59    /// Will return an error if the base64 string is not valid
60    pub fn r_hash_hex(&self) -> Result<String, LndInvoiceError> {
61        use std::fmt::Write;
62        BASE64_STANDARD.decode(&self.r_hash).map(|unsafe_str| {
63            unsafe_str.iter().try_fold(String::new(), |mut acc, b| {
64                write!(acc, "{b:02x}")?;
65                Ok(acc)
66            })
67        })?
68    }
69
70    /// Returns the payment hash as a byte vector
71    ///
72    /// # Errors
73    ///
74    /// Will return an error if the base64 string is not valid
75    pub fn payment_hash(&self) -> Result<Vec<u8>, LndInvoiceError> {
76        Ok(BASE64_STANDARD.decode(&self.payment_addr)?)
77    }
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
81pub struct LndInvoice {
82    pub r_preimage: String,
83    pub r_hash: String,
84    pub payment_request: String,
85    pub add_index: String,
86    pub payment_addr: String,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub memo: Option<String>,
89    pub value: String,
90    pub value_msat: String,
91    pub settled: bool,
92    pub creation_date: String,
93    pub settle_date: String,
94    pub state: LndInvoiceState,
95}
96impl std::str::FromStr for LndInvoice {
97    type Err = serde_json::Error;
98    fn from_str(s: &str) -> Result<Self, Self::Err> {
99        serde_json::from_str(s)
100    }
101}
102impl TryFrom<LndInvoice> for String {
103    type Error = serde_json::Error;
104    fn try_from(value: LndInvoice) -> Result<Self, Self::Error> {
105        serde_json::to_string(&value)
106    }
107}
108impl LndInvoice {
109    #[must_use]
110    pub fn r_hash_url_safe(&self) -> String {
111        let unsafe_str = BASE64_STANDARD.decode(&self.r_hash).unwrap_or_default();
112
113        BASE64_URL_SAFE.encode(unsafe_str)
114    }
115    /// Returns the `r_hash` as a hex string, by decoding the `base_64` string and then encoding it again
116    /// as hex
117    ///
118    /// # Errors
119    ///
120    /// Will return an error if the base64 string is not valid
121    pub fn r_hash_hex(&self) -> Result<String, LndInvoiceError> {
122        use std::fmt::Write;
123        BASE64_STANDARD.decode(&self.r_hash).map(|unsafe_str| {
124            unsafe_str.iter().try_fold(String::new(), |mut acc, b| {
125                write!(acc, "{b:02x}")?;
126                Ok(acc)
127            })
128        })?
129    }
130    #[must_use]
131    pub fn payment_hash(&self) -> Vec<u8> {
132        BASE64_STANDARD
133            .decode(&self.payment_addr)
134            .unwrap_or_default()
135    }
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
139pub struct LndInvoiceList {
140    pub invoices: Vec<LndInvoice>,
141    pub last_index_offset: String,
142    pub first_index_offset: String,
143}
144impl std::str::FromStr for LndInvoiceList {
145    type Err = serde_json::Error;
146    fn from_str(s: &str) -> Result<Self, Self::Err> {
147        serde_json::from_str(s)
148    }
149}
150impl TryFrom<LndInvoiceList> for String {
151    type Error = serde_json::Error;
152    fn try_from(value: LndInvoiceList) -> Result<Self, Self::Error> {
153        serde_json::to_string(&value)
154    }
155}
156#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
157pub struct LndNewAddress {
158    pub addr: String,
159}
160impl std::str::FromStr for LndNewAddress {
161    type Err = serde_json::Error;
162    fn from_str(s: &str) -> Result<Self, Self::Err> {
163        serde_json::from_str(s)
164    }
165}
166impl TryFrom<LndNewAddress> for String {
167    type Error = serde_json::Error;
168    fn try_from(value: LndNewAddress) -> Result<Self, Self::Error> {
169        serde_json::to_string(&value)
170    }
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
174pub struct LndNextAddressRequest {
175    account: String,
176    #[serde(rename = "type")]
177    address_type: OnchainAddressType,
178    change: bool,
179}
180impl std::str::FromStr for LndNextAddressRequest {
181    type Err = serde_json::Error;
182    fn from_str(s: &str) -> Result<Self, Self::Err> {
183        serde_json::from_str(s)
184    }
185}
186impl TryFrom<LndNextAddressRequest> for String {
187    type Error = serde_json::Error;
188    fn try_from(value: LndNextAddressRequest) -> Result<Self, Self::Error> {
189        serde_json::to_string(&value)
190    }
191}
192impl Default for LndNextAddressRequest {
193    fn default() -> Self {
194        Self {
195            account: String::new(),
196            address_type: OnchainAddressType::TaprootPubkey,
197            change: false,
198        }
199    }
200}