Docs polish: active-pill sync, license-sidebar bug fix, pricing standardized, ~70 em-dashes removed
- docs.js (new): sync sidebar .active pill with location.hash on load, click, and hashchange so in-page anchor links (Architecture, Discount codes, Backups, etc.) update the pill instead of leaving it stuck on whatever was statically marked - Wire docs.js into every page just before </body> - license.html: sidebar Project/Operate order matches every other page (Project first) - pricing.html: rewritten to use the standard docs layout (full sidebar groups, prose main, breadcrumb) instead of a one-off shell that felt detached from the rest of the docs - Reference section: remove Admin API + SDKs anchor links (they masqueraded as separate pages but just scrolled within integrate.html); Wire format stands alone - Pricing copy: Zaprite reframed as "expanded payment options including card payment capabilities", "shipping in v0.3" removed (it shipped), Patron rephrased as perpetual (never expires or renews) - "Toggling inactive" cap-evasion language replaced — admin UI exposes delete only, no soft-disable affordance for products - ~70 em-dashes removed across 8 pages using a small pattern set (elaboration→period, list-intro→colon, tight clarification→comma, parentheticals→parens). Decorative stamp ornaments and references to actual third-party UI labels are kept verbatim.
This commit is contained in:
+12
-13
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Keysat Docs — Integrate the SDK</title>
|
||||
<title>Keysat Docs: Integrate the SDK</title>
|
||||
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg">
|
||||
<link rel="stylesheet" href="docs.css">
|
||||
</head>
|
||||
@@ -33,8 +33,6 @@
|
||||
<div class="group">
|
||||
<div class="glabel">Reference</div>
|
||||
<a href="wire-format.html">Wire format</a>
|
||||
<a href="integrate.html#api">Admin API</a>
|
||||
<a href="integrate.html#sdks">SDKs</a>
|
||||
</div>
|
||||
<div class="group">
|
||||
<div class="glabel">Project</div>
|
||||
@@ -52,18 +50,18 @@
|
||||
<main class="prose">
|
||||
<div class="crumb">Get started · Integrate the SDK</div>
|
||||
<h1>Integrate the SDK.</h1>
|
||||
<p class="lead">Wire Keysat licenses into your software in under an afternoon. The verifier is pure-function, offline, and ships in five lines. What you do with the result — refuse to start without a license, unlock specific features, just show a "supporter" badge — is your call. The SDK is the primitive; the business model is yours.</p>
|
||||
<p class="lead">Wire Keysat licenses into your software in under an afternoon. The verifier is pure-function, offline, and ships in five lines. What you do with the result (refuse to start without a license, unlock specific features, just show a "supporter" badge) is your call. The SDK is the primitive; the business model is yours.</p>
|
||||
|
||||
<h2 id="prereq">Prerequisites</h2>
|
||||
<p>Before you start, you should have:</p>
|
||||
<ul>
|
||||
<li>A Keysat installation running on your Start9 — see <a href="install.html">Install & setup</a>.</li>
|
||||
<li>BTCPay Server connected to Keysat — ditto.</li>
|
||||
<li>A Keysat installation running on your Start9; see <a href="install.html">Install & setup</a>.</li>
|
||||
<li>BTCPay Server connected to Keysat; ditto.</li>
|
||||
<li>At least one product defined in the admin UI.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="sdks">Pick an SDK</h2>
|
||||
<p>Four official SDKs ship today. They are wire-compatible — 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>
|
||||
<p>Four official SDKs ship today. They are wire-compatible. 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>
|
||||
@@ -88,11 +86,11 @@ 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>
|
||||
<span class="c">// stdlib only: no third-party Go dependencies</span></pre>
|
||||
|
||||
<p>If your language isn’t covered, see <a href="wire-format.html">Wire format</a>. The format is small and porting takes about an afternoon.</p>
|
||||
|
||||
<h2 id="embed">Step 1 — Embed your public key</h2>
|
||||
<h2 id="embed">Step 1: Embed your public key</h2>
|
||||
<p>In the admin UI, open <strong>Overview</strong> and copy the issuer public key from the "Embed your public key" card. (Or fetch it from <code>GET /v1/issuer/public-key</code>.) Paste it into your application’s source code as a compile-time constant.</p>
|
||||
|
||||
<pre class="code lang-pane" data-lang="ts"><span class="k">const</span> <span class="f">ISSUER_PEM</span> = <span class="s">`-----BEGIN PUBLIC KEY-----
|
||||
@@ -110,7 +108,7 @@ MCowBQYDK2VwAyEAmz7q8r4t1v…h3k2pXq9wL
|
||||
<p><strong>Embed it. Don’t fetch it.</strong> The whole point of offline verification is that your software can’t be tricked by a network-level attacker. If you fetch the public key at runtime, you’re back to trusting a server.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="verify">Step 2 — Verify a license at startup</h2>
|
||||
<h2 id="verify">Step 2: Verify a license at startup</h2>
|
||||
<p>Read the user’s license key from wherever you store it (a file in their data directory, the OS keychain, an env var) and verify it on application start.</p>
|
||||
|
||||
<pre class="code lang-pane" data-lang="ts"><span class="k">import</span> { <span class="f">Verifier</span>, <span class="f">PublicKey</span> } <span class="k">from</span> <span class="s">'@keysat/licensing-client'</span>;
|
||||
@@ -167,7 +165,7 @@ result = verifier.<span class="f">verify</span>(license_key_from_user)
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2 id="errors">Step 3 — Handle errors gracefully</h2>
|
||||
<h2 id="errors">Step 3: Handle errors gracefully</h2>
|
||||
<p>Verification can fail for benign reasons (the user hasn’t pasted a license yet) or hostile ones (someone tampered with a license file). Distinguish them in your UX:</p>
|
||||
|
||||
<pre class="code lang-pane" data-lang="ts"><span class="k">try</span> {
|
||||
@@ -198,7 +196,7 @@ result = verifier.<span class="f">verify</span>(license_key_from_user)
|
||||
show_input_error()</pre>
|
||||
|
||||
<h2 id="renewals">Renewals & revocation</h2>
|
||||
<p>Keysat licenses are signed at issue time and do not phone home. If a license is revoked in the admin UI, the existing key continues to verify in your app — that’s the trade-off for offline.</p>
|
||||
<p>Keysat licenses are signed at issue time and do not phone home. If a license is revoked in the admin UI, the existing key continues to verify in your app. That’s the trade-off for offline.</p>
|
||||
|
||||
<p>If you need revocation, ship a thin <em>online</em> check that runs on a cadence (e.g. once a week) against your Keysat’s revocation feed:</p>
|
||||
|
||||
@@ -232,7 +230,7 @@ result = verifier.<span class="f">verify</span>(license_key_from_user)
|
||||
|
||||
<div class="callout">
|
||||
<i data-lucide="key-round"></i>
|
||||
<p><strong>You decide the policy.</strong> Many indie developers ship no revocation at all. Once a key is sold, it stays valid — refunds happen offline via BTCPay. That’s perfectly reasonable.</p>
|
||||
<p><strong>You decide the policy.</strong> Many indie developers ship no revocation at all. Once a key is sold, it stays valid. Refunds happen offline via BTCPay. That’s perfectly reasonable.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="api">Admin API</h2>
|
||||
@@ -284,5 +282,6 @@ result = verifier.<span class="f">verify</span>(license_key_from_user)
|
||||
b.addEventListener('click', () => setLang(b.dataset.lang));
|
||||
});
|
||||
</script>
|
||||
<script src="docs.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user