cat_gateway/service/utilities/
mod.rs

1//! `API` Utility operations
2pub(crate) mod catch_panic;
3pub(crate) mod convert;
4pub(crate) mod health;
5pub(crate) mod middleware;
6pub(crate) mod net;
7
8use anyhow::{bail, Result};
9// use pallas::ledger::addresses::Network as PallasNetwork;
10// use poem_openapi::types::ToJSON;
11
12// use crate::service::common::objects::cardano::network::Network;
13
14/// Convert bytes to hex string with the `0x` prefix
15pub(crate) fn as_hex_string(bytes: &[u8]) -> String {
16    format!("0x{}", hex::encode(bytes))
17}
18
19/// Convert bytes to hex string with the `0x` prefix
20pub(crate) fn from_hex_string(hex: &str) -> Result<Vec<u8>> {
21    #[allow(clippy::string_slice)] // Safe because of size checks.
22    if hex.len() < 4 || hex.len() % 2 != 0 || &hex[0..2] != "0x" {
23        bail!("Invalid hex string");
24    }
25
26    #[allow(clippy::string_slice)] // Safe due to above checks.
27    Ok(hex::decode(&hex[2..])?)
28}
29
30/// Unused
31const _UNUSED: &str = r#"
32/// Network validation error
33#[derive(thiserror::Error, Debug)]
34pub(crate) enum NetworkValidationError {
35    /// Provided network type does not match stake address
36    #[error("Provided network type {0} does not match stake address network type {1}")]
37    NetworkMismatch(String, String),
38    /// Unknown address network type
39    #[error("Unknown address network type {0}")]
40    UnknownNetwork(u8),
41}
42
43/// Check the provided network type with the encoded inside the stake address
44pub(crate) fn check_network(
45    address_network: PallasNetwork, provided_network: Option<Network>,
46) -> anyhow::Result<Network> {
47    match address_network {
48        PallasNetwork::Mainnet => {
49            if let Some(network) = provided_network {
50                if !matches!(&network, Network::Mainnet) {
51                    return Err(NetworkValidationError::NetworkMismatch(
52                        network.to_json_string(),
53                        "Mainnet".to_string(),
54                    )
55                    .into());
56                }
57            }
58            Ok(Network::Mainnet)
59        },
60        PallasNetwork::Testnet => {
61            // the preprod and preview network types are encoded as `testnet` in the stake
62            // address, so here we are checking if the `provided_network` type matches the
63            // one, and if not - we return an error.
64            // if the `provided_network` omitted - we return the `testnet` network type
65            if let Some(network) = provided_network {
66                if !matches!(network, Network::Preprod | Network::Preview) {
67                    return Err(NetworkValidationError::NetworkMismatch(
68                        network.to_json_string(),
69                        "Testnet".to_string(),
70                    )
71                    .into());
72                }
73                Ok(network)
74            } else {
75                Ok(Network::Preprod)
76            }
77        },
78        PallasNetwork::Other(x) => Err(NetworkValidationError::UnknownNetwork(x).into()),
79    }
80}
81"#;