Package Exports
- genuine-verify-sdk
Readme
Genuine Verify SDK
A privacy-first, real-time human verification widget (anti-bot) for React apps. Uses TensorFlow.js and BlazeFace for gesture-based verificationβno CAPTCHAs, no user friction.
π¦ Installation
npm install genuine-verify-sdk
# or
yarn add genuine-verify-sdkPeer dependencies:
- React 18+
- react-dom 18+
π Overview
- Purpose: Prevent bots and ensure genuine human interaction with a privacy-first, client-side widget.
- How it works: User completes a gesture (e.g., head tilt). The widget issues a signed presence token. You can validate this token client-side or send it to your backend for verification.
βοΈ Widget Usage
Basic Example
import { GenuineWidgetEmbeddable } from 'genuine-verify-sdk';
function MyApp() {
const handleTokenIssued = (payload: {
token: string;
metadata: {
issuedAt: string;
expiresAt: string;
gestureType: string;
};
}) => {
// Send token to your backend or validate client-side
console.log('Token:', payload.token);
console.log('Metadata:', payload.metadata);
};
return (
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
tokenTTL={300}
debug={true}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
onTokenIssued |
(payload: { token: string; metadata: { issuedAt: string; expiresAt: string; gestureType: string; } }) => void |
β | Required. Called when token is issued with metadata |
onFailure |
(context: FailureContext) => void |
β | Called when gesture detection fails after max attempts |
maxAttempts |
number |
3 |
Maximum attempts before triggering fallback |
fallback |
React.ComponentType<{ failureContext: FailureContext; triggerRetry: () => void }> |
β | Custom fallback component to render on failure |
tokenTTL |
number |
300 |
Token time-to-live (seconds) |
debug |
boolean |
false |
Show debug panel |
headTiltThreshold |
number |
15 |
Head tilt angle threshold (degrees) |
persist |
boolean |
true |
Persist token in sessionStorage |
trigger |
'auto' | 'manual' |
'auto' |
When to start detection |
onStartRef |
(startFn: () => void) => void |
β | Get manual start function |
onError |
(error: Error) => void |
β | Error callback |
π Utility Functions
All utilities are available as named exports:
import {
verifyToken,
createPresenceToken,
getStoredToken,
storeToken,
clearStoredToken,
isStoredTokenValid,
createMockToken
} from 'genuine-verify-sdk';π Verification Status Hook
Check human verification status with real-time updates:
import { useVerificationStatus } from 'genuine-verify-sdk'
function MyApp() {
const { isVerified, token, expiresIn, timeRemaining, clearToken } = useVerificationStatus()
return (
<div>
{isVerified ? (
<div>
<p>β
Human verified! Expires in {timeRemaining}</p>
<button onClick={clearToken}>Clear Verification</button>
</div>
) : (
<p>β Human not verified</p>
)}
</div>
)
}Hook Features:
- β Real-time updates: Auto-updates every second when verified
- β Live countdown: Shows time remaining until expiration
- β Expiration warning: Detects when token expires soon (β€60s)
- β Token management: Clear stored tokens
- β Manual refresh: Force status update
- β TypeScript support: Full type safety
π‘οΈ Fallback Strategy
Handle gesture detection failures gracefully:
import { GenuineWidgetEmbeddable } from 'genuine-verify-sdk'
// Custom fallback component
const CustomFallback = ({ failureContext, triggerRetry }) => (
<div>
<h2>Verification Failed</h2>
<p>Attempts: {failureContext.attempts}/{failureContext.maxAttempts}</p>
<button onClick={triggerRetry}>Try Again</button>
</div>
)
function MyApp() {
const handleFailure = (context) => {
console.log('Failed after', context.attempts, 'attempts')
console.log('Reason:', context.reason)
}
return (
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
onFailure={handleFailure}
maxAttempts={5}
fallback={CustomFallback}
/>
)
}Fallback Features:
- β onFailure callback: Get structured failure context with reason, attempts, and error details
- β maxAttempts prop: Configure attempts before fallback (default: 3)
- β Custom fallback component: Pass your own React component for custom error UI
- β triggerRetry function: Exposed retry handler for "Try Again" buttons
- β Default fallback UI: Built-in error display when no custom component provided
π― Trigger Control
Control when verification starts with flexible trigger modes:
import { GenuineWidgetEmbeddable, useGenuineTrigger } from 'genuine-verify-sdk'
function MyApp() {
const [startFunction, setStartFunction] = useState(null)
// Auto-start (default)
return (
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
trigger="auto"
/>
)
// Manual button
return (
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
trigger="manual"
/>
)
// Programmatic control
return (
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
trigger="manualStart"
onStartRef={setStartFunction}
/>
)
}Advanced Programmatic Control:
import { useGenuineTrigger } from 'genuine-verify-sdk'
function MyApp() {
const [startFunction, setStartFunction] = useState(null)
const [isDetectionActive, setIsDetectionActive] = useState(false)
const [isModelReady, setIsModelReady] = useState(false)
const triggerControls = useGenuineTrigger(
startFunction,
null, // stopFn
null, // resetFn
isDetectionActive,
isModelReady,
{
onStart: () => setIsDetectionActive(true),
onStop: () => setIsDetectionActive(false)
}
)
const handleFormSubmit = (e) => {
e.preventDefault()
triggerControls.startDetection() // Trigger on form submit
}
return (
<form onSubmit={handleFormSubmit}>
<GenuineWidgetEmbeddable
onTokenIssued={handleTokenIssued}
trigger="manualStart"
onStartRef={setStartFunction}
/>
<button type="submit">Submit Form</button>
</form>
)
}Trigger Features:
- β Auto trigger: Start detection immediately when widget loads
- β Manual trigger: User clicks button to start detection
- β Manual start: Programmatic control via start function
- β useGenuineTrigger hook: Provides programmatic control methods
- β Status tracking: Know when detection is active and model is ready
- β Event callbacks: onStart, onStop, onReset callbacks
- β Flexible integration: Trigger on form submit, route change, suspicious activity, etc.
Example: Token Validation
const result = await verifyToken(token);
if (result.valid) {
// Token is valid!
} else {
// Token is invalid or expired
}π Token Flow
- User completes gesture in widget.
- Widget issues a presence token (JWT-like JSON).
- You validate the token:
- Client-side:
verifyToken(token) - Server-side: POST to
/api/verify-human(see below)
- Client-side:
π€ Token Endpoint (Optional)
POST /api/verify-human
- Header:
Authorization: Bearer <token> - Body:
{ "token": "<token>" }
Returns:
{
"valid": true,
"reason": null,
"gestureType": "headTilt",
"expiresIn": 299,
"issuedAt": "2025-01-06T20:00:00.000Z"
}π§ Example Integration
import { GenuineWidgetEmbeddable, verifyToken } from 'genuine-verify-sdk';
function Demo() {
const [status, setStatus] = useState<string | null>(null);
const handleTokenIssued = async (payload: {
token: string;
metadata: {
issuedAt: string;
expiresAt: string;
gestureType: string;
};
}) => {
const result = await verifyToken(payload.token);
setStatus(result.valid ? 'β
Valid' : 'β Invalid');
};
return (
<>
<GenuineWidgetEmbeddable onTokenIssued={handleTokenIssued} />
{status && <div>{status}</div>}
</>
);
}π Exports
GenuineWidgetEmbeddable(main widget)verifyToken,createPresenceToken,getStoredToken,storeToken,clearStoredToken,isStoredTokenValid,createMockToken- Types:
PresenceToken,TokenValidationResult, etc.
β±οΈ Get Started in <10 Minutes
- Install the SDK.
- Add
<GenuineWidgetEmbeddable />to your app. - Handle the token in
onTokenIssued. - Validate the token with
verifyToken().
For more, see the full API docs or open an issue!
π οΈ TypeScript Configuration Notes
If you use TypeScript and want to avoid React import warnings, make sure your tsconfig.json includes these settings:
{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}This is needed because of how TypeScript handles default imports from CommonJS modules like React. Most modern React/TypeScript setups already have these enabled by default.
π Analytics (Dev Only)
Track real-time detection analytics in development with the useGenuineAnalytics hook.
import { useGenuineAnalytics } from 'genuine-verify-sdk'
function AnalyticsPanel() {
// You need to pass detection state from your widget
const detectionState: AnalyticsDetectionState = {
isCameraActive: false,
gestureMatched: false,
detectionState: 'idle',
fps: 0
}
const { successCount, failureCount, attemptCount, fps, lastEvent, clear } = useGenuineAnalytics(detectionState, {
persist: false, // Set true to persist to localStorage
logToConsole: true // Set false to disable console logs
})
return (
<div>
<h3>Analytics (Dev Only)</h3>
<ul>
<li>Successes: {successCount}</li>
<li>Failures: {failureCount}</li>
<li>Attempts: {attemptCount}</li>
<li>FPS: {fps}</li>
<li>Last Event: {lastEvent}</li>
</ul>
<button onClick={clear}>Clear Analytics</button>
</div>
)
}Features:
- β Real-time updates for detection attempts, successes, failures, and FPS
- β Lightweight, no server calls
- β Console logging (dev only)
- β Optional localStorage persistence (dev only)
Usage Notes:
- Analytics are only active in development (
NODE_ENV !== 'production'). - No data is sent to any serverβeverything is client-side.
- For privacy and performance, do not use analytics in production or for user-facing metrics.
- You can disable console logging or localStorage with the hook options.
- To extend analytics (e.g., custom events), use the
logfunction returned by the hook.
Warning:
Overuse of analytics in production can impact privacy and performance. This hook is intended for development and debugging only. Do not use for user tracking or telemetry.