use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use super::PublicKey;
use crate::nut00::KnownMethod;
use crate::nut25::MeltQuoteBolt12Response;
use crate::nuts::{
CurrencyUnit, MeltQuoteBolt11Response, MeltQuoteCustomResponse, MintQuoteBolt11Response,
MintQuoteCustomResponse, PaymentMethod, ProofState,
};
use crate::quote_id::QuoteIdError;
use crate::MintQuoteBolt12Response;
pub mod ws;
#[derive(Debug, Clone, Serialize, Eq, PartialEq, Hash, Deserialize)]
#[serde(bound = "I: DeserializeOwned + Serialize")]
pub struct Params<I> {
pub kind: Kind,
pub filters: Vec<String>,
#[serde(rename = "subId")]
pub id: I,
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
pub struct SupportedSettings {
pub supported: Vec<SupportedMethods>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
pub struct SupportedMethods {
pub method: PaymentMethod,
pub unit: CurrencyUnit,
pub commands: Vec<WsCommand>,
}
impl SupportedMethods {
pub fn new(method: PaymentMethod, unit: CurrencyUnit, commands: Vec<WsCommand>) -> Self {
Self {
method,
unit,
commands,
}
}
pub fn default_bolt11(unit: CurrencyUnit) -> Self {
let commands = vec![
WsCommand::Bolt11MintQuote,
WsCommand::Bolt11MeltQuote,
WsCommand::ProofState,
];
Self {
method: PaymentMethod::Known(KnownMethod::Bolt11),
unit,
commands,
}
}
pub fn default_bolt12(unit: CurrencyUnit) -> Self {
let commands = vec![
WsCommand::Bolt12MintQuote,
WsCommand::Bolt12MeltQuote,
WsCommand::ProofState,
];
Self {
method: PaymentMethod::Known(KnownMethod::Bolt12),
unit,
commands,
}
}
pub fn default_custom(method: PaymentMethod, unit: CurrencyUnit) -> Self {
let method_name = method.to_string();
let commands = vec![
WsCommand::Custom(format!("{}_mint_quote", method_name)),
WsCommand::Custom(format!("{}_melt_quote", method_name)),
WsCommand::ProofState,
];
Self {
method,
unit,
commands,
}
}
}
impl WsCommand {
pub fn custom_mint_quote(method: &str) -> Self {
WsCommand::Custom(format!("{}_mint_quote", method))
}
pub fn custom_melt_quote(method: &str) -> Self {
WsCommand::Custom(format!("{}_melt_quote", method))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
pub enum WsCommand {
Bolt11MintQuote,
Bolt11MeltQuote,
Bolt12MintQuote,
Bolt12MeltQuote,
ProofState,
Custom(String),
}
impl Serialize for WsCommand {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let s = match self {
WsCommand::Bolt11MintQuote => "bolt11_mint_quote",
WsCommand::Bolt11MeltQuote => "bolt11_melt_quote",
WsCommand::Bolt12MintQuote => "bolt12_mint_quote",
WsCommand::Bolt12MeltQuote => "bolt12_melt_quote",
WsCommand::ProofState => "proof_state",
WsCommand::Custom(custom) => custom.as_str(),
};
serializer.serialize_str(s)
}
}
impl<'de> Deserialize<'de> for WsCommand {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(match s.as_str() {
"bolt11_mint_quote" => WsCommand::Bolt11MintQuote,
"bolt11_melt_quote" => WsCommand::Bolt11MeltQuote,
"bolt12_mint_quote" => WsCommand::Bolt12MintQuote,
"bolt12_melt_quote" => WsCommand::Bolt12MeltQuote,
"proof_state" => WsCommand::ProofState,
custom => WsCommand::Custom(custom.to_string()),
})
}
}
impl<T> From<MintQuoteBolt12Response<T>> for NotificationPayload<T>
where
T: Clone,
{
fn from(mint_quote: MintQuoteBolt12Response<T>) -> NotificationPayload<T> {
NotificationPayload::MintQuoteBolt12Response(mint_quote)
}
}
impl<T> From<MeltQuoteBolt12Response<T>> for NotificationPayload<T>
where
T: Clone,
{
fn from(melt_quote: MeltQuoteBolt12Response<T>) -> NotificationPayload<T> {
NotificationPayload::MeltQuoteBolt12Response(melt_quote)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound = "T: Serialize + DeserializeOwned")]
#[serde(untagged)]
pub enum NotificationPayload<T>
where
T: Clone,
{
ProofState(ProofState),
MeltQuoteBolt11Response(MeltQuoteBolt11Response<T>),
MintQuoteBolt11Response(MintQuoteBolt11Response<T>),
MintQuoteBolt12Response(MintQuoteBolt12Response<T>),
MeltQuoteBolt12Response(MeltQuoteBolt12Response<T>),
CustomMintQuoteResponse(String, MintQuoteCustomResponse<T>),
CustomMeltQuoteResponse(String, MeltQuoteCustomResponse<T>),
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Hash, Serialize)]
#[serde(bound = "T: Serialize + DeserializeOwned")]
pub enum NotificationId<T>
where
T: Clone,
{
ProofState(PublicKey),
MeltQuoteBolt11(T),
MintQuoteBolt11(T),
MintQuoteBolt12(T),
MeltQuoteBolt12(T),
MintQuoteCustom(String, T),
MeltQuoteCustom(String, T),
}
#[derive(Debug, Clone, Eq, Ord, PartialOrd, PartialEq, Hash)]
pub enum Kind {
Bolt11MeltQuote,
Bolt11MintQuote,
ProofState,
Bolt12MintQuote,
Bolt12MeltQuote,
Custom(String),
}
impl Serialize for Kind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let s = match self {
Kind::Bolt11MintQuote => "bolt11_mint_quote",
Kind::Bolt11MeltQuote => "bolt11_melt_quote",
Kind::Bolt12MintQuote => "bolt12_mint_quote",
Kind::Bolt12MeltQuote => "bolt12_melt_quote",
Kind::ProofState => "proof_state",
Kind::Custom(custom) => custom.as_str(),
};
serializer.serialize_str(s)
}
}
impl<'de> Deserialize<'de> for Kind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(match s.as_str() {
"bolt11_mint_quote" => Kind::Bolt11MintQuote,
"bolt11_melt_quote" => Kind::Bolt11MeltQuote,
"bolt12_mint_quote" => Kind::Bolt12MintQuote,
"bolt12_melt_quote" => Kind::Bolt12MeltQuote,
"proof_state" => Kind::ProofState,
custom => Kind::Custom(custom.to_string()),
})
}
}
impl<I> AsRef<I> for Params<I> {
fn as_ref(&self) -> &I {
&self.id
}
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Uuid Error: {0}")]
QuoteId(#[from] QuoteIdError),
#[error("PublicKey Error: {0}")]
PublicKey(#[from] crate::nuts::nut01::Error),
}