DEA SDK for React Native¶
Detect whether an app session comes from a real person. The SDK observes touch and device-motion input across your whole React Native app, natively on Android and iOS, and scores the session on the device.
On this page: Prerequisites · Install · Initialize the SDK · Ask for consent · Use the classification · Verify your setup · Before you release · Next steps
Prerequisites¶
- An
appIdandappKeyfor each platform's app — see Accounts and keys. On Android, also the Google Cloud project number DEA issued for Play Integrity — see Attest. - React Native 0.76 or later, with the New Architecture enabled. The SDK is a TurboModule and does not load on the old architecture.
- Android:
minSdkVersion24 (Android 7.0) or later - iOS: deployment target 15.1 or later
The SDK runs on Android and iOS. Other React Native targets (web, Windows, macOS) are not
supported: init rejects there.
Expo¶
Expo Go is not supported. The SDK contains native code that is not part of Expo Go.
The package ships no Expo config plugin, so npx expo prebuild does not add the iOS and Android
setup described below to the native projects it generates.
Install¶
Not available yet.
@dea/react-nativeis not published: it is not on the npm registry, and the 0.19.0 release lists no React Native package. The package also needs DEA's native Android and iOS SDKs at its own version, and neither of those can be installed either: DEA's Maven repository (https://sdk.dep-protocol.com/maven) servesai.dea:dea-sdk0.2.2 only, and no podspec or Swift package of the native iOS SDK is published. No install command for React Native works at this release.
The JavaScript package wraps DEA's native Android and iOS SDKs. React Native's autolinking links
both native halves. Each half depends on the native SDK at the same version as
@dea/react-native.
iOS setup¶
Not available yet. The iOS half of the package depends on the
DeaSDKpod (which depends onDeaBase). Neither pod is on the CocoaPods trunk or in any published spec repository, sopod installcannot resolve them.
The package's pod requires an iOS deployment target of 15.1 or later.
Android setup¶
Not available yet. The Android half of the package depends on
ai.dea:dea-sdkat the same version as@dea/react-native, resolved from the repositories your app declares. DEA's Maven repository serves 0.2.2 only, and the artifact is not on Maven Central, so Gradle cannot resolve it.
The native Android SDK declares the INTERNET permission, which Android's manifest merger adds to
your app.
Initialize the SDK¶
Initialize once, as early as possible — at the top level of your entry file or in your root component's first effect — so that capture covers the whole session.
import {useEffect} from 'react';
import * as Dea from '@dea/react-native';
import {Root} from './Root';
export default function App() {
useEffect(() => {
Dea.init({appId: 'YOUR_APP_ID'}).then(started => {
if (!started.ready) {
console.warn('DEA cannot score:', started.coreFault);
}
});
}, []);
return <Root />;
}
- Every call returns a promise, including the cheap ones. Await them when the order matters.
initis safe to call more than once. A repeat call returns the running session and keeps its options.initdoes not fail when the scoring engine cannot start. The SDK keeps capturing,started.readyisfalse, andstarted.coreFaultsays why.- Capture is global: every touch in the app, the motion sensors, and the app lifecycle. There is no component to wrap your app in and nothing to register per screen.
- Every other call except
deaTarget,getTargetTallyandonAttestationEventrejects untilinithas run. - Nothing is recorded until the user consents. See the next step.
Note: Pass
appKeytoinitas well — the key of the platform the build is for. Reading the classification does not need it: scoring runs on the device. Without it, with a productionappId,attest()resolvesunsupportedwithout contacting DEA. See Accounts and keys for what the key is for.
Ask for consent¶
By default the SDK records nothing until the user agrees. This step is required: an app that never asks collects no data and never gets a classification.
The React Native SDK has no built-in consent dialog. Ask with your own UI, then record the answer:
import {Alert} from 'react-native';
import * as Dea from '@dea/react-native';
export async function askForConsent(): Promise<void> {
if ((await Dea.getConsent()) !== 'unknown') return; // already answered
Alert.alert(
'Help us keep bots out',
'We measure how you touch and hold your phone to tell people apart from bots. We never record what you type or what is on your screen.',
[
{text: 'Not now', style: 'cancel', onPress: () => Dea.setConsent(false)},
{text: 'Allow', onPress: () => Dea.setConsent(true)},
],
);
}
The answer is stored on the device, so the question only needs to be asked once. If you already
asked before init, pass the answer to init instead — see
User Consent. What the SDK captures, and what it never
reads, is on Privacy and network.
Use the classification¶
Read the classification at the moment you make a decision. The read is fast and local: it does not call the network.
import * as Dea from '@dea/react-native';
async function onSignUp(form: SignUpForm) {
const {result} = await Dea.getClassification();
if (result === 'human') {
await submitSignUp(form);
} else {
showChallenge(); // 'bot', 'undetermined' or 'insufficient': a captcha, a delay, a manual review
}
}
The thresholds come from the loaded model, never from your app.
insufficient and undetermined are answers in their own right, and your app decides what each
allows. insufficient means the session is not
sufficient yet, because it has fewer
actions than the model asks for (8 with the built-in model, see
Evidence); value is null then. undetermined
means the score is between the two thresholds. See
How scoring works.
Verify your setup¶
- Check the SDK from code after
init:
const started = await Dea.init({appId: 'YOUR_APP_ID'});
console.log('ready:', started.ready); // true
console.log('fault:', started.coreFault); // null
console.log('sdk:', started.sdkVersion);
const info = await Dea.getSessionInfo();
console.log('session:', info.session); // a UUID
- Grant consent, use the app — tap, scroll, swipe — for at least 8 actions, then read the classification:
console.log(await Dea.getConsent()); // 'granted'
console.log(await Dea.getClassification());
// { result, value, actions, botThreshold, humanThreshold, modelVersion }
result leaves 'insufficient' once actions reaches the number the model asks for: 8 with the
built-in model.
- On Android, you can also turn on
debugand watch Logcat:
You should see one [dea] … line per captured event after consent is granted. If you see
nothing after touching the screen, see Troubleshooting.
Turn debug off before you ship.
Before you release¶
- [ ]
debugisfalse - [ ] Your consent flow calls
setConsent, or passesconsenttoinit— see User Consent - [ ] The classification is read at the decision point, with a fallback for
bot,undeterminedandinsufficient— see Human Scoring - [ ] Your main controls are named with
deaTarget— see Name your views - [ ] Capture is paused on password and payment screens — see Sensitive Screens
- [ ]
reset()is called on logout — see Sessions - [ ] Your privacy policy covers what the SDK captures and sends — see Privacy and network and Going to production
Next steps¶
- User Consent — ask before anything is recorded
- Human Scoring — read the classification, and name your views
- Sensitive Screens — pause capture on password and payment screens
- Sessions — start a new session on logout
- Options — every option
initaccepts - How scoring works — sessions, evidence, the model and its thresholds
- Accounts and keys — the
appIdandappKeyDEA issues - Troubleshooting