mod chain;
mod config;
mod facilitator;
mod facilitator_local;
mod handlers;
mod networks;
mod proto;
mod scheme;
mod timestamp;
mod util;
use axum::Router;
use axum::http::Method;
use dotenvy::dotenv;
use std::net::SocketAddr;
use std::sync::Arc;
use tower_http::cors;
use crate::chain::ChainRegistry;
use crate::config::Config;
use crate::facilitator_local::FacilitatorLocal;
use crate::scheme::{SchemeBlueprints, SchemeRegistry};
use crate::util::{SigDown, Telemetry};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok();
let telemetry = Telemetry::new()
.with_name(env!("CARGO_PKG_NAME"))
.with_version(env!("CARGO_PKG_VERSION"))
.register();
let config = Config::load()?;
let chain_registry = ChainRegistry::from_config(config.chains()).await?;
let scheme_blueprints = SchemeBlueprints::full();
let scheme_registry =
SchemeRegistry::build(chain_registry, scheme_blueprints, config.schemes());
let facilitator = FacilitatorLocal::new(scheme_registry);
let axum_state = Arc::new(facilitator);
let http_endpoints = Router::new()
.merge(handlers::routes().with_state(axum_state))
.layer(telemetry.http_tracing())
.layer(
cors::CorsLayer::new()
.allow_origin(cors::Any)
.allow_methods([Method::GET, Method::POST])
.allow_headers(cors::Any),
);
let addr = SocketAddr::new(config.host(), config.port());
tracing::info!("Starting server at http://{}", addr);
let listener = tokio::net::TcpListener::bind(addr)
.await
.unwrap_or_else(|e| {
tracing::error!("Failed to bind to {}: {}", addr, e);
std::process::exit(1);
});
let sig_down = SigDown::try_new()?;
let axum_cancellation_token = sig_down.cancellation_token();
let axum_graceful_shutdown = async move { axum_cancellation_token.cancelled().await };
axum::serve(listener, http_endpoints)
.with_graceful_shutdown(axum_graceful_shutdown)
.await?;
Ok(())
}