cdk_signatory/
signatory.rs

1//! Signatory mod
2//!
3//! This module abstract all the key related operations, defining an interface for the necessary
4//! operations, to be implemented by the different signatory implementations.
5//!
6//! There is an in memory implementation, when the keys are stored in memory, in the same process,
7//! but it is isolated from the rest of the application, and they communicate through a channel with
8//! the defined API.
9use cdk_common::error::Error;
10use cdk_common::mint::MintKeySetInfo;
11use cdk_common::{
12    BlindSignature, BlindedMessage, CurrencyUnit, Id, KeySet, Keys, MintKeySet, Proof, PublicKey,
13};
14
15#[derive(Debug)]
16/// Type alias to make the keyset info API more useful, queryable by unit and Id
17pub enum KeysetIdentifier {
18    /// Mint Keyset by unit
19    Unit(CurrencyUnit),
20    /// Mint Keyset by Id
21    Id(Id),
22}
23
24impl From<Id> for KeysetIdentifier {
25    fn from(id: Id) -> Self {
26        Self::Id(id)
27    }
28}
29
30impl From<CurrencyUnit> for KeysetIdentifier {
31    fn from(unit: CurrencyUnit) -> Self {
32        Self::Unit(unit)
33    }
34}
35
36/// RotateKeyArguments
37///
38/// This struct is used to pass the arguments to the rotate_keyset function
39///
40/// TODO: Change argument to accept a vector of Amount instead of max_order.
41#[derive(Debug, Clone)]
42pub struct RotateKeyArguments {
43    /// Unit
44    pub unit: CurrencyUnit,
45    /// Max order
46    pub amounts: Vec<u64>,
47    /// Input fee
48    pub input_fee_ppk: u64,
49}
50
51#[derive(Debug, Clone)]
52/// Signatory keysets
53pub struct SignatoryKeysets {
54    /// The public key
55    pub pubkey: PublicKey,
56    /// The list of keysets
57    pub keysets: Vec<SignatoryKeySet>,
58}
59
60#[derive(Debug, Clone)]
61/// SignatoryKeySet
62///
63/// This struct is used to represent a keyset and its info, pretty much all the information but the
64/// private key, that will never leave the signatory
65pub struct SignatoryKeySet {
66    /// The keyset Id
67    pub id: Id,
68    /// The Currency Unit
69    pub unit: CurrencyUnit,
70    /// Whether to set it as active or not
71    pub active: bool,
72    /// The list of public keys
73    pub keys: Keys,
74    /// Information about the fee per public key
75    pub input_fee_ppk: u64,
76    /// Final expiry of the keyset (unix timestamp in the future)
77    pub final_expiry: Option<u64>,
78}
79
80impl From<&SignatoryKeySet> for KeySet {
81    fn from(val: &SignatoryKeySet) -> Self {
82        val.to_owned().into()
83    }
84}
85
86impl From<SignatoryKeySet> for KeySet {
87    fn from(val: SignatoryKeySet) -> Self {
88        KeySet {
89            id: val.id,
90            unit: val.unit,
91            keys: val.keys,
92            final_expiry: val.final_expiry,
93        }
94    }
95}
96
97impl From<&SignatoryKeySet> for MintKeySetInfo {
98    fn from(val: &SignatoryKeySet) -> Self {
99        val.to_owned().into()
100    }
101}
102
103impl From<SignatoryKeySet> for MintKeySetInfo {
104    fn from(val: SignatoryKeySet) -> Self {
105        MintKeySetInfo {
106            id: val.id,
107            unit: val.unit,
108            active: val.active,
109            input_fee_ppk: val.input_fee_ppk,
110            derivation_path: Default::default(),
111            derivation_path_index: Default::default(),
112            max_order: 0,
113            amounts: vec![],
114            final_expiry: val.final_expiry,
115            valid_from: 0,
116        }
117    }
118}
119
120impl From<&(MintKeySetInfo, MintKeySet)> for SignatoryKeySet {
121    fn from((info, key): &(MintKeySetInfo, MintKeySet)) -> Self {
122        Self {
123            id: info.id,
124            unit: key.unit.clone(),
125            active: info.active,
126            input_fee_ppk: info.input_fee_ppk,
127            keys: key.keys.clone().into(),
128            final_expiry: key.final_expiry,
129        }
130    }
131}
132
133#[async_trait::async_trait]
134/// Signatory trait
135pub trait Signatory {
136    /// The Signatory implementation name. This may be exposed, so being as discrete as possible is
137    /// advised.
138    fn name(&self) -> String;
139
140    /// Blind sign a message.
141    ///
142    /// The message can be for a coin or an auth token.
143    async fn blind_sign(
144        &self,
145        blinded_messages: Vec<BlindedMessage>,
146    ) -> Result<Vec<BlindSignature>, Error>;
147
148    /// Verify [`Proof`] meets conditions and is signed
149    async fn verify_proofs(&self, proofs: Vec<Proof>) -> Result<(), Error>;
150
151    /// Retrieve the list of all mint keysets
152    async fn keysets(&self) -> Result<SignatoryKeysets, Error>;
153
154    /// Add current keyset to inactive keysets
155    /// Generate new keyset
156    async fn rotate_keyset(&self, args: RotateKeyArguments) -> Result<SignatoryKeySet, Error>;
157}