ソースを参照

improve: Use keyset info

thesimplekid 1 年間 前
コミット
bcc344c194

+ 5 - 0
bindings/cashu-ffi/src/cashu.udl

@@ -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",

+ 1 - 0
bindings/cashu-ffi/src/lib.rs

@@ -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;

+ 44 - 0
bindings/cashu-ffi/src/types/keyset_info.rs

@@ -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,
+            },
+        }
+    }
+}

+ 4 - 0
bindings/cashu-ffi/src/types/mod.rs

@@ -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;

+ 1 - 1
bindings/cashu-js/src/lib.rs

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

+ 10 - 10
bindings/cashu-js/src/nuts/mod.rs

@@ -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;

+ 48 - 16
bindings/cashu-js/src/nuts/nut02/keyset.rs

@@ -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)
+    }
+}

+ 2 - 0
bindings/cashu-js/src/nuts/nut02/mod.rs

@@ -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;

+ 2 - 2
bindings/cashu-js/src/nuts/nut09.rs

@@ -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())

+ 7 - 1
bindings/cashu-sdk-ffi/src/cashu_sdk.udl

@@ -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();

+ 3 - 3
bindings/cashu-sdk-ffi/src/lib.rs

@@ -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,
     };
 

+ 3 - 8
bindings/cashu-sdk-ffi/src/mint.rs

@@ -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 {

+ 1 - 0
bindings/cashu-sdk-js/src/lib.rs

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

+ 98 - 0
bindings/cashu-sdk-js/src/mint.rs

@@ -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())
+    }
+}

+ 28 - 9
crates/cashu-sdk/src/mint.rs

@@ -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()
                 }
             },
         );

+ 1 - 0
crates/cashu/src/nuts/nut02.rs

@@ -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

+ 14 - 1
crates/cashu/src/types.rs

@@ -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,
+}