mirror of
https://github.com/aljazceru/cdk.git
synced 2026-01-10 00:16:02 +01:00
Merge pull request #576 from thesimplekid/fix_mint_inflation
Fix mint inflation
This commit is contained in:
@@ -37,6 +37,11 @@
|
||||
|
||||
### Removed
|
||||
|
||||
#[cdk:v0.6.1,cdk-mintd:v0.6.2]
|
||||
### Fixed
|
||||
cdk: Missing check on mint that outputs equals the quote amount ([thesimplekid]).
|
||||
cdk: Reset mint quote status if in state that cannot continue ([thesimeokid]).
|
||||
|
||||
#[0.6.1]
|
||||
### Added
|
||||
cdk-mintd: Get work-dir from env var ([thesimplekid])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cdk-common"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
edition = "2021"
|
||||
description = "CDK common types and traits"
|
||||
rust-version = "1.63.0" # MSRV
|
||||
|
||||
@@ -157,9 +157,6 @@ pub enum Error {
|
||||
/// Receive can only be used with tokens from single mint
|
||||
#[error("Multiple mint tokens not supported by receive. Please deconstruct the token and use receive with_proof")]
|
||||
MultiMintTokenNotSupported,
|
||||
/// Unit Not supported
|
||||
#[error("Unit not supported for method")]
|
||||
UnitUnsupported,
|
||||
/// Preimage not provided
|
||||
#[error("Preimage not provided")]
|
||||
PreimageNotProvided,
|
||||
@@ -233,6 +230,9 @@ pub enum Error {
|
||||
/// NUT03 error
|
||||
#[error(transparent)]
|
||||
NUT03(#[from] crate::nuts::nut03::Error),
|
||||
/// NUT04 error
|
||||
#[error(transparent)]
|
||||
NUT04(#[from] crate::nuts::nut04::Error),
|
||||
/// NUT05 error
|
||||
#[error(transparent)]
|
||||
NUT05(#[from] crate::nuts::nut05::Error),
|
||||
@@ -329,7 +329,7 @@ impl From<Error> for ErrorResponse {
|
||||
detail: None,
|
||||
},
|
||||
Error::UnsupportedUnit => ErrorResponse {
|
||||
code: ErrorCode::UnitUnsupported,
|
||||
code: ErrorCode::UnsupportedUnit,
|
||||
error: Some(err.to_string()),
|
||||
detail: None,
|
||||
},
|
||||
@@ -412,7 +412,7 @@ impl From<ErrorResponse> for Error {
|
||||
ErrorCode::KeysetNotFound => Self::UnknownKeySet,
|
||||
ErrorCode::KeysetInactive => Self::InactiveKeyset,
|
||||
ErrorCode::BlindedMessageAlreadySigned => Self::BlindedMessageAlreadySigned,
|
||||
ErrorCode::UnitUnsupported => Self::UnitUnsupported,
|
||||
ErrorCode::UnsupportedUnit => Self::UnsupportedUnit,
|
||||
ErrorCode::TransactionUnbalanced => Self::TransactionUnbalanced(0, 0, 0),
|
||||
ErrorCode::MintingDisabled => Self::MintingDisabled,
|
||||
ErrorCode::InvoiceAlreadyPaid => Self::RequestAlreadyPaid,
|
||||
@@ -449,7 +449,7 @@ pub enum ErrorCode {
|
||||
/// Blinded Message Already signed
|
||||
BlindedMessageAlreadySigned,
|
||||
/// Unsupported unit
|
||||
UnitUnsupported,
|
||||
UnsupportedUnit,
|
||||
/// Token already issed for quote
|
||||
TokensAlreadyIssued,
|
||||
/// Minting Disabled
|
||||
@@ -478,7 +478,7 @@ impl ErrorCode {
|
||||
10003 => Self::TokenNotVerified,
|
||||
11001 => Self::TokenAlreadySpent,
|
||||
11002 => Self::TransactionUnbalanced,
|
||||
11005 => Self::UnitUnsupported,
|
||||
11005 => Self::UnsupportedUnit,
|
||||
11006 => Self::AmountOutofLimitRange,
|
||||
11007 => Self::TokenPending,
|
||||
12001 => Self::KeysetNotFound,
|
||||
@@ -502,7 +502,7 @@ impl ErrorCode {
|
||||
Self::TokenNotVerified => 10003,
|
||||
Self::TokenAlreadySpent => 11001,
|
||||
Self::TransactionUnbalanced => 11002,
|
||||
Self::UnitUnsupported => 11005,
|
||||
Self::UnsupportedUnit => 11005,
|
||||
Self::AmountOutofLimitRange => 11006,
|
||||
Self::TokenPending => 11007,
|
||||
Self::KeysetNotFound => 12001,
|
||||
|
||||
@@ -15,7 +15,7 @@ use async_trait::async_trait;
|
||||
use bitcoin::hashes::{sha256, Hash};
|
||||
use bitcoin::secp256k1::rand::{thread_rng, Rng};
|
||||
use bitcoin::secp256k1::{Secp256k1, SecretKey};
|
||||
use cdk::amount::{to_unit, Amount, MSAT_IN_SAT};
|
||||
use cdk::amount::{Amount, MSAT_IN_SAT};
|
||||
use cdk::cdk_lightning::{
|
||||
self, CreateInvoiceResponse, MintLightning, PayInvoiceResponse, PaymentQuoteResponse, Settings,
|
||||
};
|
||||
@@ -199,14 +199,15 @@ impl MintLightning for FakeWallet {
|
||||
async fn create_invoice(
|
||||
&self,
|
||||
amount: Amount,
|
||||
unit: &CurrencyUnit,
|
||||
_unit: &CurrencyUnit,
|
||||
description: String,
|
||||
unix_expiry: u64,
|
||||
) -> Result<CreateInvoiceResponse, Self::Err> {
|
||||
let time_now = unix_time();
|
||||
assert!(unix_expiry > time_now);
|
||||
|
||||
let amount_msat = to_unit(amount, unit, &CurrencyUnit::Msat)?;
|
||||
// Since this is fake we just use the amount no matter the unit to create an invoice
|
||||
let amount_msat = amount;
|
||||
|
||||
let invoice = create_fake_invoice(amount_msat.into(), description);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ where
|
||||
|
||||
let fee_reserve = FeeReserve {
|
||||
min_fee_reserve: 1.into(),
|
||||
percent_fee_reserve: 1.0,
|
||||
percent_fee_reserve: 0.0,
|
||||
};
|
||||
|
||||
let fake_wallet = FakeWallet::new(fee_reserve, HashMap::default(), HashSet::default(), 0);
|
||||
@@ -46,6 +46,20 @@ where
|
||||
Arc::new(fake_wallet),
|
||||
);
|
||||
|
||||
let fee_reserve = FeeReserve {
|
||||
min_fee_reserve: 1.into(),
|
||||
percent_fee_reserve: 0.0,
|
||||
};
|
||||
|
||||
let fake_wallet = FakeWallet::new(fee_reserve, HashMap::default(), HashSet::default(), 0);
|
||||
|
||||
mint_builder = mint_builder.add_ln_backend(
|
||||
CurrencyUnit::Usd,
|
||||
PaymentMethod::Bolt11,
|
||||
MintMeltLimits::new(1, 5_000),
|
||||
Arc::new(fake_wallet),
|
||||
);
|
||||
|
||||
let mnemonic = Mnemonic::generate(12)?;
|
||||
|
||||
mint_builder = mint_builder
|
||||
|
||||
@@ -6,8 +6,8 @@ use cdk::amount::SplitTarget;
|
||||
use cdk::cdk_database::WalletMemoryDatabase;
|
||||
use cdk::nuts::nut00::ProofsMethods;
|
||||
use cdk::nuts::{
|
||||
CurrencyUnit, MeltBolt11Request, MeltQuoteState, MintBolt11Request, PreMintSecrets, SecretKey,
|
||||
State,
|
||||
CurrencyUnit, MeltBolt11Request, MeltQuoteState, MintBolt11Request, PreMintSecrets, Proofs,
|
||||
SecretKey, State, SwapRequest,
|
||||
};
|
||||
use cdk::wallet::client::{HttpClient, MintConnector};
|
||||
use cdk::wallet::Wallet;
|
||||
@@ -476,3 +476,347 @@ async fn test_fake_mint_with_wrong_witness() -> Result<()> {
|
||||
Ok(_) => bail!("Minting should not have succeed without a witness"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn test_fake_mint_inflated() -> Result<()> {
|
||||
let wallet = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Sat,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet.mint_quote(100.into(), None).await?;
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet, &mint_quote.id, 60).await?;
|
||||
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 500.into(), &SplitTarget::None)?;
|
||||
|
||||
let quote_info = wallet
|
||||
.localstore
|
||||
.get_mint_quote(&mint_quote.id)
|
||||
.await?
|
||||
.expect("there is a quote");
|
||||
|
||||
let mut mint_request = MintBolt11Request {
|
||||
quote: mint_quote.id,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
signature: None,
|
||||
};
|
||||
|
||||
if let Some(secret_key) = quote_info.secret_key {
|
||||
mint_request.sign(secret_key)?;
|
||||
}
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
|
||||
let response = http_client.post_mint(mint_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::TransactionUnbalanced(_, _, _) => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed second payment");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn test_fake_mint_multiple_units() -> Result<()> {
|
||||
let wallet = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Sat,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet.mint_quote(100.into(), None).await?;
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet, &mint_quote.id, 60).await?;
|
||||
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 50.into(), &SplitTarget::None)?;
|
||||
|
||||
let wallet_usd = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Usd,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let active_keyset_id = wallet_usd.get_active_mint_keyset().await?.id;
|
||||
|
||||
let usd_pre_mint = PreMintSecrets::random(active_keyset_id, 50.into(), &SplitTarget::None)?;
|
||||
|
||||
let quote_info = wallet
|
||||
.localstore
|
||||
.get_mint_quote(&mint_quote.id)
|
||||
.await?
|
||||
.expect("there is a quote");
|
||||
|
||||
let mut sat_outputs = pre_mint.blinded_messages();
|
||||
|
||||
let mut usd_outputs = usd_pre_mint.blinded_messages();
|
||||
|
||||
sat_outputs.append(&mut usd_outputs);
|
||||
|
||||
let mut mint_request = MintBolt11Request {
|
||||
quote: mint_quote.id,
|
||||
outputs: sat_outputs,
|
||||
signature: None,
|
||||
};
|
||||
|
||||
if let Some(secret_key) = quote_info.secret_key {
|
||||
mint_request.sign(secret_key)?;
|
||||
}
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
|
||||
let response = http_client.post_mint(mint_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::UnsupportedUnit => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed to mint with multiple units");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn test_fake_mint_multiple_unit_swap() -> Result<()> {
|
||||
let wallet = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Sat,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet.mint_quote(100.into(), None).await?;
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet, &mint_quote.id, 60).await?;
|
||||
|
||||
let proofs = wallet.mint(&mint_quote.id, SplitTarget::None, None).await?;
|
||||
|
||||
let wallet_usd = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Usd,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet_usd.mint_quote(100.into(), None).await?;
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet_usd, &mint_quote.id, 60).await?;
|
||||
|
||||
let usd_proofs = wallet_usd
|
||||
.mint(&mint_quote.id, SplitTarget::None, None)
|
||||
.await?;
|
||||
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
|
||||
{
|
||||
let inputs: Proofs = vec![
|
||||
proofs.first().expect("There is a proof").clone(),
|
||||
usd_proofs.first().expect("There is a proof").clone(),
|
||||
];
|
||||
|
||||
let pre_mint =
|
||||
PreMintSecrets::random(active_keyset_id, inputs.total_amount()?, &SplitTarget::None)?;
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs,
|
||||
outputs: pre_mint.blinded_messages(),
|
||||
};
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::UnsupportedUnit => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed to mint with multiple units");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let usd_active_keyset_id = wallet_usd.get_active_mint_keyset().await?.id;
|
||||
let inputs: Proofs = proofs.into_iter().take(2).collect();
|
||||
|
||||
let total_inputs = inputs.total_amount()?;
|
||||
|
||||
let half = total_inputs / 2.into();
|
||||
let usd_pre_mint = PreMintSecrets::random(usd_active_keyset_id, half, &SplitTarget::None)?;
|
||||
let pre_mint =
|
||||
PreMintSecrets::random(active_keyset_id, total_inputs - half, &SplitTarget::None)?;
|
||||
|
||||
let mut usd_outputs = usd_pre_mint.blinded_messages();
|
||||
let mut sat_outputs = pre_mint.blinded_messages();
|
||||
|
||||
usd_outputs.append(&mut sat_outputs);
|
||||
|
||||
let swap_request = SwapRequest {
|
||||
inputs,
|
||||
outputs: usd_outputs,
|
||||
};
|
||||
|
||||
let http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
let response = http_client.post_swap(swap_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::UnsupportedUnit => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed to mint with multiple units");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn test_fake_mint_multiple_unit_melt() -> Result<()> {
|
||||
let wallet = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Sat,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet.mint_quote(100.into(), None).await.unwrap();
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet, &mint_quote.id, 60).await?;
|
||||
|
||||
let proofs = wallet
|
||||
.mint(&mint_quote.id, SplitTarget::None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("Minted sat");
|
||||
|
||||
let wallet_usd = Wallet::new(
|
||||
MINT_URL,
|
||||
CurrencyUnit::Usd,
|
||||
Arc::new(WalletMemoryDatabase::default()),
|
||||
&Mnemonic::generate(12)?.to_seed_normalized(""),
|
||||
None,
|
||||
)?;
|
||||
|
||||
let mint_quote = wallet_usd.mint_quote(100.into(), None).await.unwrap();
|
||||
println!("Minted quote usd");
|
||||
|
||||
wait_for_mint_to_be_paid(&wallet_usd, &mint_quote.id, 60).await?;
|
||||
|
||||
let usd_proofs = wallet_usd
|
||||
.mint(&mint_quote.id, SplitTarget::None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let inputs: Proofs = vec![
|
||||
proofs.first().expect("There is a proof").clone(),
|
||||
usd_proofs.first().expect("There is a proof").clone(),
|
||||
];
|
||||
|
||||
let input_amount: u64 = inputs.total_amount()?.into();
|
||||
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 http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
let response = http_client.post_melt(melt_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::UnsupportedUnit => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed to melt with multiple units");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let inputs: Proofs = vec![proofs.first().expect("There is a proof").clone()];
|
||||
|
||||
let input_amount: u64 = inputs.total_amount()?.into();
|
||||
|
||||
let invoice = create_fake_invoice((input_amount - 1) * 1000, "".to_string());
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
let usd_active_keyset_id = wallet_usd.get_active_mint_keyset().await?.id;
|
||||
|
||||
let usd_pre_mint = PreMintSecrets::random(
|
||||
usd_active_keyset_id,
|
||||
inputs.total_amount()? + 100.into(),
|
||||
&SplitTarget::None,
|
||||
)?;
|
||||
let pre_mint = PreMintSecrets::random(active_keyset_id, 100.into(), &SplitTarget::None)?;
|
||||
|
||||
let mut usd_outputs = usd_pre_mint.blinded_messages();
|
||||
let mut sat_outputs = pre_mint.blinded_messages();
|
||||
|
||||
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 http_client = HttpClient::new(MINT_URL.parse()?);
|
||||
let response = http_client.post_melt(melt_request.clone()).await;
|
||||
|
||||
match response {
|
||||
Err(err) => match err {
|
||||
cdk::Error::UnsupportedUnit => (),
|
||||
err => {
|
||||
bail!("Wrong mint error returned: {}", err.to_string());
|
||||
}
|
||||
},
|
||||
Ok(_) => {
|
||||
bail!("Should not have allowed to melt with multiple units");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ async fn test_cached_mint() -> Result<()> {
|
||||
let active_keyset_id = wallet.get_active_mint_keyset().await?.id;
|
||||
let http_client = HttpClient::new(get_mint_url().as_str().parse()?);
|
||||
let premint_secrets =
|
||||
PreMintSecrets::random(active_keyset_id, 31.into(), &SplitTarget::default()).unwrap();
|
||||
PreMintSecrets::random(active_keyset_id, 100.into(), &SplitTarget::default()).unwrap();
|
||||
|
||||
let mut request = MintBolt11Request {
|
||||
quote: quote.id,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cdk-mintd"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
edition = "2021"
|
||||
authors = ["CDK Developers"]
|
||||
license = "MIT"
|
||||
@@ -12,7 +12,7 @@ description = "CDK mint binary"
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
axum = "0.6.20"
|
||||
cdk = { path = "../cdk", version = "0.6.0", default-features = false, features = [
|
||||
cdk = { path = "../cdk", version = "0.6.1", default-features = false, features = [
|
||||
"mint",
|
||||
] }
|
||||
cdk-redb = { path = "../cdk-redb", version = "0.6.0", default-features = false, features = [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "cdk"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
edition = "2021"
|
||||
authors = ["CDK Developers"]
|
||||
description = "Core Cashu Development Kit library implementing the Cashu protocol"
|
||||
@@ -21,7 +21,7 @@ http_subscription = []
|
||||
|
||||
|
||||
[dependencies]
|
||||
cdk-common = { path = "../cdk-common", version = "0.6.0" }
|
||||
cdk-common = { path = "../cdk-common", version = "0.6.1" }
|
||||
cbor-diag = "0.1.12"
|
||||
async-trait = "0.1"
|
||||
anyhow = { version = "1.0.43", features = ["backtrace"] }
|
||||
|
||||
@@ -41,7 +41,7 @@ impl Mint {
|
||||
|
||||
let settings = nut05
|
||||
.get_settings(&unit, &method)
|
||||
.ok_or(Error::UnitUnsupported)?;
|
||||
.ok_or(Error::UnsupportedUnit)?;
|
||||
|
||||
if matches!(options, Some(MeltOptions::Mpp { mpp: _ })) {
|
||||
// Verify there is no corresponding mint quote.
|
||||
@@ -103,7 +103,7 @@ impl Mint {
|
||||
.ok_or_else(|| {
|
||||
tracing::info!("Could not get ln backend for {}, bolt11 ", unit);
|
||||
|
||||
Error::UnitUnsupported
|
||||
Error::UnsupportedUnit
|
||||
})?;
|
||||
|
||||
let payment_quote = ln.get_payment_quote(melt_request).await.map_err(|err| {
|
||||
@@ -113,7 +113,7 @@ impl Mint {
|
||||
err
|
||||
);
|
||||
|
||||
Error::UnitUnsupported
|
||||
Error::UnsupportedUnit
|
||||
})?;
|
||||
|
||||
// We only want to set the msats_to_pay of the melt quote if the invoice is amountless
|
||||
@@ -224,7 +224,7 @@ impl Mint {
|
||||
|
||||
Some(
|
||||
to_unit(partial_msats, &CurrencyUnit::Msat, &melt_quote.unit)
|
||||
.map_err(|_| Error::UnitUnsupported)?,
|
||||
.map_err(|_| Error::UnsupportedUnit)?,
|
||||
)
|
||||
}
|
||||
false => None,
|
||||
@@ -233,7 +233,7 @@ impl Mint {
|
||||
let amount_to_pay = match partial_amount {
|
||||
Some(amount_to_pay) => amount_to_pay,
|
||||
None => to_unit(invoice_amount_msats, &CurrencyUnit::Msat, &melt_quote.unit)
|
||||
.map_err(|_| Error::UnitUnsupported)?,
|
||||
.map_err(|_| Error::UnsupportedUnit)?,
|
||||
};
|
||||
|
||||
let inputs_amount_quote_unit = melt_request.proofs_amount().map_err(|_| {
|
||||
@@ -366,7 +366,7 @@ impl Mint {
|
||||
|
||||
// Check that all input and output proofs are the same unit
|
||||
if keyset_units.len().gt(&1) {
|
||||
return Err(Error::MultipleUnits);
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
|
||||
tracing::debug!("Verified melt quote: {}", melt_request.quote);
|
||||
@@ -502,7 +502,7 @@ impl Mint {
|
||||
tracing::error!("Could not reset melt quote state: {}", err);
|
||||
}
|
||||
|
||||
return Err(Error::UnitUnsupported);
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use cdk_common::Id;
|
||||
use tracing::instrument;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -49,7 +52,7 @@ impl Mint {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Err(Error::UnitUnsupported);
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +80,7 @@ impl Mint {
|
||||
.ok_or_else(|| {
|
||||
tracing::info!("Bolt11 mint request for unsupported unit");
|
||||
|
||||
Error::UnitUnsupported
|
||||
Error::UnsupportedUnit
|
||||
})?;
|
||||
|
||||
let mint_ttl = self.localstore.get_quote_ttl().await?.mint_ttl;
|
||||
@@ -275,12 +278,20 @@ impl Mint {
|
||||
|
||||
match state {
|
||||
MintQuoteState::Unpaid => {
|
||||
let _state = self
|
||||
.localstore
|
||||
.update_mint_quote_state(&mint_request.quote, MintQuoteState::Unpaid)
|
||||
.await?;
|
||||
return Err(Error::UnpaidQuote);
|
||||
}
|
||||
MintQuoteState::Pending => {
|
||||
return Err(Error::PendingQuote);
|
||||
}
|
||||
MintQuoteState::Issued => {
|
||||
let _state = self
|
||||
.localstore
|
||||
.update_mint_quote_state(&mint_request.quote, MintQuoteState::Issued)
|
||||
.await?;
|
||||
return Err(Error::IssuedQuote);
|
||||
}
|
||||
MintQuoteState::Paid => (),
|
||||
@@ -292,6 +303,35 @@ impl Mint {
|
||||
mint_request.verify_signature(pubkey)?;
|
||||
}
|
||||
|
||||
// We check the the total value of blinded messages == mint quote
|
||||
if mint_request.total_amount()? != mint_quote.amount {
|
||||
return Err(Error::TransactionUnbalanced(
|
||||
mint_quote.amount.into(),
|
||||
mint_request.total_amount()?.into(),
|
||||
0,
|
||||
));
|
||||
}
|
||||
|
||||
let keyset_ids: HashSet<Id> = mint_request.outputs.iter().map(|b| b.keyset_id).collect();
|
||||
|
||||
let mut keyset_units = HashSet::new();
|
||||
|
||||
for keyset_id in keyset_ids {
|
||||
let keyset = self.keyset(&keyset_id).await?.ok_or(Error::UnknownKeySet)?;
|
||||
|
||||
keyset_units.insert(keyset.unit);
|
||||
}
|
||||
|
||||
if keyset_units.len() != 1 {
|
||||
tracing::debug!("Client attempted to mint with outputs of multiple units");
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
|
||||
if keyset_units.iter().next().expect("Checked len above") != &mint_quote.unit {
|
||||
tracing::debug!("Client attempted to mint with unit not in quote");
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
|
||||
let blinded_messages: Vec<PublicKey> = mint_request
|
||||
.outputs
|
||||
.iter()
|
||||
@@ -315,8 +355,7 @@ impl Mint {
|
||||
|
||||
self.localstore
|
||||
.update_mint_quote_state(&mint_request.quote, MintQuoteState::Paid)
|
||||
.await
|
||||
.unwrap();
|
||||
.await?;
|
||||
|
||||
return Err(Error::BlindedMessageAlreadySigned);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ impl Mint {
|
||||
self.localstore
|
||||
.update_proofs_states(&input_ys, State::Unspent)
|
||||
.await?;
|
||||
return Err(Error::MultipleUnits);
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
|
||||
let EnforceSigFlag {
|
||||
|
||||
@@ -195,7 +195,7 @@ impl Wallet {
|
||||
let unit = token.unit().unwrap_or_default();
|
||||
|
||||
if unit != self.unit {
|
||||
return Err(Error::UnitUnsupported);
|
||||
return Err(Error::UnsupportedUnit);
|
||||
}
|
||||
|
||||
let proofs = token.proofs();
|
||||
|
||||
Reference in New Issue
Block a user