cdk_common/
subscription.rs1use std::ops::Deref;
3use std::str::FromStr;
4use std::sync::Arc;
5
6use cashu::nut17::{self, Kind, NotificationId};
7use cashu::quote_id::QuoteId;
8use cashu::PublicKey;
9use serde::{Deserialize, Serialize};
10
11use crate::pub_sub::{Error, SubscriptionRequest};
12
13pub type Params = nut17::Params<Arc<SubId>>;
17
18impl SubscriptionRequest for Params {
19 type Topic = NotificationId<QuoteId>;
20
21 type SubscriptionId = SubId;
22
23 fn subscription_name(&self) -> Arc<Self::SubscriptionId> {
24 self.id.clone()
25 }
26
27 fn try_get_topics(&self) -> Result<Vec<Self::Topic>, Error> {
28 self.filters
29 .iter()
30 .map(|filter| match self.kind {
31 Kind::Bolt11MeltQuote => QuoteId::from_str(filter)
32 .map(NotificationId::MeltQuoteBolt11)
33 .map_err(|_| Error::ParsingError(filter.to_owned())),
34 Kind::Bolt11MintQuote => QuoteId::from_str(filter)
35 .map(NotificationId::MintQuoteBolt11)
36 .map_err(|_| Error::ParsingError(filter.to_owned())),
37 Kind::ProofState => PublicKey::from_str(filter)
38 .map(NotificationId::ProofState)
39 .map_err(|_| Error::ParsingError(filter.to_owned())),
40
41 Kind::Bolt12MintQuote => QuoteId::from_str(filter)
42 .map(NotificationId::MintQuoteBolt12)
43 .map_err(|_| Error::ParsingError(filter.to_owned())),
44 Kind::Bolt12MeltQuote => QuoteId::from_str(filter)
45 .map(NotificationId::MeltQuoteBolt12)
46 .map_err(|_| Error::ParsingError(filter.to_owned())),
47 Kind::Custom(ref s) => {
48 if let Some(method) = s.strip_suffix("_mint_quote") {
49 QuoteId::from_str(filter)
50 .map(|id| NotificationId::MintQuoteCustom(method.to_string(), id))
51 .map_err(|_| Error::ParsingError(filter.to_owned()))
52 } else if let Some(method) = s.strip_suffix("_melt_quote") {
53 QuoteId::from_str(filter)
54 .map(|id| NotificationId::MeltQuoteCustom(method.to_string(), id))
55 .map_err(|_| Error::ParsingError(filter.to_owned()))
56 } else {
57 Err(Error::ParsingError(filter.to_owned()))
58 }
59 }
60 })
61 .collect::<Result<Vec<_>, _>>()
62 }
63}
64
65pub type WalletParams = nut17::Params<Arc<String>>;
70
71impl SubscriptionRequest for WalletParams {
72 type Topic = NotificationId<String>;
73
74 type SubscriptionId = String;
75
76 fn subscription_name(&self) -> Arc<Self::SubscriptionId> {
77 self.id.clone()
78 }
79
80 fn try_get_topics(&self) -> Result<Vec<Self::Topic>, Error> {
81 self.filters
82 .iter()
83 .map(|filter| {
84 Ok(match self.kind {
85 Kind::Bolt11MeltQuote => NotificationId::MeltQuoteBolt11(filter.to_owned()),
86 Kind::Bolt11MintQuote => NotificationId::MintQuoteBolt11(filter.to_owned()),
87 Kind::ProofState => PublicKey::from_str(filter)
88 .map(NotificationId::ProofState)
89 .map_err(|_| Error::ParsingError(filter.to_owned()))?,
90
91 Kind::Bolt12MintQuote => NotificationId::MintQuoteBolt12(filter.to_owned()),
92 Kind::Bolt12MeltQuote => NotificationId::MeltQuoteBolt12(filter.to_owned()),
93 Kind::Custom(ref s) => {
94 if let Some(method) = s.strip_suffix("_mint_quote") {
95 NotificationId::MintQuoteCustom(method.to_string(), filter.to_owned())
96 } else if let Some(method) = s.strip_suffix("_melt_quote") {
97 NotificationId::MeltQuoteCustom(method.to_string(), filter.to_owned())
98 } else {
99 return Err(Error::ParsingError(format!("Invalid custom kind: {}", s)));
102 }
103 }
104 })
105 })
106 .collect::<Result<Vec<_>, _>>()
107 }
108}
109
110#[derive(Debug, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
115pub struct SubId(String);
116
117impl From<&str> for SubId {
118 fn from(s: &str) -> Self {
119 Self(s.to_string())
120 }
121}
122
123impl From<String> for SubId {
124 fn from(s: String) -> Self {
125 Self(s)
126 }
127}
128
129impl FromStr for SubId {
130 type Err = ();
131
132 fn from_str(s: &str) -> Result<Self, Self::Err> {
133 Ok(Self(s.to_string()))
134 }
135}
136
137impl Deref for SubId {
138 type Target = String;
139
140 fn deref(&self) -> &Self::Target {
141 &self.0
142 }
143}