use std::collections::BTreeMap;
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use fedimint_core::admin_client::GuardianConfigBackup;
use fedimint_core::bitcoin::Network;
use fedimint_core::core::ModuleKind;
use fedimint_core::module::ApiAuth;
use fedimint_core::module::audit::AuditSummary;
use fedimint_core::net::auth::GuardianAuthToken;
use fedimint_core::session_outcome::SessionStatusV2;
use fedimint_core::util::SafeUrl;
use fedimint_core::{Feerate, PeerId};
use serde::{Deserialize, Serialize};
use crate::{DynServerModule, ServerModule};
pub type DynDashboardApi = Arc<dyn IDashboardApi + Send + Sync + 'static>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConnectionType {
Direct,
Relay,
Mixed,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct P2PConnectionStatus {
pub conn_type: Option<ConnectionType>,
pub rtt: Option<Duration>,
}
#[async_trait]
pub trait IDashboardApi {
async fn auth(&self) -> ApiAuth;
async fn guardian_id(&self) -> PeerId;
async fn guardian_names(&self) -> BTreeMap<PeerId, String>;
async fn federation_name(&self) -> String;
async fn session_count(&self) -> u64;
async fn get_session_status(&self, session_idx: u64) -> SessionStatusV2;
async fn consensus_ord_latency(&self) -> Option<Duration>;
async fn p2p_connection_status(&self) -> BTreeMap<PeerId, Option<P2PConnectionStatus>>;
async fn federation_invite_code(&self) -> String;
async fn federation_audit(&self) -> AuditSummary;
async fn bitcoin_rpc_url(&self) -> SafeUrl;
async fn bitcoin_rpc_status(&self) -> Option<ServerBitcoinRpcStatus>;
async fn download_guardian_config_backup(
&self,
password: &str,
guardian_auth: &GuardianAuthToken,
) -> GuardianConfigBackup;
fn get_module_by_kind(&self, kind: ModuleKind) -> Option<&DynServerModule>;
async fn fedimintd_version(&self) -> String;
async fn change_password(
&self,
new_password: &str,
current_password: &str,
guardian_auth: &GuardianAuthToken,
) -> Result<(), String>;
fn into_dyn(self) -> DynDashboardApi
where
Self: Sized + Send + Sync + 'static,
{
Arc::new(self)
}
}
pub trait DashboardApiModuleExt {
fn get_module<M: ServerModule + 'static>(&self) -> Option<&M>;
}
impl DashboardApiModuleExt for DynDashboardApi {
fn get_module<M: ServerModule + 'static>(&self) -> Option<&M> {
self.get_module_by_kind(M::module_kind())?
.as_any()
.downcast_ref::<M>()
}
}
#[derive(Debug, Clone)]
pub struct ServerBitcoinRpcStatus {
pub network: Network,
pub block_count: u64,
pub fee_rate: Feerate,
pub sync_progress: Option<f64>,
}