mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-05 13:16:00 +01:00
mintd: sort pks by amount in /v1/keys
This commit is contained in:
@@ -4,8 +4,9 @@
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::nuts::CurrencyUnit;
|
||||
@@ -214,6 +215,54 @@ impl std::ops::Div for Amount {
|
||||
}
|
||||
}
|
||||
|
||||
/// String wrapper for an [Amount].
|
||||
///
|
||||
/// It ser-/deserializes the inner [Amount] to a string, while at the same time using the [u64]
|
||||
/// value of the [Amount] for comparison and ordering. This helps automatically sort the keys of
|
||||
/// a [BTreeMap] when [AmountStr] is used as key.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AmountStr(Amount);
|
||||
|
||||
impl AmountStr {
|
||||
pub(crate) fn from(amt: Amount) -> Self {
|
||||
Self(amt)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd<Self> for AmountStr {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for AmountStr {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0.cmp(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for AmountStr {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
u64::from_str(&s)
|
||||
.map(Amount)
|
||||
.map(Self)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for AmountStr {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.0.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Kinds of targeting that are supported
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize)]
|
||||
pub enum SplitTarget {
|
||||
|
||||
@@ -16,7 +16,7 @@ mod secret_key;
|
||||
pub use self::public_key::PublicKey;
|
||||
pub use self::secret_key::SecretKey;
|
||||
use super::nut02::KeySet;
|
||||
use crate::amount::Amount;
|
||||
use crate::amount::{Amount, AmountStr};
|
||||
|
||||
/// Nut01 Error
|
||||
#[derive(Debug, Error)]
|
||||
@@ -37,16 +37,20 @@ pub enum Error {
|
||||
},
|
||||
}
|
||||
|
||||
/// Mint Keys [NUT-01]
|
||||
/// Mint public keys per amount.
|
||||
///
|
||||
/// This is a variation of [MintKeys] that only exposes the public keys.
|
||||
///
|
||||
/// See [NUT-01]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct Keys(BTreeMap<String, PublicKey>);
|
||||
pub struct Keys(BTreeMap<AmountStr, PublicKey>);
|
||||
|
||||
impl From<MintKeys> for Keys {
|
||||
fn from(keys: MintKeys) -> Self {
|
||||
Self(
|
||||
keys.0
|
||||
.iter()
|
||||
.map(|(amount, keypair)| (amount.to_string(), keypair.public_key))
|
||||
.into_iter()
|
||||
.map(|(amount, keypair)| (AmountStr::from(amount), keypair.public_key))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
@@ -55,25 +59,25 @@ impl From<MintKeys> for Keys {
|
||||
impl Keys {
|
||||
/// Create new [`Keys`]
|
||||
#[inline]
|
||||
pub fn new(keys: BTreeMap<String, PublicKey>) -> Self {
|
||||
pub fn new(keys: BTreeMap<AmountStr, PublicKey>) -> Self {
|
||||
Self(keys)
|
||||
}
|
||||
|
||||
/// Get [`Keys`]
|
||||
#[inline]
|
||||
pub fn keys(&self) -> &BTreeMap<String, PublicKey> {
|
||||
pub fn keys(&self) -> &BTreeMap<AmountStr, PublicKey> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Get [`PublicKey`] for [`Amount`]
|
||||
#[inline]
|
||||
pub fn amount_key(&self, amount: Amount) -> Option<PublicKey> {
|
||||
self.0.get(&amount.to_string()).copied()
|
||||
self.0.get(&AmountStr::from(amount)).copied()
|
||||
}
|
||||
|
||||
/// Iterate through the (`Amount`, `PublicKey`) entries in the Map
|
||||
#[inline]
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&String, &PublicKey)> {
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&AmountStr, &PublicKey)> {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
@@ -87,7 +91,7 @@ pub struct KeysResponse {
|
||||
pub keysets: Vec<KeySet>,
|
||||
}
|
||||
|
||||
/// Mint keys
|
||||
/// Mint key pairs per amount
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MintKeys(BTreeMap<Amount, MintKeyPair>);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ use thiserror::Error;
|
||||
use super::nut01::Keys;
|
||||
#[cfg(feature = "mint")]
|
||||
use super::nut01::{MintKeyPair, MintKeys};
|
||||
use crate::amount::AmountStr;
|
||||
use crate::nuts::nut00::CurrencyUnit;
|
||||
use crate::util::hex;
|
||||
#[cfg(feature = "mint")]
|
||||
@@ -197,9 +198,9 @@ impl From<&Keys> for Id {
|
||||
5 - prefix it with a keyset ID version byte
|
||||
*/
|
||||
|
||||
let mut keys: Vec<(&String, &super::PublicKey)> = map.iter().collect();
|
||||
let mut keys: Vec<(&AmountStr, &super::PublicKey)> = map.iter().collect();
|
||||
|
||||
keys.sort_by_key(|(k, _v)| u64::from_str(k).unwrap());
|
||||
keys.sort_by_key(|(amt, _v)| *amt);
|
||||
|
||||
let pubkeys_concat: Vec<u8> = keys
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user