use crate::{GAS_PRICE_AMOUNT, mainnet};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use url::Url;
#[cfg(feature = "env")]
use crate::var_names;
#[cfg(feature = "env")]
use std::env::var;
#[cfg(feature = "env")]
use std::ffi::OsStr;
pub mod v1;
pub mod v2;
pub type NymNetworkDetails = v2::NymNetworkDetails;
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ChainDetails {
pub bech32_account_prefix: String,
pub mix_denom: DenomDetailsOwned,
pub stake_denom: DenomDetailsOwned,
}
impl ChainDetails {
pub fn mainnet() -> Self {
ChainDetails {
bech32_account_prefix: mainnet::BECH32_PREFIX.into(),
mix_denom: mainnet::MIX_DENOM.into(),
stake_denom: mainnet::STAKE_DENOM.into(),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct NymContracts {
pub mixnet_contract_address: Option<String>,
pub vesting_contract_address: Option<String>,
#[serde(default)]
pub performance_contract_address: Option<String>,
#[serde(default)]
pub network_monitors_contract_address: Option<String>,
#[serde(default)]
pub node_families_contract_address: Option<String>,
#[serde(default)]
pub directory_contract_address: Option<String>,
#[serde(default)]
pub geolocation_contract_address: Option<String>,
pub ecash_contract_address: Option<String>,
pub group_contract_address: Option<String>,
pub multisig_contract_address: Option<String>,
pub coconut_dkg_contract_address: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ApiUrl {
pub url: String,
pub front_hosts: Option<Vec<String>>,
}
impl From<Url> for ApiUrl {
fn from(value: Url) -> Self {
ApiUrl {
url: value.to_string(),
front_hosts: None,
}
}
}
#[derive(Copy, Clone, Debug, Serialize)]
pub struct ApiUrlConst<'a> {
pub url: &'a str,
pub front_hosts: Option<&'a [&'a str]>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ContractAttestationSource {
pub api_url: String,
pub identity_ed25519_bs58: String,
}
#[derive(Copy, Clone, Debug, Serialize)]
pub struct ContractAttestationSourceConst<'a> {
pub api_url: &'a str,
pub identity_ed25519_bs58: &'a str,
}
impl From<ContractAttestationSourceConst<'_>> for ContractAttestationSource {
fn from(value: ContractAttestationSourceConst) -> Self {
ContractAttestationSource {
api_url: value.api_url.into(),
identity_ed25519_bs58: value.identity_ed25519_bs58.into(),
}
}
}
pub fn default_contract_attestation_sources() -> Vec<ContractAttestationSource> {
#[cfg(feature = "env")]
{
if crate::env_configured() {
return json_deserialise_env(var_names::DIRECTORY_ATTESTATION_SOURCES)
.unwrap_or_default();
}
}
mainnet::CONTRACT_ATTESTATION_SOURCES
.iter()
.map(|i| (*i).into())
.collect()
}
#[cfg(feature = "env")]
pub(crate) fn json_serialise<T>(data: &T) -> String
where
T: ?Sized + serde::Serialize,
{
serde_json::to_string(data)
.inspect_err(|e| tracing::warn!("failed to serialise data for env: {e}"))
.unwrap_or_default()
}
#[cfg(feature = "env")]
pub(crate) fn json_deserialise_env<T>(k: impl AsRef<OsStr>) -> Option<T>
where
T: serde::de::DeserializeOwned,
{
let raw = var(k).ok()?;
serde_json::from_str(&raw)
.inspect_err(|e| tracing::warn!("failed to parse data from env \"{raw:?}\": {e}"))
.ok()
}
impl From<ApiUrlConst<'_>> for ApiUrl {
fn from(value: ApiUrlConst) -> Self {
ApiUrl {
url: value.url.to_string(),
front_hosts: value
.front_hosts
.map(|slice| slice.iter().map(|s| s.to_string()).collect()),
}
}
}
#[derive(Debug, Copy, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct DenomDetails {
pub base: &'static str,
pub display: &'static str,
pub display_exponent: u32,
}
impl DenomDetails {
pub const fn new(base: &'static str, display: &'static str, display_exponent: u32) -> Self {
DenomDetails {
base,
display,
display_exponent,
}
}
}
#[derive(Debug, Serialize, Deserialize, Hash, Clone, PartialEq, Eq, JsonSchema)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct DenomDetailsOwned {
pub base: String,
pub display: String,
pub display_exponent: u32,
}
impl From<DenomDetails> for DenomDetailsOwned {
fn from(details: DenomDetails) -> Self {
DenomDetailsOwned {
base: details.base.to_owned(),
display: details.display.to_owned(),
display_exponent: details.display_exponent,
}
}
}
impl DenomDetailsOwned {
pub fn base_only(base: String) -> Self {
DenomDetailsOwned {
base: base.clone(),
display: base,
display_exponent: 0,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ValidatorDetails {
pub nyxd_url: String,
pub websocket_url: Option<String>,
pub api_url: Option<String>,
}
impl ValidatorDetails {
pub fn new<S: Into<String>>(nyxd_url: S, api_url: Option<S>, websocket_url: Option<S>) -> Self {
ValidatorDetails {
nyxd_url: nyxd_url.into(),
websocket_url: websocket_url.map(Into::into),
api_url: api_url.map(Into::into),
}
}
pub fn new_nyxd_only<S: Into<String>>(nyxd_url: S) -> Self {
ValidatorDetails {
nyxd_url: nyxd_url.into(),
websocket_url: None,
api_url: None,
}
}
pub fn nyxd_url(&self) -> Url {
self.nyxd_url
.parse()
.expect("the provided nyxd url is invalid!")
}
pub fn api_url(&self) -> Option<Url> {
self.api_url
.as_ref()
.map(|url| url.parse().expect("the provided api url is invalid!"))
}
pub fn websocket_url(&self) -> Option<Url> {
self.websocket_url
.as_ref()
.map(|url| url.parse().expect("the provided websocket url is invalid!"))
}
}