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::OnchainMintQuote => QuoteId::from_str(filter)
48 .map(NotificationId::MintQuoteOnchain)
49 .map_err(|_| Error::ParsingError(filter.to_owned())),
50 Kind::OnchainMeltQuote => QuoteId::from_str(filter)
51 .map(NotificationId::MeltQuoteOnchain)
52 .map_err(|_| Error::ParsingError(filter.to_owned())),
53 Kind::Custom(ref s) => {
54 if let Some(method) = s.strip_suffix("_mint_quote") {
55 QuoteId::from_str(filter)
56 .map(|id| NotificationId::MintQuoteCustom(method.to_string(), id))
57 .map_err(|_| Error::ParsingError(filter.to_owned()))
58 } else if let Some(method) = s.strip_suffix("_melt_quote") {
59 QuoteId::from_str(filter)
60 .map(|id| NotificationId::MeltQuoteCustom(method.to_string(), id))
61 .map_err(|_| Error::ParsingError(filter.to_owned()))
62 } else {
63 Err(Error::ParsingError(filter.to_owned()))
64 }
65 }
66 })
67 .collect::<Result<Vec<_>, _>>()
68 }
69}
70
71pub type WalletParams = nut17::Params<Arc<String>>;
76
77impl SubscriptionRequest for WalletParams {
78 type Topic = NotificationId<String>;
79
80 type SubscriptionId = String;
81
82 fn subscription_name(&self) -> Arc<Self::SubscriptionId> {
83 self.id.clone()
84 }
85
86 fn try_get_topics(&self) -> Result<Vec<Self::Topic>, Error> {
87 self.filters
88 .iter()
89 .map(|filter| {
90 Ok(match self.kind {
91 Kind::Bolt11MeltQuote => NotificationId::MeltQuoteBolt11(filter.to_owned()),
92 Kind::Bolt11MintQuote => NotificationId::MintQuoteBolt11(filter.to_owned()),
93 Kind::ProofState => PublicKey::from_str(filter)
94 .map(NotificationId::ProofState)
95 .map_err(|_| Error::ParsingError(filter.to_owned()))?,
96
97 Kind::Bolt12MintQuote => NotificationId::MintQuoteBolt12(filter.to_owned()),
98 Kind::Bolt12MeltQuote => NotificationId::MeltQuoteBolt12(filter.to_owned()),
99 Kind::OnchainMintQuote => NotificationId::MintQuoteOnchain(filter.to_owned()),
100 Kind::OnchainMeltQuote => NotificationId::MeltQuoteOnchain(filter.to_owned()),
101 Kind::Custom(ref s) => {
102 if let Some(method) = s.strip_suffix("_mint_quote") {
103 NotificationId::MintQuoteCustom(method.to_string(), filter.to_owned())
104 } else if let Some(method) = s.strip_suffix("_melt_quote") {
105 NotificationId::MeltQuoteCustom(method.to_string(), filter.to_owned())
106 } else {
107 return Err(Error::ParsingError(format!("Invalid custom kind: {}", s)));
110 }
111 }
112 })
113 })
114 .collect::<Result<Vec<_>, _>>()
115 }
116}
117
118#[derive(Debug, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
123pub struct SubId(String);
124
125impl From<&str> for SubId {
126 fn from(s: &str) -> Self {
127 Self(s.to_string())
128 }
129}
130
131impl From<String> for SubId {
132 fn from(s: String) -> Self {
133 Self(s)
134 }
135}
136
137impl FromStr for SubId {
138 type Err = ();
139
140 fn from_str(s: &str) -> Result<Self, Self::Err> {
141 Ok(Self(s.to_string()))
142 }
143}
144
145impl Deref for SubId {
146 type Target = String;
147
148 fn deref(&self) -> &Self::Target {
149 &self.0
150 }
151}