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:
- A per-region pill anchored over each
[data-fidemark-uid][data-fidemark-content-hash]element, with live tamper detection. - A floating summary pill at the bottom-right of the viewport, aggregating regions and badges into a one-glance status.
- 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.
What it detects
Section titled “What it detects”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.
Regions (content + hash)
Section titled “Regions (content + hash)”| Marker | Source 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:
| State | Meaning |
|---|---|
| Verified | All three hashes match, attestation not revoked. |
| Tampered | Declared ≠ recomputed. Page bytes drifted from what was attested. |
| Mismatch | Declared ≠ on-chain. Markup carries the wrong UID. |
| Revoked | Match but attester revoked. |
| Unreachable | Network 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/badgescript 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.
Badges (UID-only markers)
Section titled “Badges (UID-only markers)”| Marker | Example |
|---|---|
<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.
The summary pill
Section titled “The summary pill”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.
The toolbar popup
Section titled “The toolbar popup”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 whosecontentHashmatches. - 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.
Privacy and isolation
Section titled “Privacy and isolation”- The extension never mutates publisher DOM. Pills, the summary, and the side panel all live in a dedicated
#fidemark-extension-overlay-rootelement appended todocument.bodyand 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.devin production,http://localhost:3100in 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.
Installing
Section titled “Installing”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.