cdk_common/
subscription.rs

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