use actix_web::{web, App, HttpServer, middleware::Logger}; use clap::Parser; use log::info; use std::sync::Arc; mod config; mod error; mod proxy; mod types; mod webhook; mod websocket; use config::Config; use proxy::ProxyState; #[derive(Parser)] #[command(name = "hero-http-proxy")] #[command(about = "HTTP proxy server for converting webhooks to WebSocket JSON-RPC calls")] struct Args { /// HTTP server port #[arg(short, long, default_value = "8080")] port: u16, /// WebSocket server URL #[arg(short, long, default_value = "ws://localhost:3030")] websocket_url: String, /// Configuration file path #[arg(short, long)] config: Option, } #[actix_web::main] async fn main() -> std::io::Result<()> { env_logger::init(); let args = Args::parse(); // Load configuration let config = if let Some(config_path) = args.config { Config::from_file(&config_path).unwrap_or_else(|e| { eprintln!("Failed to load config from {}: {}", config_path, e); std::process::exit(1); }) } else { Config::default() }; let proxy_state = Arc::new(ProxyState::new(args.websocket_url, config)); info!("Starting HTTP proxy server on port {}", args.port); HttpServer::new(move || { App::new() .app_data(web::Data::new(proxy_state.clone())) .wrap(Logger::default()) .service( web::scope("/webhooks") .route("/stripe/{circle_pk}", web::post().to(webhook::handlers::handle_stripe_webhook)) .route("/idenfy/{circle_pk}", web::post().to(webhook::handlers::handle_idenfy_webhook)) ) .route("/health", web::get().to(webhook::handlers::health_check)) }) .bind(("0.0.0.0", args.port))? .run() .await }