Переглянути джерело

refactor(wallet): add swap function

thesimplekid 11 місяців тому
батько
коміт
fd4afeb2bd
1 змінених файлів з 115 додано та 82 видалено
  1. 115 82
      crates/cdk/src/wallet.rs

+ 115 - 82
crates/cdk/src/wallet.rs

@@ -466,6 +466,113 @@ impl Wallet {
         Ok(minted_amount)
     }
 
+    /// Swap
+    async fn swap(
+        &mut self,
+        mint_url: &UncheckedUrl,
+        unit: &CurrencyUnit,
+        amount: Option<Amount>,
+        input_proofs: Proofs,
+        spending_conditions: Option<SpendingConditions>,
+    ) -> Result<Option<Proofs>, Error> {
+        let pre_swap = self
+            .create_swap(
+                mint_url,
+                unit,
+                amount,
+                input_proofs.clone(),
+                spending_conditions,
+            )
+            .await?;
+
+        let swap_response = self
+            .client
+            .post_swap(mint_url.clone().try_into()?, pre_swap.swap_request)
+            .await?;
+
+        let mut post_swap_proofs = construct_proofs(
+            swap_response.signatures,
+            pre_swap.pre_mint_secrets.rs(),
+            pre_swap.pre_mint_secrets.secrets(),
+            &self
+                .active_keys(mint_url, unit)
+                .await?
+                .ok_or(Error::UnknownKey)?,
+        )?;
+
+        #[cfg(feature = "nut13")]
+        if self.mnemonic.is_some() {
+            let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?;
+
+            self.localstore
+                .increment_keyset_counter(&active_keyset_id, post_swap_proofs.len() as u64)
+                .await?;
+        }
+
+        let mut keep_proofs = Proofs::new();
+        let proofs_to_send;
+
+        match amount {
+            Some(amount) => {
+                post_swap_proofs.reverse();
+
+                let mut left_proofs = vec![];
+                let mut send_proofs = vec![];
+
+                for proof in post_swap_proofs {
+                    let nut10: Result<nut10::Secret, _> = proof.secret.clone().try_into();
+
+                    match nut10 {
+                        Ok(_) => send_proofs.push(proof),
+                        Err(_) => left_proofs.push(proof),
+                    }
+                }
+
+                for proof in left_proofs {
+                    if (proof.amount + send_proofs.iter().map(|p| p.amount).sum()).gt(&amount) {
+                        keep_proofs.push(proof);
+                    } else {
+                        send_proofs.push(proof);
+                    }
+                }
+
+                let send_amount: Amount = send_proofs.iter().map(|p| p.amount).sum();
+
+                if send_amount.ne(&amount) {
+                    tracing::warn!(
+                        "Send amount proofs is {:?} expected {:?}",
+                        send_amount,
+                        amount
+                    );
+                }
+
+                self.localstore
+                    .add_pending_proofs(mint_url.clone(), send_proofs.clone())
+                    .await?;
+
+                proofs_to_send = Some(send_proofs);
+            }
+            None => {
+                keep_proofs = post_swap_proofs;
+                proofs_to_send = None;
+            }
+        }
+
+        self.localstore
+            .remove_proofs(mint_url.clone(), &input_proofs)
+            .await?;
+
+        self.localstore
+            .add_pending_proofs(mint_url.clone(), input_proofs)
+            .await?;
+
+        self.localstore
+            .add_proofs(mint_url.clone(), keep_proofs)
+            .await?;
+
+        Ok(proofs_to_send)
+    }
+
     /// Create Swap Payload
     async fn create_swap(
         &mut self,
@@ -667,91 +774,17 @@ impl Wallet {
     ) -> Result<String, Error> {
         let input_proofs = self.select_proofs(mint_url.clone(), unit, amount).await?;
 
-        let active_keyset_id = self.active_mint_keyset(mint_url, unit).await?;
-
-        let pre_swap = self
-            .create_swap(
-                mint_url,
-                unit,
-                Some(amount),
-                input_proofs.clone(),
-                conditions,
-            )
-            .await?;
-
-        let swap_response = self
-            .client
-            .post_swap(mint_url.clone().try_into()?, pre_swap.swap_request)
-            .await?;
-
-        let mut keep_proofs = Proofs::new();
-        let mut send_proofs = Proofs::new();
-
-        let mut post_swap_proofs = construct_proofs(
-            swap_response.signatures,
-            pre_swap.pre_mint_secrets.rs(),
-            pre_swap.pre_mint_secrets.secrets(),
-            &self
-                .active_keys(mint_url, unit)
-                .await?
-                .ok_or(Error::UnknownKey)?,
-        )?;
-
-        #[cfg(feature = "nut13")]
-        if self.mnemonic.is_some() {
-            self.localstore
-                .increment_keyset_counter(&active_keyset_id, post_swap_proofs.len() as u64)
-                .await?;
-        }
-
-        post_swap_proofs.reverse();
-
-        let mut left_proofs = vec![];
-
-        for proof in post_swap_proofs {
-            let nut10: Result<nut10::Secret, _> = proof.secret.clone().try_into();
-
-            match nut10 {
-                Ok(_) => send_proofs.push(proof),
-                Err(_) => left_proofs.push(proof),
-            }
-        }
-
-        for proof in left_proofs {
-            if (proof.amount + send_proofs.iter().map(|p| p.amount).sum()).gt(&amount) {
-                keep_proofs.push(proof);
-            } else {
-                send_proofs.push(proof);
-            }
-        }
-
-        let send_amount: Amount = send_proofs.iter().map(|p| p.amount).sum();
-
-        if send_amount.ne(&amount) {
-            tracing::warn!(
-                "Send amount proofs is {:?} expected {:?}",
-                send_amount,
-                amount
-            );
-        }
-
-        self.localstore
-            .remove_proofs(mint_url.clone(), &input_proofs)
-            .await?;
-
-        self.localstore
-            .add_pending_proofs(mint_url.clone(), input_proofs)
-            .await?;
-        self.localstore
-            .add_pending_proofs(mint_url.clone(), send_proofs.clone())
-            .await?;
-
-        self.localstore
-            .add_proofs(mint_url.clone(), keep_proofs)
+        let send_proofs = self
+            .swap(mint_url, unit, Some(amount), input_proofs, conditions)
             .await?;
 
         Ok(self
-            .proofs_to_token(mint_url.clone(), send_proofs, memo, Some(unit.clone()))?
+            .proofs_to_token(
+                mint_url.clone(),
+                send_proofs.ok_or(Error::InsufficientFunds)?,
+                memo,
+                Some(unit.clone()),
+            )?
             .to_string())
     }