<h1 align="center">Age SDK Lite</h1>

#### <p align="center">Powered by Private Identity® <br/> [https://private.id](https://private.id)</p>

<p>
Age SDK Lite Implementation is an npm package that uses the W3C WebAssembly to perform 1:N fully homomorphically encrypted (FHE) face recognition. 
</p>

<h2> Note: This version (1.0.0) is a breaking change! </h2>
<p> Please update code accordingly because it might cause issue. </p>

#### BENEFITS
<ul>
    <li>Face biometric capture</li>
    <li>Encrypted face recognition every 200ms</li> 
    <li>1:n biometric match in 60ms constant time</li>
    <li>Human age estimation</li>
    <li>Unlimited users (unlimited gallery size)</li>
    <li>Fair, accurate and unbiased</li>
    <li>Preserves user privacy with neural network cryptography + fully homomorphic encryption (CryptoNets)</li>
    <li>IEEE 2410 Standard for Biometric Privacy, ISO 27001, ISO 9001 compliant</li>
    <li>Exempt from GDPR, CCPA, BIPA, and HIPAA privacy law obligations</li>
    <li>Predicts in 50ms with or without network using local storage</li>
</ul>

#### BUILD
<ul>
    <li>Verified Identity</li>
    <li>Web Sign-in</li>
    <li>Payments</li>
    <li>Phone Unlock</li>
    <li>Ticketless Access Control</li>
    <li>Account Recovery</li>
    <li>Face CAPTCHA</li>
</ul>

## Prerequisite

Sign up on the waitlist on https://private.id to obtain your apiKey.

Installation

```bsh
npm install @privateid/cryptonets-web-sdk
```

Copy the necessary dependencies to the public folder of your app

```bsh
"prestart": "cp -R ./node_modules/@privateid/cryptonets-web-sdk/wasm public/&& cp -R ./node_modules/@privateid/cryptonets-web-sdk/workers public/",
"prebuild": "cp -R ./node_modules/@privateid/cryptonets-web-sdk/wasm public/ && cp -R ./node_modules/@privateid/cryptonets-web-sdk/workers public/"
```

Add the necessary environment variables on the .env file in the root of your project


```bsh
SKIP_PREFLIGHT_CHECK=true
REACT_APP_API_URL= 
REACT_APP_API_KEY=
REACT_APP_WASM_MODULE= face_mask | face | voice
```

Optional environment variable

```bsh
REACT_APP_API_ORCHESTRATION=
REACT_APP_SET_CACHE= true | false (Used for predict caching)
```

## Load the WASM Module

The first step is to load and initialize the wasm module and clear the content of the local database.

```javascript
import { loadPrivIdModule, clearDB } from '@privateid/cryptonets-web-sdk';

const isSupported = await loadPrivIdModule();
clearDB();
```

In case of .env file (evironment variable) does not work for you we have added a support to set the variables on load.
```javascript
import { loadPrivIdModule } from '@privateid/cryptonets-web-sdk';

const isSupported =await loadPrivIdModule(
  api_url, 
  api_key,
  api_orchestration_url,
  wasm_url,
  wasm_module,
);
```

| Status        | Description                                                                     |
|---------------|---------------------------------------------------------------------------------|
| api_url    | Equivalent to env variable REACT_APP_API_URL |
| api_key | Equivalent to env variable REACT_APP_API_KEY |
| api_orchestration_url | Equivalent to env variable REACT_APP_API_ORCHESTRATION_URL |
| wasm_url | Please set it the same with api_url or REACT_APP_API_URL |
| wasm_module | face_mask , face , voice | 

The loadPrivIdModule() function returns an object to check if the device is supporting WASM and WebRTC.  
```javascript
{
    support: boolean,
    message: string,
}
```

## Open or switch camera or close camera

The first step is to load and initialize the wasm module.

#### Open the camera

To open user camera use the openCamera function with element id of the video tag in the DOM
```javascript
import { openCamera } from '@privateid/cryptonets-web-sdk';

const { devices, faceMode } = await openCamera(element);
```

it returns list of the available video devices.

#### Switch to another camera

To switch to another media device use the switchCamera function with the ID of the device to be used

```javascript
import { switchCamera } from '@privateid/cryptonets-web-sdk';

switchCamera(deviceID);
```

for the mobile phone we can select whether it's front or back camera for this we pass 'front' or 'back' to the switch function

```javascript
import { switchCamera } from '@privateid/cryptonets-web-sdk';

switchCamera('front');
```

#### Close the camera

To close user camera use the closeCamera function with element id of the video tag in the DOM. 
```javascript
import { closeCamera } from '@privateid/cryptonets-web-sdk';

closeCamera(element); // Will specifically look for the element id and will close that camera
closeCamera(); // By default will close opened camera using openCamera
```

## Predict Age 

Perform an age estimation using `predictAge` function on all detected faces from image or camera.

```javascript
import { predictAge } from '@privateid/cryptonets-web-sdk';

await predictAge(null, predictAgeCallback);

```

The function takes 3 parameters 


| Property | Description                                |
|----------|--------------------------------------------|
| imageData | If this parameter is provided it will check age of the imageData instead of opened camera. |
| callback   | The callback function to handle predictAge results.        |

Callback

Here are sample returned data to callback from predictAge :
```javascript
{
    "status": "WASM_RESPONSE",
    "returnValue": {
        "error": 0,
        "faces": [
            {
                "status": 0,
                "age": 16.912670135498047,
                "box": {
                    "top_left": {
                        "x": 486,
                        "y": 371
                    },
                    "bottom_right": {
                        "x": 652,
                        "y": 545
                    }
                }
            },
        ]
    }
}
```