cdk_common/
subscription.rs

1//! Subscription types and traits
2use std::str::FromStr;
3
4use cashu::nut17::{self, Error, Kind, Notification};
5use cashu::{NotificationPayload, PublicKey};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
10use crate::pub_sub::SubId;
11
12/// Subscription parameters.
13///
14/// This is a concrete type alias for `nut17::Params<SubId>`.
15pub type Params = nut17::Params<SubId>;
16
17/// Wrapper around `nut17::Params` to implement `Indexable` for `Notification`.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct IndexableParams(Params);
20
21impl From<Params> for IndexableParams {
22    fn from(params: Params) -> Self {
23        Self(params)
24    }
25}
26
27impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
28    type Error = Error;
29    fn try_from(params: IndexableParams) -> Result<Self, Self::Error> {
30        let sub_id: SubscriptionGlobalId = Default::default();
31        let params = params.0;
32        params
33            .filters
34            .into_iter()
35            .map(|filter| {
36                let idx = match params.kind {
37                    Kind::Bolt11MeltQuote => {
38                        Notification::MeltQuoteBolt11(Uuid::from_str(&filter)?)
39                    }
40                    Kind::Bolt11MintQuote => {
41                        Notification::MintQuoteBolt11(Uuid::from_str(&filter)?)
42                    }
43                    Kind::ProofState => Notification::ProofState(PublicKey::from_str(&filter)?),
44                };
45
46                Ok(Index::from((idx, params.id.clone(), sub_id)))
47            })
48            .collect::<Result<_, _>>()
49    }
50}
51
52impl AsRef<SubId> for IndexableParams {
53    fn as_ref(&self) -> &SubId {
54        &self.0.id
55    }
56}
57
58impl Indexable for NotificationPayload<Uuid> {
59    type Type = Notification;
60
61    fn to_indexes(&self) -> Vec<Index<Self::Type>> {
62        match self {
63            NotificationPayload::ProofState(proof_state) => {
64                vec![Index::from(Notification::ProofState(proof_state.y))]
65            }
66            NotificationPayload::MeltQuoteBolt11Response(melt_quote) => {
67                vec![Index::from(Notification::MeltQuoteBolt11(melt_quote.quote))]
68            }
69            NotificationPayload::MintQuoteBolt11Response(mint_quote) => {
70                vec![Index::from(Notification::MintQuoteBolt11(mint_quote.quote))]
71            }
72        }
73    }
74}