# FACEKI Blaze React Native SDK

<p align="center">
  <strong>Know Your Customer (KYC) SDK for React Native — v2.0.0</strong>
</p>

---

## Requirements

| Requirement | Minimum Version |
|---|---|
| React Native | **>= 0.84.1** |
| React | **>= 19.x** |
| iOS Deployment Target | **15.1** |
| Android `minSdkVersion` | **24** |
| New Architecture | **Required** (`newArchEnabled=true`) |

> **Breaking change (v2.0.0) and above:** React Native New Architecture is now required. If you are on RN < 0.84 or still using the old architecture, stay on v1.x.

---

## Client ID and Client Secret

Create an account on the Faceki Dashboard to obtain your credentials:
[https://intelligence.faceki.com/](https://intelligence.faceki.com/)

---

## Installation

### Step 1 — Install the SDK

```bash
npm install @faceki/blaze-react-native
```

### Step 2 — Install peer dependencies

All of these packages are required. Install them in your **app** project (not inside the SDK):

```bash
npm install react-native-vision-camera@">=4.7.0"
npm install lottie-react-native@">=7.0.0"
npm install @bam.tech/react-native-image-resizer@">=3.0.11"
npm install react-native-loading-spinner-overlay@">=3.0.0"
npm install react-native-safe-area-context@">=5.0.0"
npm install react-native-toast-message@">=2.0.0"
npm install react-native-vector-icons@">=10.0.0"
npm install react-native-fs">=2.20.0"
npm install @react-native-community/geolocation@">=3.4.0"

```

Or install them all in one command:

```bash
npm install react-native-vision-camera lottie-react-native @bam.tech/react-native-image-resizer react-native-loading-spinner-overlay react-native-safe-area-context react-native-toast-message react-native-vector-icons react-native-fs @react-native-community/geolocation
```

### Step 3 — Android setup

#### 3a. Camera and location permissions

Add to `android/app/src/main/AndroidManifest.xml`:

```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

```

`ACCESS_FINE_LOCATION` is required so the SDK can capture GPS automatically.

#### 3b. GIF support

Add to `android/app/build.gradle` inside `dependencies { }`:

```gradle
// Animated GIF support
implementation("com.facebook.fresco:animated-gif:2.5.0")
```

#### 3c. Vector icons font

Add to `android/app/build.gradle` (top of file, after `apply plugin`):

```gradle
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
```

#### 3d. Enable New Architecture

In `android/gradle.properties` make sure this is set:

```properties
newArchEnabled=true
```

### Step 4 — iOS Info.plist

Add to `ios/<YourProject>/Info.plist`:

```xml
<!-- Camera permission -->
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Location.</string>

<!-- Vector icons fonts -->
<key>UIAppFonts</key>
<array>
    <string>AntDesign.ttf</string>
    <string>Entypo.ttf</string>
    <string>EvilIcons.ttf</string>
    <string>Feather.ttf</string>
    <string>FontAwesome.ttf</string>
    <string>FontAwesome5_Brands.ttf</string>
    <string>FontAwesome5_Regular.ttf</string>
    <string>FontAwesome5_Solid.ttf</string>
    <string>Fontisto.ttf</string>
    <string>Foundation.ttf</string>
    <string>Ionicons.ttf</string>
    <string>MaterialCommunityIcons.ttf</string>
    <string>MaterialIcons.ttf</string>
    <string>Octicons.ttf</string>
    <string>SimpleLineIcons.ttf</string>
    <string>Zocial.ttf</string>
</array>
```

### Step 5 — iOS Podfile

Add the following **before** `platform :ios` in your `ios/Podfile`. This patch automatically fixes a known compatibility issue with `@bam.tech/react-native-image-resizer` on every `pod install`, including after `npm install` overwrites the podspec.

```ruby
# ---------------------------------------------------------------------------
# Patch @bam.tech/react-native-image-resizer podspec for New Architecture.
# Its podspec has a hard dependency on `RCT-Folly` which was removed in RN 0.71+.
# This function runs before CocoaPods reads the spec and is idempotent.
# ---------------------------------------------------------------------------
def patch_image_resizer_podspec(podfile_dir)
  podspec_path = File.expand_path(
    '../node_modules/@bam.tech/react-native-image-resizer/react-native-image-resizer.podspec',
    podfile_dir
  )
  return unless File.exist?(podspec_path)
  content = File.read(podspec_path)
  return unless content.include?('"RCT-Folly"')
  patched = content.gsub(
    /\n  # Don't install the dependencies.*?  end\n/m,
    "\n  install_modules_dependencies(s)\n"
  )
  if content != patched
    File.write(podspec_path, patched)
    Pod::UI.puts '[Patch] Fixed react-native-image-resizer podspec for New Architecture'
  end
end
patch_image_resizer_podspec(__dir__)
# ---------------------------------------------------------------------------

platform :ios, min_ios_version_supported
```

Also, inside your `target` block, add:

```ruby
target 'YourAppName' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )
  # ...
end
```

### Step 6 — pod install

```bash
cd ios && pod install && cd ..
```

### Step 7 — Rebuild the app

```bash
# iOS
npx react-native run-ios

# Android
npx react-native run-android
```

---

## Usage

### Generate a KYC Link

Before using the SDK you must generate a KYC link from the Faceki API:

[https://docs.faceki.com/api-integration/verification-apis/generate-kyc-link](https://docs.faceki.com/api-integration/verification-apis/generate-kyc-link)

Use the `data` value from the response as `verification_url`.

### Basic Usage

```jsx
import FacekiApp from '@faceki/blaze-react-native';

<FacekiApp
  verification_url="XXXX-XXXX-xxxX-XxXXX"
  onError={(error) => console.log('Error', error)}
  onComplete={(data) => console.log('KYC data', data)}
/>
```

### Advanced Usage

```jsx
import FacekiApp from '@faceki/blaze-react-native';
import type { Branding } from '@faceki/blaze-react-native/src/service/types/interfaces';

const customBranding: Branding = {
  colors: {
    primary: '#F8B427',
    secondary: '#343333',
    buttonColor: 'rgba(253, 181, 40, 0.10)',
    success: '#59C547',
    danger: '#FF3B30',
    warning: '#FF9500',
    info: '#5AC8FA',
    light: '#F5F5F5',
    dark: '#1C1C1E',
    background: '#f5f5f5',
    backgroundSecondary: '#eeeeee',
    backgroundCaptureBtn: '#F6F6F7',
    textDefault: '#444343',
    textSecondary: '#3E3E3E',
    fontRegular: 'Inter',
    fontMedium: 'Inter-Medium',
    fontBold: 'Inter-Bold',
    title_color: '#F8B427',
    title_camera_color: '#F8B427',
  },
  images: {
    card_guidance: '',   // optional custom image URL
    selfie_guidance: '', // optional custom image URL
  },
};

<FacekiApp
  verification_url="XXXX-XXXX-xxxX-XxXXX"
  record_identifier="unique-id-from-your-side"
  onError={(error) => console.log('ERROR', error)}
  onComplete={(data) => console.log('EKYCdata', data)}
  onCancel={() => console.log('User cancelled')}
  onLivenessError={(imageBase64, response) => console.log(imageBase64, response)}
  resultContent={{
    success: { heading: '', subHeading: '' },
    fail: { heading: '', subHeading: '' },
  }}
  consenttermofuseLink="https://faceki.com"
  logoURL="https://example.com/logo.png"
  skipFirstScreen={false}
  skipGuidanceScreens={false}
  skipResultScreen={false}
  branding={customBranding}
  language="en"    {/* 'en' (default) or 'ar' for Arabic */}
/>
```

### Props Reference

| Prop | Type | Required | Description |
|---|---|---|---|
| `verification_url` | `string` | **Yes** | KYC link generated from Faceki API |
| `record_identifier` | `string` | No | Unique ID from your system for this verification |
| `onError` | `(error: any) => void` | **Yes** | Called when a fatal error occurs |
| `onComplete` | `(data: any) => void` | **Yes** | Called when KYC flow completes successfully |
| `onCancel` | `() => void` | No | Called when the user taps the close (✕) button to cancel the flow |
| `onLivenessError` | `(imageBase64: string, response: any) => void` | No | Called when liveness check fails |
| `resultContent` | `{ success: { heading, subHeading }, fail: { heading, subHeading } }` | No | Customise result screen text |
| `consenttermofuseLink` | `string` | No | URL for Terms of Use link on consent screen |
| `logoURL` | `string` | No | URL of your logo shown in the SDK |
| `skipFirstScreen` | `boolean` | No | Skip the "Getting Started" screen (default `false`) |
| `skipGuidanceScreens` | `boolean` | No | Skip guidance/instruction screens (default `false`) |
| `skipResultScreen` | `boolean` | No | Skip result screen and handle outcome via callbacks (default `false`) |
| `branding` | `Branding` | No | Custom colors and images |
| `language` | `'en' \| 'ar'` | No | UI language — `'en'` English (default) or `'ar'` Arabic with RTL layout |

---

## Upgrading from v1.x to v2.0.0 and above

v2.0.0 and above requires **React Native New Architecture** and **React 19**. Follow these steps carefully.

### Step 1 — Update the SDK

```bash
npm install @faceki/blaze-react-native@2.0.0
```

### Step 2 — Install all peer dependencies

Run the one-liner from [Step 2 of Installation](#step-2--install-peer-dependencies) above. All native packages that were previously bundled inside the SDK must now be installed in **your project**.

### Step 3 — Enable New Architecture on Android

In `android/gradle.properties`:

```properties
newArchEnabled=true
```

### Step 4 — Upgrade React Native (if needed)

v2.0.0 and above requires RN >= 0.84.1. Use the [React Native Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) to migrate if you are on an older version.

### Step 5 — Add the Podfile patch function (iOS)

Add the `patch_image_resizer_podspec` Ruby function to your `ios/Podfile` as described in [Step 5 of Installation](#step-5--ios-podfile). This replaces the manual one-time patch that was required in v1.x.

### Step 6 — Re-install pods and rebuild

```bash
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
npx react-native run-ios
```

---

## Troubleshooting

### `system/camera-module-not-found`

**Cause:** The native camera module is not linked because `react-native-vision-camera` is missing from your app's `node_modules`.

**Fix:** Make sure all peer dependencies are installed in your **app** project (see [Step 2](#step-2--install-peer-dependencies)). Running `npm install` at the SDK root is not enough — the packages must be in your app.

---

### `RCT-Folly` build error on iOS

**Cause:** `@bam.tech/react-native-image-resizer` podspec references the removed `RCT-Folly` pod.

**Fix:** Add the `patch_image_resizer_podspec` function to your Podfile (see [Step 5](#step-5--ios-podfile)). It runs automatically on every `pod install`.

---

### Vector icons not appearing

**Android:** Add to `android/app/build.gradle`:

```gradle
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
```

If you get a Gradle task error in release builds, add this workaround to `node_modules/react-native-vector-icons/fonts.gradle`:

```gradle
android.applicationVariants.all { variant ->
    def targetName = variant.name.capitalize()
    def lintTask = tasks.findByName("lintVitalAnalyze${targetName}")
    if (lintTask) { lintTask.dependsOn(fontCopyTask) }
    def assetsTask = tasks.findByName("generate${targetName}Assets")
    assetsTask.dependsOn(fontCopyTask)
}
```

See the [GitHub discussion](https://github.com/oblador/react-native-vector-icons/issues/1508) for context.

**iOS:** Add the `UIAppFonts` array to `Info.plist` (see [Step 4](#step-4--ios-infoplist)).

---

### Full clean & reinstall

When all else fails, do a full clean:

```bash
rm -rf node_modules yarn.lock
watchman watch-del-all
cd ios && rm -rf Pods Podfile.lock && pod deintegrate && pod cache clean --all && cd ..
npm install
cd ios && pod install && cd ..
```

---

## Camera permissions at runtime (iOS)

The SDK requests permissions at runtime for its flow:

- Camera: requested by SDK.
- Location: SDK attempts to fetch location automatically on both platforms.

On iOS, `NSLocationWhenInUseUsageDescription` is mandatory in `Info.plist` so the OS can show the location permission prompt.

---

## Changelog

* **2026-05-11 — 2.0.2**
  #### Breaking Changes
  * Install @react-native-community/geolocation in Peer Dependency
  #### Improvements
  * Added Support for geolocation


* **2026-05-11 — 2.0.1**
  #### Breaking Changes
  * Install react-native-fs in Peer Dependency

  #### Improvements
  * Fix issue with OnLivenessError Callback
  * Fix View Scroll on Android and iOS
  * Updated Selfie Liveness Guidance



* **2026-03-29 — 2.0.0**

  #### Breaking Changes
  * **React Native New Architecture is now required** (`newArchEnabled=true`, RN >= 0.84.1, React >= 19.x). If you are on an older stack, stay on v1.x.
  * Peer dependencies must now be installed explicitly in your **app** project. They are no longer bundled inside the SDK.

  #### New Features
  * **`onCancel` prop** — optional `() => void` callback fired when the user taps the close (✕) button. A close button is now shown in the top-right corner on every screen (header, selfie camera, document camera). When `onCancel` is not provided the button is hidden.
  * **Arabic language & RTL support** — pass `language="ar"` to switch all UI strings to Arabic and enable a full right-to-left layout. English remains the default (`language="en"`). The translation layer is self-contained (no external i18n library).

* **2025-08-07 — 1.0.9**
  * Updated React Native version support to 0.75.4

* **2024-11-26 — 1.0.8**
  * Added `title_color` and `title_camera_color` in Branding
  * Updated Icons

* **2024-05-03 — 1.0.7**
  * Added `onLivenessError` callback

* **2024-05-03 — 1.0.6**
  * Support for Vision Camera V4 (4.5.3)
  * Support for React Native 0.74.x

* **2024-05-03 — 1.0.5**
  * Replaced Client ID/Secret with generated KYC link flow

* **2024-02-26 — 1.0.4**
  * Image resize/compress added (fixes issue #413)

* **2024-02-25 — 1.0.3**
  * Updated guidance GIFs

* **2024-02-25 — 1.0.2**
  * Updated Vector Icons to latest

* **2024-02-14 — 1.0.1**
  * Upgraded React Vision Camera V2 → V3

* **2024-01-24 — 1.0.0**
  * Initial release
