# Building and sideloading Keysat This repo ships three components that you'll bundle into a single installable `.s9pk`: - `licensing-service/` — the Rust daemon (`keysat` binary). - `licensing-service-startos/` — the StartOS 0.4.0.x wrapper (TypeScript manifest + actions + Dockerfile). - `licensing-client-rust/` and `licensing-client-ts/` — SDKs for downstream software. Not bundled into the `.s9pk`; published separately when you cut a release. The Rust service's on-disk folder name is still `licensing-service/` for continuity, but the crate, binary, and operator-visible branding are all **Keysat** now. ## Prerequisites 1. A working **StartOS 0.4.0.x development environment** on a Linux or macOS workstation. Follow [docs.start9.com](https://docs.start9.com) if you haven't set this up yet. 2. `start-cli` installed on your PATH, with `~/.startos/developer.key.pem` initialised (`start-cli init`). 3. **Node 20+** (for the StartOS SDK, TypeScript). 4. **Docker + buildx** (for multi-arch image builds). 5. Network reachability from your workstation to your Start9 server (LAN or Tor — whatever you usually use to `start-cli install`). 6. A running **BTCPay Server** on the same Start9 server (Keysat depends on it). You do **not** need Rust locally — the Dockerfile pulls a pinned `rust:1.75-slim-bookworm` image. ## One-time setup ### 1. Fetch the shared build logic Every 0.4.0.x wrapper includes `s9pk.mk`, which is maintained by the Start9 team. Fetch the current copy once: ```bash cd licensing-service-startos curl -o s9pk.mk https://raw.githubusercontent.com/Start9Labs/hello-world-startos/master/s9pk.mk ``` The `Makefile` `include s9pk.mk` line will error out until that file is in place. ### 2. Install TypeScript deps ```bash cd licensing-service-startos npm install ``` ## Building From `licensing-service-startos/`: ```bash # Build for all supported architectures (x86_64 + aarch64) make # Or just the architecture your Start9 box runs make arm # Raspberry Pi / Apple Silicon make x86 # x86_64 StartOS server ``` The resulting artifact lands in `licensing-service-startos/*.s9pk` — a single file you can sideload. ## Sideloading ```bash cd licensing-service-startos make install ``` This uses your `~/.startos/developer.key.pem` to push the package to the Start9 server it's registered against. First-run prompts for the Start9 dashboard password; subsequent installs reuse the cached session. If you prefer to upload the `.s9pk` through the StartOS dashboard UI, copy the file off your workstation and drag it into **Sideload package** from the dashboard. ## First-boot checklist Once installed, open **Keysat** in your StartOS dashboard and run these actions in order: 1. **Set operator name** — your display name, shown on the public homepage. 2. **Connect BTCPay** — opens a BTCPay consent page in your browser. Click Authorize; Keysat auto-detects your store and registers its inbound webhook. 3. **Check BTCPay connection** — confirms the authorize completed and the webhook is live. 4. **Create product** — one per thing you plan to sell. 5. **Create policy** — at least one per product, slugged `default`. Sets the shape of keys issued through the public purchase flow. At this point your buyers can `POST /v1/purchase` against your Keysat URL, pay via BTCPay, and poll back for their license key. ## Testing it end-to-end Keysat ships with a cross-check test suite that independently signs license keys with a Python reference implementation and replays them through the Rust and TypeScript SDK parsers. See `tests/crosscheck/README.md`. The simplest smoke test against a live install: ```bash # On your workstation, once the service is running on StartOS: curl https:///v1/pubkey curl https:///healthz ``` The first returns the Ed25519 public key you'll bake into downstream software. The second should just return `{"ok":true}`. ## Troubleshooting - **"KEYSAT_ADMIN_API_KEY must be at least 32 characters"** — shouldn't happen from StartOS (the wrapper generates the key), but if you're running locally, `openssl rand -hex 32` gives a valid value. - **"BTCPay not yet configured — purchases will return 503"** — run **Connect BTCPay** from the StartOS dashboard. - **Rebuilds don't reflect Rust source changes** — Docker layer caching is aggressive; `make clean` before `make` to force a full rebuild. - **Existing installs using `LICENSING_*` env vars** — the daemon still reads those as a fallback for one release cycle. New installs set `KEYSAT_*` directly.