use std::sync::Arc;
use cdk_common::database::{self, MintDatabase};
use cdk_common::nut17::Notification;
use cdk_common::pub_sub::OnNewSubscription;
use cdk_common::NotificationPayload;
use uuid::Uuid;
use crate::nuts::{MeltQuoteBolt11Response, MintQuoteBolt11Response, ProofState, PublicKey};
#[derive(Default)]
pub struct OnSubscription(
pub(crate) Option<Arc<dyn MintDatabase<Err = database::Error> + Send + Sync>>,
);
#[async_trait::async_trait]
impl OnNewSubscription for OnSubscription {
type Event = NotificationPayload<Uuid>;
type Index = Notification;
async fn on_new_subscription(
&self,
request: &[&Self::Index],
) -> Result<Vec<Self::Event>, String> {
let datastore = if let Some(localstore) = self.0.as_ref() {
localstore
} else {
return Ok(vec![]);
};
let mut to_return = vec![];
let mut public_keys: Vec<PublicKey> = Vec::new();
let mut melt_queries = Vec::new();
let mut mint_queries = Vec::new();
for idx in request.iter() {
match idx {
Notification::ProofState(pk) => public_keys.push(*pk),
Notification::MeltQuoteBolt11(uuid) => {
melt_queries.push(datastore.get_melt_quote(uuid))
}
Notification::MintQuoteBolt11(uuid) => {
mint_queries.push(datastore.get_mint_quote(uuid))
}
}
}
to_return.extend(
futures::future::try_join_all(melt_queries)
.await
.map(|quotes| {
quotes
.into_iter()
.filter_map(|quote| quote.map(|x| x.into()))
.map(|x: MeltQuoteBolt11Response<Uuid>| x.into())
.collect::<Vec<_>>()
})
.map_err(|e| e.to_string())?,
);
to_return.extend(
futures::future::try_join_all(mint_queries)
.await
.map(|quotes| {
quotes
.into_iter()
.filter_map(|quote| quote.map(|x| x.into()))
.map(|x: MintQuoteBolt11Response<Uuid>| x.into())
.collect::<Vec<_>>()
})
.map_err(|e| e.to_string())?,
);
to_return.extend(
datastore
.get_proofs_states(public_keys.as_slice())
.await
.map_err(|e| e.to_string())?
.into_iter()
.enumerate()
.filter_map(|(idx, state)| state.map(|state| (public_keys[idx], state).into()))
.map(|state: ProofState| state.into()),
);
Ok(to_return)
}
}