WIP: send

This commit is contained in:
thesimplekid
2023-04-23 23:02:46 -04:00
parent 8aa2b42d25
commit 92c3b69c47
5 changed files with 86 additions and 2 deletions

View File

@@ -109,6 +109,7 @@ impl CashuMint {
// TODO: need to handle response error
// specfically token already spent
println!("{:?}", res);
Ok(serde_json::from_value(res).unwrap())
}

View File

@@ -7,8 +7,8 @@ use crate::{
dhke::construct_proof,
error::Error,
types::{
BlindedMessages, MintKeys, Proof, ProofsStatus, RequestMintResponse, SplitPayload,
SplitRequest, TokenData,
BlindedMessages, MintKeys, Proof, ProofsStatus, RequestMintResponse, SendProofs,
SplitPayload, SplitRequest, TokenData,
},
};
@@ -102,6 +102,7 @@ impl CashuWallet {
Ok(proofs.iter().flatten().cloned().collect())
}
/// Create Split Payload
pub async fn create_split(
&self,
keep_amount: Amount,
@@ -128,4 +129,59 @@ impl CashuWallet {
split_payload,
})
}
/// Send
pub async fn send(&self, amount: Amount, proofs: Vec<Proof>) -> Result<SendProofs, Error> {
let mut amount_avaliable = Amount::ZERO;
let mut send_proofs = SendProofs::default();
for proof in proofs {
amount_avaliable += proof.amount;
if amount_avaliable > amount {
send_proofs.change_proofs.push(proof);
break;
} else {
send_proofs.send_proofs.push(proof);
}
}
if amount_avaliable.lt(&amount) {
return Err(Error::InsufficantFunds);
}
// If amount avaliable is EQUAL to send amount no need to split
if amount_avaliable.eq(&amount) {
return Ok(send_proofs);
}
let amount_to_keep = amount_avaliable - amount;
let amount_to_send = amount;
let split_payload = self
.create_split(amount_to_keep, amount_to_send, send_proofs.send_proofs)
.await?;
let split_response = self.mint.split(split_payload.split_payload).await?;
// Proof to keep
let keep_proofs = construct_proof(
split_response.fst,
split_payload.keep_blinded_messages.rs,
split_payload.keep_blinded_messages.secrets,
&self.keys,
)?;
// Proofs to send
let send_proofs = construct_proof(
split_response.snd,
split_payload.send_blinded_messages.rs,
split_payload.send_blinded_messages.secrets,
&self.keys,
)?;
Ok(SendProofs {
change_proofs: keep_proofs,
send_proofs,
})
}
}

View File

@@ -23,4 +23,7 @@ pub enum Error {
/// Base64 error
#[error("Base64 error: {0}")]
Base64Error(#[from] base64::DecodeError),
/// Insufficaint Funds
#[error("Not enough funds")]
InsufficantFunds,
}

View File

@@ -147,6 +147,7 @@ pub struct PostMintResponse {
}
/// Check Fees Response [NUT-05]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CheckFeesResponse {
/// Expected Mac Fee in satoshis
@@ -219,6 +220,12 @@ pub struct ProofsStatus {
pub spent: Vec<Proof>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct SendProofs {
pub change_proofs: Vec<Proof>,
pub send_proofs: Vec<Proof>,
}
/// Mint Version
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MintVersion {

View File

@@ -83,6 +83,23 @@ async fn test_receive() {
println!("{:?}", prom);
}
// #[ignore]
#[tokio::test]
async fn test_send() {
let url = Url::from_str(MINTURL).unwrap();
let mint = CashuMint::new(url);
let mint_keys = mint.get_keys().await.unwrap();
let wallet = CashuWallet::new(mint, mint_keys);
// FIXME: Have to manully paste an unspent token
let token = "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJpZCI6Im9DV2NkWXJyeVRrUiIsImFtb3VudCI6MSwiQyI6IjAyMjRhMjU5NGY5NWMyMmRiZTA2YjZlN2YzMDNkYTdiZWYwNmM1YzI5YTBjMDU3ZWYyNmNhOWU3ZDVlYzc3MTYzZiIsInNlY3JldCI6IncyL1FpZjZFdlBRYWRtUlYxZzQyTWMrZWVVZ1V3TVZtSC9ndlVlaHhZTXM9In0seyJpZCI6Im9DV2NkWXJyeVRrUiIsImFtb3VudCI6NCwiQyI6IjAyMWEwYTIwYTZmOGEwY2JmMWY2Njc5OTIzNWE5N2U4ZTgxNjkxZWExMTFkMWVjYWJiOWZlZjE5OWRhMzYxNmU0YiIsInNlY3JldCI6InFYazRGbjZKdFBaUnVIRWlFMVVBUDB4MCtEcjd4Y21yNWRwTUVRRldDZ2s9In1dLCJtaW50IjoiaHR0cHM6Ly9sZWdlbmQubG5iaXRzLmNvbS9jYXNodS9hcGkvdjEvU0t2SFJ1czlkbWpXSGhzdEhyc2F6VyJ9XX0=";
let prom = wallet.receive(token).await.unwrap();
let send = wallet.send(Amount::from_sat(1), prom).await.unwrap();
println!("{:?}", send);
}
#[ignore]
#[tokio::test]
async fn test_get_mint_info() {