mirror of
https://github.com/aljazceru/cdk.git
synced 2026-01-08 23:45:52 +01:00
feat: get mint keysets and keys
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cashu::nuts::{
|
||||
BlindedMessage, Keys, MeltBolt11Request, MeltBolt11Response, MintBolt11Request,
|
||||
MintBolt11Response, MintInfo, PreMintSecrets, Proof, SwapRequest, SwapResponse, *,
|
||||
BlindedMessage, MeltBolt11Request, MeltBolt11Response, MintBolt11Request, MintBolt11Response,
|
||||
MintInfo, PreMintSecrets, Proof, SwapRequest, SwapResponse, *,
|
||||
};
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::{CheckSpendableRequest, CheckSpendableResponse};
|
||||
@@ -21,7 +21,7 @@ pub struct HttpClient {}
|
||||
#[async_trait(?Send)]
|
||||
impl Client for HttpClient {
|
||||
/// Get Mint Keys [NUT-01]
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error> {
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error> {
|
||||
let url = join_url(mint_url, &["v1", "keys"])?;
|
||||
let keys = Request::get(url.as_str())
|
||||
.send()
|
||||
@@ -31,8 +31,8 @@ impl Client for HttpClient {
|
||||
.await
|
||||
.map_err(|err| Error::Gloo(err.to_string()))?;
|
||||
|
||||
let keys: Keys = serde_json::from_str(&keys.to_string())?;
|
||||
Ok(keys)
|
||||
let keys: KeysResponse = serde_json::from_str(&keys.to_string())?;
|
||||
Ok(keys.keysets)
|
||||
}
|
||||
|
||||
/// Get Keysets [NUT-02]
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::println;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cashu::nuts::{
|
||||
nut00, BlindedMessage, CurrencyUnit, Keys, KeysResponse, KeysetResponse, MeltBolt11Request,
|
||||
nut00, BlindedMessage, CurrencyUnit, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
|
||||
MeltBolt11Response, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MintBolt11Request,
|
||||
MintBolt11Response, MintInfo, MintQuoteBolt11Request, MintQuoteBolt11Response, PreMintSecrets,
|
||||
Proof, SwapRequest, SwapResponse,
|
||||
@@ -25,14 +25,12 @@ pub struct HttpClient {}
|
||||
#[async_trait(?Send)]
|
||||
impl Client for HttpClient {
|
||||
/// Get Mint Keys [NUT-01]
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error> {
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error> {
|
||||
let url = join_url(mint_url, &["v1", "keys"])?;
|
||||
let keys = minreq::get(url).send()?.json::<Value>()?;
|
||||
|
||||
println!("{}", keys);
|
||||
|
||||
let keys: KeysResponse = serde_json::from_str(&keys.to_string())?;
|
||||
Ok(keys.keysets[0].keys.clone())
|
||||
Ok(keys.keysets)
|
||||
}
|
||||
|
||||
/// Get Keysets [NUT-02]
|
||||
|
||||
@@ -6,7 +6,7 @@ use cashu::nuts::nut00;
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu::nuts::CheckSpendableResponse;
|
||||
use cashu::nuts::{
|
||||
BlindedMessage, CurrencyUnit, Keys, KeysetResponse, MeltBolt11Response,
|
||||
BlindedMessage, CurrencyUnit, KeySet, KeysetResponse, MeltBolt11Response,
|
||||
MeltQuoteBolt11Response, MintBolt11Response, MintInfo, MintQuoteBolt11Response, PreMintSecrets,
|
||||
Proof, SwapRequest, SwapResponse,
|
||||
};
|
||||
@@ -84,7 +84,7 @@ pub struct MintErrorResponse {
|
||||
|
||||
#[async_trait(?Send)]
|
||||
pub trait Client {
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error>;
|
||||
async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error>;
|
||||
|
||||
async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error>;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct BackupInfo {
|
||||
pub struct Wallet<C: Client> {
|
||||
backup_info: Option<BackupInfo>,
|
||||
pub client: C,
|
||||
pub mints: HashMap<UncheckedUrl, MintInfo>,
|
||||
pub mints: HashMap<UncheckedUrl, Option<MintInfo>>,
|
||||
pub mint_keysets: HashMap<UncheckedUrl, HashSet<KeySetInfo>>,
|
||||
pub mint_quotes: HashMap<String, MintQuote>,
|
||||
pub melt_quotes: HashMap<String, MeltQuote>,
|
||||
@@ -63,7 +63,7 @@ pub struct Wallet<C: Client> {
|
||||
impl<C: Client> Wallet<C> {
|
||||
pub fn new(
|
||||
client: C,
|
||||
mints: HashMap<UncheckedUrl, MintInfo>,
|
||||
mints: HashMap<UncheckedUrl, Option<MintInfo>>,
|
||||
mint_keysets: HashMap<UncheckedUrl, HashSet<KeySetInfo>>,
|
||||
mint_quotes: Vec<MintQuote>,
|
||||
melt_quotes: Vec<MeltQuote>,
|
||||
@@ -164,22 +164,50 @@ impl<C: Client> Wallet<C> {
|
||||
Ok(quote)
|
||||
}
|
||||
|
||||
fn active_mint_keyset(&self, mint_url: &UncheckedUrl, unit: &CurrencyUnit) -> Option<Id> {
|
||||
async fn active_mint_keyset(
|
||||
&mut self,
|
||||
mint_url: &UncheckedUrl,
|
||||
unit: &CurrencyUnit,
|
||||
) -> Result<Option<Id>, Error> {
|
||||
if let Some(keysets) = self.mint_keysets.get(mint_url) {
|
||||
for keyset in keysets {
|
||||
if keyset.unit.eq(unit) && keyset.active {
|
||||
return Some(keyset.id);
|
||||
return Ok(Some(keyset.id));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let keysets = self.client.get_mint_keysets(mint_url.try_into()?).await?;
|
||||
|
||||
self.mint_keysets
|
||||
.insert(mint_url.clone(), keysets.keysets.into_iter().collect());
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn active_keys(
|
||||
&mut self,
|
||||
mint_url: &UncheckedUrl,
|
||||
unit: &CurrencyUnit,
|
||||
) -> Result<Option<Keys>, Error> {
|
||||
let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap();
|
||||
|
||||
let mut keys = None;
|
||||
|
||||
if let Some(k) = self.mint_keys.get(&active_keyset_id) {
|
||||
keys = Some(k.clone())
|
||||
} else {
|
||||
let keysets = self.client.get_mint_keys(mint_url.try_into()?).await?;
|
||||
|
||||
for keyset in keysets {
|
||||
if keyset.id.eq(&active_keyset_id) {
|
||||
keys = Some(keyset.keys.clone())
|
||||
}
|
||||
self.mint_keys.insert(keyset.id, keyset.keys);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn active_keys(&self, mint_url: &UncheckedUrl, unit: &CurrencyUnit) -> Option<Keys> {
|
||||
self.active_mint_keyset(mint_url, unit)
|
||||
.and_then(|id| self.mint_keys.get(&id))
|
||||
.cloned()
|
||||
Ok(keys)
|
||||
}
|
||||
|
||||
/// Mint
|
||||
@@ -198,6 +226,7 @@ impl<C: Client> Wallet<C> {
|
||||
|
||||
let active_keyset_id = self
|
||||
.active_mint_keyset(&mint_url, "e_info.unit)
|
||||
.await?
|
||||
.unwrap();
|
||||
|
||||
let premint_secrets = match &self.backup_info {
|
||||
@@ -234,7 +263,7 @@ impl<C: Client> Wallet<C> {
|
||||
}
|
||||
|
||||
/// Receive
|
||||
pub async fn receive(&self, encoded_token: &str) -> Result<Proofs, Error> {
|
||||
pub async fn receive(&mut self, encoded_token: &str) -> Result<Proofs, Error> {
|
||||
let token_data = Token::from_str(encoded_token)?;
|
||||
|
||||
let unit = token_data.unit.unwrap_or_default();
|
||||
@@ -252,16 +281,18 @@ impl<C: Client> Wallet<C> {
|
||||
};
|
||||
*/
|
||||
|
||||
let active_keyset_id = self.active_mint_keyset(&token.mint, &unit);
|
||||
let active_keyset_id = self.active_mint_keyset(&token.mint, &unit).await?;
|
||||
|
||||
// TODO: if none fetch keyset for mint
|
||||
|
||||
let keys = self.mint_keys.get(&active_keyset_id.unwrap());
|
||||
let keys = self.mint_keys.get(&active_keyset_id.unwrap()).cloned();
|
||||
|
||||
// Sum amount of all proofs
|
||||
let amount: Amount = token.proofs.iter().map(|p| p.amount).sum();
|
||||
|
||||
let pre_swap = self.create_split(&token.mint, &unit, Some(amount), token.proofs)?;
|
||||
let pre_swap = self
|
||||
.create_split(&token.mint, &unit, Some(amount), token.proofs)
|
||||
.await?;
|
||||
|
||||
let swap_response = self
|
||||
.client
|
||||
@@ -273,7 +304,7 @@ impl<C: Client> Wallet<C> {
|
||||
swap_response.signatures,
|
||||
pre_swap.pre_mint_secrets.rs(),
|
||||
pre_swap.pre_mint_secrets.secrets(),
|
||||
keys.unwrap(),
|
||||
&keys.unwrap(),
|
||||
)?;
|
||||
proofs.push(p);
|
||||
}
|
||||
@@ -281,8 +312,8 @@ impl<C: Client> Wallet<C> {
|
||||
}
|
||||
|
||||
/// Create Split Payload
|
||||
fn create_split(
|
||||
&self,
|
||||
async fn create_split(
|
||||
&mut self,
|
||||
mint_url: &UncheckedUrl,
|
||||
unit: &CurrencyUnit,
|
||||
amount: Option<Amount>,
|
||||
@@ -291,7 +322,7 @@ impl<C: Client> Wallet<C> {
|
||||
// Since split is used to get the needed combination of tokens for a specific
|
||||
// amount first blinded messages are created for the amount
|
||||
|
||||
let active_keyset_id = self.active_mint_keyset(mint_url, unit).unwrap();
|
||||
let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?.unwrap();
|
||||
|
||||
let pre_mint_secrets = if let Some(amount) = amount {
|
||||
let mut desired_messages = PreMintSecrets::random(active_keyset_id, amount)?;
|
||||
@@ -352,7 +383,7 @@ impl<C: Client> Wallet<C> {
|
||||
|
||||
/// Send
|
||||
pub async fn send(
|
||||
&self,
|
||||
&mut self,
|
||||
mint_url: &UncheckedUrl,
|
||||
unit: &CurrencyUnit,
|
||||
amount: Amount,
|
||||
@@ -365,7 +396,9 @@ impl<C: Client> Wallet<C> {
|
||||
return Err(Error::InsufficientFunds);
|
||||
}
|
||||
|
||||
let pre_swap = self.create_split(mint_url, unit, Some(amount), proofs)?;
|
||||
let pre_swap = self
|
||||
.create_split(mint_url, unit, Some(amount), proofs)
|
||||
.await?;
|
||||
|
||||
let swap_response = self
|
||||
.client
|
||||
@@ -379,7 +412,7 @@ impl<C: Client> Wallet<C> {
|
||||
swap_response.signatures,
|
||||
pre_swap.pre_mint_secrets.rs(),
|
||||
pre_swap.pre_mint_secrets.secrets(),
|
||||
&self.active_keys(mint_url, unit).unwrap(),
|
||||
&self.active_keys(mint_url, unit).await?.unwrap(),
|
||||
)?;
|
||||
|
||||
proofs.reverse();
|
||||
@@ -439,7 +472,7 @@ impl<C: Client> Wallet<C> {
|
||||
|
||||
/// Melt
|
||||
pub async fn melt(
|
||||
&self,
|
||||
&mut self,
|
||||
mint_url: &UncheckedUrl,
|
||||
quote_id: &str,
|
||||
proofs: Proofs,
|
||||
@@ -457,7 +490,9 @@ impl<C: Client> Wallet<C> {
|
||||
};
|
||||
|
||||
let blinded = PreMintSecrets::blank(
|
||||
self.active_mint_keyset(mint_url, "e_info.unit).unwrap(),
|
||||
self.active_mint_keyset(mint_url, "e_info.unit)
|
||||
.await?
|
||||
.unwrap(),
|
||||
quote_info.fee_reserve,
|
||||
)?;
|
||||
|
||||
@@ -476,7 +511,7 @@ impl<C: Client> Wallet<C> {
|
||||
change,
|
||||
blinded.rs(),
|
||||
blinded.secrets(),
|
||||
&self.active_keys(mint_url, "e_info.unit).unwrap(),
|
||||
&self.active_keys(mint_url, "e_info.unit).await?.unwrap(),
|
||||
)?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user