@trustchex/react-native-sdk 1.374.0 → 1.409.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 (137) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +1 -21
  2. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
  3. package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +636 -301
  4. package/ios/Camera/TrustchexCameraView.swift +9 -20
  5. package/ios/MLKit/MLKitModule.swift +1 -1
  6. package/ios/OpenCV/OpenCVHelper.h +0 -7
  7. package/ios/OpenCV/OpenCVHelper.mm +0 -60
  8. package/ios/OpenCV/OpenCVModule.h +0 -4
  9. package/ios/OpenCV/OpenCVModule.mm +440 -358
  10. package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
  11. package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
  12. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -29
  13. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +5 -0
  14. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
  15. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +26 -6
  16. package/lib/module/Screens/Dynamic/VideoCallScreen.js +676 -0
  17. package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
  18. package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
  19. package/lib/module/Screens/Static/ResultScreen.js +27 -13
  20. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +51 -51
  21. package/lib/module/Shared/Animations/video-call.json +1 -0
  22. package/lib/module/Shared/Components/DebugNavigationPanel.js +180 -14
  23. package/lib/module/Shared/Components/DebugOverlay.js +541 -0
  24. package/lib/module/Shared/Components/EIDScanner.js +1 -4
  25. package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +44 -0
  26. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +270 -0
  27. package/lib/module/Shared/Components/IdentityDocumentCamera.js +702 -1703
  28. package/lib/module/Shared/Components/IdentityDocumentCamera.types.js +3 -0
  29. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +273 -0
  30. package/lib/module/Shared/Components/NavigationManager.js +15 -3
  31. package/lib/module/Shared/Contexts/AppContext.js +1 -0
  32. package/lib/module/Shared/Libs/SignalingClient.js +128 -0
  33. package/lib/module/Shared/Libs/analytics.utils.js +4 -0
  34. package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
  35. package/lib/module/Shared/Libs/http-client.js +9 -0
  36. package/lib/module/Shared/Libs/promise.utils.js +16 -2
  37. package/lib/module/Shared/Libs/status-bar.utils.js +21 -0
  38. package/lib/module/Shared/Services/DataUploadService.js +294 -0
  39. package/lib/module/Shared/Services/VideoSessionService.js +156 -0
  40. package/lib/module/Shared/Services/WebRTCService.js +510 -0
  41. package/lib/module/Shared/Types/analytics.types.js +2 -0
  42. package/lib/module/Translation/Resources/en.js +20 -0
  43. package/lib/module/Translation/Resources/tr.js +20 -0
  44. package/lib/module/Trustchex.js +10 -0
  45. package/lib/module/version.js +1 -1
  46. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
  47. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
  48. package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
  49. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  50. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  51. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  52. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  53. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
  54. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
  55. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  56. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  57. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  58. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  59. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  60. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts +30 -0
  61. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts.map +1 -0
  62. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  63. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +35 -0
  64. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -0
  65. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -56
  66. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  67. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +88 -0
  68. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -0
  69. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +116 -0
  70. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -0
  71. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +93 -0
  72. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -0
  73. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  74. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
  75. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  76. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
  77. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
  78. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  79. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  80. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  81. package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
  82. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
  83. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
  84. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
  85. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
  86. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
  87. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
  88. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
  89. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
  90. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +2 -0
  91. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
  92. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +4 -1
  93. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  94. package/lib/typescript/src/Translation/Resources/en.d.ts +20 -0
  95. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  96. package/lib/typescript/src/Translation/Resources/tr.d.ts +20 -0
  97. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  98. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  99. package/lib/typescript/src/version.d.ts +1 -1
  100. package/package.json +29 -2
  101. package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
  102. package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
  103. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +59 -33
  104. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +6 -0
  105. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
  106. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +34 -6
  107. package/src/Screens/Dynamic/VideoCallScreen.tsx +764 -0
  108. package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
  109. package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
  110. package/src/Screens/Static/ResultScreen.tsx +58 -23
  111. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +58 -72
  112. package/src/Shared/Animations/video-call.json +1 -0
  113. package/src/Shared/Components/DebugNavigationPanel.tsx +185 -9
  114. package/src/Shared/Components/DebugOverlay.tsx +656 -0
  115. package/src/Shared/Components/EIDScanner.tsx +1 -5
  116. package/src/Shared/Components/IdentityDocumentCamera.constants.ts +44 -0
  117. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +342 -0
  118. package/src/Shared/Components/IdentityDocumentCamera.tsx +1089 -2465
  119. package/src/Shared/Components/IdentityDocumentCamera.types.ts +136 -0
  120. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +364 -0
  121. package/src/Shared/Components/NavigationManager.tsx +14 -1
  122. package/src/Shared/Contexts/AppContext.ts +2 -0
  123. package/src/Shared/Libs/SignalingClient.ts +189 -0
  124. package/src/Shared/Libs/analytics.utils.ts +4 -0
  125. package/src/Shared/Libs/deeplink.utils.ts +12 -1
  126. package/src/Shared/Libs/http-client.ts +10 -0
  127. package/src/Shared/Libs/promise.utils.ts +16 -2
  128. package/src/Shared/Libs/status-bar.utils.ts +19 -0
  129. package/src/Shared/Services/DataUploadService.ts +395 -0
  130. package/src/Shared/Services/VideoSessionService.ts +190 -0
  131. package/src/Shared/Services/WebRTCService.ts +636 -0
  132. package/src/Shared/Types/analytics.types.ts +2 -0
  133. package/src/Shared/Types/identificationInfo.ts +5 -1
  134. package/src/Translation/Resources/en.ts +25 -0
  135. package/src/Translation/Resources/tr.ts +27 -0
  136. package/src/Trustchex.tsx +12 -2
  137. package/src/version.ts +1 -1
@@ -0,0 +1,189 @@
1
+ import EventSource, { type EventSourceListener } from 'react-native-sse';
2
+
3
+ export type SignalingMessageType =
4
+ | 'offer'
5
+ | 'answer'
6
+ | 'ice-candidate'
7
+ | 'command';
8
+
9
+ export interface SignalingMessage {
10
+ id?: string;
11
+ type: SignalingMessageType;
12
+ payload: any;
13
+ createdAt?: string;
14
+ }
15
+
16
+ export type SignalingEventHandler = (message: SignalingMessage) => void;
17
+ export type SessionEndedHandler = (state: string) => void;
18
+
19
+ export class SignalingClient {
20
+ private eventSource: EventSource | null = null;
21
+ private sessionId: string;
22
+ private baseUrl: string;
23
+ private onMessage: SignalingEventHandler;
24
+ private onConnected?: () => void;
25
+ private onDisconnected?: () => void;
26
+ private onSessionEnded?: SessionEndedHandler;
27
+ private identificationId?: string;
28
+
29
+ constructor(
30
+ baseUrl: string,
31
+ sessionId: string,
32
+ onMessage: SignalingEventHandler,
33
+ identificationId?: string,
34
+ onSessionEnded?: SessionEndedHandler
35
+ ) {
36
+ this.baseUrl = baseUrl;
37
+ this.sessionId = sessionId;
38
+ this.onMessage = onMessage;
39
+ this.identificationId = identificationId;
40
+ this.onSessionEnded = onSessionEnded;
41
+ }
42
+
43
+ public connect(): void {
44
+ if (this.eventSource) {
45
+ this.eventSource.close();
46
+ }
47
+
48
+ const urlParams = new URLSearchParams();
49
+ if (this.identificationId) {
50
+ urlParams.append('identificationId', this.identificationId);
51
+ }
52
+ const url = `${this.baseUrl}/api/app/mobile/video-sessions/${this.sessionId}/signaling/stream?${urlParams.toString()}`;
53
+
54
+ console.log('[SignalingClient] Connecting to SSE:', url);
55
+
56
+ this.eventSource = new EventSource(url, {
57
+ pollingInterval: 0, // 0 means default/no polling if SSE is real
58
+ });
59
+
60
+ const listener: EventSourceListener = (event) => {
61
+ if (event.type === 'open') {
62
+ console.log('[SignalingClient] Connected');
63
+ this.onConnected?.();
64
+ } else if (event.type === 'error') {
65
+ console.error(
66
+ '[SignalingClient] Connection error:',
67
+ JSON.stringify(event, null, 2)
68
+ );
69
+ this.onDisconnected?.();
70
+ } else if (event.type === 'message') {
71
+ try {
72
+ const data = JSON.parse(event.data || '{}');
73
+
74
+ if (
75
+ ['offer', 'answer', 'ice-candidate', 'command'].includes(data.type)
76
+ ) {
77
+ this.onMessage({
78
+ id: data.id,
79
+ type: data.type as SignalingMessageType,
80
+ payload: data.payload,
81
+ createdAt: data.createdAt,
82
+ });
83
+ }
84
+ } catch (e) {
85
+ console.error('[SignalingClient] Error parsing message:', e);
86
+ }
87
+ }
88
+ };
89
+
90
+ const customEventListener = (event: any) => {
91
+ try {
92
+ const data = JSON.parse(event.data || '{}');
93
+ const eventType = event.type;
94
+
95
+ if (
96
+ ['offer', 'answer', 'ice-candidate', 'command'].includes(eventType)
97
+ ) {
98
+ this.onMessage({
99
+ id: data.id,
100
+ type: eventType as SignalingMessageType,
101
+ payload: data.payload,
102
+ createdAt: data.createdAt,
103
+ });
104
+ }
105
+ } catch (e) {
106
+ console.error('[SignalingClient] Error parsing custom event:', e);
107
+ }
108
+ };
109
+
110
+ // Ping handler - server sends pings to keep connection alive
111
+ const pingListener = (event: any) => {
112
+ console.log('[SignalingClient] Received ping');
113
+ // Just acknowledge by doing nothing, server-side heartbeat keeps connection alive
114
+ };
115
+
116
+ // Session-ended event listener
117
+ const sessionEndedListener = (event: any) => {
118
+ try {
119
+ const data = JSON.parse(event.data || '{}');
120
+ console.log('[SignalingClient] Session ended:', data.state);
121
+ if (this.onSessionEnded) {
122
+ this.onSessionEnded(data.state);
123
+ }
124
+ } catch (e) {
125
+ console.error(
126
+ '[SignalingClient] Error parsing session-ended event:',
127
+ e
128
+ );
129
+ }
130
+ };
131
+
132
+ this.eventSource.addEventListener('open', listener);
133
+ this.eventSource.addEventListener('message', listener);
134
+ this.eventSource.addEventListener('error', listener);
135
+ this.eventSource.addEventListener('ping' as any, pingListener);
136
+ this.eventSource.addEventListener('offer' as any, customEventListener);
137
+ this.eventSource.addEventListener('answer' as any, customEventListener);
138
+ this.eventSource.addEventListener(
139
+ 'ice-candidate' as any,
140
+ customEventListener
141
+ );
142
+ this.eventSource.addEventListener('command' as any, customEventListener);
143
+ this.eventSource.addEventListener(
144
+ 'session-ended' as any,
145
+ sessionEndedListener
146
+ );
147
+ }
148
+
149
+ public async send(type: SignalingMessageType, payload: any): Promise<void> {
150
+ const urlParams = new URLSearchParams();
151
+ if (this.identificationId) {
152
+ urlParams.append('identificationId', this.identificationId);
153
+ }
154
+ const url = `${this.baseUrl}/api/app/mobile/video-sessions/${this.sessionId}/signaling?${urlParams.toString()}`;
155
+
156
+ try {
157
+ const body = {
158
+ type,
159
+ data: payload,
160
+ };
161
+
162
+ const response = await fetch(url, {
163
+ method: 'POST',
164
+ headers: {
165
+ 'Content-Type': 'application/json',
166
+ },
167
+ body: JSON.stringify(body),
168
+ });
169
+
170
+ if (!response.ok) {
171
+ throw new Error(
172
+ `Failed to send signaling message: ${response.statusText}`
173
+ );
174
+ }
175
+ } catch (error) {
176
+ console.error('[SignalingClient] Error sending message:', error);
177
+ throw error;
178
+ }
179
+ }
180
+
181
+ public disconnect(): void {
182
+ if (this.eventSource) {
183
+ this.eventSource.removeAllEventListeners();
184
+ this.eventSource.close();
185
+ this.eventSource = null;
186
+ this.onDisconnected?.();
187
+ }
188
+ }
189
+ }
@@ -289,6 +289,10 @@ const STEP_EVENT_MAP: Record<
289
289
  started: AnalyticsEventName.LIVENESS_CHECK_STARTED,
290
290
  completed: AnalyticsEventName.LIVENESS_CHECK_COMPLETED,
291
291
  },
292
+ video_call: {
293
+ started: AnalyticsEventName.VIDEO_CALL_STARTED,
294
+ completed: AnalyticsEventName.VIDEO_CALL_COMPLETED,
295
+ },
292
296
  };
293
297
 
294
298
  function getStepEventName(
@@ -10,7 +10,10 @@ const handleDeepLink = ({ url }: { url: string }) => {
10
10
  let sessionId = '';
11
11
 
12
12
  for (let i = 0; i < segments.length; i++) {
13
- if (segments[i] === 'verification-session') {
13
+ if (
14
+ segments[i] === 'verification-session' ||
15
+ segments[i] === 'verification-sessions'
16
+ ) {
14
17
  sessionId = segments[i + 1] ?? '';
15
18
  debugLog('handleDeepLink', 'Found sessionId:', sessionId);
16
19
  } else if (segments[i] === 'app-url') {
@@ -19,6 +22,14 @@ const handleDeepLink = ({ url }: { url: string }) => {
19
22
  }
20
23
  }
21
24
 
25
+ // If no app-url segment found, derive baseUrl from the URL itself
26
+ if (!baseUrl && sessionId) {
27
+ const match = url.match(/^(https?:\/\/[^/]+)/);
28
+ if (match) {
29
+ baseUrl = match[1];
30
+ }
31
+ }
32
+
22
33
  debugLog('handleDeepLink', 'Returning:', { baseUrl, sessionId });
23
34
  return [baseUrl, sessionId];
24
35
  };
@@ -64,6 +64,11 @@ const request = async <TResponse, TBody>(
64
64
  let statusCode = 0;
65
65
  let success = false;
66
66
 
67
+ console.log(`[HTTP] ${httpMethod} ${url}`);
68
+ if (body) {
69
+ console.log('[HTTP] Request body:', JSON.stringify(body).substring(0, 200) + '...');
70
+ }
71
+
67
72
  try {
68
73
  const response = await fetch(url, {
69
74
  method: httpMethod,
@@ -75,13 +80,18 @@ const request = async <TResponse, TBody>(
75
80
 
76
81
  statusCode = response.status;
77
82
  success = response.ok;
83
+ console.log(`[HTTP] Response status: ${statusCode} ${response.ok ? '✓' : '✗'}`);
78
84
 
79
85
  let responseJson = null;
80
86
 
81
87
  try {
82
88
  responseJson = await response.json();
89
+ if (responseJson) {
90
+ console.log('[HTTP] Response body:', JSON.stringify(responseJson).substring(0, 200) + '...');
91
+ }
83
92
  } catch (error) {
84
93
  // Invalid JSON response
94
+ console.log('[HTTP] Response body: (non-JSON)');
85
95
  }
86
96
 
87
97
  // Track API call performance (non-blocking)
@@ -4,17 +4,31 @@ const runWithRetry = async <T>(
4
4
  delay: number = 1000
5
5
  ): Promise<T> => {
6
6
  let retries = 0;
7
+ let lastError: Error | unknown;
7
8
  let result: T;
8
9
  while (retries < maxRetries) {
9
10
  try {
11
+ if (retries > 0) {
12
+ console.log(`[Retry] Attempt ${retries + 1}/${maxRetries}...`);
13
+ }
10
14
  result = await fn();
15
+ if (retries > 0) {
16
+ console.log(`[Retry] ✓ Success on attempt ${retries + 1}`);
17
+ }
11
18
  return result;
12
19
  } catch (error) {
20
+ lastError = error;
13
21
  retries++;
14
- await new Promise((resolve) => setTimeout(resolve, delay * retries));
22
+ console.error(`[Retry] Attempt ${retries}/${maxRetries} failed:`, error instanceof Error ? error.message : error);
23
+ if (retries < maxRetries) {
24
+ const waitTime = delay * retries;
25
+ console.log(`[Retry] Waiting ${waitTime}ms before retry...`);
26
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
27
+ }
15
28
  }
16
29
  }
17
- throw new Error('Max retries exceeded');
30
+ console.error('[Retry] ✗ All retries exhausted. Last error:', lastError);
31
+ throw new Error(`Max retries (${maxRetries}) exceeded. Last error: ${lastError instanceof Error ? lastError.message : String(lastError)}`);
18
32
  };
19
33
 
20
34
  export { runWithRetry };
@@ -0,0 +1,19 @@
1
+ import { StatusBar } from 'react-native';
2
+ import { useEffect } from 'react';
3
+
4
+ /**
5
+ * Configure status bar for white background with dark content for better contrast
6
+ */
7
+ export const configureStatusBarForWhiteBackground = (): void => {
8
+ StatusBar.setBarStyle('dark-content', true);
9
+ StatusBar.setBackgroundColor('#ffffff', true);
10
+ };
11
+
12
+ /**
13
+ * Hook to configure status bar for white background on mount
14
+ */
15
+ export const useStatusBarWhiteBackground = (): void => {
16
+ useEffect(() => {
17
+ configureStatusBarForWhiteBackground();
18
+ }, []);
19
+ };