@sanctum-key/react-native-sdk 1.0.24 → 1.0.25
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.
- package/build/package.json +3 -1
- package/build/src/components/EnhancedCameraView.d.ts +7 -1
- package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.js +88 -30
- package/build/src/components/EnhancedCameraView.js.map +1 -1
- package/build/src/components/EnhancedCameraView.web.d.ts +5 -1
- package/build/src/components/EnhancedCameraView.web.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.web.js +80 -295
- package/build/src/components/EnhancedCameraView.web.js.map +1 -1
- package/build/src/components/KYCElements/CameraCapture.js +1 -1
- package/build/src/components/KYCElements/CameraCapture.js.map +1 -1
- package/build/src/components/KYCElements/CountrySelection.d.ts.map +1 -1
- package/build/src/components/KYCElements/CountrySelection.js +38 -218
- package/build/src/components/KYCElements/CountrySelection.js.map +1 -1
- package/build/src/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/CountrySelectionTemplate.js +5 -17
- package/build/src/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +509 -95
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/VerificationProgressTemplate.js +93 -51
- package/build/src/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
- package/build/src/components/OverLay/type.d.ts +1 -0
- package/build/src/components/OverLay/type.d.ts.map +1 -1
- package/build/src/components/OverLay/type.js.map +1 -1
- package/build/src/components/WebBarcodeScanner.d.ts +9 -0
- package/build/src/components/WebBarcodeScanner.d.ts.map +1 -0
- package/build/src/components/WebBarcodeScanner.js +152 -0
- package/build/src/components/WebBarcodeScanner.js.map +1 -0
- package/build/src/config/KYCConfigs.js +2 -2
- package/build/src/config/KYCConfigs.js.map +1 -1
- package/build/src/config/region_mapping.json +0 -14
- package/build/src/modules/api/CardAuthentification.d.ts +2 -0
- package/build/src/modules/api/CardAuthentification.d.ts.map +1 -1
- package/build/src/modules/api/CardAuthentification.js +22 -39
- package/build/src/modules/api/CardAuthentification.js.map +1 -1
- package/build/src/modules/api/KYCService.d.ts +7 -2
- package/build/src/modules/api/KYCService.d.ts.map +1 -1
- package/build/src/modules/api/KYCService.js +163 -57
- package/build/src/modules/api/KYCService.js.map +1 -1
- package/build/src/types/KYC.types.d.ts +1 -0
- package/build/src/types/KYC.types.d.ts.map +1 -1
- package/build/src/types/KYC.types.js.map +1 -1
- package/build/src/utils/aamvaParser.d.ts +62 -0
- package/build/src/utils/aamvaParser.d.ts.map +1 -0
- package/build/src/utils/aamvaParser.js +91 -0
- package/build/src/utils/aamvaParser.js.map +1 -0
- package/build/src/utils/cropByObb.d.ts.map +1 -1
- package/build/src/utils/cropByObb.js +4 -3
- package/build/src/utils/cropByObb.js.map +1 -1
- package/build/src/web/WebKYCEntry.d.ts +1 -1
- package/build/src/web/WebKYCEntry.d.ts.map +1 -1
- package/build/src/web/WebKYCEntry.js +105 -239
- package/build/src/web/WebKYCEntry.js.map +1 -1
- package/package.json +3 -1
- package/src/components/EnhancedCameraView.tsx +116 -42
- package/src/components/EnhancedCameraView.web.tsx +98 -338
- package/src/components/KYCElements/CameraCapture.tsx +1 -1
- package/src/components/KYCElements/CountrySelection.tsx +60 -240
- package/src/components/KYCElements/CountrySelectionTemplate.tsx +7 -20
- package/src/components/KYCElements/IDCardCapture.tsx +672 -151
- package/src/components/KYCElements/VerificationProgressTemplate.tsx +112 -65
- package/src/components/OverLay/type.ts +1 -1
- package/src/components/WebBarcodeScanner.tsx +273 -0
- package/src/config/KYCConfigs.ts +2 -2
- package/src/config/region_mapping.json +0 -14
- package/src/modules/api/CardAuthentification.ts +41 -56
- package/src/modules/api/KYCService.ts +236 -82
- package/src/types/KYC.types.ts +1 -0
- package/src/utils/aamvaParser.ts +102 -0
- package/src/utils/cropByObb.ts +5 -3
- package/src/web/WebKYCEntry.tsx +125 -301
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from 'react-native';
|
|
5
|
-
import { Camera, useCameraDevice } from 'react-native-vision-camera';
|
|
2
|
+
import { View, StyleSheet, Text, Platform } from 'react-native';
|
|
3
|
+
import { Camera, CodeType, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';
|
|
6
4
|
import VisionCameraModule from '../modules/camera/VisionCameraModule';
|
|
7
5
|
import { useI18n } from '../hooks/useI18n';
|
|
8
6
|
import { EnhancedCameraViewProps } from './OverLay/type';
|
|
9
|
-
import {
|
|
7
|
+
import { WebBarcodeScanner } from './WebBarcodeScanner';
|
|
10
8
|
|
|
9
|
+
export interface ExtendedCameraProps extends EnhancedCameraViewProps {
|
|
10
|
+
isScanningBarcode?: boolean;
|
|
11
|
+
onBarcodeScanned?: (data: string) => void;
|
|
12
|
+
barcodeTypes?: CodeType[];
|
|
13
|
+
}
|
|
11
14
|
|
|
12
|
-
export const EnhancedCameraView: React.FC<
|
|
15
|
+
export const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({
|
|
13
16
|
showCamera,
|
|
14
17
|
cameraType: initialCameraType = 'front',
|
|
15
18
|
style,
|
|
@@ -18,21 +21,31 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
18
21
|
silentCaptureResult,
|
|
19
22
|
isProcessing = false,
|
|
20
23
|
overlayComponent,
|
|
24
|
+
isScanningBarcode = false,
|
|
25
|
+
onBarcodeScanned,
|
|
26
|
+
barcodeTypes
|
|
21
27
|
}) => {
|
|
22
28
|
const { t } = useI18n();
|
|
23
29
|
const camera = useRef<Camera>(null);
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
const [cameraType]
|
|
30
|
+
|
|
31
|
+
const webVideoRef = useRef<HTMLVideoElement | null>(null);
|
|
32
|
+
const isCapturingRef = useRef(false);
|
|
33
|
+
const isProcessingRef = useRef(isProcessing);
|
|
34
|
+
const [cameraType] = useState<'front' | 'back'>(initialCameraType);
|
|
29
35
|
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
|
|
30
36
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
31
|
-
const [refreshCamera
|
|
37
|
+
const [refreshCamera] = useState(false);
|
|
38
|
+
|
|
39
|
+
// 🚨 NEW STATE: Tells React when it is safe to mount the Web Scanner
|
|
40
|
+
const [isVideoFound, setIsVideoFound] = useState(false);
|
|
32
41
|
|
|
42
|
+
const scannedBarcodeRef = useRef<string | null>(null);
|
|
43
|
+
const containerRef = useRef<any>(null);
|
|
33
44
|
const device = useCameraDevice(cameraType);
|
|
34
45
|
|
|
35
|
-
useEffect(() => {
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
isProcessingRef.current = isProcessing;
|
|
48
|
+
}, [isProcessing]);
|
|
36
49
|
|
|
37
50
|
const checkPermissions = async () => {
|
|
38
51
|
try {
|
|
@@ -52,29 +65,40 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
52
65
|
}
|
|
53
66
|
};
|
|
54
67
|
|
|
55
|
-
useEffect(() => { if (showCamera) checkPermissions(); }, [showCamera, refreshCamera]);
|
|
56
|
-
|
|
57
68
|
useEffect(() => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const onInitialized = useCallback(() => setIsInitialized(true), []);
|
|
65
|
-
const onCameraError = useCallback((error: any) => {
|
|
69
|
+
if (showCamera) checkPermissions();
|
|
70
|
+
}, [showCamera, refreshCamera]);
|
|
71
|
+
|
|
72
|
+
const onInitialized = useCallback(() => setIsInitialized(true), []);
|
|
73
|
+
const onCameraError = useCallback((error: any) => {
|
|
66
74
|
onError?.({ message: error.message || t('camera.errorOccurred') });
|
|
67
75
|
}, [onError, t]);
|
|
68
76
|
|
|
77
|
+
const codeScanner = useCodeScanner({
|
|
78
|
+
codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],
|
|
79
|
+
onCodeScanned: (codes) => {
|
|
80
|
+
if (!isProcessingRef.current && isScanningBarcode) {
|
|
81
|
+
for (const code of codes) {
|
|
82
|
+
if (code.value && scannedBarcodeRef.current !== code.value) {
|
|
83
|
+
scannedBarcodeRef.current = code.value;
|
|
84
|
+
onBarcodeScanned?.(code.value);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
69
92
|
const captureSilentPhoto = useCallback(async () => {
|
|
70
93
|
if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;
|
|
71
94
|
if (silentCaptureResult?.isAnalyzing) return;
|
|
72
95
|
try {
|
|
73
96
|
isCapturingRef.current = true;
|
|
74
|
-
const photo
|
|
97
|
+
const photo = await camera.current.takePhoto({ enableShutterSound: false, flash: 'off' });
|
|
75
98
|
const result = await VisionCameraModule.processPhotoResult(photo);
|
|
76
|
-
onSilentCapture?.({ ...result, path: result.path || photo.path });
|
|
77
|
-
} catch {
|
|
99
|
+
onSilentCapture?.({ ...result, path: result.path || photo.path, barcode: scannedBarcodeRef.current });
|
|
100
|
+
} catch {
|
|
101
|
+
} finally {
|
|
78
102
|
isCapturingRef.current = false;
|
|
79
103
|
}
|
|
80
104
|
}, [isInitialized, onSilentCapture, silentCaptureResult]);
|
|
@@ -85,26 +109,67 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
85
109
|
let id: ReturnType<typeof setInterval>;
|
|
86
110
|
const timer = setTimeout(() => {
|
|
87
111
|
if (!active) return;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
const intervalDelay = isScanningBarcode ? 3000 : 1500;
|
|
113
|
+
id = setInterval(captureSilentPhoto, intervalDelay);
|
|
114
|
+
}, 1500);
|
|
115
|
+
return () => {
|
|
116
|
+
active = false;
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
if (id) clearInterval(id);
|
|
119
|
+
};
|
|
120
|
+
}, [showCamera, isInitialized, isProcessing, captureSilentPhoto, isScanningBarcode]);
|
|
121
|
+
|
|
122
|
+
// Web: Aggressive Video Element Hunter
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
// 🚨 Kick off the search immediately if we are on the web and the camera should be showing
|
|
125
|
+
if (Platform.OS !== 'web' || !showCamera) return;
|
|
126
|
+
|
|
127
|
+
let timeoutId: ReturnType<typeof setTimeout>;
|
|
128
|
+
|
|
129
|
+
const findVideo = () => {
|
|
130
|
+
console.log('🔍 [WEB ENGINE] Searching for <video> element in DOM...');
|
|
131
|
+
|
|
132
|
+
let video: HTMLVideoElement | null = null;
|
|
133
|
+
if (containerRef.current?.querySelector) {
|
|
134
|
+
video = containerRef.current.querySelector('video');
|
|
135
|
+
}
|
|
136
|
+
if (!video) {
|
|
137
|
+
video = document.querySelector('video');
|
|
138
|
+
}
|
|
94
139
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
140
|
+
if (video) {
|
|
141
|
+
console.log('✅ [WEB ENGINE] <video> element locked! Booting ZXing Scanner.');
|
|
142
|
+
webVideoRef.current = video;
|
|
143
|
+
setIsVideoFound(true); // This tells React to mount the scanner!
|
|
144
|
+
} else {
|
|
145
|
+
console.log('⏳ [WEB ENGINE] <video> not found yet, retrying in 500ms...');
|
|
146
|
+
timeoutId = setTimeout(findVideo, 500);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// Start hunting immediately, do NOT wait for isInitialized
|
|
151
|
+
findVideo();
|
|
152
|
+
|
|
153
|
+
return () => clearTimeout(timeoutId);
|
|
154
|
+
}, [showCamera]);
|
|
155
|
+
|
|
156
|
+
// 🚨 FIX: Memoized Web Callback to prevent infinite re-rendering loop
|
|
157
|
+
const handleWebBarcodeScanned = useCallback((value: string) => {
|
|
158
|
+
console.log(`🎉 [WEB SCANNER] SUCCESS! Decoded value:`, value);
|
|
159
|
+
alert(`Decoded: ${value.substring(0, 50)}...`);
|
|
160
|
+
|
|
161
|
+
if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {
|
|
162
|
+
scannedBarcodeRef.current = value;
|
|
163
|
+
onBarcodeScanned?.(value);
|
|
164
|
+
}
|
|
165
|
+
}, [onBarcodeScanned]);
|
|
103
166
|
|
|
167
|
+
if (hasPermission === null) return <View style={[styles.container, style]} />;
|
|
168
|
+
if (hasPermission === false) return <View style={[styles.container, style]}><Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text></View>;
|
|
104
169
|
if (!device || !showCamera) return <View style={[styles.container, style]} />;
|
|
105
170
|
|
|
106
171
|
return (
|
|
107
|
-
<View style={[styles.container, style]}>
|
|
172
|
+
<View ref={containerRef} style={[styles.container, style]}>
|
|
108
173
|
<Camera
|
|
109
174
|
ref={camera}
|
|
110
175
|
style={StyleSheet.absoluteFill}
|
|
@@ -116,8 +181,17 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
116
181
|
audio={false}
|
|
117
182
|
onInitialized={onInitialized}
|
|
118
183
|
onError={onCameraError}
|
|
184
|
+
codeScanner={Platform.OS !== 'web' && isScanningBarcode ? codeScanner : undefined}
|
|
119
185
|
/>
|
|
120
|
-
|
|
186
|
+
|
|
187
|
+
{Platform.OS === 'web' && isScanningBarcode && isVideoFound && (
|
|
188
|
+
<WebBarcodeScanner
|
|
189
|
+
videoRef={webVideoRef as React.RefObject<HTMLVideoElement>}
|
|
190
|
+
onBarcodeScanned={handleWebBarcodeScanned}
|
|
191
|
+
active={!isProcessingRef.current}
|
|
192
|
+
/>
|
|
193
|
+
)}
|
|
194
|
+
|
|
121
195
|
{overlayComponent}
|
|
122
196
|
</View>
|
|
123
197
|
);
|