use std::{borrow::Cow, time::Duration};
use om_primitives_types::core::{chain::NamedChain, types::ChainId};
pub const MAINNET_URL: &str = "https://api.mainnet.1money.network";
pub const TESTNET_URL: &str = "https://api.testnet.1money.network";
pub const LOCAL_URL: &str = "http://127.0.0.1:18555";
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
pub const API_VERSION: &str = "/v1";
pub fn api_path(path: &str) -> String {
format!("{}{}", API_VERSION, path)
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum Network {
#[default]
Mainnet,
Testnet,
Local,
Custom(Cow<'static, str>),
}
impl Network {
pub fn url(&self) -> &str {
match self {
Network::Mainnet => MAINNET_URL,
Network::Testnet => TESTNET_URL,
Network::Local => LOCAL_URL,
Network::Custom(s) => s,
}
}
pub const fn chain_id(&self) -> Option<ChainId> {
match self {
Network::Mainnet => Some(NamedChain::MAINNET_CHAIN_ID),
Network::Testnet => Some(NamedChain::TESTNET_CHAIN_ID),
Network::Local => Some(NamedChain::TESTNET_CHAIN_ID),
Network::Custom(_) => {
None
}
}
}
pub fn is_production(&self) -> bool {
matches!(self, Network::Mainnet)
}
pub fn is_test(&self) -> bool {
!self.is_production()
}
}
pub mod endpoints {
pub mod accounts {
pub const NONCE: &str = "/accounts/nonce";
pub const BBNONCE: &str = "/accounts/bbnonce";
pub const TOKEN_ACCOUNT: &str = "/accounts/token_account";
}
pub mod chains {
pub const CHAIN_ID: &str = "/chains/chain_id";
}
pub mod checkpoints {
pub const NUMBER: &str = "/checkpoints/number";
pub const BY_NUMBER: &str = "/checkpoints/by_number";
pub const BY_HASH: &str = "/checkpoints/by_hash";
}
pub mod transactions {
pub const PAYMENT: &str = "/transactions/payment";
pub const RAW: &str = "/transactions/raw";
pub const BY_HASH: &str = "/transactions/by_hash";
pub const RECEIPT_BY_HASH: &str = "/transactions/receipt/by_hash";
pub const ESTIMATE_FEE: &str = "/transactions/estimate_fee";
pub const FINALIZED_BY_HASH: &str = "/transactions/finalized/by_hash";
}
pub mod tokens {
pub const MINT: &str = "/tokens/mint";
pub const BURN: &str = "/tokens/burn";
pub const GRANT_AUTHORITY: &str = "/tokens/grant_authority";
pub const UPDATE_METADATA: &str = "/tokens/update_metadata";
pub const MANAGE_BLACKLIST: &str = "/tokens/manage_blacklist";
pub const MANAGE_WHITELIST: &str = "/tokens/manage_whitelist";
pub const PAUSE: &str = "/tokens/pause";
pub const TOKEN_METADATA: &str = "/tokens/token_metadata";
}
pub mod governance {
pub const CURRENT_EPOCH: &str = "/governances/epoch";
pub const EPOCH_BY_ID: &str = "/governances/epoch/by_id";
}
#[cfg(feature = "bridge")]
pub mod bridge {
pub const BRIDGE_AND_MINT: &str = "/tokens/bridge_and_mint";
pub const BURN_AND_BRIDGE: &str = "/tokens/burn_and_bridge";
}
}
#[cfg(test)]
mod tests {
use om_primitives_types::core::chain::ChainSpec;
use super::*;
#[test]
fn test_network_urls() {
assert_eq!(Network::Mainnet.url(), "https://api.mainnet.1money.network");
assert_eq!(Network::Testnet.url(), "https://api.testnet.1money.network");
assert_eq!(Network::Local.url(), "http://127.0.0.1:18555");
}
#[test]
fn test_network_properties() {
assert!(Network::Mainnet.is_production());
assert!(!Network::Testnet.is_production());
assert!(!Network::Local.is_production());
assert!(!Network::Mainnet.is_test());
assert!(Network::Testnet.is_test());
assert!(Network::Local.is_test());
}
#[test]
fn test_api_path_construction() {
let path = api_path("/test");
assert_eq!(path, "/v1/test");
assert!(path.contains("/v1/test"));
let path_with_slash = api_path("/accounts/nonce");
assert_eq!(path_with_slash, "/v1/accounts/nonce");
let path_without_slash = api_path("chains/chain_id");
assert_eq!(path_without_slash, "/v1chains/chain_id");
}
#[test]
fn test_endpoint_constants() {
assert_eq!(endpoints::accounts::NONCE, "/accounts/nonce");
assert_eq!(endpoints::accounts::BBNONCE, "/accounts/bbnonce");
assert_eq!(endpoints::accounts::TOKEN_ACCOUNT, "/accounts/token_account");
assert_eq!(endpoints::chains::CHAIN_ID, "/chains/chain_id");
assert_eq!(endpoints::checkpoints::NUMBER, "/checkpoints/number");
assert_eq!(endpoints::checkpoints::BY_NUMBER, "/checkpoints/by_number");
assert_eq!(endpoints::checkpoints::BY_HASH, "/checkpoints/by_hash");
assert_eq!(endpoints::transactions::PAYMENT, "/transactions/payment");
assert_eq!(endpoints::transactions::RAW, "/transactions/raw");
assert_eq!(endpoints::transactions::BY_HASH, "/transactions/by_hash");
assert_eq!(
endpoints::transactions::RECEIPT_BY_HASH,
"/transactions/receipt/by_hash"
);
assert_eq!(endpoints::transactions::ESTIMATE_FEE, "/transactions/estimate_fee");
assert_eq!(endpoints::tokens::MINT, "/tokens/mint");
assert_eq!(endpoints::tokens::BURN, "/tokens/burn");
assert_eq!(endpoints::tokens::GRANT_AUTHORITY, "/tokens/grant_authority");
assert_eq!(endpoints::tokens::UPDATE_METADATA, "/tokens/update_metadata");
assert_eq!(endpoints::tokens::MANAGE_BLACKLIST, "/tokens/manage_blacklist");
assert_eq!(endpoints::tokens::MANAGE_WHITELIST, "/tokens/manage_whitelist");
assert_eq!(endpoints::tokens::PAUSE, "/tokens/pause");
assert_eq!(endpoints::tokens::TOKEN_METADATA, "/tokens/token_metadata");
assert_eq!(endpoints::governance::CURRENT_EPOCH, "/governances/epoch");
assert_eq!(endpoints::governance::EPOCH_BY_ID, "/governances/epoch/by_id");
}
#[test]
fn test_network_default() {
let default_network = Network::default();
assert_eq!(default_network, Network::Mainnet);
}
#[test]
fn test_network_chain_ids() {
assert_eq!(Network::Mainnet.chain_id(), Some(ChainSpec::MAINNET.chain_id()));
assert_eq!(Network::Testnet.chain_id(), Some(ChainSpec::TESTNET.chain_id()));
assert_eq!(Network::Local.chain_id(), Some(ChainSpec::TESTNET.chain_id()));
}
#[test]
fn test_predefined_chain_id_panics_for_custom() {
let n = Network::Custom("http://localhost:18555".into());
assert_eq!(None, n.chain_id());
}
#[test]
fn test_constants() {
assert_eq!(API_VERSION, "/v1");
assert_eq!(DEFAULT_TIMEOUT, Duration::from_secs(30));
assert!(MAINNET_URL.starts_with("https://"));
assert!(TESTNET_URL.starts_with("https://"));
assert!(LOCAL_URL.starts_with("http://"));
}
}