@tinfoilsh/verification-center-ui
v0.1.0
Published
Self-contained Web Component for the Tinfoil verification center UI
Readme
Tinfoil Verification Center UI
Self‑contained Web Component that renders the Tinfoil verification center UI inside a Shadow DOM. It bundles its own runtime and styles; no React is required in your app.
Installation
npm install @tinfoilsh/verification-center-uiDefault usage requires only a modern browser with ES modules. No React in the host app is required.
Usage
Default usage defines a self-contained Web Component that renders inside a Shadow DOM and bundles its own runtime and styles.
<!-- Register the custom element (ESM) -->
<script type="module">
import '@tinfoilsh/verification-center-ui'
// Custom element <tinfoil-verification-center> is now defined
// Optional: you can set properties after mount
window.addEventListener('DOMContentLoaded', () => {
const el = document.querySelector('tinfoil-verification-center')
// el.verificationDocument = { ... } // when available
})
</script>
<!-- Place the element anywhere in your page (embedded). Provide a host height. -->
<tinfoil-verification-center
mode="embedded"
is-dark-mode="true"
show-verification-flow="true"
style="height: min(80vh, 680px); width: min(720px, 100%); overflow: hidden; border-radius: 8px;"
></tinfoil-verification-center>
<!-- Sidebar: fixed right panel with built-in header and close -->
<tinfoil-verification-center
mode="sidebar"
open
is-dark-mode="true"
show-verification-flow="true"
sidebar-width="420"
></tinfoil-verification-center>
<!-- Modal: full-screen overlay with centered panel -->
<tinfoil-verification-center mode="modal" open is-dark-mode="true"></tinfoil-verification-center>The component focuses purely on rendering attestation documents. Provide a verificationDocument property when you have one available (for example, from the tinfoil client).
Props
The component exposes a small set of attributes/properties so you can integrate it with the rest of your UI:
is-dark-mode?: boolean– toggles the dark theme (defaults totrue).show-verification-flow?: boolean– hides the network diagram whenfalse(defaults totrue).compact?: boolean– hides process step descriptions for a more compact view (defaults tofalse).verificationDocument?: VerificationDocument– property to supply the attestation document that the UI should render.
Using the result from TinfoilAI
If your app already initializes a TinfoilAI client you can reuse its verification document instead of triggering another attestation pass. Set it on the Web Component as a property:
<script type="module">
import '@tinfoilsh/verification-center-ui'
import { TinfoilAI } from 'tinfoil'
async function init() {
const client = new TinfoilAI({
apiKey: '<YOUR_API_KEY>',
})
await client.ready()
const doc = await client.getVerificationDocument()
const el = document.querySelector('tinfoil-verification-center')
if (el) {
el.verificationDocument = doc
}
}
init().catch(console.error)
</script>
<tinfoil-verification-center is-dark-mode="true" show-verification-flow="true"></tinfoil-verification-center>
> The UI doesn't bundle the `tinfoil` client. If you want to fetch attestation documents directly from Tinfoil, install the `tinfoil` package in your application and pass the resulting documents into the component as shown above.Local Demo
A small Vite app in examples/dev renders the component against mock data.
npm install
npm run build # generates dist/ so the demo consumes the packaged bundle
npm run devOpen the printed URL (defaults to http://localhost:5173) to explore the UI. The demo lets you toggle dark mode, collapse or expand the verification flow diagram, switch between the built-in mock documents, and choose a display mode: Sidebar, Modal, or Web Component (Shadow DOM).
Remote Demo
See it in action at demo.tinfoil.sh.
Web Component (Shadow DOM)
The package provides a completely self-contained UI that won’t leak styles or depend on your app’s React. It renders inside a Shadow DOM and includes all required dependencies.
Install as usual, then import the package (default WC) once and place the element anywhere in your page or app:
<!-- ESM import (bundlers) -->
<script type="module">
import '@tinfoilsh/verification-center-ui'
// custom element <tinfoil-verification-center> is now defined
</script>
<tinfoil-verification-center
mode="embedded"
is-dark-mode="true"
show-verification-flow="true"
style="height: min(80vh, 680px); width: min(720px, 100%); overflow: hidden; border-radius: 8px;"
></tinfoil-verification-center>You can also set the verificationDocument as a property from JavaScript when you already have one from your app’s Tinfoil client:
import '@tinfoilsh/verification-center-ui'
const el = document.querySelector('tinfoil-verification-center')!
el.verificationDocument = myVerificationDocument // object from tinfoil clientSupported attributes/properties:
mode("embedded" | "sidebar" | "modal"; defaultembedded)open(boolean; forsidebar/modalto show/hide UI)sidebar-width(number in px; default420whenmode="sidebar")is-dark-mode(boolean, defaulttrue)show-verification-flow(boolean, defaulttrue)compact(boolean, defaultfalse) - hides process step descriptions for a more compact viewverificationDocument(property only)
Close event (sidebar and modal)
The built-in header includes a close button. When clicked, the component:
- Removes the
openattribute (hides itself), and - Dispatches a
closeevent on the custom element. It also closes when the user presses Escape while a modal or sidebar is open.
Vanilla JS:
<tinfoil-verification-center id="vc" mode="sidebar" open></tinfoil-verification-center>
<script type="module">
import '@tinfoilsh/verification-center-ui'
const el = document.getElementById('vc')
el.addEventListener('close', () => {
// Optional: sync your app state or analytics
console.log('Verification Center closed')
})
// To reopen later:
function openVc() { el.setAttribute('open', '') }
function closeVc() { el.removeAttribute('open') }
window.openVc = openVc
window.closeVc = closeVc
// If you already have a verification document:
// el.verificationDocument = myVerificationDocument
</script>React:
import { useEffect, useRef, useState } from 'react'
import '@tinfoilsh/verification-center-ui'
export function Example() {
const ref = useRef<any>(null)
const [open, setOpen] = useState(true)
useEffect(() => {
const el = ref.current
if (!el) return
const onClose = () => setOpen(false)
el.addEventListener('close', onClose)
return () => el.removeEventListener('close', onClose)
}, [])
return (
<tinfoil-verification-center
ref={ref}
mode="modal"
open={open as any}
/>
)
}Note for React users: for hyphenated boolean attributes on custom elements (e.g., is-dark-mode, show-verification-flow), pass string values 'true' | 'false' to keep the attribute present during toggles.
Nothing else is required — React, styles, and icons are bundled inside the component and fully isolated via Shadow DOM.
Badge Component
The package also includes a <tinfoil-badge> component for displaying verification status in a compact format.
<script type="module">
import '@tinfoilsh/verification-center-ui'
// Custom element <tinfoil-badge> is now defined
</script>
<!-- Standard badge with "Powered by Tinfoil" footer -->
<tinfoil-badge
is-dark-mode="true"
style="width: 300px; height: 45px;"
></tinfoil-badge>
<!-- Compact badge (horizontal layout, no footer) -->
<tinfoil-badge
compact="true"
is-dark-mode="false"
style="width: 200px; height: 32px;"
></tinfoil-badge>Badge Props
is-dark-mode?: boolean– toggles dark theme (defaults totrue)compact?: boolean– enables compact horizontal layout without "Powered by" footer (defaults tofalse)verificationDocument?: VerificationDocument– property to supply the attestation documentstate?: 'idle' | 'loading' | 'success' | 'error'– manual state control (optional, computed from verificationDocument if provided)error-message?: string– custom error message to display on error state
Badge Behavior
The badge displays different states based on the verification document:
- Loading: Shows spinner icon and "Verifying security..." text
- Success: Shows Tinfoil icon (compact mode) or CPU icon (standard mode) with "Security verified" text in green (#004444 in light mode)
- Error: Shows shield alert icon with "Verification failed" text in red
In compact mode:
- Horizontal layout with icon and text side-by-side
- No "Powered by Tinfoil" footer
- Shows Tinfoil icon on success, shield alert on error, spinner on loading
Badge Click Event
The badge emits a badge-click event when clicked:
const badge = document.querySelector('tinfoil-badge')
badge.addEventListener('badge-click', () => {
console.log('Badge clicked')
// Example: open verification center
document.querySelector('tinfoil-verification-center').setAttribute('open', '')
})Notes for React apps
- Import the package in a client-side context only (e.g., in
useEffector in a client component in Next.js) because custom elements are not defined on the server. - When toggling hyphenated boolean attributes (like
is-dark-mode), set them to'true'or'false'strings so attribute presence stays in sync.
