use base64::prelude::*;
use serde::{Deserialize, Serialize};
use super::OnchainAddressType;
#[derive(Debug, thiserror::Error)]
pub enum LndInvoiceError {
#[error("Base64Error: {0}")]
Base64Error(#[from] base64::DecodeError),
#[error("String Error: {0}")]
FormatError(#[from] std::fmt::Error),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "UPPERCASE")]
pub enum LndInvoiceState {
Open,
Settled,
Canceled,
Accepted,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct LndPaymentInvoice {
pub r_hash: String,
pub payment_request: String,
pub add_index: String,
pub payment_addr: String,
}
impl std::str::FromStr for LndPaymentInvoice {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl TryFrom<LndPaymentInvoice> for String {
type Error = serde_json::Error;
fn try_from(value: LndPaymentInvoice) -> Result<Self, Self::Error> {
serde_json::to_string(&value)
}
}
impl LndPaymentInvoice {
pub fn r_hash_url_safe(&self) -> Result<String, base64::DecodeError> {
BASE64_STANDARD
.decode(&self.r_hash)
.map(|unsafe_str| BASE64_URL_SAFE.encode(unsafe_str))
}
pub fn r_hash_hex(&self) -> Result<String, LndInvoiceError> {
use std::fmt::Write;
BASE64_STANDARD.decode(&self.r_hash).map(|unsafe_str| {
unsafe_str.iter().try_fold(String::new(), |mut acc, b| {
write!(acc, "{b:02x}")?;
Ok(acc)
})
})?
}
pub fn payment_hash(&self) -> Result<Vec<u8>, LndInvoiceError> {
Ok(BASE64_STANDARD.decode(&self.payment_addr)?)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct LndInvoice {
pub r_preimage: String,
pub r_hash: String,
pub payment_request: String,
pub add_index: String,
pub payment_addr: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub memo: Option<String>,
pub value: String,
pub value_msat: String,
pub settled: bool,
pub creation_date: String,
pub settle_date: String,
pub state: LndInvoiceState,
}
impl std::str::FromStr for LndInvoice {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl TryFrom<LndInvoice> for String {
type Error = serde_json::Error;
fn try_from(value: LndInvoice) -> Result<Self, Self::Error> {
serde_json::to_string(&value)
}
}
impl LndInvoice {
#[must_use]
pub fn r_hash_url_safe(&self) -> String {
let unsafe_str = BASE64_STANDARD.decode(&self.r_hash).unwrap_or_default();
BASE64_URL_SAFE.encode(unsafe_str)
}
pub fn r_hash_hex(&self) -> Result<String, LndInvoiceError> {
use std::fmt::Write;
BASE64_STANDARD.decode(&self.r_hash).map(|unsafe_str| {
unsafe_str.iter().try_fold(String::new(), |mut acc, b| {
write!(acc, "{b:02x}")?;
Ok(acc)
})
})?
}
#[must_use]
pub fn payment_hash(&self) -> Vec<u8> {
BASE64_STANDARD
.decode(&self.payment_addr)
.unwrap_or_default()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct LndInvoiceList {
pub invoices: Vec<LndInvoice>,
pub last_index_offset: String,
pub first_index_offset: String,
}
impl std::str::FromStr for LndInvoiceList {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl TryFrom<LndInvoiceList> for String {
type Error = serde_json::Error;
fn try_from(value: LndInvoiceList) -> Result<Self, Self::Error> {
serde_json::to_string(&value)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct LndNewAddress {
pub addr: String,
}
impl std::str::FromStr for LndNewAddress {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl TryFrom<LndNewAddress> for String {
type Error = serde_json::Error;
fn try_from(value: LndNewAddress) -> Result<Self, Self::Error> {
serde_json::to_string(&value)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct LndNextAddressRequest {
account: String,
#[serde(rename = "type")]
address_type: OnchainAddressType,
change: bool,
}
impl std::str::FromStr for LndNextAddressRequest {
type Err = serde_json::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
serde_json::from_str(s)
}
}
impl TryFrom<LndNextAddressRequest> for String {
type Error = serde_json::Error;
fn try_from(value: LndNextAddressRequest) -> Result<Self, Self::Error> {
serde_json::to_string(&value)
}
}
impl Default for LndNextAddressRequest {
fn default() -> Self {
Self {
account: String::new(),
address_type: OnchainAddressType::TaprootPubkey,
change: false,
}
}
}