> ## Documentation Index
> Fetch the complete documentation index at: https://eurusys-6c0957fa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Web (Browser / TypeScript)

> Integrate the MBKYC SDK into a browser app via the @mbkyc/sdk package, browser extension, and native host.

The web flow has three pieces. Only the first is code you write:

* **TypeScript SDK** (`@mbkyc/sdk`) — imported by your web app. The only piece your application touches.
* **Browser extension** (Chrome/Edge) — bridges the page to the local helper.
* **Native host** (`mbkyc-web-host`) — a small desktop helper, started by the browser, that talks to the local smart card and fingerprint hardware.

The page never talks to the host directly: **page → extension → native host**.

<Card title="Download the example" icon="download" href="/examples/mbkyc-web-example.zip" cta="mbkyc-web-example.zip">
  A self-contained React + Vite app. Fill in `src/config.ts`, point `MBKYC_NPM_REGISTRY` at the MBKYC npm registry (your proxied `repo.client.ae` host), and `npm install && npm run dev`.
</Card>

```mermaid theme={null}
flowchart TB
    A["Web app (your code)<br/>@mbkyc/sdk"] --> B["Browser extension"]
    B --> C["mbkyc-web-host<br/>(native host)"]
    C --> D["Smart card reader ·<br/>fingerprint sensor"]
```

## Prerequisites

<Warning>
  `@mbkyc/sdk` alone is not enough. The end-user machine must also have the **browser extension** and the **`mbkyc-web-host`** native host installed (ship the host with your desktop installer — `.deb`/`.rpm`/`.pkg`/`.msi`). Card reads and fingerprint capture additionally require the matching **[desktop services](/distribution/services-overview)** — the PC/SC service and your vendor fingerprint service — which the native host talks to.
</Warning>

<Info>
  Installing the `mbkyc-web-host` package **registers the Chrome and Edge native-messaging host manifest for you**, system-wide — every installer format does it (`.pkg`/`.deb`/`.rpm` post-install, `.msi`/Chocolatey via the registry). There's no manual manifest step; once the package is installed the browser can discover and launch the host.
</Info>

## Install

```bash theme={null}
npm install @mbkyc/sdk
# or
pnpm add @mbkyc/sdk
```

## Token signer

The SDK never holds your API secret. Supply a `tokenSigner`: when the SDK needs a JWT, it hands you the `header.payload` bytes; you return the raw signature — typically by forwarding the bytes to your backend, which holds the secret.

```ts theme={null}
import type { TokenSigner } from '@mbkyc/sdk';

const tokenSigner: TokenSigner = {
  async sign(signingInput: Uint8Array): Promise<Uint8Array> {
    const res = await fetch('/api/mbkyc/sign', { method: 'POST', body: signingInput });
    return new Uint8Array(await res.arrayBuffer());
  },
};
```

## Initialize & validate

```ts theme={null}
import { MBKYCClient } from '@mbkyc/sdk';

const client = new MBKYCClient();

await client.init({
  baseUrl: 'https://api.client.ae',
  apiKeyId: 'key-id',
  tokenSigner,
  logConfig: { logDir: '/var/log/myapp' }, // maxFileSizeBytes?, maxFiles? optional
  // timeoutMs?  (default 30000) · extraHeaders?  (max 5)
});

const readers = await client.listSmartcardReaders();
await client.registerDevice('lobby-kiosk');

const result = await client.validate({
  kind: 'emiratesIdManual',
  idNumber: '784-XXXX-XXXXXXX-X',
  documentNumber: '...',
  nationality: 'ARE',
});

await client.deInit();
```

### Lifecycle

```
new MBKYCClient(options?)
  → await client.init(config)   // once, before any operation
  → operations …                // getInfo, list*, validate, registerDevice, …
  → await client.deInit()       // tear down; a fresh init() may follow
```

`getInfo()` (host version + capabilities) is the one call that does **not** require `init()` — use it to detect whether the host/extension are installed.

## Operations

| Method                     | Returns                                 | Needs `init()`? |
| -------------------------- | --------------------------------------- | --------------- |
| `getInfo()`                | `HostInfo`                              | no              |
| `registerDevice(name)`     | `void`                                  | yes             |
| `checkRegistration()`      | `'active' \| 'inactive' \| 'not_found'` | yes             |
| `listSmartcardReaders()`   | `ReaderInfo[]`                          | yes             |
| `listFingerprintReaders()` | `ReaderInfo[]`                          | yes             |
| `validate(request)`        | `VerificationResult`                    | yes             |
| `exportLogs(outputPath)`   | `void`                                  | yes             |
| `cancel()`                 | `void`                                  | —               |

## Validation requests

A `validate(request)` call selects the document and capture mode through the request's `kind`. The requests, grouped by document:

<Info>
  The `emiratesIdCard` and `fingerprint` variants need the matching [desktop service](/distribution/services-overview) reachable through the native host — the **PC/SC service** for card reads and your **vendor fingerprint service** for biometrics — in addition to the browser extension and `mbkyc-web-host`. Manual entry needs no hardware or service.
</Info>

<Tabs>
  <Tab title="Emirates ID">
    **Manual entry** — no hardware required.

    ```ts theme={null}
    // Manually entered Emirates ID details.
    { kind: 'emiratesIdManual', idNumber, documentNumber, nationality,
      dateOfBirth?, issueDate?, expiryDate?, fingerprint?, clientReferenceId? }
    ```

    **Card read** — needs a smart card reader + the PC/SC service (via the native host). Get `readerId` from `listSmartcardReaders()`.

    ```ts theme={null}
    // Read the Emirates ID chip from a smartcard reader.
    { kind: 'emiratesIdCard', readerId, cardDipTimeoutMs?, fingerprint?, clientReferenceId? }
    ```

    **+ Fingerprint** — add the `fingerprint` field to either Emirates ID request (`emiratesIdCard` or `emiratesIdManual`) for a biometric match. Needs a fingerprint sensor + its service; see [Biometrics](#biometrics) below.
  </Tab>

  <Tab title="Passport">
    **Manual entry** — no hardware required. No biometric variant.

    ```ts theme={null}
    // Manually entered passport details.
    { kind: 'passportManual', passportNumber, passportType, nationality,
      dateOfBirth?, issueDate?, expiryDate?, clientReferenceId? }
    ```
  </Tab>
</Tabs>

`VerificationResult` is `{ success, message, data?, clientReferenceId? }`.

### Biometrics

Attach a `fingerprint` to an Emirates ID request:

```ts theme={null}
const result = await client.validate({
  kind: 'emiratesIdCard',
  readerId: scReader.id,
  fingerprint: {
    readerId: fpReader.id,
    recommendationCallback: {
      async onFingerRecommendation(recommendedFingers /* Finger[] */) {
        // backend's quality-ranked list (best first); may be empty if not enrolled
        return FingerSelection.recommended(recommendedFingers[0]);
        // or FingerSelection.custom(finger) / FingerSelection.cancel()
      },
    },
    captureTimeoutMs: 10_000,
  },
});
```

## Errors

Failures reject with an `MBKYCError`:

* `error.code` — symbolic display code (e.g. `"E9900"`)
* `error.numericCode` — numeric code (e.g. `9900`)
* `error.error` — the typed `ErrorCode`; compare against the exported per-module buckets (`vendor.EXTENSION_NOT_FOUND` is raised when the extension is not installed)

See the [error reference](/reference/error-codes).

<Info>
  The SDK targets a fixed extension ID. Only pass `new MBKYCClient({ extensionId })` if you ship a private fork of the extension under a different keypair (which also requires updating the native host manifest).
</Info>

## Reference

The full operation list is in the [Operations](#operations) table above. Shared value types — [`ReaderInfo`](/reference/data-types#readerinfo), [`RegistrationStatus`](/reference/data-types#registrationstatus), [`VerificationResult`](/reference/data-types#verificationresult), [`Finger`](/reference/data-types#finger), [`FingerSelection`](/reference/data-types#fingerselection), [config](/reference/data-types#config) — are documented in [Data types](/reference/data-types), and the cross-platform map in the [API overview](/reference/api-overview).

**Export logs** writes a `tar.zst` archive for support:

```ts theme={null}
await client.exportLogs('/tmp/mbkyc-logs.tar.zst');
```
