o402 0.1.3

OpenAI-compatible gateway, paid with x402.
//! OpenAI-compatible HTTP gateway, paid with x402.
//!
//! Load one TOML file, bind `server.bind`, and serve `/health`, `/ready`,
//! `/v1/pricing`, and a billed reverse proxy to an OpenAI-compatible
//! upstream (Bifrost). Chat/completions/embeddings/responses use `upto`;
//! other exported HTTP paths use `exact`. Realtime WebSocket and admin
//! paths are rejected.
//!
//! Default features are `evm` + `svm`. Production extras (`near`, `xrpl`,
//! `hedera`, `avm`, `aptos`, `keeta`, `tvm`, `stellar`, `concordium`) are
//! behind `full`. `experimental-tron` is opt-in and is **not** in `full`.

mod cmd;
mod config;
mod error;
mod http;
mod obs;
mod payment;
mod proxy;
mod shutdown;
mod state;

pub use config::{Config, ConfigError};
pub use error::AppError;

/// Process entry used by the `o402` binary: `init` or `serve`.
///
/// # Errors
///
/// Returns [`AppError`] from the selected subcommand.
pub async fn run() -> Result<(), AppError> {
    cmd::run().await
}

/// Serve HTTP on `config.server.bind` until SIGINT/SIGTERM.
///
/// # Errors
///
/// Returns [`AppError`] if bind or the server IO loop fails.
pub async fn serve(config: Config) -> Result<(), AppError> {
    cmd::serve::listen(config).await
}

#[cfg(test)]
mod tests {
    #[test]
    fn crate_loads() {
        assert_eq!(
            env!("CARGO_PKG_NAME"),
            "o402",
            "package name must match the crate directory"
        );
    }
}