Skip to main content

vta_sdk/keys/
mod.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5#[serde(rename_all = "lowercase")]
6#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
7pub enum KeyType {
8    Ed25519,
9    X25519,
10    /// ECDSA P-256 key for ES256 signing.
11    P256,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
15#[serde(rename_all = "lowercase")]
16#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
17pub enum KeyStatus {
18    Active,
19    Revoked,
20}
21
22/// Whether a key was derived from the BIP-32 seed or imported externally.
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
24#[serde(rename_all = "lowercase")]
25#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
26pub enum KeyOrigin {
27    Derived,
28    Imported,
29}
30
31fn default_derived() -> KeyOrigin {
32    KeyOrigin::Derived
33}
34
35/// One key as the maintainer holds it — canonical
36/// `keys/_shared/0.1/key-record#KeyRecord`.
37///
38/// The **wire** names are canonical camelCase; the Rust field names are the
39/// maintainer's historical snake_case ones, kept so every call site did not
40/// have to move in the same change. Snake_case is additionally accepted on
41/// *intake* via aliases, so a producer written against the pre-fold shape keeps
42/// working while it migrates — emission is canonical either way.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44#[serde(rename_all = "camelCase")]
45#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
46pub struct KeyRecord {
47    #[serde(alias = "key_id")]
48    pub key_id: String,
49    #[serde(alias = "derivation_path")]
50    pub derivation_path: String,
51    #[serde(alias = "key_type")]
52    pub key_type: KeyType,
53    pub status: KeyStatus,
54    #[serde(alias = "public_key")]
55    pub public_key: String,
56    pub label: Option<String>,
57    #[serde(default, alias = "context_id")]
58    pub context_id: Option<String>,
59    #[serde(default, alias = "seed_id")]
60    pub seed_id: Option<u32>,
61    #[serde(default = "default_derived")]
62    pub origin: KeyOrigin,
63    #[serde(alias = "created_at")]
64    pub created_at: DateTime<Utc>,
65    #[serde(alias = "updated_at")]
66    pub updated_at: DateTime<Utc>,
67}
68
69impl std::fmt::Display for KeyType {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        match self {
72            KeyType::Ed25519 => write!(f, "ed25519"),
73            KeyType::X25519 => write!(f, "x25519"),
74            KeyType::P256 => write!(f, "p256"),
75        }
76    }
77}
78
79impl std::fmt::Display for KeyStatus {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        match self {
82            KeyStatus::Active => write!(f, "active"),
83            KeyStatus::Revoked => write!(f, "revoked"),
84        }
85    }
86}