@hexar/biometric-identity-sdk-react-native 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +68 -0
  2. package/dist/components/BiometricIdentityFlow.d.ts +17 -0
  3. package/dist/components/BiometricIdentityFlow.d.ts.map +1 -0
  4. package/dist/components/BiometricIdentityFlow.js +366 -0
  5. package/dist/components/CameraCapture.d.ts +15 -0
  6. package/dist/components/CameraCapture.d.ts.map +1 -0
  7. package/dist/components/CameraCapture.js +238 -0
  8. package/dist/components/ErrorScreen.d.ts +15 -0
  9. package/dist/components/ErrorScreen.d.ts.map +1 -0
  10. package/dist/components/ErrorScreen.js +142 -0
  11. package/dist/components/InstructionsScreen.d.ts +14 -0
  12. package/dist/components/InstructionsScreen.d.ts.map +1 -0
  13. package/dist/components/InstructionsScreen.js +181 -0
  14. package/dist/components/ResultScreen.d.ts +15 -0
  15. package/dist/components/ResultScreen.d.ts.map +1 -0
  16. package/dist/components/ResultScreen.js +182 -0
  17. package/dist/components/ValidationProgress.d.ts +14 -0
  18. package/dist/components/ValidationProgress.d.ts.map +1 -0
  19. package/dist/components/ValidationProgress.js +143 -0
  20. package/dist/components/VideoRecorder.d.ts +43 -0
  21. package/dist/components/VideoRecorder.d.ts.map +1 -0
  22. package/dist/components/VideoRecorder.js +631 -0
  23. package/dist/hooks/useBiometricSDK.d.ts +25 -0
  24. package/dist/hooks/useBiometricSDK.d.ts.map +1 -0
  25. package/dist/hooks/useBiometricSDK.js +173 -0
  26. package/dist/index.d.ts +15 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +47 -0
  29. package/package.json +27 -0
  30. package/src/components/BiometricIdentityFlow.tsx +557 -0
  31. package/src/components/CameraCapture.tsx +262 -0
  32. package/src/components/ErrorScreen.tsx +201 -0
  33. package/src/components/InstructionsScreen.tsx +269 -0
  34. package/src/components/ResultScreen.tsx +301 -0
  35. package/src/components/ValidationProgress.tsx +223 -0
  36. package/src/components/VideoRecorder.tsx +794 -0
  37. package/src/hooks/useBiometricSDK.ts +230 -0
  38. package/src/index.ts +24 -0
  39. package/tsconfig.json +20 -0
@@ -0,0 +1,230 @@
1
+ import { useState, useEffect, useCallback, useRef } from 'react';
2
+ import {
3
+ BiometricIdentitySDK,
4
+ SDKState,
5
+ VideoResult,
6
+ } from '@hexar/biometric-identity-sdk-core';
7
+
8
+ export interface ChallengeAction {
9
+ action: string;
10
+ instruction: string;
11
+ duration_ms: number;
12
+ order: number;
13
+ }
14
+
15
+ export interface UseBiometricSDKResult {
16
+ sdk: BiometricIdentitySDK;
17
+ state: SDKState;
18
+ isInitialized: boolean;
19
+ isUsingBackend: boolean;
20
+ sessionId: string | null;
21
+ challenges: ChallengeAction[];
22
+ uploadFrontID: (imageData: string | File | Blob) => Promise<void>;
23
+ uploadBackID: (imageData: string | File | Blob) => Promise<void>;
24
+ storeVideoRecording: (videoData: VideoResult) => Promise<void>;
25
+ fetchChallenges: (type?: 'active' | 'passive') => Promise<ChallengeAction[]>;
26
+ validateIdentity: () => Promise<any>;
27
+ reset: () => void;
28
+ recordVideo: (videoData?: VideoResult) => Promise<void>;
29
+ }
30
+
31
+ export const useBiometricSDK = (): UseBiometricSDKResult => {
32
+ const [sdk] = useState(() => BiometricIdentitySDK.createSession());
33
+ const [state, setState] = useState<SDKState>(sdk.getState());
34
+ const [isInitialized, setIsInitialized] = useState(false);
35
+ const [challenges, setChallenges] = useState<ChallengeAction[]>([]);
36
+ const isMounted = useRef(true);
37
+
38
+ useEffect(() => {
39
+ isMounted.current = true;
40
+
41
+ const init = async () => {
42
+ try {
43
+ await sdk.initialize();
44
+ if (isMounted.current) {
45
+ setIsInitialized(true);
46
+ setState(sdk.getState());
47
+ }
48
+ } catch (error) {
49
+ console.error('SDK initialization failed:', error);
50
+ }
51
+ };
52
+
53
+ init();
54
+
55
+ return () => {
56
+ isMounted.current = false;
57
+ sdk.dispose();
58
+ };
59
+ }, [sdk]);
60
+
61
+ // Poll state updates while loading
62
+ useEffect(() => {
63
+ if (!state.isLoading) return;
64
+
65
+ const interval = setInterval(() => {
66
+ if (isMounted.current) {
67
+ setState(sdk.getState());
68
+ }
69
+ }, 100);
70
+
71
+ return () => clearInterval(interval);
72
+ }, [sdk, state.isLoading]);
73
+
74
+ /**
75
+ * Fetch liveness challenges from backend
76
+ */
77
+ const fetchChallenges = useCallback(
78
+ async (type: 'active' | 'passive' = 'active'): Promise<ChallengeAction[]> => {
79
+ try {
80
+ const response = await sdk.generateLivenessChallenge(type);
81
+
82
+ if (response && response.challenges) {
83
+ const challengeActions: ChallengeAction[] = response.challenges.map(c => ({
84
+ action: c.action,
85
+ instruction: c.instruction,
86
+ duration_ms: c.duration_ms,
87
+ order: c.order,
88
+ }));
89
+
90
+ setChallenges(challengeActions);
91
+ return challengeActions;
92
+ }
93
+
94
+ // Return default challenges if backend not available
95
+ const defaultChallenges: ChallengeAction[] = sdk.getDefaultChallenges().map(c => ({
96
+ action: c.action,
97
+ instruction: c.instruction,
98
+ duration_ms: c.duration_ms,
99
+ order: c.order,
100
+ }));
101
+ setChallenges(defaultChallenges);
102
+ return defaultChallenges;
103
+ } catch (error) {
104
+ console.error('Failed to fetch challenges:', error);
105
+ const defaultChallenges: ChallengeAction[] = sdk.getDefaultChallenges().map(c => ({
106
+ action: c.action,
107
+ instruction: c.instruction,
108
+ duration_ms: c.duration_ms,
109
+ order: c.order,
110
+ }));
111
+ setChallenges(defaultChallenges);
112
+ return defaultChallenges;
113
+ }
114
+ },
115
+ [sdk]
116
+ );
117
+
118
+ /**
119
+ * Upload front ID image
120
+ */
121
+ const uploadFrontID = useCallback(
122
+ async (imageData: string | File | Blob) => {
123
+ await sdk.uploadFrontID(imageData);
124
+ if (isMounted.current) {
125
+ setState(sdk.getState());
126
+ }
127
+ },
128
+ [sdk]
129
+ );
130
+
131
+ /**
132
+ * Upload back ID image
133
+ */
134
+ const uploadBackID = useCallback(
135
+ async (imageData: string | File | Blob) => {
136
+ await sdk.uploadBackID(imageData);
137
+ if (isMounted.current) {
138
+ setState(sdk.getState());
139
+ }
140
+ },
141
+ [sdk]
142
+ );
143
+
144
+ /**
145
+ * Store video recording result
146
+ */
147
+ const storeVideoRecording = useCallback(
148
+ async (videoData: VideoResult) => {
149
+ // Add session ID if using backend
150
+ const sessionId = sdk.getSessionId();
151
+ if (sessionId) {
152
+ videoData.sessionId = sessionId;
153
+ }
154
+
155
+ await sdk.storeVideoRecording(videoData);
156
+ if (isMounted.current) {
157
+ setState(sdk.getState());
158
+ }
159
+ },
160
+ [sdk]
161
+ );
162
+
163
+ /**
164
+ * Legacy: Record video (for backwards compatibility)
165
+ */
166
+ const recordVideo = useCallback(
167
+ async (videoData?: VideoResult) => {
168
+ if (videoData) {
169
+ await storeVideoRecording(videoData);
170
+ } else {
171
+ // Mock video result for backwards compatibility
172
+ const mockVideoResult: VideoResult = {
173
+ frames: Array.from({ length: 80 }, (_, i) => `frame_${i}_base64`),
174
+ duration: 8000,
175
+ instructionsFollowed: true,
176
+ qualityScore: 85,
177
+ challengesCompleted: challenges.map(c => c.action),
178
+ sessionId: sdk.getSessionId() || undefined,
179
+ };
180
+
181
+ await sdk.storeVideoRecording(mockVideoResult);
182
+ }
183
+
184
+ if (isMounted.current) {
185
+ setState(sdk.getState());
186
+ }
187
+ },
188
+ [sdk, storeVideoRecording, challenges]
189
+ );
190
+
191
+ /**
192
+ * Validate identity with all collected data
193
+ */
194
+ const validateIdentity = useCallback(async () => {
195
+ const result = await sdk.validateIdentity();
196
+ if (isMounted.current) {
197
+ setState(sdk.getState());
198
+ }
199
+ return result;
200
+ }, [sdk]);
201
+
202
+ /**
203
+ * Reset SDK state
204
+ */
205
+ const reset = useCallback(() => {
206
+ sdk.reset();
207
+ setChallenges([]);
208
+ if (isMounted.current) {
209
+ setState(sdk.getState());
210
+ }
211
+ }, [sdk]);
212
+
213
+ return {
214
+ sdk,
215
+ state,
216
+ isInitialized,
217
+ isUsingBackend: sdk.isUsingBackend(),
218
+ sessionId: sdk.getSessionId(),
219
+ challenges,
220
+ uploadFrontID,
221
+ uploadBackID,
222
+ storeVideoRecording,
223
+ fetchChallenges,
224
+ validateIdentity,
225
+ reset,
226
+ recordVideo,
227
+ };
228
+ };
229
+
230
+ export default useBiometricSDK;
package/src/index.ts ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * React Native Biometric Identity SDK
3
+ * Main entry point
4
+ */
5
+
6
+ // Main component
7
+ export { BiometricIdentityFlow } from './components/BiometricIdentityFlow';
8
+ export { default } from './components/BiometricIdentityFlow';
9
+
10
+ // Individual components (for custom implementations)
11
+ export { CameraCapture } from './components/CameraCapture';
12
+ export { VideoRecorder } from './components/VideoRecorder';
13
+ export { ValidationProgress } from './components/ValidationProgress';
14
+ export { ResultScreen } from './components/ResultScreen';
15
+ export { ErrorScreen } from './components/ErrorScreen';
16
+ export { InstructionsScreen } from './components/InstructionsScreen';
17
+
18
+ // Hooks
19
+ export { useBiometricSDK } from './hooks/useBiometricSDK';
20
+
21
+ // Re-export core types
22
+ export * from '@hexar/biometric-identity-sdk-core';
23
+
24
+
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "jsx": "react",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "outDir": "./dist",
10
+ "rootDir": "./src",
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "moduleResolution": "node"
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }