Skip to content

Browser extension

The Fidemark browser extension scans every web page for attestation markers, runs verification in the background worker, and surfaces results in three places:

  1. A per-region pill anchored over each [data-fidemark-uid][data-fidemark-content-hash] element, with live tamper detection.
  2. A floating summary pill at the bottom-right of the viewport, aggregating regions and badges into a one-glance status.
  3. The toolbar popup, which lists every detected attestation grouped by kind, plus actions to verify or attest the current text selection.

Status: not yet available. The extension will appear on the Chrome Web Store once it has cleared review. A Firefox build is on the roadmap.

The content script scans the page at document_idle and watches the DOM for the next ~10 s, so late-mounted markers (React hydration, infinite scroll) are picked up too.

MarkerSource of truth
<fidemark-region uid="0x..." content-hash="0x...">@fidemark/badge custom element.
[data-fidemark-uid][data-fidemark-content-hash]Plain HTML attributes on any element.

For each region, the extension recomputes the canonical hash with canonicalizeDom + SHA-256 (identical rules to all three SDKs) and runs a three-way check: declared (markup) vs recomputed (this browser) vs on-chain (/api/attestation/<uid>). The pill resolves to one of:

StateMeaning
VerifiedAll three hashes match, attestation not revoked.
TamperedDeclared ≠ recomputed. Page bytes drifted from what was attested.
MismatchDeclared ≠ on-chain. Markup carries the wrong UID.
RevokedMatch but attester revoked.
UnreachableNetwork error or malformed UID.

A MutationObserver re-runs verification whenever the region’s subtree changes, so editing a contentEditable paragraph or a SPA route swap flips the pill in real time.

<fidemark-region> elements that are already wired up to the @fidemark/badge script render their own pill from a shadow root. The extension detects those for the popup list and the summary count, but does not draw a duplicate pill on top.

MarkerExample
<fidemark-badge uid="0x...">The rendered @fidemark/badge component.
<meta name="fidemark-uid" content="0x...">Page-level UID declaration.
[data-fidemark-uid="0x..."] (without data-fidemark-content-hash)Generic attribute.

Badges are simpler: there’s no content to hash, so the extension only fetches the on-chain attestation and reports valid, revoked, not-found, or error.

A single floating button anchored bottom-right of the viewport, visible only when ≥ 1 marker is detected. It aggregates regions and badges:

  • ✓ N verified (green): every marker is currently valid.
  • N verified · M issue(s) (amber): mix of valid and tampered/mismatched/revoked.
  • N issue(s) (red): nothing valid.
  • Verifying N… (dark) while lookups complete.

Click it to open a side panel listing every detected attestation grouped by kind, with their UIDs and statuses.

Opens to a list of every region and badge on the page (re-verified on each open so a fresh edit is reflected immediately) plus two actions:

  • Verify selection — hashes the current text selection in the active tab via Web Crypto, then opens https://verify.fidemark.dev/hash/<hash> to show every attestation whose contentHash matches.
  • Attest selection — same hash, but opens the dashboard at /app?contentHash=…&source=… ready to attest. The dashboard reads the query parameter and prefills the form in precomputed-hash mode: a banner shows the digest and the source URL, the original text stays on the originating page, and only the 32-byte hash goes on chain. The form keeps a Switch to manual entry escape hatch.

You finish either flow with your own wallet: the extension never holds keys.

  • The extension never mutates publisher DOM. Pills, the summary, and the side panel all live in a dedicated #fidemark-extension-overlay-root element appended to document.body and absolutely positioned over their target. SSR-hydrated frameworks (React, Vue, Svelte) keep byte-identical DOM to what the server sent — no hydration warnings.
  • All chain lookups go through the verify host (https://verify.fidemark.dev in production, http://localhost:3100 in the dev build). The extension does not talk to RPC providers directly and does not include any wallet code.
  • The 30 s in-memory cache in the background worker keeps repeated lookups for the same UID or hash off the wire as you scroll long pages.

Install from the Chrome Web Store. The link will go live once the listing has cleared review; in the meantime the extension is private to the team.