--- paths: - "licensing-service-startos/licensing-service/src/**" --- # Daemon architecture (licensing-service/src/) `axum` HTTP service over `sqlx`/SQLite, Ed25519 signing. Request flow: `main.rs` builds the router and spawns the background worker; `api/mod.rs` mounts ~30 route modules (`purchase`, `validate`, `redeem`, `subscriptions`, `upgrade`, `admin*`, plus `webhook*` for inbound provider callbacks). `api/auth.rs` + `session_layer.rs` gate admin/session routes. `AppState` (in `api/mod.rs`) is the shared handle — DB pool, config, the payment-provider resolution layer, and the self-license tier. Module map: - **crypto/** — Ed25519 signing and the LIC1 key byte layout. THE contract the four SDKs implement. See [crypto-wire-format](crypto-wire-format.md). - **payment/**, **merchant_profiles.rs** — provider abstraction over `btcpay` / `zaprite` and the multi-merchant-profile routing model. See [payments](payments.md). - **reconcile.rs / subscriptions.rs / upgrades.rs** — the background worker loop: reconciles payment state, charges recurring subs, processes tier upgrades out of band. - **license_self.rs** — the daemon licenses itself via its own scheme. See [licensing-tiers](licensing-tiers.md). - **db/repo.rs** — all SQLite access. Queries are **runtime-prepared** (`sqlx::query(&format!(...))`), NOT the compile-checked `query!` macro — so bad columns / ambiguous columns surface only when the query executes. Migrations are numbered + additive in `migrations/`. See [testing](testing.md) for why this matters. - **rates.rs / rate_limit.rs / analytics.rs / tipping.rs** — fiat rate lookup, request throttling, opt-in analytics, and Lightning tipping. The embedded admin SPA is a single `web/index.html` (rust-embed). See [admin-ui](admin-ui.md).