@unbraided/kenal-ekyc-rn
v0.1.10
Published
Kenal eKYC SDK for React Native — document verification and face liveness
Downloads
778
Readme
@unbraided/kenal-ekyc-rn
React Native SDK for Kenal eKYC identity verification. Provides document scanning with on-device ML, face liveness detection, and a fully managed verification flow.
Features
- On-device document detection and auto-capture (ONNX Runtime)
- Automatic document type classification (MyKad, MyPR, MyTentera, Passport)
- MRZ detection and recognition for passports
- Face liveness verification (AWS Rekognition)
- Configurable theme, text strings, and custom screens
- Both imperative and component APIs
Installation
npm install @unbraided/kenal-ekyc-rnPeer Dependencies
Install the required peer dependencies:
npm install \
react-native-safe-area-context \
@react-navigation/native \
@react-navigation/stack \
react-native-gesture-handler \
react-native-reanimated \
react-native-screens \
react-native-svg \
react-native-fs| Package | Required | Tested with |
|---|---|---|
| react-native | >=0.76.0 | 0.83.1 |
| react-native-safe-area-context | >=4.0.0 | 5.6.2 |
| @react-navigation/native | >=7.0.0 | 7.1.28 |
| @react-navigation/stack | >=7.0.0 | 7.7.1 |
| react-native-gesture-handler | >=2.0.0 | 2.30.0 |
| react-native-reanimated | >=3.0.0 | 4.2.1 |
| react-native-screens | >=4.0.0 | 4.22.0 |
| react-native-svg | >=13.0.0 | 15.15.2 |
| react-native-fs | >=2.20.0 | 2.20.0 |
React Native 0.76–0.80: pin
react-native-reanimatedto v3, as Reanimated 4 requires RN 0.81+:npm install react-native-reanimated@^3.0.0
Reanimated v4+ (RN 0.81+): also requires
react-native-worklets— install it alongside Reanimated:
Add the Reanimated Babel plugin to your babel.config.js:
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['react-native-reanimated/plugin'],
};iOS Setup
Install pods:
cd ios && pod installAdd modular headers for ONNX Runtime in your
Podfile:pod 'onnxruntime-objc', :modular_headers => trueAdd camera permission to
Info.plist:<key>NSCameraUsageDescription</key> <string>Camera access is required for identity verification.</string>Minimum deployment target: iOS 14.0 (required by AWS Amplify FaceLiveness SwiftUI components)
Android Setup
Add camera permission to
AndroidManifest.xml:<uses-permission android:name="android.permission.CAMERA" />Enable core library desugaring in
app/build.gradle(required by AWS Amplify Liveness):android { compileOptions { coreLibraryDesugaringEnabled true } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' }Ensure Gradle configuration:
minSdk: 24+compileSdk: 35+
What's Included
The SDK ships native modules and ML models — no additional native code or manual file setup needed.
- Native modules (
KenalCameraModule,KenalLivenessModule) are bundled and auto-linked. The liveness module uses AWS Amplify, which the SDK configures lazily and safely (no conflict if your app already uses Amplify). - ONNX model files (~113 MB) for document detection, classification, and MRZ reading are bundled in the npm package and automatically included in your iOS/Android build via the podspec and Gradle config.
Quick Start
import { useState } from 'react';
import { Button, View } from 'react-native';
import { KenalEkyc, KenalEKYCView } from '@unbraided/kenal-ekyc-rn';
function App() {
const [showEkyc, setShowEkyc] = useState(false);
const startVerification = () => {
KenalEkyc.start({
apiKey: 'your-api-key',
environment: 'production',
refId: 'your-user-or-transaction-id', // your internal ID — returned via callback so you can link the result
name: 'John Doe',
idNumber: '901234-56-7890',
docIssueCountry: 'MYS', // ISO 3166-1 alpha-3; required for passport workflows; must match the MRZ issuing state
});
setShowEkyc(true);
};
if (showEkyc) {
return (
<KenalEKYCView
onCompleted={(result) => {
console.log('Verification:', result.verificationStatus); // 'Success' | 'Fail' | 'In Review'
console.log('Steps:', result.executions);
setShowEkyc(false);
}}
onCancelled={() => setShowEkyc(false)}
onError={(error) => {
if (error.isRetryable) {
console.warn(`Retryable error [${error.code}]: ${error.message}`);
} else {
console.error(`Fatal error [${error.code}]: ${error.message}`);
}
setShowEkyc(false);
}}
onExpired={() => setShowEkyc(false)}
/>
);
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Start Verification" onPress={startVerification} />
</View>
);
}Querying Status
You can query the status of any eKYC session at any time (even after the session has expired):
const status = await KenalEkyc.getStatus('validation-id', 'your-api-key', 'production');
console.log(status.verificationStatus); // 'Success' | 'Fail' | 'In Progress' | 'In Review'
console.log(status.executions); // [{ componentType: 'MyKad', result: 'Pass' }, ...]
console.log(status.reasons); // ['Customer Name Mismatch', ...] (empty if passed)Error Handling
The onError callback receives a KenalEkycError object:
interface KenalEkycError {
domain: 'SDK' | 'NETWORK' | 'SERVER'; // where the error originated
code: string; // machine-readable code (see below)
message: string; // human-readable message
isRetryable: boolean; // true → safe to retry; false → fatal
traceId?: string; // backend trace ID for support
}Common error codes by domain:
| Domain | Code | Retryable | Meaning |
|---|---|---|---|
| SDK | SDK_CAMERA_PERMISSION_DENIED | No | User denied camera access |
| SDK | SDK_MODEL_LOAD_FAILED | No | ONNX model failed to load |
| SDK | SDK_LIVENESS_CANCELLED | No | User cancelled the liveness check |
| NETWORK | NETWORK_UNREACHABLE | Yes | No internet connection |
| NETWORK | NETWORK_REQUEST_FAILED | Yes | Request failed or timed out |
| SERVER | SERVER_SESSION_EXPIRED | No | Session expired (also fires onExpired) |
| SERVER | SERVER_UPLOAD_FAILED | Yes | Document upload failed |
| SERVER | SERVER_UNAUTHORIZED | No | Invalid API key |
| SERVER | SERVER_MAX_RETRY_EXCEEDED | No | User exceeded maximum verification attempts |
Use isRetryable to decide whether to restart the flow or show a final error. For the full list of error codes, see Errors and Types.
Configuration
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiKey | string | required | API key from the Kenal admin portal |
| environment | 'sandbox' \| 'production' | 'sandbox' | Backend environment ('sandbox' for dev/testing, 'production' for live) |
| refId | string | required | Your application's reference ID for this eKYC session (e.g. a user ID or transaction ID). Passed back to your server via the webhook/callback URL so you can link the eKYC result to the correct record in your own system. |
| name | string | required | User's full name (matched against the document during verification — see note below) |
| idNumber | string | required | User's ID number, e.g. MyKad number or passport number (matched against the document during verification — see note below) |
| docIssueCountry | string | — | Passport issuing country. ISO 3166-1 alpha-3 (e.g. 'MYS', 'GBR', 'USA'). Required for passport workflows — session fails to start if omitted. Must match the MRZ issuing state code (see note below). |
| theme | Partial<KenalEkycTheme> | — | Style/theme overrides |
| texts | Partial<KenalEkycTexts> | — | Text label overrides for i18n |
| enableDebugLogs | boolean | false | Enable verbose debug logging |
| showDetectionOverlay | boolean | false | Show polygon detection overlay (debug) |
| enableDocumentLiveness | boolean | true | Enable document liveness step |
Why are
nameandidNumberrequired?eKYC verification has two parts: (1) extracting personal information from the document, and (2) cross-checking it against an external source for an additional layer of security. Typically, integrating platforms have already captured their user's personal information — by passing
nameandidNumberto the SDK, the extracted document data is verified against this trusted source. This ensures the document belongs to the person performing the verification.In a future release, these fields will become optional to support flows where the integrating platform relies on the SDK to extract the information and performs the cross-check on their own platform.
docIssueCountry— use the MRZ issuing state code, not the country of residenceThe value must be the ISO 3166-1 alpha-3 code that appears in the passport's MRZ (Machine Readable Zone). This is the issuing state, not necessarily the holder's country of residence. In most cases they are the same, but there are exceptions — for example, Hong Kong and Macau HKSAR passports are issued under the PRC, so the MRZ issuing state is
CHN. Pass'CHN', not'HKG'or'MAC'.If the value does not match what's in the passport's MRZ, the passport verification step will fail and the user will be rejected.
Customization
Theme
All theme keys are optional — only override what you need.
config={{
// ...
theme: {
primaryColor: '#1a73e8', // buttons, progress indicators
backgroundColor: '#ffffff', // non-camera screen backgrounds
textColor: '#111827', // primary text
textSecondaryColor: '#6b7280', // subtitles, hints
errorColor: '#dc2626', // error states
successColor: '#16a34a', // success states
buttonBorderRadius: 12, // button corner radius (px)
cardBorderRadius: 16, // card/container corner radius (px)
fontFamily: 'Inter', // optional font override
},
}}Text / Localisation
Override any string shown in the SDK UI. All keys are optional.
config={{
// ...
texts: {
// Camera screen
detectingCard: 'Place your document in the frame',
holdStill: 'Hold still...',
captured: 'Captured!',
flipToBack: 'Now scan the back',
// Session expired screen
sessionExpiredTitle: 'Session Expired',
sessionExpiredMessage: 'Your session has timed out. Please start again.',
sessionExpiredButton: 'Close',
// General
cancelButton: 'Cancel',
},
}}For the full list of available text keys, see SDK Reference → KenalEkycTexts.
Documentation
- Overview — Architecture, features, and flow lifecycle
- Getting Started — Installation, platform setup, and liveness module
- SDK Reference — Full API reference, types, and callbacks
- REST API — Backend endpoint specification
- Errors and Types — Error codes, ML engine specs
Platform Support
| Platform | Minimum Version | |----------|----------------| | iOS | 14.0+ (arm64) | | Android | API 24+ (Android 7.0) |
License
MIT
