1use serde::de::DeserializeOwned;
3use serde::{Deserialize, Serialize};
4
5use super::PublicKey;
6use crate::nut00::KnownMethod;
7use crate::nut25::MeltQuoteBolt12Response;
8use crate::nuts::{
9 CurrencyUnit, MeltQuoteBolt11Response, MeltQuoteCustomResponse, MintQuoteBolt11Response,
10 MintQuoteCustomResponse, PaymentMethod, ProofState,
11};
12use crate::quote_id::QuoteIdError;
13use crate::MintQuoteBolt12Response;
14
15pub mod ws;
16
17#[derive(Debug, Clone, Serialize, Eq, PartialEq, Hash, Deserialize)]
19#[serde(bound = "I: DeserializeOwned + Serialize")]
20pub struct Params<I> {
21 pub kind: Kind,
23 pub filters: Vec<String>,
25 #[serde(rename = "subId")]
27 pub id: I,
28}
29
30#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
32#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
33pub struct SupportedSettings {
34 pub supported: Vec<SupportedMethods>,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
40#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
41pub struct SupportedMethods {
42 pub method: PaymentMethod,
44 pub unit: CurrencyUnit,
46 pub commands: Vec<WsCommand>,
48}
49
50impl SupportedMethods {
51 pub fn new(method: PaymentMethod, unit: CurrencyUnit, commands: Vec<WsCommand>) -> Self {
53 Self {
54 method,
55 unit,
56 commands,
57 }
58 }
59
60 pub fn default_bolt11(unit: CurrencyUnit) -> Self {
62 let commands = vec![
63 WsCommand::Bolt11MintQuote,
64 WsCommand::Bolt11MeltQuote,
65 WsCommand::ProofState,
66 ];
67
68 Self {
69 method: PaymentMethod::Known(KnownMethod::Bolt11),
70 unit,
71 commands,
72 }
73 }
74
75 pub fn default_bolt12(unit: CurrencyUnit) -> Self {
77 let commands = vec![
78 WsCommand::Bolt12MintQuote,
79 WsCommand::Bolt12MeltQuote,
80 WsCommand::ProofState,
81 ];
82
83 Self {
84 method: PaymentMethod::Known(KnownMethod::Bolt12),
85 unit,
86 commands,
87 }
88 }
89
90 pub fn default_custom(method: PaymentMethod, unit: CurrencyUnit) -> Self {
92 let method_name = method.to_string();
93 let commands = vec![
94 WsCommand::Custom(format!("{}_mint_quote", method_name)),
95 WsCommand::Custom(format!("{}_melt_quote", method_name)),
96 WsCommand::ProofState,
97 ];
98
99 Self {
100 method,
101 unit,
102 commands,
103 }
104 }
105}
106
107impl WsCommand {
108 pub fn custom_mint_quote(method: &str) -> Self {
110 WsCommand::Custom(format!("{}_mint_quote", method))
111 }
112
113 pub fn custom_melt_quote(method: &str) -> Self {
115 WsCommand::Custom(format!("{}_melt_quote", method))
116 }
117}
118
119#[derive(Debug, Clone, PartialEq, Eq, Hash)]
121#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
122pub enum WsCommand {
123 Bolt11MintQuote,
125 Bolt11MeltQuote,
127 Bolt12MintQuote,
129 Bolt12MeltQuote,
131 ProofState,
133 Custom(String),
135}
136
137impl Serialize for WsCommand {
138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139 where
140 S: serde::Serializer,
141 {
142 let s = match self {
143 WsCommand::Bolt11MintQuote => "bolt11_mint_quote",
144 WsCommand::Bolt11MeltQuote => "bolt11_melt_quote",
145 WsCommand::Bolt12MintQuote => "bolt12_mint_quote",
146 WsCommand::Bolt12MeltQuote => "bolt12_melt_quote",
147 WsCommand::ProofState => "proof_state",
148 WsCommand::Custom(custom) => custom.as_str(),
149 };
150 serializer.serialize_str(s)
151 }
152}
153
154impl<'de> Deserialize<'de> for WsCommand {
155 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
156 where
157 D: serde::Deserializer<'de>,
158 {
159 let s = String::deserialize(deserializer)?;
160 Ok(match s.as_str() {
161 "bolt11_mint_quote" => WsCommand::Bolt11MintQuote,
162 "bolt11_melt_quote" => WsCommand::Bolt11MeltQuote,
163 "bolt12_mint_quote" => WsCommand::Bolt12MintQuote,
164 "bolt12_melt_quote" => WsCommand::Bolt12MeltQuote,
165 "proof_state" => WsCommand::ProofState,
166 custom => WsCommand::Custom(custom.to_string()),
167 })
168 }
169}
170
171impl<T> From<MintQuoteBolt12Response<T>> for NotificationPayload<T>
172where
173 T: Clone,
174{
175 fn from(mint_quote: MintQuoteBolt12Response<T>) -> NotificationPayload<T> {
176 NotificationPayload::MintQuoteBolt12Response(mint_quote)
177 }
178}
179
180impl<T> From<MeltQuoteBolt12Response<T>> for NotificationPayload<T>
181where
182 T: Clone,
183{
184 fn from(melt_quote: MeltQuoteBolt12Response<T>) -> NotificationPayload<T> {
185 NotificationPayload::MeltQuoteBolt12Response(melt_quote)
186 }
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190#[serde(bound = "T: Serialize + DeserializeOwned")]
191#[serde(untagged)]
192pub enum NotificationPayload<T>
194where
195 T: Clone,
196{
197 ProofState(ProofState),
199 MeltQuoteBolt11Response(MeltQuoteBolt11Response<T>),
201 MintQuoteBolt11Response(MintQuoteBolt11Response<T>),
203 MintQuoteBolt12Response(MintQuoteBolt12Response<T>),
205 MeltQuoteBolt12Response(MeltQuoteBolt12Response<T>),
207 CustomMintQuoteResponse(String, MintQuoteCustomResponse<T>),
209 CustomMeltQuoteResponse(String, MeltQuoteCustomResponse<T>),
211}
212
213#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Hash, Serialize)]
214#[serde(bound = "T: Serialize + DeserializeOwned")]
215pub enum NotificationId<T>
217where
218 T: Clone,
219{
220 ProofState(PublicKey),
222 MeltQuoteBolt11(T),
224 MintQuoteBolt11(T),
226 MintQuoteBolt12(T),
228 MeltQuoteBolt12(T),
230 MintQuoteCustom(String, T),
232 MeltQuoteCustom(String, T),
234}
235
236#[derive(Debug, Clone, Eq, Ord, PartialOrd, PartialEq, Hash)]
238pub enum Kind {
239 Bolt11MeltQuote,
241 Bolt11MintQuote,
243 ProofState,
245 Bolt12MintQuote,
247 Bolt12MeltQuote,
249 Custom(String),
251}
252
253impl Serialize for Kind {
254 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
255 where
256 S: serde::Serializer,
257 {
258 let s = match self {
259 Kind::Bolt11MintQuote => "bolt11_mint_quote",
260 Kind::Bolt11MeltQuote => "bolt11_melt_quote",
261 Kind::Bolt12MintQuote => "bolt12_mint_quote",
262 Kind::Bolt12MeltQuote => "bolt12_melt_quote",
263 Kind::ProofState => "proof_state",
264 Kind::Custom(custom) => custom.as_str(),
265 };
266 serializer.serialize_str(s)
267 }
268}
269
270impl<'de> Deserialize<'de> for Kind {
271 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
272 where
273 D: serde::Deserializer<'de>,
274 {
275 let s = String::deserialize(deserializer)?;
276 Ok(match s.as_str() {
277 "bolt11_mint_quote" => Kind::Bolt11MintQuote,
278 "bolt11_melt_quote" => Kind::Bolt11MeltQuote,
279 "bolt12_mint_quote" => Kind::Bolt12MintQuote,
280 "bolt12_melt_quote" => Kind::Bolt12MeltQuote,
281 "proof_state" => Kind::ProofState,
282 custom => Kind::Custom(custom.to_string()),
283 })
284 }
285}
286
287impl<I> AsRef<I> for Params<I> {
288 fn as_ref(&self) -> &I {
289 &self.id
290 }
291}
292
293#[derive(thiserror::Error, Debug)]
295pub enum Error {
296 #[error("Uuid Error: {0}")]
297 QuoteId(#[from] QuoteIdError),
299
300 #[error("PublicKey Error: {0}")]
301 PublicKey(#[from] crate::nuts::nut01::Error),
303}