Parcourir la source

deprecate amount field

thesimplekid il y a 1 an
Parent
commit
e8303fcc8c
3 fichiers modifiés avec 182 ajouts et 76 suppressions
  1. 34 25
      src/mint.rs
  2. 78 13
      src/nuts/nut06.rs
  3. 70 38
      src/wallet.rs

+ 34 - 25
src/mint.rs

@@ -99,46 +99,55 @@ impl Mint {
     ) -> Result<SplitResponse, Error> {
         let proofs_total = split_request.proofs_amount();
 
-        if proofs_total < split_request.amount {
-            return Err(Error::Amount);
-        }
-
         let output_total = split_request.output_amount();
-        if output_total < split_request.amount {
-            return Err(Error::Amount);
-        }
-
         if proofs_total != output_total {
             return Err(Error::Amount);
         }
 
         let mut secrets = Vec::with_capacity(split_request.proofs.len());
         for proof in &split_request.proofs {
-            secrets.push(self.verify_proof(proof)?);
+            secrets.push(self.verify_proof(&proof)?);
+            self.spent_secrets.insert(proof.secret.clone());
         }
 
-        let outs_fst = (proofs_total - split_request.amount).split();
+        match &split_request.amount {
+            None => {
+                let promises: Vec<BlindedSignature> = split_request
+                    .outputs
+                    .iter()
+                    .map(|b| self.blind_sign(b).unwrap())
+                    .collect();
+
+                Ok(SplitResponse::new(promises))
+            }
+            Some(amount) => {
+                if proofs_total.le(amount) {
+                    return Err(Error::Amount);
+                }
 
-        // Blinded change messages
-        let b_fst = split_request.outputs[0..outs_fst.len()].to_vec();
-        let b_snd = split_request.outputs[outs_fst.len()..].to_vec();
+                if output_total.gt(amount) {
+                    return Err(Error::Amount);
+                }
 
-        let fst: Vec<BlindedSignature> =
-            b_fst.iter().map(|b| self.blind_sign(b).unwrap()).collect();
-        let snd: Vec<BlindedSignature> =
-            b_snd.iter().map(|b| self.blind_sign(b).unwrap()).collect();
+                let outs_fst = (proofs_total.to_owned() - amount.to_owned()).split();
 
-        let split_response = SplitResponse { snd, fst };
+                // Blinded change messages
+                let b_fst = split_request.outputs[0..outs_fst.len()].to_vec();
+                let b_snd = split_request.outputs[outs_fst.len()..].to_vec();
+                let fst: Vec<BlindedSignature> =
+                    b_fst.iter().map(|b| self.blind_sign(b).unwrap()).collect();
+                let snd: Vec<BlindedSignature> =
+                    b_snd.iter().map(|b| self.blind_sign(b).unwrap()).collect();
 
-        if split_response.target_amount() != split_request.amount {
-            return Err(Error::OutputOrdering);
-        }
+                let split_response = SplitResponse::new_from_amount(snd, fst);
 
-        for proof in split_request.proofs {
-            self.spent_secrets.insert(proof.secret);
-        }
+                if split_response.target_amount() != split_request.amount {
+                    return Err(Error::OutputOrdering);
+                }
 
-        Ok(split_response)
+                Ok(split_response)
+            }
+        }
     }
 
     pub fn verify_proof(&self, proof: &Proof) -> Result<String, Error> {

+ 78 - 13
src/nuts/nut06.rs

@@ -17,7 +17,9 @@ pub struct SplitPayload {
 /// Split Request [NUT-06]
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub struct SplitRequest {
-    pub amount: Amount,
+    #[deprecated(since = "0.1.1", note = "mint does not need amount")]
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub amount: Option<Amount>,
     pub proofs: Proofs,
     pub outputs: Vec<BlindedMessage>,
 }
@@ -35,23 +37,86 @@ impl SplitRequest {
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub struct SplitResponse {
     /// Promises to keep
-    pub fst: Vec<BlindedSignature>,
+    #[deprecated(
+        since = "0.1.1",
+        note = "mint only response with one list of all promises"
+    )]
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub fst: Option<Vec<BlindedSignature>>,
     /// Promises to send
-    pub snd: Vec<BlindedSignature>,
+    #[deprecated(
+        since = "0.1.1",
+        note = "mint only response with one list of all promises"
+    )]
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub snd: Option<Vec<BlindedSignature>>,
+    /// Promises
+    pub promises: Option<Vec<BlindedSignature>>,
 }
 
 impl SplitResponse {
-    pub fn change_amount(&self) -> Amount {
-        self.fst
-            .iter()
-            .map(|BlindedSignature { amount, .. }| *amount)
-            .sum()
+    pub fn new(promises: Vec<BlindedSignature>) -> SplitResponse {
+        SplitResponse {
+            fst: None,
+            snd: None,
+            promises: Some(promises),
+        }
     }
 
-    pub fn target_amount(&self) -> Amount {
-        self.snd
-            .iter()
-            .map(|BlindedSignature { amount, .. }| *amount)
-            .sum()
+    #[deprecated(
+        since = "0.1.1",
+        note = "mint only response with one list of all promises"
+    )]
+    pub fn new_from_amount(
+        fst: Vec<BlindedSignature>,
+        snd: Vec<BlindedSignature>,
+    ) -> SplitResponse {
+        Self {
+            fst: Some(fst),
+            snd: Some(snd),
+            promises: None,
+        }
+    }
+
+    #[deprecated(
+        since = "0.1.1",
+        note = "mint only response with one list of all promises"
+    )]
+    pub fn change_amount(&self) -> Option<Amount> {
+        match &self.fst {
+            Some(fst) => Some(
+                fst.iter()
+                    .map(|BlindedSignature { amount, .. }| *amount)
+                    .sum(),
+            ),
+            None => None,
+        }
+    }
+
+    #[deprecated(
+        since = "0.1.1",
+        note = "mint only response with one list of all promises"
+    )]
+    pub fn target_amount(&self) -> Option<Amount> {
+        match &self.snd {
+            Some(snd) => Some(
+                snd.iter()
+                    .map(|BlindedSignature { amount, .. }| *amount)
+                    .sum(),
+            ),
+            None => None,
+        }
+    }
+
+    pub fn promises_amount(&self) -> Option<Amount> {
+        match &self.promises {
+            Some(promises) => Some(
+                promises
+                    .iter()
+                    .map(|BlindedSignature { amount, .. }| *amount)
+                    .sum(),
+            ),
+            None => None,
+        }
     }
 }

+ 70 - 38
src/wallet.rs

@@ -84,7 +84,7 @@ impl Wallet {
     pub async fn receive(&self, encoded_token: &str) -> Result<Proofs, Error> {
         let token_data = Token::from_str(encoded_token)?;
 
-        let mut proofs = vec![];
+        let mut proofs: Vec<Proofs> = vec![vec![]];
         for token in token_data.token {
             if token.proofs.is_empty() {
                 continue;
@@ -106,26 +106,36 @@ impl Wallet {
 
             let split_response = self.client.split(split_payload.split_payload).await?;
 
-            // Proof to keep
-            let keep_proofs = construct_proofs(
-                split_response.fst,
-                split_payload.keep_blinded_messages.rs,
-                split_payload.keep_blinded_messages.secrets,
-                &keys,
-            )?;
-
-            // Proofs to send
-            let send_proofs = construct_proofs(
-                split_response.snd,
-                split_payload.send_blinded_messages.rs,
-                split_payload.send_blinded_messages.secrets,
-                &keys,
-            )?;
-
-            proofs.push(keep_proofs);
-            proofs.push(send_proofs);
+            if let Some(promises) = &split_response.promises {
+                // Proof to keep
+                let p = construct_proofs(
+                    split_response.promises.unwrap(),
+                    split_payload.keep_blinded_messages.rs,
+                    split_payload.keep_blinded_messages.secrets,
+                    &keys,
+                )?;
+                proofs.push(p);
+            } else {
+                // Proof to keep
+                let keep_proofs = construct_proofs(
+                    split_response.fst.unwrap(),
+                    split_payload.keep_blinded_messages.rs,
+                    split_payload.keep_blinded_messages.secrets,
+                    &keys,
+                )?;
+
+                // Proofs to send
+                let send_proofs = construct_proofs(
+                    split_response.snd.unwrap(),
+                    split_payload.send_blinded_messages.rs,
+                    split_payload.send_blinded_messages.secrets,
+                    &keys,
+                )?;
+
+                proofs.push(send_proofs);
+                proofs.push(keep_proofs);
+            }
         }
-
         Ok(proofs.iter().flatten().cloned().collect())
     }
 
@@ -146,7 +156,7 @@ impl Wallet {
         };
 
         let split_payload = SplitRequest {
-            amount: send_amount,
+            amount: Some(send_amount),
             proofs,
             outputs,
         };
@@ -161,7 +171,7 @@ impl Wallet {
     pub fn process_split_response(
         &self,
         blinded_messages: BlindedMessages,
-        promisses: Vec<BlindedSignature>,
+        promises: Vec<BlindedSignature>,
     ) -> Result<Proofs, Error> {
         let BlindedMessages {
             blinded_messages: _,
@@ -173,7 +183,7 @@ impl Wallet {
         let secrets: Vec<_> = secrets.iter().collect();
         let mut proofs = vec![];
 
-        for (i, promise) in promisses.iter().enumerate() {
+        for (i, promise) in promises.iter().enumerate() {
             let a = self
                 .mint_keys
                 .amount_key(promise.amount)
@@ -225,26 +235,48 @@ impl Wallet {
         let amount_to_keep = amount_available - amount;
         let amount_to_send = amount;
 
+        // TODO: Will need to change https://github.com/cashubtc/cashu/pull/263/files
         let split_payload =
             self.create_split(amount_to_keep, amount_to_send, send_proofs.send_proofs)?;
 
         let split_response = self.client.split(split_payload.split_payload).await?;
 
-        // Proof to keep
-        let keep_proofs = construct_proofs(
-            split_response.fst,
-            split_payload.keep_blinded_messages.rs,
-            split_payload.keep_blinded_messages.secrets,
-            &self.mint_keys,
-        )?;
+        // If only prmises assemble proofs needed for amount
 
-        // Proofs to send
-        let send_proofs = construct_proofs(
-            split_response.snd,
-            split_payload.send_blinded_messages.rs,
-            split_payload.send_blinded_messages.secrets,
-            &self.mint_keys,
-        )?;
+        let keep_proofs;
+        let send_proofs;
+
+        if let Some(promises) = split_response.promises {
+            let proofs = construct_proofs(
+                promises,
+                split_payload.keep_blinded_messages.rs,
+                split_payload.keep_blinded_messages.secrets,
+                &self.mint_keys,
+            )?;
+
+            let split = amount_to_send.split();
+
+            keep_proofs = proofs[0..split.len()].to_vec();
+            send_proofs = proofs[split.len()..].to_vec();
+        } else if let (Some(fst), Some(snd)) = (split_response.fst, split_response.snd) {
+            // Proof to keep
+            keep_proofs = construct_proofs(
+                fst,
+                split_payload.keep_blinded_messages.rs,
+                split_payload.keep_blinded_messages.secrets,
+                &self.mint_keys,
+            )?;
+
+            // Proofs to send
+            send_proofs = construct_proofs(
+                snd,
+                split_payload.send_blinded_messages.rs,
+                split_payload.send_blinded_messages.secrets,
+                &self.mint_keys,
+            )?;
+        } else {
+            return Err(Error::CustomError("Invalid split response".to_string()));
+        }
 
         // println!("Send Proofs: {:#?}", send_proofs);
         // println!("Keep Proofs: {:#?}", keep_proofs);
@@ -343,7 +375,7 @@ mod tests {
         let p = split_response.snd;
 
         let snd_proofs = wallet
-            .process_split_response(split.send_blinded_messages, p)
+            .process_split_response(split.send_blinded_messages, p.unwrap())
             .unwrap();
 
         let mut error = false;