use crate::{
directory,
types::{Endpoint, MescError, RpcConfig},
MultiEndpointQuery, TryIntoChainId,
};
use std::collections::HashMap;
pub fn get_default_endpoint(
config: &RpcConfig,
profile: Option<&str>,
) -> Result<Option<Endpoint>, MescError> {
if let Some(profile) = profile {
if let Some(profile_data) = config.profiles.get(profile) {
if !profile_data.use_mesc {
return Ok(None);
}
if let Some(endpoint_name) = profile_data.default_endpoint.as_deref() {
return get_endpoint_by_name(config, endpoint_name);
}
}
};
match &config.default_endpoint {
Some(name) => get_endpoint_by_name(config, name.as_str()),
None => Ok(None),
}
}
pub fn get_endpoint_by_network<T: TryIntoChainId + std::fmt::Debug + std::clone::Clone>(
config: &RpcConfig,
chain_id: T,
profile: Option<&str>,
) -> Result<Option<Endpoint>, MescError> {
let chain_id = chain_id.try_into_chain_id()?;
if let Some(profile) = profile {
if let Some(profile_data) = config.profiles.get(profile) {
if !profile_data.use_mesc {
return Ok(None);
}
if let Some(endpoint_name) = profile_data.network_defaults.get(&chain_id) {
return get_endpoint_by_name(config, endpoint_name);
}
}
};
match config.network_defaults.get(&chain_id) {
Some(name) => get_endpoint_by_name(config, name.as_str()),
None => Ok(None),
}
}
pub fn get_endpoint_by_name(config: &RpcConfig, name: &str) -> Result<Option<Endpoint>, MescError> {
if let Some(endpoint) = config.endpoints.get(name) {
Ok(Some(endpoint.clone()))
} else {
Err(MescError::MissingEndpoint(name.to_string()))
}
}
pub fn get_endpoint_by_query(
config: &RpcConfig,
query: &str,
profile: Option<&str>,
) -> Result<Option<Endpoint>, MescError> {
if let Some(profile) = profile {
if let Some(profile_data) = config.profiles.get(profile) {
if !profile_data.use_mesc {
return Ok(None);
}
}
}
if let Some(endpoint) = config.endpoints.get(query) {
return Ok(Some(endpoint.clone()));
}
if let Ok(chain_id) = query.try_into_chain_id() {
if let Ok(Some(endpoint)) = get_endpoint_by_network(config, chain_id, profile) {
return Ok(Some(endpoint));
}
}
if let Some(chain_id) = config.network_names.get(query) {
return get_endpoint_by_network(config, chain_id.clone(), profile);
} else if let Some(chain_id) = directory::get_network_chain_id(query) {
return get_endpoint_by_network(config, chain_id.clone(), profile);
}
Ok(None)
}
pub fn find_endpoints(
config: &RpcConfig,
query: MultiEndpointQuery,
) -> Result<Vec<Endpoint>, MescError> {
let mut candidates: Vec<Endpoint> = config.endpoints.clone().into_values().collect();
if let Some(chain_id) = query.chain_id {
candidates.retain(|endpoint| endpoint.chain_id.as_ref() == Some(&chain_id));
}
if let Some(name) = query.name_contains {
candidates.retain(|endpoint| endpoint.name.contains(&name))
}
if let Some(url) = query.url_contains {
candidates.retain(|endpoint| endpoint.url.contains(&url))
}
Ok(candidates)
}
pub fn get_global_metadata(
config: &RpcConfig,
profile: Option<&str>,
) -> Result<HashMap<String, serde_json::Value>, MescError> {
let mut metadata = config.global_metadata.clone();
if let Some(profile) = profile {
if let Some(profile_data) = config.profiles.get(profile) {
if !profile_data.use_mesc {
return Ok(HashMap::new());
}
metadata.extend(profile_data.profile_metadata.clone())
}
}
Ok(metadata)
}