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
+10 -7
View File
@@ -132,21 +132,24 @@ payment_methods: <span class="s">[BTC-OnChain, BTC-LightningNetwork]</span></pre
<li><strong>Slug</strong> &mdash; lowercase, hyphens, will appear in the public URL. e.g. <code>bitcoin-ticker-pro</code>.</li>
<li><strong>Display name</strong> &mdash; shown on the buyer&rsquo;s purchase page and on receipts.</li>
<li><strong>Description</strong> &mdash; one or two sentences; rendered as plain text.</li>
<li><strong>Price (sats)</strong> &mdash; an integer. e.g. <code>50000</code> for ~$30 USD at current rates.</li>
<li><strong>Price</strong> &mdash; the currency picker accepts sats, USD, or EUR. For sats, enter an integer (e.g. <code>50000</code>). For USD/EUR, enter the amount in dollars/euros — Keysat converts to BTC at invoice creation and the buyer pays the locked-in BTC amount.</li>
</ul>
<p>The product is created with no policies attached. Next:</p>
<h2 id="first-policy">Step 7 — Define a default policy</h2>
<p>Go to <strong>Policies &rarr; Create a new policy</strong>. Pick the product, then:</p>
<h2 id="first-policy">Step 7 — Define one or more policies</h2>
<p>Go to <strong>Policies &rarr; Create a new policy</strong>. Pick the product, then fill in:</p>
<ul>
<li>Set <strong>slug</strong> to <code>default</code>. This is the policy consumed by the public purchase flow; other slugs are reserved for manual issuance.</li>
<li>Set <strong>duration_seconds</strong>. Common choices: <code>0</code> (perpetual), <code>31536000</code> (1 year), <code>2592000</code> (30 days for trials).</li>
<li>Set <strong>max_machines</strong>. Use <code>1</code> for single-seat licenses or <code>0</code> for unlimited.</li>
<li>Optionally add <strong>entitlements</strong> &mdash; comma-separated feature flags. These are baked into the signed key and your app reads them at verify time.</li>
<li><strong>Slug</strong> &mdash; lowercase id (e.g. <code>basic</code>, <code>pro</code>, <code>annual</code>). Not "special" in any way; the buy page renders a tier picker when a product has two or more public policies, with the initial tier chosen by <code>?policy=&lt;slug&gt;</code> in the URL, then by the policy you mark "most popular", then by cheapest.</li>
<li><strong>Duration</strong>. Common choices: perpetual, 30 days (trial), 1 year. Recurring subscriptions are a separate toggle on the same form &mdash; flip "Recurring subscription" + set a renewal cadence and Keysat handles the cycle (invoice → settle → re-sign) automatically.</li>
<li><strong>Max devices</strong>. <code>1</code> for single-seat, <code>0</code> for unlimited.</li>
<li><strong>Entitlements</strong> &mdash; pick from the product's catalog (you set up the catalog when you created the product on the previous step). The picked entitlements are baked into the signed license and your app reads them at verify time. Optionally toggle the "hide on buy page" eye icon on any entitlement to drop it from the tier card without un-granting it &mdash; useful for higher tiers that use "Everything in Basic, plus:" marketing copy.</li>
<li><strong>Marketing bullets</strong> (optional) &mdash; operator-authored ✓ items rendered on the tier card alongside the entitlements. Pure marketing copy, not enforced.</li>
</ul>
<p>If you're selling a multi-tier product (e.g. Basic / Pro / Max), repeat this step for each tier. Drag the cards in the Policies grid to set the order shown to buyers.</p>
<h2 id="purchase-url">Step 8 — Share your purchase URL</h2>
<p>Your public purchase URL is now live at:</p>