diff --git a/src/screen/LockScreen.tsx b/src/screen/LockScreen.tsx
new file mode 100644
index 0000000..3be0454
--- /dev/null
+++ b/src/screen/LockScreen.tsx
@@ -0,0 +1,70 @@
+import React, { useState } from 'react';
+import {
+ View,
+ Text,
+ TouchableOpacity,
+ TextInput,
+ Alert,
+} from 'react-native';
+import { verifyPin } from '../auth/AppPinService';
+import { unlockWithDevice, unlockApp } from '../auth/AuthManager';
+
+const LockScreen = ({ onUnlock }: any) => {
+ const [pin, setPin] = useState('');
+
+ const handlePinUnlock = async () => {
+ const valid = await verifyPin(pin);
+ if (valid) {
+ await unlockApp();
+ onUnlock();
+ } else {
+ Alert.alert('Wrong PIN');
+ }
+ };
+
+ const handleDeviceUnlock = async () => {
+ const res = await unlockWithDevice();
+ if (res.success) {
+ await unlockApp();
+ onUnlock();
+ } else {
+ Alert.alert('Authentication Failed');
+ }
+ };
+
+ return (
+
+
+ Enter App PIN
+
+
+
+
+
+
+ Unlock with PIN
+
+
+
+
+
+ Unlock with Device Lock
+
+
+
+ );
+};
+
+export default LockScreen;
diff --git a/src/screen/SetPinScreen.tsx b/src/screen/SetPinScreen.tsx
new file mode 100644
index 0000000..18946ad
--- /dev/null
+++ b/src/screen/SetPinScreen.tsx
@@ -0,0 +1,31 @@
+import React, { useState } from 'react';
+import { View, TextInput, Text, TouchableOpacity } from 'react-native';
+import { savePin } from '../auth/AppPinService';
+
+const SetPinScreen = ({ onDone }: any) => {
+ const [pin, setPin] = useState('');
+
+ const save = async () => {
+ await savePin(pin);
+ onDone();
+ };
+
+ return (
+
+ Create App PIN
+
+
+ Save PIN
+
+
+ );
+};
+
+export default SetPinScreen;
diff --git a/src/screen/authorised/AppPinService.ts b/src/screen/authorised/AppPinService.ts
new file mode 100644
index 0000000..4b2f2f9
--- /dev/null
+++ b/src/screen/authorised/AppPinService.ts
@@ -0,0 +1,20 @@
+import * as Keychain from 'react-native-keychain';
+
+const PIN_KEY = 'APP_PIN';
+
+export const savePin = async (pin: string) => {
+ await Keychain.setGenericPassword(PIN_KEY, pin, {
+ accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED,
+ });
+};
+
+export const verifyPin = async (inputPin: string) => {
+ const creds = await Keychain.getGenericPassword();
+ if (!creds) return false;
+ return creds.password === inputPin;
+};
+
+export const isPinSet = async () => {
+ const creds = await Keychain.getGenericPassword();
+ return !!creds;
+};
diff --git a/src/screen/authorised/AuthManager.ts b/src/screen/authorised/AuthManager.ts
new file mode 100644
index 0000000..d8adade
--- /dev/null
+++ b/src/screen/authorised/AuthManager.ts
@@ -0,0 +1,21 @@
+import AsyncStorage from '@react-native-async-storage/async-storage';
+import { deviceAuthenticate } from './DeviceAuth';
+
+const LOCK_KEY = 'APP_LOCKED';
+
+export const lockApp = async () => {
+ await AsyncStorage.setItem(LOCK_KEY, 'true');
+};
+
+export const unlockApp = async () => {
+ await AsyncStorage.removeItem(LOCK_KEY);
+};
+
+export const isAppLocked = async () => {
+ const v = await AsyncStorage.getItem(LOCK_KEY);
+ return v === 'true';
+};
+
+export const unlockWithDevice = async () => {
+ return await deviceAuthenticate();
+};