mint tests

This commit is contained in:
thesimplekid
2023-04-23 15:21:09 -04:00
parent 231bc6f286
commit e93104a3f1
7 changed files with 104 additions and 8 deletions

View File

@@ -5,9 +5,10 @@ use url::Url;
use crate::{
error::Error,
types::{
BlindedMessage, CheckFeesRequest, CheckFeesResponse, CheckSpendableRequest,
CheckSpendableResponse, MeltRequest, MeltResposne, MintInfo, MintKeySets, MintKeys,
MintRequest, PostMintResponse, Proof, RequestMintResponse, SplitRequest, SplitResponse,
BlindedMessage, BlindedMessages, CheckFeesRequest, CheckFeesResponse,
CheckSpendableRequest, CheckSpendableResponse, MeltRequest, MeltResposne, MintInfo,
MintKeySets, MintKeys, MintRequest, PostMintResponse, Proof, RequestMintResponse,
SplitRequest, SplitResponse,
},
};
@@ -45,7 +46,7 @@ impl CashuMint {
/// Mint Tokens [NUT-04]
pub async fn mint(
&self,
blinded_messages: Vec<BlindedMessage>,
blinded_messages: BlindedMessages,
payment_hash: &str,
) -> Result<PostMintResponse, Error> {
let mut url = self.url.join("mint")?;
@@ -53,7 +54,7 @@ impl CashuMint {
.append_pair("payment_hash", payment_hash);
let request = MintRequest {
outputs: blinded_messages,
outputs: blinded_messages.blinded_messages,
};
Ok(minreq::post(url)

View File

@@ -1,7 +1,6 @@
//! Diffie-Hellmann key exchange
use bitcoin_hashes::sha256;
// use bitcoin_hashes::Hash;
use bitcoin_hashes::Hash;
use secp256k1::rand::rngs::OsRng;
use secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};

View File

@@ -2,3 +2,4 @@ pub mod cashu_mint;
pub mod dhke;
pub mod error;
pub mod types;
pub mod utils;

View File

@@ -4,8 +4,12 @@ use std::collections::HashMap;
use bitcoin::Amount;
use lightning_invoice::Invoice;
use rand::Rng;
use secp256k1::{PublicKey, SecretKey};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::{dhke::blind_message, error::Error, utils::split_amount};
/// Blinded Message [NUT-00]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BlindedMessage {
@@ -14,7 +18,41 @@ pub struct BlindedMessage {
pub amount: Amount,
/// encrypted secret message (B_)
#[serde(rename = "B_")]
pub b: String,
pub b: PublicKey,
}
/// Blinded Messages [NUT-00]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct BlindedMessages {
/// Blinded messages
pub blinded_messages: Vec<BlindedMessage>,
/// Secrets
pub secrets: Vec<Vec<u8>>,
/// Rs
pub rs: Vec<SecretKey>,
/// Amounts
pub amounts: Vec<Amount>,
}
impl BlindedMessages {
pub fn random(amount: Amount) -> Result<Self, Error> {
let mut blinded_messages = BlindedMessages::default();
let mut rng = rand::thread_rng();
for amount in split_amount(amount) {
let bytes: [u8; 32] = rng.gen();
let (blinded, r) = blind_message(&bytes, None)?;
let blinded_message = BlindedMessage { amount, b: blinded };
blinded_messages.secrets.push(bytes.to_vec());
blinded_messages.blinded_messages.push(blinded_message);
blinded_messages.rs.push(r);
blinded_messages.amounts.push(amount);
}
Ok(blinded_messages)
}
}
/// Promise (BlindedSignature) [NIP-00]

36
src/utils.rs Normal file
View File

@@ -0,0 +1,36 @@
use bitcoin::Amount;
/// Split amount into cashu denominations (powers of 2)
pub fn split_amount(amount: Amount) -> Vec<Amount> {
let mut chunks = Vec::new();
let value = amount.to_sat();
for i in 0..64 {
let mask = 1 << i;
if (value & mask) != 0 {
chunks.push(Amount::from_sat(2u64.pow(i as u32)));
}
}
chunks
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_split_amount() {
assert_eq!(split_amount(Amount::from_sat(1)), vec![Amount::from_sat(1)]);
assert_eq!(split_amount(Amount::from_sat(2)), vec![Amount::from_sat(2)]);
assert_eq!(
split_amount(Amount::from_sat(3)),
vec![Amount::from_sat(1), Amount::from_sat(2)]
);
let amounts: Vec<Amount> = vec![1, 2, 8].iter().map(|a| Amount::from_sat(*a)).collect();
assert_eq!(split_amount(Amount::from_sat(11)), amounts);
let amounts: Vec<Amount> = vec![1, 2, 4, 8, 16, 32, 64, 128]
.iter()
.map(|a| Amount::from_sat(*a))
.collect();
assert_eq!(split_amount(Amount::from_sat(255)), amounts);
}
}