@trustchex/react-native-sdk 1.253.0 → 1.266.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 (84) hide show
  1. package/README.md +43 -2
  2. package/android/src/main/java/com/trustchex/reactnativesdk/DeviceBrightnessModule.kt +66 -0
  3. package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +12 -0
  4. package/ios/DeviceBrightnessModule.h +4 -0
  5. package/ios/DeviceBrightnessModule.m +27 -0
  6. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +25 -0
  7. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +19 -0
  8. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +19 -0
  9. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +18 -5
  10. package/lib/module/Screens/Static/QrCodeScanningScreen.js +10 -2
  11. package/lib/module/Screens/Static/ResultScreen.js +52 -3
  12. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +41 -2
  13. package/lib/module/Shared/Components/EIDScanner.js +63 -3
  14. package/lib/module/Shared/Components/FaceCamera.js +69 -4
  15. package/lib/module/Shared/Components/IdentityDocumentCamera.js +4 -1
  16. package/lib/module/Shared/Components/NavigationManager.js +2 -0
  17. package/lib/module/Shared/Components/QrCodeScannerCamera.js +2 -0
  18. package/lib/module/Shared/Contexts/AppContext.js +3 -1
  19. package/lib/module/Shared/Libs/analytics.utils.js +430 -0
  20. package/lib/module/Shared/Libs/camera.utils.js +58 -2
  21. package/lib/module/Shared/Libs/deeplink.utils.js +8 -0
  22. package/lib/module/Shared/Libs/http-client.js +89 -28
  23. package/lib/module/Shared/Services/AnalyticsService.js +404 -0
  24. package/lib/module/Shared/Types/analytics.types.js +111 -0
  25. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.js +1 -0
  26. package/lib/module/Translation/index.js +5 -0
  27. package/lib/module/Trustchex.js +47 -4
  28. package/lib/module/index.js +3 -0
  29. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  30. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  31. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  32. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  33. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  34. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  35. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  36. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  37. package/lib/typescript/src/Shared/Components/FaceCamera.d.ts +7 -1
  38. package/lib/typescript/src/Shared/Components/FaceCamera.d.ts.map +1 -1
  39. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  40. package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
  41. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +2 -0
  42. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  43. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts +98 -0
  44. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -0
  45. package/lib/typescript/src/Shared/Libs/camera.utils.d.ts +19 -1
  46. package/lib/typescript/src/Shared/Libs/camera.utils.d.ts.map +1 -1
  47. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  48. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  49. package/lib/typescript/src/Shared/Services/AnalyticsService.d.ts +86 -0
  50. package/lib/typescript/src/Shared/Services/AnalyticsService.d.ts.map +1 -0
  51. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +146 -0
  52. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -0
  53. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.d.ts.map +1 -1
  54. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  55. package/lib/typescript/src/Translation/index.d.ts.map +1 -1
  56. package/lib/typescript/src/Trustchex.d.ts +1 -0
  57. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  58. package/lib/typescript/src/index.d.ts +4 -0
  59. package/lib/typescript/src/index.d.ts.map +1 -1
  60. package/package.json +6 -2
  61. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +35 -1
  62. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +30 -0
  63. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +30 -0
  64. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +30 -4
  65. package/src/Screens/Static/QrCodeScanningScreen.tsx +12 -2
  66. package/src/Screens/Static/ResultScreen.tsx +79 -4
  67. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +65 -10
  68. package/src/Shared/Components/EIDScanner.tsx +132 -3
  69. package/src/Shared/Components/FaceCamera.tsx +77 -2
  70. package/src/Shared/Components/IdentityDocumentCamera.tsx +4 -4
  71. package/src/Shared/Components/NavigationManager.tsx +2 -0
  72. package/src/Shared/Components/QrCodeScannerCamera.tsx +2 -0
  73. package/src/Shared/Contexts/AppContext.ts +4 -0
  74. package/src/Shared/Libs/analytics.utils.ts +644 -0
  75. package/src/Shared/Libs/camera.utils.ts +74 -2
  76. package/src/Shared/Libs/deeplink.utils.ts +5 -0
  77. package/src/Shared/Libs/http-client.ts +105 -31
  78. package/src/Shared/Services/AnalyticsService.ts +470 -0
  79. package/src/Shared/Types/analytics.types.ts +179 -0
  80. package/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.ts +1 -0
  81. package/src/Translation/Resources/tr.ts +2 -1
  82. package/src/Translation/index.ts +9 -0
  83. package/src/Trustchex.tsx +54 -2
  84. package/src/index.tsx +33 -0
@@ -1,5 +1,15 @@
1
1
  import type { Frame } from 'react-native-vision-camera';
2
2
 
3
+ interface Rect {
4
+ minX: number;
5
+ minY: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+
10
+ /**
11
+ * Get average brightness for entire frame (center area)
12
+ */
3
13
  const getAverageBrightness = (frame: Frame): number => {
4
14
  'worklet';
5
15
  const buffer = frame.toArrayBuffer();
@@ -26,9 +36,71 @@ const getAverageBrightness = (frame: Frame): number => {
26
36
  return luminanceSum / pixelCount;
27
37
  };
28
38
 
39
+ /**
40
+ * Get average brightness for a specific circular region (for face detection)
41
+ * Calculates brightness only for pixels inside the circle defined by centerX, centerY, and radius
42
+ */
43
+ const getCircularRegionBrightness = (
44
+ frame: Frame,
45
+ circleRect: Rect
46
+ ): number => {
47
+ 'worklet';
48
+ const buffer = frame.toArrayBuffer();
49
+ const data = new Uint8Array(buffer);
50
+ const width = frame.width;
51
+ const height = frame.height;
52
+
53
+ // Calculate circle parameters from rect
54
+ const centerX = Math.floor(circleRect.minX + circleRect.width / 2);
55
+ const centerY = Math.floor(circleRect.minY + circleRect.height / 2);
56
+ const radius = Math.floor(Math.min(circleRect.width, circleRect.height) / 2);
57
+
58
+ let luminanceSum = 0;
59
+ let pixelCount = 0;
60
+
61
+ // Calculate bounding box for the circle to optimize iteration
62
+ const minX = Math.max(0, centerX - radius);
63
+ const maxX = Math.min(width - 1, centerX + radius);
64
+ const minY = Math.max(0, centerY - radius);
65
+ const maxY = Math.min(height - 1, centerY + radius);
66
+
67
+ // Iterate only over pixels in the bounding box
68
+ for (let y = minY; y <= maxY; y++) {
69
+ for (let x = minX; x <= maxX; x++) {
70
+ // Check if pixel is inside the circle
71
+ const dx = x - centerX;
72
+ const dy = y - centerY;
73
+ const distanceSquared = dx * dx + dy * dy;
74
+
75
+ if (distanceSquared <= radius * radius) {
76
+ const index = y * width + x;
77
+ if (data[index] !== undefined) {
78
+ luminanceSum += data[index];
79
+ pixelCount++;
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ return pixelCount > 0 ? luminanceSum / pixelCount : 0;
86
+ };
87
+
29
88
  const isFrameBright = (frame: Frame): boolean => {
30
89
  'worklet';
31
- return getAverageBrightness(frame) > 80;
90
+ return getAverageBrightness(frame) > 60;
32
91
  };
33
92
 
34
- export { isFrameBright, getAverageBrightness };
93
+ /**
94
+ * Check if a circular region in the frame is bright enough
95
+ */
96
+ const isCircularRegionBright = (frame: Frame, circleRect: Rect, threshold: number = 60): boolean => {
97
+ 'worklet';
98
+ return getCircularRegionBrightness(frame, circleRect) > threshold;
99
+ };
100
+
101
+ export {
102
+ isFrameBright,
103
+ getAverageBrightness,
104
+ getCircularRegionBrightness,
105
+ isCircularRegionBright
106
+ };
@@ -1,18 +1,23 @@
1
1
  const handleDeepLink = ({ url }: { url: string }) => {
2
+ console.log('[handleDeepLink] Received URL:', url);
2
3
  const isHttps = url.includes('https');
3
4
  const route = url.replace(/http(s)?(:)?(\/\/)?/g, '');
4
5
  const segments = route.split('/');
6
+ console.log('[handleDeepLink] Parsed segments:', segments);
5
7
  let baseUrl = '';
6
8
  let sessionId = '';
7
9
 
8
10
  for (let i = 0; i < segments.length; i++) {
9
11
  if (segments[i] === 'verification-session') {
10
12
  sessionId = segments[i + 1] ?? '';
13
+ console.log('[handleDeepLink] Found sessionId:', sessionId);
11
14
  } else if (segments[i] === 'app-url') {
12
15
  baseUrl = `${isHttps ? 'https' : 'http'}://${segments[i + 1]}`;
16
+ console.log('[handleDeepLink] Found baseUrl:', baseUrl);
13
17
  }
14
18
  }
15
19
 
20
+ console.log('[handleDeepLink] Returning:', { baseUrl, sessionId });
16
21
  return [baseUrl, sessionId];
17
22
  };
18
23
 
@@ -1,3 +1,5 @@
1
+ import { trackApiCall, trackError } from './analytics.utils';
2
+
1
3
  interface ErrorResponse {
2
4
  message: string;
3
5
  }
@@ -52,49 +54,121 @@ const request = async <TResponse, TBody>(
52
54
  });
53
55
  }
54
56
 
55
- const response = await fetch(url, {
56
- method: httpMethod,
57
- headers: {
58
- 'Content-Type': 'application/json',
59
- },
60
- body: body ? JSON.stringify(body) : undefined,
61
- });
62
-
63
- let responseJson = null;
57
+ const startTime = Date.now();
58
+ let statusCode = 0;
59
+ let success = false;
64
60
 
65
61
  try {
66
- responseJson = await response.json();
67
- } catch (error) {
68
- // throw new Error("Invalid response");
69
- }
70
-
71
- if (response && !response.ok && responseJson) {
72
- const message = (responseJson as unknown as ErrorResponse).message;
62
+ const response = await fetch(url, {
63
+ method: httpMethod,
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ },
67
+ body: body ? JSON.stringify(body) : undefined,
68
+ });
73
69
 
74
- if (response.status === 401) {
75
- throw new UnauthorizedError(message);
76
- }
70
+ statusCode = response.status;
71
+ success = response.ok;
77
72
 
78
- if (response.status === 403) {
79
- throw new ForbiddenError(message);
80
- }
73
+ let responseJson = null;
81
74
 
82
- if (response.status === 404) {
83
- throw new NotFoundError(message);
75
+ try {
76
+ responseJson = await response.json();
77
+ } catch (error) {
78
+ // Invalid JSON response
84
79
  }
85
80
 
86
- if (response.status >= 500) {
87
- throw new InternalServerError(message);
81
+ // Track API call performance (non-blocking)
82
+ // Wrap in try-catch to ensure analytics failures never mask HTTP errors
83
+ try {
84
+ const duration = Date.now() - startTime;
85
+ trackApiCall(url, duration, statusCode, success).catch(() => { });
86
+ } catch { }
87
+
88
+ if (response && !response.ok && responseJson) {
89
+ const message = (responseJson as unknown as ErrorResponse).message;
90
+
91
+ const getErrorCodeFromStatus = (status: number): string => {
92
+ switch (status) {
93
+ case 400:
94
+ return 'BAD_REQUEST';
95
+ case 401:
96
+ return 'UNAUTHORIZED';
97
+ case 403:
98
+ return 'FORBIDDEN';
99
+ case 404:
100
+ return 'NOT_FOUND';
101
+ case 500:
102
+ return 'INTERNAL_SERVER_ERROR';
103
+ case 502:
104
+ return 'BAD_GATEWAY';
105
+ case 503:
106
+ return 'SERVICE_UNAVAILABLE';
107
+ case 504:
108
+ return 'GATEWAY_TIMEOUT';
109
+ default:
110
+ return `API_ERROR_${status}`;
111
+ }
112
+ };
113
+
114
+ const getSeverityFromStatus = (status: number): 'low' | 'medium' | 'high' | 'critical' => {
115
+ if (status >= 500) return 'high';
116
+ if (status === 401 || status === 403) return 'medium';
117
+ if (status === 400 || status === 404) return 'low';
118
+ return 'medium';
119
+ };
120
+
121
+ // Track API error (non-blocking)
122
+ // Wrap in try-catch to ensure analytics failures never mask HTTP errors
123
+ try {
124
+ trackError(
125
+ getErrorCodeFromStatus(statusCode),
126
+ message || 'API request failed',
127
+ 'http_client',
128
+ getSeverityFromStatus(statusCode)
129
+ ).catch(() => { });
130
+ } catch { }
131
+
132
+ if (response.status === 401) {
133
+ throw new UnauthorizedError(message);
134
+ }
135
+
136
+ if (response.status === 403) {
137
+ throw new ForbiddenError(message);
138
+ }
139
+
140
+ if (response.status === 404) {
141
+ throw new NotFoundError(message);
142
+ }
143
+
144
+ if (response.status >= 500) {
145
+ throw new InternalServerError(message);
146
+ }
147
+
148
+ if (response.status >= 400) {
149
+ throw new BadRequestError(message);
150
+ }
151
+
152
+ throw new Error(message);
88
153
  }
89
154
 
90
- if (response.status >= 400) {
91
- throw new BadRequestError(message);
155
+ return responseJson as Promise<TResponse>;
156
+ } catch (error) {
157
+ // Only track network errors for actual network failures, not HTTP errors
158
+ // HTTP errors (4xx, 5xx) are already tracked above before throwing
159
+ if (!(error instanceof HttpClientError)) {
160
+ try {
161
+ const duration = Date.now() - startTime;
162
+ const errorMessage =
163
+ error instanceof Error ? error.message : 'Unknown error';
164
+
165
+ trackApiCall(url, duration, statusCode, false).catch(() => { });
166
+ trackError('NETWORK_ERROR', errorMessage, 'http_client', 'high').catch(() => { });
167
+ } catch { }
92
168
  }
93
169
 
94
- throw new Error(message);
170
+ throw error;
95
171
  }
96
-
97
- return responseJson as Promise<TResponse>;
98
172
  };
99
173
 
100
174
  const get = <TResponse>(url: string, simulatedResponse?: TResponse) => {