omnipay-reactnative-sdk 1.2.3-beta.8 → 1.2.3

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 (58) hide show
  1. package/README.md +42 -102
  2. package/android/build.gradle +4 -15
  3. package/android/src/main/java/com/omniretail/omnipay/OmnipayActivityPackage.java +0 -5
  4. package/lib/commonjs/components/OmnipayProvider.js +91 -18
  5. package/lib/commonjs/components/OmnipayProvider.js.map +1 -1
  6. package/lib/module/components/OmnipayProvider.js +92 -19
  7. package/lib/module/components/OmnipayProvider.js.map +1 -1
  8. package/lib/module/components/OmnipayView.js.map +1 -1
  9. package/lib/module/components/views/BvnVerification.js.map +1 -1
  10. package/lib/module/components/views/PaylaterAgreement.js.map +1 -1
  11. package/lib/module/components/views/Registration.js.map +1 -1
  12. package/lib/typescript/components/OmnipayProvider.d.ts +3 -2
  13. package/lib/typescript/components/OmnipayProvider.d.ts.map +1 -1
  14. package/lib/typescript/hooks/useOmnipay.d.ts +2 -1
  15. package/lib/typescript/hooks/useOmnipay.d.ts.map +1 -1
  16. package/package.json +12 -29
  17. package/src/components/OmnipayProvider.tsx +133 -21
  18. package/src/components/OmnipayView.tsx +1 -1
  19. package/src/components/views/BvnVerification.tsx +1 -1
  20. package/src/components/views/PaylaterAgreement.tsx +1 -1
  21. package/src/components/views/Registration.tsx +1 -1
  22. package/src/hooks/useOmnipay.tsx +1 -1
  23. package/android/src/main/java/com/omniretail/omnipay/FaceVerificationFrameProcessor.kt +0 -111
  24. package/ios/FaceVerificationFrameProcessor.swift +0 -138
  25. package/ios/FaceVerificationFrameProcessorPlugin.m +0 -10
  26. package/ios/OmnipayReactnativeSdk.m +0 -5
  27. package/ios/OmnipayReactnativeSdk.swift +0 -10
  28. package/ios/omnipay-reactnative-sdk-Bridging-Header.h +0 -8
  29. package/ios/omnipay_reactnative_sdk.h +0 -6
  30. package/lib/commonjs/components/Button.js +0 -68
  31. package/lib/commonjs/components/Button.js.map +0 -1
  32. package/lib/commonjs/components/biometrics/FaceVerification.js +0 -380
  33. package/lib/commonjs/components/biometrics/FaceVerification.js.map +0 -1
  34. package/lib/commonjs/components/biometrics/useFaceVerification.js +0 -85
  35. package/lib/commonjs/components/biometrics/useFaceVerification.js.map +0 -1
  36. package/lib/commonjs/components/biometrics/useFaceVerificationFlow.js +0 -157
  37. package/lib/commonjs/components/biometrics/useFaceVerificationFlow.js.map +0 -1
  38. package/lib/module/components/Button.js +0 -61
  39. package/lib/module/components/Button.js.map +0 -1
  40. package/lib/module/components/biometrics/FaceVerification.js +0 -372
  41. package/lib/module/components/biometrics/FaceVerification.js.map +0 -1
  42. package/lib/module/components/biometrics/useFaceVerification.js +0 -78
  43. package/lib/module/components/biometrics/useFaceVerification.js.map +0 -1
  44. package/lib/module/components/biometrics/useFaceVerificationFlow.js +0 -150
  45. package/lib/module/components/biometrics/useFaceVerificationFlow.js.map +0 -1
  46. package/lib/typescript/components/Button.d.ts +0 -17
  47. package/lib/typescript/components/Button.d.ts.map +0 -1
  48. package/lib/typescript/components/biometrics/FaceVerification.d.ts +0 -9
  49. package/lib/typescript/components/biometrics/FaceVerification.d.ts.map +0 -1
  50. package/lib/typescript/components/biometrics/useFaceVerification.d.ts +0 -38
  51. package/lib/typescript/components/biometrics/useFaceVerification.d.ts.map +0 -1
  52. package/lib/typescript/components/biometrics/useFaceVerificationFlow.d.ts +0 -29
  53. package/lib/typescript/components/biometrics/useFaceVerificationFlow.d.ts.map +0 -1
  54. package/omnipay_reactnative_sdk.podspec +0 -50
  55. package/src/components/Button.tsx +0 -86
  56. package/src/components/biometrics/FaceVerification.tsx +0 -429
  57. package/src/components/biometrics/useFaceVerification.ts +0 -120
  58. package/src/components/biometrics/useFaceVerificationFlow.ts +0 -224
@@ -1,429 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import {
3
- View,
4
- Modal,
5
- Dimensions,
6
- Platform,
7
- StyleSheet,
8
- TouchableOpacity,
9
- Image,
10
- Text,
11
- } from 'react-native';
12
- import {
13
- Camera,
14
- useCameraDevice,
15
- useCameraPermission,
16
- } from 'react-native-vision-camera';
17
- import Button from '../Button';
18
- import { useFaceVerification } from './useFaceVerification';
19
- import { useFaceVerificationFlow } from './useFaceVerificationFlow';
20
-
21
- type FaceVerificationProps = {
22
- onClose: () => void;
23
- onSuccess: () => void;
24
- primaryColor: string;
25
- };
26
-
27
- const FaceVerification: React.FC<FaceVerificationProps> = ({
28
- onClose,
29
- onSuccess,
30
- primaryColor,
31
- }) => {
32
- const device = useCameraDevice('front');
33
- const { hasPermission, requestPermission } = useCameraPermission();
34
- const [isRequestingPermission, setIsRequestingPermission] = useState(false);
35
-
36
- // Face verification flow
37
- const {
38
- state: flowState,
39
- resetFlow,
40
- isCompleted,
41
- isFailed,
42
- } = useFaceVerificationFlow();
43
-
44
- // Frame processor
45
- const frameProcessor = useFaceVerification();
46
-
47
- // Handle completion
48
- useEffect(() => {
49
- if (isCompleted) {
50
- setTimeout(() => {
51
- onSuccess();
52
- }, 1000); // Show success message briefly
53
- }
54
- }, [isCompleted, onSuccess]);
55
-
56
- const handleRequestPermission = async () => {
57
- setIsRequestingPermission(true);
58
- try {
59
- await requestPermission();
60
- } catch (error) {
61
- console.error('Error requesting camera permission:', error);
62
- } finally {
63
- setIsRequestingPermission(false);
64
- }
65
- };
66
-
67
- const renderPermissionRequest = () => (
68
- <View style={styles.permissionContainer}>
69
- <View style={styles.permissionIconContainer}>
70
- <Text style={styles.permissionIcon}>📷</Text>
71
- </View>
72
- <Text style={styles.permissionTitle}>Camera Permission Required</Text>
73
- <Text style={styles.permissionDescription}>
74
- To verify your identity, we need access to your camera. This allows us
75
- to capture your face for secure verification.
76
- </Text>
77
- <Button
78
- title="Allow Camera Access"
79
- onPress={handleRequestPermission}
80
- backgroundColor={primaryColor}
81
- loading={isRequestingPermission}
82
- />
83
- </View>
84
- );
85
-
86
- const renderNoDevice = () => (
87
- <View style={styles.errorContainer}>
88
- <Text style={styles.errorTitle}>Camera Not Available</Text>
89
- <Text style={styles.errorSubtitle}>
90
- No front camera detected on this device. Face verification requires a
91
- front-facing camera.
92
- </Text>
93
- </View>
94
- );
95
-
96
- const renderCamera = () => {
97
- if (!device) return null;
98
-
99
- return (
100
- <View style={styles.cameraContainer}>
101
- <Camera
102
- device={device}
103
- style={styles.camera}
104
- isActive={true}
105
- frameProcessor={frameProcessor}
106
- />
107
- <View style={styles.cameraOverlay}>
108
- <View style={styles.faceFrame} />
109
-
110
- {/* Progress indicator */}
111
- <View style={styles.progressContainer}>
112
- <View
113
- style={[
114
- styles.progressBar,
115
- {
116
- width: `${flowState.progress}%`,
117
- backgroundColor: primaryColor,
118
- },
119
- ]}
120
- />
121
- </View>
122
-
123
- {/* Current instruction */}
124
- <Text style={styles.instructionText}>{flowState.instruction}</Text>
125
-
126
- {/* Step indicator */}
127
- <Text style={styles.stepIndicator}>
128
- Step {flowState.completedSteps.length + 1} of 5
129
- </Text>
130
-
131
- {/* Success/Failure messages */}
132
- {isCompleted && (
133
- <View
134
- style={[
135
- styles.statusContainer,
136
- { backgroundColor: primaryColor },
137
- ]}
138
- >
139
- <Text style={styles.statusText}>✓ Verification Complete!</Text>
140
- </View>
141
- )}
142
-
143
- {isFailed && (
144
- <View style={[styles.statusContainer, styles.statusContainerError]}>
145
- <Text style={styles.statusText}>✗ Verification Failed</Text>
146
- <Button
147
- title="Try Again"
148
- onPress={resetFlow}
149
- backgroundColor="white"
150
- textColor="#ff4444"
151
- style={styles.retryButton}
152
- />
153
- </View>
154
- )}
155
- </View>
156
- </View>
157
- );
158
- };
159
-
160
- console.log(onSuccess, primaryColor);
161
-
162
- return (
163
- <Modal
164
- visible={true}
165
- transparent={true}
166
- onRequestClose={onClose}
167
- style={styles.modal}
168
- >
169
- <TouchableOpacity
170
- style={styles.backdrop}
171
- activeOpacity={1}
172
- onPress={onClose}
173
- >
174
- <View style={[styles.container]}>
175
- <TouchableOpacity style={styles.close} onPress={onClose}>
176
- <Image
177
- source={require('../../assets/cancel.png')}
178
- style={styles.closeIcon}
179
- />
180
- </TouchableOpacity>
181
- <View style={styles.contentContainer}>
182
- {!hasPermission && renderPermissionRequest()}
183
- {hasPermission && !device && renderNoDevice()}
184
- {hasPermission && device && renderCamera()}
185
- </View>
186
- </View>
187
- </TouchableOpacity>
188
- </Modal>
189
- );
190
- };
191
-
192
- export default FaceVerification;
193
-
194
- const styles = StyleSheet.create({
195
- hide: {
196
- display: 'none',
197
- },
198
- full: {
199
- flex: 1,
200
- width: '100%',
201
- height: '100%',
202
- },
203
- webview: {
204
- flex: 1,
205
- width: '100%',
206
- height: Dimensions.get('window').height - 40,
207
- backgroundColor: 'white',
208
- borderTopRightRadius: 20,
209
- borderTopLeftRadius: 20,
210
- paddingTop: 150,
211
- },
212
- webviewLoader: {
213
- zIndex: 3,
214
- backgroundColor: 'white',
215
- alignItems: 'center',
216
- justifyContent: 'center',
217
- flex: 1,
218
- width: '100%',
219
- height: '100%',
220
- position: 'absolute',
221
- top: 0,
222
- left: 0,
223
- borderTopRightRadius: 20,
224
- borderTopLeftRadius: 20,
225
- },
226
- backdrop: {
227
- backgroundColor: 'rgba(0,0,0,0.3)',
228
- flex: 1,
229
- justifyContent: 'flex-end',
230
- position: 'relative',
231
- height: '100%',
232
- },
233
- container: {
234
- backgroundColor: 'white',
235
- borderTopRightRadius: 20,
236
- borderTopLeftRadius: 20,
237
- maxHeight: Dimensions.get('window').height - 120,
238
- flex: 1,
239
- position: 'relative',
240
- ...(Platform.OS === 'android' && { overflow: 'hidden' }),
241
- },
242
- modal: {
243
- flex: 1,
244
- backgroundColor: 'rgba(0,0,0,0.48)',
245
- height: '100%',
246
- width: '100%',
247
- },
248
- close: {
249
- position: 'absolute',
250
- top: 10,
251
- right: 10,
252
- backgroundColor: 'white',
253
- height: 24,
254
- width: 24,
255
- borderRadius: 1000,
256
- alignItems: 'center',
257
- justifyContent: 'center',
258
- zIndex: 2,
259
- },
260
- closeIcon: {
261
- height: 12,
262
- width: 12,
263
- },
264
- contentContainer: {
265
- height: '100%',
266
- position: 'relative',
267
- borderTopRightRadius: 20,
268
- borderTopLeftRadius: 20,
269
- padding: 16,
270
- },
271
- testContent: {
272
- paddingTop: 30,
273
- paddingLeft: 16,
274
- },
275
- testTwoContent: {
276
- paddingTop: 10,
277
- paddingLeft: 16,
278
- },
279
- errorSubtitle: {
280
- textAlign: 'center',
281
- fontSize: 14,
282
- color: '#5e7079',
283
- marginBottom: 20,
284
- paddingHorizontal: 8,
285
- marginTop: 14,
286
- },
287
- errorContainer: {
288
- flex: 1,
289
- justifyContent: 'center',
290
- alignItems: 'center',
291
- width: Dimensions.get('window').width,
292
- height: Dimensions.get('window').height,
293
- zIndex: 2,
294
- backgroundColor: 'white',
295
- },
296
-
297
- camera: {
298
- width: '100%',
299
- height: 400,
300
- },
301
- // Permission request styles
302
- permissionContainer: {
303
- flex: 1,
304
- justifyContent: 'center',
305
- alignItems: 'center',
306
- paddingHorizontal: 24,
307
- paddingVertical: 40,
308
- },
309
- permissionIconContainer: {
310
- width: 80,
311
- height: 80,
312
- borderRadius: 40,
313
- backgroundColor: '#f0f0f0',
314
- justifyContent: 'center',
315
- alignItems: 'center',
316
- marginBottom: 24,
317
- },
318
- permissionIcon: {
319
- fontSize: 40,
320
- },
321
- permissionTitle: {
322
- fontSize: 20,
323
- fontWeight: '600',
324
- color: '#1a1a1a',
325
- textAlign: 'center',
326
- marginBottom: 12,
327
- },
328
- permissionDescription: {
329
- fontSize: 16,
330
- color: '#666',
331
- textAlign: 'center',
332
- lineHeight: 22,
333
- marginBottom: 32,
334
- },
335
-
336
- // Error styles
337
- errorTitle: {
338
- fontSize: 18,
339
- fontWeight: '600',
340
- color: '#1a1a1a',
341
- textAlign: 'center',
342
- marginBottom: 8,
343
- },
344
- // Camera styles
345
- cameraContainer: {
346
- flex: 1,
347
- position: 'relative',
348
- marginTop: 60,
349
- },
350
- cameraOverlay: {
351
- position: 'absolute',
352
- top: 0,
353
- left: 0,
354
- right: 0,
355
- bottom: 0,
356
- justifyContent: 'center',
357
- alignItems: 'center',
358
- },
359
- faceFrame: {
360
- width: 200,
361
- height: 250,
362
- borderWidth: 3,
363
- borderColor: 'white',
364
- borderRadius: 100,
365
- borderStyle: 'dashed',
366
- backgroundColor: 'transparent',
367
- },
368
- instructionText: {
369
- color: 'white',
370
- fontSize: 16,
371
- fontWeight: '500',
372
- textAlign: 'center',
373
- marginTop: 20,
374
- backgroundColor: 'rgba(0,0,0,0.7)',
375
- paddingHorizontal: 16,
376
- paddingVertical: 8,
377
- borderRadius: 20,
378
- },
379
- // Verification flow styles
380
- progressContainer: {
381
- position: 'absolute',
382
- top: 20,
383
- left: 20,
384
- right: 20,
385
- height: 4,
386
- backgroundColor: 'rgba(255,255,255,0.3)',
387
- borderRadius: 2,
388
- overflow: 'hidden',
389
- },
390
- progressBar: {
391
- height: '100%',
392
- borderRadius: 2,
393
- },
394
- stepIndicator: {
395
- color: 'white',
396
- fontSize: 14,
397
- fontWeight: '400',
398
- textAlign: 'center',
399
- marginTop: 8,
400
- backgroundColor: 'rgba(0,0,0,0.5)',
401
- paddingHorizontal: 12,
402
- paddingVertical: 4,
403
- borderRadius: 12,
404
- alignSelf: 'center',
405
- },
406
- statusContainer: {
407
- position: 'absolute',
408
- bottom: 40,
409
- left: 20,
410
- right: 20,
411
- padding: 20,
412
- borderRadius: 12,
413
- alignItems: 'center',
414
- },
415
- statusContainerError: {
416
- backgroundColor: '#ff4444',
417
- },
418
- statusText: {
419
- color: 'white',
420
- fontSize: 18,
421
- fontWeight: '600',
422
- textAlign: 'center',
423
- marginBottom: 8,
424
- },
425
- retryButton: {
426
- marginTop: 12,
427
- minWidth: 120,
428
- },
429
- });
@@ -1,120 +0,0 @@
1
- import {
2
- useFrameProcessor,
3
- VisionCameraProxy,
4
- } from 'react-native-vision-camera';
5
-
6
- export interface FaceVerificationResult {
7
- faceDetected: boolean;
8
- isSmiling?: boolean;
9
- isBlinking?: boolean;
10
- leftEyeClosed?: boolean;
11
- rightEyeClosed?: boolean;
12
- headPose?: {
13
- yaw: number; // Left-right movement (-90 to 90)
14
- pitch: number; // Up-down movement (-90 to 90)
15
- roll: number; // Tilt movement (-180 to 180)
16
- };
17
- boundingBox?: {
18
- x?: number;
19
- y?: number;
20
- width?: number;
21
- height?: number;
22
- left?: number;
23
- top?: number;
24
- right?: number;
25
- bottom?: number;
26
- };
27
- smileProbability?: number;
28
- leftEyeOpenProbability?: number;
29
- rightEyeOpenProbability?: number;
30
- trackingId?: number;
31
- error?: string;
32
- }
33
-
34
- // Note: For production use, you would typically use shared values or state management
35
- // to communicate results from the worklet back to the React component.
36
- // This simplified version just logs results for debugging.
37
-
38
- // Initialize the plugin
39
- const plugin = VisionCameraProxy.initFrameProcessorPlugin('detectFaces', {});
40
-
41
- export const useFaceVerification = () => {
42
- const frameProcessor = useFrameProcessor((frame) => {
43
- 'worklet';
44
-
45
- try {
46
- if (plugin == null) {
47
- console.error('Failed to load Frame Processor Plugin "detectFaces"!');
48
- return null;
49
- }
50
-
51
- const result = plugin.call(frame, {}) as any;
52
-
53
- // For debugging - this works in worklets
54
- if (result && result.faceDetected) {
55
- console.log('Face detected:', result);
56
- }
57
-
58
- return result;
59
- } catch (error) {
60
- console.error('Face verification error:', error);
61
- return {
62
- faceDetected: false,
63
- error: error instanceof Error ? error.message : 'Unknown error',
64
- };
65
- }
66
- }, []);
67
-
68
- return frameProcessor;
69
- };
70
-
71
- // Utility functions for interpreting results
72
- export const FaceVerificationUtils = {
73
- // Check if head is turned left (yaw > 20 degrees)
74
- isHeadTurnedLeft: (result: FaceVerificationResult): boolean => {
75
- return result.headPose?.yaw ? result.headPose.yaw > 20 : false;
76
- },
77
-
78
- // Check if head is turned right (yaw < -20 degrees)
79
- isHeadTurnedRight: (result: FaceVerificationResult): boolean => {
80
- return result.headPose?.yaw ? result.headPose.yaw < -20 : false;
81
- },
82
-
83
- // Check if head is tilted up (pitch > 10 degrees)
84
- isHeadTiltedUp: (result: FaceVerificationResult): boolean => {
85
- return result.headPose?.pitch ? result.headPose.pitch > 10 : false;
86
- },
87
-
88
- // Check if head is tilted down (pitch < -10 degrees)
89
- isHeadTiltedDown: (result: FaceVerificationResult): boolean => {
90
- return result.headPose?.pitch ? result.headPose.pitch < -10 : false;
91
- },
92
-
93
- // Check if face is centered (within ±10 degrees)
94
- isFaceCentered: (result: FaceVerificationResult): boolean => {
95
- if (!result.headPose) return false;
96
- const { yaw, pitch } = result.headPose;
97
- return Math.abs(yaw) <= 10 && Math.abs(pitch) <= 10;
98
- },
99
-
100
- // Check if smile is confident (high probability)
101
- isConfidentSmile: (result: FaceVerificationResult): boolean => {
102
- return result.smileProbability
103
- ? result.smileProbability > 0.8
104
- : result.isSmiling || false;
105
- },
106
-
107
- // Check if both eyes are confidently closed
108
- isConfidentBlink: (result: FaceVerificationResult): boolean => {
109
- if (
110
- result.leftEyeOpenProbability !== undefined &&
111
- result.rightEyeOpenProbability !== undefined
112
- ) {
113
- return (
114
- result.leftEyeOpenProbability < 0.2 &&
115
- result.rightEyeOpenProbability < 0.2
116
- );
117
- }
118
- return result.isBlinking || false;
119
- },
120
- };