@valifysolutions/react-native-vidvdigitalcontract
v1.1.0
Published
React Native plugin for the VIDV Digital Contract SDK
Readme
VIDV Digital Contract — React Native Plugin
A React Native bridge for the VIDV Digital Contract native SDK. Identical functionality,
API design, and flow to the Flutter plugin (VIDVDigitalContractFlutter).
Requirements
| Platform | Minimum version | |----------|----------------| | iOS | 13.0 | | Android | API 24 (7.0) | | React Native | ≥ 0.70 |
Installation
# npm
npm install vidv-digital-contract-react-native
# yarn
yarn add vidv-digital-contract-react-nativeAndroid — repository credentials
The native SDK is hosted on Valify's private Artifactory. Add the repository to your
project-level build.gradle (or settings.gradle for newer React Native templates):
repositories {
maven {
credentials {
username "sdk"
password "sdk123456"
}
url "https://www.valifystage.com/artifactory/libs-release/"
}
maven { url "https://jitpack.io" }
maven { url "https://developer.huawei.com/repo/" }
}Android — manifest entries
Add the following to your app's AndroidManifest.xml. Both the main activity and the
SDK host activity must share the same taskAffinity so the flow returns correctly:
<activity
android:name=".MainActivity"
android:taskAffinity="com.yourapp.example"
android:launchMode="singleTop"
... />
<!-- Required SDK host activity -->
<activity
android:name="me.vidv.vidvdigitalcontractsdk.VIDVDigitalContractHostActivity"
android:exported="true"
android:taskAffinity="com.yourapp.example"
android:documentLaunchMode="never"
android:excludeFromRecents="true"
tools:replace="android:taskAffinity,android:documentLaunchMode,android:excludeFromRecents" />Also add packaging exclusions in app/build.gradle:
packagingOptions {
pickFirst 'META-INF/versions/9/OSGI-INF/MANIFEST.MF'
}iOS — CocoaPods
cd ios && pod installThe plugin's podspec depends on VIDVDigitalContract ~> 1.1.0. Make sure your team has
access to the CocoaPods source for this pod, or point your Podfile to the private spec repo.
Usage
import { startDigitalContract } from 'vidv-digital-contract-react-native';
import type { DigitalContractResponse } from 'vidv-digital-contract-react-native';
async function launch() {
const response: DigitalContractResponse = await startDigitalContract({
vidvBaseUrl: 'https://www.valifystage.com/',
dcBaseUrl: 'https://valify.staging.knfrm.com/',
bundleKey: '<your-bundle-key>',
vidvAccessToken: '<vidv-oauth-token>',
dcAccessToken: '<dc-auth-token>',
tenantId: '<tenant-id>',
userReferenceId: 'user-123',
language: 'en', // 'en' or 'ar'
templateVersionId: 2,
contractExpiryMinutes: 30,
contractData: JSON.stringify([
{ field_id: '1', value: 'John' },
{ field_id: '2', value: 'Doe' },
]),
allowHandSignature: false, // optional
});
switch (response.state) {
case 'SUCCESS':
console.log('Contract signed!', response.result);
break;
case 'FAILURE':
console.warn('Service failure', response.result);
break;
case 'ERROR':
console.error('Builder error', response.result);
break;
case 'EXIT':
console.log('User exited', response.result);
break;
}
}API
startDigitalContract(config)
Returns Promise<DigitalContractResponse>.
DigitalContractConfig
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| vidvBaseUrl | string | ✓ | VIDV backend base URL |
| dcBaseUrl | string | ✓ | Digital Contract backend base URL |
| bundleKey | string | ✓ | Your integration bundle key |
| vidvAccessToken | string | ✓ | OAuth token from VIDV (/api/o/token/) |
| dcAccessToken | string | ✓ | Auth token from DC (/api/v1/auth-token) |
| tenantId | string | ✓ | Tenant ID returned with DC token |
| userReferenceId | string | ✓ | Your internal user identifier |
| language | 'en' \| 'ar' | ✓ | UI language |
| templateVersionId | number | ✓ | Contract template version (> 0) |
| contractExpiryMinutes | number | ✓ | Session expiry in minutes (> 0) |
| contractData | string | ✓ | JSON array of {field_id, value} objects |
| allowHandSignature | boolean | — | Enable hand-signature capture |
DigitalContractResponse
{
state: 'SUCCESS' | 'ERROR' | 'FAILURE' | 'EXIT';
result: {
// SUCCESS
data?: { contractID?: string; iframeURL?: string; contractStatus?: string };
// ERROR (builder validation)
code?: string | number;
message?: string;
// FAILURE (service error)
code?: string | number;
message?: string;
data?: DigitalContractData;
sdkError?: { errorCode?: string | number; message?: string };
// EXIT (user cancelled)
step?: string;
data?: DigitalContractData;
};
}Token fetching
Tokens are not fetched by the plugin — your app must obtain them before calling
startDigitalContract.
VIDV token (OAuth password grant)
const res = await fetch(`${vidvBaseUrl}/api/o/token/`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `username=...&password=...&client_id=...&client_secret=...&grant_type=password`,
});
const { access_token } = await res.json();DC token (HMAC-SHA256 authenticated)
import CryptoJS from 'crypto-js';
const body = JSON.stringify({ username, password, client_id, client_secret });
const hmac = CryptoJS.HmacSHA256(body, secretKey).toString(CryptoJS.enc.Hex);
const res = await fetch(`${dcBaseUrl}/api/v1/auth-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', hmac },
body,
});
const { data: { token, tenant_id } } = await res.json();Example app
A complete demo app is located in example/. It mirrors the Flutter example app exactly.
cd example
yarn install
# iOS
cd ios && pod install && cd ..
yarn ios
# Android
yarn androidNative SDK versions
| Platform | SDK | Version |
|----------|-----|---------|
| Android | com.vidv:vidvdigitalcontractsdk | 1.2.1 |
| iOS | VIDVDigitalContract (CocoaPod) | ~> 1.1.0 |
