Skip to content

Complete Example

A full React Native screen that initializes the SDK, performs a scan, listens for security events, and displays the results:

import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
SafeAreaView,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import { AlphynSDK, RiskFactor, type ScanResult } from '@alphyn/react-native-sdk';
type SecurityStatus = 'loading' | 'trusted' | 'flagged' | 'untrusted' | 'error';
export function SecurityOverviewScreen() {
const [status, setStatus] = useState<SecurityStatus>('loading');
const [scanResult, setScanResult] = useState<ScanResult | null>(null);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
useEffect(() => {
let mounted = true;
async function bootstrap() {
try {
await AlphynSDK.initialize({
scanInterval: 45,
androidDebugHash: __DEV__ ? 'YOUR_ANDROID_DEBUG_HASH' : undefined,
iosDebugHash: __DEV__ ? 'YOUR_IOS_DEBUG_HASH' : undefined,
});
const result = await AlphynSDK.performScan();
if (!mounted) return;
setScanResult(result);
setStatus(classifyStatus(result));
} catch (error) {
if (!mounted) return;
setErrorMessage(error instanceof Error ? error.message : String(error));
setStatus('error');
}
}
const listener = AlphynSDK.addSecurityListener((event) => {
console.log('Security event:', event.originalEventType, event.message);
});
bootstrap();
return () => {
mounted = false;
listener.remove();
};
}, []);
if (status === 'loading') {
return (
<SafeAreaView style={styles.center}>
<ActivityIndicator />
<Text style={styles.subtitle}>Initializing Alphyn SDK...</Text>
</SafeAreaView>
);
}
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.content}>
<Text style={styles.title}>Security Overview</Text>
<Text style={styles.status}>Status: {status.toUpperCase()}</Text>
{errorMessage ? <Text style={styles.error}>{errorMessage}</Text> : null}
{scanResult ? (
<View style={styles.card}>
<Text style={styles.label}>Device ID</Text>
<Text style={styles.value}>{scanResult.deviceId}</Text>
<Text style={styles.label}>App Hash</Text>
<Text style={styles.value}>{scanResult.appHash}</Text>
<Text style={styles.label}>Primary Risk Factor</Text>
<Text style={styles.value}>{scanResult.primaryRiskFactor}</Text>
<Text style={styles.label}>All Risk Factors</Text>
<Text style={styles.value}>
{scanResult.allRiskFactors.length > 0
? scanResult.allRiskFactors.join(', ')
: RiskFactor.DEVICE_CLEAN}
</Text>
<Text style={styles.label}>Reject Reasons</Text>
<Text style={styles.value}>
{scanResult.rejectReasons.length > 0
? scanResult.rejectReasons.join('\n')
: 'No threats detected'}
</Text>
</View>
) : null}
</ScrollView>
</SafeAreaView>
);
}
function classifyStatus(result: ScanResult): SecurityStatus {
if (result.isSafe) return 'trusted';
if (result.rejectReasons.length < 3) return 'flagged';
return 'untrusted';
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#fff' },
content: { padding: 24, gap: 16 },
center: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12 },
title: { fontSize: 28, fontWeight: '700' },
subtitle: { fontSize: 16, color: '#666' },
status: { fontSize: 16, fontWeight: '600' },
error: { color: '#b42318' },
card: { padding: 16, borderRadius: 12, borderWidth: 1, borderColor: '#ddd', gap: 8 },
label: { fontSize: 12, fontWeight: '700', color: '#666', textTransform: 'uppercase' },
value: { fontSize: 14, color: '#111' },
});