A passkey sign-in built around a dial of sixty ticks: a sweep while the browser looks for a passkey, a draining countdown ring while you confirm on your device, then every tick lights up as the signature is verified. A live checklist shows each step of the ceremony.
Asking your browser for a passkey saved for this site.
Lost your device?
npx shadcn@latest add https://hyperblur.dev/r/auth-passkey-handshake.jsonWorks in any React project set up with the shadcn CLI. The file lands in components/hyperblur/auth-passkey-handshake.tsx.
import { AuthPasskeyHandshake } from "@/components/hyperblur/auth-passkey-handshake"
<AuthPasskeyHandshake device="MacBook Pro" onPasskey={async () => !!(await navigator.credentials.get({ publicKey: options }))} />| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | "Sign in with your passkey" | Heading before the flow starts. |
| subtitle | string | "No password needed. Your device signs a one-time challenge..." | Text before the flow starts. |
| account | { name: string; email: string } | { name: "Maya Okafor", email: "maya@lumen.dev" } | Account shown in the chip at the top. |
| device | string | "MacBook Pro" | Device name used in the prompts and the checklist. |
| timeoutSeconds | number | 60 | Seconds to confirm on the device before the request times out. |
| defaultStage | "idle" | "searching" | "confirm" | "verified" | "failed" | "idle" | Initial stage, useful for previews. |
| onPasskey | () => boolean | void | Promise<boolean | void> | Run your WebAuthn ceremony here. Return or resolve false, or throw, to show the failed state. Without it the flow is simulated. | |
| onFallback | () => void | Called by the Sign in with an email code link. | |
| onSwitchAccount | () => void | Called by the Switch button in the account chip. | |
| onStageChange | (stage) => void | Called whenever the stage changes. | |
| accent | string | "#3dd68c" | Tick, ring and button color. |