mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-05 21:26:13 +01:00
refactor: nut-07 state
This commit is contained in:
@@ -209,15 +209,13 @@ impl Client for HttpClient {
|
||||
|
||||
/// Spendable check [NUT-07]
|
||||
#[cfg(feature = "nut07")]
|
||||
async fn post_check_spendable(
|
||||
async fn post_check_state(
|
||||
&self,
|
||||
mint_url: Url,
|
||||
proofs: Vec<nut00::mint::Proof>,
|
||||
) -> Result<CheckSpendableResponse, Error> {
|
||||
secrets: Vec<Secret>,
|
||||
) -> Result<CheckStateResponse, Error> {
|
||||
let url = join_url(mint_url, &["v1", "check"])?;
|
||||
let request = CheckSpendableRequest {
|
||||
proofs: proofs.to_owned(),
|
||||
};
|
||||
let request = CheckSpendableRequest { secrets };
|
||||
|
||||
let res = Request::post(url.as_str())
|
||||
.json(&request)
|
||||
|
||||
@@ -4,13 +4,14 @@ use std::println;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cashu::nuts::{
|
||||
nut00, BlindedMessage, CurrencyUnit, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
|
||||
BlindedMessage, CurrencyUnit, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
|
||||
MeltBolt11Response, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MintBolt11Request,
|
||||
MintBolt11Response, MintInfo, MintQuoteBolt11Request, MintQuoteBolt11Response, PreMintSecrets,
|
||||
Proof, SwapRequest, SwapResponse,
|
||||
};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::{CheckSpendableRequest, CheckSpendableResponse};
|
||||
use cashu::nuts::{CheckStateRequest, CheckStateResponse};
|
||||
use cashu::secret::Secret;
|
||||
use cashu::{Amount, Bolt11Invoice};
|
||||
use serde_json::Value;
|
||||
use tracing::warn;
|
||||
@@ -179,20 +180,20 @@ impl Client for HttpClient {
|
||||
|
||||
/// Spendable check [NUT-07]
|
||||
#[cfg(feature = "nut07")]
|
||||
async fn post_check_spendable(
|
||||
async fn post_check_state(
|
||||
&self,
|
||||
mint_url: Url,
|
||||
proofs: Vec<nut00::mint::Proof>,
|
||||
) -> Result<CheckSpendableResponse, Error> {
|
||||
let url = join_url(mint_url, &["v1", "check"])?;
|
||||
let request = CheckSpendableRequest { proofs };
|
||||
secrets: Vec<Secret>,
|
||||
) -> Result<CheckStateResponse, Error> {
|
||||
let url = join_url(mint_url, &["v1", "checkstate"])?;
|
||||
let request = CheckStateRequest { secrets };
|
||||
|
||||
let res = minreq::post(url)
|
||||
.with_json(&request)?
|
||||
.send()?
|
||||
.json::<Value>()?;
|
||||
|
||||
let response: Result<CheckSpendableResponse, serde_json::Error> =
|
||||
let response: Result<CheckStateResponse, serde_json::Error> =
|
||||
serde_json::from_value(res.clone());
|
||||
|
||||
match response {
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
//! Client to connet to mint
|
||||
|
||||
use async_trait::async_trait;
|
||||
#[cfg(feature = "mint")]
|
||||
use cashu::nuts::nut00;
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::CheckSpendableResponse;
|
||||
use cashu::nuts::CheckStateResponse;
|
||||
use cashu::nuts::{
|
||||
BlindedMessage, CurrencyUnit, KeySet, KeysetResponse, MeltBolt11Response,
|
||||
MeltQuoteBolt11Response, MintBolt11Response, MintInfo, MintQuoteBolt11Response, PreMintSecrets,
|
||||
Proof, SwapRequest, SwapResponse,
|
||||
};
|
||||
use cashu::secret::Secret;
|
||||
use cashu::{utils, Amount};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
@@ -127,11 +126,11 @@ pub trait Client {
|
||||
) -> Result<SwapResponse, Error>;
|
||||
|
||||
#[cfg(feature = "nut07")]
|
||||
async fn post_check_spendable(
|
||||
async fn post_check_state(
|
||||
&self,
|
||||
mint_url: Url,
|
||||
proofs: Vec<nut00::mint::Proof>,
|
||||
) -> Result<CheckSpendableResponse, Error>;
|
||||
secrets: Vec<Secret>,
|
||||
) -> Result<CheckStateResponse, Error>;
|
||||
|
||||
async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error>;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use cashu::dhke::{sign_message, verify_message};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::nut07::State;
|
||||
use cashu::nuts::{
|
||||
BlindedMessage, BlindedSignature, MeltBolt11Request, MeltBolt11Response, Proof, SwapRequest,
|
||||
SwapResponse, *,
|
||||
};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::{CheckSpendableRequest, CheckSpendableResponse};
|
||||
use cashu::nuts::{CheckStateRequest, CheckStateResponse};
|
||||
use cashu::secret::Secret;
|
||||
use cashu::types::{MeltQuote, MintQuote};
|
||||
use cashu::Amount;
|
||||
@@ -369,29 +371,41 @@ impl<L: LocalStore> Mint<L> {
|
||||
#[cfg(feature = "nut07")]
|
||||
pub async fn check_spendable(
|
||||
&self,
|
||||
check_spendable: &CheckSpendableRequest,
|
||||
) -> Result<CheckSpendableResponse, Error> {
|
||||
let mut spendable = Vec::with_capacity(check_spendable.proofs.len());
|
||||
let mut pending = Vec::with_capacity(check_spendable.proofs.len());
|
||||
check_spendable: &CheckStateRequest,
|
||||
) -> Result<CheckStateResponse, Error> {
|
||||
use cashu::nuts::nut07::ProofState;
|
||||
|
||||
for proof in &check_spendable.proofs {
|
||||
spendable.push(
|
||||
self.localstore
|
||||
.get_spent_proof(&proof.secret)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none(),
|
||||
);
|
||||
pending.push(
|
||||
self.localstore
|
||||
.get_pending_proof(&proof.secret)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some(),
|
||||
);
|
||||
let mut states = Vec::with_capacity(check_spendable.secrets.len());
|
||||
|
||||
for secret in &check_spendable.secrets {
|
||||
let state = if self
|
||||
.localstore
|
||||
.get_spent_proof(secret)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some()
|
||||
{
|
||||
State::Spent
|
||||
} else if self
|
||||
.localstore
|
||||
.get_pending_proof(secret)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_some()
|
||||
{
|
||||
State::Pending
|
||||
} else {
|
||||
State::Unspent
|
||||
};
|
||||
|
||||
states.push(ProofState {
|
||||
secret: secret.clone(),
|
||||
state,
|
||||
witness: None,
|
||||
})
|
||||
}
|
||||
|
||||
Ok(CheckSpendableResponse { spendable, pending })
|
||||
Ok(CheckStateResponse { states })
|
||||
}
|
||||
|
||||
pub async fn verify_melt_request(
|
||||
|
||||
@@ -5,13 +5,13 @@ use std::str::FromStr;
|
||||
use bip39::Mnemonic;
|
||||
use cashu::dhke::{construct_proofs, unblind_message};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::nut00::mint;
|
||||
use cashu::nuts::nut07::ProofState;
|
||||
use cashu::nuts::{
|
||||
BlindedSignature, CurrencyUnit, Id, KeySetInfo, Keys, PreMintSecrets, PreSwap, Proof, Proofs,
|
||||
SwapRequest, Token,
|
||||
};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::types::ProofsStatus;
|
||||
use cashu::secret::Secret;
|
||||
use cashu::types::{MeltQuote, Melted, MintQuote};
|
||||
use cashu::url::UncheckedUrl;
|
||||
use cashu::{Amount, Bolt11Invoice};
|
||||
@@ -125,30 +125,23 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
|
||||
&self,
|
||||
mint_url: UncheckedUrl,
|
||||
proofs: Proofs,
|
||||
) -> Result<ProofsStatus, Error> {
|
||||
) -> Result<Vec<ProofState>, Error> {
|
||||
let spendable = self
|
||||
.client
|
||||
.post_check_spendable(
|
||||
.post_check_state(
|
||||
mint_url.try_into()?,
|
||||
proofs
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|p| p.into())
|
||||
.collect::<mint::Proofs>()
|
||||
.map(|p| p.secret)
|
||||
.collect::<Vec<Secret>>()
|
||||
.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Separate proofs in spent and unspent based on mint response
|
||||
let (spendable, spent): (Vec<_>, Vec<_>) = proofs
|
||||
.iter()
|
||||
.zip(spendable.spendable.iter())
|
||||
.partition(|(_, &b)| b);
|
||||
|
||||
Ok(ProofsStatus {
|
||||
spendable: spendable.into_iter().map(|(s, _)| s).cloned().collect(),
|
||||
spent: spent.into_iter().map(|(s, _)| s).cloned().collect(),
|
||||
})
|
||||
Ok(spendable.states)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,7 +28,7 @@ pub use nut05::{MeltQuoteBolt11Request, MeltQuoteBolt11Response};
|
||||
pub use nut06::{MintInfo, MintVersion, Nuts};
|
||||
#[cfg(feature = "wallet")]
|
||||
#[cfg(feature = "nut07")]
|
||||
pub use nut07::{CheckSpendableRequest, CheckSpendableResponse};
|
||||
pub use nut07::{CheckStateRequest, CheckStateResponse};
|
||||
#[cfg(feature = "nut08")]
|
||||
pub use nut08::{MeltBolt11Request, MeltBolt11Response};
|
||||
|
||||
|
||||
@@ -3,21 +3,37 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::nut00::mint;
|
||||
use crate::secret::Secret;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum State {
|
||||
Spent,
|
||||
Unspent,
|
||||
Pending,
|
||||
}
|
||||
|
||||
/// Check spendabale request [NUT-07]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CheckSpendableRequest {
|
||||
pub proofs: mint::Proofs,
|
||||
pub struct CheckStateRequest {
|
||||
pub secrets: Vec<Secret>,
|
||||
}
|
||||
|
||||
/// Proof state [NUT-07]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ProofState {
|
||||
/// Secret of proof
|
||||
pub secret: Secret,
|
||||
/// State of proof
|
||||
pub state: State,
|
||||
/// Witness data if it is supplied
|
||||
pub witness: Option<String>,
|
||||
}
|
||||
|
||||
/// Check Spendable Response [NUT-07]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CheckSpendableResponse {
|
||||
/// booleans indicating whether the provided Proof is still spendable.
|
||||
/// In same order as provided proofs
|
||||
pub spendable: Vec<bool>,
|
||||
pub pending: Vec<bool>,
|
||||
pub struct CheckStateResponse {
|
||||
pub states: Vec<ProofState>,
|
||||
}
|
||||
|
||||
/// Spendable Settings
|
||||
|
||||
Reference in New Issue
Block a user