refactor: move nut06 to nut03

rename 'proofs' to 'to inputs'
This commit is contained in:
thesimplekid
2023-11-25 21:41:07 +00:00
parent 989035e12e
commit 417e3037ee
13 changed files with 294 additions and 168 deletions

View File

@@ -18,13 +18,12 @@ mod ffi {
pub use crate::nuts::nut01::public_key::PublicKey;
pub use crate::nuts::nut01::secret_key::SecretKey;
pub use crate::nuts::nut02::{Id, KeySet, KeySetResponse, MintKeySet};
pub use crate::nuts::nut03::RequestMintResponse;
pub use crate::nuts::nut03::{RequestMintResponse, SplitRequest, SplitResponse};
pub use crate::nuts::nut04::{MintRequest, PostMintResponse};
pub use crate::nuts::nut05::{
CheckFeesRequest, CheckFeesResponse, MeltRequest as Nut05MeltRequest,
MeltResponse as Nut05MeltResponse,
};
pub use crate::nuts::nut06::{SplitRequest, SplitResponse};
pub use crate::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse};
pub use crate::nuts::nut08::{MeltRequest, MeltResponse};
pub use crate::nuts::nut09::{MintInfo, MintVersion};

View File

@@ -4,7 +4,6 @@ pub mod nut02;
pub mod nut03;
pub mod nut04;
pub mod nut05;
pub mod nut06;
pub mod nut07;
pub mod nut08;
pub mod nut09;

View File

@@ -1,9 +1,13 @@
use std::ops::Deref;
use std::str::FromStr;
use std::sync::Arc;
use cashu::nuts::nut03::RequestMintResponse as RequestMintResponseSdk;
use cashu::nuts::{SplitRequest as SplitRequestSdk, SplitResponse as SplitResponseSdk};
use cashu::Bolt11Invoice;
use crate::error::Result;
use crate::{Amount, BlindedMessage, BlindedSignature, Proof};
pub struct RequestMintResponse {
inner: RequestMintResponseSdk,
@@ -34,3 +38,84 @@ impl From<cashu::nuts::nut03::RequestMintResponse> for RequestMintResponse {
}
}
}
pub struct SplitRequest {
inner: SplitRequestSdk,
}
impl Deref for SplitRequest {
type Target = SplitRequestSdk;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl SplitRequest {
pub fn new(proofs: Vec<Arc<Proof>>, outputs: Vec<Arc<BlindedMessage>>) -> Self {
let proofs = proofs.into_iter().map(|p| p.as_ref().into()).collect();
let outputs = outputs.into_iter().map(|o| o.as_ref().into()).collect();
Self {
inner: SplitRequestSdk::new(proofs, outputs),
}
}
pub fn proofs(&self) -> Vec<Arc<Proof>> {
self.inner
.inputs
.clone()
.into_iter()
.map(|p| Arc::new(p.into()))
.collect()
}
pub fn outputs(&self) -> Vec<Arc<BlindedMessage>> {
self.inner
.outputs
.clone()
.into_iter()
.map(|o| Arc::new(o.into()))
.collect()
}
pub fn proofs_amount(&self) -> Arc<Amount> {
Arc::new(self.inner.input_amount().into())
}
pub fn output_amount(&self) -> Arc<Amount> {
Arc::new(self.inner.output_amount().into())
}
}
pub struct SplitResponse {
inner: SplitResponseSdk,
}
impl SplitResponse {
pub fn new(promises: Vec<Arc<BlindedSignature>>) -> Self {
let promises = promises.into_iter().map(|p| p.as_ref().into()).collect();
Self {
inner: SplitResponseSdk::new(promises),
}
}
pub fn promises(&self) -> Vec<Arc<BlindedSignature>> {
self.inner
.promises
.clone()
.unwrap_or_default()
.into_iter()
.map(|p| Arc::new(p.into()))
.collect()
}
pub fn promises_amount(&self) -> Option<Arc<Amount>> {
self.inner.promises_amount().map(|a| Arc::new(a.into()))
}
}
impl From<cashu::nuts::SplitResponse> for SplitResponse {
fn from(inner: cashu::nuts::SplitResponse) -> SplitResponse {
SplitResponse { inner }
}
}

View File

@@ -1,87 +0,0 @@
use std::ops::Deref;
use std::sync::Arc;
use cashu::nuts::nut06::{SplitRequest as SplitRequestSdk, SplitResponse as SplitResponseSdk};
use crate::{Amount, BlindedMessage, BlindedSignature, Proof};
pub struct SplitRequest {
inner: SplitRequestSdk,
}
impl Deref for SplitRequest {
type Target = SplitRequestSdk;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl SplitRequest {
pub fn new(proofs: Vec<Arc<Proof>>, outputs: Vec<Arc<BlindedMessage>>) -> Self {
let proofs = proofs.into_iter().map(|p| p.as_ref().into()).collect();
let outputs = outputs.into_iter().map(|o| o.as_ref().into()).collect();
Self {
inner: SplitRequestSdk::new(proofs, outputs),
}
}
pub fn proofs(&self) -> Vec<Arc<Proof>> {
self.inner
.proofs
.clone()
.into_iter()
.map(|p| Arc::new(p.into()))
.collect()
}
pub fn outputs(&self) -> Vec<Arc<BlindedMessage>> {
self.inner
.outputs
.clone()
.into_iter()
.map(|o| Arc::new(o.into()))
.collect()
}
pub fn proofs_amount(&self) -> Arc<Amount> {
Arc::new(self.inner.proofs_amount().into())
}
pub fn output_amount(&self) -> Arc<Amount> {
Arc::new(self.inner.output_amount().into())
}
}
pub struct SplitResponse {
inner: SplitResponseSdk,
}
impl SplitResponse {
pub fn new(promises: Vec<Arc<BlindedSignature>>) -> Self {
let promises = promises.into_iter().map(|p| p.as_ref().into()).collect();
Self {
inner: SplitResponseSdk::new(promises),
}
}
pub fn promises(&self) -> Vec<Arc<BlindedSignature>> {
self.inner
.promises
.clone()
.unwrap_or_default()
.into_iter()
.map(|p| Arc::new(p.into()))
.collect()
}
pub fn promises_amount(&self) -> Option<Arc<Amount>> {
self.inner.promises_amount().map(|a| Arc::new(a.into()))
}
}
impl From<cashu::nuts::nut06::SplitResponse> for SplitResponse {
fn from(inner: cashu::nuts::nut06::SplitResponse) -> SplitResponse {
SplitResponse { inner }
}
}

View File

@@ -4,9 +4,17 @@ pub mod nut02;
pub mod nut03;
pub mod nut04;
pub mod nut05;
pub mod nut06;
#[cfg(feature = "nut07")]
pub mod nut07;
pub mod nut08;
#[cfg(feature = "nut09")]
pub mod nut09;
pub use nut00::{JsBlindedMessage, JsBlindedMessages, JsBlindedSignature, JsProof, JsToken};
pub use nut01::{JsKeyPair, JsKeys, JsPublicKey, JsSecretKey};
pub use nut02::{JsId, JsKeySet, JsKeySetsResponse, JsKeysResponse, JsMintKeySet};
pub use nut03::{JsRequestMintResponse, JsSplitRequest, JsSplitResponse};
pub use nut04::{JsMintRequest, JsPostMintResponse};
#[cfg(feature = "nut07")]
pub use nut07::{JsCheckSpendableRequest, JsCheckSpendableResponse};
pub use nut08::{JsMeltRequest, JsMeltResponse};

View File

@@ -1,9 +1,10 @@
use std::ops::Deref;
use cashu::nuts::nut03::RequestMintResponse;
use cashu::nuts::{RequestMintResponse, SplitRequest, SplitResponse};
use wasm_bindgen::prelude::*;
use crate::types::JsBolt11Invoice;
use crate::error::{into_err, Result};
use crate::types::{JsAmount, JsBolt11Invoice};
#[wasm_bindgen(js_name = RequestMintResponse)]
pub struct JsRequestMintResponse {
@@ -47,3 +48,102 @@ impl JsRequestMintResponse {
self.inner.hash.to_string()
}
}
#[wasm_bindgen(js_name = SplitRequest)]
pub struct JsSplitRequest {
inner: SplitRequest,
}
impl Deref for JsSplitRequest {
type Target = SplitRequest;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<SplitRequest> for JsSplitRequest {
fn from(inner: SplitRequest) -> JsSplitRequest {
JsSplitRequest { inner }
}
}
#[wasm_bindgen(js_class = SplitRequest)]
impl JsSplitRequest {
#[wasm_bindgen(constructor)]
pub fn new(inputs: JsValue, outputs: JsValue) -> Result<JsSplitRequest> {
let inputs = serde_wasm_bindgen::from_value(inputs).map_err(into_err)?;
let outputs = serde_wasm_bindgen::from_value(outputs).map_err(into_err)?;
Ok(JsSplitRequest {
inner: SplitRequest { inputs, outputs },
})
}
/// Get Proofs
#[wasm_bindgen(getter)]
pub fn proofs(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.inputs).map_err(into_err)
}
/// Get Outputs
#[wasm_bindgen(getter)]
pub fn outputs(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.outputs).map_err(into_err)
}
/// Proofs Amount
#[wasm_bindgen(js_name = proofsAmount)]
pub fn proofs_amount(&self) -> JsAmount {
self.inner.input_amount().into()
}
/// Output Amount
#[wasm_bindgen(js_name = outputAmount)]
pub fn output_amount(&self) -> JsAmount {
self.inner.output_amount().into()
}
}
#[wasm_bindgen(js_name = SplitResponse)]
pub struct JsSplitResponse {
inner: SplitResponse,
}
impl Deref for JsSplitResponse {
type Target = SplitResponse;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<SplitResponse> for JsSplitResponse {
fn from(inner: SplitResponse) -> JsSplitResponse {
JsSplitResponse { inner }
}
}
#[wasm_bindgen(js_class = SplitResponse)]
impl JsSplitResponse {
#[wasm_bindgen(constructor)]
pub fn new(promises: JsValue) -> Result<JsSplitResponse> {
let promises = serde_wasm_bindgen::from_value(promises).map_err(into_err)?;
Ok(JsSplitResponse {
inner: SplitResponse {
promises: Some(promises),
},
})
}
/// Get Promises
#[wasm_bindgen(getter)]
pub fn promises(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.promises).map_err(into_err)
}
/// Promises Amount
#[wasm_bindgen(js_name = promisesAmount)]
pub fn promises_amount(&self) -> Option<JsAmount> {
self.inner.promises_amount().map(|a| a.into())
}
}

View File

@@ -1,6 +1,6 @@
use std::ops::Deref;
use cashu::nuts::nut06::{SplitRequest, SplitResponse};
use cashu::nuts::{SplitRequest, SplitResponse};
use wasm_bindgen::prelude::*;
use crate::error::{into_err, Result};
@@ -27,23 +27,19 @@ impl From<SplitRequest> for JsSplitRequest {
#[wasm_bindgen(js_class = SplitRequest)]
impl JsSplitRequest {
#[wasm_bindgen(constructor)]
pub fn new(proofs: JsValue, outputs: JsValue) -> Result<JsSplitRequest> {
let proofs = serde_wasm_bindgen::from_value(proofs).map_err(into_err)?;
pub fn new(inputs: JsValue, outputs: JsValue) -> Result<JsSplitRequest> {
let inputs = serde_wasm_bindgen::from_value(inputs).map_err(into_err)?;
let outputs = serde_wasm_bindgen::from_value(outputs).map_err(into_err)?;
Ok(JsSplitRequest {
inner: SplitRequest {
amount: None,
proofs,
outputs,
},
inner: SplitRequest { inputs, outputs },
})
}
/// Get Proofs
#[wasm_bindgen(getter)]
pub fn proofs(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.proofs).map_err(into_err)
serde_wasm_bindgen::to_value(&self.inner.inputs).map_err(into_err)
}
/// Get Outputs
@@ -55,7 +51,7 @@ impl JsSplitRequest {
/// Proofs Amount
#[wasm_bindgen(js_name = proofsAmount)]
pub fn proofs_amount(&self) -> JsAmount {
self.inner.proofs_amount().into()
self.inner.input_amount().into()
}
/// Output Amount
@@ -91,8 +87,6 @@ impl JsSplitResponse {
Ok(JsSplitResponse {
inner: SplitResponse {
fst: None,
snd: None,
promises: Some(promises),
},
})

View File

@@ -1,11 +1,11 @@
use std::ops::Deref;
use cashu_js::nuts::nut02::{JsId, JsKeySet, JsKeySetsResponse, JsKeysResponse, JsMintKeySet};
use cashu_js::nuts::nut04::{JsMintRequest, JsPostMintResponse};
use cashu_js::nuts::nut06::{JsSplitRequest, JsSplitResponse};
#[cfg(feature = "nut07")]
use cashu_js::nuts::nut07::{JsCheckSpendableRequest, JsCheckSpendableResponse};
use cashu_js::nuts::nut08::{JsMeltRequest, JsMeltResponse};
use cashu_js::nuts::{JsCheckSpendableRequest, JsCheckSpendableResponse};
use cashu_js::nuts::{
JsId, JsKeySet, JsKeySetsResponse, JsKeysResponse, JsMeltRequest, JsMeltResponse, JsMintKeySet,
JsMintRequest, JsPostMintResponse, JsSplitRequest, JsSplitResponse,
};
use cashu_js::JsAmount;
use cashu_sdk::mint::Mint;
use cashu_sdk::nuts::{KeySet, KeysResponse};

View File

@@ -1,19 +1,15 @@
//! gloo wasm http Client
use async_trait::async_trait;
use cashu::nuts::nut00::wallet::BlindedMessages;
use cashu::nuts::nut00::{BlindedMessage, Proof};
use cashu::nuts::nut01::Keys;
use cashu::nuts::nut03::RequestMintResponse;
use cashu::nuts::nut04::{MintRequest, PostMintResponse};
use cashu::nuts::nut05::{CheckFeesRequest, CheckFeesResponse};
use cashu::nuts::nut06::{SplitRequest, SplitResponse};
#[cfg(feature = "nut07")]
use cashu::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse};
use cashu::nuts::nut08::{MeltRequest, MeltResponse};
#[cfg(feature = "nut09")]
use cashu::nuts::MintInfo;
use cashu::nuts::*;
use cashu::nuts::{
BlindedMessage, BlindedMessages, CheckFeesRequest, CheckFeesResponse, Keys, MeltRequest,
MeltResponse, MintRequest, PostMintResponse, Proof, RequestMintResponse, SplitRequest,
SplitResponse, *,
};
#[cfg(feature = "nut07")]
use cashu::nuts::{CheckSpendableRequest, CheckSpendableResponse};
use cashu::{Amount, Bolt11Invoice};
use gloo::net::http::Request;
use serde_json::Value;

View File

@@ -3,19 +3,15 @@
use std::println;
use async_trait::async_trait;
use cashu::nuts::nut00::wallet::BlindedMessages;
use cashu::nuts::nut00::{BlindedMessage, Proof};
use cashu::nuts::nut01::Keys;
use cashu::nuts::nut03::RequestMintResponse;
use cashu::nuts::nut04::{MintRequest, PostMintResponse};
use cashu::nuts::nut05::{CheckFeesRequest, CheckFeesResponse};
use cashu::nuts::nut06::{SplitRequest, SplitResponse};
#[cfg(feature = "nut07")]
use cashu::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse};
use cashu::nuts::nut08::{MeltRequest, MeltResponse};
#[cfg(feature = "nut09")]
use cashu::nuts::MintInfo;
use cashu::nuts::*;
use cashu::nuts::{
BlindedMessage, BlindedMessages, CheckFeesRequest, CheckFeesResponse, Keys, MeltRequest,
MeltResponse, MintRequest, PostMintResponse, Proof, RequestMintResponse, SplitRequest,
SplitResponse, *,
};
#[cfg(feature = "nut07")]
use cashu::nuts::{CheckSpendableRequest, CheckSpendableResponse};
use cashu::{Amount, Bolt11Invoice};
use serde_json::Value;
use url::Url;

View File

@@ -147,7 +147,7 @@ impl Mint {
&mut self,
split_request: SplitRequest,
) -> Result<SplitResponse, Error> {
let proofs_total = split_request.proofs_amount();
let proofs_total = split_request.input_amount();
let output_total = split_request.output_amount();
@@ -155,10 +155,10 @@ impl Mint {
return Err(Error::Amount);
}
let proof_count = split_request.proofs.len();
let proof_count = split_request.inputs.len();
let secrets: HashSet<Secret> = split_request
.proofs
.inputs
.iter()
.map(|p| p.secret.clone())
.collect();
@@ -168,7 +168,7 @@ impl Mint {
return Err(Error::DuplicateProofs);
}
for proof in &split_request.proofs {
for proof in &split_request.inputs {
self.verify_proof(proof)?
}
@@ -176,36 +176,13 @@ impl Mint {
self.spent_secrets.insert(secret);
}
match &split_request.amount {
None => {
let promises: Vec<BlindedSignature> = split_request
.outputs
.iter()
.map(|b| self.blind_sign(b).unwrap())
.collect();
let promises: Vec<BlindedSignature> = split_request
.outputs
.iter()
.map(|b| self.blind_sign(b).unwrap())
.collect();
Ok(SplitResponse::new(promises))
}
Some(amount) => {
let outs_fst = (proofs_total.to_owned() - amount.to_owned()).split();
// Blinded change messages
let b_fst = split_request.outputs[0..outs_fst.len()].to_vec();
let b_snd = split_request.outputs[outs_fst.len()..].to_vec();
let fst: Vec<BlindedSignature> =
b_fst.iter().map(|b| self.blind_sign(b).unwrap()).collect();
let snd: Vec<BlindedSignature> =
b_snd.iter().map(|b| self.blind_sign(b).unwrap()).collect();
let split_response = SplitResponse::new_from_amount(fst, snd);
if split_response.target_amount() != split_request.amount {
return Err(Error::CustomError("Output order".to_string()));
}
Ok(split_response)
}
}
Ok(SplitResponse::new(promises))
}
fn verify_proof(&self, proof: &Proof) -> Result<(), Error> {

View File

@@ -18,14 +18,12 @@ pub use nut00::{BlindedMessage, BlindedSignature, Proof};
pub use nut01::{Keys, KeysResponse, PublicKey, SecretKey};
pub use nut02::mint::KeySet as MintKeySet;
pub use nut02::{Id, KeySet, KeySetInfo, KeysetResponse};
pub use nut03::RequestMintResponse;
pub use nut03::{RequestMintResponse, SplitPayload, SplitRequest, SplitResponse};
pub use nut04::{MintRequest, PostMintResponse};
pub use nut05::{CheckFeesRequest, CheckFeesResponse};
#[cfg(not(feature = "nut08"))]
pub use nut05::{MeltRequest, MeltResponse};
#[cfg(feature = "wallet")]
pub use nut06::SplitPayload;
pub use nut06::{SplitRequest, SplitResponse};
#[cfg(feature = "nut07")]
pub use nut07::{CheckSpendableRequest, CheckSpendableResponse};
#[cfg(feature = "nut08")]

View File

@@ -3,6 +3,11 @@
use serde::{Deserialize, Serialize};
use super::nut00::BlindedSignature;
#[cfg(feature = "wallet")]
use crate::nuts::BlindedMessages;
use crate::nuts::{BlindedMessage, Proofs};
use crate::Amount;
pub use crate::Bolt11Invoice;
/// Mint request response [NUT-03]
@@ -13,3 +18,59 @@ pub struct RequestMintResponse {
/// Random hash MUST not be the hash of invoice
pub hash: String,
}
#[cfg(feature = "wallet")]
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SplitPayload {
pub blinded_messages: BlindedMessages,
pub split_payload: SplitRequest,
}
/// Split Request [NUT-06]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SplitRequest {
/// Proofs that are to be spent in `Split`
pub inputs: Proofs,
/// Blinded Messages for Mint to sign
pub outputs: Vec<BlindedMessage>,
}
impl SplitRequest {
pub fn new(inputs: Proofs, outputs: Vec<BlindedMessage>) -> Self {
Self { inputs, outputs }
}
/// Total value of proofs in `SplitRequest`
pub fn input_amount(&self) -> Amount {
self.inputs.iter().map(|proof| proof.amount).sum()
}
/// Total value of outputs in `SplitRequest`
pub fn output_amount(&self) -> Amount {
self.outputs.iter().map(|proof| proof.amount).sum()
}
}
/// Split Response [NUT-06]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SplitResponse {
/// Promises
pub promises: Option<Vec<BlindedSignature>>,
}
impl SplitResponse {
pub fn new(promises: Vec<BlindedSignature>) -> SplitResponse {
SplitResponse {
promises: Some(promises),
}
}
pub fn promises_amount(&self) -> Option<Amount> {
self.promises.as_ref().map(|promises| {
promises
.iter()
.map(|BlindedSignature { amount, .. }| *amount)
.sum()
})
}
}