mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-23 23:55:01 +01:00
Merge pull request #690 from thesimplekid/request_without_dleq
Request without dleq
This commit is contained in:
@@ -164,7 +164,7 @@ pub struct AuthProof {
|
||||
#[cfg_attr(feature = "swagger", schema(value_type = String))]
|
||||
pub c: PublicKey,
|
||||
/// Auth Proof Dleq
|
||||
pub dleq: ProofDleq,
|
||||
pub dleq: Option<ProofDleq>,
|
||||
}
|
||||
|
||||
impl AuthProof {
|
||||
@@ -182,7 +182,7 @@ impl From<AuthProof> for Proof {
|
||||
secret: value.secret,
|
||||
c: value.c,
|
||||
witness: None,
|
||||
dleq: Some(value.dleq),
|
||||
dleq: value.dleq,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,10 +194,7 @@ impl TryFrom<Proof> for AuthProof {
|
||||
keyset_id: value.keyset_id,
|
||||
secret: value.secret,
|
||||
c: value.c,
|
||||
dleq: value.dleq.ok_or_else(|| {
|
||||
tracing::warn!("Dleq proof not included in auth");
|
||||
Error::DleqProofNotIncluded
|
||||
})?,
|
||||
dleq: value.dleq,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -214,6 +211,20 @@ impl BlindAuthToken {
|
||||
pub fn new(auth_proof: AuthProof) -> Self {
|
||||
BlindAuthToken { auth_proof }
|
||||
}
|
||||
|
||||
/// Remove DLEQ
|
||||
///
|
||||
/// We do not send the DLEQ to the mint as it links redemption and creation
|
||||
pub fn without_dleq(&self) -> Self {
|
||||
Self {
|
||||
auth_proof: AuthProof {
|
||||
keyset_id: self.auth_proof.keyset_id,
|
||||
secret: self.auth_proof.secret.clone(),
|
||||
c: self.auth_proof.c,
|
||||
dleq: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BlindAuthToken {
|
||||
|
||||
@@ -50,6 +50,9 @@ pub trait ProofsMethods {
|
||||
|
||||
/// Try to fetch the pubkeys of all [Proof]s
|
||||
fn ys(&self) -> Result<Vec<PublicKey>, Error>;
|
||||
|
||||
/// Create a copy of proofs without dleqs
|
||||
fn without_dleqs(&self) -> Proofs;
|
||||
}
|
||||
|
||||
impl ProofsMethods for Proofs {
|
||||
@@ -68,6 +71,16 @@ impl ProofsMethods for Proofs {
|
||||
fn ys(&self) -> Result<Vec<PublicKey>, Error> {
|
||||
ys(self.iter())
|
||||
}
|
||||
|
||||
fn without_dleqs(&self) -> Proofs {
|
||||
self.iter()
|
||||
.map(|p| {
|
||||
let mut p = p.clone();
|
||||
p.dleq = None;
|
||||
p
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl ProofsMethods for HashSet<Proof> {
|
||||
@@ -86,6 +99,16 @@ impl ProofsMethods for HashSet<Proof> {
|
||||
fn ys(&self) -> Result<Vec<PublicKey>, Error> {
|
||||
ys(self.iter())
|
||||
}
|
||||
|
||||
fn without_dleqs(&self) -> Proofs {
|
||||
self.iter()
|
||||
.map(|p| {
|
||||
let mut p = p.clone();
|
||||
p.dleq = None;
|
||||
p
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn count_by_keyset<'a, I: Iterator<Item = &'a Proof>>(proofs: I) -> HashMap<Id, u64> {
|
||||
|
||||
@@ -8,6 +8,7 @@ use thiserror::Error;
|
||||
#[cfg(feature = "wallet")]
|
||||
use super::nut00::PreMintSecrets;
|
||||
use super::nut00::{BlindSignature, BlindedMessage, Proofs};
|
||||
use super::ProofsMethods;
|
||||
use crate::Amount;
|
||||
|
||||
/// NUT03 Error
|
||||
@@ -41,15 +42,33 @@ pub struct PreSwap {
|
||||
pub struct SwapRequest {
|
||||
/// Proofs that are to be spent in a `Swap`
|
||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
|
||||
pub inputs: Proofs,
|
||||
inputs: Proofs,
|
||||
/// Blinded Messages for Mint to sign
|
||||
pub outputs: Vec<BlindedMessage>,
|
||||
outputs: Vec<BlindedMessage>,
|
||||
}
|
||||
|
||||
impl SwapRequest {
|
||||
/// Create new [`SwapRequest`]
|
||||
pub fn new(inputs: Proofs, outputs: Vec<BlindedMessage>) -> Self {
|
||||
Self { inputs, outputs }
|
||||
Self {
|
||||
inputs: inputs.without_dleqs(),
|
||||
outputs,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get inputs (proofs)
|
||||
pub fn inputs(&self) -> &Proofs {
|
||||
&self.inputs
|
||||
}
|
||||
|
||||
/// Get outputs (blinded messages)
|
||||
pub fn outputs(&self) -> &Vec<BlindedMessage> {
|
||||
&self.outputs
|
||||
}
|
||||
|
||||
/// Get mutable reference to outputs (blinded messages)
|
||||
pub fn outputs_mut(&mut self) -> &mut Vec<BlindedMessage> {
|
||||
&mut self.outputs
|
||||
}
|
||||
|
||||
/// Total value of proofs in [`SwapRequest`]
|
||||
@@ -76,9 +95,9 @@ pub struct SwapResponse {
|
||||
}
|
||||
|
||||
impl SwapResponse {
|
||||
/// Create new [`SwapRequest`]
|
||||
pub fn new(promises: Vec<BlindSignature>) -> SwapResponse {
|
||||
SwapResponse {
|
||||
/// Create new [`SwapResponse`]
|
||||
pub fn new(promises: Vec<BlindSignature>) -> Self {
|
||||
Self {
|
||||
signatures: promises,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use uuid::Uuid;
|
||||
|
||||
use super::nut00::{BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod, Proofs};
|
||||
use super::nut15::Mpp;
|
||||
use super::ProofsMethods;
|
||||
use crate::nuts::MeltQuoteState;
|
||||
use crate::{Amount, Bolt11Invoice};
|
||||
|
||||
@@ -320,13 +321,13 @@ impl<'de, Q: DeserializeOwned> Deserialize<'de> for MeltQuoteBolt11Response<Q> {
|
||||
#[serde(bound = "Q: Serialize + DeserializeOwned")]
|
||||
pub struct MeltBolt11Request<Q> {
|
||||
/// Quote ID
|
||||
pub quote: Q,
|
||||
quote: Q,
|
||||
/// Proofs
|
||||
#[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
|
||||
pub inputs: Proofs,
|
||||
inputs: Proofs,
|
||||
/// Blinded Message that can be used to return change [NUT-08]
|
||||
/// Amount field of BlindedMessages `SHOULD` be set to zero
|
||||
pub outputs: Option<Vec<BlindedMessage>>,
|
||||
outputs: Option<Vec<BlindedMessage>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "mint")]
|
||||
@@ -342,7 +343,34 @@ impl TryFrom<MeltBolt11Request<String>> for MeltBolt11Request<Uuid> {
|
||||
}
|
||||
}
|
||||
|
||||
// Basic implementation without trait bounds
|
||||
impl<Q> MeltBolt11Request<Q> {
|
||||
/// Get inputs (proofs)
|
||||
pub fn inputs(&self) -> &Proofs {
|
||||
&self.inputs
|
||||
}
|
||||
|
||||
/// Get outputs (blinded messages for change)
|
||||
pub fn outputs(&self) -> &Option<Vec<BlindedMessage>> {
|
||||
&self.outputs
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Serialize + DeserializeOwned> MeltBolt11Request<Q> {
|
||||
/// Create new [`MeltBolt11Request`]
|
||||
pub fn new(quote: Q, inputs: Proofs, outputs: Option<Vec<BlindedMessage>>) -> Self {
|
||||
Self {
|
||||
quote,
|
||||
inputs: inputs.without_dleqs(),
|
||||
outputs,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get quote
|
||||
pub fn quote(&self) -> &Q {
|
||||
&self.quote
|
||||
}
|
||||
|
||||
/// Total [`Amount`] of [`Proofs`]
|
||||
pub fn proofs_amount(&self) -> Result<Amount, Error> {
|
||||
Amount::try_sum(self.inputs.iter().map(|proof| proof.amount))
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::Amount;
|
||||
impl<Q> MeltBolt11Request<Q> {
|
||||
/// Total output [`Amount`]
|
||||
pub fn output_amount(&self) -> Option<Amount> {
|
||||
self.outputs
|
||||
self.outputs()
|
||||
.as_ref()
|
||||
.and_then(|o| Amount::try_sum(o.iter().map(|proof| proof.amount)).ok())
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ pub(crate) async fn get_mint_info(
|
||||
/// Requests a set of Proofs to be swapped for another set of BlindSignatures.
|
||||
///
|
||||
/// This endpoint can be used by Alice to swap a set of proofs before making a payment to Carol. It can then used by Carol to redeem the tokens for new proofs.
|
||||
#[instrument(skip_all, fields(inputs_count = ?payload.inputs.len()))]
|
||||
#[instrument(skip_all, fields(inputs_count = ?payload.inputs().len()))]
|
||||
pub(crate) async fn post_swap(
|
||||
#[cfg(feature = "auth")] auth: AuthHeader,
|
||||
State(state): State<MintState>,
|
||||
|
||||
@@ -156,10 +156,7 @@ async fn test_mint_bat_without_cat() {
|
||||
async fn test_swap_without_auth() {
|
||||
let client = HttpClient::new(MintUrl::from_str(MINT_URL).expect("Valid mint url"), None);
|
||||
|
||||
let request = SwapRequest {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
};
|
||||
let request = SwapRequest::new(vec![], vec![]);
|
||||
|
||||
let quote_res = client.post_swap(request).await;
|
||||
|
||||
@@ -210,11 +207,11 @@ async fn test_melt_without_auth() {
|
||||
|
||||
// Test melt
|
||||
{
|
||||
let request = MeltBolt11Request {
|
||||
inputs: vec![],
|
||||
outputs: None,
|
||||
quote: "123e4567-e89b-12d3-a456-426614174000".to_string(),
|
||||
};
|
||||
let request = MeltBolt11Request::new(
|
||||
"123e4567-e89b-12d3-a456-426614174000".to_string(),
|
||||
vec![],
|
||||
None,
|
||||
);
|
||||
|
||||
let melt_res = client.post_melt(request).await;
|
||||
|
||||
@@ -571,7 +568,7 @@ async fn test_melt_with_invalid_auth() {
|
||||
keyset_id: proof.keyset_id,
|
||||
secret: proof.secret.clone(),
|
||||
c: proof.c,
|
||||
dleq: proof.dleq.clone().unwrap(),
|
||||
dleq: proof.dleq.clone(),
|
||||
};
|
||||
|
||||
let _auth_token = AuthToken::BlindAuth(BlindAuthToken::new(invalid_auth_proof));
|
||||
|
||||
@@ -355,11 +355,11 @@ async fn test_fake_melt_change_in_quote() -> Result<()> {
|
||||
|
||||
let client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: melt_quote.id.clone(),
|
||||
inputs: proofs.clone(),
|
||||
outputs: Some(premint_secrets.blinded_messages()),
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(
|
||||
melt_quote.id.clone(),
|
||||
proofs.clone(),
|
||||
Some(premint_secrets.blinded_messages()),
|
||||
);
|
||||
|
||||
let melt_response = client.post_melt(melt_request).await?;
|
||||
|
||||
@@ -676,10 +676,7 @@ async fn test_fake_mint_multiple_unit_swap() -> Result<()> {
|
||||
let pre_mint =
|
||||
PreMintSecrets::random(active_keyset_id, inputs.total_amount()?, &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(inputs, pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -713,10 +710,7 @@ async fn test_fake_mint_multiple_unit_swap() -> Result<()> {
|
||||
|
||||
usd_outputs.append(&mut sat_outputs);
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs,
|
||||
outputs: usd_outputs,
|
||||
};
|
||||
let swap_request = SwapRequest::new(inputs, usd_outputs);
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -786,11 +780,7 @@ async fn test_fake_mint_multiple_unit_melt() -> Result<()> {
|
||||
let invoice = create_fake_invoice((input_amount - 1) * 1000, "".to_string());
|
||||
let melt_quote = wallet.melt_quote(invoice.to_string(), None).await?;
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: melt_quote.id,
|
||||
inputs,
|
||||
outputs: None,
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(melt_quote.id, inputs, None);
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_melt(melt_request.clone()).await;
|
||||
@@ -830,11 +820,7 @@ async fn test_fake_mint_multiple_unit_melt() -> Result<()> {
|
||||
usd_outputs.append(&mut sat_outputs);
|
||||
let quote = wallet.melt_quote(invoice.to_string(), None).await?;
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: quote.id,
|
||||
inputs,
|
||||
outputs: Some(usd_outputs),
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(quote.id, inputs, Some(usd_outputs));
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
|
||||
@@ -890,10 +876,7 @@ async fn test_fake_mint_input_output_mismatch() -> Result<()> {
|
||||
&SplitTarget::None,
|
||||
)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(inputs, pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -930,10 +913,7 @@ async fn test_fake_mint_swap_inflated() -> Result<()> {
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 101.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs, pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -973,10 +953,7 @@ async fn test_fake_mint_swap_spend_after_fail() -> Result<()> {
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 100.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs.clone(),
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs.clone(), pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -985,10 +962,7 @@ async fn test_fake_mint_swap_spend_after_fail() -> Result<()> {
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 101.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs.clone(),
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs.clone(), pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1003,10 +977,7 @@ async fn test_fake_mint_swap_spend_after_fail() -> Result<()> {
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 100.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs, pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1046,10 +1017,7 @@ async fn test_fake_mint_melt_spend_after_fail() -> Result<()> {
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 100.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs.clone(),
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs.clone(), pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1058,10 +1026,7 @@ async fn test_fake_mint_melt_spend_after_fail() -> Result<()> {
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 101.into(), &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: proofs.clone(),
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(proofs.clone(), pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1078,11 +1043,7 @@ async fn test_fake_mint_melt_spend_after_fail() -> Result<()> {
|
||||
let invoice = create_fake_invoice((input_amount - 1) * 1000, "".to_string());
|
||||
let melt_quote = wallet.melt_quote(invoice.to_string(), None).await?;
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: melt_quote.id,
|
||||
inputs: proofs,
|
||||
outputs: None,
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(melt_quote.id, proofs, None);
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_melt(melt_request.clone()).await;
|
||||
@@ -1126,10 +1087,7 @@ async fn test_fake_mint_duplicate_proofs_swap() -> Result<()> {
|
||||
let pre_mint =
|
||||
PreMintSecrets::random(active_keyset_id, inputs.total_amount()?, &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs: inputs.clone(),
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
let swap_request = SwapRequest::new(inputs.clone(), pre_mint.blinded_messages());
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1153,7 +1111,7 @@ async fn test_fake_mint_duplicate_proofs_swap() -> Result<()> {
|
||||
|
||||
let outputs = vec![blinded_message[0].clone(), blinded_message[0].clone()];
|
||||
|
||||
let swap_request = SwapRequest { inputs, outputs };
|
||||
let swap_request = SwapRequest::new(inputs, outputs);
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
@@ -1199,11 +1157,7 @@ async fn test_fake_mint_duplicate_proofs_melt() -> Result<()> {
|
||||
|
||||
let melt_quote = wallet.melt_quote(invoice.to_string(), None).await?;
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: melt_quote.id,
|
||||
inputs,
|
||||
outputs: None,
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(melt_quote.id, inputs, None);
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?, None);
|
||||
let response = http_client.post_melt(melt_request.clone()).await;
|
||||
|
||||
@@ -215,7 +215,7 @@ pub async fn test_p2pk_swap() -> Result<()> {
|
||||
|
||||
// Listen for status updates on all input proof pks
|
||||
let public_keys_to_listen: Vec<_> = swap_request
|
||||
.inputs
|
||||
.inputs()
|
||||
.ys()?
|
||||
.iter()
|
||||
.map(|pk| pk.to_string())
|
||||
|
||||
@@ -543,7 +543,7 @@ impl MintQuotesDatabase for MintRedbDatabase {
|
||||
|
||||
table
|
||||
.insert(
|
||||
melt_request.quote.as_bytes(),
|
||||
melt_request.quote().as_bytes(),
|
||||
(
|
||||
serde_json::to_string(&melt_request)?.as_str(),
|
||||
serde_json::to_string(&ln_key)?.as_str(),
|
||||
|
||||
@@ -900,9 +900,9 @@ ON CONFLICT(id) DO UPDATE SET
|
||||
unit = excluded.unit
|
||||
"#,
|
||||
)
|
||||
.bind(melt_request.quote)
|
||||
.bind(serde_json::to_string(&melt_request.inputs)?)
|
||||
.bind(serde_json::to_string(&melt_request.outputs)?)
|
||||
.bind(melt_request.quote())
|
||||
.bind(serde_json::to_string(&melt_request.inputs())?)
|
||||
.bind(serde_json::to_string(&melt_request.outputs())?)
|
||||
.bind(ln_key.method.to_string())
|
||||
.bind(ln_key.unit.to_string())
|
||||
.execute(&mut *transaction)
|
||||
@@ -1746,11 +1746,11 @@ fn sqlite_row_to_melt_request(
|
||||
let row_method: String = row.try_get("method").map_err(Error::from)?;
|
||||
let row_unit: String = row.try_get("unit").map_err(Error::from)?;
|
||||
|
||||
let melt_request = MeltBolt11Request {
|
||||
quote: quote_id.into_uuid(),
|
||||
inputs: serde_json::from_str(&row_inputs)?,
|
||||
outputs: row_outputs.and_then(|o| serde_json::from_str(&o).ok()),
|
||||
};
|
||||
let melt_request = MeltBolt11Request::new(
|
||||
quote_id.into_uuid(),
|
||||
serde_json::from_str(&row_inputs)?,
|
||||
row_outputs.and_then(|o| serde_json::from_str(&o).ok()),
|
||||
);
|
||||
|
||||
let ln_key = PaymentProcessorKey {
|
||||
unit: CurrencyUnit::from_str(&row_unit)?,
|
||||
|
||||
@@ -289,7 +289,7 @@ impl Mint {
|
||||
) -> Result<MeltQuote, Error> {
|
||||
let state = self
|
||||
.localstore
|
||||
.update_melt_quote_state(&melt_request.quote, MeltQuoteState::Pending)
|
||||
.update_melt_quote_state(melt_request.quote(), MeltQuoteState::Pending)
|
||||
.await?;
|
||||
|
||||
match state {
|
||||
@@ -301,20 +301,20 @@ impl Mint {
|
||||
|
||||
let quote = self
|
||||
.localstore
|
||||
.get_melt_quote(&melt_request.quote)
|
||||
.get_melt_quote(melt_request.quote())
|
||||
.await?
|
||||
.ok_or(Error::UnknownQuote)?;
|
||||
|
||||
let Verification {
|
||||
amount: input_amount,
|
||||
unit: input_unit,
|
||||
} = self.verify_inputs(&melt_request.inputs).await?;
|
||||
} = self.verify_inputs(melt_request.inputs()).await?;
|
||||
|
||||
ensure_cdk!(input_unit.is_some(), Error::UnsupportedUnit);
|
||||
|
||||
let input_ys = melt_request.inputs.ys()?;
|
||||
let input_ys = melt_request.inputs().ys()?;
|
||||
|
||||
let fee = self.get_proofs_fee(&melt_request.inputs).await?;
|
||||
let fee = self.get_proofs_fee(melt_request.inputs()).await?;
|
||||
|
||||
let required_total = quote.amount + quote.fee_reserve + fee;
|
||||
|
||||
@@ -335,16 +335,16 @@ impl Mint {
|
||||
}
|
||||
|
||||
self.localstore
|
||||
.add_proofs(melt_request.inputs.clone(), None)
|
||||
.add_proofs(melt_request.inputs().clone(), None)
|
||||
.await?;
|
||||
|
||||
self.check_ys_spendable(&input_ys, State::Pending).await?;
|
||||
|
||||
let EnforceSigFlag { sig_flag, .. } = enforce_sig_flag(melt_request.inputs.clone());
|
||||
let EnforceSigFlag { sig_flag, .. } = enforce_sig_flag(melt_request.inputs().clone());
|
||||
|
||||
ensure_cdk!(sig_flag.ne(&SigFlag::SigAll), Error::SigAllUsedInMelt);
|
||||
|
||||
if let Some(outputs) = &melt_request.outputs {
|
||||
if let Some(outputs) = &melt_request.outputs() {
|
||||
if !outputs.is_empty() {
|
||||
let Verification {
|
||||
amount: _,
|
||||
@@ -355,7 +355,7 @@ impl Mint {
|
||||
}
|
||||
}
|
||||
|
||||
tracing::debug!("Verified melt quote: {}", melt_request.quote);
|
||||
tracing::debug!("Verified melt quote: {}", melt_request.quote());
|
||||
Ok(quote)
|
||||
}
|
||||
|
||||
@@ -368,17 +368,17 @@ impl Mint {
|
||||
&self,
|
||||
melt_request: &MeltBolt11Request<Uuid>,
|
||||
) -> Result<(), Error> {
|
||||
let input_ys = melt_request.inputs.ys()?;
|
||||
let input_ys = melt_request.inputs().ys()?;
|
||||
|
||||
self.localstore
|
||||
.remove_proofs(&input_ys, Some(melt_request.quote))
|
||||
.remove_proofs(&input_ys, Some(*melt_request.quote()))
|
||||
.await?;
|
||||
|
||||
self.localstore
|
||||
.update_melt_quote_state(&melt_request.quote, MeltQuoteState::Unpaid)
|
||||
.update_melt_quote_state(melt_request.quote(), MeltQuoteState::Unpaid)
|
||||
.await?;
|
||||
|
||||
if let Ok(Some(quote)) = self.localstore.get_melt_quote(&melt_request.quote).await {
|
||||
if let Ok(Some(quote)) = self.localstore.get_melt_quote(melt_request.quote()).await {
|
||||
self.pubsub_manager
|
||||
.melt_quote_status(quote, None, None, MeltQuoteState::Unpaid);
|
||||
}
|
||||
@@ -427,7 +427,7 @@ impl Mint {
|
||||
if let Err(err) = self.process_unpaid_melt(melt_request).await {
|
||||
tracing::error!(
|
||||
"Could not reset melt quote {} state: {}",
|
||||
melt_request.quote,
|
||||
melt_request.quote(),
|
||||
err
|
||||
);
|
||||
}
|
||||
@@ -443,7 +443,7 @@ impl Mint {
|
||||
if let Err(err) = self.process_unpaid_melt(melt_request).await {
|
||||
tracing::error!(
|
||||
"Could not reset melt quote {} state: {}",
|
||||
melt_request.quote,
|
||||
melt_request.quote(),
|
||||
err
|
||||
);
|
||||
}
|
||||
@@ -545,7 +545,7 @@ impl Mint {
|
||||
MeltQuoteState::Unpaid | MeltQuoteState::Unknown | MeltQuoteState::Failed => {
|
||||
tracing::info!(
|
||||
"Lightning payment for quote {} failed.",
|
||||
melt_request.quote
|
||||
melt_request.quote()
|
||||
);
|
||||
if let Err(err) = self.process_unpaid_melt(melt_request).await {
|
||||
tracing::error!("Could not reset melt quote state: {}", err);
|
||||
@@ -555,7 +555,7 @@ impl Mint {
|
||||
MeltQuoteState::Pending => {
|
||||
tracing::warn!(
|
||||
"LN payment pending, proofs are stuck as pending for quote: {}",
|
||||
melt_request.quote
|
||||
melt_request.quote()
|
||||
);
|
||||
return Err(Error::PendingQuote);
|
||||
}
|
||||
@@ -610,22 +610,22 @@ impl Mint {
|
||||
payment_preimage: Option<String>,
|
||||
total_spent: Amount,
|
||||
) -> Result<MeltQuoteBolt11Response<Uuid>, Error> {
|
||||
tracing::debug!("Processing melt quote: {}", melt_request.quote);
|
||||
tracing::debug!("Processing melt quote: {}", melt_request.quote());
|
||||
|
||||
let quote = self
|
||||
.localstore
|
||||
.get_melt_quote(&melt_request.quote)
|
||||
.get_melt_quote(melt_request.quote())
|
||||
.await?
|
||||
.ok_or(Error::UnknownQuote)?;
|
||||
|
||||
let input_ys = melt_request.inputs.ys()?;
|
||||
let input_ys = melt_request.inputs().ys()?;
|
||||
|
||||
self.localstore
|
||||
.update_proofs_states(&input_ys, State::Spent)
|
||||
.await?;
|
||||
|
||||
self.localstore
|
||||
.update_melt_quote_state(&melt_request.quote, MeltQuoteState::Paid)
|
||||
.update_melt_quote_state(melt_request.quote(), MeltQuoteState::Paid)
|
||||
.await?;
|
||||
|
||||
self.pubsub_manager.melt_quote_status(
|
||||
@@ -644,7 +644,7 @@ impl Mint {
|
||||
// Check if there is change to return
|
||||
if melt_request.proofs_amount()? > total_spent {
|
||||
// Check if wallet provided change outputs
|
||||
if let Some(outputs) = melt_request.outputs.clone() {
|
||||
if let Some(outputs) = melt_request.outputs().clone() {
|
||||
let blinded_messages: Vec<PublicKey> =
|
||||
outputs.iter().map(|b| b.blinded_secret).collect();
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ impl Mint {
|
||||
{
|
||||
tracing::error!(
|
||||
"Could not process melt request for pending quote: {}",
|
||||
melt_request.quote
|
||||
melt_request.quote()
|
||||
);
|
||||
tracing::error!("{}", err);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ impl Mint {
|
||||
MeltQuoteState::Pending => {
|
||||
tracing::warn!(
|
||||
"LN payment pending, proofs are stuck as pending for quote: {}",
|
||||
melt_request.quote
|
||||
melt_request.quote()
|
||||
);
|
||||
// Quote is still pending we do not want to do anything
|
||||
// continue to check next quote
|
||||
|
||||
@@ -13,7 +13,7 @@ impl Mint {
|
||||
swap_request: SwapRequest,
|
||||
) -> Result<SwapResponse, Error> {
|
||||
if let Err(err) = self
|
||||
.verify_transaction_balanced(&swap_request.inputs, &swap_request.outputs)
|
||||
.verify_transaction_balanced(swap_request.inputs(), swap_request.outputs())
|
||||
.await
|
||||
{
|
||||
tracing::debug!("Attempt to swap unbalanced transaction, aborting: {err}");
|
||||
@@ -23,15 +23,15 @@ impl Mint {
|
||||
self.validate_sig_flag(&swap_request).await?;
|
||||
|
||||
// After swap request is fully validated, add the new proofs to DB
|
||||
let input_ys = swap_request.inputs.ys()?;
|
||||
let input_ys = swap_request.inputs().ys()?;
|
||||
self.localstore
|
||||
.add_proofs(swap_request.inputs.clone(), None)
|
||||
.add_proofs(swap_request.inputs().clone(), None)
|
||||
.await?;
|
||||
self.check_ys_spendable(&input_ys, State::Pending).await?;
|
||||
|
||||
let mut promises = Vec::with_capacity(swap_request.outputs.len());
|
||||
let mut promises = Vec::with_capacity(swap_request.outputs().len());
|
||||
|
||||
for blinded_message in swap_request.outputs.iter() {
|
||||
for blinded_message in swap_request.outputs() {
|
||||
let blinded_signature = self.blind_sign(blinded_message).await?;
|
||||
promises.push(blinded_signature);
|
||||
}
|
||||
@@ -47,7 +47,7 @@ impl Mint {
|
||||
self.localstore
|
||||
.add_blind_signatures(
|
||||
&swap_request
|
||||
.outputs
|
||||
.outputs()
|
||||
.iter()
|
||||
.map(|o| o.blinded_secret)
|
||||
.collect::<Vec<PublicKey>>(),
|
||||
@@ -64,11 +64,11 @@ impl Mint {
|
||||
sig_flag,
|
||||
pubkeys,
|
||||
sigs_required,
|
||||
} = enforce_sig_flag(swap_request.inputs.clone());
|
||||
} = enforce_sig_flag(swap_request.inputs().clone());
|
||||
|
||||
if sig_flag.eq(&SigFlag::SigAll) {
|
||||
let pubkeys = pubkeys.into_iter().collect();
|
||||
for blinded_message in &swap_request.outputs {
|
||||
for blinded_message in swap_request.outputs() {
|
||||
if let Err(err) = blinded_message.verify_p2pk(&pubkeys, sigs_required) {
|
||||
tracing::info!("Could not verify p2pk in swap request");
|
||||
return Err(err.into());
|
||||
|
||||
@@ -270,7 +270,7 @@ impl AuthWallet {
|
||||
|
||||
/// Get Auth Token
|
||||
#[instrument(skip(self))]
|
||||
pub async fn get_blind_auth_token(&self) -> Result<Option<AuthToken>, Error> {
|
||||
pub async fn get_blind_auth_token(&self) -> Result<Option<BlindAuthToken>, Error> {
|
||||
let unspent = self.get_unspent_auth_proofs().await?;
|
||||
|
||||
let auth_proof = match unspent.first() {
|
||||
@@ -283,9 +283,9 @@ impl AuthWallet {
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
Ok(Some(AuthToken::BlindAuth(BlindAuthToken {
|
||||
Ok(Some(BlindAuthToken {
|
||||
auth_proof: auth_proof.clone(),
|
||||
})))
|
||||
}))
|
||||
}
|
||||
|
||||
/// Auth for request
|
||||
@@ -309,7 +309,9 @@ impl AuthWallet {
|
||||
Error::InsufficientBlindAuthTokens
|
||||
})?;
|
||||
|
||||
Ok(Some(proof))
|
||||
let auth_token = AuthToken::BlindAuth(proof.without_dleq());
|
||||
|
||||
Ok(Some(auth_token))
|
||||
}
|
||||
},
|
||||
None => Ok(None),
|
||||
|
||||
@@ -150,11 +150,11 @@ impl Wallet {
|
||||
proofs_total - quote_info.amount,
|
||||
)?;
|
||||
|
||||
let request = MeltBolt11Request {
|
||||
quote: quote_id.to_string(),
|
||||
inputs: proofs.clone(),
|
||||
outputs: Some(premint_secrets.blinded_messages()),
|
||||
};
|
||||
let request = MeltBolt11Request::new(
|
||||
quote_id.to_string(),
|
||||
proofs.clone(),
|
||||
Some(premint_secrets.blinded_messages()),
|
||||
);
|
||||
|
||||
let melt_response = self.client.post_melt(request).await;
|
||||
|
||||
|
||||
@@ -492,7 +492,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_select_proofs_many_ones() {
|
||||
let proofs = (0..1024).into_iter().map(|_| proof(1)).collect::<Vec<_>>();
|
||||
let proofs = (0..1024).map(|_| proof(1)).collect::<Vec<_>>();
|
||||
let selected_proofs =
|
||||
Wallet::select_proofs(1024.into(), proofs, &vec![id()], &HashMap::new(), false)
|
||||
.unwrap();
|
||||
@@ -505,12 +505,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_select_proofs_huge_proofs() {
|
||||
let proofs = (0..32)
|
||||
.flat_map(|i| {
|
||||
(0..5)
|
||||
.into_iter()
|
||||
.map(|_| proof(1 << i))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.flat_map(|i| (0..5).map(|_| proof(1 << i)).collect::<Vec<_>>())
|
||||
.collect::<Vec<_>>();
|
||||
let mut selected_proofs = Wallet::select_proofs(
|
||||
((1u64 << 32) - 1).into(),
|
||||
|
||||
@@ -121,7 +121,7 @@ impl Wallet {
|
||||
.await?;
|
||||
|
||||
if sig_flag.eq(&SigFlag::SigAll) {
|
||||
for blinded_message in &mut pre_swap.swap_request.outputs {
|
||||
for blinded_message in pre_swap.swap_request.outputs_mut() {
|
||||
for signing_key in p2pk_signing_keys.values() {
|
||||
blinded_message.sign_p2pk(signing_key.to_owned().clone())?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user