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