Skip to content

Commit

Permalink
feat: nut19 signature on mint witness
Browse files Browse the repository at this point in the history
  • Loading branch information
thesimplekid committed Nov 15, 2024
1 parent 4e7f55e commit e088803
Show file tree
Hide file tree
Showing 27 changed files with 367 additions and 68 deletions.
12 changes: 10 additions & 2 deletions bindings/cdk-js/src/nuts/nut04.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,18 @@ impl From<MintBolt11Request> for JsMintBolt11Request {
impl JsMintBolt11Request {
/// Try From Base 64 String
#[wasm_bindgen(constructor)]
pub fn new(quote: String, outputs: JsValue) -> Result<JsMintBolt11Request> {
pub fn new(
quote: String,
outputs: JsValue,
witness: Option<String>,
) -> Result<JsMintBolt11Request> {
let outputs = serde_wasm_bindgen::from_value(outputs).map_err(into_err)?;
Ok(JsMintBolt11Request {
inner: MintBolt11Request { quote, outputs },
inner: MintBolt11Request {
quote,
outputs,
witness,
},
})
}

Expand Down
4 changes: 2 additions & 2 deletions bindings/cdk-js/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl JsWallet {
) -> Result<JsMintQuote> {
let quote = self
.inner
.mint_quote(amount.into(), description)
.mint_quote(amount.into(), description, None)
.await
.map_err(into_err)?;

Expand Down Expand Up @@ -142,7 +142,7 @@ impl JsWallet {

Ok(self
.inner
.mint(&quote_id, target, conditions)
.mint(&quote_id, target, conditions, None)
.await
.map_err(into_err)?
.into())
Expand Down
6 changes: 4 additions & 2 deletions crates/cdk-cli/src/sub_commands/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub async fn mint(
};

let quote = wallet
.mint_quote(Amount::from(sub_command_args.amount), description)
.mint_quote(Amount::from(sub_command_args.amount), description, None)
.await?;

println!("Quote: {:#?}", quote);
Expand All @@ -69,7 +69,9 @@ pub async fn mint(
sleep(Duration::from_secs(2)).await;
}

let receive_amount = wallet.mint(&quote.id, SplitTarget::default(), None).await?;
let receive_amount = wallet
.mint(&quote.id, SplitTarget::default(), None, None)
.await?;

println!("Received {receive_amount} from mint {mint_url}");

Expand Down
6 changes: 4 additions & 2 deletions crates/cdk-integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub async fn wallet_mint(
split_target: SplitTarget,
description: Option<String>,
) -> Result<()> {
let quote = wallet.mint_quote(amount, description).await?;
let quote = wallet.mint_quote(amount, description, None).await?;

loop {
let status = wallet.mint_quote_state(&quote.id).await?;
Expand All @@ -138,7 +138,7 @@ pub async fn wallet_mint(
sleep(Duration::from_secs(2)).await;
}

let receive_amount = wallet.mint(&quote.id, split_target, None).await?;
let receive_amount = wallet.mint(&quote.id, split_target, None, None).await?;

println!("Minted: {}", receive_amount);

Expand All @@ -161,6 +161,7 @@ pub async fn mint_proofs(
amount,
unit: CurrencyUnit::Sat,
description,
pubkey: None,
};

let mint_quote = wallet_client
Expand All @@ -187,6 +188,7 @@ pub async fn mint_proofs(
let request = MintBolt11Request {
quote: mint_quote.quote,
outputs: premint_secrets.blinded_messages(),
witness: None,
};

let mint_response = wallet_client.post_mint(mint_url.parse()?, request).await?;
Expand Down
111 changes: 96 additions & 15 deletions crates/cdk-integration-tests/tests/fake_wallet.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;
use std::time::Duration;

use anyhow::Result;
use anyhow::{bail, Result};
use bip39::Mnemonic;
use cdk::amount::SplitTarget;
use cdk::cdk_database::WalletMemoryDatabase;
Expand All @@ -27,12 +27,12 @@ async fn test_fake_tokens_pending() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -67,12 +67,12 @@ async fn test_fake_melt_payment_fail() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -130,12 +130,12 @@ async fn test_fake_melt_payment_fail_and_check() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -175,12 +175,12 @@ async fn test_fake_melt_payment_return_fail_status() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -235,12 +235,12 @@ async fn test_fake_melt_payment_error_unknown() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -296,12 +296,12 @@ async fn test_fake_melt_payment_err_paid() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription {
Expand Down Expand Up @@ -334,12 +334,12 @@ async fn test_fake_melt_change_in_quote() -> Result<()> {
None,
)?;

let mint_quote = wallet.mint_quote(100.into(), None).await?;
let mint_quote = wallet.mint_quote(100.into(), None, None).await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let _mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None)
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await?;

let fake_description = FakeInvoiceDescription::default();
Expand Down Expand Up @@ -377,6 +377,87 @@ async fn test_fake_melt_change_in_quote() -> Result<()> {
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_fake_mint_with_witness() -> Result<()> {
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&Mnemonic::generate(12)?.to_seed_normalized(""),
None,
)?;
let secret = SecretKey::generate();
let mint_quote = wallet
.mint_quote(100.into(), None, Some(secret.public_key()))
.await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None, Some(secret))
.await?;

assert!(mint_amount == 100.into());

Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_fake_mint_without_witness() -> Result<()> {
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&Mnemonic::generate(12)?.to_seed_normalized(""),
None,
)?;

let secret = SecretKey::generate();
let mint_quote = wallet
.mint_quote(100.into(), None, Some(secret.public_key()))
.await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;

let mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None, None)
.await;

match mint_amount {
Err(cdk::error::Error::SecretKeyNotProvided) => Ok(()),
_ => bail!("Wrong mint response for minting without witness"),
}
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_fake_mint_with_wrong_witness() -> Result<()> {
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&Mnemonic::generate(12)?.to_seed_normalized(""),
None,
)?;
let secret = SecretKey::generate();
let mint_quote = wallet
.mint_quote(100.into(), None, Some(secret.public_key()))
.await?;

wait_for_mint_to_be_paid(&wallet, &mint_quote.id).await?;
let secret = SecretKey::generate();

let mint_amount = wallet
.mint(&mint_quote.id, SplitTarget::default(), None, Some(secret))
.await;

match mint_amount {
Err(cdk::error::Error::IncorrectSecretKey) => Ok(()),
_ => {
bail!("Wrong mint response for minting without witness")
}
}
}

// Keep polling the state of the mint quote id until it's paid
async fn wait_for_mint_to_be_paid(wallet: &Wallet, mint_quote_id: &str) -> Result<()> {
loop {
Expand Down
2 changes: 2 additions & 0 deletions crates/cdk-integration-tests/tests/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ async fn mint_proofs(
amount,
unix_time() + 36000,
request_lookup.to_string(),
None,
);

mint.localstore.add_mint_quote(quote.clone()).await?;
Expand All @@ -90,6 +91,7 @@ async fn mint_proofs(
let mint_request = MintBolt11Request {
quote: quote.id,
outputs: premint.blinded_messages(),
witness: None,
};

let after_mint = mint.process_mint_request(mint_request).await?;
Expand Down
Loading

0 comments on commit e088803

Please # to comment.