mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-18 21:25:09 +01:00
Update the signatory.proto file to match NUT-XXX (#1032)
* Update the signatory.proto file to match NUT-XXX Source: https://github.com/cashubtc/nuts/pull/250/files * Add unit tests as requested in https://github.com/cashubtc/cdk/pull/1032#discussion_r2321436860 * Remove unused types from proto file
This commit is contained in:
@@ -553,13 +553,12 @@ impl MintKeySet {
|
|||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
xpriv: Xpriv,
|
xpriv: Xpriv,
|
||||||
unit: CurrencyUnit,
|
unit: CurrencyUnit,
|
||||||
max_order: u8,
|
amounts: &[u64],
|
||||||
final_expiry: Option<u64>,
|
final_expiry: Option<u64>,
|
||||||
version: KeySetVersion,
|
version: KeySetVersion,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
for i in 0..max_order {
|
for (i, amount) in amounts.iter().enumerate() {
|
||||||
let amount = Amount::from(2_u64.pow(i as u32));
|
|
||||||
let secret_key = xpriv
|
let secret_key = xpriv
|
||||||
.derive_priv(
|
.derive_priv(
|
||||||
secp,
|
secp,
|
||||||
@@ -569,7 +568,7 @@ impl MintKeySet {
|
|||||||
.private_key;
|
.private_key;
|
||||||
let public_key = secret_key.public_key(secp);
|
let public_key = secret_key.public_key(secp);
|
||||||
map.insert(
|
map.insert(
|
||||||
amount,
|
amount.into(),
|
||||||
MintKeyPair {
|
MintKeyPair {
|
||||||
secret_key: secret_key.into(),
|
secret_key: secret_key.into(),
|
||||||
public_key: public_key.into(),
|
public_key: public_key.into(),
|
||||||
@@ -594,7 +593,7 @@ impl MintKeySet {
|
|||||||
pub fn generate_from_seed<C: secp256k1::Signing>(
|
pub fn generate_from_seed<C: secp256k1::Signing>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
seed: &[u8],
|
seed: &[u8],
|
||||||
max_order: u8,
|
amounts: &[u64],
|
||||||
currency_unit: CurrencyUnit,
|
currency_unit: CurrencyUnit,
|
||||||
derivation_path: DerivationPath,
|
derivation_path: DerivationPath,
|
||||||
final_expiry: Option<u64>,
|
final_expiry: Option<u64>,
|
||||||
@@ -607,7 +606,7 @@ impl MintKeySet {
|
|||||||
.derive_priv(secp, &derivation_path)
|
.derive_priv(secp, &derivation_path)
|
||||||
.expect("RNG busted"),
|
.expect("RNG busted"),
|
||||||
currency_unit,
|
currency_unit,
|
||||||
max_order,
|
amounts,
|
||||||
final_expiry,
|
final_expiry,
|
||||||
version,
|
version,
|
||||||
)
|
)
|
||||||
@@ -617,7 +616,7 @@ impl MintKeySet {
|
|||||||
pub fn generate_from_xpriv<C: secp256k1::Signing>(
|
pub fn generate_from_xpriv<C: secp256k1::Signing>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
xpriv: Xpriv,
|
xpriv: Xpriv,
|
||||||
max_order: u8,
|
amounts: &[u64],
|
||||||
currency_unit: CurrencyUnit,
|
currency_unit: CurrencyUnit,
|
||||||
derivation_path: DerivationPath,
|
derivation_path: DerivationPath,
|
||||||
final_expiry: Option<u64>,
|
final_expiry: Option<u64>,
|
||||||
@@ -629,7 +628,7 @@ impl MintKeySet {
|
|||||||
.derive_priv(secp, &derivation_path)
|
.derive_priv(secp, &derivation_path)
|
||||||
.expect("RNG busted"),
|
.expect("RNG busted"),
|
||||||
currency_unit,
|
currency_unit,
|
||||||
max_order,
|
amounts,
|
||||||
final_expiry,
|
final_expiry,
|
||||||
version,
|
version,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl From<Uuid> for QuoteId {
|
|||||||
impl fmt::Display for QuoteId {
|
impl fmt::Display for QuoteId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
QuoteId::BASE64(s) => write!(f, "{}", s),
|
QuoteId::BASE64(s) => write!(f, "{s}"),
|
||||||
QuoteId::UUID(u) => write!(f, "{}", u.hyphenated()),
|
QuoteId::UUID(u) => write!(f, "{}", u.hyphenated()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ where
|
|||||||
derivation_path_index: Some(0),
|
derivation_path_index: Some(0),
|
||||||
max_order: 32,
|
max_order: 32,
|
||||||
input_fee_ppk: 0,
|
input_fee_ppk: 0,
|
||||||
|
amounts: vec![],
|
||||||
};
|
};
|
||||||
let mut writer = db.begin_transaction().await.expect("db.begin()");
|
let mut writer = db.begin_transaction().await.expect("db.begin()");
|
||||||
writer.add_keyset_info(keyset_info).await.unwrap();
|
writer.add_keyset_info(keyset_info).await.unwrap();
|
||||||
|
|||||||
@@ -313,6 +313,8 @@ pub struct MintKeySetInfo {
|
|||||||
pub derivation_path_index: Option<u32>,
|
pub derivation_path_index: Option<u32>,
|
||||||
/// Max order of keyset
|
/// Max order of keyset
|
||||||
pub max_order: u8,
|
pub max_order: u8,
|
||||||
|
/// Supported amounts
|
||||||
|
pub amounts: Vec<u64>,
|
||||||
/// Input Fee ppk
|
/// Input Fee ppk
|
||||||
#[serde(default = "default_fee")]
|
#[serde(default = "default_fee")]
|
||||||
pub input_fee_ppk: u64,
|
pub input_fee_ppk: u64,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ pub async fn init_keysets(
|
|||||||
let keyset = MintKeySet::generate_from_xpriv(
|
let keyset = MintKeySet::generate_from_xpriv(
|
||||||
secp_ctx,
|
secp_ctx,
|
||||||
xpriv,
|
xpriv,
|
||||||
highest_index_keyset.max_order,
|
&highest_index_keyset.amounts,
|
||||||
highest_index_keyset.unit.clone(),
|
highest_index_keyset.unit.clone(),
|
||||||
highest_index_keyset.derivation_path.clone(),
|
highest_index_keyset.derivation_path.clone(),
|
||||||
highest_index_keyset.final_expiry,
|
highest_index_keyset.final_expiry,
|
||||||
@@ -98,7 +98,7 @@ pub async fn init_keysets(
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
Some(derivation_path_index),
|
Some(derivation_path_index),
|
||||||
unit.clone(),
|
unit.clone(),
|
||||||
*max_order,
|
&highest_index_keyset.amounts,
|
||||||
*input_fee_ppk,
|
*input_fee_ppk,
|
||||||
// TODO: add Mint settings for a final expiry of newly generated keysets
|
// TODO: add Mint settings for a final expiry of newly generated keysets
|
||||||
None,
|
None,
|
||||||
@@ -128,7 +128,7 @@ pub fn create_new_keyset<C: secp256k1::Signing>(
|
|||||||
derivation_path: DerivationPath,
|
derivation_path: DerivationPath,
|
||||||
derivation_path_index: Option<u32>,
|
derivation_path_index: Option<u32>,
|
||||||
unit: CurrencyUnit,
|
unit: CurrencyUnit,
|
||||||
max_order: u8,
|
amounts: &[u64],
|
||||||
input_fee_ppk: u64,
|
input_fee_ppk: u64,
|
||||||
final_expiry: Option<u64>,
|
final_expiry: Option<u64>,
|
||||||
) -> (MintKeySet, MintKeySetInfo) {
|
) -> (MintKeySet, MintKeySetInfo) {
|
||||||
@@ -138,7 +138,7 @@ pub fn create_new_keyset<C: secp256k1::Signing>(
|
|||||||
.derive_priv(secp, &derivation_path)
|
.derive_priv(secp, &derivation_path)
|
||||||
.expect("RNG busted"),
|
.expect("RNG busted"),
|
||||||
unit,
|
unit,
|
||||||
max_order,
|
amounts,
|
||||||
final_expiry,
|
final_expiry,
|
||||||
// TODO: change this to Version01 to generate keysets v2
|
// TODO: change this to Version01 to generate keysets v2
|
||||||
cdk_common::nut02::KeySetVersion::Version00,
|
cdk_common::nut02::KeySetVersion::Version00,
|
||||||
@@ -151,7 +151,8 @@ pub fn create_new_keyset<C: secp256k1::Signing>(
|
|||||||
final_expiry: keyset.final_expiry,
|
final_expiry: keyset.final_expiry,
|
||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order: 0,
|
||||||
|
amounts: amounts.to_owned(),
|
||||||
input_fee_ppk,
|
input_fee_ppk,
|
||||||
};
|
};
|
||||||
(keyset, keyset_info)
|
(keyset, keyset_info)
|
||||||
|
|||||||
@@ -65,13 +65,17 @@ impl DbSignatory {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let amounts = (0..max_order)
|
||||||
|
.map(|i| 2_u64.pow(i as u32))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let (keyset, keyset_info) = create_new_keyset(
|
let (keyset, keyset_info) = create_new_keyset(
|
||||||
&secp_ctx,
|
&secp_ctx,
|
||||||
xpriv,
|
xpriv,
|
||||||
derivation_path,
|
derivation_path,
|
||||||
Some(0),
|
Some(0),
|
||||||
unit.clone(),
|
unit.clone(),
|
||||||
max_order,
|
&amounts,
|
||||||
fee,
|
fee,
|
||||||
// TODO: add and connect settings for this
|
// TODO: add and connect settings for this
|
||||||
None,
|
None,
|
||||||
@@ -132,7 +136,7 @@ impl DbSignatory {
|
|||||||
MintKeySet::generate_from_xpriv(
|
MintKeySet::generate_from_xpriv(
|
||||||
&self.secp_ctx,
|
&self.secp_ctx,
|
||||||
self.xpriv,
|
self.xpriv,
|
||||||
keyset_info.max_order,
|
&keyset_info.amounts,
|
||||||
keyset_info.unit.clone(),
|
keyset_info.unit.clone(),
|
||||||
keyset_info.derivation_path.clone(),
|
keyset_info.derivation_path.clone(),
|
||||||
keyset_info.final_expiry,
|
keyset_info.final_expiry,
|
||||||
@@ -241,7 +245,7 @@ impl Signatory for DbSignatory {
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
Some(path_index),
|
Some(path_index),
|
||||||
args.unit.clone(),
|
args.unit.clone(),
|
||||||
args.max_order,
|
&args.amounts,
|
||||||
args.input_fee_ppk,
|
args.input_fee_ppk,
|
||||||
// TODO: add and connect settings for this
|
// TODO: add and connect settings for this
|
||||||
None,
|
None,
|
||||||
@@ -274,7 +278,7 @@ mod test {
|
|||||||
let keyset = MintKeySet::generate_from_seed(
|
let keyset = MintKeySet::generate_from_seed(
|
||||||
&Secp256k1::new(),
|
&Secp256k1::new(),
|
||||||
seed,
|
seed,
|
||||||
2,
|
&[1, 2],
|
||||||
CurrencyUnit::Sat,
|
CurrencyUnit::Sat,
|
||||||
derivation_path_from_unit(CurrencyUnit::Sat, 0).unwrap(),
|
derivation_path_from_unit(CurrencyUnit::Sat, 0).unwrap(),
|
||||||
None,
|
None,
|
||||||
@@ -320,7 +324,7 @@ mod test {
|
|||||||
let keyset = MintKeySet::generate_from_xpriv(
|
let keyset = MintKeySet::generate_from_xpriv(
|
||||||
&Secp256k1::new(),
|
&Secp256k1::new(),
|
||||||
xpriv,
|
xpriv,
|
||||||
2,
|
&[1, 2],
|
||||||
CurrencyUnit::Sat,
|
CurrencyUnit::Sat,
|
||||||
derivation_path_from_unit(CurrencyUnit::Sat, 0).unwrap(),
|
derivation_path_from_unit(CurrencyUnit::Sat, 0).unwrap(),
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
|
|||||||
|
|
||||||
use cdk_common::secret::Secret;
|
use cdk_common::secret::Secret;
|
||||||
use cdk_common::util::hex;
|
use cdk_common::util::hex;
|
||||||
use cdk_common::{Amount, PublicKey};
|
use cdk_common::{Amount, Id, PublicKey};
|
||||||
use tonic::Status;
|
use tonic::Status;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -44,7 +44,7 @@ impl TryInto<crate::signatory::SignatoryKeySet> for KeySet {
|
|||||||
|
|
||||||
fn try_into(self) -> Result<crate::signatory::SignatoryKeySet, Self::Error> {
|
fn try_into(self) -> Result<crate::signatory::SignatoryKeySet, Self::Error> {
|
||||||
Ok(crate::signatory::SignatoryKeySet {
|
Ok(crate::signatory::SignatoryKeySet {
|
||||||
id: self.id.parse()?,
|
id: Id::from_bytes(&self.id)?,
|
||||||
unit: self
|
unit: self
|
||||||
.unit
|
.unit
|
||||||
.ok_or(cdk_common::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
.ok_or(cdk_common::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
||||||
@@ -68,7 +68,7 @@ impl TryInto<crate::signatory::SignatoryKeySet> for KeySet {
|
|||||||
impl From<crate::signatory::SignatoryKeySet> for KeySet {
|
impl From<crate::signatory::SignatoryKeySet> for KeySet {
|
||||||
fn from(keyset: crate::signatory::SignatoryKeySet) -> Self {
|
fn from(keyset: crate::signatory::SignatoryKeySet) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: keyset.id.to_string(),
|
id: keyset.id.to_bytes(),
|
||||||
unit: Some(keyset.unit.into()),
|
unit: Some(keyset.unit.into()),
|
||||||
active: keyset.active,
|
active: keyset.active,
|
||||||
input_fee_ppk: keyset.input_fee_ppk,
|
input_fee_ppk: keyset.input_fee_ppk,
|
||||||
@@ -80,6 +80,7 @@ impl From<crate::signatory::SignatoryKeySet> for KeySet {
|
|||||||
.collect(),
|
.collect(),
|
||||||
}),
|
}),
|
||||||
final_expiry: keyset.final_expiry,
|
final_expiry: keyset.final_expiry,
|
||||||
|
version: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ impl From<cdk_common::BlindSignature> for BlindSignature {
|
|||||||
BlindSignature {
|
BlindSignature {
|
||||||
amount: value.amount.into(),
|
amount: value.amount.into(),
|
||||||
blinded_secret: value.c.to_bytes().to_vec(),
|
blinded_secret: value.c.to_bytes().to_vec(),
|
||||||
keyset_id: value.keyset_id.to_string(),
|
keyset_id: value.keyset_id.to_bytes(),
|
||||||
dleq: value.dleq.map(|x| x.into()),
|
dleq: value.dleq.map(|x| x.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +162,7 @@ impl From<cdk_common::Proof> for Proof {
|
|||||||
fn from(value: cdk_common::Proof) -> Self {
|
fn from(value: cdk_common::Proof) -> Self {
|
||||||
Proof {
|
Proof {
|
||||||
amount: value.amount.into(),
|
amount: value.amount.into(),
|
||||||
keyset_id: value.keyset_id.to_string(),
|
keyset_id: value.keyset_id.to_bytes(),
|
||||||
secret: value.secret.to_bytes(),
|
secret: value.secret.to_bytes(),
|
||||||
c: value.c.to_bytes().to_vec(),
|
c: value.c.to_bytes().to_vec(),
|
||||||
}
|
}
|
||||||
@@ -179,9 +180,7 @@ impl TryInto<cdk_common::Proof> for Proof {
|
|||||||
|
|
||||||
Ok(cdk_common::Proof {
|
Ok(cdk_common::Proof {
|
||||||
amount: self.amount.into(),
|
amount: self.amount.into(),
|
||||||
keyset_id: self
|
keyset_id: Id::from_bytes(&self.keyset_id)
|
||||||
.keyset_id
|
|
||||||
.parse()
|
|
||||||
.map_err(|e| Status::from_error(Box::new(e)))?,
|
.map_err(|e| Status::from_error(Box::new(e)))?,
|
||||||
secret: Secret::new(secret),
|
secret: Secret::new(secret),
|
||||||
c: cdk_common::PublicKey::from_slice(&self.c)
|
c: cdk_common::PublicKey::from_slice(&self.c)
|
||||||
@@ -199,7 +198,7 @@ impl TryInto<cdk_common::BlindSignature> for BlindSignature {
|
|||||||
Ok(cdk_common::BlindSignature {
|
Ok(cdk_common::BlindSignature {
|
||||||
amount: self.amount.into(),
|
amount: self.amount.into(),
|
||||||
c: cdk_common::PublicKey::from_slice(&self.blinded_secret)?,
|
c: cdk_common::PublicKey::from_slice(&self.blinded_secret)?,
|
||||||
keyset_id: self.keyset_id.parse().expect("Invalid keyset id"),
|
keyset_id: Id::from_bytes(&self.keyset_id)?,
|
||||||
dleq: self.dleq.map(|dleq| dleq.try_into()).transpose()?,
|
dleq: self.dleq.map(|dleq| dleq.try_into()).transpose()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -209,7 +208,7 @@ impl From<cdk_common::BlindedMessage> for BlindedMessage {
|
|||||||
fn from(value: cdk_common::BlindedMessage) -> Self {
|
fn from(value: cdk_common::BlindedMessage) -> Self {
|
||||||
BlindedMessage {
|
BlindedMessage {
|
||||||
amount: value.amount.into(),
|
amount: value.amount.into(),
|
||||||
keyset_id: value.keyset_id.to_string(),
|
keyset_id: value.keyset_id.to_bytes(),
|
||||||
blinded_secret: value.blinded_secret.to_bytes().to_vec(),
|
blinded_secret: value.blinded_secret.to_bytes().to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,9 +219,7 @@ impl TryInto<cdk_common::BlindedMessage> for BlindedMessage {
|
|||||||
fn try_into(self) -> Result<cdk_common::BlindedMessage, Self::Error> {
|
fn try_into(self) -> Result<cdk_common::BlindedMessage, Self::Error> {
|
||||||
Ok(cdk_common::BlindedMessage {
|
Ok(cdk_common::BlindedMessage {
|
||||||
amount: self.amount.into(),
|
amount: self.amount.into(),
|
||||||
keyset_id: self
|
keyset_id: Id::from_bytes(&self.keyset_id)
|
||||||
.keyset_id
|
|
||||||
.parse()
|
|
||||||
.map_err(|e| Status::from_error(Box::new(e)))?,
|
.map_err(|e| Status::from_error(Box::new(e)))?,
|
||||||
blinded_secret: cdk_common::PublicKey::from_slice(&self.blinded_secret)
|
blinded_secret: cdk_common::PublicKey::from_slice(&self.blinded_secret)
|
||||||
.map_err(|e| Status::from_error(Box::new(e)))?,
|
.map_err(|e| Status::from_error(Box::new(e)))?,
|
||||||
@@ -311,10 +308,7 @@ impl TryInto<cdk_common::KeySet> for KeySet {
|
|||||||
type Error = cdk_common::error::Error;
|
type Error = cdk_common::error::Error;
|
||||||
fn try_into(self) -> Result<cdk_common::KeySet, Self::Error> {
|
fn try_into(self) -> Result<cdk_common::KeySet, Self::Error> {
|
||||||
Ok(cdk_common::KeySet {
|
Ok(cdk_common::KeySet {
|
||||||
id: self
|
id: Id::from_bytes(&self.id)?,
|
||||||
.id
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| cdk_common::error::Error::Custom("Invalid ID".to_owned()))?,
|
|
||||||
unit: self
|
unit: self
|
||||||
.unit
|
.unit
|
||||||
.ok_or(cdk_common::error::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
.ok_or(cdk_common::error::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
||||||
@@ -337,7 +331,7 @@ impl From<crate::signatory::RotateKeyArguments> for RotationRequest {
|
|||||||
fn from(value: crate::signatory::RotateKeyArguments) -> Self {
|
fn from(value: crate::signatory::RotateKeyArguments) -> Self {
|
||||||
Self {
|
Self {
|
||||||
unit: Some(value.unit.into()),
|
unit: Some(value.unit.into()),
|
||||||
max_order: value.max_order.into(),
|
amounts: value.amounts,
|
||||||
input_fee_ppk: value.input_fee_ppk,
|
input_fee_ppk: value.input_fee_ppk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,10 +346,7 @@ impl TryInto<crate::signatory::RotateKeyArguments> for RotationRequest {
|
|||||||
.unit
|
.unit
|
||||||
.ok_or(Status::invalid_argument("unit not set"))?
|
.ok_or(Status::invalid_argument("unit not set"))?
|
||||||
.try_into()?,
|
.try_into()?,
|
||||||
max_order: self
|
amounts: self.amounts,
|
||||||
.max_order
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| Status::invalid_argument("Invalid max_order"))?,
|
|
||||||
input_fee_ppk: self.input_fee_ppk,
|
input_fee_ppk: self.input_fee_ppk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -364,12 +355,13 @@ impl TryInto<crate::signatory::RotateKeyArguments> for RotationRequest {
|
|||||||
impl From<cdk_common::KeySetInfo> for KeySet {
|
impl From<cdk_common::KeySetInfo> for KeySet {
|
||||||
fn from(value: cdk_common::KeySetInfo) -> Self {
|
fn from(value: cdk_common::KeySetInfo) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: value.id.into(),
|
id: value.id.to_bytes(),
|
||||||
unit: Some(value.unit.into()),
|
unit: Some(value.unit.into()),
|
||||||
active: value.active,
|
active: value.active,
|
||||||
input_fee_ppk: value.input_fee_ppk,
|
input_fee_ppk: value.input_fee_ppk,
|
||||||
keys: Default::default(),
|
keys: Default::default(),
|
||||||
final_expiry: value.final_expiry,
|
final_expiry: value.final_expiry,
|
||||||
|
version: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,7 +371,7 @@ impl TryInto<cdk_common::KeySetInfo> for KeySet {
|
|||||||
|
|
||||||
fn try_into(self) -> Result<cdk_common::KeySetInfo, Self::Error> {
|
fn try_into(self) -> Result<cdk_common::KeySetInfo, Self::Error> {
|
||||||
Ok(cdk_common::KeySetInfo {
|
Ok(cdk_common::KeySetInfo {
|
||||||
id: self.id.try_into()?,
|
id: Id::from_bytes(&self.id)?,
|
||||||
unit: self
|
unit: self
|
||||||
.unit
|
.unit
|
||||||
.ok_or(cdk_common::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
.ok_or(cdk_common::Error::Custom(INTERNAL_ERROR.to_owned()))?
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ message BlindedMessages {
|
|||||||
// Represents a blinded message
|
// Represents a blinded message
|
||||||
message BlindedMessage {
|
message BlindedMessage {
|
||||||
uint64 amount = 1;
|
uint64 amount = 1;
|
||||||
string keyset_id = 2;
|
bytes keyset_id = 2;
|
||||||
bytes blinded_secret = 3;
|
bytes blinded_secret = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,12 +57,13 @@ message SignatoryKeysets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message KeySet {
|
message KeySet {
|
||||||
string id = 1;
|
bytes id = 1;
|
||||||
CurrencyUnit unit = 2;
|
CurrencyUnit unit = 2;
|
||||||
bool active = 3;
|
bool active = 3;
|
||||||
uint64 input_fee_ppk = 4;
|
uint64 input_fee_ppk = 4;
|
||||||
Keys keys = 5;
|
Keys keys = 5;
|
||||||
optional uint64 final_expiry = 6;
|
optional uint64 final_expiry = 6;
|
||||||
|
uint64 version = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Keys {
|
message Keys {
|
||||||
@@ -72,7 +73,7 @@ message Keys {
|
|||||||
message RotationRequest {
|
message RotationRequest {
|
||||||
CurrencyUnit unit = 1;
|
CurrencyUnit unit = 1;
|
||||||
uint64 input_fee_ppk = 2;
|
uint64 input_fee_ppk = 2;
|
||||||
uint32 max_order = 3;
|
repeated uint64 amounts = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CurrencyUnitType {
|
enum CurrencyUnitType {
|
||||||
@@ -99,18 +100,28 @@ message Proofs {
|
|||||||
|
|
||||||
message Proof {
|
message Proof {
|
||||||
uint64 amount = 1;
|
uint64 amount = 1;
|
||||||
string keyset_id = 2;
|
bytes keyset_id = 2;
|
||||||
bytes secret = 3;
|
bytes secret = 3;
|
||||||
bytes c = 4;
|
bytes c = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ProofDLEQ {
|
||||||
|
bytes e = 1;
|
||||||
|
bytes s = 2;
|
||||||
|
bytes r = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SigningResponse {
|
||||||
|
Error error = 1;
|
||||||
|
BlindSignatures blind_signatures = 2;
|
||||||
|
}
|
||||||
message BlindSignatures {
|
message BlindSignatures {
|
||||||
repeated BlindSignature blind_signatures = 1;
|
repeated BlindSignature blind_signatures = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message BlindSignature {
|
message BlindSignature {
|
||||||
uint64 amount = 1;
|
uint64 amount = 1;
|
||||||
string keyset_id = 2;
|
bytes keyset_id = 2;
|
||||||
bytes blinded_secret = 3;
|
bytes blinded_secret = 3;
|
||||||
optional BlindSignatureDLEQ dleq = 4;
|
optional BlindSignatureDLEQ dleq = 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ pub struct RotateKeyArguments {
|
|||||||
/// Unit
|
/// Unit
|
||||||
pub unit: CurrencyUnit,
|
pub unit: CurrencyUnit,
|
||||||
/// Max order
|
/// Max order
|
||||||
pub max_order: u8,
|
pub amounts: Vec<u64>,
|
||||||
/// Input fee
|
/// Input fee
|
||||||
pub input_fee_ppk: u64,
|
pub input_fee_ppk: u64,
|
||||||
}
|
}
|
||||||
@@ -110,6 +110,7 @@ impl From<SignatoryKeySet> for MintKeySetInfo {
|
|||||||
derivation_path: Default::default(),
|
derivation_path: Default::default(),
|
||||||
derivation_path_index: Default::default(),
|
derivation_path_index: Default::default(),
|
||||||
max_order: 0,
|
max_order: 0,
|
||||||
|
amounts: vec![],
|
||||||
final_expiry: val.final_expiry,
|
final_expiry: val.final_expiry,
|
||||||
valid_from: 0,
|
valid_from: 0,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ where
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order,
|
||||||
|
amounts,
|
||||||
input_fee_ppk
|
input_fee_ppk
|
||||||
FROM
|
FROM
|
||||||
keyset
|
keyset
|
||||||
@@ -308,6 +309,7 @@ where
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order,
|
||||||
|
amounts,
|
||||||
input_fee_ppk
|
input_fee_ppk
|
||||||
FROM
|
FROM
|
||||||
keyset
|
keyset
|
||||||
|
|||||||
@@ -29,4 +29,6 @@ pub static MIGRATIONS: &[(&str, &str, &str)] = &[
|
|||||||
("sqlite", "20250819200000_remove_request_lookup_kind_constraints.sql", include_str!(r#"./migrations/sqlite/20250819200000_remove_request_lookup_kind_constraints.sql"#)),
|
("sqlite", "20250819200000_remove_request_lookup_kind_constraints.sql", include_str!(r#"./migrations/sqlite/20250819200000_remove_request_lookup_kind_constraints.sql"#)),
|
||||||
("sqlite", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/sqlite/20250901090000_add_kv_store.sql"#)),
|
("sqlite", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/sqlite/20250901090000_add_kv_store.sql"#)),
|
||||||
("postgres", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/postgres/20250901090000_add_kv_store.sql"#)),
|
("postgres", "20250901090000_add_kv_store.sql", include_str!(r#"./migrations/postgres/20250901090000_add_kv_store.sql"#)),
|
||||||
|
("sqlite", "20250903200000_add_signatory_amounts.sql", include_str!(r#"./migrations/sqlite/20250903200000_add_signatory_amounts.sql"#)),
|
||||||
|
("postgres", "20250903200000_add_signatory_amounts.sql", include_str!(r#"./migrations/postgres/20250903200000_add_signatory_amounts.sql"#)),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE keyset ADD COLUMN amounts TEXT DEFAULT NULL;
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
CREATE TABLE keyset_new (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
unit TEXT NOT NULL,
|
||||||
|
active BOOL NOT NULL,
|
||||||
|
valid_from INTEGER NOT NULL,
|
||||||
|
valid_to INTEGER,
|
||||||
|
max_order INTEGER NOT NULL,
|
||||||
|
amounts TEXT DEFAULT NULL,
|
||||||
|
input_fee_ppk INTEGER,
|
||||||
|
derivation_path TEXT NOT NULL,
|
||||||
|
derivation_path_index INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO keyset_new SELECT
|
||||||
|
id,
|
||||||
|
unit,
|
||||||
|
active,
|
||||||
|
valid_from,
|
||||||
|
valid_to,
|
||||||
|
max_order,
|
||||||
|
NULL,
|
||||||
|
input_fee_ppk,
|
||||||
|
derivation_path,
|
||||||
|
derivation_path_index
|
||||||
|
FROM keyset;
|
||||||
|
|
||||||
|
DROP TABLE keyset;
|
||||||
|
|
||||||
|
ALTER TABLE keyset_new RENAME TO keyset;
|
||||||
|
|
||||||
|
CREATE INDEX unit_index ON keyset(unit);
|
||||||
|
CREATE INDEX active_index ON keyset(active);
|
||||||
@@ -383,11 +383,11 @@ where
|
|||||||
INSERT INTO
|
INSERT INTO
|
||||||
keyset (
|
keyset (
|
||||||
id, unit, active, valid_from, valid_to, derivation_path,
|
id, unit, active, valid_from, valid_to, derivation_path,
|
||||||
max_order, input_fee_ppk, derivation_path_index
|
max_order, amounts, input_fee_ppk, derivation_path_index
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
:id, :unit, :active, :valid_from, :valid_to, :derivation_path,
|
:id, :unit, :active, :valid_from, :valid_to, :derivation_path,
|
||||||
:max_order, :input_fee_ppk, :derivation_path_index
|
:max_order, :amounts, :input_fee_ppk, :derivation_path_index
|
||||||
)
|
)
|
||||||
ON CONFLICT(id) DO UPDATE SET
|
ON CONFLICT(id) DO UPDATE SET
|
||||||
unit = excluded.unit,
|
unit = excluded.unit,
|
||||||
@@ -396,6 +396,7 @@ where
|
|||||||
valid_to = excluded.valid_to,
|
valid_to = excluded.valid_to,
|
||||||
derivation_path = excluded.derivation_path,
|
derivation_path = excluded.derivation_path,
|
||||||
max_order = excluded.max_order,
|
max_order = excluded.max_order,
|
||||||
|
amounts = excluded.amounts,
|
||||||
input_fee_ppk = excluded.input_fee_ppk,
|
input_fee_ppk = excluded.input_fee_ppk,
|
||||||
derivation_path_index = excluded.derivation_path_index
|
derivation_path_index = excluded.derivation_path_index
|
||||||
"#,
|
"#,
|
||||||
@@ -407,6 +408,7 @@ where
|
|||||||
.bind("valid_to", keyset.final_expiry.map(|v| v as i64))
|
.bind("valid_to", keyset.final_expiry.map(|v| v as i64))
|
||||||
.bind("derivation_path", keyset.derivation_path.to_string())
|
.bind("derivation_path", keyset.derivation_path.to_string())
|
||||||
.bind("max_order", keyset.max_order)
|
.bind("max_order", keyset.max_order)
|
||||||
|
.bind("amounts", serde_json::to_string(&keyset.amounts).ok())
|
||||||
.bind("input_fee_ppk", keyset.input_fee_ppk as i64)
|
.bind("input_fee_ppk", keyset.input_fee_ppk as i64)
|
||||||
.bind("derivation_path_index", keyset.derivation_path_index)
|
.bind("derivation_path_index", keyset.derivation_path_index)
|
||||||
.execute(&self.inner)
|
.execute(&self.inner)
|
||||||
@@ -496,6 +498,7 @@ where
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order,
|
||||||
|
amounts,
|
||||||
input_fee_ppk
|
input_fee_ppk
|
||||||
FROM
|
FROM
|
||||||
keyset
|
keyset
|
||||||
@@ -520,6 +523,7 @@ where
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order,
|
||||||
|
amounts,
|
||||||
input_fee_ppk
|
input_fee_ppk
|
||||||
FROM
|
FROM
|
||||||
keyset
|
keyset
|
||||||
@@ -1837,10 +1841,16 @@ fn sql_row_to_keyset_info(row: Vec<Column>) -> Result<MintKeySetInfo, Error> {
|
|||||||
derivation_path,
|
derivation_path,
|
||||||
derivation_path_index,
|
derivation_path_index,
|
||||||
max_order,
|
max_order,
|
||||||
|
amounts,
|
||||||
row_keyset_ppk
|
row_keyset_ppk
|
||||||
) = row
|
) = row
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let max_order: u8 = column_as_number!(max_order);
|
||||||
|
let amounts = column_as_nullable_string!(amounts)
|
||||||
|
.and_then(|str| serde_json::from_str(&str).ok())
|
||||||
|
.unwrap_or_else(|| (0..max_order).map(|m| 2u64.pow(m.into())).collect());
|
||||||
|
|
||||||
Ok(MintKeySetInfo {
|
Ok(MintKeySetInfo {
|
||||||
id: column_as_string!(id, Id::from_str, Id::from_bytes),
|
id: column_as_string!(id, Id::from_str, Id::from_bytes),
|
||||||
unit: column_as_string!(unit, CurrencyUnit::from_str),
|
unit: column_as_string!(unit, CurrencyUnit::from_str),
|
||||||
@@ -1848,7 +1858,8 @@ fn sql_row_to_keyset_info(row: Vec<Column>) -> Result<MintKeySetInfo, Error> {
|
|||||||
valid_from: column_as_number!(valid_from),
|
valid_from: column_as_number!(valid_from),
|
||||||
derivation_path: column_as_string!(derivation_path, DerivationPath::from_str),
|
derivation_path: column_as_string!(derivation_path, DerivationPath::from_str),
|
||||||
derivation_path_index: column_as_nullable_number!(derivation_path_index),
|
derivation_path_index: column_as_nullable_number!(derivation_path_index),
|
||||||
max_order: column_as_number!(max_order),
|
max_order,
|
||||||
|
amounts,
|
||||||
input_fee_ppk: column_as_number!(row_keyset_ppk),
|
input_fee_ppk: column_as_number!(row_keyset_ppk),
|
||||||
final_expiry: column_as_nullable_number!(valid_to),
|
final_expiry: column_as_nullable_number!(valid_to),
|
||||||
})
|
})
|
||||||
@@ -2062,3 +2073,97 @@ fn sql_row_to_blind_signature(row: Vec<Column>) -> Result<BlindSignature, Error>
|
|||||||
dleq,
|
dleq,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod max_order_to_amounts_migrations {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn legacy_payload() {
|
||||||
|
let result = sql_row_to_keyset_info(vec![
|
||||||
|
Column::Text("0083a60439303340".to_owned()),
|
||||||
|
Column::Text("sat".to_owned()),
|
||||||
|
Column::Integer(1),
|
||||||
|
Column::Integer(1749844864),
|
||||||
|
Column::Null,
|
||||||
|
Column::Text("0'/0'/0'".to_owned()),
|
||||||
|
Column::Integer(0),
|
||||||
|
Column::Integer(32),
|
||||||
|
Column::Null,
|
||||||
|
Column::Integer(0),
|
||||||
|
]);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn migrated_payload() {
|
||||||
|
let legacy = sql_row_to_keyset_info(vec![
|
||||||
|
Column::Text("0083a60439303340".to_owned()),
|
||||||
|
Column::Text("sat".to_owned()),
|
||||||
|
Column::Integer(1),
|
||||||
|
Column::Integer(1749844864),
|
||||||
|
Column::Null,
|
||||||
|
Column::Text("0'/0'/0'".to_owned()),
|
||||||
|
Column::Integer(0),
|
||||||
|
Column::Integer(32),
|
||||||
|
Column::Null,
|
||||||
|
Column::Integer(0),
|
||||||
|
]);
|
||||||
|
assert!(legacy.is_ok());
|
||||||
|
|
||||||
|
let amounts = (0..32).map(|x| 2u64.pow(x)).collect::<Vec<_>>();
|
||||||
|
let migrated = sql_row_to_keyset_info(vec![
|
||||||
|
Column::Text("0083a60439303340".to_owned()),
|
||||||
|
Column::Text("sat".to_owned()),
|
||||||
|
Column::Integer(1),
|
||||||
|
Column::Integer(1749844864),
|
||||||
|
Column::Null,
|
||||||
|
Column::Text("0'/0'/0'".to_owned()),
|
||||||
|
Column::Integer(0),
|
||||||
|
Column::Integer(32),
|
||||||
|
Column::Text(serde_json::to_string(&amounts).expect("valid json")),
|
||||||
|
Column::Integer(0),
|
||||||
|
]);
|
||||||
|
assert!(migrated.is_ok());
|
||||||
|
assert_eq!(legacy.unwrap(), migrated.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn amounts_over_max_order() {
|
||||||
|
let legacy = sql_row_to_keyset_info(vec![
|
||||||
|
Column::Text("0083a60439303340".to_owned()),
|
||||||
|
Column::Text("sat".to_owned()),
|
||||||
|
Column::Integer(1),
|
||||||
|
Column::Integer(1749844864),
|
||||||
|
Column::Null,
|
||||||
|
Column::Text("0'/0'/0'".to_owned()),
|
||||||
|
Column::Integer(0),
|
||||||
|
Column::Integer(32),
|
||||||
|
Column::Null,
|
||||||
|
Column::Integer(0),
|
||||||
|
]);
|
||||||
|
assert!(legacy.is_ok());
|
||||||
|
|
||||||
|
let amounts = (0..16).map(|x| 2u64.pow(x)).collect::<Vec<_>>();
|
||||||
|
let migrated = sql_row_to_keyset_info(vec![
|
||||||
|
Column::Text("0083a60439303340".to_owned()),
|
||||||
|
Column::Text("sat".to_owned()),
|
||||||
|
Column::Integer(1),
|
||||||
|
Column::Integer(1749844864),
|
||||||
|
Column::Null,
|
||||||
|
Column::Text("0'/0'/0'".to_owned()),
|
||||||
|
Column::Integer(0),
|
||||||
|
Column::Integer(32),
|
||||||
|
Column::Text(serde_json::to_string(&amounts).expect("valid json")),
|
||||||
|
Column::Integer(0),
|
||||||
|
]);
|
||||||
|
assert!(migrated.is_ok());
|
||||||
|
let migrated = migrated.unwrap();
|
||||||
|
assert_ne!(legacy.unwrap(), migrated);
|
||||||
|
assert_eq!(migrated.amounts.len(), 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl Mint {
|
|||||||
.signatory
|
.signatory
|
||||||
.rotate_keyset(RotateKeyArguments {
|
.rotate_keyset(RotateKeyArguments {
|
||||||
unit,
|
unit,
|
||||||
max_order,
|
amounts: (0..max_order).map(|n| 2u64.pow(n.into())).collect(),
|
||||||
input_fee_ppk,
|
input_fee_ppk,
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user