From fd4afeb2bdd6735ebf581cc37cbb48882779d939 Mon Sep 17 00:00:00 2001 From: thesimplekid Date: Wed, 8 May 2024 22:35:27 +0100 Subject: [PATCH] refactor(wallet): add swap function --- crates/cdk/src/wallet.rs | 197 +++++++++++++++++++++++---------------- 1 file changed, 115 insertions(+), 82 deletions(-) diff --git a/crates/cdk/src/wallet.rs b/crates/cdk/src/wallet.rs index f100e14f..706f035c 100644 --- a/crates/cdk/src/wallet.rs +++ b/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, + input_proofs: Proofs, + spending_conditions: Option, + ) -> Result, 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 = 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 { 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 = 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()) }