improve: Use keyset info

This commit is contained in:
thesimplekid
2023-09-30 18:10:11 +01:00
parent f51691bddd
commit bcc344c194
17 changed files with 272 additions and 51 deletions

View File

@@ -241,6 +241,11 @@ interface MintInfo {
string? motd();
};
interface KeySetInfo {
constructor(Id id, u64 valid_from, u64? valid_to, string secret, string derivation_path, u8 max_order);
};
enum InvoiceStatus {
"Unpaid",
"Paid",

View File

@@ -27,6 +27,7 @@ mod ffi {
pub use crate::nuts::nut09::{MintInfo, MintVersion};
pub use crate::types::amount::Amount;
pub use crate::types::Bolt11Invoice;
pub use crate::types::KeySetInfo;
pub use crate::types::Secret;
pub use cashu::types::InvoiceStatus;

View File

@@ -0,0 +1,44 @@
use std::{ops::Deref, sync::Arc};
use cashu::types::KeysetInfo as KeySetInfoSdk;
use crate::Id;
pub struct KeySetInfo {
inner: KeySetInfoSdk,
}
impl Deref for KeySetInfo {
type Target = KeySetInfoSdk;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<KeySetInfoSdk> for KeySetInfo {
fn from(inner: KeySetInfoSdk) -> KeySetInfo {
KeySetInfo { inner }
}
}
impl KeySetInfo {
pub fn new(
id: Arc<Id>,
valid_from: u64,
valid_to: Option<u64>,
secret: String,
derivation_path: String,
max_order: u8,
) -> Self {
Self {
inner: KeySetInfoSdk {
id: *id.as_ref().deref(),
valid_from,
valid_to,
secret,
derivation_path,
max_order,
},
}
}
}

View File

@@ -1,6 +1,10 @@
pub mod amount;
pub mod bolt11_invoice;
pub mod keyset_info;
pub mod proofs_status;
pub mod secret;
pub use bolt11_invoice::Bolt11Invoice;
pub use keyset_info::KeySetInfo;
pub use proofs_status::ProofsStatus;
pub use secret::Secret;

View File

@@ -1,3 +1,3 @@
pub mod error;
mod nuts;
pub mod nuts;
pub mod types;

View File

@@ -1,10 +1,10 @@
mod nut00;
mod nut01;
mod nut02;
mod nut03;
mod nut04;
mod nut05;
mod nut06;
mod nut07;
mod nut08;
mod nut09;
pub mod nut00;
pub mod nut01;
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,7 +1,7 @@
use std::ops::Deref;
use cashu::nuts::nut02::Id;
use cashu::nuts::nut02::{KeySet, Response};
use cashu::nuts::nut01::Response as KeysResponse;
use cashu::nuts::nut02::{Id, KeySet, Response as KeySetsResponse};
use wasm_bindgen::prelude::*;
use crate::{
@@ -86,36 +86,68 @@ impl JsKeySet {
}
}
#[wasm_bindgen(js_name = KeySetResponse)]
pub struct JsKeyResponse {
inner: Response,
#[wasm_bindgen(js_name = KeySetsResponse)]
pub struct JsKeySetsResponse {
inner: KeySetsResponse,
}
impl Deref for JsKeyResponse {
type Target = Response;
impl Deref for JsKeySetsResponse {
type Target = KeySetsResponse;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<Response> for JsKeyResponse {
fn from(inner: Response) -> JsKeyResponse {
JsKeyResponse { inner }
impl From<KeySetsResponse> for JsKeySetsResponse {
fn from(inner: KeySetsResponse) -> JsKeySetsResponse {
JsKeySetsResponse { inner }
}
}
#[wasm_bindgen(js_class = KeyResponse)]
impl JsKeyResponse {
/// From Hex
#[wasm_bindgen(js_class = KeySetsResponse)]
impl JsKeySetsResponse {
#[wasm_bindgen(constructor)]
pub fn new(keysets: JsValue) -> Result<JsKeyResponse> {
pub fn new(keysets: JsValue) -> Result<JsKeySetsResponse> {
let response = serde_wasm_bindgen::from_value(keysets).map_err(into_err)?;
Ok(Self { inner: response })
}
/// Get Keysets
/// Get KeySets
#[wasm_bindgen(getter)]
pub fn keysets(&self) -> Result<JsValue> {
pub fn keys(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.keysets).map_err(into_err)
}
}
#[wasm_bindgen(js_name = KeysResponse)]
pub struct JsKeysResponse {
inner: KeysResponse,
}
impl Deref for JsKeysResponse {
type Target = KeysResponse;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<KeysResponse> for JsKeysResponse {
fn from(inner: KeysResponse) -> JsKeysResponse {
JsKeysResponse { inner }
}
}
#[wasm_bindgen(js_class = KeysResponse)]
impl JsKeysResponse {
#[wasm_bindgen(constructor)]
pub fn new(keysets: JsValue) -> Result<JsKeysResponse> {
let response = serde_wasm_bindgen::from_value(keysets).map_err(into_err)?;
Ok(Self { inner: response })
}
/// Get Keys
#[wasm_bindgen(getter)]
pub fn keys(&self) -> Result<JsValue> {
serde_wasm_bindgen::to_value(&self.inner.keys).map_err(into_err)
}
}

View File

@@ -3,4 +3,6 @@ mod mint_keyset;
pub use keyset::JsId;
pub use keyset::JsKeySet;
pub use keyset::JsKeySetsResponse;
pub use keyset::JsKeysResponse;
pub use mint_keyset::JsMintKeySet;

View File

@@ -40,7 +40,7 @@ impl JsMintVersion {
self.inner.name.clone()
}
/// Get Name
/// Get Version
#[wasm_bindgen(getter)]
pub fn version(&self) -> String {
self.inner.version.clone()
@@ -105,7 +105,7 @@ impl JsMintInfo {
self.inner.pubkey.clone().map(|p| p.into())
}
/// Get Name
/// Get Version
#[wasm_bindgen(getter)]
pub fn version(&self) -> Option<JsMintVersion> {
self.inner.version.clone().map(|v| v.into())

View File

@@ -259,6 +259,12 @@ interface ProofsStatus {
sequence<MintProof> spent();
};
interface KeySetInfo {
constructor(Id id, u64 valid_from, u64? valid_to, string secret, string derivation_path, u8 max_order);
};
// Cashu Sdk
@@ -330,7 +336,7 @@ interface Wallet {
interface Mint {
[Throws=CashuSdkError]
constructor(string secret, string derivation_path, record<string, MintKeySet> inactive_keysets, sequence<Secret> spent_secrets, u8 max_order, Amount min_fee_reserve, f32 percent_fee_reserve);
constructor(string secret, string derivation_path, sequence<KeySetInfo> inactive_keysets, sequence<Secret> spent_secrets, u8 max_order, Amount min_fee_reserve, f32 percent_fee_reserve);
KeysResponse active_keyset_pubkeys();
KeySetResponse keysets();
MintKeySet active_keyset();

View File

@@ -8,9 +8,9 @@ mod ffi {
pub use cashu_ffi::{
Amount, BlindedMessage, BlindedMessages, BlindedSignature, Bolt11Invoice, CashuError,
CheckFeesRequest, CheckFeesResponse, CheckSpendableRequest, CheckSpendableResponse, Id,
InvoiceStatus, KeyPair, KeySet, KeySetResponse, Keys, KeysResponse, MeltRequest,
MeltResponse, MintInfo, MintKeySet, MintProof, MintProofs, MintRequest, MintVersion,
Nut05MeltRequest, Nut05MeltResponse, PostMintResponse, Proof, PublicKey,
InvoiceStatus, KeyPair, KeySet, KeySetInfo, KeySetResponse, Keys, KeysResponse,
MeltRequest, MeltResponse, MintInfo, MintKeySet, MintProof, MintProofs, MintRequest,
MintVersion, Nut05MeltRequest, Nut05MeltResponse, PostMintResponse, Proof, PublicKey,
RequestMintResponse, Secret, SecretKey, SplitRequest, SplitResponse, Token,
};

View File

@@ -1,16 +1,14 @@
use std::{
collections::HashMap,
ops::Deref,
sync::{Arc, RwLock},
};
use cashu_ffi::{
Amount, CheckSpendableRequest, CheckSpendableResponse, Id, KeySet, KeySetResponse,
Amount, CheckSpendableRequest, CheckSpendableResponse, Id, KeySet, KeySetInfo, KeySetResponse,
KeysResponse, MeltRequest, MeltResponse, MintKeySet, MintRequest, PostMintResponse, Secret,
SplitRequest, SplitResponse,
};
use cashu_sdk::mint::Mint as MintSdk;
use cashu_sdk::nuts::nut02::Id as IdSdk;
use crate::error::Result;
@@ -22,7 +20,7 @@ impl Mint {
pub fn new(
secret: String,
derivation_path: String,
inactive_keysets: HashMap<String, Arc<MintKeySet>>,
inactive_keysets: Vec<Arc<KeySetInfo>>,
spent_secrets: Vec<Arc<Secret>>,
max_order: u8,
min_fee_reserve: Arc<Amount>,
@@ -35,10 +33,7 @@ impl Mint {
let inactive_keysets = inactive_keysets
.into_iter()
.flat_map(|(k, v)| {
let id = IdSdk::try_from_base64(&k);
id.map(|id| (id, v.as_ref().deref().clone()))
})
.map(|ik| ik.as_ref().deref().clone())
.collect();
Ok(Self {

View File

@@ -1,2 +1,3 @@
mod error;
mod mint;
mod types;

View File

@@ -0,0 +1,98 @@
use std::ops::Deref;
use cashu_js::{
nuts::{
nut02::{JsId, JsKeySet, JsKeySetsResponse, JsKeysResponse, JsMintKeySet},
nut04::{JsMintRequest, JsPostMintResponse},
},
types::JsAmount,
};
use cashu_sdk::{mint::Mint, nuts::nut01, nuts::nut02::KeySet};
use wasm_bindgen::prelude::*;
use crate::error::{into_err, Result};
#[wasm_bindgen(js_name = Mint)]
pub struct JsMint {
inner: Mint,
}
impl Deref for JsMint {
type Target = Mint;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl From<Mint> for JsMint {
fn from(inner: Mint) -> JsMint {
JsMint { inner }
}
}
#[wasm_bindgen(js_class = Mint)]
impl JsMint {
#[wasm_bindgen(constructor)]
pub fn new(
secret: String,
derivation_path: String,
inactive_keyset: JsValue,
spent_secrets: JsValue,
max_order: u8,
min_fee_reserve: JsAmount,
percent_fee_reserve: f32,
) -> Result<JsMint> {
let inactive_keyset = serde_wasm_bindgen::from_value(inactive_keyset).map_err(into_err)?;
let spent_secrets = serde_wasm_bindgen::from_value(spent_secrets).map_err(into_err)?;
Ok(JsMint {
inner: Mint::new(
&secret,
&derivation_path,
inactive_keyset,
spent_secrets,
max_order,
*min_fee_reserve.deref(),
percent_fee_reserve,
),
})
}
/// Get Active Keyset Pubkeys
#[wasm_bindgen(getter)]
pub fn active_keyset_pubkeys(&self) -> Result<JsKeysResponse> {
let keyset: KeySet = self.inner.active_keyset.clone().into();
Ok(nut01::Response { keys: keyset.keys }.into())
}
/// Get Keysets
#[wasm_bindgen(js_name = KeySets)]
pub fn keysets(&self) -> JsKeySetsResponse {
self.inner.keysets().into()
}
/// Get Active Keyset
#[wasm_bindgen(getter)]
pub fn active_keyset(&self) -> JsMintKeySet {
self.inner.active_keyset.clone().into()
}
/// Keyset
#[wasm_bindgen(js_name = KeySet)]
pub fn keyset(&self, id: JsId) -> Option<JsKeySet> {
self.inner.keyset(id.deref()).map(|ks| ks.into())
}
/// Process Mint Request
#[wasm_bindgen(js_name = ProcessMintRequest)]
pub fn process_mint_request(
&mut self,
mint_request: JsMintRequest,
) -> Result<JsPostMintResponse> {
Ok(self
.inner
.process_mint_request(mint_request.deref().clone())
.map_err(into_err)?
.into())
}
}

View File

@@ -16,13 +16,15 @@ use cashu::nuts::nut08::MeltRequest;
use cashu::nuts::nut08::MeltResponse;
use cashu::nuts::*;
use cashu::secret::Secret;
use cashu::types::KeysetInfo;
use cashu::Amount;
use tracing::debug;
pub struct Mint {
// pub pubkey: PublicKey,
pub active_keyset: nut02::mint::KeySet,
pub inactive_keysets: HashMap<Id, nut02::mint::KeySet>,
pub active_keyset_info: KeysetInfo,
pub inactive_keysets: HashMap<Id, KeysetInfo>,
pub spent_secrets: HashSet<Secret>,
pub pending_secrets: HashSet<Secret>,
pub fee_reserve: FeeReserve,
@@ -32,15 +34,26 @@ impl Mint {
pub fn new(
secret: &str,
derivation_path: &str,
inactive_keysets: HashMap<Id, nut02::mint::KeySet>,
inactive_keysets: HashSet<KeysetInfo>,
spent_secrets: HashSet<Secret>,
max_order: u8,
min_fee_reserve: Amount,
percent_fee_reserve: f32,
) -> Self {
let active_keyset = nut02::mint::KeySet::generate(secret, derivation_path, max_order);
let id = active_keyset.id;
Self {
active_keyset: nut02::mint::KeySet::generate(secret, derivation_path, max_order),
inactive_keysets,
active_keyset,
inactive_keysets: inactive_keysets.into_iter().map(|ks| (ks.id, ks)).collect(),
active_keyset_info: KeysetInfo {
id,
valid_from: 0,
valid_to: None,
secret: secret.to_string(),
derivation_path: derivation_path.to_string(),
max_order,
},
spent_secrets,
pending_secrets: HashSet::new(),
fee_reserve: FeeReserve {
@@ -74,7 +87,9 @@ impl Mint {
return Some(self.active_keyset.clone().into());
}
self.inactive_keysets.get(id).map(|k| k.clone().into())
self.inactive_keysets.get(id).map(|k| {
nut02::mint::KeySet::generate(&k.secret, &k.derivation_path, k.max_order).into()
})
}
/// Add current keyset to inactive keysets
@@ -87,7 +102,7 @@ impl Mint {
) {
// Add current set to inactive keysets
self.inactive_keysets
.insert(self.active_keyset.id, self.active_keyset.clone());
.insert(self.active_keyset.id, self.active_keyset_info.clone());
self.active_keyset = KeySet::generate(secret, derivation_path, max_order);
}
@@ -195,12 +210,16 @@ impl Mint {
}
let keyset = proof.id.as_ref().map_or_else(
|| &self.active_keyset,
|| self.active_keyset.clone(),
|id| {
if let Some(keyset) = self.inactive_keysets.get(id) {
keyset
nut02::mint::KeySet::generate(
&keyset.secret,
&keyset.derivation_path,
keyset.max_order,
)
} else {
&self.active_keyset
self.active_keyset.clone()
}
},
);

View File

@@ -148,6 +148,7 @@ impl From<&Keys> for Id {
}
/// Mint Keysets [NUT-02]
/// Ids of mints keyset ids
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Response {
/// set of public key ids that the mint generates

View File

@@ -2,7 +2,10 @@
use serde::{Deserialize, Serialize};
use crate::nuts::nut00::{mint, Proofs};
use crate::nuts::{
nut00::{mint, Proofs},
nut02::Id,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProofsStatus {
@@ -32,3 +35,13 @@ pub enum InvoiceStatus {
Expired,
InFlight,
}
#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct KeysetInfo {
pub id: Id,
pub valid_from: u64,
pub valid_to: Option<u64>,
pub secret: String,
pub derivation_path: String,
pub max_order: u8,
}