Docs sweep: align install / integrate / operate / pricing / wire-format

Five-page sweep to match the current daemon state.

install.html:
- Step 6 (first product): "Price (sats)" → reflects the
  currency picker (sats / USD / EUR) shipped in migration 0010.
- Step 7 (first policy): drop the "default slug is consumed by
  public flow" myth — buy page renders a tier picker for any
  product with ≥2 public policies. Add references to entitlements
  catalog, hide-on-buy toggles, marketing bullets, recurring
  subscriptions, and the drag-to-reorder policy grid.

integrate.html:
- "Three official SDKs" → "Four official SDKs" + Go tab + install
  snippet. Notes the daemon's cross-check fixtures assert
  byte-for-byte parity across all four.
- Admin API table: drop "by npub" from the licenses search
  description (backend supports it; UI hasn't surfaced it yet
  since the purchase flow doesn't capture npubs).

operate.html:
- Backups section: drop the imaginary `/data/issuer-key.pem`
  file — the signing keypair lives in the `server_keys` SQLite
  table, not in a PEM file on disk. Mention the self-license
  file path (`/data/keysat-license.txt`).
- Rotation: drop the "v0.1 doesn't support / v0.2 will" framing;
  rotation isn't on the v0.2 / v0.3 roadmap and the v0.1 caveat
  is misleading. Update steps to reflect SQLite-as-keystore.
- Webhook troubleshooting: point at the dedicated
  Webhooks → Failed (DLQ) view rather than the audit log.

pricing.html:
- Creator: 21,000 sats one-time → Free forever (matches actual
  master Keysat configuration).
- Pro: 250,000 sats/yr → 100,000 sats/yr (recurring). Note
  recurring + tier upgrades have shipped; only Zaprite remains
  v0.3.
- Patron: 500,000 sats/yr → 250,000 sats one-time perpetual.
  Differentiation rewritten: perpetual license + direct 1:1
  support (not just "Pro with a badge").
- Active discount-code cap: 5 → 10 (real cap).
- New "Prices shown are a snapshot" note pointing at the
  canonical live source (keysat.xyz#tiers + the buy page).
- Updated unlicensed-caps line to show 5/5/10 with units.

wire-format.html:
- Replace the entirely-fabricated "KS-base32-blob with KSAT magic
  bytes" layout with the actual LIC1 envelope:
  `LIC1-<base32 payload>-<base32 signature>` split on dashes.
- Document BOTH payload versions: v1 (legacy 74-byte fixed) and
  v2 (current default, 83-byte head + variable entitlements
  table). Field offsets, flag bits, signature scope all match
  the daemon source.
- Drop the bogus Crockford-base32 + dash-grouping sections —
  the daemon uses RFC 4648 base32 with single-dash structure
  separators, not grouped-dashes for readability.
- Drop the fabricated hex-dump worked example.
- Porting section now points at `licensing-service/tests/crosscheck/`
  (the actual fixtures location) instead of a Python-SDK path.
- Versioning policy: clarify envelope-tag vs payload-version
  cadence.
This commit is contained in:
Keysat
2026-05-11 19:30:47 -05:00
parent 95a11666d7
commit 23aa121afb
5 changed files with 117 additions and 105 deletions
+7 -2
View File
@@ -58,12 +58,13 @@
</ul>
<h2 id="sdks">Pick an SDK</h2>
<p>Three official SDKs ship today. They are wire-compatible &mdash; a license issued by your Keysat verifies identically in any of them.</p>
<p>Four official SDKs ship today. They are wire-compatible &mdash; a license issued by your Keysat verifies identically in any of them. Cross-check fixtures in the daemon repo prove each SDK accepts the same bytes the daemon mints.</p>
<div class="lang-tabs" role="tablist">
<button class="active" data-lang="ts">TypeScript</button>
<button data-lang="rs">Rust</button>
<button data-lang="py">Python</button>
<button data-lang="go">Go</button>
</div>
<pre class="code lang-pane" data-lang="ts"><span class="c"># npm</span>
@@ -79,6 +80,10 @@ pip install keysat-licensing-client
<span class="c"># or with poetry</span>
poetry add keysat-licensing-client</pre>
<pre class="code lang-pane" data-lang="go" style="display:none"><span class="c">// go.mod</span>
go get github.com/keysat-xyz/keysat-client-go
<span class="c">// stdlib only — no third-party Go dependencies</span></pre>
<p>If your language isn&rsquo;t covered, see <a href="wire-format.html">Wire format</a>. The format is small and porting takes about an afternoon.</p>
@@ -235,7 +240,7 @@ result = verifier.<span class="f">verify</span>(license_key_from_user)
<tr><td><code>POST</code></td><td><code>/v1/admin/products</code></td><td>Create a product.</td></tr>
<tr><td><code>POST</code></td><td><code>/v1/admin/policies</code></td><td>Create a policy.</td></tr>
<tr><td><code>POST</code></td><td><code>/v1/admin/discount-codes</code></td><td>Create a discount or comp code.</td></tr>
<tr><td><code>GET</code></td><td><code>/v1/admin/licenses/search</code></td><td>Find licenses by email, npub, or invoice.</td></tr>
<tr><td><code>GET</code></td><td><code>/v1/admin/licenses</code></td><td>List / search licenses by buyer email or BTCPay invoice id. (Backend also supports npub search; the buyer-side npub capture flow is still in progress.)</td></tr>
<tr><td><code>POST</code></td><td><code>/v1/admin/licenses/&lt;id&gt;/revoke</code></td><td>Revoke a license.</td></tr>
<tr><td><code>POST</code></td><td><code>/v1/admin/webhook-endpoints</code></td><td>Register an outbound webhook.</td></tr>
<tr><td><code>GET</code></td><td><code>/v1/admin/audit</code></td><td>Read audit log.</td></tr>