Skip to content

Commit

Permalink
fix: construct proofs with weong keys on mint
Browse files Browse the repository at this point in the history
  • Loading branch information
thesimplekid committed Jan 7, 2024
1 parent 7006594 commit ee417a4
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 30 deletions.
2 changes: 1 addition & 1 deletion crates/cashu-sdk/src/client/gloo_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl Client for HttpClient {
}

/// Split Token [NUT-06]
async fn post_split(
async fn post_swap(
&self,
mint_url: Url,
split_request: SwapRequest,
Expand Down
21 changes: 16 additions & 5 deletions crates/cashu-sdk/src/client/minreq_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use async_trait::async_trait;
use cashu::nuts::{
BlindedMessage, CurrencyUnit, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
BlindedMessage, CurrencyUnit, Id, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
MeltBolt11Response, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MintBolt11Request,
MintBolt11Response, MintInfo, MintQuoteBolt11Request, MintQuoteBolt11Response, PreMintSecrets,
Proof, SwapRequest, SwapResponse,
Expand Down Expand Up @@ -33,6 +33,19 @@ impl Client for HttpClient {
Ok(keys.keysets)
}

/// Get Keyset Keys [NUT-01]
async fn get_mint_keyset(&self, mint_url: Url, keyset_id: Id) -> Result<KeySet, Error> {
let url = join_url(mint_url, &["v1", "keys", &keyset_id.to_string()])?;
println!("{url}");
let keys = minreq::get(url).send()?.json::<KeysResponse>()?;
println!("{keys:?}");

// let keys: KeysResponse = serde_json::from_value(keys)?; //
// serde_json::from_str(&keys.to_string())?;
println!("{keys:?}");
Ok(keys.keysets[0].clone())
}

/// Get Keysets [NUT-02]
async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error> {
let url = join_url(mint_url, &["v1", "keysets"])?;
Expand Down Expand Up @@ -60,8 +73,6 @@ impl Client for HttpClient {

let res = minreq::post(url).with_json(&request)?.send()?;

print!("r: {:?}", res);

let response: Result<MintQuoteBolt11Response, serde_json::Error> =
serde_json::from_value(res.json()?);

Expand Down Expand Up @@ -159,7 +170,7 @@ impl Client for HttpClient {
}

/// Split Token [NUT-06]
async fn post_split(
async fn post_swap(
&self,
mint_url: Url,
split_request: SwapRequest,
Expand All @@ -169,7 +180,7 @@ impl Client for HttpClient {

let res = minreq::post(url).with_json(&split_request)?.send()?;

println!("{:?}", res);
println!("{:?}", res.json::<Value>());

let response: Result<SwapResponse, serde_json::Error> =
serde_json::from_value(res.json::<Value>()?.clone());
Expand Down
6 changes: 4 additions & 2 deletions crates/cashu-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use async_trait::async_trait;
#[cfg(feature = "nut07")]
use cashu::nuts::CheckStateResponse;
use cashu::nuts::{
BlindedMessage, CurrencyUnit, KeySet, KeysetResponse, MeltBolt11Response,
BlindedMessage, CurrencyUnit, Id, KeySet, KeysetResponse, MeltBolt11Response,
MeltQuoteBolt11Response, MintBolt11Response, MintInfo, MintQuoteBolt11Response, PreMintSecrets,
Proof, SwapRequest, SwapResponse,
};
Expand Down Expand Up @@ -88,6 +88,8 @@ pub trait Client {

async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error>;

async fn get_mint_keyset(&self, mint_url: Url, keyset_id: Id) -> Result<KeySet, Error>;

async fn post_mint_quote(
&self,
mint_url: Url,
Expand Down Expand Up @@ -120,7 +122,7 @@ pub trait Client {
// REVIEW: Should be consistent aboue passing in the Request struct or the
// compnatants and making it within the function. Here the struct is passed
// in but in check spendable and melt the compants are passed in
async fn post_split(
async fn post_swap(
&self,
mint_url: Url,
split_request: SwapRequest,
Expand Down
5 changes: 3 additions & 2 deletions crates/cashu-sdk/src/wallet/localstore/redb_store.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;

use async_trait::async_trait;
Expand Down Expand Up @@ -91,8 +92,8 @@ impl LocalStore for RedbLocalStore {
.flatten()
.map(|(mint, mint_info)| {
(
serde_json::from_str(mint.value()).unwrap(),
serde_json::from_str(mint_info.value()).unwrap(),
UncheckedUrl::from_str(mint.value()).unwrap(),
serde_json::from_str(mint_info.value()).ok(),
)
})
.collect();
Expand Down
91 changes: 72 additions & 19 deletions crates/cashu-sdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use cashu::dhke::{construct_proofs, unblind_message};
#[cfg(feature = "nut07")]
use cashu::nuts::nut07::ProofState;
use cashu::nuts::{
BlindedSignature, CurrencyUnit, Id, KeySetInfo, Keys, PreMintSecrets, PreSwap, Proof, Proofs,
SwapRequest, Token,
BlindedSignature, CurrencyUnit, Id, KeySetInfo, Keys, MintInfo, PreMintSecrets, PreSwap, Proof,
Proofs, SwapRequest, Token,
};
#[cfg(feature = "nut07")]
use cashu::secret::Secret;
Expand Down Expand Up @@ -119,6 +119,47 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
Ok(self.localstore.get_proofs(mint_url).await?)
}

pub async fn add_mint(&self, mint_url: UncheckedUrl) -> Result<Option<MintInfo>, Error> {
let mint_info = match self
.client
.get_mint_info(mint_url.clone().try_into()?)
.await
{
Ok(mint_info) => Some(mint_info),
Err(err) => {
warn!("Could not get mint info {}", err);
None
}
};

self.localstore
.add_mint(mint_url, mint_info.clone())
.await?;

Ok(mint_info)
}

pub async fn get_mint_keys(
&self,
mint_url: &UncheckedUrl,
keyset_id: Id,
) -> Result<Keys, Error> {
let keys = if let Some(keys) = self.localstore.get_keys(&keyset_id).await? {
keys
} else {
let keys = self
.client
.get_mint_keyset(mint_url.try_into()?, keyset_id)
.await?;

self.localstore.add_keys(keys.keys.clone()).await?;

keys.keys
};

Ok(keys)
}

/// Check if a proof is spent
#[cfg(feature = "nut07")]
pub async fn check_proofs_spent(
Expand Down Expand Up @@ -208,12 +249,20 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
return Ok(Some(keyset.id));
}
}
} else {
let keysets = self.client.get_mint_keysets(mint_url.try_into()?).await?;
}

self.localstore
.add_mint_keysets(mint_url.clone(), keysets.keysets.into_iter().collect())
.await?;
let keysets = self.client.get_mint_keysets(mint_url.try_into()?).await?;

self.localstore
.add_mint_keysets(
mint_url.clone(),
keysets.keysets.clone().into_iter().collect(),
)
.await?;
for keyset in &keysets.keysets {
if keyset.unit.eq(unit) && keyset.active {
return Ok(Some(keyset.id));
}
}

Ok(None)
Expand All @@ -226,30 +275,34 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
) -> Result<Option<Keys>, Error> {
let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap();

let mut keys = None;
let keys;

if let Some(k) = self.localstore.get_keys(&active_keyset_id).await? {
keys = Some(k.clone())
} else {
let keysets = self.client.get_mint_keys(mint_url.try_into()?).await?;
let keyset = self
.client
.get_mint_keyset(mint_url.try_into()?, active_keyset_id)
.await?;

for keyset in keysets {
if keyset.id.eq(&active_keyset_id) {
keys = Some(keyset.keys.clone())
}
self.localstore.add_keys(keyset.keys).await?;
}
self.localstore.add_keys(keyset.keys.clone()).await?;
keys = Some(keyset.keys);
}

Ok(keys)
}

/// Mint
pub async fn mint(&mut self, mint_url: UncheckedUrl, quote_id: &str) -> Result<Amount, Error> {
// Check that mint is in store of mints
if self.localstore.get_mint(mint_url.clone()).await?.is_none() {
self.add_mint(mint_url.clone()).await?;
}

let quote_info = self.localstore.get_mint_quote(quote_id).await?;

let quote_info = if let Some(quote) = quote_info {
if quote.expiry.le(&unix_time()) {
if quote.expiry.le(&unix_time()) && quote.expiry.ne(&0) {
return Err(Error::QuoteExpired);
}

Expand Down Expand Up @@ -282,7 +335,7 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {
)
.await?;

let keys = self.localstore.get_keys(&active_keyset_id).await?.unwrap();
let keys = self.get_mint_keys(&mint_url, active_keyset_id).await?;

let proofs = construct_proofs(
mint_res.signatures,
Expand Down Expand Up @@ -329,7 +382,7 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {

let swap_response = self
.client
.post_split(token.mint.clone().try_into()?, pre_swap.split_request)
.post_swap(token.mint.clone().try_into()?, pre_swap.split_request)
.await?;

// Proof to keep
Expand Down Expand Up @@ -437,7 +490,7 @@ impl<C: Client, L: LocalStore> Wallet<C, L> {

let swap_response = self
.client
.post_split(mint_url.clone().try_into()?, pre_swap.split_request)
.post_swap(mint_url.clone().try_into()?, pre_swap.split_request)
.await?;

let mut keep_proofs = Proofs::new();
Expand Down
2 changes: 1 addition & 1 deletion crates/cashu/src/nuts/nut01.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Keys {
#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct KeysResponse {
#[serde_as(as = "VecSkipError<_>")]
// #[serde_as(as = "VecSkipError<_>")]
pub keysets: Vec<KeySet>,
}

Expand Down

0 comments on commit ee417a4

Please sign in to comment.