@uzum-tech/luna-pass
v1.0.2
Published
<p align="center"> <img width="144px" src="https://ik.imagekit.io/jbalancer/uzum-logo.svg?updatedAt=1692012347116" /> </p>
Downloads
265
Readme
@uzum-tech/luna-pass
Обёртка над VisionLabs LunaPass SDK для простой интеграции биометрической проверки живости лица.
Полная TypeScript-типизация, автоматическое управление камерой и WebSocket-соединением.
Возможности
- Простой API поверх LunaPass и LPMessageRenderer
- Полная TypeScript-типизация без
any - Автоматическое управление камерой и WebSocket
- Автоматический рендер подсказок и ошибок через
LPMessageRenderer - Декодирование JWT прямо из результата
- Поддержка Vue 3, React и любого фреймворка
Установка
pnpm add @uzum-tech/luna-passИспользование
Базовый пример
import { LunaPassSDK } from '@uzum-tech/luna-pass';
const containerSelector = document.getElementById('camera-box') as HTMLElement;
const sdk = new LunaPassSDK({
serverUrl: 'ws://your-server/ws',
containerSelector,
onStateChange: (state) => {
console.log('State:', state);
},
onResult: (result) => {
console.log('Result:', result);
},
onError: (err) => {
console.error('Error:', err);
},
});
await sdk.start();
const result = await sdk.checkLiveness();
if (result.isOk) {
console.log('JWT:', result.jwt);
console.log('Decoded:', result.decodedJwt);
}Vue 3
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { LunaPassSDK } from '@uzum-tech/luna-pass';
const containerRef = ref<HTMLElement | null>(null);
let sdk: LunaPassSDK | null = null;
onMounted(() => {
if (!containerRef.value) return;
sdk = new LunaPassSDK({
serverUrl: 'ws://your-server/ws',
containerSelector: containerRef.value,
width: '100%',
height: '300px',
onStateChange: (state) => console.log(state),
onResult: (result) => console.log(result),
onError: (err) => console.error(err),
});
});
async function start() {
await sdk?.start();
}
async function check() {
const result = await sdk?.checkLiveness();
if (result?.isOk) {
console.log('Verified!', result.jwt);
}
}
async function stop() {
await sdk?.stop();
}
</script>
<template>
<div ref="containerRef" style="width: 100%; height: 300px;" />
<button @click="start">Start</button>
<button @click="check">Check</button>
<button @click="stop">Stop</button>
</template>API
new LunaPassSDK(config)
Создаёт экземпляр SDK. Контейнер инициализируется сразу.
sdk.start()
Запрашивает доступ к камере и открывает WebSocket-соединение с сервером.
await sdk.start();sdk.checkLiveness()
Запускает сессию проверки живости. Отправляет кадры на сервер, рендерит подсказки, возвращает результат.
const result = await sdk.checkLiveness();
// result.isOk — успех или нет
// result.jwt — токен от сервера
// result.decodedJwt — декодированный payload JWT
// result.errors — коды ошибок если isOk: falseПосле завершения автоматически вызывает stop().
sdk.stop()
Уничтожает renderer, отключает камеру и закрывает WebSocket.
await sdk.stop();sdk.state
Возвращает текущее состояние SDK.
const { isCameraAttached, isWSConnected, isReady } = sdk.state;sdk.availableCameras
Возвращает список доступных камер.
const cameras = await sdk.availableCameras;sdk.switchCamera(index)
Переключает активную камеру по индексу.
await sdk.switchCamera(1);Опции
Основные
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
| serverUrl | string | — | URL WebSocket сервера |
| container | HTMLElement | — | DOM-элемент для камеры |
| width | string | '400px' | Ширина контейнера (любой CSS) |
| height | string | '300px' | Высота контейнера (любой CSS) |
| mode | 'selfie' \| 'operator' | 'selfie' | Режим сканирования |
| requestInterval | number | 200 | Интервал отправки кадров (мс) |
| debug | boolean | false | Включить debug-логи |
Коллбэки
| Опция | Тип | Описание |
|---|---|---|
| onStateChange | (state: LunaPassState) => void | Вызывается при изменении состояния |
| onResult | (result: LunaPassLivenessResult) => void | Вызывается на каждый кадр |
| onError | (error: Error) => void | Вызывается при ошибке |
Renderer
renderer?: {
graphics?: boolean; // Визуальные подсказки (стрелки, рамка лица)
text?: boolean; // Текстовые подсказки
errorMessages?: Record<number, string>; // Кастомные сообщения ошибок
successMessage?: string | null;
unsuccessMessage?: string | null;
sessionClosedMessage?: string | null;
}Типы
import type {
LunaPassConfig,
LunaPassState,
LunaPassLivenessResult,
LunaPassDecodedJWT,
} from '@uzum-tech/luna-pass';LunaPassState
interface LunaPassState {
isCameraAttached: boolean;
isVideoAttached: boolean;
isWSConnected: boolean;
ready: boolean;
}LunaPassLivenessResult
interface LunaPassLivenessResult {
isOk: boolean;
jwt?: string;
decodedJwt?: LunaPassDecodedJWT;
errors?: number[];
error?: unknown;
}LunaPassDecodedJWT
interface LunaPassDecodedJWT {
bestshot: string; // base64 лучшего кадра
errors: unknown[];
estimations: object;
iat: number;
isOk: boolean;
jti: string;
}Как работает
sdk.start()
└── attachCamera() → запрашивает камеру у браузера
└── connectWS() → открывает WebSocket соединение
sdk.checkLiveness()
└── каждые 200мс берёт кадр с камеры
└── отправляет FRAME на сервер
└── получает STATS ответ
└── рендерит подсказки через LPMessageRenderer
└── при успехе возвращает { isOk: true, jwt, decodedJwt }
└── автоматически вызывает stop()JWT генерируется на клиенте — внутри зашит лучший кадр (bestshot) в base64. Для верификации передай токен на свой бэкенд.
Авторы
| Имя | Контакт | |---|---| | Mardonov Baxtiyor | jbalancer.com | | Raxmatov Sanjar | [email protected] |
Organization: KapitalLab / Uzum Tech
