cdk_common/
subscription.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Subscription types and traits
use std::str::FromStr;

use cashu::nut17::{self, Error, Kind, Notification};
use cashu::{NotificationPayload, PublicKey};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
use crate::pub_sub::SubId;

/// Subscription parameters.
///
/// This is a concrete type alias for `nut17::Params<SubId>`.
pub type Params = nut17::Params<SubId>;

/// Wrapper around `nut17::Params` to implement `Indexable` for `Notification`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndexableParams(Params);

impl From<Params> for IndexableParams {
    fn from(params: Params) -> Self {
        Self(params)
    }
}

impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
    type Error = Error;
    fn try_from(params: IndexableParams) -> Result<Self, Self::Error> {
        let sub_id: SubscriptionGlobalId = Default::default();
        let params = params.0;
        params
            .filters
            .into_iter()
            .map(|filter| {
                let idx = match params.kind {
                    Kind::Bolt11MeltQuote => {
                        Notification::MeltQuoteBolt11(Uuid::from_str(&filter)?)
                    }
                    Kind::Bolt11MintQuote => {
                        Notification::MintQuoteBolt11(Uuid::from_str(&filter)?)
                    }
                    Kind::ProofState => Notification::ProofState(PublicKey::from_str(&filter)?),
                };

                Ok(Index::from((idx, params.id.clone(), sub_id)))
            })
            .collect::<Result<_, _>>()
    }
}

impl AsRef<SubId> for IndexableParams {
    fn as_ref(&self) -> &SubId {
        &self.0.id
    }
}

impl Indexable for NotificationPayload<Uuid> {
    type Type = Notification;

    fn to_indexes(&self) -> Vec<Index<Self::Type>> {
        match self {
            NotificationPayload::ProofState(proof_state) => {
                vec![Index::from(Notification::ProofState(proof_state.y))]
            }
            NotificationPayload::MeltQuoteBolt11Response(melt_quote) => {
                vec![Index::from(Notification::MeltQuoteBolt11(melt_quote.quote))]
            }
            NotificationPayload::MintQuoteBolt11Response(mint_quote) => {
                vec![Index::from(Notification::MintQuoteBolt11(mint_quote.quote))]
            }
        }
    }
}