Skip to main content

cdk_common/
melt.rs

1//! Unified Melt Quote types for melt use-cases.
2
3use serde::de::DeserializeOwned;
4use serde::{Deserialize, Serialize};
5
6use crate::nuts::nut00::KnownMethod;
7use crate::nuts::nut05::{MeltQuoteCustomRequest, MeltQuoteCustomResponse};
8use crate::nuts::nut23::{MeltQuoteBolt11Request, MeltQuoteBolt11Response};
9use crate::nuts::nut25::{MeltQuoteBolt12Request, MeltQuoteBolt12Response};
10use crate::{Amount, CurrencyUnit, MeltQuoteState, PaymentMethod};
11
12/// Melt quote request enum for different types of quotes
13///
14/// This enum represents the different types of melt quote requests
15/// that can be made, either BOLT11, BOLT12, or Custom.
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub enum MeltQuoteRequest {
18    /// Lightning Network BOLT11 invoice request
19    Bolt11(MeltQuoteBolt11Request),
20    /// Lightning Network BOLT12 offer request
21    Bolt12(MeltQuoteBolt12Request),
22    /// Custom payment method request
23    Custom(MeltQuoteCustomRequest),
24}
25
26impl From<MeltQuoteBolt11Request> for MeltQuoteRequest {
27    fn from(request: MeltQuoteBolt11Request) -> Self {
28        MeltQuoteRequest::Bolt11(request)
29    }
30}
31
32impl From<MeltQuoteBolt12Request> for MeltQuoteRequest {
33    fn from(request: MeltQuoteBolt12Request) -> Self {
34        MeltQuoteRequest::Bolt12(request)
35    }
36}
37
38impl From<MeltQuoteCustomRequest> for MeltQuoteRequest {
39    fn from(request: MeltQuoteCustomRequest) -> Self {
40        MeltQuoteRequest::Custom(request)
41    }
42}
43
44impl MeltQuoteRequest {
45    /// Returns the payment method for this request.
46    pub fn method(&self) -> PaymentMethod {
47        match self {
48            Self::Bolt11(_) => PaymentMethod::Known(KnownMethod::Bolt11),
49            Self::Bolt12(_) => PaymentMethod::Known(KnownMethod::Bolt12),
50            Self::Custom(request) => PaymentMethod::from(request.method.as_str()),
51        }
52    }
53}
54
55/// Unified melt quote response for all payment methods
56#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
57#[serde(bound = "Q: Serialize + DeserializeOwned")]
58pub enum MeltQuoteResponse<Q> {
59    /// Bolt11 (Lightning invoice)
60    Bolt11(MeltQuoteBolt11Response<Q>),
61    /// Bolt12 (Offers)
62    Bolt12(MeltQuoteBolt12Response<Q>),
63    /// Custom payment method
64    Custom((PaymentMethod, MeltQuoteCustomResponse<Q>)),
65}
66
67impl<Q> MeltQuoteResponse<Q> {
68    /// Returns the payment method for this response.
69    pub fn method(&self) -> PaymentMethod {
70        match self {
71            Self::Bolt11(_) => PaymentMethod::Known(KnownMethod::Bolt11),
72            Self::Bolt12(_) => PaymentMethod::Known(KnownMethod::Bolt12),
73            Self::Custom((method, _)) => method.clone(),
74        }
75    }
76
77    /// Returns the quote ID.
78    pub fn quote(&self) -> &Q {
79        match self {
80            Self::Bolt11(r) => &r.quote,
81            Self::Bolt12(r) => &r.quote,
82            Self::Custom((_, r)) => &r.quote,
83        }
84    }
85
86    /// Returns the quoted amount.
87    pub fn amount(&self) -> Amount {
88        match self {
89            Self::Bolt11(r) => r.amount,
90            Self::Bolt12(r) => r.amount,
91            Self::Custom((_, r)) => r.amount,
92        }
93    }
94
95    /// Returns the fee reserve.
96    pub fn fee_reserve(&self) -> Amount {
97        match self {
98            Self::Bolt11(r) => r.fee_reserve,
99            Self::Bolt12(r) => r.fee_reserve,
100            Self::Custom((_, r)) => r.fee_reserve,
101        }
102    }
103
104    /// Returns the quote state.
105    pub fn state(&self) -> MeltQuoteState {
106        match self {
107            Self::Bolt11(r) => r.state,
108            Self::Bolt12(r) => r.state,
109            Self::Custom((_, r)) => r.state,
110        }
111    }
112
113    /// Returns the quote expiry timestamp.
114    pub fn expiry(&self) -> u64 {
115        match self {
116            Self::Bolt11(r) => r.expiry,
117            Self::Bolt12(r) => r.expiry,
118            Self::Custom((_, r)) => r.expiry,
119        }
120    }
121
122    /// Returns the payment preimage.
123    pub fn payment_preimage(&self) -> Option<&str> {
124        match self {
125            Self::Bolt11(r) => r.payment_preimage.as_deref(),
126            Self::Bolt12(r) => r.payment_preimage.as_deref(),
127            Self::Custom((_, r)) => r.payment_preimage.as_deref(),
128        }
129    }
130
131    /// Returns the change signatures when present.
132    pub fn change(&self) -> Option<&Vec<crate::BlindSignature>> {
133        match self {
134            Self::Bolt11(r) => r.change.as_ref(),
135            Self::Bolt12(r) => r.change.as_ref(),
136            Self::Custom((_, r)) => r.change.as_ref(),
137        }
138    }
139
140    /// Returns the payment request string when present.
141    pub fn request(&self) -> Option<&str> {
142        match self {
143            Self::Bolt11(r) => r.request.as_deref(),
144            Self::Bolt12(r) => r.request.as_deref(),
145            Self::Custom((_, r)) => r.request.as_deref(),
146        }
147    }
148
149    /// Returns the unit when present.
150    pub fn unit(&self) -> Option<CurrencyUnit> {
151        match self {
152            Self::Bolt11(r) => r.unit.clone(),
153            Self::Bolt12(r) => r.unit.clone(),
154            Self::Custom((_, r)) => r.unit.clone(),
155        }
156    }
157}