Expo
Learn how to implement biometric authentication as a PIN alternative in your Expo app
npx expo install expo-local-authentication
import React, { useState, useEffect } from 'react'; import { View, Text, TouchableOpacity, Alert } from 'react-native'; import * as LocalAuthentication from 'expo-local-authentication'; import { useCreateWallet } from '@chipi/sdk'; export default function BiometricAuth() { const [isBiometricSupported, setIsBiometricSupported] = useState(false); const { createWallet, isPending } = useCreateWallet(); useEffect(() => { checkBiometricSupport(); }, []); const checkBiometricSupport = async () => { const hasHardware = await LocalAuthentication.hasHardwareAsync(); const isEnrolled = await LocalAuthentication.isEnrolledAsync(); setIsBiometricSupported(hasHardware && isEnrolled); }; const authenticateWithBiometrics = async () => { try { const result = await LocalAuthentication.authenticateAsync({ promptMessage: 'Authenticate to access your wallet', fallbackLabel: 'Use PIN instead', }); if (result.success) { // Biometric authentication successful await createWallet(); Alert.alert('Success', 'Wallet created successfully!'); } else { Alert.alert('Authentication Failed', 'Please try again'); } } catch (error) { Alert.alert('Error', 'Biometric authentication failed'); } }; if (!isBiometricSupported) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Biometric authentication is not available on this device</Text> </View> ); } return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <TouchableOpacity onPress={authenticateWithBiometrics} disabled={isPending} style={{ backgroundColor: '#0ab785', padding: 16, borderRadius: 8, }} > <Text style={{ color: 'white', fontSize: 16 }}> {isPending ? 'Creating Wallet...' : 'Authenticate with Biometrics'} </Text> </TouchableOpacity> </View> ); }
const authenticateWithBiometrics = async () => { const result = await LocalAuthentication.authenticateAsync({ promptMessage: 'Verify your identity', fallbackLabel: 'Use PIN', cancelLabel: 'Cancel', disableDeviceFallback: false, requireAuthentication: true, }); };
const getBiometricType = async () => { const types = await LocalAuthentication.supportedAuthenticationTypesAsync(); if (types.includes(LocalAuthentication.AuthenticationType.FINGERPRINT)) { return 'fingerprint'; } else if (types.includes(LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION)) { return 'face'; } else if (types.includes(LocalAuthentication.AuthenticationType.IRIS)) { return 'iris'; } return 'none'; };