mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-19 13:44:55 +01:00
compatibility for migrating Nutshell Mints quote ids (#984)
This commit is contained in:
@@ -44,4 +44,3 @@ uuid = { workspace = true, features = ["js"], optional = true }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bip39.workspace = true
|
bip39.workspace = true
|
||||||
uuid.workspace = true
|
|
||||||
|
|||||||
@@ -25,3 +25,107 @@ macro_rules! ensure_cdk {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
/// Quote ID. The specifications only define a string but CDK uses Uuid, so we use an enum to port compatibility.
|
||||||
|
pub mod quote_id {
|
||||||
|
use std::fmt;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use bitcoin::base64::engine::general_purpose;
|
||||||
|
use bitcoin::base64::Engine as _;
|
||||||
|
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||||
|
use thiserror::Error;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
/// Invalid UUID
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum QuoteIdError {
|
||||||
|
/// UUID Error
|
||||||
|
#[error("invalid UUID: {0}")]
|
||||||
|
Uuid(#[from] uuid::Error),
|
||||||
|
/// Invalid base64
|
||||||
|
#[error("invalid base64")]
|
||||||
|
Base64,
|
||||||
|
/// Invalid quote ID
|
||||||
|
#[error("neither a valid UUID nor a valid base64 string")]
|
||||||
|
InvalidQuoteId,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mint Quote ID
|
||||||
|
#[derive(Serialize, Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum QuoteId {
|
||||||
|
/// (Nutshell) base64 quote ID
|
||||||
|
BASE64(String),
|
||||||
|
/// UUID quote ID
|
||||||
|
UUID(Uuid),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QuoteId {
|
||||||
|
/// Create a new UUID-based MintQuoteId
|
||||||
|
pub fn new_uuid() -> Self {
|
||||||
|
Self::UUID(Uuid::new_v4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Uuid> for QuoteId {
|
||||||
|
fn from(uuid: Uuid) -> Self {
|
||||||
|
Self::UUID(uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for QuoteId {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
QuoteId::BASE64(s) => write!(f, "{}", s),
|
||||||
|
QuoteId::UUID(u) => write!(f, "{}", u),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for QuoteId {
|
||||||
|
type Err = QuoteIdError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
// Try UUID first
|
||||||
|
if let Ok(u) = Uuid::parse_str(s) {
|
||||||
|
return Ok(QuoteId::UUID(u));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try base64: decode, then re-encode and compare to ensure canonical form
|
||||||
|
// Use the standard (URL/filename safe or standard) depending on your needed alphabet.
|
||||||
|
// Here we use standard base64.
|
||||||
|
match general_purpose::URL_SAFE.decode(s) {
|
||||||
|
Ok(_bytes) => Ok(QuoteId::BASE64(s.to_string())),
|
||||||
|
Err(_) => Err(QuoteIdError::InvalidQuoteId),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for QuoteId {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
// Deserialize as plain string first
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
// Try UUID first
|
||||||
|
if let Ok(u) = Uuid::parse_str(&s) {
|
||||||
|
return Ok(QuoteId::UUID(u));
|
||||||
|
}
|
||||||
|
|
||||||
|
if general_purpose::URL_SAFE.decode(&s).is_ok() {
|
||||||
|
return Ok(QuoteId::BASE64(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neither matched — return a helpful error
|
||||||
|
Err(de::Error::custom(format!(
|
||||||
|
"QuoteId must be either a UUID (e.g. {}) or a valid base64 string; got: {}",
|
||||||
|
Uuid::nil(),
|
||||||
|
s
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ use serde::de::{self, DeserializeOwned, Deserializer, MapAccess, Visitor};
|
|||||||
use serde::ser::{SerializeStruct, Serializer};
|
use serde::ser::{SerializeStruct, Serializer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::nut00::{BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod};
|
use super::nut00::{BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::QuoteId;
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::QuoteIdError;
|
||||||
use crate::Amount;
|
use crate::Amount;
|
||||||
|
|
||||||
/// NUT04 Error
|
/// NUT04 Error
|
||||||
@@ -44,12 +46,12 @@ pub struct MintRequest<Q> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl TryFrom<MintRequest<String>> for MintRequest<Uuid> {
|
impl TryFrom<MintRequest<String>> for MintRequest<QuoteId> {
|
||||||
type Error = uuid::Error;
|
type Error = QuoteIdError;
|
||||||
|
|
||||||
fn try_from(value: MintRequest<String>) -> Result<Self, Self::Error> {
|
fn try_from(value: MintRequest<String>) -> Result<Self, Self::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
quote: Uuid::from_str(&value.quote)?,
|
quote: QuoteId::from_str(&value.quote)?,
|
||||||
outputs: value.outputs,
|
outputs: value.outputs,
|
||||||
signature: value.signature,
|
signature: value.signature,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ use serde::de::{self, DeserializeOwned, Deserializer, MapAccess, Visitor};
|
|||||||
use serde::ser::{SerializeStruct, Serializer};
|
use serde::ser::{SerializeStruct, Serializer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::nut00::{BlindedMessage, CurrencyUnit, PaymentMethod, Proofs};
|
use super::nut00::{BlindedMessage, CurrencyUnit, PaymentMethod, Proofs};
|
||||||
use super::ProofsMethods;
|
use super::ProofsMethods;
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::QuoteId;
|
||||||
use crate::Amount;
|
use crate::Amount;
|
||||||
|
|
||||||
/// NUT05 Error
|
/// NUT05 Error
|
||||||
@@ -28,6 +28,9 @@ pub enum Error {
|
|||||||
/// Unsupported unit
|
/// Unsupported unit
|
||||||
#[error("Unsupported unit")]
|
#[error("Unsupported unit")]
|
||||||
UnsupportedUnit,
|
UnsupportedUnit,
|
||||||
|
/// Invalid quote id
|
||||||
|
#[error("Invalid quote id")]
|
||||||
|
InvalidQuote,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible states of a quote
|
/// Possible states of a quote
|
||||||
@@ -91,12 +94,12 @@ pub struct MeltRequest<Q> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl TryFrom<MeltRequest<String>> for MeltRequest<Uuid> {
|
impl TryFrom<MeltRequest<String>> for MeltRequest<QuoteId> {
|
||||||
type Error = uuid::Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(value: MeltRequest<String>) -> Result<Self, Self::Error> {
|
fn try_from(value: MeltRequest<String>) -> Result<Self, Self::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
quote: Uuid::from_str(&value.quote)?,
|
quote: QuoteId::from_str(&value.quote).map_err(|_e| Error::InvalidQuote)?,
|
||||||
inputs: value.inputs,
|
inputs: value.inputs,
|
||||||
outputs: value.outputs,
|
outputs: value.outputs,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1262,6 +1262,7 @@ impl<'de> Deserialize<'de> for Tag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@@ -1270,6 +1271,7 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::nuts::Id;
|
use crate::nuts::Id;
|
||||||
|
use crate::quote_id::QuoteId;
|
||||||
use crate::secret::Secret;
|
use crate::secret::Secret;
|
||||||
use crate::{Amount, BlindedMessage};
|
use crate::{Amount, BlindedMessage};
|
||||||
|
|
||||||
@@ -1514,7 +1516,11 @@ mod tests {
|
|||||||
let blinded_msg = create_test_blinded_msg(pubkey);
|
let blinded_msg = create_test_blinded_msg(pubkey);
|
||||||
|
|
||||||
// Create melt request
|
// Create melt request
|
||||||
let mut melt = MeltRequest::new(Uuid::new_v4(), vec![proof], Some(vec![blinded_msg]));
|
let mut melt = MeltRequest::new(
|
||||||
|
QuoteId::UUID(Uuid::new_v4()),
|
||||||
|
vec![proof],
|
||||||
|
Some(vec![blinded_msg]),
|
||||||
|
);
|
||||||
|
|
||||||
// Before signing, should fail verification
|
// Before signing, should fail verification
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
//! Specific Subscription for the cdk crate
|
//! Specific Subscription for the cdk crate
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use super::PublicKey;
|
use super::PublicKey;
|
||||||
use crate::nuts::{
|
use crate::nuts::{
|
||||||
CurrencyUnit, MeltQuoteBolt11Response, MintQuoteBolt11Response, PaymentMethod, ProofState,
|
CurrencyUnit, MeltQuoteBolt11Response, MintQuoteBolt11Response, PaymentMethod, ProofState,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::{QuoteId, QuoteIdError};
|
||||||
use crate::MintQuoteBolt12Response;
|
use crate::MintQuoteBolt12Response;
|
||||||
|
|
||||||
pub mod ws;
|
pub mod ws;
|
||||||
@@ -154,14 +154,14 @@ impl<T> From<MintQuoteBolt11Response<T>> for NotificationPayload<T> {
|
|||||||
pub enum Notification {
|
pub enum Notification {
|
||||||
/// ProofState id is a Pubkey
|
/// ProofState id is a Pubkey
|
||||||
ProofState(PublicKey),
|
ProofState(PublicKey),
|
||||||
/// MeltQuote id is an Uuid
|
/// MeltQuote id is an QuoteId
|
||||||
MeltQuoteBolt11(Uuid),
|
MeltQuoteBolt11(QuoteId),
|
||||||
/// MintQuote id is an Uuid
|
/// MintQuote id is an QuoteId
|
||||||
MintQuoteBolt11(Uuid),
|
MintQuoteBolt11(QuoteId),
|
||||||
/// MintQuote id is an Uuid
|
/// MintQuote id is an QuoteId
|
||||||
MintQuoteBolt12(Uuid),
|
MintQuoteBolt12(QuoteId),
|
||||||
/// MintQuote id is an Uuid
|
/// MintQuote id is an QuoteId
|
||||||
MeltQuoteBolt12(Uuid),
|
MeltQuoteBolt12(QuoteId),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Kind
|
/// Kind
|
||||||
@@ -190,7 +190,7 @@ pub enum Error {
|
|||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
#[error("Uuid Error: {0}")]
|
#[error("Uuid Error: {0}")]
|
||||||
/// Uuid Error
|
/// Uuid Error
|
||||||
Uuid(#[from] uuid::Error),
|
QuoteId(#[from] QuoteIdError),
|
||||||
|
|
||||||
#[error("PublicKey Error: {0}")]
|
#[error("PublicKey Error: {0}")]
|
||||||
/// PublicKey Error
|
/// PublicKey Error
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -111,8 +109,11 @@ mod tests {
|
|||||||
assert_eq!(expected_msg_to_sign, request_msg_to_sign);
|
assert_eq!(expected_msg_to_sign, request_msg_to_sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_valid_signature() {
|
fn test_valid_signature() {
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
let pubkey = PublicKey::from_hex(
|
let pubkey = PublicKey::from_hex(
|
||||||
"03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac",
|
"03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use serde::de::DeserializeOwned;
|
|||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::{BlindSignature, CurrencyUnit, MeltQuoteState, Mpp, PublicKey};
|
use super::{BlindSignature, CurrencyUnit, MeltQuoteState, Mpp, PublicKey};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::QuoteId;
|
||||||
use crate::Amount;
|
use crate::Amount;
|
||||||
|
|
||||||
/// NUT023 Error
|
/// NUT023 Error
|
||||||
@@ -120,8 +120,8 @@ impl<Q: ToString> MintQuoteBolt11Response<Q> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl From<MintQuoteBolt11Response<Uuid>> for MintQuoteBolt11Response<String> {
|
impl From<MintQuoteBolt11Response<QuoteId>> for MintQuoteBolt11Response<String> {
|
||||||
fn from(value: MintQuoteBolt11Response<Uuid>) -> Self {
|
fn from(value: MintQuoteBolt11Response<QuoteId>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
quote: value.quote.to_string(),
|
quote: value.quote.to_string(),
|
||||||
request: value.request,
|
request: value.request,
|
||||||
@@ -293,8 +293,8 @@ impl<Q: ToString> MeltQuoteBolt11Response<Q> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl From<MeltQuoteBolt11Response<Uuid>> for MeltQuoteBolt11Response<String> {
|
impl From<MeltQuoteBolt11Response<QuoteId>> for MeltQuoteBolt11Response<String> {
|
||||||
fn from(value: MeltQuoteBolt11Response<Uuid>) -> Self {
|
fn from(value: MeltQuoteBolt11Response<QuoteId>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
quote: value.quote.to_string(),
|
quote: value.quote.to_string(),
|
||||||
amount: value.amount,
|
amount: value.amount,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! Bolt12
|
//! Bolt12
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::{CurrencyUnit, MeltOptions, PublicKey};
|
use super::{CurrencyUnit, MeltOptions, PublicKey};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
use crate::quote_id::QuoteId;
|
||||||
use crate::Amount;
|
use crate::Amount;
|
||||||
|
|
||||||
/// NUT18 Error
|
/// NUT18 Error
|
||||||
@@ -76,8 +76,8 @@ impl<Q: ToString> MintQuoteBolt12Response<Q> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl From<MintQuoteBolt12Response<Uuid>> for MintQuoteBolt12Response<String> {
|
impl From<MintQuoteBolt12Response<QuoteId>> for MintQuoteBolt12Response<String> {
|
||||||
fn from(value: MintQuoteBolt12Response<Uuid>) -> Self {
|
fn from(value: MintQuoteBolt12Response<QuoteId>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
quote: value.quote.to_string(),
|
quote: value.quote.to_string(),
|
||||||
request: value.request,
|
request: value.request,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use axum::extract::{Json, Path, State};
|
|||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
#[cfg(feature = "swagger")]
|
#[cfg(feature = "swagger")]
|
||||||
use cdk::error::ErrorResponse;
|
use cdk::error::ErrorResponse;
|
||||||
|
use cdk::mint::QuoteId;
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
use cdk::nuts::nut21::{Method, ProtectedEndpoint, RoutePath};
|
use cdk::nuts::nut21::{Method, ProtectedEndpoint, RoutePath};
|
||||||
use cdk::nuts::{
|
use cdk::nuts::{
|
||||||
@@ -11,17 +12,16 @@ use cdk::nuts::{
|
|||||||
};
|
};
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
use crate::auth::AuthHeader;
|
use crate::auth::AuthHeader;
|
||||||
use crate::{into_response, post_cache_wrapper, MintState};
|
use crate::{into_response, post_cache_wrapper, MintState};
|
||||||
|
|
||||||
post_cache_wrapper!(post_mint_bolt12, MintRequest<Uuid>, MintResponse);
|
post_cache_wrapper!(post_mint_bolt12, MintRequest<QuoteId>, MintResponse);
|
||||||
post_cache_wrapper!(
|
post_cache_wrapper!(
|
||||||
post_melt_bolt12,
|
post_melt_bolt12,
|
||||||
MeltRequest<Uuid>,
|
MeltRequest<QuoteId>,
|
||||||
MeltQuoteBolt11Response<Uuid>
|
MeltQuoteBolt11Response<QuoteId>
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg_attr(feature = "swagger", utoipa::path(
|
#[cfg_attr(feature = "swagger", utoipa::path(
|
||||||
@@ -38,7 +38,7 @@ pub async fn post_mint_bolt12_quote(
|
|||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MintQuoteBolt12Request>,
|
Json(payload): Json<MintQuoteBolt12Request>,
|
||||||
) -> Result<Json<MintQuoteBolt12Response<Uuid>>, Response> {
|
) -> Result<Json<MintQuoteBolt12Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -77,8 +77,8 @@ pub async fn post_mint_bolt12_quote(
|
|||||||
pub async fn get_check_mint_bolt12_quote(
|
pub async fn get_check_mint_bolt12_quote(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Path(quote_id): Path<Uuid>,
|
Path(quote_id): Path<QuoteId>,
|
||||||
) -> Result<Json<MintQuoteBolt12Response<Uuid>>, Response> {
|
) -> Result<Json<MintQuoteBolt12Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -115,7 +115,7 @@ pub async fn get_check_mint_bolt12_quote(
|
|||||||
pub async fn post_mint_bolt12(
|
pub async fn post_mint_bolt12(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MintRequest<Uuid>>,
|
Json(payload): Json<MintRequest<QuoteId>>,
|
||||||
) -> Result<Json<MintResponse>, Response> {
|
) -> Result<Json<MintResponse>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
@@ -155,7 +155,7 @@ pub async fn post_melt_bolt12_quote(
|
|||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MeltQuoteBolt12Request>,
|
Json(payload): Json<MeltQuoteBolt12Request>,
|
||||||
) -> Result<Json<MeltQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MeltQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -193,8 +193,8 @@ pub async fn post_melt_bolt12_quote(
|
|||||||
pub async fn post_melt_bolt12(
|
pub async fn post_melt_bolt12(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MeltRequest<Uuid>>,
|
Json(payload): Json<MeltRequest<QuoteId>>,
|
||||||
) -> Result<Json<MeltQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MeltQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use axum::extract::{Json, Path, State};
|
|||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use cdk::error::{ErrorCode, ErrorResponse};
|
use cdk::error::{ErrorCode, ErrorResponse};
|
||||||
|
use cdk::mint::QuoteId;
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
use cdk::nuts::nut21::{Method, ProtectedEndpoint, RoutePath};
|
use cdk::nuts::nut21::{Method, ProtectedEndpoint, RoutePath};
|
||||||
use cdk::nuts::{
|
use cdk::nuts::{
|
||||||
@@ -15,7 +16,6 @@ use cdk::nuts::{
|
|||||||
use cdk::util::unix_time;
|
use cdk::util::unix_time;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
use crate::auth::AuthHeader;
|
use crate::auth::AuthHeader;
|
||||||
@@ -62,11 +62,11 @@ macro_rules! post_cache_wrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
post_cache_wrapper!(post_swap, SwapRequest, SwapResponse);
|
post_cache_wrapper!(post_swap, SwapRequest, SwapResponse);
|
||||||
post_cache_wrapper!(post_mint_bolt11, MintRequest<Uuid>, MintResponse);
|
post_cache_wrapper!(post_mint_bolt11, MintRequest<QuoteId>, MintResponse);
|
||||||
post_cache_wrapper!(
|
post_cache_wrapper!(
|
||||||
post_melt_bolt11,
|
post_melt_bolt11,
|
||||||
MeltRequest<Uuid>,
|
MeltRequest<QuoteId>,
|
||||||
MeltQuoteBolt11Response<Uuid>
|
MeltQuoteBolt11Response<QuoteId>
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg_attr(feature = "swagger", utoipa::path(
|
#[cfg_attr(feature = "swagger", utoipa::path(
|
||||||
@@ -152,7 +152,7 @@ pub(crate) async fn post_mint_bolt11_quote(
|
|||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MintQuoteBolt11Request>,
|
Json(payload): Json<MintQuoteBolt11Request>,
|
||||||
) -> Result<Json<MintQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MintQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
state
|
state
|
||||||
.mint
|
.mint
|
||||||
@@ -191,8 +191,8 @@ pub(crate) async fn post_mint_bolt11_quote(
|
|||||||
pub(crate) async fn get_check_mint_bolt11_quote(
|
pub(crate) async fn get_check_mint_bolt11_quote(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Path(quote_id): Path<Uuid>,
|
Path(quote_id): Path<QuoteId>,
|
||||||
) -> Result<Json<MintQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MintQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -244,7 +244,7 @@ pub(crate) async fn ws_handler(
|
|||||||
pub(crate) async fn post_mint_bolt11(
|
pub(crate) async fn post_mint_bolt11(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MintRequest<Uuid>>,
|
Json(payload): Json<MintRequest<QuoteId>>,
|
||||||
) -> Result<Json<MintResponse>, Response> {
|
) -> Result<Json<MintResponse>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
@@ -286,7 +286,7 @@ pub(crate) async fn post_melt_bolt11_quote(
|
|||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MeltQuoteBolt11Request>,
|
Json(payload): Json<MeltQuoteBolt11Request>,
|
||||||
) -> Result<Json<MeltQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MeltQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -327,8 +327,8 @@ pub(crate) async fn post_melt_bolt11_quote(
|
|||||||
pub(crate) async fn get_check_melt_bolt11_quote(
|
pub(crate) async fn get_check_melt_bolt11_quote(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Path(quote_id): Path<Uuid>,
|
Path(quote_id): Path<QuoteId>,
|
||||||
) -> Result<Json<MeltQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MeltQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
@@ -370,8 +370,8 @@ pub(crate) async fn get_check_melt_bolt11_quote(
|
|||||||
pub(crate) async fn post_melt_bolt11(
|
pub(crate) async fn post_melt_bolt11(
|
||||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||||
State(state): State<MintState>,
|
State(state): State<MintState>,
|
||||||
Json(payload): Json<MeltRequest<Uuid>>,
|
Json(payload): Json<MeltRequest<QuoteId>>,
|
||||||
) -> Result<Json<MeltQuoteBolt11Response<Uuid>>, Response> {
|
) -> Result<Json<MeltQuoteBolt11Response<QuoteId>>, Response> {
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use axum::extract::ws::{Message, WebSocket};
|
use axum::extract::ws::{Message, WebSocket};
|
||||||
|
use cdk::mint::QuoteId;
|
||||||
use cdk::nuts::nut17::NotificationPayload;
|
use cdk::nuts::nut17::NotificationPayload;
|
||||||
use cdk::pub_sub::SubId;
|
use cdk::pub_sub::SubId;
|
||||||
use cdk::ws::{
|
use cdk::ws::{
|
||||||
@@ -9,7 +10,6 @@ use cdk::ws::{
|
|||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::MintState;
|
use crate::MintState;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ pub use error::WsError;
|
|||||||
pub struct WsContext {
|
pub struct WsContext {
|
||||||
state: MintState,
|
state: MintState,
|
||||||
subscriptions: HashMap<SubId, tokio::task::JoinHandle<()>>,
|
subscriptions: HashMap<SubId, tokio::task::JoinHandle<()>>,
|
||||||
publisher: mpsc::Sender<(SubId, NotificationPayload<Uuid>)>,
|
publisher: mpsc::Sender<(SubId, NotificationPayload<QuoteId>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Main function for websocket connections
|
/// Main function for websocket connections
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use cashu::quote_id::QuoteId;
|
||||||
use cashu::{Amount, MintInfo};
|
use cashu::{Amount, MintInfo};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@@ -64,25 +65,27 @@ pub trait QuotesTransaction<'a> {
|
|||||||
type Err: Into<Error> + From<Error>;
|
type Err: Into<Error> + From<Error>;
|
||||||
|
|
||||||
/// Get [`MintMintQuote`] and lock it for update in this transaction
|
/// Get [`MintMintQuote`] and lock it for update in this transaction
|
||||||
async fn get_mint_quote(&mut self, quote_id: &Uuid)
|
async fn get_mint_quote(
|
||||||
-> Result<Option<MintMintQuote>, Self::Err>;
|
&mut self,
|
||||||
|
quote_id: &QuoteId,
|
||||||
|
) -> Result<Option<MintMintQuote>, Self::Err>;
|
||||||
/// Add [`MintMintQuote`]
|
/// Add [`MintMintQuote`]
|
||||||
async fn add_mint_quote(&mut self, quote: MintMintQuote) -> Result<(), Self::Err>;
|
async fn add_mint_quote(&mut self, quote: MintMintQuote) -> Result<(), Self::Err>;
|
||||||
/// Increment amount paid [`MintMintQuote`]
|
/// Increment amount paid [`MintMintQuote`]
|
||||||
async fn increment_mint_quote_amount_paid(
|
async fn increment_mint_quote_amount_paid(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
amount_paid: Amount,
|
amount_paid: Amount,
|
||||||
payment_id: String,
|
payment_id: String,
|
||||||
) -> Result<Amount, Self::Err>;
|
) -> Result<Amount, Self::Err>;
|
||||||
/// Increment amount paid [`MintMintQuote`]
|
/// Increment amount paid [`MintMintQuote`]
|
||||||
async fn increment_mint_quote_amount_issued(
|
async fn increment_mint_quote_amount_issued(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
amount_issued: Amount,
|
amount_issued: Amount,
|
||||||
) -> Result<Amount, Self::Err>;
|
) -> Result<Amount, Self::Err>;
|
||||||
/// Remove [`MintMintQuote`]
|
/// Remove [`MintMintQuote`]
|
||||||
async fn remove_mint_quote(&mut self, quote_id: &Uuid) -> Result<(), Self::Err>;
|
async fn remove_mint_quote(&mut self, quote_id: &QuoteId) -> Result<(), Self::Err>;
|
||||||
/// Get [`mint::MeltQuote`] and lock it for update in this transaction
|
/// Get [`mint::MeltQuote`] and lock it for update in this transaction
|
||||||
async fn get_melt_quote(
|
async fn get_melt_quote(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -94,7 +97,7 @@ pub trait QuotesTransaction<'a> {
|
|||||||
/// Updates the request lookup id for a melt quote
|
/// Updates the request lookup id for a melt quote
|
||||||
async fn update_melt_quote_request_lookup_id(
|
async fn update_melt_quote_request_lookup_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
new_request_lookup_id: &PaymentIdentifier,
|
new_request_lookup_id: &PaymentIdentifier,
|
||||||
) -> Result<(), Self::Err>;
|
) -> Result<(), Self::Err>;
|
||||||
|
|
||||||
@@ -103,7 +106,7 @@ pub trait QuotesTransaction<'a> {
|
|||||||
/// It is expected for this function to fail if the state is already set to the new state
|
/// It is expected for this function to fail if the state is already set to the new state
|
||||||
async fn update_melt_quote_state(
|
async fn update_melt_quote_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
new_state: MeltQuoteState,
|
new_state: MeltQuoteState,
|
||||||
payment_proof: Option<String>,
|
payment_proof: Option<String>,
|
||||||
) -> Result<(MeltQuoteState, mint::MeltQuote), Self::Err>;
|
) -> Result<(MeltQuoteState, mint::MeltQuote), Self::Err>;
|
||||||
@@ -129,7 +132,7 @@ pub trait QuotesDatabase {
|
|||||||
type Err: Into<Error> + From<Error>;
|
type Err: Into<Error> + From<Error>;
|
||||||
|
|
||||||
/// Get [`MintMintQuote`]
|
/// Get [`MintMintQuote`]
|
||||||
async fn get_mint_quote(&self, quote_id: &Uuid) -> Result<Option<MintMintQuote>, Self::Err>;
|
async fn get_mint_quote(&self, quote_id: &QuoteId) -> Result<Option<MintMintQuote>, Self::Err>;
|
||||||
|
|
||||||
/// Get all [`MintMintQuote`]s
|
/// Get all [`MintMintQuote`]s
|
||||||
async fn get_mint_quote_by_request(
|
async fn get_mint_quote_by_request(
|
||||||
@@ -144,7 +147,10 @@ pub trait QuotesDatabase {
|
|||||||
/// Get Mint Quotes
|
/// Get Mint Quotes
|
||||||
async fn get_mint_quotes(&self) -> Result<Vec<MintMintQuote>, Self::Err>;
|
async fn get_mint_quotes(&self) -> Result<Vec<MintMintQuote>, Self::Err>;
|
||||||
/// Get [`mint::MeltQuote`]
|
/// Get [`mint::MeltQuote`]
|
||||||
async fn get_melt_quote(&self, quote_id: &Uuid) -> Result<Option<mint::MeltQuote>, Self::Err>;
|
async fn get_melt_quote(
|
||||||
|
&self,
|
||||||
|
quote_id: &QuoteId,
|
||||||
|
) -> Result<Option<mint::MeltQuote>, Self::Err>;
|
||||||
/// Get all [`mint::MeltQuote`]s
|
/// Get all [`mint::MeltQuote`]s
|
||||||
async fn get_melt_quotes(&self) -> Result<Vec<mint::MeltQuote>, Self::Err>;
|
async fn get_melt_quotes(&self) -> Result<Vec<mint::MeltQuote>, Self::Err>;
|
||||||
}
|
}
|
||||||
@@ -205,7 +211,7 @@ pub trait SignaturesTransaction<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
blinded_messages: &[PublicKey],
|
blinded_messages: &[PublicKey],
|
||||||
blind_signatures: &[BlindSignature],
|
blind_signatures: &[BlindSignature],
|
||||||
quote_id: Option<Uuid>,
|
quote_id: Option<QuoteId>,
|
||||||
) -> Result<(), Self::Err>;
|
) -> Result<(), Self::Err>;
|
||||||
|
|
||||||
/// Get [`BlindSignature`]s
|
/// Get [`BlindSignature`]s
|
||||||
@@ -234,7 +240,7 @@ pub trait SignaturesDatabase {
|
|||||||
/// Get [`BlindSignature`]s for quote
|
/// Get [`BlindSignature`]s for quote
|
||||||
async fn get_blind_signatures_for_quote(
|
async fn get_blind_signatures_for_quote(
|
||||||
&self,
|
&self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
) -> Result<Vec<BlindSignature>, Self::Err>;
|
) -> Result<Vec<BlindSignature>, Self::Err>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,13 @@ pub enum Error {
|
|||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
NUT22(#[from] crate::nuts::nut22::Error),
|
NUT22(#[from] crate::nuts::nut22::Error),
|
||||||
|
/// NUT04 Error
|
||||||
|
#[error(transparent)]
|
||||||
|
NUT04(#[from] crate::nuts::nut04::Error),
|
||||||
|
/// Quote ID Error
|
||||||
|
#[error(transparent)]
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
QuoteId(#[from] crate::quote_id::QuoteIdError),
|
||||||
/// Serde Error
|
/// Serde Error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Serde(#[from] serde_json::Error),
|
Serde(#[from] serde_json::Error),
|
||||||
|
|||||||
@@ -363,6 +363,10 @@ pub enum Error {
|
|||||||
/// NUT23 Error
|
/// NUT23 Error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
NUT23(#[from] crate::nuts::nut23::Error),
|
NUT23(#[from] crate::nuts::nut23::Error),
|
||||||
|
/// Quote ID Error
|
||||||
|
#[error(transparent)]
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
QuoteId(#[from] crate::quote_id::QuoteIdError),
|
||||||
/// From slice error
|
/// From slice error
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
TryFromSliceError(#[from] TryFromSliceError),
|
TryFromSliceError(#[from] TryFromSliceError),
|
||||||
|
|||||||
@@ -29,5 +29,7 @@ pub use bitcoin;
|
|||||||
pub use cashu::amount::{self, Amount};
|
pub use cashu::amount::{self, Amount};
|
||||||
pub use cashu::lightning_invoice::{self, Bolt11Invoice};
|
pub use cashu::lightning_invoice::{self, Bolt11Invoice};
|
||||||
pub use cashu::nuts::{self, *};
|
pub use cashu::nuts::{self, *};
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
|
pub use cashu::quote_id::{self, *};
|
||||||
pub use cashu::{dhke, ensure_cdk, mint_url, secret, util, SECP256K1};
|
pub use cashu::{dhke, ensure_cdk, mint_url, secret, util, SECP256K1};
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//! Mint types
|
//! Mint types
|
||||||
|
|
||||||
use bitcoin::bip32::DerivationPath;
|
use bitcoin::bip32::DerivationPath;
|
||||||
|
use cashu::quote_id::QuoteId;
|
||||||
use cashu::util::unix_time;
|
use cashu::util::unix_time;
|
||||||
use cashu::{
|
use cashu::{
|
||||||
Bolt11Invoice, MeltOptions, MeltQuoteBolt11Response, MintQuoteBolt11Response,
|
Bolt11Invoice, MeltOptions, MeltQuoteBolt11Response, MintQuoteBolt11Response,
|
||||||
@@ -19,7 +20,7 @@ use crate::{Amount, CurrencyUnit, Id, KeySetInfo, PublicKey};
|
|||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct MintQuote {
|
pub struct MintQuote {
|
||||||
/// Quote id
|
/// Quote id
|
||||||
pub id: Uuid,
|
pub id: QuoteId,
|
||||||
/// Amount of quote
|
/// Amount of quote
|
||||||
pub amount: Option<Amount>,
|
pub amount: Option<Amount>,
|
||||||
/// Unit of quote
|
/// Unit of quote
|
||||||
@@ -56,7 +57,7 @@ impl MintQuote {
|
|||||||
/// Create new [`MintQuote`]
|
/// Create new [`MintQuote`]
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: Option<Uuid>,
|
id: Option<QuoteId>,
|
||||||
request: String,
|
request: String,
|
||||||
unit: CurrencyUnit,
|
unit: CurrencyUnit,
|
||||||
amount: Option<Amount>,
|
amount: Option<Amount>,
|
||||||
@@ -70,7 +71,7 @@ impl MintQuote {
|
|||||||
payments: Vec<IncomingPayment>,
|
payments: Vec<IncomingPayment>,
|
||||||
issuance: Vec<Issuance>,
|
issuance: Vec<Issuance>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let id = id.unwrap_or(Uuid::new_v4());
|
let id = id.unwrap_or_else(QuoteId::new_uuid);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
@@ -230,7 +231,7 @@ impl Issuance {
|
|||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct MeltQuote {
|
pub struct MeltQuote {
|
||||||
/// Quote id
|
/// Quote id
|
||||||
pub id: Uuid,
|
pub id: QuoteId,
|
||||||
/// Quote unit
|
/// Quote unit
|
||||||
pub unit: CurrencyUnit,
|
pub unit: CurrencyUnit,
|
||||||
/// Quote amount
|
/// Quote amount
|
||||||
@@ -277,7 +278,7 @@ impl MeltQuote {
|
|||||||
let id = Uuid::new_v4();
|
let id = Uuid::new_v4();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
id,
|
id: QuoteId::UUID(id),
|
||||||
amount,
|
amount,
|
||||||
unit,
|
unit,
|
||||||
request,
|
request,
|
||||||
@@ -336,10 +337,10 @@ impl From<MintKeySetInfo> for KeySetInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MintQuote> for MintQuoteBolt11Response<Uuid> {
|
impl From<MintQuote> for MintQuoteBolt11Response<QuoteId> {
|
||||||
fn from(mint_quote: crate::mint::MintQuote) -> MintQuoteBolt11Response<Uuid> {
|
fn from(mint_quote: crate::mint::MintQuote) -> MintQuoteBolt11Response<QuoteId> {
|
||||||
MintQuoteBolt11Response {
|
MintQuoteBolt11Response {
|
||||||
quote: mint_quote.id,
|
quote: mint_quote.id.clone(),
|
||||||
state: mint_quote.state(),
|
state: mint_quote.state(),
|
||||||
request: mint_quote.request,
|
request: mint_quote.request,
|
||||||
expiry: Some(mint_quote.expiry),
|
expiry: Some(mint_quote.expiry),
|
||||||
@@ -352,18 +353,18 @@ impl From<MintQuote> for MintQuoteBolt11Response<Uuid> {
|
|||||||
|
|
||||||
impl From<MintQuote> for MintQuoteBolt11Response<String> {
|
impl From<MintQuote> for MintQuoteBolt11Response<String> {
|
||||||
fn from(quote: MintQuote) -> Self {
|
fn from(quote: MintQuote) -> Self {
|
||||||
let quote: MintQuoteBolt11Response<Uuid> = quote.into();
|
let quote: MintQuoteBolt11Response<QuoteId> = quote.into();
|
||||||
|
|
||||||
quote.into()
|
quote.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<crate::mint::MintQuote> for MintQuoteBolt12Response<Uuid> {
|
impl TryFrom<crate::mint::MintQuote> for MintQuoteBolt12Response<QuoteId> {
|
||||||
type Error = crate::Error;
|
type Error = crate::Error;
|
||||||
|
|
||||||
fn try_from(mint_quote: crate::mint::MintQuote) -> Result<Self, Self::Error> {
|
fn try_from(mint_quote: crate::mint::MintQuote) -> Result<Self, Self::Error> {
|
||||||
Ok(MintQuoteBolt12Response {
|
Ok(MintQuoteBolt12Response {
|
||||||
quote: mint_quote.id,
|
quote: mint_quote.id.clone(),
|
||||||
request: mint_quote.request,
|
request: mint_quote.request,
|
||||||
expiry: Some(mint_quote.expiry),
|
expiry: Some(mint_quote.expiry),
|
||||||
amount_paid: mint_quote.amount_paid,
|
amount_paid: mint_quote.amount_paid,
|
||||||
@@ -379,16 +380,16 @@ impl TryFrom<MintQuote> for MintQuoteBolt12Response<String> {
|
|||||||
type Error = crate::Error;
|
type Error = crate::Error;
|
||||||
|
|
||||||
fn try_from(quote: MintQuote) -> Result<Self, Self::Error> {
|
fn try_from(quote: MintQuote) -> Result<Self, Self::Error> {
|
||||||
let quote: MintQuoteBolt12Response<Uuid> = quote.try_into()?;
|
let quote: MintQuoteBolt12Response<QuoteId> = quote.try_into()?;
|
||||||
|
|
||||||
Ok(quote.into())
|
Ok(quote.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&MeltQuote> for MeltQuoteBolt11Response<Uuid> {
|
impl From<&MeltQuote> for MeltQuoteBolt11Response<QuoteId> {
|
||||||
fn from(melt_quote: &MeltQuote) -> MeltQuoteBolt11Response<Uuid> {
|
fn from(melt_quote: &MeltQuote) -> MeltQuoteBolt11Response<QuoteId> {
|
||||||
MeltQuoteBolt11Response {
|
MeltQuoteBolt11Response {
|
||||||
quote: melt_quote.id,
|
quote: melt_quote.id.clone(),
|
||||||
payment_preimage: None,
|
payment_preimage: None,
|
||||||
change: None,
|
change: None,
|
||||||
state: melt_quote.state,
|
state: melt_quote.state,
|
||||||
@@ -402,11 +403,11 @@ impl From<&MeltQuote> for MeltQuoteBolt11Response<Uuid> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MeltQuote> for MeltQuoteBolt11Response<Uuid> {
|
impl From<MeltQuote> for MeltQuoteBolt11Response<QuoteId> {
|
||||||
fn from(melt_quote: MeltQuote) -> MeltQuoteBolt11Response<Uuid> {
|
fn from(melt_quote: MeltQuote) -> MeltQuoteBolt11Response<QuoteId> {
|
||||||
let paid = melt_quote.state == MeltQuoteState::Paid;
|
let paid = melt_quote.state == MeltQuoteState::Paid;
|
||||||
MeltQuoteBolt11Response {
|
MeltQuoteBolt11Response {
|
||||||
quote: melt_quote.id,
|
quote: melt_quote.id.clone(),
|
||||||
amount: melt_quote.amount,
|
amount: melt_quote.amount,
|
||||||
fee_reserve: melt_quote.fee_reserve,
|
fee_reserve: melt_quote.fee_reserve,
|
||||||
paid: Some(paid),
|
paid: Some(paid),
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ use cashu::nut17::{self};
|
|||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use cashu::nut17::{Error, Kind, Notification};
|
use cashu::nut17::{Error, Kind, Notification};
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
|
use cashu::quote_id::QuoteId;
|
||||||
|
#[cfg(feature = "mint")]
|
||||||
use cashu::{NotificationPayload, PublicKey};
|
use cashu::{NotificationPayload, PublicKey};
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "mint")]
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
|
use crate::pub_sub::index::{Index, Indexable, SubscriptionGlobalId};
|
||||||
@@ -45,14 +45,14 @@ impl TryFrom<IndexableParams> for Vec<Index<Notification>> {
|
|||||||
.map(|filter| {
|
.map(|filter| {
|
||||||
let idx = match params.kind {
|
let idx = match params.kind {
|
||||||
Kind::Bolt11MeltQuote => {
|
Kind::Bolt11MeltQuote => {
|
||||||
Notification::MeltQuoteBolt11(Uuid::from_str(&filter)?)
|
Notification::MeltQuoteBolt11(QuoteId::from_str(&filter)?)
|
||||||
}
|
}
|
||||||
Kind::Bolt11MintQuote => {
|
Kind::Bolt11MintQuote => {
|
||||||
Notification::MintQuoteBolt11(Uuid::from_str(&filter)?)
|
Notification::MintQuoteBolt11(QuoteId::from_str(&filter)?)
|
||||||
}
|
}
|
||||||
Kind::ProofState => Notification::ProofState(PublicKey::from_str(&filter)?),
|
Kind::ProofState => Notification::ProofState(PublicKey::from_str(&filter)?),
|
||||||
Kind::Bolt12MintQuote => {
|
Kind::Bolt12MintQuote => {
|
||||||
Notification::MintQuoteBolt12(Uuid::from_str(&filter)?)
|
Notification::MintQuoteBolt12(QuoteId::from_str(&filter)?)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ impl AsRef<SubId> for IndexableParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl Indexable for NotificationPayload<Uuid> {
|
impl Indexable for NotificationPayload<QuoteId> {
|
||||||
type Type = Notification;
|
type Type = Notification;
|
||||||
|
|
||||||
fn to_indexes(&self) -> Vec<Index<Self::Type>> {
|
fn to_indexes(&self) -> Vec<Index<Self::Type>> {
|
||||||
@@ -79,13 +79,19 @@ impl Indexable for NotificationPayload<Uuid> {
|
|||||||
vec![Index::from(Notification::ProofState(proof_state.y))]
|
vec![Index::from(Notification::ProofState(proof_state.y))]
|
||||||
}
|
}
|
||||||
NotificationPayload::MeltQuoteBolt11Response(melt_quote) => {
|
NotificationPayload::MeltQuoteBolt11Response(melt_quote) => {
|
||||||
vec![Index::from(Notification::MeltQuoteBolt11(melt_quote.quote))]
|
vec![Index::from(Notification::MeltQuoteBolt11(
|
||||||
|
melt_quote.quote.clone(),
|
||||||
|
))]
|
||||||
}
|
}
|
||||||
NotificationPayload::MintQuoteBolt11Response(mint_quote) => {
|
NotificationPayload::MintQuoteBolt11Response(mint_quote) => {
|
||||||
vec![Index::from(Notification::MintQuoteBolt11(mint_quote.quote))]
|
vec![Index::from(Notification::MintQuoteBolt11(
|
||||||
|
mint_quote.quote.clone(),
|
||||||
|
))]
|
||||||
}
|
}
|
||||||
NotificationPayload::MintQuoteBolt12Response(mint_quote) => {
|
NotificationPayload::MintQuoteBolt12Response(mint_quote) => {
|
||||||
vec![Index::from(Notification::MintQuoteBolt12(mint_quote.quote))]
|
vec![Index::from(Notification::MintQuoteBolt12(
|
||||||
|
mint_quote.quote.clone(),
|
||||||
|
))]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
use cashu::nut17::ws::JSON_RPC_VERSION;
|
use cashu::nut17::ws::JSON_RPC_VERSION;
|
||||||
use cashu::nut17::{self};
|
use cashu::nut17::{self};
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use cashu::NotificationPayload;
|
use cashu::quote_id::QuoteId;
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
use uuid::Uuid;
|
use cashu::NotificationPayload;
|
||||||
|
|
||||||
use crate::pub_sub::SubId;
|
use crate::pub_sub::SubId;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ pub type NotificationInner<T> = nut17::ws::NotificationInner<T, SubId>;
|
|||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
/// Converts a notification with UUID identifiers to a notification with string identifiers
|
/// Converts a notification with UUID identifiers to a notification with string identifiers
|
||||||
pub fn notification_uuid_to_notification_string(
|
pub fn notification_uuid_to_notification_string(
|
||||||
notification: NotificationInner<Uuid>,
|
notification: NotificationInner<QuoteId>,
|
||||||
) -> NotificationInner<String> {
|
) -> NotificationInner<String> {
|
||||||
nut17::ws::NotificationInner {
|
nut17::ws::NotificationInner {
|
||||||
sub_id: notification.sub_id,
|
sub_id: notification.sub_id,
|
||||||
@@ -69,7 +69,7 @@ pub fn notification_uuid_to_notification_string(
|
|||||||
|
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
/// Converts a notification to a websocket message that can be sent to clients
|
/// Converts a notification to a websocket message that can be sent to clients
|
||||||
pub fn notification_to_ws_message(notification: NotificationInner<Uuid>) -> WsMessageOrResponse {
|
pub fn notification_to_ws_message(notification: NotificationInner<QuoteId>) -> WsMessageOrResponse {
|
||||||
nut17::ws::WsMessageOrResponse::Notification(nut17::ws::WsNotification {
|
nut17::ws::WsMessageOrResponse::Notification(nut17::ws::WsNotification {
|
||||||
jsonrpc: JSON_RPC_VERSION.to_owned(),
|
jsonrpc: JSON_RPC_VERSION.to_owned(),
|
||||||
method: "subscribe".to_string(),
|
method: "subscribe".to_string(),
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ fn create_ldk_settings(
|
|||||||
url: format!("http://127.0.0.1:{port}"),
|
url: format!("http://127.0.0.1:{port}"),
|
||||||
listen_host: "127.0.0.1".to_string(),
|
listen_host: "127.0.0.1".to_string(),
|
||||||
listen_port: port,
|
listen_port: port,
|
||||||
|
seed: None,
|
||||||
mnemonic: Some(mnemonic),
|
mnemonic: Some(mnemonic),
|
||||||
signatory_url: None,
|
signatory_url: None,
|
||||||
signatory_certs: None,
|
signatory_certs: None,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::{env, fs};
|
|||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bip39::Mnemonic;
|
use bip39::Mnemonic;
|
||||||
|
use cashu::quote_id::QuoteId;
|
||||||
use cashu::{MeltQuoteBolt12Request, MintQuoteBolt12Request, MintQuoteBolt12Response};
|
use cashu::{MeltQuoteBolt12Request, MintQuoteBolt12Request, MintQuoteBolt12Response};
|
||||||
use cdk::amount::SplitTarget;
|
use cdk::amount::SplitTarget;
|
||||||
use cdk::cdk_database::{self, MintDatabase, WalletDatabase};
|
use cdk::cdk_database::{self, MintDatabase, WalletDatabase};
|
||||||
@@ -80,16 +81,15 @@ impl MintConnector for DirectMintConnection {
|
|||||||
&self,
|
&self,
|
||||||
quote_id: &str,
|
quote_id: &str,
|
||||||
) -> Result<MintQuoteBolt11Response<String>, Error> {
|
) -> Result<MintQuoteBolt11Response<String>, Error> {
|
||||||
let quote_id_uuid = Uuid::from_str(quote_id).unwrap();
|
|
||||||
self.mint
|
self.mint
|
||||||
.check_mint_quote("e_id_uuid)
|
.check_mint_quote(&QuoteId::from_str(quote_id)?)
|
||||||
.await
|
.await
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_mint(&self, request: MintRequest<String>) -> Result<MintResponse, Error> {
|
async fn post_mint(&self, request: MintRequest<String>) -> Result<MintResponse, Error> {
|
||||||
let request_uuid = request.try_into().unwrap();
|
let request_id: MintRequest<QuoteId> = request.try_into().unwrap();
|
||||||
self.mint.process_mint_request(request_uuid).await
|
self.mint.process_mint_request(request_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_melt_quote(
|
async fn post_melt_quote(
|
||||||
@@ -106,9 +106,8 @@ impl MintConnector for DirectMintConnection {
|
|||||||
&self,
|
&self,
|
||||||
quote_id: &str,
|
quote_id: &str,
|
||||||
) -> Result<MeltQuoteBolt11Response<String>, Error> {
|
) -> Result<MeltQuoteBolt11Response<String>, Error> {
|
||||||
let quote_id_uuid = Uuid::from_str(quote_id).unwrap();
|
|
||||||
self.mint
|
self.mint
|
||||||
.check_melt_quote("e_id_uuid)
|
.check_melt_quote(&QuoteId::from_str(quote_id)?)
|
||||||
.await
|
.await
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
@@ -156,7 +155,7 @@ impl MintConnector for DirectMintConnection {
|
|||||||
&self,
|
&self,
|
||||||
request: MintQuoteBolt12Request,
|
request: MintQuoteBolt12Request,
|
||||||
) -> Result<MintQuoteBolt12Response<String>, Error> {
|
) -> Result<MintQuoteBolt12Response<String>, Error> {
|
||||||
let res: MintQuoteBolt12Response<Uuid> =
|
let res: MintQuoteBolt12Response<QuoteId> =
|
||||||
self.mint.get_mint_quote(request.into()).await?.try_into()?;
|
self.mint.get_mint_quote(request.into()).await?.try_into()?;
|
||||||
Ok(res.into())
|
Ok(res.into())
|
||||||
}
|
}
|
||||||
@@ -165,10 +164,9 @@ impl MintConnector for DirectMintConnection {
|
|||||||
&self,
|
&self,
|
||||||
quote_id: &str,
|
quote_id: &str,
|
||||||
) -> Result<MintQuoteBolt12Response<String>, Error> {
|
) -> Result<MintQuoteBolt12Response<String>, Error> {
|
||||||
let quote_id_uuid = Uuid::from_str(quote_id).unwrap();
|
let quote: MintQuoteBolt12Response<QuoteId> = self
|
||||||
let quote: MintQuoteBolt12Response<Uuid> = self
|
|
||||||
.mint
|
.mint
|
||||||
.check_mint_quote("e_id_uuid)
|
.check_mint_quote(&QuoteId::from_str(quote_id)?)
|
||||||
.await?
|
.await?
|
||||||
.try_into()?;
|
.try_into()?;
|
||||||
|
|
||||||
@@ -190,9 +188,8 @@ impl MintConnector for DirectMintConnection {
|
|||||||
&self,
|
&self,
|
||||||
quote_id: &str,
|
quote_id: &str,
|
||||||
) -> Result<MeltQuoteBolt11Response<String>, Error> {
|
) -> Result<MeltQuoteBolt11Response<String>, Error> {
|
||||||
let quote_id_uuid = Uuid::from_str(quote_id).unwrap();
|
|
||||||
self.mint
|
self.mint
|
||||||
.check_melt_quote("e_id_uuid)
|
.check_melt_quote(&QuoteId::from_str(quote_id)?)
|
||||||
.await
|
.await
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ pub fn create_fake_wallet_settings(
|
|||||||
url: format!("http://127.0.0.1:{port}"),
|
url: format!("http://127.0.0.1:{port}"),
|
||||||
listen_host: "127.0.0.1".to_string(),
|
listen_host: "127.0.0.1".to_string(),
|
||||||
listen_port: port,
|
listen_port: port,
|
||||||
|
seed: None,
|
||||||
mnemonic,
|
mnemonic,
|
||||||
signatory_url: signatory_config.as_ref().map(|(url, _)| url.clone()),
|
signatory_url: signatory_config.as_ref().map(|(url, _)| url.clone()),
|
||||||
signatory_certs: signatory_config
|
signatory_certs: signatory_config
|
||||||
@@ -233,6 +234,7 @@ pub fn create_cln_settings(
|
|||||||
url: format!("http://127.0.0.1:{port}"),
|
url: format!("http://127.0.0.1:{port}"),
|
||||||
listen_host: "127.0.0.1".to_string(),
|
listen_host: "127.0.0.1".to_string(),
|
||||||
listen_port: port,
|
listen_port: port,
|
||||||
|
seed: None,
|
||||||
mnemonic: Some(mnemonic),
|
mnemonic: Some(mnemonic),
|
||||||
signatory_url: None,
|
signatory_url: None,
|
||||||
signatory_certs: None,
|
signatory_certs: None,
|
||||||
@@ -277,6 +279,7 @@ pub fn create_lnd_settings(
|
|||||||
url: format!("http://127.0.0.1:{port}"),
|
url: format!("http://127.0.0.1:{port}"),
|
||||||
listen_host: "127.0.0.1".to_string(),
|
listen_host: "127.0.0.1".to_string(),
|
||||||
listen_port: port,
|
listen_port: port,
|
||||||
|
seed: None,
|
||||||
mnemonic: Some(mnemonic),
|
mnemonic: Some(mnemonic),
|
||||||
signatory_url: None,
|
signatory_url: None,
|
||||||
signatory_certs: None,
|
signatory_certs: None,
|
||||||
|
|||||||
@@ -677,7 +677,7 @@ impl CdkMint for MintRPCServer {
|
|||||||
_ => {
|
_ => {
|
||||||
// Create a new quote with the same values
|
// Create a new quote with the same values
|
||||||
let quote = MintQuote::new(
|
let quote = MintQuote::new(
|
||||||
Some(mint_quote.id), // id
|
Some(mint_quote.id.clone()), // id
|
||||||
mint_quote.request.clone(), // request
|
mint_quote.request.clone(), // request
|
||||||
mint_quote.unit.clone(), // unit
|
mint_quote.unit.clone(), // unit
|
||||||
mint_quote.amount, // amount
|
mint_quote.amount, // amount
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ pub struct Info {
|
|||||||
pub url: String,
|
pub url: String,
|
||||||
pub listen_host: String,
|
pub listen_host: String,
|
||||||
pub listen_port: u16,
|
pub listen_port: u16,
|
||||||
|
/// Overrides mnemonic
|
||||||
|
pub seed: Option<String>,
|
||||||
pub mnemonic: Option<String>,
|
pub mnemonic: Option<String>,
|
||||||
pub signatory_url: Option<String>,
|
pub signatory_url: Option<String>,
|
||||||
pub signatory_certs: Option<String>,
|
pub signatory_certs: Option<String>,
|
||||||
@@ -74,6 +76,7 @@ impl Default for Info {
|
|||||||
url: String::new(),
|
url: String::new(),
|
||||||
listen_host: "127.0.0.1".to_string(),
|
listen_host: "127.0.0.1".to_string(),
|
||||||
listen_port: 8091, // Default to port 8091 instead of 0
|
listen_port: 8091, // Default to port 8091 instead of 0
|
||||||
|
seed: None,
|
||||||
mnemonic: None,
|
mnemonic: None,
|
||||||
signatory_url: None,
|
signatory_url: None,
|
||||||
signatory_certs: None,
|
signatory_certs: None,
|
||||||
@@ -88,7 +91,7 @@ impl Default for Info {
|
|||||||
impl std::fmt::Debug for Info {
|
impl std::fmt::Debug for Info {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
// Use a fallback approach that won't panic
|
// Use a fallback approach that won't panic
|
||||||
let mnemonic_display = {
|
let mnemonic_display: String = {
|
||||||
if let Some(mnemonic) = self.mnemonic.as_ref() {
|
if let Some(mnemonic) = self.mnemonic.as_ref() {
|
||||||
let hash = sha256::Hash::hash(mnemonic.as_bytes());
|
let hash = sha256::Hash::hash(mnemonic.as_bytes());
|
||||||
format!("<hashed: {hash}>")
|
format!("<hashed: {hash}>")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub const DATABASE_URL_ENV_VAR: &str = "CDK_MINTD_DATABASE_URL"; // Legacy, main
|
|||||||
pub const ENV_URL: &str = "CDK_MINTD_URL";
|
pub const ENV_URL: &str = "CDK_MINTD_URL";
|
||||||
pub const ENV_LISTEN_HOST: &str = "CDK_MINTD_LISTEN_HOST";
|
pub const ENV_LISTEN_HOST: &str = "CDK_MINTD_LISTEN_HOST";
|
||||||
pub const ENV_LISTEN_PORT: &str = "CDK_MINTD_LISTEN_PORT";
|
pub const ENV_LISTEN_PORT: &str = "CDK_MINTD_LISTEN_PORT";
|
||||||
|
pub const ENV_SEED: &str = "CDK_MINTD_SEED";
|
||||||
pub const ENV_MNEMONIC: &str = "CDK_MINTD_MNEMONIC";
|
pub const ENV_MNEMONIC: &str = "CDK_MINTD_MNEMONIC";
|
||||||
pub const ENV_SIGNATORY_URL: &str = "CDK_MINTD_SIGNATORY_URL";
|
pub const ENV_SIGNATORY_URL: &str = "CDK_MINTD_SIGNATORY_URL";
|
||||||
pub const ENV_SIGNATORY_CERTS: &str = "CDK_MINTD_SIGNATORY_CERTS";
|
pub const ENV_SIGNATORY_CERTS: &str = "CDK_MINTD_SIGNATORY_CERTS";
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ impl Info {
|
|||||||
self.signatory_certs = Some(signatory_certs);
|
self.signatory_certs = Some(signatory_certs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(seed) = env::var(ENV_SEED) {
|
||||||
|
self.seed = Some(seed);
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(mnemonic) = env::var(ENV_MNEMONIC) {
|
if let Ok(mnemonic) = env::var(ENV_MNEMONIC) {
|
||||||
self.mnemonic = Some(mnemonic);
|
self.mnemonic = Some(mnemonic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -805,6 +805,9 @@ async fn build_mint(
|
|||||||
.await?,
|
.await?,
|
||||||
))
|
))
|
||||||
.await?)
|
.await?)
|
||||||
|
} else if let Some(seed) = settings.info.seed.clone() {
|
||||||
|
let seed_bytes: Vec<u8> = seed.into();
|
||||||
|
Ok(mint_builder.build_with_seed(keystore, &seed_bytes).await?)
|
||||||
} else if let Some(mnemonic) = settings
|
} else if let Some(mnemonic) = settings
|
||||||
.info
|
.info
|
||||||
.mnemonic
|
.mnemonic
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use cdk_common::mint::{
|
|||||||
};
|
};
|
||||||
use cdk_common::nut00::ProofsMethods;
|
use cdk_common::nut00::ProofsMethods;
|
||||||
use cdk_common::payment::PaymentIdentifier;
|
use cdk_common::payment::PaymentIdentifier;
|
||||||
|
use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::secret::Secret;
|
use cdk_common::secret::Secret;
|
||||||
use cdk_common::state::check_state_transition;
|
use cdk_common::state::check_state_transition;
|
||||||
use cdk_common::util::unix_time;
|
use cdk_common::util::unix_time;
|
||||||
@@ -309,7 +310,7 @@ where
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
async fn get_mint_quote_payments<C>(
|
async fn get_mint_quote_payments<C>(
|
||||||
conn: &C,
|
conn: &C,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
) -> Result<Vec<IncomingPayment>, Error>
|
) -> Result<Vec<IncomingPayment>, Error>
|
||||||
where
|
where
|
||||||
C: DatabaseExecutor + Send + Sync,
|
C: DatabaseExecutor + Send + Sync,
|
||||||
@@ -327,7 +328,13 @@ where
|
|||||||
quote_id=:quote_id
|
quote_id=:quote_id
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_all(conn)
|
.fetch_all(conn)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -344,7 +351,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
async fn get_mint_quote_issuance<C>(conn: &C, quote_id: &Uuid) -> Result<Vec<Issuance>, Error>
|
async fn get_mint_quote_issuance<C>(conn: &C, quote_id: &QuoteId) -> Result<Vec<Issuance>, Error>
|
||||||
where
|
where
|
||||||
C: DatabaseExecutor + Send + Sync,
|
C: DatabaseExecutor + Send + Sync,
|
||||||
{
|
{
|
||||||
@@ -356,7 +363,13 @@ FROM mint_quote_issued
|
|||||||
WHERE quote_id=:quote_id
|
WHERE quote_id=:quote_id
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_all(conn)
|
.fetch_all(conn)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -542,7 +555,7 @@ where
|
|||||||
#[instrument(skip(self))]
|
#[instrument(skip(self))]
|
||||||
async fn increment_mint_quote_amount_paid(
|
async fn increment_mint_quote_amount_paid(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
amount_paid: Amount,
|
amount_paid: Amount,
|
||||||
payment_id: String,
|
payment_id: String,
|
||||||
) -> Result<Amount, Self::Err> {
|
) -> Result<Amount, Self::Err> {
|
||||||
@@ -578,7 +591,13 @@ where
|
|||||||
FOR UPDATE
|
FOR UPDATE
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_one(&self.inner)
|
.fetch_one(&self.inner)
|
||||||
.await
|
.await
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
@@ -613,7 +632,13 @@ where
|
|||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("amount_paid", new_amount_paid.to_i64())
|
.bind("amount_paid", new_amount_paid.to_i64())
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await
|
.await
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
@@ -628,7 +653,13 @@ where
|
|||||||
VALUES (:quote_id, :payment_id, :amount, :timestamp)
|
VALUES (:quote_id, :payment_id, :amount, :timestamp)
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.bind("payment_id", payment_id)
|
.bind("payment_id", payment_id)
|
||||||
.bind("amount", amount_paid.to_i64())
|
.bind("amount", amount_paid.to_i64())
|
||||||
.bind("timestamp", unix_time() as i64)
|
.bind("timestamp", unix_time() as i64)
|
||||||
@@ -645,7 +676,7 @@ where
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn increment_mint_quote_amount_issued(
|
async fn increment_mint_quote_amount_issued(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
amount_issued: Amount,
|
amount_issued: Amount,
|
||||||
) -> Result<Amount, Self::Err> {
|
) -> Result<Amount, Self::Err> {
|
||||||
// Get current amount_issued from quote
|
// Get current amount_issued from quote
|
||||||
@@ -657,7 +688,13 @@ where
|
|||||||
FOR UPDATE
|
FOR UPDATE
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_one(&self.inner)
|
.fetch_one(&self.inner)
|
||||||
.await
|
.await
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
@@ -685,7 +722,13 @@ where
|
|||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("amount_issued", new_amount_issued.to_i64())
|
.bind("amount_issued", new_amount_issued.to_i64())
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await
|
.await
|
||||||
.inspect_err(|err| {
|
.inspect_err(|err| {
|
||||||
@@ -701,7 +744,13 @@ INSERT INTO mint_quote_issued
|
|||||||
VALUES (:quote_id, :amount, :timestamp);
|
VALUES (:quote_id, :amount, :timestamp);
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.bind("amount", amount_issued.to_i64())
|
.bind("amount", amount_issued.to_i64())
|
||||||
.bind("timestamp", current_time as i64)
|
.bind("timestamp", current_time as i64)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
@@ -741,9 +790,15 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_mint_quote(&mut self, quote_id: &Uuid) -> Result<(), Self::Err> {
|
async fn remove_mint_quote(&mut self, quote_id: &QuoteId) -> Result<(), Self::Err> {
|
||||||
query(r#"DELETE FROM mint_quote WHERE id=:id"#)?
|
query(r#"DELETE FROM mint_quote WHERE id=:id"#)?
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -800,13 +855,16 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
|
|
||||||
async fn update_melt_quote_request_lookup_id(
|
async fn update_melt_quote_request_lookup_id(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
new_request_lookup_id: &PaymentIdentifier,
|
new_request_lookup_id: &PaymentIdentifier,
|
||||||
) -> Result<(), Self::Err> {
|
) -> Result<(), Self::Err> {
|
||||||
query(r#"UPDATE melt_quote SET request_lookup_id = :new_req_id, request_lookup_id_kind = :new_kind WHERE id = :id"#)?
|
query(r#"UPDATE melt_quote SET request_lookup_id = :new_req_id, request_lookup_id_kind = :new_kind WHERE id = :id"#)?
|
||||||
.bind("new_req_id", new_request_lookup_id.to_string())
|
.bind("new_req_id", new_request_lookup_id.to_string())
|
||||||
.bind("new_kind",new_request_lookup_id.kind() )
|
.bind("new_kind",new_request_lookup_id.kind() )
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind("id", match quote_id {
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
})
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -814,7 +872,7 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
|
|
||||||
async fn update_melt_quote_state(
|
async fn update_melt_quote_state(
|
||||||
&mut self,
|
&mut self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
state: MeltQuoteState,
|
state: MeltQuoteState,
|
||||||
payment_proof: Option<String>,
|
payment_proof: Option<String>,
|
||||||
) -> Result<(MeltQuoteState, mint::MeltQuote), Self::Err> {
|
) -> Result<(MeltQuoteState, mint::MeltQuote), Self::Err> {
|
||||||
@@ -842,7 +900,13 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
AND state != :state
|
AND state != :state
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.bind("state", state.to_string())
|
.bind("state", state.to_string())
|
||||||
.fetch_one(&self.inner)
|
.fetch_one(&self.inner)
|
||||||
.await?
|
.await?
|
||||||
@@ -856,13 +920,22 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
.bind("state", state.to_string())
|
.bind("state", state.to_string())
|
||||||
.bind("paid_time", current_time as i64)
|
.bind("paid_time", current_time as i64)
|
||||||
.bind("payment_preimage", payment_proof)
|
.bind("payment_preimage", payment_proof)
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind("id", match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
})
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
query(r#"UPDATE melt_quote SET state = :state WHERE id = :id"#)?
|
query(r#"UPDATE melt_quote SET state = :state WHERE id = :id"#)?
|
||||||
.bind("state", state.to_string())
|
.bind("state", state.to_string())
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
.await
|
.await
|
||||||
};
|
};
|
||||||
@@ -895,7 +968,7 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_mint_quote(&mut self, quote_id: &Uuid) -> Result<Option<MintQuote>, Self::Err> {
|
async fn get_mint_quote(&mut self, quote_id: &QuoteId) -> Result<Option<MintQuote>, Self::Err> {
|
||||||
let payments = get_mint_quote_payments(&self.inner, quote_id).await?;
|
let payments = get_mint_quote_payments(&self.inner, quote_id).await?;
|
||||||
let issuance = get_mint_quote_issuance(&self.inner, quote_id).await?;
|
let issuance = get_mint_quote_issuance(&self.inner, quote_id).await?;
|
||||||
|
|
||||||
@@ -920,7 +993,13 @@ VALUES (:quote_id, :amount, :timestamp);
|
|||||||
FOR UPDATE
|
FOR UPDATE
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_one(&self.inner)
|
.fetch_one(&self.inner)
|
||||||
.await?
|
.await?
|
||||||
.map(|row| sql_row_to_mint_quote(row, payments, issuance))
|
.map(|row| sql_row_to_mint_quote(row, payments, issuance))
|
||||||
@@ -1053,7 +1132,7 @@ where
|
|||||||
{
|
{
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
async fn get_mint_quote(&self, quote_id: &Uuid) -> Result<Option<MintQuote>, Self::Err> {
|
async fn get_mint_quote(&self, quote_id: &QuoteId) -> Result<Option<MintQuote>, Self::Err> {
|
||||||
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
||||||
|
|
||||||
let payments = get_mint_quote_payments(&*conn, quote_id).await?;
|
let payments = get_mint_quote_payments(&*conn, quote_id).await?;
|
||||||
@@ -1078,7 +1157,13 @@ where
|
|||||||
mint_quote
|
mint_quote
|
||||||
WHERE id = :id"#,
|
WHERE id = :id"#,
|
||||||
)?
|
)?
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_one(&*conn)
|
.fetch_one(&*conn)
|
||||||
.await?
|
.await?
|
||||||
.map(|row| sql_row_to_mint_quote(row, payments, issuance))
|
.map(|row| sql_row_to_mint_quote(row, payments, issuance))
|
||||||
@@ -1206,7 +1291,10 @@ where
|
|||||||
Ok(mint_quotes)
|
Ok(mint_quotes)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_melt_quote(&self, quote_id: &Uuid) -> Result<Option<mint::MeltQuote>, Self::Err> {
|
async fn get_melt_quote(
|
||||||
|
&self,
|
||||||
|
quote_id: &QuoteId,
|
||||||
|
) -> Result<Option<mint::MeltQuote>, Self::Err> {
|
||||||
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
||||||
Ok(query(
|
Ok(query(
|
||||||
r#"
|
r#"
|
||||||
@@ -1231,7 +1319,13 @@ where
|
|||||||
id=:id
|
id=:id
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("id", quote_id.as_hyphenated().to_string())
|
.bind(
|
||||||
|
"id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_one(&*conn)
|
.fetch_one(&*conn)
|
||||||
.await?
|
.await?
|
||||||
.map(sql_row_to_melt_quote)
|
.map(sql_row_to_melt_quote)
|
||||||
@@ -1386,7 +1480,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
blinded_messages: &[PublicKey],
|
blinded_messages: &[PublicKey],
|
||||||
blind_signatures: &[BlindSignature],
|
blind_signatures: &[BlindSignature],
|
||||||
quote_id: Option<Uuid>,
|
quote_id: Option<QuoteId>,
|
||||||
) -> Result<(), Self::Err> {
|
) -> Result<(), Self::Err> {
|
||||||
let current_time = unix_time();
|
let current_time = unix_time();
|
||||||
|
|
||||||
@@ -1403,7 +1497,10 @@ where
|
|||||||
.bind("amount", u64::from(signature.amount) as i64)
|
.bind("amount", u64::from(signature.amount) as i64)
|
||||||
.bind("keyset_id", signature.keyset_id.to_string())
|
.bind("keyset_id", signature.keyset_id.to_string())
|
||||||
.bind("c", signature.c.to_bytes().to_vec())
|
.bind("c", signature.c.to_bytes().to_vec())
|
||||||
.bind("quote_id", quote_id.map(|q| q.hyphenated().to_string()))
|
.bind("quote_id", quote_id.as_ref().map(|q| match q {
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
QuoteId::UUID(u) => u.hyphenated().to_string(),
|
||||||
|
}))
|
||||||
.bind(
|
.bind(
|
||||||
"dleq_e",
|
"dleq_e",
|
||||||
signature.dleq.as_ref().map(|dleq| dleq.e.to_secret_hex()),
|
signature.dleq.as_ref().map(|dleq| dleq.e.to_secret_hex()),
|
||||||
@@ -1547,7 +1644,7 @@ where
|
|||||||
/// Get [`BlindSignature`]s for quote
|
/// Get [`BlindSignature`]s for quote
|
||||||
async fn get_blind_signatures_for_quote(
|
async fn get_blind_signatures_for_quote(
|
||||||
&self,
|
&self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
) -> Result<Vec<BlindSignature>, Self::Err> {
|
) -> Result<Vec<BlindSignature>, Self::Err> {
|
||||||
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
||||||
Ok(query(
|
Ok(query(
|
||||||
@@ -1564,7 +1661,13 @@ where
|
|||||||
quote_id=:quote_id
|
quote_id=:quote_id
|
||||||
"#,
|
"#,
|
||||||
)?
|
)?
|
||||||
.bind("quote_id", quote_id.to_string())
|
.bind(
|
||||||
|
"quote_id",
|
||||||
|
match quote_id {
|
||||||
|
QuoteId::BASE64(s) => s.to_string(),
|
||||||
|
QuoteId::UUID(u) => u.as_hyphenated().to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
.fetch_all(&*conn)
|
.fetch_all(&*conn)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -1658,7 +1761,7 @@ fn sql_row_to_mint_quote(
|
|||||||
let payment_method = column_as_string!(payment_method, PaymentMethod::from_str);
|
let payment_method = column_as_string!(payment_method, PaymentMethod::from_str);
|
||||||
|
|
||||||
Ok(MintQuote::new(
|
Ok(MintQuote::new(
|
||||||
Some(Uuid::parse_str(&id).map_err(|_| Error::InvalidUuid(id))?),
|
Some(QuoteId::from_str(&id)?),
|
||||||
request_str,
|
request_str,
|
||||||
column_as_string!(unit, CurrencyUnit::from_str),
|
column_as_string!(unit, CurrencyUnit::from_str),
|
||||||
amount.map(Amount::from),
|
amount.map(Amount::from),
|
||||||
@@ -1745,7 +1848,7 @@ fn sql_row_to_melt_quote(row: Vec<Column>) -> Result<mint::MeltQuote, Error> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(MeltQuote {
|
Ok(MeltQuote {
|
||||||
id: Uuid::parse_str(&id).map_err(|_| Error::InvalidUuid(id))?,
|
id: QuoteId::from_str(&id)?,
|
||||||
unit: CurrencyUnit::from_str(&unit)?,
|
unit: CurrencyUnit::from_str(&unit)?,
|
||||||
amount: Amount::from(amount),
|
amount: Amount::from(amount),
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use cdk_common::payment::{
|
|||||||
Bolt11IncomingPaymentOptions, Bolt11Settings, Bolt12IncomingPaymentOptions,
|
Bolt11IncomingPaymentOptions, Bolt11Settings, Bolt12IncomingPaymentOptions,
|
||||||
IncomingPaymentOptions, WaitPaymentResponse,
|
IncomingPaymentOptions, WaitPaymentResponse,
|
||||||
};
|
};
|
||||||
|
use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::util::unix_time;
|
use cdk_common::util::unix_time;
|
||||||
use cdk_common::{
|
use cdk_common::{
|
||||||
database, ensure_cdk, Amount, CurrencyUnit, Error, MintQuoteBolt11Request,
|
database, ensure_cdk, Amount, CurrencyUnit, Error, MintQuoteBolt11Request,
|
||||||
@@ -10,7 +11,6 @@ use cdk_common::{
|
|||||||
MintRequest, MintResponse, NotificationPayload, PaymentMethod, PublicKey,
|
MintRequest, MintResponse, NotificationPayload, PaymentMethod, PublicKey,
|
||||||
};
|
};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::mint::Verification;
|
use crate::mint::Verification;
|
||||||
use crate::Mint;
|
use crate::Mint;
|
||||||
@@ -49,12 +49,12 @@ impl From<MintQuoteBolt12Request> for MintQuoteRequest {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum MintQuoteResponse {
|
pub enum MintQuoteResponse {
|
||||||
/// Lightning Network BOLT11 invoice response
|
/// Lightning Network BOLT11 invoice response
|
||||||
Bolt11(MintQuoteBolt11Response<Uuid>),
|
Bolt11(MintQuoteBolt11Response<QuoteId>),
|
||||||
/// Lightning Network BOLT12 offer response
|
/// Lightning Network BOLT12 offer response
|
||||||
Bolt12(MintQuoteBolt12Response<Uuid>),
|
Bolt12(MintQuoteBolt12Response<QuoteId>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<MintQuoteResponse> for MintQuoteBolt11Response<Uuid> {
|
impl TryFrom<MintQuoteResponse> for MintQuoteBolt11Response<QuoteId> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(response: MintQuoteResponse) -> Result<Self, Self::Error> {
|
fn try_from(response: MintQuoteResponse) -> Result<Self, Self::Error> {
|
||||||
@@ -65,7 +65,7 @@ impl TryFrom<MintQuoteResponse> for MintQuoteBolt11Response<Uuid> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<MintQuoteResponse> for MintQuoteBolt12Response<Uuid> {
|
impl TryFrom<MintQuoteResponse> for MintQuoteBolt12Response<QuoteId> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn try_from(response: MintQuoteResponse) -> Result<Self, Self::Error> {
|
fn try_from(response: MintQuoteResponse) -> Result<Self, Self::Error> {
|
||||||
@@ -82,7 +82,7 @@ impl TryFrom<MintQuote> for MintQuoteResponse {
|
|||||||
fn try_from(quote: MintQuote) -> Result<Self, Self::Error> {
|
fn try_from(quote: MintQuote) -> Result<Self, Self::Error> {
|
||||||
match quote.payment_method {
|
match quote.payment_method {
|
||||||
PaymentMethod::Bolt11 => {
|
PaymentMethod::Bolt11 => {
|
||||||
let bolt11_response: MintQuoteBolt11Response<Uuid> = quote.into();
|
let bolt11_response: MintQuoteBolt11Response<QuoteId> = quote.into();
|
||||||
Ok(MintQuoteResponse::Bolt11(bolt11_response))
|
Ok(MintQuoteResponse::Bolt11(bolt11_response))
|
||||||
}
|
}
|
||||||
PaymentMethod::Bolt12 => {
|
PaymentMethod::Bolt12 => {
|
||||||
@@ -298,12 +298,12 @@ impl Mint {
|
|||||||
|
|
||||||
match payment_method {
|
match payment_method {
|
||||||
PaymentMethod::Bolt11 => {
|
PaymentMethod::Bolt11 => {
|
||||||
let res: MintQuoteBolt11Response<Uuid> = quote.clone().into();
|
let res: MintQuoteBolt11Response<QuoteId> = quote.clone().into();
|
||||||
self.pubsub_manager
|
self.pubsub_manager
|
||||||
.broadcast(NotificationPayload::MintQuoteBolt11Response(res));
|
.broadcast(NotificationPayload::MintQuoteBolt11Response(res));
|
||||||
}
|
}
|
||||||
PaymentMethod::Bolt12 => {
|
PaymentMethod::Bolt12 => {
|
||||||
let res: MintQuoteBolt12Response<Uuid> = quote.clone().try_into()?;
|
let res: MintQuoteBolt12Response<QuoteId> = quote.clone().try_into()?;
|
||||||
self.pubsub_manager
|
self.pubsub_manager
|
||||||
.broadcast(NotificationPayload::MintQuoteBolt12Response(res));
|
.broadcast(NotificationPayload::MintQuoteBolt12Response(res));
|
||||||
}
|
}
|
||||||
@@ -333,7 +333,7 @@ impl Mint {
|
|||||||
/// * `Ok(())` if removal was successful
|
/// * `Ok(())` if removal was successful
|
||||||
/// * `Error` if the quote doesn't exist or removal fails
|
/// * `Error` if the quote doesn't exist or removal fails
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn remove_mint_quote(&self, quote_id: &Uuid) -> Result<(), Error> {
|
pub async fn remove_mint_quote(&self, quote_id: &QuoteId) -> Result<(), Error> {
|
||||||
let mut tx = self.localstore.begin_transaction().await?;
|
let mut tx = self.localstore.begin_transaction().await?;
|
||||||
tx.remove_mint_quote(quote_id).await?;
|
tx.remove_mint_quote(quote_id).await?;
|
||||||
tx.commit().await?;
|
tx.commit().await?;
|
||||||
@@ -421,7 +421,7 @@ impl Mint {
|
|||||||
/// * `MintQuoteResponse` - The current state of the quote
|
/// * `MintQuoteResponse` - The current state of the quote
|
||||||
/// * `Error` if the quote doesn't exist or checking fails
|
/// * `Error` if the quote doesn't exist or checking fails
|
||||||
#[instrument(skip(self))]
|
#[instrument(skip(self))]
|
||||||
pub async fn check_mint_quote(&self, quote_id: &Uuid) -> Result<MintQuoteResponse, Error> {
|
pub async fn check_mint_quote(&self, quote_id: &QuoteId) -> Result<MintQuoteResponse, Error> {
|
||||||
let mut quote = self
|
let mut quote = self
|
||||||
.localstore
|
.localstore
|
||||||
.get_mint_quote(quote_id)
|
.get_mint_quote(quote_id)
|
||||||
@@ -454,7 +454,7 @@ impl Mint {
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn process_mint_request(
|
pub async fn process_mint_request(
|
||||||
&self,
|
&self,
|
||||||
mint_request: MintRequest<Uuid>,
|
mint_request: MintRequest<QuoteId>,
|
||||||
) -> Result<MintResponse, Error> {
|
) -> Result<MintResponse, Error> {
|
||||||
let mut mint_quote = self
|
let mut mint_quote = self
|
||||||
.localstore
|
.localstore
|
||||||
@@ -563,7 +563,7 @@ impl Mint {
|
|||||||
.map(|p| p.blinded_secret)
|
.map(|p| p.blinded_secret)
|
||||||
.collect::<Vec<PublicKey>>(),
|
.collect::<Vec<PublicKey>>(),
|
||||||
&blind_signatures,
|
&blind_signatures,
|
||||||
Some(mint_request.quote),
|
Some(mint_request.quote.clone()),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ use cdk_common::payment::{
|
|||||||
Bolt11OutgoingPaymentOptions, Bolt12OutgoingPaymentOptions, OutgoingPaymentOptions,
|
Bolt11OutgoingPaymentOptions, Bolt12OutgoingPaymentOptions, OutgoingPaymentOptions,
|
||||||
PaymentIdentifier,
|
PaymentIdentifier,
|
||||||
};
|
};
|
||||||
|
use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::{MeltOptions, MeltQuoteBolt12Request};
|
use cdk_common::{MeltOptions, MeltQuoteBolt12Request};
|
||||||
use lightning::offers::offer::Offer;
|
use lightning::offers::offer::Offer;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CurrencyUnit, MeltQuote, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MeltRequest, Mint,
|
CurrencyUnit, MeltQuote, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MeltRequest, Mint,
|
||||||
@@ -114,7 +114,7 @@ impl Mint {
|
|||||||
pub async fn get_melt_quote(
|
pub async fn get_melt_quote(
|
||||||
&self,
|
&self,
|
||||||
melt_quote_request: MeltQuoteRequest,
|
melt_quote_request: MeltQuoteRequest,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
match melt_quote_request {
|
match melt_quote_request {
|
||||||
MeltQuoteRequest::Bolt11(bolt11_request) => {
|
MeltQuoteRequest::Bolt11(bolt11_request) => {
|
||||||
self.get_melt_bolt11_quote_impl(&bolt11_request).await
|
self.get_melt_bolt11_quote_impl(&bolt11_request).await
|
||||||
@@ -130,7 +130,7 @@ impl Mint {
|
|||||||
async fn get_melt_bolt11_quote_impl(
|
async fn get_melt_bolt11_quote_impl(
|
||||||
&self,
|
&self,
|
||||||
melt_request: &MeltQuoteBolt11Request,
|
melt_request: &MeltQuoteBolt11Request,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
let MeltQuoteBolt11Request {
|
let MeltQuoteBolt11Request {
|
||||||
request,
|
request,
|
||||||
unit,
|
unit,
|
||||||
@@ -222,7 +222,7 @@ impl Mint {
|
|||||||
async fn get_melt_bolt12_quote_impl(
|
async fn get_melt_bolt12_quote_impl(
|
||||||
&self,
|
&self,
|
||||||
melt_request: &MeltQuoteBolt12Request,
|
melt_request: &MeltQuoteBolt12Request,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
let MeltQuoteBolt12Request {
|
let MeltQuoteBolt12Request {
|
||||||
request,
|
request,
|
||||||
unit,
|
unit,
|
||||||
@@ -322,8 +322,8 @@ impl Mint {
|
|||||||
#[instrument(skip(self))]
|
#[instrument(skip(self))]
|
||||||
pub async fn check_melt_quote(
|
pub async fn check_melt_quote(
|
||||||
&self,
|
&self,
|
||||||
quote_id: &Uuid,
|
quote_id: &QuoteId,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
let quote = self
|
let quote = self
|
||||||
.localstore
|
.localstore
|
||||||
.get_melt_quote(quote_id)
|
.get_melt_quote(quote_id)
|
||||||
@@ -363,7 +363,7 @@ impl Mint {
|
|||||||
pub async fn check_melt_expected_ln_fees(
|
pub async fn check_melt_expected_ln_fees(
|
||||||
&self,
|
&self,
|
||||||
melt_quote: &MeltQuote,
|
melt_quote: &MeltQuote,
|
||||||
melt_request: &MeltRequest<Uuid>,
|
melt_request: &MeltRequest<QuoteId>,
|
||||||
) -> Result<Option<Amount>, Error> {
|
) -> Result<Option<Amount>, Error> {
|
||||||
let quote_msats = to_unit(melt_quote.amount, &melt_quote.unit, &CurrencyUnit::Msat)
|
let quote_msats = to_unit(melt_quote.amount, &melt_quote.unit, &CurrencyUnit::Msat)
|
||||||
.expect("Quote unit is checked above that it can convert to msat");
|
.expect("Quote unit is checked above that it can convert to msat");
|
||||||
@@ -445,7 +445,7 @@ impl Mint {
|
|||||||
&self,
|
&self,
|
||||||
tx: &mut Box<dyn MintTransaction<'_, database::Error> + Send + Sync + '_>,
|
tx: &mut Box<dyn MintTransaction<'_, database::Error> + Send + Sync + '_>,
|
||||||
input_verification: Verification,
|
input_verification: Verification,
|
||||||
melt_request: &MeltRequest<Uuid>,
|
melt_request: &MeltRequest<QuoteId>,
|
||||||
) -> Result<(ProofWriter, MeltQuote), Error> {
|
) -> Result<(ProofWriter, MeltQuote), Error> {
|
||||||
let (state, quote) = tx
|
let (state, quote) = tx
|
||||||
.update_melt_quote_state(melt_request.quote(), MeltQuoteState::Pending, None)
|
.update_melt_quote_state(melt_request.quote(), MeltQuoteState::Pending, None)
|
||||||
@@ -518,8 +518,8 @@ impl Mint {
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn melt(
|
pub async fn melt(
|
||||||
&self,
|
&self,
|
||||||
melt_request: &MeltRequest<Uuid>,
|
melt_request: &MeltRequest<QuoteId>,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
async fn check_payment_state(
|
async fn check_payment_state(
|
||||||
ln: Arc<dyn MintPayment<Err = cdk_payment::Error> + Send + Sync>,
|
ln: Arc<dyn MintPayment<Err = cdk_payment::Error> + Send + Sync>,
|
||||||
@@ -743,10 +743,10 @@ impl Mint {
|
|||||||
mut tx: Box<dyn MintTransaction<'_, database::Error> + Send + Sync + '_>,
|
mut tx: Box<dyn MintTransaction<'_, database::Error> + Send + Sync + '_>,
|
||||||
mut proof_writer: ProofWriter,
|
mut proof_writer: ProofWriter,
|
||||||
quote: MeltQuote,
|
quote: MeltQuote,
|
||||||
melt_request: &MeltRequest<Uuid>,
|
melt_request: &MeltRequest<QuoteId>,
|
||||||
payment_preimage: Option<String>,
|
payment_preimage: Option<String>,
|
||||||
total_spent: Amount,
|
total_spent: Amount,
|
||||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
) -> Result<MeltQuoteBolt11Response<QuoteId>, Error> {
|
||||||
let input_ys = melt_request.inputs().ys()?;
|
let input_ys = melt_request.inputs().ys()?;
|
||||||
|
|
||||||
proof_writer
|
proof_writer
|
||||||
@@ -823,7 +823,7 @@ impl Mint {
|
|||||||
.map(|o| o.blinded_secret)
|
.map(|o| o.blinded_secret)
|
||||||
.collect::<Vec<PublicKey>>(),
|
.collect::<Vec<PublicKey>>(),
|
||||||
&change_sigs,
|
&change_sigs,
|
||||||
Some(quote.id),
|
Some(quote.id.clone()),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use cdk_common::database::MintAuthDatabase;
|
|||||||
use cdk_common::database::{self, MintDatabase, MintTransaction};
|
use cdk_common::database::{self, MintDatabase, MintTransaction};
|
||||||
use cdk_common::nuts::{self, BlindSignature, BlindedMessage, CurrencyUnit, Id, Kind};
|
use cdk_common::nuts::{self, BlindSignature, BlindedMessage, CurrencyUnit, Id, Kind};
|
||||||
use cdk_common::payment::WaitPaymentResponse;
|
use cdk_common::payment::WaitPaymentResponse;
|
||||||
|
pub use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::secret;
|
use cdk_common::secret;
|
||||||
use cdk_signatory::signatory::{Signatory, SignatoryKeySet};
|
use cdk_signatory::signatory::{Signatory, SignatoryKeySet};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
@@ -21,7 +22,6 @@ use subscription::PubSubManager;
|
|||||||
use tokio::sync::{Mutex, Notify};
|
use tokio::sync::{Mutex, Notify};
|
||||||
use tokio::task::{JoinHandle, JoinSet};
|
use tokio::task::{JoinHandle, JoinSet};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::cdk_payment::{self, MintPayment};
|
use crate::cdk_payment::{self, MintPayment};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
@@ -758,7 +758,7 @@ impl Mint {
|
|||||||
&self,
|
&self,
|
||||||
tx: &mut Box<dyn MintTransaction<'_, cdk_database::Error> + Send + Sync + '_>,
|
tx: &mut Box<dyn MintTransaction<'_, cdk_database::Error> + Send + Sync + '_>,
|
||||||
melt_quote: &MeltQuote,
|
melt_quote: &MeltQuote,
|
||||||
melt_request: &MeltRequest<Uuid>,
|
melt_request: &MeltRequest<QuoteId>,
|
||||||
) -> Result<Option<Amount>, Error> {
|
) -> Result<Option<Amount>, Error> {
|
||||||
let mint_quote = match tx
|
let mint_quote = match tx
|
||||||
.get_mint_quote_by_request(&melt_quote.request.to_string())
|
.get_mint_quote_by_request(&melt_quote.request.to_string())
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use std::sync::Arc;
|
|||||||
use cdk_common::database::{self, MintDatabase};
|
use cdk_common::database::{self, MintDatabase};
|
||||||
use cdk_common::mint::MintQuote;
|
use cdk_common::mint::MintQuote;
|
||||||
use cdk_common::nut17::Notification;
|
use cdk_common::nut17::Notification;
|
||||||
|
use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::{Amount, MintQuoteBolt12Response, NotificationPayload, PaymentMethod};
|
use cdk_common::{Amount, MintQuoteBolt12Response, NotificationPayload, PaymentMethod};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use super::OnSubscription;
|
use super::OnSubscription;
|
||||||
use crate::nuts::{
|
use crate::nuts::{
|
||||||
@@ -20,7 +20,9 @@ use crate::pub_sub;
|
|||||||
///
|
///
|
||||||
/// Nut-17 implementation is system-wide and not only through the WebSocket, so
|
/// Nut-17 implementation is system-wide and not only through the WebSocket, so
|
||||||
/// it is possible for another part of the system to subscribe to events.
|
/// it is possible for another part of the system to subscribe to events.
|
||||||
pub struct PubSubManager(pub_sub::Manager<NotificationPayload<Uuid>, Notification, OnSubscription>);
|
pub struct PubSubManager(
|
||||||
|
pub_sub::Manager<NotificationPayload<QuoteId>, Notification, OnSubscription>,
|
||||||
|
);
|
||||||
|
|
||||||
#[allow(clippy::default_constructed_unit_structs)]
|
#[allow(clippy::default_constructed_unit_structs)]
|
||||||
impl Default for PubSubManager {
|
impl Default for PubSubManager {
|
||||||
@@ -36,7 +38,7 @@ impl From<Arc<dyn MintDatabase<database::Error> + Send + Sync>> for PubSubManage
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for PubSubManager {
|
impl Deref for PubSubManager {
|
||||||
type Target = pub_sub::Manager<NotificationPayload<Uuid>, Notification, OnSubscription>;
|
type Target = pub_sub::Manager<NotificationPayload<QuoteId>, Notification, OnSubscription>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.0
|
&self.0
|
||||||
@@ -88,7 +90,7 @@ impl PubSubManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to emit a MintQuoteBolt11Response status
|
/// Helper function to emit a MintQuoteBolt11Response status
|
||||||
pub fn mint_quote_bolt11_status<E: Into<MintQuoteBolt11Response<Uuid>>>(
|
pub fn mint_quote_bolt11_status<E: Into<MintQuoteBolt11Response<QuoteId>>>(
|
||||||
&self,
|
&self,
|
||||||
quote: E,
|
quote: E,
|
||||||
new_state: MintQuoteState,
|
new_state: MintQuoteState,
|
||||||
@@ -100,7 +102,7 @@ impl PubSubManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to emit a MintQuoteBolt11Response status
|
/// Helper function to emit a MintQuoteBolt11Response status
|
||||||
pub fn mint_quote_bolt12_status<E: TryInto<MintQuoteBolt12Response<Uuid>>>(
|
pub fn mint_quote_bolt12_status<E: TryInto<MintQuoteBolt12Response<QuoteId>>>(
|
||||||
&self,
|
&self,
|
||||||
quote: E,
|
quote: E,
|
||||||
amount_paid: Amount,
|
amount_paid: Amount,
|
||||||
@@ -117,7 +119,7 @@ impl PubSubManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to emit a MeltQuoteBolt11Response status
|
/// Helper function to emit a MeltQuoteBolt11Response status
|
||||||
pub fn melt_quote_status<E: Into<MeltQuoteBolt11Response<Uuid>>>(
|
pub fn melt_quote_status<E: Into<MeltQuoteBolt11Response<QuoteId>>>(
|
||||||
&self,
|
&self,
|
||||||
quote: E,
|
quote: E,
|
||||||
payment_preimage: Option<String>,
|
payment_preimage: Option<String>,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use std::sync::Arc;
|
|||||||
use cdk_common::database::{self, MintDatabase};
|
use cdk_common::database::{self, MintDatabase};
|
||||||
use cdk_common::nut17::Notification;
|
use cdk_common::nut17::Notification;
|
||||||
use cdk_common::pub_sub::OnNewSubscription;
|
use cdk_common::pub_sub::OnNewSubscription;
|
||||||
|
use cdk_common::quote_id::QuoteId;
|
||||||
use cdk_common::{MintQuoteBolt12Response, NotificationPayload, PaymentMethod};
|
use cdk_common::{MintQuoteBolt12Response, NotificationPayload, PaymentMethod};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::nuts::{MeltQuoteBolt11Response, MintQuoteBolt11Response, ProofState, PublicKey};
|
use crate::nuts::{MeltQuoteBolt11Response, MintQuoteBolt11Response, ProofState, PublicKey};
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ pub struct OnSubscription(pub(crate) Option<Arc<dyn MintDatabase<database::Error
|
|||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl OnNewSubscription for OnSubscription {
|
impl OnNewSubscription for OnSubscription {
|
||||||
type Event = NotificationPayload<Uuid>;
|
type Event = NotificationPayload<QuoteId>;
|
||||||
type Index = Notification;
|
type Index = Notification;
|
||||||
|
|
||||||
async fn on_new_subscription(
|
async fn on_new_subscription(
|
||||||
@@ -65,7 +65,7 @@ impl OnNewSubscription for OnSubscription {
|
|||||||
quotes
|
quotes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|quote| quote.map(|x| x.into()))
|
.filter_map(|quote| quote.map(|x| x.into()))
|
||||||
.map(|x: MeltQuoteBolt11Response<Uuid>| x.into())
|
.map(|x: MeltQuoteBolt11Response<QuoteId>| x.into())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
.map_err(|e| e.to_string())?,
|
.map_err(|e| e.to_string())?,
|
||||||
@@ -82,12 +82,13 @@ impl OnNewSubscription for OnSubscription {
|
|||||||
.filter_map(|quote| {
|
.filter_map(|quote| {
|
||||||
quote.and_then(|x| match x.payment_method {
|
quote.and_then(|x| match x.payment_method {
|
||||||
PaymentMethod::Bolt11 => {
|
PaymentMethod::Bolt11 => {
|
||||||
let response: MintQuoteBolt11Response<Uuid> = x.into();
|
let response: MintQuoteBolt11Response<QuoteId> = x.into();
|
||||||
Some(response.into())
|
Some(response.into())
|
||||||
}
|
}
|
||||||
PaymentMethod::Bolt12 => match x.try_into() {
|
PaymentMethod::Bolt12 => match x.try_into() {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
let response: MintQuoteBolt12Response<Uuid> = response;
|
let response: MintQuoteBolt12Response<QuoteId> =
|
||||||
|
response;
|
||||||
Some(response.into())
|
Some(response.into())
|
||||||
}
|
}
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
|
|||||||
Reference in New Issue
Block a user