mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-22 05:25:41 +01:00
intergration tests
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use bitcoin::Amount;
|
||||
use k256::PublicKey;
|
||||
use lightning_invoice::Invoice;
|
||||
use serde_json::Value;
|
||||
use url::Url;
|
||||
@@ -26,7 +29,18 @@ impl CashuMint {
|
||||
/// Get Mint Keys [NUT-01]
|
||||
pub async fn get_keys(&self) -> Result<MintKeys, Error> {
|
||||
let url = self.url.join("keys")?;
|
||||
Ok(minreq::get(url).send()?.json::<MintKeys>()?)
|
||||
let keys = minreq::get(url).send()?.json::<HashMap<u64, String>>()?;
|
||||
|
||||
Ok(MintKeys(
|
||||
keys.into_iter()
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
k,
|
||||
PublicKey::from_sec1_bytes(&hex::decode(v).unwrap()).unwrap(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Get Keysets [NUT-02]
|
||||
|
||||
@@ -4,11 +4,11 @@ use bitcoin::Amount;
|
||||
|
||||
use crate::{
|
||||
cashu_mint::CashuMint,
|
||||
dhke::construct_proof,
|
||||
dhke::{construct_proofs, unblind_message},
|
||||
error::Error,
|
||||
types::{
|
||||
BlindedMessages, MintKeys, Proof, ProofsStatus, RequestMintResponse, SendProofs,
|
||||
SplitPayload, SplitRequest, TokenData,
|
||||
BlindedMessage, BlindedMessages, MintKeys, Proof, ProofsStatus, RequestMintResponse,
|
||||
SendProofs, SplitPayload, SplitRequest, Token, TokenData,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -43,6 +43,33 @@ impl CashuWallet {
|
||||
self.mint.request_mint(amount).await
|
||||
}
|
||||
|
||||
/// Mint Token
|
||||
pub async fn mint_token(&self, amount: Amount, payment_hash: &str) -> Result<TokenData, Error> {
|
||||
let blinded_messages = BlindedMessages::random(amount)?;
|
||||
|
||||
let mint_res = self
|
||||
.mint
|
||||
.mint(blinded_messages.clone(), payment_hash)
|
||||
.await?;
|
||||
|
||||
let proofs = construct_proofs(
|
||||
mint_res.promises,
|
||||
blinded_messages.rs,
|
||||
blinded_messages.secrets,
|
||||
&self.keys,
|
||||
)?;
|
||||
|
||||
let token = Token {
|
||||
mint: self.mint.url.clone(),
|
||||
proofs,
|
||||
};
|
||||
|
||||
Ok(TokenData {
|
||||
token: vec![token],
|
||||
memo: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Check fee
|
||||
pub async fn check_fee(&self, invoice: lightning_invoice::Invoice) -> Result<Amount, Error> {
|
||||
Ok(self.mint.check_fees(invoice).await?.fee)
|
||||
@@ -80,7 +107,7 @@ impl CashuWallet {
|
||||
let split_response = self.mint.split(split_payload.split_payload).await?;
|
||||
|
||||
// Proof to keep
|
||||
let keep_proofs = construct_proof(
|
||||
let keep_proofs = construct_proofs(
|
||||
split_response.fst,
|
||||
split_payload.keep_blinded_messages.rs,
|
||||
split_payload.keep_blinded_messages.secrets,
|
||||
@@ -88,7 +115,7 @@ impl CashuWallet {
|
||||
)?;
|
||||
|
||||
// Proofs to send
|
||||
let send_proofs = construct_proof(
|
||||
let send_proofs = construct_proofs(
|
||||
split_response.snd,
|
||||
split_payload.send_blinded_messages.rs,
|
||||
split_payload.send_blinded_messages.secrets,
|
||||
@@ -167,7 +194,7 @@ impl CashuWallet {
|
||||
let split_response = self.mint.split(split_payload.split_payload).await?;
|
||||
|
||||
// Proof to keep
|
||||
let keep_proofs = construct_proof(
|
||||
let keep_proofs = construct_proofs(
|
||||
split_response.fst,
|
||||
split_payload.keep_blinded_messages.rs,
|
||||
split_payload.keep_blinded_messages.secrets,
|
||||
@@ -175,7 +202,7 @@ impl CashuWallet {
|
||||
)?;
|
||||
|
||||
// Proofs to send
|
||||
let send_proofs = construct_proof(
|
||||
let send_proofs = construct_proofs(
|
||||
split_response.snd,
|
||||
split_payload.send_blinded_messages.rs,
|
||||
split_payload.send_blinded_messages.secrets,
|
||||
|
||||
14
src/dhke.rs
14
src/dhke.rs
@@ -94,7 +94,7 @@ fn _verify_message(a: SecretKey, unblinded_message: PublicKey, msg: &str) -> Res
|
||||
}
|
||||
|
||||
/// Construct Proof
|
||||
pub fn construct_proof(
|
||||
pub fn construct_proofs(
|
||||
promises: Vec<Promise>,
|
||||
rs: Vec<SecretKey>,
|
||||
secrets: Vec<String>,
|
||||
@@ -103,17 +103,9 @@ pub fn construct_proof(
|
||||
let mut proofs = vec![];
|
||||
for (i, promise) in promises.into_iter().enumerate() {
|
||||
let blinded_c = promise.c;
|
||||
let a: PublicKey = PublicKey::from_sec1_bytes(
|
||||
keys.0
|
||||
.get(&promise.amount.to_sat())
|
||||
.unwrap()
|
||||
.to_owned()
|
||||
.as_bytes(),
|
||||
)
|
||||
.unwrap();
|
||||
let a: PublicKey = keys.0.get(&promise.amount.to_sat()).unwrap().to_owned();
|
||||
// println!("Construct proof Pub {:?}", serde_json::to_string(&a));
|
||||
todo!();
|
||||
let unblinded_signature = unblind_message(blinded_c, rs[i], a)?;
|
||||
let unblinded_signature = unblind_message(blinded_c, rs[i].clone(), a)?;
|
||||
|
||||
let proof = Proof {
|
||||
id: Some(promise.id),
|
||||
|
||||
@@ -8,7 +8,7 @@ pub mod serde_url {
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(url.as_ref())
|
||||
serializer.serialize_str(url.to_string().trim_end_matches('/'))
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Url, D::Error>
|
||||
|
||||
25
src/types.rs
25
src/types.rs
@@ -125,8 +125,8 @@ pub struct Proof {
|
||||
}
|
||||
|
||||
/// Mint Keys [NUT-01]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MintKeys(pub HashMap<u64, String>);
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MintKeys(pub HashMap<u64, PublicKey>);
|
||||
|
||||
/// Mint Keysets [UT-02]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -321,6 +321,15 @@ impl FromStr for TokenData {
|
||||
Ok(token)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for TokenData {
|
||||
fn to_string(&self) -> String {
|
||||
let json_string = serde_json::to_string(self).unwrap();
|
||||
let encoded = general_purpose::STANDARD.encode(json_string);
|
||||
format!("cashuA{}", encoded)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -334,14 +343,20 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_token_from_str() {
|
||||
let token = "cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHBzOi8vODMzMy5zcGFjZTozMzM4IiwicHJvb2ZzIjpbeyJpZCI6IkRTQWw5bnZ2eWZ2YSIsImFtb3VudCI6Miwic2VjcmV0IjoiRWhwZW5uQzlxQjNpRmxXOEZaX3BadyIsIkMiOiIwMmMwMjAwNjdkYjcyN2Q1ODZiYzMxODNhZWNmOTdmY2I4MDBjM2Y0Y2M0NzU5ZjY5YzYyNmM5ZGI1ZDhmNWI1ZDQifSx7ImlkIjoiRFNBbDludnZ5ZnZhIiwiYW1vdW50Ijo4LCJzZWNyZXQiOiJUbVM2Q3YwWVQ1UFVfNUFUVktudWt3IiwiQyI6IjAyYWM5MTBiZWYyOGNiZTVkNzMyNTQxNWQ1YzI2MzAyNmYxNWY5Yjk2N2EwNzljYTk3NzlhYjZlNWMyZGIxMzNhNyJ9XX1dLCJtZW1vIjoiVGhhbmt5b3UuIn0=";
|
||||
let token = TokenData::from_str(token).unwrap();
|
||||
fn test_token_str_round_trip() {
|
||||
let token_str = "cashuAeyJ0b2tlbiI6W3sibWludCI6Imh0dHBzOi8vODMzMy5zcGFjZTozMzM4IiwicHJvb2ZzIjpbeyJpZCI6IkRTQWw5bnZ2eWZ2YSIsImFtb3VudCI6Miwic2VjcmV0IjoiRWhwZW5uQzlxQjNpRmxXOEZaX3BadyIsIkMiOiIwMmMwMjAwNjdkYjcyN2Q1ODZiYzMxODNhZWNmOTdmY2I4MDBjM2Y0Y2M0NzU5ZjY5YzYyNmM5ZGI1ZDhmNWI1ZDQifSx7ImlkIjoiRFNBbDludnZ5ZnZhIiwiYW1vdW50Ijo4LCJzZWNyZXQiOiJUbVM2Q3YwWVQ1UFVfNUFUVktudWt3IiwiQyI6IjAyYWM5MTBiZWYyOGNiZTVkNzMyNTQxNWQ1YzI2MzAyNmYxNWY5Yjk2N2EwNzljYTk3NzlhYjZlNWMyZGIxMzNhNyJ9XX1dLCJtZW1vIjoiVGhhbmt5b3UuIn0=";
|
||||
let token = TokenData::from_str(token_str).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
token.token[0].mint,
|
||||
Url::from_str("https://8333.space:3338").unwrap()
|
||||
);
|
||||
assert_eq!(token.token[0].proofs[0].clone().id.unwrap(), "DSAl9nvvyfva");
|
||||
|
||||
let encoded = &token.to_string();
|
||||
|
||||
let token_data = TokenData::from_str(encoded).unwrap();
|
||||
|
||||
assert_eq!(token_data, token);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user