mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-08 06:35:52 +01:00
fix: send in wallet proof totals
This commit is contained in:
@@ -171,6 +171,11 @@ impl<C: Client> Wallet<C> {
|
||||
|
||||
/// Create Split Payload
|
||||
fn create_split(&self, proofs: Proofs) -> Result<SplitPayload, Error> {
|
||||
let mut proofs = proofs;
|
||||
|
||||
// Sort proofs in ascending order to avoid fingerprinting
|
||||
proofs.sort();
|
||||
|
||||
let value = proofs.iter().map(|p| p.amount).sum();
|
||||
|
||||
let blinded_messages = BlindedMessages::random(value)?;
|
||||
@@ -223,33 +228,14 @@ impl<C: Client> Wallet<C> {
|
||||
|
||||
/// Send
|
||||
pub async fn send(&self, amount: Amount, proofs: Proofs) -> Result<SendProofs, Error> {
|
||||
let mut amount_available = Amount::ZERO;
|
||||
let mut send_proofs = SendProofs::default();
|
||||
|
||||
for proof in proofs {
|
||||
let proof_value = proof.amount;
|
||||
if amount_available > amount {
|
||||
send_proofs.change_proofs.push(proof);
|
||||
} else {
|
||||
send_proofs.send_proofs.push(proof);
|
||||
}
|
||||
amount_available += proof_value;
|
||||
}
|
||||
let amount_available: Amount = proofs.iter().map(|p| p.amount).sum();
|
||||
|
||||
if amount_available.lt(&amount) {
|
||||
println!("Not enough funds");
|
||||
return Err(Error::InsufficientFunds);
|
||||
}
|
||||
|
||||
// If amount available is EQUAL to send amount no need to split
|
||||
if amount_available.eq(&amount) {
|
||||
return Ok(send_proofs);
|
||||
}
|
||||
|
||||
let _amount_to_keep = amount_available - amount;
|
||||
let amount_to_send = amount;
|
||||
|
||||
let split_payload = self.create_split(send_proofs.send_proofs)?;
|
||||
let split_payload = self.create_split(proofs)?;
|
||||
|
||||
let split_response = self
|
||||
.client
|
||||
@@ -259,22 +245,26 @@ impl<C: Client> Wallet<C> {
|
||||
)
|
||||
.await?;
|
||||
|
||||
// If only promises assemble proofs needed for amount
|
||||
let keep_proofs;
|
||||
let send_proofs;
|
||||
let mut keep_proofs = Proofs::new();
|
||||
let mut send_proofs = Proofs::new();
|
||||
|
||||
if let Some(promises) = split_response.promises {
|
||||
let proofs = construct_proofs(
|
||||
let mut proofs = construct_proofs(
|
||||
promises,
|
||||
split_payload.blinded_messages.rs,
|
||||
split_payload.blinded_messages.secrets,
|
||||
&self.mint_keys,
|
||||
)?;
|
||||
|
||||
let split = amount_to_send.split();
|
||||
proofs.reverse();
|
||||
|
||||
keep_proofs = proofs[0..split.len()].to_vec();
|
||||
send_proofs = proofs[split.len()..].to_vec();
|
||||
for proof in proofs {
|
||||
if (proof.amount + send_proofs.iter().map(|p| p.amount).sum()).gt(&amount) {
|
||||
keep_proofs.push(proof);
|
||||
} else {
|
||||
send_proofs.push(proof);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(Error::Custom("Invalid split response".to_string()));
|
||||
}
|
||||
@@ -282,6 +272,16 @@ impl<C: Client> Wallet<C> {
|
||||
// println!("Send Proofs: {:#?}", send_proofs);
|
||||
// println!("Keep Proofs: {:#?}", keep_proofs);
|
||||
|
||||
let send_amount: Amount = send_proofs.iter().map(|p| p.amount).sum();
|
||||
|
||||
if send_amount.ne(&amount) {
|
||||
warn!(
|
||||
"Send amount proofs is {} expected {}",
|
||||
send_amount.to_sat(),
|
||||
amount.to_sat()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(SendProofs {
|
||||
change_proofs: keep_proofs,
|
||||
send_proofs,
|
||||
|
||||
@@ -204,6 +204,18 @@ pub struct Proof {
|
||||
pub id: Option<Id>,
|
||||
}
|
||||
|
||||
impl Ord for Proof {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.amount.cmp(&other.amount)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Proof {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Proof> for mint::Proof {
|
||||
fn from(proof: Proof) -> Self {
|
||||
Self {
|
||||
|
||||
Reference in New Issue
Block a user