# @nsure-ai/react-native-client-sdk

**Official React Native SDK wrapper for nSure (Android & iOS)**

Easily integrate the nSure SDK into your React Native applications using this unified npm package.

---

## Prerequisites

- **React Native 0.78+** (verified on 0.87)
- **Android**: minSdk 23+
- **iOS**: 14.0+

---

## Installation

Using npm:
```bash
npm install @nsure-ai/react-native-client-sdk
npx pod-install
```

---

## Usage

### Step 1: Initialize nSure SDK

Call `initialize` with your App ID, Partner ID, and optionally a `configBaseUrl` parameter (can be `null`) to override the default configuration endpoint:

```js
import NSure from '@nsure-ai/react-native-client-sdk';

// Basic initialization
await NSure.initialize('YOUR_APP_ID', 'OPTIONAL_PARTNER_ID');

// Optionally specify a custom configuration base URL (can be null)
await NSure.initialize('YOUR_APP_ID', 'OPTIONAL_PARTNER_ID', 'https://custom-config-url.com');
```
> **Note:**
> - On **Android**: `appId`, `partnerId`, and optional `configBaseUrl` (can be `null`) are passed into the native SDK.
> - On **iOS**: `appId`, `partnerId`, and optional `configBaseUrl` (can be `null`) are passed into the native SDK.

---

### Step 2: Retrieve Device ID

Once initialized, get the device ID:
```js
const deviceId = await NSure.getDeviceId();
```
This `deviceId` must be sent to your server to identify sessions.

---

### Step 3: Pass Device ID to Your Server

Include the `deviceId` in your API requests under `sessionInfo`:
```json
{
  "sessionInfo": {
    "deviceId": "DEVICE_ID_FROM_SDK"
  }
}
```

---

### Step 4: (Optional) Check SDK Version

At any time you can read the nSure SDK version:
```js
const sdkVersion = await NSure.getVersion();
console.log('nSure SDK Version:', sdkVersion);
```

---

## Native Dependencies

### Android (Gradle) - (Handled Automatically)

Your app does **not** need any manual changes. This package automatically adds:
```gradle
implementation 'com.github.nsure-ai:android-sdk:1.4.1'
implementation 'com.fingerprint.android:sdk:4.0.0'
```

### AndroidManifest.xml - Add screen-capture permission

In your **AndroidManifest.xml**, add:

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

This permission is required for nSure to detect when the user takes a screenshot.

### iOS (CocoaPods) - (Handled Automatically)

CocoaPods integration is driven by `nsure.podspec`. After installing:
```bash
npx pod-install
```
the nSure iOS SDK (`nSure` pod) is pulled via CocoaPods and the framework is embedded automatically.

---

## Architecture

The package exposes one Promise-based JS API (`initialize`, `getDeviceId`,
`getVersion`) over a native bridge that runs on both the **Old Architecture**
(Bridge) and the **New Architecture** (TurboModules). React Native 0.82 removed the
Old Architecture, so on 0.82+ the module always uses TurboModules; `newArchEnabled=false`
selects the Bridge implementation only on React Native 0.78-0.81. The correct path is
selected automatically — no app configuration required.

### Bridge files

| Layer | File | Role |
| --- | --- | --- |
| JS API | `src/index.js` | Default export; selects the native module and returns Promises |
| Spec | `src/NativeNSureSDK.ts` | Codegen TurboModule spec (`NSureSDKSpec`) |
| iOS | `ios/NSureSDK.mm` | Both arches in one file, split by `#ifdef RCT_NEW_ARCH_ENABLED` |
| Android (shared) | `android/src/main/.../NSureSDKImpl.java` | Real SDK calls; both arches delegate here |
| Android (old) | `android/src/oldarch/.../NSureSDK.java` | `ReactContextBaseJavaModule` + `@ReactMethod` |
| Android (new) | `android/src/newarch/.../NSureSDK.java` | Subclass of codegen `NativeNSureSDKSpec` |

### Old vs New bridge

- **Selection** is per-platform: iOS uses `#ifdef RCT_NEW_ARCH_ENABLED` in the
  single `.mm`; Android uses Gradle `oldarch`/`newarch` source sets; JS detects
  the TurboModule at runtime via `isTurbo()`.
- **iOS Old Architecture** is callback-based (`RCTResponseSenderBlock`), which
  `src/index.js` wraps into Promises. **iOS New Architecture and both Android
  arches** are natively Promise-based.
- Every arch funnels through the same native SDK (`NSureSDKImpl` / the shared
  `NSure` instance), so behavior is identical regardless of architecture.

---

## Troubleshooting

- **`Native Module "NSureSDK" is null`**
  • Make sure you've rebuilt your app (`npx react-native run-android` / `run-ios`)
  • Clear Metro cache: `npx react-native start --reset-cache`
  • Confirm `@nsure-ai/react-native-client-sdk` appears in `npx react-native config`

- **TurboModule argument errors**
  If you see "expected X arguments," ensure you're on RN 0.78+ and using the latest version of this package, which uses Promise‐based bridges.

- **App crashes with `EXC_BAD_ACCESS` or `performVoidMethodInvocation`**
  Ensure you are using version 1.4.0+ which supports both Old and New Architecture. If on an older version, upgrade or disable New Architecture.

---

## DEV-only Crash Lab harness (`crashLab` subpath)

Separate DEV-only fault-injection module
(`@nsure-ai/react-native-client-sdk/crashLab`) used to verify the RN
bridge's crash containment. Stripped from Release artifacts on both
platforms: iOS via `#if DEBUG` (`ios/CrashLab/`), Android via the
`src/debug/` source set (AGP excludes from release variants at compile
time), JS via `__DEV__` no-op. The `scripts/release-strip-check.sh`
gate verifies on every CI run.

Production consumers should NOT import the subpath. The default export
stays `{ initialize, getDeviceId, getVersion }`.

---

Happy coding! 🚀
