npm package: @kwik-id/sdk-react
Description: SDK for [KwikID](https://identity.kwiknkap.com) identity verification. Adds a complete KYC verification flow to any web application with a single function call.
Latest version: 0.1.0

# @kwik-id/sdk-react

SDK for [KwikID](https://identity.kwiknkap.com) identity verification. Adds a complete KYC verification flow to any web application with a single function call.

## Installation

```bash
npm install @kwik-id/sdk-react
# or
pnpm add @kwik-id/sdk-react
# or
yarn add @kwik-id/sdk-react
```

**Peer dependencies:** `react >= 18`, `react-dom >= 18`, `framer-motion >= 10`, `lucide-react >= 0.300`, `lottie-react >= 2.4`

## Quick Start

### 1. Create a session on your backend

> **Security:** Sessions must be created server-side. Your API key must never be exposed to the browser. Use [`@kwik-id/sdk-node`](https://www.npmjs.com/package/@kwik-id/sdk-node) or a direct API call from your backend to get a short-lived `clientSecret` (session token) to pass to the frontend.

```ts
// Backend (Express, Next.js API route, etc.)
import { KwikIDNode } from "@kwik-id/sdk-node";

const kwikId = new KwikIDNode({ apiKey: process.env.KWIKID_API_KEY! });

app.post("/api/create-session", async (req, res) => {
    const session = await kwikId.createSession({
        referenceId: req.user.id,
        userName: req.user.name,
    });
    res.json({ clientSecret: session.token });
});
```

### 2. Open the verification modal

Call `openKwikVerification()` from any button click or event handler. It injects the modal at `document.body` — zero layout impact on your page — and returns a Promise that resolves when the user finishes or exits.

```ts
import { openKwikVerification } from "@kwik-id/sdk-react";

// Works in React, Vue, Angular, or plain JavaScript
async function handleVerifyClick() {
    const { clientSecret } = await fetch("/api/create-session", { method: "POST" }).then((r) =>
        r.json()
    );

    const { status, jobId } = await openKwikVerification({
        clientSecret,
        appName: "My App",
        theme: { primary: "#2563EB", accent: "#FBBF24" },
        onSubmitted: ({ jobId }) => {
            // Fires while modal is still open — save the jobId immediately.
            // The actual verification result (pass/fail) arrives later via webhook.
            console.log("Submitted for review, jobId:", jobId);
        },
    });

    if (status === "submitted") {
        // Modal closed. Documents are with the backend.
        // Listen for the result via your webhook endpoint.
        showMessage("We'll notify you once your identity is verified.");
    } else if (status === "cancelled") {
        // User closed the modal before submitting.
    } else if (status === "error") {
        // Upload or submission failed.
    }
}
```

That's it — the modal handles the full flow: document selection, camera capture, quality checks, liveness, and submission.

> **Note:** `status === "submitted"` means documents were received by the backend and processing has started — **not** that the verification passed. The pass/fail result arrives asynchronously via [webhooks](#webhooks).

## Configuration

### `OpenVerificationOptions`

| Option         | Type                  | Required | Description                                                                                       |
| -------------- | --------------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `clientSecret` | `string`              | Yes      | Session token from your backend                                                                   |
| `appName`      | `string`              | No       | App name shown in the modal header (falls back to org name)                                       |
| `baseUrl`      | `string`              | No       | API base URL (defaults to production)                                                             |
| `theme`        | `KwikIDTheme`         | No       | Custom theme colors                                                                               |
| `showLogo`     | `boolean`             | No       | Show org logo in header (default: `true`)                                                         |
| `onSubmitted`  | `({ jobId }) => void` | No       | Called while the modal is still open, immediately when documents are uploaded. Save `jobId` here. |

### `VerificationOutcome`

Resolved value of the Promise returned by `openKwikVerification()`:

| Field    | Type                                    | Description                                          |
| -------- | --------------------------------------- | ---------------------------------------------------- |
| `status` | `"submitted" \| "cancelled" \| "error"` | What happened when the modal closed                  |
| `jobId`  | `string`                                | Present on `"submitted"` — use to track via webhooks |
| `error`  | `Error`                                 | Present on `"cancelled"` and `"error"`               |

### `KwikIDTheme`

```ts
{
  primary?: string;    // Primary brand color (hex, e.g. "#2563EB")
  accent?: string;     // Accent color (hex)
  background?: string; // Background color (hex)
  foreground?: string; // Foreground/text color (hex)
}
```

## React Component (alternative)

If you prefer a declarative React approach, `<KwikID>` is available. It renders the same modal as `openKwikVerification()` — mount it conditionally, unmount it to close.

```tsx
import { KwikID } from "@kwik-id/sdk-react";

{
    showVerification && (
        <KwikID
            config={{
                clientSecret,
                appName: "My App",
                onSubmitted: ({ jobId }) => saveJobId(jobId),
                onComplete: () => setShowVerification(false),
                onError: () => setShowVerification(false),
            }}
        />
    );
}
```

### `<KwikIDProvider>` — Context Provider

Wraps your components to provide SDK state and actions via the `useKwikID()` hook. Used internally by both `openKwikVerification()` and `<KwikID>`.

> **Note:** Building a fully custom verification flow with this provider (custom camera UI, custom step sequencing, cross-device handoff) requires significant implementation work. Detailed documentation for custom integrations is coming.

`useKwikID()` returns: `isSDKReady`, `orgName`, `orgLogoUrl`, `qualityResult`, `detectedFace`, `alignmentResult`, `livenessResult`, `analyzeQuality(video)`, `detectFace(video)`, `checkAlignment()`, `runPassiveLiveness()`, `submitVerification(docType)`, `uploadFile(type, file)`.

## Hooks

The following hooks are exported. They are used internally by the built-in components and are available for custom integrations. Hooks marked **requires provider** must be used inside `<KwikIDProvider>`.

| Hook                        | Requires provider | Description                                          |
| --------------------------- | ----------------- | ---------------------------------------------------- |
| `useKwikID()`               | Yes               | Full SDK state and actions (camera, capture, submit) |
| `useCamera(options)`        | No                | Camera access and frame capture                      |
| `useQuality(options)`       | No                | Real-time image quality analysis                     |
| `useFaceDetection(options)` | No                | Face detection and alignment                         |
| `useLiveness(options)`      | No                | Passive liveness detection                           |
| `useVerification(options)`  | Yes               | Verification step state machine                      |
| `useHandoff()`              | Yes               | Cross-device QR handoff                              |

## Utilities

```tsx
import {
    // Check image sharpness
    UploadManager,
    // Manage file uploads
    // Compress images before upload
    analyzeImageQuality,
    // Check image brightness
    checkBlur,
    // Analyze image quality from a frame
    checkLuminance,
    compressImage,
} from "@kwik-id/sdk-react";
```

## TypeScript

All types are exported for full TypeScript support:

```tsx
import type {
    AlignmentResult,
    DetectedFace,
    DocumentData,
    KYCFormData,
    KwikIdConfig,
    KwikIdTheme,
    PassiveLivenessResult,
    QualityResult,
    SDKState,
    SDKStatus,
    SelfieData,
    VerificationResult,
} from "@kwik-id/sdk-react";
```

## Supported Document Types

- National ID Card
- Passport
- Driver's License
- Voter's Card

## Browser Support

- Chrome 80+
- Firefox 78+
- Safari 14+
- Edge 80+

Camera access requires HTTPS in production (except `localhost` for development).

## License

MIT