sim-cli 0.6.0

CLI tool for running and comparing Solana simulator backtests
mod compare_cmd;
mod fetch;
mod output;
mod ranges_cmd;
mod run_cmd;
mod signals;
mod subscription;
mod summarize_cmd;
mod update_cmd;
mod usage_cmd;

use clap::{Parser, Subcommand};
use compare_cmd::CompareArgs;
use eyre::Result;
use ranges_cmd::RangesArgs;
use run_cmd::RunArgs;
use signals::spawn_os_signal_handler;
use summarize_cmd::SummarizeArgs;
use tokio_util::sync::CancellationToken;
use usage_cmd::UsageArgs;

/// Simulator CLI
/// Run and compare simulations against historical Solana slots
#[derive(Parser)]
struct Cli {
    /// Simulator endpoint hostname (e.g. staging.simulator.termina.technology)
    #[arg(
        long,
        global = true,
        env = "SIMULATOR_URL",
        default_value = "simulator.termina.technology"
    )]
    url: String,

    /// API key for authentication
    #[arg(long, global = true, env = "SIMULATOR_API_KEY", default_value = "")]
    api_key: String,

    #[command(subcommand)]
    command: Command,
}

#[derive(Subcommand)]
enum Command {
    /// Run a backtest simulation over a slot range
    Run(RunArgs),
    /// Compare two simulation output files (baseline vs experiment)
    Compare(CompareArgs),
    /// Extract and print a summary of a simulation output file
    Summarize(SummarizeArgs),
    /// Update the sim binary to the latest published version
    Update,
    /// List available slot ranges on the simulator server
    Ranges(RangesArgs),
    /// Show API key usage metrics for a time window
    Usage(UsageArgs),
}

#[tokio::main]
async fn main() -> Result<()> {
    let _ = rustls::crypto::aws_lc_rs::default_provider()
        .install_default()
        .map_err(|_| ())
        .ok();

    let cli = Cli::parse();
    let cancellation = CancellationToken::new();
    spawn_os_signal_handler(cancellation.clone());

    match cli.command {
        Command::Run(args) => run_cmd::run(args, cli.url, cli.api_key, cancellation.clone()).await,
        Command::Compare(args) => compare_cmd::compare(args).await,
        Command::Summarize(args) => summarize_cmd::summarize(args),
        Command::Update => update_cmd::update().await,
        Command::Ranges(args) => ranges_cmd::ranges(args, cli.url).await,
        Command::Usage(args) => usage_cmd::usage(args, cli.url, cli.api_key).await,
    }
}