cdk_common/
lightning.rs

1//! CDK Mint Lightning
2
3use std::pin::Pin;
4
5use async_trait::async_trait;
6use futures::Stream;
7use lightning_invoice::{Bolt11Invoice, ParseOrSemanticError};
8use serde::{Deserialize, Serialize};
9use thiserror::Error;
10
11use crate::nuts::{CurrencyUnit, MeltQuoteBolt11Request, MeltQuoteState, MintQuoteState};
12use crate::{mint, Amount};
13
14/// CDK Lightning Error
15#[derive(Debug, Error)]
16pub enum Error {
17    /// Invoice already paid
18    #[error("Invoice already paid")]
19    InvoiceAlreadyPaid,
20    /// Invoice pay pending
21    #[error("Invoice pay is pending")]
22    InvoicePaymentPending,
23    /// Unsupported unit
24    #[error("Unsupported unit")]
25    UnsupportedUnit,
26    /// Payment state is unknown
27    #[error("Payment state is unknown")]
28    UnknownPaymentState,
29    /// Lightning Error
30    #[error(transparent)]
31    Lightning(Box<dyn std::error::Error + Send + Sync>),
32    /// Serde Error
33    #[error(transparent)]
34    Serde(#[from] serde_json::Error),
35    /// AnyHow Error
36    #[error(transparent)]
37    Anyhow(#[from] anyhow::Error),
38    /// Parse Error
39    #[error(transparent)]
40    Parse(#[from] ParseOrSemanticError),
41    /// Amount Error
42    #[error(transparent)]
43    Amount(#[from] crate::amount::Error),
44    /// NUT05 Error
45    #[error(transparent)]
46    NUT05(#[from] crate::nuts::nut05::Error),
47}
48
49/// MintLighting Trait
50#[async_trait]
51pub trait MintLightning {
52    /// Mint Lightning Error
53    type Err: Into<Error> + From<Error>;
54
55    /// Base Unit
56    fn get_settings(&self) -> Settings;
57
58    /// Create a new invoice
59    async fn create_invoice(
60        &self,
61        amount: Amount,
62        unit: &CurrencyUnit,
63        description: String,
64        unix_expiry: u64,
65    ) -> Result<CreateInvoiceResponse, Self::Err>;
66
67    /// Get payment quote
68    /// Used to get fee and amount required for a payment request
69    async fn get_payment_quote(
70        &self,
71        melt_quote_request: &MeltQuoteBolt11Request,
72    ) -> Result<PaymentQuoteResponse, Self::Err>;
73
74    /// Pay bolt11 invoice
75    async fn pay_invoice(
76        &self,
77        melt_quote: mint::MeltQuote,
78        partial_amount: Option<Amount>,
79        max_fee_amount: Option<Amount>,
80    ) -> Result<PayInvoiceResponse, Self::Err>;
81
82    /// Listen for invoices to be paid to the mint
83    /// Returns a stream of request_lookup_id once invoices are paid
84    async fn wait_any_invoice(
85        &self,
86    ) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err>;
87
88    /// Is wait invoice active
89    fn is_wait_invoice_active(&self) -> bool;
90
91    /// Cancel wait invoice
92    fn cancel_wait_invoice(&self);
93
94    /// Check the status of an incoming payment
95    async fn check_incoming_invoice_status(
96        &self,
97        request_lookup_id: &str,
98    ) -> Result<MintQuoteState, Self::Err>;
99
100    /// Check the status of an outgoing payment
101    async fn check_outgoing_payment(
102        &self,
103        request_lookup_id: &str,
104    ) -> Result<PayInvoiceResponse, Self::Err>;
105}
106
107/// Create invoice response
108#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
109pub struct CreateInvoiceResponse {
110    /// Id that is used to look up the invoice from the ln backend
111    pub request_lookup_id: String,
112    /// Bolt11 payment request
113    pub request: Bolt11Invoice,
114    /// Unix Expiry of Invoice
115    pub expiry: Option<u64>,
116}
117
118/// Pay invoice response
119#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
120pub struct PayInvoiceResponse {
121    /// Payment hash
122    pub payment_lookup_id: String,
123    /// Payment Preimage
124    pub payment_preimage: Option<String>,
125    /// Status
126    pub status: MeltQuoteState,
127    /// Total Amount Spent
128    pub total_spent: Amount,
129    /// Unit of total spent
130    pub unit: CurrencyUnit,
131}
132
133/// Payment quote response
134#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
135pub struct PaymentQuoteResponse {
136    /// Request look up id
137    pub request_lookup_id: String,
138    /// Amount
139    pub amount: Amount,
140    /// Fee required for melt
141    pub fee: Amount,
142    /// Status
143    pub state: MeltQuoteState,
144}
145
146/// Ln backend settings
147#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
148pub struct Settings {
149    /// MPP supported
150    pub mpp: bool,
151    /// Base unit of backend
152    pub unit: CurrencyUnit,
153    /// Invoice Description supported
154    pub invoice_description: bool,
155}