mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-04 12:45:55 +01:00
improve: use bip39 mnemonic for mint secret
This commit is contained in:
@@ -2,7 +2,9 @@ use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use cashu::nuts::{Id as IdSdk, KeySet as KeySetSdk, KeysetResponse as KeysetResponseSdk};
|
||||
use cashu::nuts::{
|
||||
CurrencyUnit, Id as IdSdk, KeySet as KeySetSdk, KeysetResponse as KeysetResponseSdk,
|
||||
};
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::nuts::nut01::keys::Keys;
|
||||
@@ -54,7 +56,7 @@ impl KeySet {
|
||||
Self {
|
||||
inner: KeySetSdk {
|
||||
id: *id.as_ref().deref(),
|
||||
unit,
|
||||
unit: CurrencyUnit::from_str(&unit).unwrap(),
|
||||
keys: keys.as_ref().deref().clone(),
|
||||
},
|
||||
}
|
||||
@@ -65,7 +67,7 @@ impl KeySet {
|
||||
}
|
||||
|
||||
pub fn unit(&self) -> String {
|
||||
self.inner.unit.clone()
|
||||
self.inner.unit.clone().to_string()
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> Arc<Keys> {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
use cashu::nuts::nut02::mint::KeySet as KeySetSdk;
|
||||
use cashu::nuts::CurrencyUnit;
|
||||
|
||||
pub struct MintKeySet {
|
||||
inner: KeySetSdk,
|
||||
@@ -16,7 +18,12 @@ impl Deref for MintKeySet {
|
||||
impl MintKeySet {
|
||||
pub fn generate(secret: String, unit: String, derivation_path: String, max_order: u8) -> Self {
|
||||
Self {
|
||||
inner: KeySetSdk::generate(secret, unit, derivation_path, max_order),
|
||||
inner: KeySetSdk::generate(
|
||||
secret.as_bytes(),
|
||||
CurrencyUnit::from_str(&unit).unwrap(),
|
||||
&derivation_path,
|
||||
max_order,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use cashu::nuts::KeySetInfo as KeySetInfoSdk;
|
||||
use cashu::nuts::{CurrencyUnit, KeySetInfo as KeySetInfoSdk};
|
||||
|
||||
use crate::Id;
|
||||
|
||||
@@ -27,7 +28,7 @@ impl KeySetInfo {
|
||||
Self {
|
||||
inner: KeySetInfoSdk {
|
||||
id: *id.as_ref().deref(),
|
||||
unit,
|
||||
unit: CurrencyUnit::from_str(&unit).unwrap(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
use cashu::nuts::{Id, KeySet, KeysResponse, KeysetResponse};
|
||||
use cashu::nuts::{CurrencyUnit, Id, KeySet, KeysResponse, KeysetResponse};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::error::{into_err, Result};
|
||||
@@ -68,7 +68,7 @@ impl JsKeySet {
|
||||
Self {
|
||||
inner: KeySet {
|
||||
id: *id.deref(),
|
||||
unit,
|
||||
unit: CurrencyUnit::from_str(&unit).unwrap(),
|
||||
keys: keys.deref().clone(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
use cashu::nuts::nut02::mint::KeySet;
|
||||
use cashu::nuts::CurrencyUnit;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(js_name = MintKeySet)]
|
||||
@@ -32,7 +34,12 @@ impl JsMintKeySet {
|
||||
max_order: u8,
|
||||
) -> JsMintKeySet {
|
||||
Self {
|
||||
inner: KeySet::generate(secret, unit, derivation_path, max_order),
|
||||
inner: KeySet::generate(
|
||||
secret.as_bytes(),
|
||||
CurrencyUnit::from_str(&unit).unwrap(),
|
||||
&derivation_path,
|
||||
max_order,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use cashu_ffi::{
|
||||
@@ -7,6 +8,7 @@ use cashu_ffi::{
|
||||
Secret, SwapRequest, SwapResponse,
|
||||
};
|
||||
use cashu_sdk::mint::Mint as MintSdk;
|
||||
use cashu_sdk::Mnemonic;
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::types::MintKeySetInfo;
|
||||
@@ -35,7 +37,7 @@ impl Mint {
|
||||
|
||||
Ok(Self {
|
||||
inner: MintSdk::new(
|
||||
&secret,
|
||||
Mnemonic::from_str(&secret).unwrap(),
|
||||
keysets,
|
||||
spent_secrets,
|
||||
// TODO: quotes
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use cashu_sdk::mint::MintKeySetInfo as MintKeySetInfoSdk;
|
||||
use cashu_sdk::nuts::CurrencyUnit;
|
||||
|
||||
use crate::Id;
|
||||
|
||||
@@ -36,7 +38,7 @@ impl MintKeySetInfo {
|
||||
inner: MintKeySetInfoSdk {
|
||||
id: *id.as_ref().deref(),
|
||||
active,
|
||||
unit,
|
||||
unit: CurrencyUnit::from_str(&unit).unwrap(),
|
||||
valid_from,
|
||||
valid_to,
|
||||
derivation_path,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[cfg(feature = "nut07")]
|
||||
use cashu_js::nuts::{JsCheckSpendableRequest, JsCheckSpendableResponse};
|
||||
@@ -9,6 +10,7 @@ use cashu_js::nuts::{
|
||||
use cashu_js::JsAmount;
|
||||
use cashu_sdk::mint::Mint;
|
||||
use cashu_sdk::nuts::{KeySet, KeysResponse};
|
||||
use cashu_sdk::Mnemonic;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::error::{into_err, Result};
|
||||
@@ -48,7 +50,7 @@ impl JsMint {
|
||||
let quotes = serde_wasm_bindgen::from_value(quotes).map_err(into_err)?;
|
||||
Ok(JsMint {
|
||||
inner: Mint::new(
|
||||
&secret,
|
||||
Mnemonic::from_str(&secret).unwrap(),
|
||||
keyset_info,
|
||||
spent_secrets,
|
||||
quotes,
|
||||
|
||||
@@ -20,6 +20,7 @@ nut08 = ["cashu/nut08"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
bip39 = "2.0.0"
|
||||
cashu = { path = "../cashu" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -16,6 +16,8 @@ pub mod mint;
|
||||
pub mod utils;
|
||||
#[cfg(feature = "wallet")]
|
||||
pub mod wallet;
|
||||
|
||||
pub use bip39::Mnemonic;
|
||||
pub use cashu::{self, *};
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
|
||||
@@ -14,12 +14,14 @@ use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, info};
|
||||
|
||||
use crate::types::MeltQuote;
|
||||
use crate::Mnemonic;
|
||||
|
||||
pub struct Mint {
|
||||
// pub pubkey: PublicKey
|
||||
_secret: String,
|
||||
pub keysets: HashMap<Id, nut02::mint::KeySet>,
|
||||
pub keysets_info: HashMap<Id, MintKeySetInfo>,
|
||||
// pub pubkey: PublicKey,
|
||||
mnemonic: Mnemonic,
|
||||
pub spent_secrets: HashSet<Secret>,
|
||||
pub pending_secrets: HashSet<Secret>,
|
||||
pub fee_reserve: FeeReserve,
|
||||
@@ -28,7 +30,7 @@ pub struct Mint {
|
||||
|
||||
impl Mint {
|
||||
pub fn new(
|
||||
secret: &str,
|
||||
mnemonic: Mnemonic,
|
||||
keysets_info: HashSet<MintKeySetInfo>,
|
||||
spent_secrets: HashSet<Secret>,
|
||||
melt_quotes: Vec<MeltQuote>,
|
||||
@@ -38,7 +40,7 @@ impl Mint {
|
||||
let mut keysets = HashMap::default();
|
||||
let mut info = HashMap::default();
|
||||
|
||||
let mut active_units: HashSet<String> = HashSet::default();
|
||||
let mut active_units: HashSet<CurrencyUnit> = HashSet::default();
|
||||
|
||||
let melt_quotes = melt_quotes.into_iter().map(|q| (q.id.clone(), q)).collect();
|
||||
|
||||
@@ -50,9 +52,9 @@ impl Mint {
|
||||
}
|
||||
|
||||
let keyset = nut02::mint::KeySet::generate(
|
||||
secret,
|
||||
&mnemonic.to_seed_normalized(""),
|
||||
keyset_info.unit.clone(),
|
||||
keyset_info.derivation_path.clone(),
|
||||
&keyset_info.derivation_path.clone(),
|
||||
keyset_info.max_order,
|
||||
);
|
||||
|
||||
@@ -62,7 +64,7 @@ impl Mint {
|
||||
}
|
||||
|
||||
Self {
|
||||
_secret: secret.to_string(),
|
||||
mnemonic,
|
||||
keysets,
|
||||
melt_quotes,
|
||||
keysets_info: info,
|
||||
@@ -105,6 +107,21 @@ impl Mint {
|
||||
self.keysets.get(id).map(|ks| ks.clone().into())
|
||||
}
|
||||
|
||||
/// Add current keyset to inactive keysets
|
||||
/// Generate new keyset
|
||||
pub fn rotate_keyset(&mut self, unit: CurrencyUnit, derivation_path: &str, max_order: u8) {
|
||||
// TODO: Set old keyset as inactive
|
||||
|
||||
let new_keyset = MintKeySet::generate(
|
||||
&self.mnemonic.to_seed_normalized(""),
|
||||
unit,
|
||||
derivation_path,
|
||||
max_order,
|
||||
);
|
||||
|
||||
self.keysets.insert(new_keyset.id, new_keyset);
|
||||
}
|
||||
|
||||
pub fn process_mint_request(
|
||||
&mut self,
|
||||
mint_request: nut04::MintBolt11Request,
|
||||
@@ -327,7 +344,7 @@ pub struct FeeReserve {
|
||||
#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MintKeySetInfo {
|
||||
pub id: Id,
|
||||
pub unit: String,
|
||||
pub unit: CurrencyUnit,
|
||||
pub active: bool,
|
||||
pub valid_from: u64,
|
||||
pub valid_to: Option<u64>,
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct BlindedMessage {
|
||||
pub b: PublicKey,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum CurrencyUnit {
|
||||
#[default]
|
||||
|
||||
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::nut01::Keys;
|
||||
use super::CurrencyUnit;
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum Error {
|
||||
@@ -164,7 +165,7 @@ impl KeysetResponse {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct KeySet {
|
||||
pub id: Id,
|
||||
pub unit: String,
|
||||
pub unit: CurrencyUnit,
|
||||
pub keys: Keys,
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ impl From<mint::KeySet> for KeySet {
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct KeySetInfo {
|
||||
pub id: Id,
|
||||
pub unit: String,
|
||||
pub unit: CurrencyUnit,
|
||||
}
|
||||
|
||||
impl From<KeySet> for KeySetInfo {
|
||||
@@ -203,20 +204,21 @@ pub mod mint {
|
||||
|
||||
use super::Id;
|
||||
use crate::nuts::nut01::mint::{KeyPair, Keys};
|
||||
use crate::nuts::CurrencyUnit;
|
||||
use crate::Amount;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
|
||||
pub struct KeySet {
|
||||
pub id: Id,
|
||||
pub unit: String,
|
||||
pub unit: CurrencyUnit,
|
||||
pub keys: Keys,
|
||||
}
|
||||
|
||||
impl KeySet {
|
||||
pub fn generate(
|
||||
secret: impl Into<String>,
|
||||
unit: impl Into<String>,
|
||||
derivation_path: impl Into<String>,
|
||||
secret: &[u8],
|
||||
unit: CurrencyUnit,
|
||||
derivation_path: &str,
|
||||
max_order: u8,
|
||||
) -> Self {
|
||||
// Elliptic curve math context
|
||||
@@ -230,8 +232,8 @@ pub mod mint {
|
||||
|
||||
// SHA-256 midstate, for quicker hashing
|
||||
let mut engine = Sha256::engine();
|
||||
engine.input(secret.into().as_bytes());
|
||||
engine.input(derivation_path.into().as_bytes());
|
||||
engine.input(secret);
|
||||
engine.input(derivation_path.as_bytes());
|
||||
|
||||
for i in 0..max_order {
|
||||
let amount = Amount::from(2_u64.pow(i as u32));
|
||||
@@ -249,7 +251,7 @@ pub mod mint {
|
||||
|
||||
Self {
|
||||
id: (&keys).into(),
|
||||
unit: unit.into(),
|
||||
unit,
|
||||
keys,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::nuts::{CurrencyUnit, Proofs};
|
||||
use crate::nuts::{CurrencyUnit, Id, Proofs};
|
||||
use crate::{Amount, Bolt11Invoice};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -56,3 +56,13 @@ pub struct MeltQuote {
|
||||
pub paid: bool,
|
||||
pub expiry: u64,
|
||||
}
|
||||
|
||||
/// Keyset id
|
||||
#[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct KeysetInfo {
|
||||
pub id: Id,
|
||||
pub valid_from: u64,
|
||||
pub valid_to: Option<u64>,
|
||||
pub derivation_path: String,
|
||||
pub max_order: u8,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user