Forráskód Böngészése

feat: add mint builder

thesimplekid 5 hónapja
szülő
commit
58864ea52a
2 módosított fájl, 219 hozzáadás és 0 törlés
  1. 217 0
      crates/cdk/src/mint/builder.rs
  2. 2 0
      crates/cdk/src/mint/mod.rs

+ 217 - 0
crates/cdk/src/mint/builder.rs

@@ -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,
+}

+ 2 - 0
crates/cdk/src/mint/mod.rs

@@ -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