瀏覽代碼

chore: wallet doc tests

thesimplekid 6 月之前
父節點
當前提交
2994d778c0
共有 4 個文件被更改,包括 183 次插入9 次删除
  1. 1 1
      crates/cdk/src/amount.rs
  2. 2 0
      crates/cdk/src/mint_url.rs
  3. 22 0
      crates/cdk/src/wallet/README.md
  4. 158 8
      crates/cdk/src/wallet/mod.rs

+ 1 - 1
crates/cdk/src/amount.rs

@@ -190,7 +190,7 @@ pub enum SplitTarget {
     None,
     /// Target amount for wallet to have most proofs that add up to value
     Value(Amount),
-    /// Specific amounts to split into **must** equal amount being split
+    /// Specific amounts to split into **MUST** equal amount being split
     Values(Vec<Amount>),
 }
 

+ 2 - 0
crates/cdk/src/mint_url.rs

@@ -48,6 +48,7 @@ impl MintUrl {
         Self(self.to_string().trim_end_matches('/').to_string())
     }
 }
+
 impl<'de> Deserialize<'de> for MintUrl {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
     where
@@ -57,6 +58,7 @@ impl<'de> Deserialize<'de> for MintUrl {
         MintUrl::from_str(&s).map_err(serde::de::Error::custom)
     }
 }
+
 impl<S> From<S> for MintUrl
 where
     S: Into<String>,

+ 22 - 0
crates/cdk/src/wallet/README.md

@@ -0,0 +1,22 @@
+# CDK Wallet
+
+The CDK [`Wallet`] is a high level Cashu wallet. The [`Wallet`] is for a single mint and single unit. Multiple [`Wallet`]s can be created to support multi mints and multi units.
+
+
+## Example
+
+### Create [`Wallet`]
+```rust
+  use std::sync::Arc;
+  use cdk::cdk_database::WalletMemoryDatabase;
+  use cdk::nuts::CurrencyUnit;
+  use cdk::wallet::Wallet;
+  use rand::Rng;
+
+  let seed = rand::thread_rng().gen::<[u8; 32]>();
+  let mint_url = "https://testnut.cashu.space";
+  let unit = CurrencyUnit::Sat;
+
+  let localstore = WalletMemoryDatabase::default();
+  let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+```

+ 158 - 8
crates/cdk/src/wallet/mod.rs

@@ -1,6 +1,4 @@
-//! Cashu Wallet
-//!
-//! Each wallet is single mint and single unit
+#![doc = include_str!("./README.md")]
 
 use std::collections::{HashMap, HashSet};
 use std::str::FromStr;
@@ -39,6 +37,10 @@ pub use multi_mint_wallet::MultiMintWallet;
 pub use types::{MeltQuote, MintQuote, SendKind};
 
 /// CDK Wallet
+///
+/// The CDK [`Wallet`] is a high level cashu wallet.
+///
+/// A [`Wallet`] is for a single mint and single unit.
 #[derive(Debug, Clone)]
 pub struct Wallet {
     /// Mint Url
@@ -55,6 +57,22 @@ pub struct Wallet {
 
 impl Wallet {
     /// Create new [`Wallet`]
+    /// # Synopsis
+    /// ```rust
+    /// # use std::sync::Arc;
+    ///
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// let seed = rand::thread_rng().gen::<[u8; 32]>();
+    /// let mint_url = "https://testnut.cashu.space";
+    /// let unit = CurrencyUnit::Sat;
+    ///
+    /// let localstore = WalletMemoryDatabase::default();
+    /// let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    /// ```
     pub fn new(
         mint_url: &str,
         unit: CurrencyUnit,
@@ -248,7 +266,7 @@ impl Wallet {
         Ok(())
     }
 
-    /// Add mint to wallet
+    /// Qeury mint for current mint information
     #[instrument(skip(self))]
     pub async fn get_mint_info(&self) -> Result<Option<MintInfo>, Error> {
         let mint_info = match self
@@ -267,12 +285,15 @@ impl Wallet {
             .add_mint(self.mint_url.clone(), mint_info.clone())
             .await?;
 
-        tracing::trace!("Mint info fetched for {}", self.mint_url);
+        tracing::trace!("Mint info updated for {}", self.mint_url);
 
         Ok(mint_info)
     }
 
     /// Get keys for mint keyset
+    ///
+    /// Selected keys from localstore if they are already known
+    /// If they are not known queries mint for keyset id and stores the [`Keys`]
     #[instrument(skip(self))]
     pub async fn get_keyset_keys(&self, keyset_id: Id) -> Result<Keys, Error> {
         let keys = if let Some(keys) = self.localstore.get_keys(&keyset_id).await? {
@@ -292,6 +313,8 @@ impl Wallet {
     }
 
     /// Get keysets for mint
+    ///
+    /// Queries mint for all keysets
     #[instrument(skip(self))]
     pub async fn get_mint_keysets(&self) -> Result<Vec<KeySetInfo>, Error> {
         let keysets = self
@@ -307,7 +330,8 @@ impl Wallet {
     }
 
     /// Get active keyset for mint
-    /// Quieries mint for current keysets then gets Keys for any unknown keysets
+    ///
+    /// Quieries mint for current keysets then gets [`Keys`] for any unknown keysets
     #[instrument(skip(self))]
     pub async fn get_active_mint_keyset(&self) -> Result<KeySetInfo, Error> {
         let keysets = self
@@ -352,6 +376,8 @@ impl Wallet {
     }
 
     /// Reclaim unspent proofs
+    ///
+    /// Checks the stats of [`Proofs`] swapping for a new [`Proof`] if unspent
     #[instrument(skip(self, proofs))]
     pub async fn reclaim_unspent(&self, proofs: Proofs) -> Result<(), Error> {
         let proof_ys = proofs
@@ -378,7 +404,7 @@ impl Wallet {
         Ok(())
     }
 
-    /// Check if a proof is spent
+    /// NUT-07 Check the state of a [`Proof`] with the mint
     #[instrument(skip(self, proofs))]
     pub async fn check_proofs_spent(&self, proofs: Proofs) -> Result<Vec<ProofState>, Error> {
         let spendable = self
@@ -444,6 +470,30 @@ impl Wallet {
     }
 
     /// Mint Quote
+    /// # Synopsis
+    /// ```rust
+    /// # use std::sync::Arc;
+    ///
+    /// # use cdk::amount::Amount;
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// #[tokio::main]
+    /// async fn main() -> anyhow::Result<()> {
+    ///   # let seed = rand::thread_rng().gen::<[u8; 32]>();
+    ///   # let mint_url = "https://testnut.cashu.space";
+    ///   # let unit = CurrencyUnit::Sat;
+    ///
+    ///   # let localstore = WalletMemoryDatabase::default();
+    ///     let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    ///     let amount = Amount::from(100);
+    ///
+    ///     let quote = wallet.mint_quote(amount).await?;
+    ///     Ok(())
+    /// }
+    /// ```
     #[instrument(skip(self))]
     pub async fn mint_quote(&self, amount: Amount) -> Result<MintQuote, Error> {
         let mint_url = self.mint_url.clone();
@@ -468,7 +518,7 @@ impl Wallet {
         Ok(quote)
     }
 
-    /// Mint quote status
+    /// Check mint quote status
     #[instrument(skip(self, quote_id))]
     pub async fn mint_quote_state(&self, quote_id: &str) -> Result<MintQuoteBolt11Response, Error> {
         let response = self
@@ -513,6 +563,35 @@ impl Wallet {
     }
 
     /// Mint
+    /// # Synopsis
+    /// ```rust
+    /// # use std::sync::Arc;
+    ///
+    /// # use anyhow::Result;
+    /// # use cdk::amount::{Amount, SplitTarget};
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// #[tokio::main]
+    /// async fn main() -> Result<()> {
+    ///   # let seed = rand::thread_rng().gen::<[u8; 32]>();
+    ///   # let mint_url = "https://testnut.cashu.space";
+    ///   # let unit = CurrencyUnit::Sat;
+    ///
+    ///   # let localstore = WalletMemoryDatabase::default();
+    ///     let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    ///     let amount = Amount::from(100);
+    ///
+    ///     let quote = wallet.mint_quote(amount).await?;
+    ///     let quote_id = quote.id;
+    ///     // To be called after quote request is paid
+    ///     let amount_minted = wallet.mint(&quote_id, SplitTarget::default(), None).await?;
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
     #[instrument(skip(self))]
     pub async fn mint(
         &self,
@@ -1173,6 +1252,29 @@ impl Wallet {
     }
 
     /// Melt Quote
+    /// # Synopsis
+    /// ```rust
+    /// # use std::sync::Arc;
+    ///
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// #[tokio::main]
+    /// async fn main() -> anyhow::Result<()> {
+    /// # let seed = rand::thread_rng().gen::<[u8; 32]>();
+    /// # let mint_url = "https://testnut.cashu.space";
+    /// # let unit = CurrencyUnit::Sat;
+    ///
+    /// # let localstore = WalletMemoryDatabase::default();
+    /// let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    /// let bolt11 = "lnbc100n1pnvpufspp5djn8hrq49r8cghwye9kqw752qjncwyfnrprhprpqk43mwcy4yfsqdq5g9kxy7fqd9h8vmmfvdjscqzzsxqyz5vqsp5uhpjt36rj75pl7jq2sshaukzfkt7uulj456s4mh7uy7l6vx7lvxs9qxpqysgqedwz08acmqwtk8g4vkwm2w78suwt2qyzz6jkkwcgrjm3r3hs6fskyhvud4fan3keru7emjm8ygqpcrwtlmhfjfmer3afs5hhwamgr4cqtactdq".to_string();
+    /// let quote = wallet.melt_quote(bolt11, None).await?;
+    ///
+    /// Ok(())
+    /// }
+    /// ```
     #[instrument(skip(self))]
     pub async fn melt_quote(
         &self,
@@ -1361,6 +1463,31 @@ impl Wallet {
     }
 
     /// Melt
+    /// # Synopsis
+    /// ```rust, no_run
+    /// # use std::sync::Arc;
+    ///
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// #[tokio::main]
+    /// async fn main() -> anyhow::Result<()> {
+    /// # let seed = rand::thread_rng().gen::<[u8; 32]>();
+    /// # let mint_url = "https://testnut.cashu.space";
+    /// # let unit = CurrencyUnit::Sat;
+    ///
+    /// # let localstore = WalletMemoryDatabase::default();
+    /// # let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    /// # let bolt11 = "lnbc100n1pnvpufspp5djn8hrq49r8cghwye9kqw752qjncwyfnrprhprpqk43mwcy4yfsqdq5g9kxy7fqd9h8vmmfvdjscqzzsxqyz5vqsp5uhpjt36rj75pl7jq2sshaukzfkt7uulj456s4mh7uy7l6vx7lvxs9qxpqysgqedwz08acmqwtk8g4vkwm2w78suwt2qyzz6jkkwcgrjm3r3hs6fskyhvud4fan3keru7emjm8ygqpcrwtlmhfjfmer3afs5hhwamgr4cqtactdq".to_string();
+    /// let quote = wallet.melt_quote(bolt11, None).await?;
+    /// let quote_id = quote.id;
+    ///
+    /// let _ = wallet.melt(&quote_id).await?;
+    ///
+    /// Ok(())
+    /// }
     #[instrument(skip(self))]
     pub async fn melt(&self, quote_id: &str) -> Result<Melted, Error> {
         let quote_info = self.localstore.get_melt_quote(quote_id).await?;
@@ -1635,6 +1762,29 @@ impl Wallet {
     }
 
     /// Receive
+    /// # Synopsis
+    /// ```rust, no_run
+    /// # use std::sync::Arc;
+    ///
+    /// # use cdk::amount::SplitTarget;
+    /// # use cdk::cdk_database::WalletMemoryDatabase;
+    /// # use cdk::nuts::CurrencyUnit;
+    /// # use cdk::wallet::Wallet;
+    /// # use rand::Rng;
+    ///
+    /// #[tokio::main]
+    /// async fn main() -> anyhow::Result<()> {
+    /// # let seed = rand::thread_rng().gen::<[u8; 32]>();
+    /// # let mint_url = "https://testnut.cashu.space";
+    /// # let unit = CurrencyUnit::Sat;
+    ///
+    /// # let localstore = WalletMemoryDatabase::default();
+    /// let wallet = Wallet::new(mint_url, unit, Arc::new(localstore), &seed, None);
+    /// let token = "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJhbW91bnQiOjEsInNlY3JldCI6ImI0ZjVlNDAxMDJhMzhiYjg3NDNiOTkwMzU5MTU1MGYyZGEzZTQxNWEzMzU0OTUyN2M2MmM5ZDc5MGVmYjM3MDUiLCJDIjoiMDIzYmU1M2U4YzYwNTMwZWVhOWIzOTQzZmRhMWEyY2U3MWM3YjNmMGNmMGRjNmQ4NDZmYTc2NWFhZjc3OWZhODFkIiwiaWQiOiIwMDlhMWYyOTMyNTNlNDFlIn1dLCJtaW50IjoiaHR0cHM6Ly90ZXN0bnV0LmNhc2h1LnNwYWNlIn1dLCJ1bml0Ijoic2F0In0=";
+    /// let amount_receive = wallet.receive(token, SplitTarget::default(), &[], &[]).await?;
+    /// Ok(())
+    /// }
+    /// ```
     #[instrument(skip_all)]
     pub async fn receive(
         &self,