feat: add mint builder

This commit is contained in:
thesimplekid
2024-11-06 08:43:30 +00:00
parent c45efe42d2
commit 58864ea52a
2 changed files with 219 additions and 0 deletions

View File

@@ -0,0 +1,217 @@
//! Mint Builder
use std::{collections::HashMap, sync::Arc};
use anyhow::anyhow;
use crate::{
amount::Amount,
cdk_database::{self, MintDatabase},
cdk_lightning::{self, MintLightning},
mint::Mint,
nuts::{
ContactInfo, CurrencyUnit, MeltMethodSettings, MintInfo, MintMethodSettings, MintVersion,
MppMethodSettings, PaymentMethod,
},
types::{LnKey, QuoteTTL},
};
/// Cashu Mint
#[derive(Default)]
pub struct MintBuilder {
/// Mint Url
mint_url: Option<String>,
/// Mint Info
mint_info: MintInfo,
/// Mint Storage backend
localstore: Option<Arc<dyn MintDatabase<Err = cdk_database::Error> + Send + Sync>>,
/// Ln backends for mint
ln: Option<HashMap<LnKey, Arc<dyn MintLightning<Err = cdk_lightning::Error> + Send + Sync>>>,
seed: Option<Vec<u8>>,
quote_ttl: Option<QuoteTTL>,
supported_units: HashMap<CurrencyUnit, (u64, u8)>,
}
impl MintBuilder {
/// New mint builder
pub fn new() -> MintBuilder {
MintBuilder::default()
}
/// Set localstore
pub fn with_localstore(
mut self,
localstore: Arc<dyn MintDatabase<Err = cdk_database::Error> + Send + Sync>,
) -> MintBuilder {
self.localstore = Some(localstore);
self
}
/// Set mint url
pub fn with_mint_url(mut self, mint_url: String) -> Self {
self.mint_url = Some(mint_url);
self
}
/// Set seed
pub fn with_seed(mut self, seed: Vec<u8>) -> Self {
self.seed = Some(seed);
self
}
/// Set name
pub fn with_name(mut self, name: String) -> Self {
self.mint_info.name = Some(name);
self
}
/// Set icon url
pub fn with_icon_url(mut self, icon_url: String) -> Self {
self.mint_info.icon_url = Some(icon_url);
self
}
/// Set icon url
pub fn with_motd(mut self, motd: String) -> Self {
self.mint_info.motd = Some(motd);
self
}
/// Set description
pub fn with_description(mut self, description: String) -> Self {
self.mint_info.description = Some(description);
self
}
/// Set long description
pub fn with_long_description(mut self, description: String) -> Self {
self.mint_info.description_long = Some(description);
self
}
/// Set version
pub fn with_version(mut self, version: MintVersion) -> Self {
self.mint_info.version = Some(version);
self
}
/// Set contact info
pub fn add_contact_info(mut self, contact_info: ContactInfo) -> Self {
let mut contacts = self.mint_info.contact.clone().unwrap_or_default();
contacts.push(contact_info);
self.mint_info.contact = Some(contacts);
self
}
/// Add ln backend
pub fn add_ln_backend(
mut self,
unit: CurrencyUnit,
method: PaymentMethod,
limits: MintMeltLimits,
ln_backend: Arc<dyn MintLightning<Err = cdk_lightning::Error> + Send + Sync>,
) -> Self {
let ln_key = LnKey {
unit: unit.clone(),
method,
};
let mut ln = self.ln.unwrap_or_default();
let settings = ln_backend.get_settings();
if settings.mpp {
let mpp_settings = MppMethodSettings {
method,
unit: unit.clone(),
mpp: true,
};
let mut mpp = self.mint_info.nuts.nut15.clone();
mpp.methods.push(mpp_settings);
self.mint_info.nuts.nut15 = mpp;
}
match method {
PaymentMethod::Bolt11 => {
let mint_method_settings = MintMethodSettings {
method,
unit: unit.clone(),
min_amount: Some(limits.mint_min),
max_amount: Some(limits.mint_max),
description: settings.invoice_description,
};
self.mint_info.nuts.nut04.methods.push(mint_method_settings);
self.mint_info.nuts.nut04.disabled = false;
let melt_method_settings = MeltMethodSettings {
method,
unit,
min_amount: Some(limits.melt_min),
max_amount: Some(limits.melt_max),
};
self.mint_info.nuts.nut05.methods.push(melt_method_settings);
self.mint_info.nuts.nut05.disabled = false;
}
}
ln.insert(ln_key.clone(), ln_backend);
let mut supported_units = self.supported_units.clone();
supported_units.insert(ln_key.unit, (0, 32));
self.supported_units = supported_units;
self.ln = Some(ln);
self
}
/// Set quote ttl
pub fn with_quote_ttl(mut self, mint_ttl: u64, melt_ttl: u64) -> Self {
let quote_ttl = QuoteTTL { mint_ttl, melt_ttl };
self.quote_ttl = Some(quote_ttl);
self
}
/// Set pubkey
pub fn with_pubkey(mut self, pubkey: crate::nuts::PublicKey) -> Self {
self.mint_info.pubkey = Some(pubkey);
self
}
/// Build mint
pub async fn build(&self) -> anyhow::Result<Mint> {
Ok(Mint::new(
self.mint_url.as_ref().ok_or(anyhow!("Mint url not set"))?,
self.seed.as_ref().ok_or(anyhow!("Mint seed not set"))?,
self.mint_info.clone(),
self.quote_ttl.ok_or(anyhow!("Quote ttl not set"))?,
self.localstore
.clone()
.ok_or(anyhow!("Localstore not set"))?,
self.ln.clone().ok_or(anyhow!("Ln backends not set"))?,
self.supported_units.clone(),
HashMap::new(),
)
.await?)
}
}
/// Mint Melt Limits
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct MintMeltLimits {
/// Min mint amount
pub mint_min: Amount,
/// Max mint amount
pub mint_max: Amount,
/// Min melt amount
pub melt_min: Amount,
/// Max melt amount
pub melt_max: Amount,
}

View File

@@ -23,6 +23,7 @@ use crate::types::{LnKey, QuoteTTL};
use crate::util::unix_time;
use crate::Amount;
mod builder;
mod check_spendable;
mod info;
mod keysets;
@@ -31,6 +32,7 @@ mod mint_nut04;
mod swap;
pub mod types;
pub use builder::{MintBuilder, MintMeltLimits};
pub use types::{MeltQuote, MintQuote};
/// Cashu Mint