Skip to content

Commit

Permalink
fix: use different MintKeySets for v1 api
Browse files Browse the repository at this point in the history
  • Loading branch information
ngutech21 committed Dec 6, 2023
1 parent 9eceb68 commit 2b4a7aa
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 54 deletions.
62 changes: 37 additions & 25 deletions moksha-mint/src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,15 @@ impl Mint {
pub fn create_blinded_signatures(
&self,
blinded_messages: &[BlindedMessage],
keyset: &MintKeyset, // FIXME refactor keyset management
) -> Result<Vec<BlindedSignature>, MokshaMintError> {
let promises = blinded_messages
.iter()
.map(|blinded_msg| {
let private_key = self
.keyset_legacy
.private_keys
.get(&blinded_msg.amount)
.unwrap(); // FIXME unwrap
let private_key = keyset.private_keys.get(&blinded_msg.amount).unwrap(); // FIXME unwrap
let blinded_sig = self.dhke.step2_bob(blinded_msg.b_, private_key).unwrap(); // FIXME unwrap
BlindedSignature {
id: Some(self.keyset_legacy.keyset_id.clone()),
id: Some(keyset.keyset_id.clone()),
amount: blinded_msg.amount,
c_: blinded_sig,
}
Expand All @@ -124,6 +121,7 @@ impl Mint {
&self,
key: String,
outputs: &[BlindedMessage],
keyset: &MintKeyset,
) -> Result<Vec<BlindedSignature>, MokshaMintError> {
let invoice = self.db.get_pending_invoice(key.clone())?;

Expand All @@ -137,7 +135,7 @@ impl Mint {
}

self.db.remove_pending_invoice(key)?;
self.create_blinded_signatures(outputs)
self.create_blinded_signatures(outputs, keyset)
}

fn has_duplicate_pubkeys(outputs: &[BlindedMessage]) -> bool {
Expand All @@ -149,7 +147,8 @@ impl Mint {
&self,
proofs: &Proofs,
blinded_messages: &[BlindedMessage],
) -> Result<PostSwapResponse, MokshaMintError> {
keyset: &MintKeyset,
) -> Result<Vec<BlindedSignature>, MokshaMintError> {
self.check_used_proofs(proofs)?;

if Self::has_duplicate_pubkeys(blinded_messages) {
Expand All @@ -158,7 +157,7 @@ impl Mint {

let sum_proofs = proofs.total_amount();

let promises = self.create_blinded_signatures(blinded_messages)?;
let promises = self.create_blinded_signatures(blinded_messages, keyset)?;
let amount_promises = promises.total_amount();
if sum_proofs != amount_promises {
return Err(MokshaMintError::SwapAmountMismatch(format!(
Expand All @@ -167,14 +166,15 @@ impl Mint {
}

self.db.add_used_proofs(proofs)?;
Ok(PostSwapResponse::with_promises(promises))
Ok(promises)
}

pub async fn melt(
&self,
payment_request: String,
proofs: &Proofs,
blinded_messages: &[BlindedMessage],
keyset: &MintKeyset,
) -> Result<(bool, String, Vec<BlindedSignature>), MokshaMintError> {
let invoice = self
.lightning
Expand Down Expand Up @@ -206,7 +206,7 @@ impl Mint {
let _remaining_amount = (amount_msat - (proofs_amount / 1000)) * 1000;

// FIXME check if output amount matches remaining_amount
let output = self.create_blinded_signatures(blinded_messages)?;
let output = self.create_blinded_signatures(blinded_messages, keyset)?;

Ok((true, result.payment_hash, output))
}
Expand Down Expand Up @@ -321,7 +321,7 @@ mod tests {
use crate::{database::MockDatabase, error::MokshaMintError};
use moksha_core::blind::{BlindedMessage, TotalAmount};
use moksha_core::dhke;
use moksha_core::primitives::PostSwapRequest;
use moksha_core::primitives::PostSplitRequest;
use moksha_core::proof::Proofs;
use moksha_core::token::TokenV3;
use std::str::FromStr;
Expand All @@ -346,7 +346,7 @@ mod tests {
),
}];

let result = mint.create_blinded_signatures(&blinded_messages)?;
let result = mint.create_blinded_signatures(&blinded_messages, &mint.keyset_legacy)?;

assert_eq!(1, result.len());
assert_eq!(8, result[0].amount);
Expand All @@ -366,7 +366,9 @@ mod tests {
let mint = create_mint_from_mocks(Some(create_mock_mint()), Some(lightning));

let outputs = vec![];
let result = mint.mint_tokens("somehash".to_string(), &outputs).await?;
let result = mint
.mint_tokens("somehash".to_string(), &outputs, &mint.keyset_legacy)
.await?;
assert!(result.is_empty());
Ok(())
}
Expand All @@ -378,7 +380,9 @@ mod tests {
let mint = create_mint_from_mocks(Some(create_mock_mint()), Some(lightning));

let outputs = create_blinded_msgs_from_fixture("blinded_messages_40.json".to_string())?;
let result = mint.mint_tokens("somehash".to_string(), &outputs).await?;
let result = mint
.mint_tokens("somehash".to_string(), &outputs, &mint.keyset_legacy)
.await?;
assert_eq!(40, result.total_amount());
Ok(())
}
Expand All @@ -389,9 +393,11 @@ mod tests {
let mint = create_mint_from_mocks(Some(create_mock_db_get_used_proofs()), None);

let proofs = Proofs::empty();
let result = mint.swap(&proofs, &blinded_messages).await?;
let result = mint
.swap(&proofs, &blinded_messages, &mint.keyset_legacy)
.await?;

assert!(result.promises.is_empty());
assert!(result.is_empty());
Ok(())
}

Expand All @@ -400,11 +406,13 @@ mod tests {
let mint = create_mint_from_mocks(Some(create_mock_db_get_used_proofs()), None);
let request = create_request_from_fixture("post_split_request_64_20.json".to_string())?;

let result = mint.swap(&request.proofs, &request.outputs).await?;
assert_eq!(result.promises.total_amount(), 64);
let result = mint
.swap(&request.proofs, &request.outputs, &mint.keyset_legacy)
.await?;
assert_eq!(result.total_amount(), 64);

let prv_lst = result.promises.get(result.promises.len() - 2).unwrap();
let lst = result.promises.last().unwrap();
let prv_lst = result.get(result.len() - 2).unwrap();
let lst = result.last().unwrap();

assert_eq!(prv_lst.amount, 4);
assert_eq!(lst.amount, 16);
Expand All @@ -417,7 +425,9 @@ mod tests {
let request =
create_request_from_fixture("post_split_request_duplicate_key.json".to_string())?;

let result = mint.swap(&request.proofs, &request.outputs).await;
let result = mint
.swap(&request.proofs, &request.outputs, &mint.keyset_legacy)
.await;
assert!(result.is_err());
Ok(())
}
Expand Down Expand Up @@ -456,7 +466,9 @@ mod tests {
let invoice = "some invoice".to_string();
let change = create_blinded_msgs_from_fixture("blinded_messages_40.json".to_string())?;

let (paid, _payment_hash, change) = mint.melt(invoice, &tokens.proofs(), &change).await?;
let (paid, _payment_hash, change) = mint
.melt(invoice, &tokens.proofs(), &change, &mint.keyset_legacy)
.await?;

assert!(paid);
assert!(change.total_amount() == 40);
Expand All @@ -470,10 +482,10 @@ mod tests {
Ok(raw_token.trim().to_string().try_into()?)
}

fn create_request_from_fixture(fixture: String) -> Result<PostSwapRequest, anyhow::Error> {
fn create_request_from_fixture(fixture: String) -> Result<PostSplitRequest, anyhow::Error> {
let base_dir = std::env::var("CARGO_MANIFEST_DIR")?;
let raw_token = std::fs::read_to_string(format!("{base_dir}/src/fixtures/{fixture}"))?;
Ok(serde_json::from_str::<PostSwapRequest>(&raw_token)?)
Ok(serde_json::from_str::<PostSplitRequest>(&raw_token)?)
}

fn create_blinded_msgs_from_fixture(
Expand Down
68 changes: 56 additions & 12 deletions moksha-mint/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ use moksha_core::primitives::{
PaymentRequest, PostMeltBolt11Request, PostMeltBolt11Response, PostMeltQuoteBolt11Request,
PostMeltQuoteBolt11Response, PostMeltRequest, PostMeltResponse, PostMintBolt11Request,
PostMintBolt11Response, PostMintQuoteBolt11Request, PostMintQuoteBolt11Response,
PostMintRequest, PostMintResponse, PostSwapRequest, PostSwapResponse,
PostMintRequest, PostMintResponse, PostSplitRequest, PostSplitResponse, PostSwapRequest,
PostSwapResponse,
};
use secp256k1::PublicKey;

Expand Down Expand Up @@ -79,11 +80,12 @@ fn app(mint: Mint, serve_wallet_path: Option<PathBuf>, prefix: Option<String>) -
.route("/mint", get(get_legacy_mint).post(post_legacy_mint))
.route("/checkfees", post(post_legacy_check_fees))
.route("/melt", post(post_legacy_melt))
.route("/split", post(post_swap))
.route("/split", post(post_legacy_split))
.route("/info", get(get_legacy_info));

let routes = Router::new()
.route("/v1/keys", get(get_keys))
.route("/v1/keys/:id", get(get_keys_by_id))
.route("/v1/keysets", get(get_keysets))
.route("/v1/mint/quote/bolt11", post(post_mint_quote_bolt11))
.route("/v1/mint/quote/bolt11/:quote", get(get_mint_quote_bolt11))
Expand Down Expand Up @@ -145,23 +147,32 @@ async fn add_response_headers(
Ok(res)
}

async fn post_swap(
async fn post_legacy_split(
State(mint): State<Mint>,
Json(swap_request): Json<PostSwapRequest>,
) -> Result<Json<PostSwapResponse>, MokshaMintError> {
Json(swap_request): Json<PostSplitRequest>,
) -> Result<Json<PostSplitResponse>, MokshaMintError> {
let response = mint
.swap(&swap_request.proofs, &swap_request.outputs)
.swap(
&swap_request.proofs,
&swap_request.outputs,
&mint.keyset_legacy,
)
.await?;

Ok(Json(response))
Ok(Json(PostSplitResponse::with_promises(response)))
}

async fn post_legacy_melt(
State(mint): State<Mint>,
Json(melt_request): Json<PostMeltRequest>,
) -> Result<Json<PostMeltResponse>, MokshaMintError> {
let (paid, preimage, change) = mint
.melt(melt_request.pr, &melt_request.proofs, &melt_request.outputs)
.melt(
melt_request.pr,
&melt_request.proofs,
&melt_request.outputs,
&mint.keyset_legacy,
)
.await?;

Ok(Json(PostMeltResponse {
Expand Down Expand Up @@ -237,7 +248,11 @@ async fn post_legacy_mint(
);

let promises = mint
.mint_tokens(mint_query.hash, &blinded_messages.outputs)
.mint_tokens(
mint_query.hash,
&blinded_messages.outputs,
&mint.keyset_legacy,
)
.await?;
Ok(Json(PostMintResponse { promises }))
}
Expand All @@ -254,6 +269,19 @@ async fn get_legacy_keysets(State(mint): State<Mint>) -> Result<Json<Keysets>, M

// ######################################################################################################

async fn post_swap(
State(mint): State<Mint>,
Json(swap_request): Json<PostSwapRequest>,
) -> Result<Json<PostSwapResponse>, MokshaMintError> {
let response = mint
.swap(&swap_request.inputs, &swap_request.outputs, &mint.keyset)
.await?;

Ok(Json(PostSwapResponse {
signatures: response,
}))
}

async fn get_keys(State(mint): State<Mint>) -> Result<Json<KeysResponse>, MokshaMintError> {
Ok(Json(KeysResponse {
keysets: vec![KeyResponse {
Expand All @@ -264,6 +292,19 @@ async fn get_keys(State(mint): State<Mint>) -> Result<Json<KeysResponse>, Moksha
}))
}

async fn get_keys_by_id(
Path(_id): Path<String>,
State(mint): State<Mint>,
) -> Result<Json<KeysResponse>, MokshaMintError> {
Ok(Json(KeysResponse {
keysets: vec![KeyResponse {
id: mint.keyset.keyset_id.clone(),
unit: CurrencyUnit::Sat,
keys: mint.keyset.public_keys.clone(),
}],
}))
}

async fn get_keysets(State(mint): State<Mint>) -> Result<Json<V1Keysets>, MokshaMintError> {
Ok(Json(V1Keysets::new(
mint.keyset.keyset_id,
Expand Down Expand Up @@ -309,7 +350,9 @@ async fn post_mint_bolt11(

match quote {
Quote::Bolt11Mint { .. } => {
let signatures = mint.mint_tokens(request.quote, &request.outputs).await?;
let signatures = mint
.mint_tokens(request.quote, &request.outputs, &mint.keyset)
.await?;
Ok(Json(PostMintBolt11Response { signatures }))
}
_ => Err(crate::error::MokshaMintError::InvalidQuote(
Expand All @@ -329,7 +372,8 @@ async fn post_melt_quote_bolt11(
let amount = invoice
.amount_milli_satoshis()
.ok_or_else(|| crate::error::MokshaMintError::InvalidAmount)?;
let fee_reserve = mint.fee_reserve(amount);
let fee_reserve = mint.fee_reserve(amount) / 1_000; // FIXME check if this is correct
info!("fee_reserve: {}", fee_reserve);

let amount_sat = amount / 1_000;
// Store quote in db
Expand Down Expand Up @@ -361,7 +405,7 @@ async fn post_melt_bolt11(
match quote {
Quote::Bolt11Melt { .. } => {
let (paid, preimage, change) = mint
.melt(melt_request.quote, &melt_request.inputs, &[])
.melt(melt_request.quote, &melt_request.inputs, &[], &mint.keyset)
.await?;

Ok(Json(PostMeltBolt11Response {
Expand Down
4 changes: 2 additions & 2 deletions moksha-wallet/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use moksha_core::{
blind::BlindedMessage,
keyset::Keysets,
primitives::{
CheckFeesResponse, PaymentRequest, PostMeltResponse, PostMintResponse, PostSwapResponse,
CheckFeesResponse, PaymentRequest, PostMeltResponse, PostMintResponse, PostSplitResponse,
},
proof::Proofs,
};
Expand All @@ -24,7 +24,7 @@ pub trait Client {
mint_url: &Url,
proofs: Proofs,
output: Vec<BlindedMessage>,
) -> Result<PostSwapResponse, MokshaWalletError>;
) -> Result<PostSplitResponse, MokshaWalletError>;

async fn post_mint_payment_request(
&self,
Expand Down
9 changes: 5 additions & 4 deletions moksha-wallet/src/client/reqwest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use moksha_core::{
keyset::Keysets,
primitives::{
CashuErrorResponse, CheckFeesRequest, CheckFeesResponse, PaymentRequest, PostMeltRequest,
PostMeltResponse, PostMintRequest, PostMintResponse, PostSwapRequest, PostSwapResponse,
PostMeltResponse, PostMintRequest, PostMintResponse, PostSplitRequest, PostSplitResponse,
PostSwapResponse,
},
proof::Proofs,
};
Expand Down Expand Up @@ -44,8 +45,8 @@ impl Client for HttpClient {
mint_url: &Url,
proofs: Proofs,
outputs: Vec<BlindedMessage>,
) -> Result<PostSwapResponse, MokshaWalletError> {
let body = serde_json::to_string(&PostSwapRequest { proofs, outputs })?;
) -> Result<PostSplitResponse, MokshaWalletError> {
let body = serde_json::to_string(&PostSplitRequest { proofs, outputs })?;

let resp = self
.request_client
Expand All @@ -55,7 +56,7 @@ impl Client for HttpClient {
.send()
.await?;

extract_response_data::<PostSwapResponse>(resp).await
extract_response_data::<PostSplitResponse>(resp).await
}

async fn post_melt_tokens(
Expand Down
Loading

0 comments on commit 2b4a7aa

Please sign in to comment.