---
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).
