Skip to main content

nym_api_requests/models/
api_status.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::signable::{SignableMessageBody, SignedMessage};
5use nym_crypto::asymmetric::ed25519;
6use serde::{Deserialize, Serialize};
7use std::time::Duration;
8use utoipa::ToSchema;
9
10#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
11pub struct ApiHealthResponse {
12    pub status: ApiStatus,
13    #[serde(default)]
14    pub chain_status: ChainStatus,
15    pub uptime: u64,
16}
17
18#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
19#[serde(rename_all = "lowercase")]
20pub enum ApiStatus {
21    Up,
22}
23
24#[derive(Clone, Copy, Debug, Serialize, Deserialize, Default, schemars::JsonSchema, ToSchema)]
25#[serde(rename_all = "snake_case")]
26pub enum ChainStatus {
27    Synced,
28    #[default]
29    Unknown,
30    Stalled {
31        #[serde(
32            serialize_with = "humantime_serde::serialize",
33            deserialize_with = "humantime_serde::deserialize"
34        )]
35        approximate_amount: Duration,
36    },
37}
38
39impl ChainStatus {
40    pub fn is_synced(&self) -> bool {
41        matches!(self, ChainStatus::Synced)
42    }
43}
44
45impl ApiHealthResponse {
46    pub fn new_healthy(uptime: Duration) -> Self {
47        ApiHealthResponse {
48            status: ApiStatus::Up,
49            chain_status: ChainStatus::Synced,
50            uptime: uptime.as_secs(),
51        }
52    }
53}
54
55impl ApiStatus {
56    pub fn is_up(&self) -> bool {
57        matches!(self, ApiStatus::Up)
58    }
59}
60
61#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
62pub struct SignerInformationResponse {
63    pub cosmos_address: String,
64
65    pub identity: String,
66
67    pub announce_address: String,
68
69    pub verification_key: Option<String>,
70}
71
72// we only allow json and yaml responses so we can easily add additional fields later
73#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
74#[serde(rename_all = "camelCase")]
75pub struct ApiInformationResponse {
76    #[schema(value_type = String)]
77    #[serde(with = "ed25519::bs58_ed25519_pubkey")]
78    pub identity: ed25519::PublicKey,
79}
80
81#[derive(Clone, Copy, Debug, Serialize, Deserialize, ToSchema)]
82#[serde(rename_all = "camelCase")]
83pub struct KeyPossessionChallenge {
84    pub nonce: [u8; 32],
85}
86
87#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
88#[serde(rename_all = "camelCase")]
89pub struct KeyPossessionChallengePlaintext {
90    version: u8,
91
92    #[serde(flatten)]
93    challenge: KeyPossessionChallenge,
94
95    purpose: &'static str,
96}
97
98impl KeyPossessionChallenge {
99    pub fn sign(&self, key: &ed25519::PrivateKey) -> KeyPossessionChallengeResponse {
100        self.plaintext_message().sign(key)
101    }
102
103    #[allow(clippy::expect_used)]
104    pub fn plaintext_message(&self) -> KeyPossessionChallengePlaintext {
105        KeyPossessionChallengePlaintext {
106            version: 1,
107            challenge: *self,
108            purpose: "key-possession-challenge",
109        }
110    }
111}
112
113pub type KeyPossessionChallengeResponse = SignedMessage<KeyPossessionChallengePlaintext>;