Skip to content

Commit

Permalink
refactor: mint into mods
Browse files Browse the repository at this point in the history
  • Loading branch information
thesimplekid committed Sep 30, 2024
1 parent 4c14484 commit 1876644
Show file tree
Hide file tree
Showing 8 changed files with 1,450 additions and 1,373 deletions.
62 changes: 62 additions & 0 deletions crates/cdk/src/mint/check_spendable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::collections::HashSet;

use tracing::instrument;

use crate::Error;

use super::{CheckStateRequest, CheckStateResponse, Mint, ProofState, PublicKey, State};

impl Mint {
/// Check state
#[instrument(skip_all)]
pub async fn check_state(
&self,
check_state: &CheckStateRequest,
) -> Result<CheckStateResponse, Error> {
let states = self.localstore.get_proofs_states(&check_state.ys).await?;

let states = states
.iter()
.zip(&check_state.ys)
.map(|(state, y)| {
let state = match state {
Some(state) => *state,
None => State::Unspent,
};

ProofState {
y: *y,
state,
witness: None,
}
})
.collect();

Ok(CheckStateResponse { states })
}

/// Check Tokens are not spent or pending
#[instrument(skip_all)]
pub async fn check_ys_spendable(
&self,
ys: &[PublicKey],
proof_state: State,
) -> Result<(), Error> {
let proofs_state = self
.localstore
.update_proofs_states(ys, proof_state)
.await?;

let proofs_state = proofs_state.iter().flatten().collect::<HashSet<&State>>();

if proofs_state.contains(&State::Pending) {
return Err(Error::TokenPending);
}

if proofs_state.contains(&State::Spent) {
return Err(Error::TokenAlreadySpent);
}

Ok(())
}
}
31 changes: 31 additions & 0 deletions crates/cdk/src/mint/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use tracing::instrument;

use crate::mint_url::MintUrl;

use super::{Mint, MintInfo};

impl Mint {
/// Set Mint Url
#[instrument(skip_all)]
pub fn set_mint_url(&mut self, mint_url: MintUrl) {
self.mint_url = mint_url;
}

/// Get Mint Url
#[instrument(skip_all)]
pub fn get_mint_url(&self) -> &MintUrl {
&self.mint_url
}

/// Set Mint Info
#[instrument(skip_all)]
pub fn set_mint_info(&mut self, mint_info: MintInfo) {
self.mint_info = mint_info;
}

/// Get Mint Info
#[instrument(skip_all)]
pub fn mint_info(&self) -> &MintInfo {
&self.mint_info
}
}
144 changes: 144 additions & 0 deletions crates/cdk/src/mint/keysets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use std::collections::HashSet;

use tracing::instrument;

use crate::Error;

use super::{
create_new_keyset, derivation_path_from_unit, CurrencyUnit, Id, KeySet, KeySetInfo,
KeysResponse, KeysetResponse, Mint, MintKeySet, MintKeySetInfo,
};

impl Mint {
/// Retrieve the public keys of the active keyset for distribution to wallet
/// clients
#[instrument(skip(self))]
pub async fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<KeysResponse, Error> {
self.ensure_keyset_loaded(keyset_id).await?;
let keysets = self.keysets.read().await;
let keyset = keysets.get(keyset_id).ok_or(Error::UnknownKeySet)?.clone();
Ok(KeysResponse {
keysets: vec![keyset.into()],
})
}

/// Retrieve the public keys of the active keyset for distribution to wallet
/// clients
#[instrument(skip_all)]
pub async fn pubkeys(&self) -> Result<KeysResponse, Error> {
let active_keysets = self.localstore.get_active_keysets().await?;

let active_keysets: HashSet<&Id> = active_keysets.values().collect();

for id in active_keysets.iter() {
self.ensure_keyset_loaded(id).await?;
}

let keysets = self.keysets.read().await;
Ok(KeysResponse {
keysets: keysets
.values()
.filter_map(|k| match active_keysets.contains(&k.id) {
true => Some(k.clone().into()),
false => None,
})
.collect(),
})
}

/// Return a list of all supported keysets
#[instrument(skip_all)]
pub async fn keysets(&self) -> Result<KeysetResponse, Error> {
let keysets = self.localstore.get_keyset_infos().await?;
let active_keysets: HashSet<Id> = self
.localstore
.get_active_keysets()
.await?
.values()
.cloned()
.collect();

let keysets = keysets
.into_iter()
.map(|k| KeySetInfo {
id: k.id,
unit: k.unit,
active: active_keysets.contains(&k.id),
input_fee_ppk: k.input_fee_ppk,
})
.collect();

Ok(KeysetResponse { keysets })
}

/// Get keysets
#[instrument(skip(self))]
pub async fn keyset(&self, id: &Id) -> Result<Option<KeySet>, Error> {
self.ensure_keyset_loaded(id).await?;
let keysets = self.keysets.read().await;
let keyset = keysets.get(id).map(|k| k.clone().into());
Ok(keyset)
}

/// Add current keyset to inactive keysets
/// Generate new keyset
#[instrument(skip(self))]
pub async fn rotate_keyset(
&self,
unit: CurrencyUnit,
derivation_path_index: u32,
max_order: u8,
input_fee_ppk: u64,
) -> Result<(), Error> {
let derivation_path = derivation_path_from_unit(unit, derivation_path_index);
let (keyset, keyset_info) = create_new_keyset(
&self.secp_ctx,
self.xpriv,
derivation_path,
Some(derivation_path_index),
unit,
max_order,
input_fee_ppk,
);
let id = keyset_info.id;
self.localstore.add_keyset_info(keyset_info).await?;
self.localstore.set_active_keyset(unit, id).await?;

let mut keysets = self.keysets.write().await;
keysets.insert(id, keyset);

Ok(())
}

/// Ensure Keyset is loaded in mint
#[instrument(skip(self))]
pub async fn ensure_keyset_loaded(&self, id: &Id) -> Result<(), Error> {
let keysets = self.keysets.read().await;
if keysets.contains_key(id) {
return Ok(());
}
drop(keysets);

let keyset_info = self
.localstore
.get_keyset_info(id)
.await?
.ok_or(Error::UnknownKeySet)?;
let id = keyset_info.id;
let mut keysets = self.keysets.write().await;
keysets.insert(id, self.generate_keyset(keyset_info));
Ok(())
}

/// Generate [`MintKeySet`] from [`MintKeySetInfo`]
#[instrument(skip_all)]
pub fn generate_keyset(&self, keyset_info: MintKeySetInfo) -> MintKeySet {
MintKeySet::generate_from_xpriv(
&self.secp_ctx,
self.xpriv,
keyset_info.max_order,
keyset_info.unit,
keyset_info.derivation_path,
)
}
}
Loading

0 comments on commit 1876644

Please sign in to comment.