@veryai/react-native-sdk
v1.0.50
Published
React Native wrapper for Very SDK - Palm biometrics verification
Readme
React Native SDK Integration
Full documentation: https://very.org/docs/native-sdk/integration
Installation
npm install @veryai/react-native-sdkFor iOS, install the native dependency:
cd ios && pod installAdd camera permission to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is needed for palm biometric verification.</string>Published on npm.
Asset Loading: Bundled vs Slim
The SDK ships with the palm-recognition native asset bundled inside it by default — your app works offline, no first-scan download wait. If you'd rather keep your binary small and have the SDK fetch the asset from CDN on first scan, you can opt into slim mode per platform.
| Mode | Adds to app size | First-scan UX | Works offline | | ------ | ----------------------------------------- | ---------------------------- | ------------- | | Bundled (default) | ~18 MB per ABI (Android), ~8 MB (iOS) | instant | yes | | Slim | nothing | one-time download (5–15 s) | no (first scan only) |
Cached assets persist across app launches; the download only happens once.
iOS — switching to slim
Step 1 — disable RN auto-linking for this package only. Add or edit react-native.config.js at your project root:
module.exports = {
dependencies: {
'@veryai/react-native-sdk': {
platforms: { ios: null },
},
},
};Step 2 — declare the slim subspec explicitly in ios/Podfile inside your app target:
target 'YourApp' do
config = use_native_modules!
use_react_native!(...)
pod 'veryai-react-native-sdk/Core',
:path => '../node_modules/@veryai/react-native-sdk'
endStep 3:
cd ios && pod installTo go back to bundled, delete the react-native.config.js entry and the pod 'veryai-react-native-sdk/Core' line, then pod install again.
Android — switching to slim
In android/app/build.gradle (the app module, not the project root), add:
android {
packaging {
jniLibs {
excludes += '**/libPalmAPISaas.so'
}
}
}This filters the bundled .so out at packaging time. The runtime falls through to CDN download.
Verifying which mode you're in
iOS — after pod install:
grep -c "VerySDK_BundledModel\|packed_data" ios/Pods/Pods.xcodeproj/project.pbxproj
# > 0 → bundled, 0 → slimAndroid — after a build:
unzip -l android/app/build/outputs/apk/debug/app-debug.apk | grep libPalmAPISaas
# matches → bundled, no output → slimCDN endpoints (slim mode)
The SDK tries the primary CDN first and falls back automatically. Allowlist both hostnames if your network has egress restrictions.
| Asset | Primary | Backup |
| -------------------------------- | ------------------------------------------------ | ------------------------------------------------------- |
| Android libPalmAPISaas.so (per ABI) | assets.very.org/sdk/data/<abi>/... | r2.assets.very.org/sdk/v1/<abi>/... |
| iOS packed_data.bin | assets.very.org/sdk/data/packed_data.bin | r2.assets.very.org/sdk/v1/packed_data.bin |
Getting an SDK Key
Native SDK keys are not yet available via the Developer Portal. Contact [email protected] to get your SDK key and client credentials.
Enroll a New User
Pass undefined for userId to register a new user. The SDK opens a consent screen, collects the user's email, then guides them through a palm scan.
import { VerySDK } from "@veryai/react-native-sdk";
const supported = await VerySDK.isSupported();
if (!supported) {
console.warn("Device not supported");
return;
}
const result = await VerySDK.authenticate({
sdkKey: "your_sdk_key",
userId: undefined, // undefined = new enrollment
themeMode: "dark",
presentationStyle: "fullScreen",
});
if (result.isSuccess) {
console.log("Auth code:", result.code);
console.log("User ID:", result.userId);
} else {
console.error("Error:", result.error, result.errorMessage);
}Verify an Existing User
Pass the user's ID from a previous enrollment to verify their identity.
const result = await VerySDK.authenticate({
sdkKey: "your_sdk_key",
userId: "vu-1ed0a927-...", // from previous enrollment
themeMode: "dark",
});
if (result.isSuccess) {
console.log("Verified:", result.code);
}Exchange the Auth Code (Backend)
When authentication succeeds, the SDK returns an authorization code. Send this to your backend, which exchanges it for an id_token:
POST https://api.very.org/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=your_client_id
&client_secret=your_client_secret
&code=AUTH_CODE_FROM_SDK
&redirect_uri=your_redirect_uriResponse:
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJhbGciOi..."
}Decode the id_token JWT to get the user's identity:
{
"iss": "https://connect.very.org",
"sub": "vu-1ed0a927-a336-45dd-9c73-20092db9ae8d",
"aud": ["your_client_id"],
"email": "[email protected]",
"exp": 1761013475,
"iat": 1761009875
}- For enrollment: store the
sub(user ID) — pass it asuserIdfor future verifications - For verification: confirm the
submatches the expected user
Important: The
client_secretfor token exchange must only be stored on your backend. Never embed it in the mobile app.
Configuration Reference
VeryConfig
| Parameter | Type | Default | Description |
| ------------------- | ------- | -------------- | ------------------------------------------------------------------ |
| sdkKey | String | required | Your SDK API key |
| userId | String? | undefined | Undefined for enrollment, user ID for verification |
| language | String? | device | Locale code (e.g. "en", "es", "ja"). 35 languages supported. |
| themeMode | String | "dark" | "dark" or "light" |
| presentationStyle | String | "fullScreen" | "fullScreen" or "bottomSheet". iOS presents modally regardless. |
| livenessMode | String? | "touch" | "gesture" or "touch". iOS only — Android always uses touch. |
| debugLogging | boolean | false | Verbose API request/response logging to the native console. |
Liveness-only flow not wrapped yet. The native SDKs also ship a standalone liveness check (
VeryAILiveness/VeryLivenessConfig) withshowError/showSuccessoptions. The React Native wrapper currently exposes only theauthenticate(palm-auth) flow; surfacing the liveness flow is tracked separately.
VeryResult
| Property | Type | Description |
| -------------- | ------- | ------------------------------------------------------------- |
| isSuccess | boolean | Whether authentication completed successfully |
| code | string | Authorization code to exchange for id_token on your backend |
| userId | string | The user's VeryAI ID |
| signedToken | string? | Signed JWT token (when available) |
| error | string? | Error code string |
| errorMessage | string? | Human-readable error message |
Requirements
- React Native 0.73+
- iOS 13.0+ / Android 6 (API 23)+
- Physical device (no simulator)
- Camera permission
Error Codes
The full list lives in the top-level README. One slim-mode-specific code worth calling out:
| Code | Name | Meaning |
|------|-------------------------------|------------------------------------------------------------------------|
| 6106 | NATIVE_LIB_DOWNLOAD_FAILED | Slim-mode partner: the SDK couldn't fetch the palm asset from CDN. Check internet, CDN allowlist, or revert to bundled mode. |
Use VerySDK.isSupported() to check device compatibility at runtime before showing the verification UI.
