@transfergratis/react-native-sdk 0.1.4 → 0.1.6

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 (216) hide show
  1. package/build/api/axios.d.ts +30 -0
  2. package/build/api/axios.d.ts.map +1 -0
  3. package/build/api/axios.js +92 -0
  4. package/build/api/axios.js.map +1 -0
  5. package/build/components/EnhancedCameraView.d.ts +1 -41
  6. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  7. package/build/components/EnhancedCameraView.js +75 -34
  8. package/build/components/EnhancedCameraView.js.map +1 -1
  9. package/build/components/EnhancedCameraView.web.d.ts +1 -41
  10. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  11. package/build/components/EnhancedCameraView.web.js +28 -4
  12. package/build/components/EnhancedCameraView.web.js.map +1 -1
  13. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +2 -2
  14. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  15. package/build/components/KYCElements/CountrySelectionTemplate.js +77 -114
  16. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  17. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  18. package/build/components/KYCElements/FileUploadTemplate.js +7 -3
  19. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  20. package/build/components/KYCElements/IDCardCapture.d.ts +7 -2
  21. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  22. package/build/components/KYCElements/IDCardCapture.js +253 -104
  23. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  24. package/build/components/KYCElements/InitializationStep.d.ts +5 -0
  25. package/build/components/KYCElements/InitializationStep.d.ts.map +1 -0
  26. package/build/components/KYCElements/InitializationStep.js +41 -0
  27. package/build/components/KYCElements/InitializationStep.js.map +1 -0
  28. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  29. package/build/components/KYCElements/LocationCaptureTemplate.js +15 -13
  30. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -2
  32. package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
  33. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  34. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -2
  35. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
  36. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  37. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -2
  38. package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
  39. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  40. package/build/components/KYCElements/ReviewSubmitTemplate.d.ts +12 -0
  41. package/build/components/KYCElements/ReviewSubmitTemplate.d.ts.map +1 -0
  42. package/build/components/KYCElements/ReviewSubmitTemplate.js +171 -0
  43. package/build/components/KYCElements/ReviewSubmitTemplate.js.map +1 -0
  44. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts +6 -2
  45. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  46. package/build/components/KYCElements/SelfieCaptureTemplate.js +137 -38
  47. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  48. package/build/components/KYCElements/VerificationProgressTemplate.d.ts +12 -0
  49. package/build/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -0
  50. package/build/components/KYCElements/VerificationProgressTemplate.js +194 -0
  51. package/build/components/KYCElements/VerificationProgressTemplate.js.map +1 -0
  52. package/build/components/OverLay/IdCard.d.ts +1 -1
  53. package/build/components/OverLay/IdCard.d.ts.map +1 -1
  54. package/build/components/OverLay/IdCard.js +10 -6
  55. package/build/components/OverLay/IdCard.js.map +1 -1
  56. package/build/components/OverLay/SelfieOverlay.d.ts +1 -1
  57. package/build/components/OverLay/SelfieOverlay.d.ts.map +1 -1
  58. package/build/components/OverLay/SelfieOverlay.js +5 -4
  59. package/build/components/OverLay/SelfieOverlay.js.map +1 -1
  60. package/build/components/OverLay/type.d.ts +71 -1
  61. package/build/components/OverLay/type.d.ts.map +1 -1
  62. package/build/components/OverLay/type.js.map +1 -1
  63. package/build/components/TemplateKYCExample.d.ts +4 -1
  64. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  65. package/build/components/TemplateKYCExample.js +74 -199
  66. package/build/components/TemplateKYCExample.js.map +1 -1
  67. package/build/components/TemplateKYCFlowRefactored.d.ts +3 -2
  68. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  69. package/build/components/TemplateKYCFlowRefactored.js +64 -40
  70. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  71. package/build/components/example/OrientationVideoExample.d.ts.map +1 -1
  72. package/build/components/example/OrientationVideoExample.js +1 -5
  73. package/build/components/example/OrientationVideoExample.js.map +1 -1
  74. package/build/config/countriesData.d.ts +3 -0
  75. package/build/config/countriesData.d.ts.map +1 -0
  76. package/build/config/countriesData.js +79 -0
  77. package/build/config/countriesData.js.map +1 -0
  78. package/build/config/region_mapping.d.ts +3 -0
  79. package/build/config/region_mapping.d.ts.map +1 -0
  80. package/build/config/region_mapping.js +687 -0
  81. package/build/config/region_mapping.js.map +1 -0
  82. package/build/hooks/useI18n.d.ts +11 -0
  83. package/build/hooks/useI18n.d.ts.map +1 -0
  84. package/build/hooks/useI18n.js +37 -0
  85. package/build/hooks/useI18n.js.map +1 -0
  86. package/build/hooks/useOrientationVideo.d.ts +1 -2
  87. package/build/hooks/useOrientationVideo.d.ts.map +1 -1
  88. package/build/hooks/useOrientationVideo.js +2 -1
  89. package/build/hooks/useOrientationVideo.js.map +1 -1
  90. package/build/hooks/useRealtimeVerifier.d.ts +28 -0
  91. package/build/hooks/useRealtimeVerifier.d.ts.map +1 -0
  92. package/build/hooks/useRealtimeVerifier.js +91 -0
  93. package/build/hooks/useRealtimeVerifier.js.map +1 -0
  94. package/build/hooks/useTemplateKYCFlow.d.ts +6 -3
  95. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  96. package/build/hooks/useTemplateKYCFlow.js +356 -42
  97. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  98. package/build/i18n/en/index.d.ts +168 -0
  99. package/build/i18n/en/index.d.ts.map +1 -0
  100. package/build/i18n/en/index.js +195 -0
  101. package/build/i18n/en/index.js.map +1 -0
  102. package/build/i18n/fr/index.d.ts +168 -0
  103. package/build/i18n/fr/index.d.ts.map +1 -0
  104. package/build/i18n/fr/index.js +194 -0
  105. package/build/i18n/fr/index.js.map +1 -0
  106. package/build/i18n/index.d.ts +10 -0
  107. package/build/i18n/index.d.ts.map +1 -0
  108. package/build/i18n/index.js +56 -0
  109. package/build/i18n/index.js.map +1 -0
  110. package/build/i18n/types.d.ts +153 -0
  111. package/build/i18n/types.d.ts.map +1 -0
  112. package/build/i18n/types.js +3 -0
  113. package/build/i18n/types.js.map +1 -0
  114. package/build/i18n/usage-example.d.ts +4 -0
  115. package/build/i18n/usage-example.d.ts.map +1 -0
  116. package/build/i18n/usage-example.js +189 -0
  117. package/build/i18n/usage-example.js.map +1 -0
  118. package/build/index.d.ts +1 -0
  119. package/build/index.d.ts.map +1 -1
  120. package/build/index.js +2 -0
  121. package/build/index.js.map +1 -1
  122. package/build/modules/api/CardAuthentification.d.ts +22 -0
  123. package/build/modules/api/CardAuthentification.d.ts.map +1 -0
  124. package/build/modules/api/CardAuthentification.js +107 -0
  125. package/build/modules/api/CardAuthentification.js.map +1 -0
  126. package/build/modules/api/KYCService.d.ts +58 -1
  127. package/build/modules/api/KYCService.d.ts.map +1 -1
  128. package/build/modules/api/KYCService.js +304 -27
  129. package/build/modules/api/KYCService.js.map +1 -1
  130. package/build/modules/api/SelfieVerification.d.ts +3 -0
  131. package/build/modules/api/SelfieVerification.d.ts.map +1 -0
  132. package/build/modules/api/SelfieVerification.js +9 -0
  133. package/build/modules/api/SelfieVerification.js.map +1 -0
  134. package/build/modules/api/backendApi.d.ts +2 -0
  135. package/build/modules/api/backendApi.d.ts.map +1 -0
  136. package/build/modules/api/backendApi.js +6 -0
  137. package/build/modules/api/backendApi.js.map +1 -0
  138. package/build/modules/api/types.d.ts +45 -0
  139. package/build/modules/api/types.d.ts.map +1 -0
  140. package/build/modules/api/types.js +2 -0
  141. package/build/modules/api/types.js.map +1 -0
  142. package/build/types/KYC.types.d.ts +56 -7
  143. package/build/types/KYC.types.d.ts.map +1 -1
  144. package/build/types/KYC.types.js +9 -1
  145. package/build/types/KYC.types.js.map +1 -1
  146. package/build/utils/cropByObb.d.ts +11 -0
  147. package/build/utils/cropByObb.d.ts.map +1 -0
  148. package/build/utils/cropByObb.js +78 -0
  149. package/build/utils/cropByObb.js.map +1 -0
  150. package/build/utils/get-document-type-info.d.ts +13 -0
  151. package/build/utils/get-document-type-info.d.ts.map +1 -0
  152. package/build/utils/get-document-type-info.js +59 -0
  153. package/build/utils/get-document-type-info.js.map +1 -0
  154. package/build/utils/pathToBase64.d.ts +3 -0
  155. package/build/utils/pathToBase64.d.ts.map +1 -0
  156. package/build/utils/pathToBase64.js +47 -0
  157. package/build/utils/pathToBase64.js.map +1 -0
  158. package/build/utils/remove-duplicate.d.ts +2 -0
  159. package/build/utils/remove-duplicate.d.ts.map +1 -0
  160. package/build/utils/remove-duplicate.js +4 -0
  161. package/build/utils/remove-duplicate.js.map +1 -0
  162. package/build/web/WebKYCEntry.d.ts +9 -0
  163. package/build/web/WebKYCEntry.d.ts.map +1 -0
  164. package/build/web/WebKYCEntry.js +156 -0
  165. package/build/web/WebKYCEntry.js.map +1 -0
  166. package/build/web/index.d.ts +2 -0
  167. package/build/web/index.d.ts.map +1 -0
  168. package/build/web/index.js +2 -0
  169. package/build/web/index.js.map +1 -0
  170. package/package.json +3 -1
  171. package/src/api/axios.ts +144 -0
  172. package/src/components/EnhancedCameraView.tsx +96 -78
  173. package/src/components/EnhancedCameraView.web.tsx +41 -40
  174. package/src/components/KYCElements/CountrySelectionTemplate.tsx +111 -136
  175. package/src/components/KYCElements/FileUploadTemplate.tsx +14 -8
  176. package/src/components/KYCElements/IDCardCapture.tsx +311 -115
  177. package/src/components/KYCElements/InitializationStep.tsx +53 -0
  178. package/src/components/KYCElements/LocationCaptureTemplate.tsx +17 -15
  179. package/src/components/KYCElements/OrientationVideoCapture.tsx +2 -2
  180. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +2 -2
  181. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +2 -2
  182. package/src/components/KYCElements/ReviewSubmitTemplate.tsx +201 -0
  183. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +174 -57
  184. package/src/components/KYCElements/VerificationProgressTemplate.tsx +246 -0
  185. package/src/components/OverLay/IdCard.tsx +17 -9
  186. package/src/components/OverLay/SelfieOverlay.tsx +6 -5
  187. package/src/components/OverLay/type.ts +64 -2
  188. package/src/components/TemplateKYCExample.tsx +80 -200
  189. package/src/components/TemplateKYCFlowRefactored.tsx +80 -48
  190. package/src/components/example/OrientationVideoExample.tsx +3 -7
  191. package/src/config/countriesData.ts +84 -0
  192. package/src/config/region_mapping.ts +688 -0
  193. package/src/hooks/useI18n.ts +53 -0
  194. package/src/hooks/useOrientationVideo.ts +2 -2
  195. package/src/hooks/useRealtimeVerifier.ts +128 -0
  196. package/src/hooks/useTemplateKYCFlow.tsx +407 -57
  197. package/src/i18n/README.md +288 -0
  198. package/src/i18n/en/index.ts +206 -0
  199. package/src/i18n/fr/index.ts +205 -0
  200. package/src/i18n/index.ts +65 -0
  201. package/src/i18n/types.ts +172 -0
  202. package/src/i18n/usage-example.tsx +202 -0
  203. package/src/index.ts +3 -0
  204. package/src/modules/api/CardAuthentification.ts +114 -0
  205. package/src/modules/api/KYCService.ts +350 -30
  206. package/src/modules/api/SelfieVerification.ts +11 -0
  207. package/src/modules/api/backendApi.ts +8 -0
  208. package/src/modules/api/types.ts +51 -0
  209. package/src/types/KYC.types.ts +82 -14
  210. package/src/utils/cropByObb.ts +99 -0
  211. package/src/utils/get-document-type-info.ts +62 -0
  212. package/src/utils/pathToBase64.ts +47 -0
  213. package/src/utils/remove-duplicate.ts +3 -0
  214. package/src/web/WebKYCEntry.tsx +215 -0
  215. package/src/web/index.ts +1 -0
  216. package/src/types/nativewind.d.ts +0 -2
@@ -1,3 +1,5 @@
1
+ import { VerificationResult } from "../modules/api/types";
2
+
1
3
  // Types pour les documents
2
4
  export interface Document {
3
5
  id: string;
@@ -111,6 +113,8 @@ export type KYCElementType =
111
113
  | 'selfie_capture'
112
114
  | 'verification'
113
115
  | 'completion';
116
+ //KYCElementType shorted
117
+
114
118
 
115
119
  // Configuration d'un élément KYC
116
120
  export interface KYCElement {
@@ -306,7 +310,7 @@ export interface LocalizedText {
306
310
  export interface ComponentUI {
307
311
  icon?: string;
308
312
  themeColor?: string;
309
- buttonText: LocalizedText;
313
+ buttonText: LocalizedText | Record<string, LocalizedText>;
310
314
  backgroundColor?: string;
311
315
  textColor?: string;
312
316
  borderRadius?: number;
@@ -314,16 +318,23 @@ export interface ComponentUI {
314
318
 
315
319
  // Types de documents gouvernementaux supportés
316
320
  export type GovernmentDocumentType =
317
- | 'id_card'
321
+ | 'identity_card'
318
322
  | 'passport'
319
- | 'drivers_license'
320
- | 'residence_permit'
323
+ | 'drivers_licence'
324
+ | 'health_insurance_card'
325
+ | 'permanent_residence'
321
326
  | 'national_id'
322
- | 'voter_id'
323
- | 'military_id'
324
- | 'student_id'
325
327
  | 'work_permit'
326
- | 'other';
328
+
329
+ export const GovernmentDocumentTypeShorted: Record<GovernmentDocumentType, string> = {
330
+ identity_card: 'id',
331
+ passport: 'pp',
332
+ drivers_licence: 'dl',
333
+ health_insurance_card: 'hic',
334
+ permanent_residence: 'pr',
335
+ national_id: 'id',
336
+ work_permit: 'wp',
337
+ }
327
338
 
328
339
  // Configuration spécifique pour chaque type de composant
329
340
  export interface IDCardConfig {
@@ -346,7 +357,7 @@ export interface IDCardConfig {
346
357
  export interface SelfieConfig {
347
358
  liveness_check: boolean;
348
359
  max_attempts: number;
349
- orientations: ('front' | 'left' | 'right')[]; // Tableau d'orientations à capturer
360
+ orientations: ('center' | 'left' | 'right')[]; // Tableau d'orientations à capturer
350
361
  }
351
362
 
352
363
  export interface FileUploadConfig {
@@ -377,12 +388,12 @@ export type ComponentConfig =
377
388
  // Nouveau type de composant basé sur le template JSON
378
389
  export interface TemplateComponent {
379
390
  id: number;
380
- type: 'id_card' | 'selfie' | 'file_upload' | 'location' | 'country_selection';
391
+ type: 'id_card' | 'selfie' | 'file_upload' | 'location' | 'country_selection' | 'initialization' | 'review_submit' | 'verification_progress';
381
392
  order: number;
382
393
  templateId?: number;
383
- labels: LocalizedText;
384
- instructions: LocalizedText;
385
- ui: ComponentUI;
394
+ labels: LocalizedText | Record<string, LocalizedText>;
395
+ instructions: LocalizedText | Record<string, LocalizedText>;
396
+ ui: ComponentUI | Record<string, ComponentUI>;
386
397
  config: ComponentConfig;
387
398
  }
388
399
 
@@ -405,6 +416,25 @@ export interface TemplateState {
405
416
  isProcessing: boolean;
406
417
  currentLanguage: string;
407
418
  showCustomStepper: boolean;
419
+ session: SessionState;
420
+ verification: VerificationState;
421
+ }
422
+
423
+ export interface SessionState {
424
+ session_id: string;
425
+ token: string;
426
+ isInitialized: boolean;
427
+ isProcessing: boolean;
428
+ error: string | null;
429
+ }
430
+
431
+ export type VerificationStatus = 'idle' | 'in_progress' | 'success' | 'failed';
432
+
433
+
434
+
435
+ export interface VerificationState {
436
+ status: VerificationStatus;
437
+ result?: VerificationResult;
408
438
  }
409
439
 
410
440
  // Actions pour le template KYC
@@ -419,6 +449,8 @@ export interface TemplateActions {
419
449
  resetTemplate: () => void;
420
450
  setLanguage: (language: string) => void;
421
451
  showCustomStepper: (show: boolean) => void;
452
+ setVerificationState: (state: VerificationState) => void;
453
+ submitVerification: () => Promise<void>;
422
454
  }
423
455
 
424
456
  // Hook pour le template KYC
@@ -431,4 +463,40 @@ export interface UseTemplateReturn {
431
463
  canGoPrevious: boolean;
432
464
  isComplete: boolean;
433
465
  getLocalizedText: (text: LocalizedText) => string;
434
- }
466
+ initializeSession: () => Promise<void>;
467
+ }
468
+
469
+
470
+ export interface ISilentCaptureResult {
471
+ success: boolean;
472
+ path?: string;
473
+ mrz?: string;
474
+ error?: string;
475
+ isAnalyzing?: boolean;
476
+ bbox?: IBbox;
477
+ country?: string;
478
+ documentType?: string;
479
+ }
480
+
481
+ export interface IBbox {
482
+ minX: number;
483
+ minY: number;
484
+ width: number;
485
+ height: number;
486
+ }
487
+
488
+ export interface ICountryMapping {
489
+ py_file?: string;
490
+ front?: string;
491
+ back?: string;
492
+ keys_found?: string | null;
493
+ }
494
+
495
+ export interface Country {
496
+ code?: string; // ISO 3166-1 alpha-2
497
+ name: string;
498
+ name_en: string;
499
+ flag: string;
500
+ regionMapping?: ICountryMapping;
501
+ hasRegions?: boolean;
502
+ }
@@ -0,0 +1,99 @@
1
+ import { Image as RNImage, Platform } from 'react-native';
2
+ import * as ImageManipulator from "expo-image-manipulator";
3
+
4
+ type Point = [number, number];
5
+
6
+ // Compute axis-aligned bounding box from oriented quadrilateral
7
+ function computeAabb(points: Point[]) {
8
+ const xs = points.map(p => p[0]);
9
+ const ys = points.map(p => p[1]);
10
+ const minX = Math.min(...xs);
11
+ const minY = Math.min(...ys);
12
+ const maxX = Math.max(...xs);
13
+ const maxY = Math.max(...ys);
14
+ return { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY };
15
+ }
16
+
17
+ // Web-only crop using Canvas; returns dataURL (base64)
18
+ async function cropWeb(uri: string, points: Point[]): Promise<string> {
19
+ return new Promise((resolve, reject) => {
20
+ const img = new Image();
21
+ img.crossOrigin = 'anonymous';
22
+ img.onload = () => {
23
+ const { minX, minY, width, height } = computeAabb(points);
24
+ const canvas = document.createElement('canvas');
25
+ canvas.width = Math.max(1, Math.round(width));
26
+ canvas.height = Math.max(1, Math.round(height));
27
+ const ctx = canvas.getContext('2d');
28
+ if (!ctx) return reject(new Error('Canvas context not available'));
29
+ ctx.drawImage(
30
+ img,
31
+ minX, // sx
32
+ minY, // sy
33
+ width, // sw
34
+ height, // sh
35
+ 0,
36
+ 0,
37
+ canvas.width,
38
+ canvas.height
39
+ );
40
+ resolve(canvas.toDataURL('image/jpeg', 0.92));
41
+ };
42
+ img.onerror = (e) => reject(e);
43
+ img.src = uri;
44
+ });
45
+ }
46
+
47
+ // Fallback: return original for native (no dependency added); caller can still use bbox to draw overlay
48
+ export async function cropByObb(uri: string, cardObb: any): Promise<{ base64?: string; bbox?: { minX: number; minY: number; width: number; height: number } }> {
49
+ try {
50
+ // card_obb format: [ [ [p1,p2,p3,p4], score ] ]
51
+ const first = Array.isArray(cardObb) ? cardObb[0] : null;
52
+ const points = Array.isArray(first?.[0]) ? (first[0] as Point[]) : null;
53
+ if (!points || points.length !== 4) return {};
54
+
55
+ const { minX, minY, width, height } = computeAabb(points);
56
+
57
+ if (Platform.OS === 'web') {
58
+ const base64 = await cropWeb(uri, points);
59
+ return { base64, bbox: { minX, minY, width, height } };
60
+ }
61
+ // Native: return bbox only; keep base64 undefined
62
+ return { bbox: { minX, minY, width, height } };
63
+ } catch (e) {
64
+ return {};
65
+ }
66
+ }
67
+
68
+
69
+
70
+
71
+ // exemple d'appel :
72
+ export async function cropImageWithBBox(uri: string, bbox: any) {
73
+ // 1️⃣ Récupère la taille originale de l'image
74
+ await RNImage.getSize(uri, (width, height) => {
75
+ console.log("Image originale:", width, height);
76
+ });
77
+
78
+ // // 2️⃣ Suppose que ton bbox vient d'une image affichée dans `displayedSize`
79
+ // const scaleX = originalWidth / displayedSize.width;
80
+ // const scaleY = originalHeight / displayedSize.height;
81
+
82
+ // 3️⃣ Convertir le bbox à la taille réelle scale 0.10 = 10%
83
+ const crop = {
84
+ originX: bbox.minX ,
85
+ originY: bbox.minY - 80,
86
+ width: bbox.width + 100,
87
+ height: bbox.height + 150,
88
+ };
89
+
90
+ // 4️⃣ Appliquer le crop
91
+ const result = await ImageManipulator.manipulateAsync(
92
+ uri,
93
+ [{ crop }],
94
+ { compress: 1, format: ImageManipulator.SaveFormat.PNG }
95
+ );
96
+
97
+ console.log("Image recadrée:", result.uri);
98
+ return result.uri;
99
+ }
@@ -0,0 +1,62 @@
1
+ import { GovernmentDocumentType } from "../types/KYC.types";
2
+
3
+ export const getDocumentTypeInfo = (docType: GovernmentDocumentType) => {
4
+ switch (docType) {
5
+ case 'identity_card':
6
+ return {
7
+ name: { en: 'ID Card', fr: 'Carte d\'identité' },
8
+ icon: '🆔',
9
+ instructions: { en: 'Position your ID card within the frame', fr: 'Positionnez votre carte d\'identité dans le cadre' }
10
+ };
11
+ case 'passport':
12
+ return {
13
+ name: { en: 'Passport', fr: 'Passeport' },
14
+ icon: '📘',
15
+ instructions: { en: 'Position your passport within the frame', fr: 'Positionnez votre passeport dans le cadre' }
16
+ };
17
+ case 'drivers_licence':
18
+ return {
19
+ name: { en: 'Driver\'s License', fr: 'Permis de conduire' },
20
+ icon: '🚗',
21
+ instructions: { en: 'Position your driver\'s license within the frame', fr: 'Positionnez votre permis de conduire dans le cadre' }
22
+ };
23
+ case 'permanent_residence':
24
+ return {
25
+ name: { en: 'Residence Permit', fr: 'Permis de séjour' },
26
+ icon: '🏠',
27
+ instructions: { en: 'Position your residence permit within the frame', fr: 'Positionnez votre permis de séjour dans le cadre' }
28
+ };
29
+ case 'national_id':
30
+ return {
31
+ name: { en: 'National ID', fr: 'Carte nationale d\'identité' },
32
+ icon: '🏛️',
33
+ instructions: { en: 'Position your national ID within the frame', fr: 'Positionnez votre carte nationale d\'identité dans le cadre' }
34
+ };
35
+ case 'health_insurance_card':
36
+ return {
37
+ name: { en: 'Health Insurance Card', fr: 'Carte d\'assurance santé' },
38
+ icon: '🗳️',
39
+ instructions: { en: 'Position your health insurance card within the frame', fr: 'Positionnez votre carte d\'assurance santé dans le cadre' }
40
+ };
41
+ case 'work_permit':
42
+ return {
43
+ name: { en: 'Work Permit', fr: 'Permis de travail' },
44
+ icon: '🎖️',
45
+ instructions: { en: 'Position your work permit within the frame', fr: 'Positionnez votre permis de travail dans le cadre' }
46
+ };
47
+
48
+ case 'passport':
49
+ return {
50
+ name: { en: 'Passport', fr: 'Passeport' },
51
+ icon: '💼',
52
+ instructions: { en: 'Position your passport within the frame', fr: 'Positionnez votre passeport dans le cadre' }
53
+ };
54
+
55
+ default:
56
+ return {
57
+ name: { en: 'Government Document', fr: 'Document gouvernemental' },
58
+ icon: '📄',
59
+ instructions: { en: 'Position your document within the frame', fr: 'Positionnez votre document dans le cadre' }
60
+ };
61
+ }
62
+ };
@@ -0,0 +1,47 @@
1
+ export async function pathToBase64(uri: string): Promise<string> {
2
+ if (!uri) throw new Error('pathToBase64: uri is required');
3
+
4
+ // If already a data URI, return the base64 part
5
+ if (uri.startsWith('data:')) {
6
+ const commaIndex = uri.indexOf(',');
7
+ return commaIndex !== -1 ? uri.substring(commaIndex + 1) : uri;
8
+ }
9
+
10
+ // Try Expo FileSystem if available (React Native + Expo)
11
+ try {
12
+ // Dynamically import to avoid hard dependency when not available
13
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
14
+ const FileSystem = require('expo-file-system');
15
+ if (FileSystem?.readAsStringAsync) {
16
+ const base64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });
17
+ if (base64) return base64;
18
+ }
19
+ } catch (_) {
20
+ // ignore - fall back to other strategies
21
+ }
22
+
23
+ // Generic fetch + FileReader strategy (works on web; often works on RN for file:// URIs)
24
+ try {
25
+ const response = await fetch(uri);
26
+ const blob = await response.blob();
27
+ const dataUrl = await new Promise<string>((resolve, reject) => {
28
+ const reader = new FileReader();
29
+ reader.onloadend = () => {
30
+ if (typeof reader.result === 'string') resolve(reader.result);
31
+ else reject(new Error('Failed to convert blob to data URL'));
32
+ };
33
+ reader.onerror = reject;
34
+ reader.readAsDataURL(blob);
35
+ });
36
+ const commaIndex = dataUrl.indexOf(',');
37
+ return commaIndex !== -1 ? dataUrl.substring(commaIndex + 1) : dataUrl;
38
+ } catch (err) {
39
+ // continue to final error
40
+ }
41
+
42
+ throw new Error('pathToBase64: unable to convert uri to base64');
43
+ }
44
+
45
+ export default pathToBase64;
46
+
47
+
@@ -0,0 +1,3 @@
1
+ export function removeDuplicates(arr: string[]): string[] {
2
+ return [...new Set(arr)];
3
+ }
@@ -0,0 +1,215 @@
1
+ import React, { useEffect, useState, useCallback } from 'react';
2
+ import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
3
+ // import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';
4
+ // import { KYCTemplate } from '../types/KYC.types';
5
+ import { useI18n } from '../hooks/useI18n';
6
+ import { TemplateKYCExample } from '../components/TemplateKYCExample';
7
+
8
+ interface WebKYCEntryProps {
9
+ onComplete?: (data: any) => void;
10
+ onError?: (error: string) => void;
11
+ onCancel?: () => void;
12
+ }
13
+
14
+ interface URLParams {
15
+ token?: string;
16
+ return_url?: string;
17
+ lang?: string;
18
+ theme?: string;
19
+ kyc_id?: string;
20
+ }
21
+
22
+ const WebKYCEntry: React.FC<WebKYCEntryProps> = ({
23
+ onComplete,
24
+ onError,
25
+ onCancel,
26
+ }) => {
27
+ const { setLocale } = useI18n();
28
+ const [urlParams, setUrlParams] = useState<URLParams>({});
29
+ const [isLoading, setIsLoading] = useState(true);
30
+ const [error, setError] = useState<string | null>(null);
31
+
32
+ // Parse URL parameters
33
+ const parseUrlParams = useCallback((): URLParams => {
34
+ if (typeof window === 'undefined') return {};
35
+
36
+ const urlParams = new URLSearchParams(window.location.search);
37
+ return {
38
+ token: urlParams.get('token') || undefined,
39
+ return_url: urlParams.get('return_url') || undefined,
40
+ lang: urlParams.get('lang') || 'en',
41
+ theme: urlParams.get('theme') || 'light',
42
+ kyc_id: urlParams.get('kyc_id') || undefined,
43
+ };
44
+ }, []);
45
+
46
+ // Safe redirect function with validation
47
+ const redirectToReturnUrl = useCallback((params: {
48
+ status: 'completed' | 'cancelled' | 'error';
49
+ kyc_id?: string;
50
+ message?: string;
51
+ sig?: string;
52
+ }) => {
53
+ const { return_url } = urlParams;
54
+
55
+ if (!return_url) {
56
+ console.warn('No return_url provided');
57
+ return;
58
+ }
59
+
60
+ // Basic URL validation - ensure it's a valid URL
61
+ try {
62
+ const returnUrl = new URL(return_url);
63
+
64
+ // Optional: Add domain allowlist validation here
65
+ // const allowedDomains = ['example.com', 'trusted-site.com'];
66
+ // if (!allowedDomains.some(domain => returnUrl.hostname.endsWith(domain))) {
67
+ // console.error('Return URL not in allowlist');
68
+ // return;
69
+ // }
70
+
71
+ // Build redirect URL with parameters
72
+ const redirectUrl = new URL(returnUrl);
73
+ redirectUrl.searchParams.set('status', params.status);
74
+
75
+ if (params.kyc_id) {
76
+ redirectUrl.searchParams.set('kyc_id', params.kyc_id);
77
+ }
78
+
79
+ if (params.message) {
80
+ redirectUrl.searchParams.set('message', params.message);
81
+ }
82
+
83
+ if (params.sig) {
84
+ redirectUrl.searchParams.set('sig', params.sig);
85
+ }
86
+
87
+ // Optional: Send postMessage to parent if in iframe
88
+ if (window.parent !== window) {
89
+ window.parent.postMessage({
90
+ type: 'kyc_result',
91
+ status: params.status,
92
+ kyc_id: params.kyc_id,
93
+ message: params.message,
94
+ }, '*');
95
+ }
96
+
97
+ // Redirect to return URL
98
+ window.location.href = redirectUrl.toString();
99
+ } catch (error) {
100
+ console.error('Invalid return URL:', error);
101
+ setError('Invalid return URL provided');
102
+ }
103
+ }, [urlParams]);
104
+
105
+ // Handle KYC completion
106
+ const handleComplete = useCallback((data: any) => {
107
+ console.log('KYC completed:', data);
108
+ redirectToReturnUrl({
109
+ status: 'completed',
110
+ kyc_id: data.session_id || urlParams.kyc_id,
111
+ message: 'KYC process completed successfully',
112
+ });
113
+ onComplete?.(data);
114
+ }, [redirectToReturnUrl, urlParams.kyc_id, onComplete]);
115
+
116
+ // Handle KYC error
117
+ const handleError = useCallback((error: string) => {
118
+ console.error('KYC error:', error);
119
+ redirectToReturnUrl({
120
+ status: 'error',
121
+ kyc_id: urlParams.kyc_id,
122
+ message: error,
123
+ });
124
+ onError?.(error);
125
+ }, [redirectToReturnUrl, urlParams.kyc_id, onError]);
126
+
127
+ // Handle KYC cancellation
128
+ const handleCancel = useCallback(() => {
129
+ console.log('KYC cancelled');
130
+ redirectToReturnUrl({
131
+ status: 'cancelled',
132
+ kyc_id: urlParams.kyc_id,
133
+ message: 'KYC process was cancelled',
134
+ });
135
+ onCancel?.();
136
+ }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
137
+
138
+ // Initialize component
139
+ useEffect(() => {
140
+ try {
141
+ const params = parseUrlParams();
142
+ setUrlParams(params);
143
+
144
+ // Set language if provided
145
+ if (params.lang) {
146
+ setLocale(params.lang);
147
+ }
148
+
149
+ setIsLoading(false);
150
+ } catch (error) {
151
+ console.error('Error parsing URL parameters:', error);
152
+ setError('Error parsing URL parameters');
153
+ setIsLoading(false);
154
+ }
155
+ }, [parseUrlParams, setLocale]);
156
+
157
+
158
+ if (isLoading) {
159
+ return (
160
+ <View style={styles.container}>
161
+ <Text style={styles.loadingText}>Loading KYC process...</Text>
162
+ </View>
163
+ );
164
+ }
165
+
166
+ if (error) {
167
+ return (
168
+ <View style={styles.container}>
169
+ <Text style={styles.errorText}>Error: {error}</Text>
170
+ </View>
171
+ );
172
+ }
173
+
174
+ if (!urlParams.token) {
175
+ return (
176
+ <View style={styles.container}>
177
+ <Text style={styles.errorText}>No token provided in URL parameters</Text>
178
+ </View>
179
+ );
180
+ }
181
+
182
+ return (
183
+ <SafeAreaView style={styles.container}>
184
+ <TemplateKYCExample
185
+ onComplete={handleComplete}
186
+ onCancel={handleCancel}
187
+ onError={handleError}
188
+ language={urlParams.lang || 'en'}
189
+ API_KEY={urlParams.token}
190
+ />
191
+ </SafeAreaView>
192
+ );
193
+ };
194
+
195
+ const styles = StyleSheet.create({
196
+ container: {
197
+ flex: 1,
198
+ backgroundColor: '#f5f5f5',
199
+ },
200
+ loadingText: {
201
+ fontSize: 18,
202
+ textAlign: 'center',
203
+ marginTop: 50,
204
+ color: '#666',
205
+ },
206
+ errorText: {
207
+ fontSize: 16,
208
+ textAlign: 'center',
209
+ marginTop: 50,
210
+ color: '#dc2626',
211
+ paddingHorizontal: 20,
212
+ },
213
+ });
214
+
215
+ export default WebKYCEntry;
@@ -0,0 +1 @@
1
+ export { default as WebKYCEntry } from './WebKYCEntry';
@@ -1,2 +0,0 @@
1
- /// <reference types="nativewind/types" />
2
-