Skip to content

feat(client): silent wd_clearance minting — closes the #124 loop (SDK half)#6

Merged
cport1 merged 1 commit into
mainfrom
feat/128-clearance-mint
Jul 16, 2026
Merged

feat(client): silent wd_clearance minting — closes the #124 loop (SDK half)#6
cport1 merged 1 commit into
mainfrom
feat/128-clearance-mint

Conversation

@cport1

@cport1 cport1 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

The SDK half of the decoy → deny-list loop (app-side #124 shipped the server half). Real browsers now silently earn and carry a wd_clearance cookie during normal browsing, so the loop works in monitor / allow-and-observe mode — not just after an enforce-mode challenge.

What's added (@webdecoy/client)

  • clearance.ts
    • computeDeviceFP(env)pure: consumes the collector's already-computed canvas + WebGL signals and does no canvas/WebGL of its own. Stable device subset only (canvas, WebGL, screen, timezone, platform, language); no User-Agent (avoids churn on browser auto-update).
    • startClearance(opts) — deferred to browser idle, at most once per session, skips when a fresh cookie already exists, refreshes before the 30-min expiry, and never solves a proof-of-work. Zero page-load cost.
  • global.ts — the standalone script auto-starts clearance from a data-site-key attribute (data-ingest / data-scope optional).
  • clearance.test.ts — locks the fp contract: the canonical string, a golden hash the edge challenge page cross-asserts, the no-canvas guarantee, and graceful na degradation.

The cross-repo contract

The fp algorithm is byte-identical to the edge challenge page (app repo edge/clearance-worker, companion PR): same wdfp1 version prefix, field order, canvas 32-bit rolling hash (matching EnvironmentalCollector._getCanvasHash), and WebGL extraction. Verified: the SDK, the worker, and the golden vector all produce the same hash. If either side drifts, the golden-vector test fails.

Performance

Per the constraints on the tracking issue: one deferred background request + one small hash + one cookie write, once per session, riding on signals the collector already gathers. No new fingerprinting, no new PoW, no blocking main-thread work.

Verify

  • tsc --noEmit clean; turbo build green (IIFE + CJS + ESM + DTS); full client jest suite passes (10/10, incl. 4 new).

… half)

Real browsers now earn and carry a wd_clearance cookie during normal
browsing, so the decoy → deny-list binding (#124, server side already
shipped) works in monitor / allow-and-observe mode, not just after an
enforce-mode challenge.

- clearance.ts: computeDeviceFP (pure — consumes the collector's canvas +
  WebGL output, does no canvas/WebGL of its own; stable subset only, no UA)
  and startClearance (deferred to idle, at most once per session, skips
  when a fresh cookie exists, refreshes before the 30-min expiry, never
  solves a PoW).
- global.ts: the standalone script auto-starts clearance from a
  data-site-key attribute (data-ingest / data-scope optional).
- clearance.test.ts: locks the fp contract — canonical string, a GOLDEN
  hash the edge challenge page cross-asserts, the no-canvas guarantee, and
  graceful "na" degradation.

The fp algorithm is a cross-repo CONTRACT with the edge challenge page
(app: edge/clearance-worker) — identical version prefix "wdfp1", field
order, canvas 32-bit hash, and WebGL extraction. Verified: SDK, worker,
and golden vector all produce the same hash.
@cport1
cport1 merged commit b3db406 into main Jul 16, 2026
2 checks passed
@cport1
cport1 deleted the feat/128-clearance-mint branch July 16, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant