@sanctum-key/react-native-sdk 1.0.61 → 1.0.62

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 (149) hide show
  1. package/README.md +34 -0
  2. package/android/build/.transforms/ac63f648699cdd4b91e6ee06476f2a70/results.bin +1 -0
  3. package/android/build/.transforms/ac63f648699cdd4b91e6ee06476f2a70/transformed/classes/classes_dex/classes.dex +0 -0
  4. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +9 -0
  5. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  6. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  7. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +45 -25
  8. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +9 -0
  9. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  10. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  11. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  12. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  13. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  14. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  15. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  16. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  17. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  18. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  19. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  20. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  21. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  22. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  23. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  24. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  25. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  26. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  27. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  28. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  29. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  30. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  31. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  32. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  33. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  34. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  35. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  36. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  54. package/android/build/outputs/logs/manifest-merger-debug-report.txt +34 -12
  55. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  56. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$BarcodeRegion.class +0 -0
  57. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$Companion.class +0 -0
  58. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$1$6$1.class → SanctumKeySdkModule$definition$1$7$1.class} +0 -0
  59. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$1$6$2.class → SanctumKeySdkModule$definition$1$7$2.class} +0 -0
  60. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$1.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$1.class} +0 -0
  61. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$5.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$2.class} +0 -0
  62. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$3.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$3.class} +0 -0
  63. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$4.class +0 -0
  64. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$2.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$5.class} +0 -0
  65. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$6.class +0 -0
  66. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$4.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$7.class} +0 -0
  67. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$8.class +0 -0
  68. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunction$6.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunction$9.class} +0 -0
  69. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$1.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$1.class} +0 -0
  70. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$2.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$2.class} +0 -0
  71. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$3.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$3.class} +0 -0
  72. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$4.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$4.class} +0 -0
  73. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$5.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$5.class} +0 -0
  74. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$6.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$6.class} +0 -0
  75. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$AsyncFunctionWithPromise$7.class → SanctumKeySdkModule$definition$lambda$24$$inlined$AsyncFunctionWithPromise$7.class} +0 -0
  76. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$$inlined$View$1.class → SanctumKeySdkModule$definition$lambda$24$$inlined$View$1.class} +0 -0
  77. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$lambda$15$$inlined$Prop$1.class → SanctumKeySdkModule$definition$lambda$24$lambda$23$$inlined$Prop$1.class} +0 -0
  78. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/{SanctumKeySdkModule$definition$lambda$16$lambda$15$$inlined$Prop$2.class → SanctumKeySdkModule$definition$lambda$24$lambda$23$$inlined$Prop$2.class} +0 -0
  79. package/android/build/tmp/kotlin-classes/debug/kyc/sanctumkey/com/SanctumKeySdkModule.class +0 -0
  80. package/android/src/main/AndroidManifest.xml +9 -0
  81. package/android/src/main/java/kyc/sanctumkey/com/SanctumKeySdkModule.kt +147 -0
  82. package/build/package.json +1 -1
  83. package/build/src/SanctumKeySdkModule.d.ts +2 -0
  84. package/build/src/SanctumKeySdkModule.d.ts.map +1 -1
  85. package/build/src/SanctumKeySdkModule.js.map +1 -1
  86. package/build/src/SanctumKeySdkModule.web.d.ts +2 -0
  87. package/build/src/SanctumKeySdkModule.web.d.ts.map +1 -1
  88. package/build/src/SanctumKeySdkModule.web.js +14 -0
  89. package/build/src/SanctumKeySdkModule.web.js.map +1 -1
  90. package/build/src/components/KYCElements/CountrySelection.d.ts.map +1 -1
  91. package/build/src/components/KYCElements/CountrySelection.js +1 -1
  92. package/build/src/components/KYCElements/CountrySelection.js.map +1 -1
  93. package/build/src/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  94. package/build/src/components/KYCElements/CountrySelectionTemplate.js +27 -17
  95. package/build/src/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  96. package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  97. package/build/src/components/KYCElements/IDCardCapture.js +46 -28
  98. package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
  99. package/build/src/components/OverLay/IdCard.d.ts +1 -1
  100. package/build/src/components/OverLay/IdCard.d.ts.map +1 -1
  101. package/build/src/components/OverLay/IdCard.js +47 -14
  102. package/build/src/components/OverLay/IdCard.js.map +1 -1
  103. package/build/src/components/OverLay/type.d.ts +2 -0
  104. package/build/src/components/OverLay/type.d.ts.map +1 -1
  105. package/build/src/components/OverLay/type.js.map +1 -1
  106. package/build/src/components/Svgs/scanningLine.d.ts +4 -1
  107. package/build/src/components/Svgs/scanningLine.d.ts.map +1 -1
  108. package/build/src/components/Svgs/scanningLine.js +15 -11
  109. package/build/src/components/Svgs/scanningLine.js.map +1 -1
  110. package/build/src/components/TemplateKYCExample.d.ts +4 -1
  111. package/build/src/components/TemplateKYCExample.d.ts.map +1 -1
  112. package/build/src/components/TemplateKYCExample.js +2 -2
  113. package/build/src/components/TemplateKYCExample.js.map +1 -1
  114. package/build/src/components/TemplateKYCFlowRefactored.d.ts +4 -2
  115. package/build/src/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  116. package/build/src/components/TemplateKYCFlowRefactored.js +157 -8
  117. package/build/src/components/TemplateKYCFlowRefactored.js.map +1 -1
  118. package/build/src/config/region_mapping.d.ts.map +1 -1
  119. package/build/src/config/region_mapping.js +12 -0
  120. package/build/src/config/region_mapping.js.map +1 -1
  121. package/build/src/config/region_mapping.json +12 -0
  122. package/build/src/index.d.ts +2 -0
  123. package/build/src/index.d.ts.map +1 -1
  124. package/build/src/index.js +2 -0
  125. package/build/src/index.js.map +1 -1
  126. package/build/src/security/deviceSecurity.d.ts +30 -0
  127. package/build/src/security/deviceSecurity.d.ts.map +1 -0
  128. package/build/src/security/deviceSecurity.js +55 -0
  129. package/build/src/security/deviceSecurity.js.map +1 -0
  130. package/build/src/utils/logger.d.ts.map +1 -1
  131. package/build/src/utils/logger.js +5 -0
  132. package/build/src/utils/logger.js.map +1 -1
  133. package/ios/SanctumKeySdkModule.swift +93 -0
  134. package/package.json +1 -1
  135. package/src/SanctumKeySdkModule.ts +2 -0
  136. package/src/SanctumKeySdkModule.web.ts +16 -0
  137. package/src/components/KYCElements/CountrySelection.tsx +3 -1
  138. package/src/components/KYCElements/CountrySelectionTemplate.tsx +73 -24
  139. package/src/components/KYCElements/IDCardCapture.tsx +53 -30
  140. package/src/components/OverLay/IdCard.tsx +72 -15
  141. package/src/components/OverLay/type.ts +4 -2
  142. package/src/components/Svgs/scanningLine.tsx +19 -12
  143. package/src/components/TemplateKYCExample.tsx +8 -1
  144. package/src/components/TemplateKYCFlowRefactored.tsx +202 -16
  145. package/src/config/region_mapping.json +12 -0
  146. package/src/config/region_mapping.ts +12 -0
  147. package/src/index.ts +9 -1
  148. package/src/security/deviceSecurity.ts +106 -0
  149. package/src/utils/logger.ts +5 -0
@@ -99,6 +99,23 @@ const isUsableBarcodeText = (value: unknown, allowShortBarcode: boolean): value
99
99
  return !isDecoderError && trimmed.length > 0 && (allowShortBarcode || value.length > 50);
100
100
  };
101
101
 
102
+ /**
103
+ * Keep barcode extraction payloads aligned with extract_mrz_text responses.
104
+ * The barcode formatter historically returned its decoded fields under
105
+ * `data`; downstream consumers expect all machine-readable document data
106
+ * under `parsed_data` regardless of whether it came from MRZ or a barcode.
107
+ */
108
+ const normalizeBarcodePayload = (payload: unknown): unknown => {
109
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return payload;
110
+
111
+ const record = payload as Record<string, unknown>;
112
+ if (Object.prototype.hasOwnProperty.call(record, 'parsed_data')) return record;
113
+ if (!Object.prototype.hasOwnProperty.call(record, 'data')) return record;
114
+
115
+ const { data, ...metadata } = record;
116
+ return { ...metadata, data: data };
117
+ };
118
+
102
119
  interface IDCardCaptureProps {
103
120
  component: TemplateComponent;
104
121
  value?: Record<string, IIDCardPayload>;
@@ -497,7 +514,26 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
497
514
  const isLandscape = screenWidth > screenHeight;
498
515
  let xMin, xMax, yMin, yMax;
499
516
 
500
- if (Platform.OS === 'web') {
517
+ if (scanPhase === 'barcode') {
518
+ // Keep the barcode target deliberately compact so users move close
519
+ // enough for dense PDF417 and linear bars to remain individually sharp.
520
+ // Pixel caps prevent the guide from becoming oversized on tablets.
521
+ const guideWidthPx = Math.min(
522
+ screenWidth * (isLandscape ? 0.68 : 0.82),
523
+ isLandscape ? 620 : 440,
524
+ );
525
+ const guideHeightPx = Math.min(
526
+ guideWidthPx / (isLandscape ? 4.2 : 3.2),
527
+ screenHeight * (isLandscape ? 0.34 : 0.12),
528
+ );
529
+ const guideWidthPercent = (guideWidthPx / screenWidth) * 100;
530
+ const guideHeightPercent = (guideHeightPx / screenHeight) * 100;
531
+
532
+ xMin = (100 - guideWidthPercent) / 2;
533
+ xMax = xMin + guideWidthPercent;
534
+ yMin = (100 - guideHeightPercent) / 2;
535
+ yMax = yMin + guideHeightPercent;
536
+ } else if (Platform.OS === 'web') {
501
537
  const boxWidthPercent = isLandscape ? 0.40 : 0.85;
502
538
  xMin = isLandscape ? 30 : 7.5;
503
539
  xMax = xMin + (boxWidthPercent * 100);
@@ -624,7 +660,13 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
624
660
 
625
661
  try {
626
662
  let imagePathForUpload = capturePath;
627
- const overlayBbox = cameraConfig.overlay.bbox;
663
+ // Barcode mode has a deliberately tighter visual guide, but this method
664
+ // saves the verified document image. If OBB bounds are unavailable, keep
665
+ // using the original full-card fallback rather than cropping to the
666
+ // barcode-only window.
667
+ const overlayBbox = scanPhaseRef.current === 'barcode'
668
+ ? { xMin: 5, yMin: 34, xMax: 95, yMax: 66 }
669
+ : cameraConfig.overlay.bbox;
628
670
 
629
671
  // Prefer the backend-detected card bounds. Front verification returns the
630
672
  // detect_face OBB-derived bbox; back verification returns extract_mrz's
@@ -705,7 +747,7 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
705
747
  setTimeout(() => {
706
748
  if (cameraGenerationRef.current !== captureGeneration) return;
707
749
  setShowCamera(false); actions.showCustomStepper(true);
708
- setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false }));
750
+ setSilentCaptureResult(prev => ({ ...prev, success: false, isAnalyzing: false, error: '' }));
709
751
  isProcessingCaptureRef.current = false;
710
752
  setIsProcessingCapture(false); setProcessingImagePath(null);
711
753
  scanPhaseRef.current = 'image';
@@ -780,10 +822,11 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
780
822
  let parsedDictionary;
781
823
 
782
824
  if (isHIC && barcodeString.length < 50) {
783
- parsedDictionary = { data: { card_number: barcodeString, barcode_type: "1D" } };
825
+ parsedDictionary = { parsed_data: { card_number: barcodeString, barcode_type: "1D" } };
784
826
  } else {
785
827
  const token = await authentification();
786
- parsedDictionary = await kycService.formatBarcodeData({ textInput: barcodeString, token }, env);
828
+ const formattedBarcode = await kycService.formatBarcodeData({ textInput: barcodeString, token }, env);
829
+ parsedDictionary = normalizeBarcodePayload(formattedBarcode);
787
830
  }
788
831
  if (isStaleBarcode()) return;
789
832
  if (!parsedDictionary) throw new Error("Could not parse the barcode data.");
@@ -1117,10 +1160,11 @@ const handleSilentCapture = async (
1117
1160
  if (isValidScan) {
1118
1161
  let parsedDictionary;
1119
1162
  if (isHIC && barcodeData.length < 50) {
1120
- parsedDictionary = { data: { card_number: barcodeData, barcode_type: "1D" } };
1163
+ parsedDictionary = { parsed_data: { card_number: barcodeData, barcode_type: "1D" } };
1121
1164
  } else {
1122
1165
  const token = await authentification();
1123
- parsedDictionary = await kycService.formatBarcodeData({ textInput: barcodeData, token }, env);
1166
+ const formattedBarcode = await kycService.formatBarcodeData({ textInput: barcodeData, token }, env);
1167
+ parsedDictionary = normalizeBarcodePayload(formattedBarcode);
1124
1168
  }
1125
1169
  if (isStaleFrame()) {
1126
1170
  clearTimeout(watchdog);
@@ -1327,7 +1371,8 @@ const handleSilentCapture = async (
1327
1371
  overlayComponent={
1328
1372
  <IdCardOverlay
1329
1373
  xMin={cameraConfig.overlay.bbox.xMin} yMin={cameraConfig.overlay.bbox.yMin} xMax={cameraConfig.overlay.bbox.xMax} yMax={cameraConfig.overlay.bbox.yMax}
1330
- instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number} isSuccess={silentCaptureResult.success || scanPhase === 'barcode'} language={state.currentLanguage}
1374
+ instructions={cameraConfig.overlay.guideText} cornerOpacity={cameraConfig.overlay.bbox.cornerRadius || 0 as number} isSuccess={silentCaptureResult.success} language={state.currentLanguage}
1375
+ mode={scanPhase === 'barcode' ? 'barcode' : 'document'}
1331
1376
  stepperProps={{
1332
1377
  back: () => {
1333
1378
  if (currentSide === 'back') {
@@ -1342,21 +1387,6 @@ const handleSilentCapture = async (
1342
1387
  />
1343
1388
  }
1344
1389
  />
1345
- {scanPhase === 'barcode' && !isBusy && (
1346
- <View style={styles.barcodePromptContainer}>
1347
- <View style={styles.barcodePromptContent}>
1348
- <View style={styles.barcodeIconContainer}><Text style={styles.barcodeIcon}>✓</Text></View>
1349
- <View style={styles.barcodeTextContainer}>
1350
- <Text style={styles.barcodePromptTitle}>{state.currentLanguage === 'en' ? 'Image Verified' : 'Image Vérifiée'}</Text>
1351
- <Text style={styles.barcodePromptDesc}>
1352
- {state.currentLanguage === 'en'
1353
- ? 'Proceed to scan the barcode. Move closer but ensure it is fully visible in the frame.'
1354
- : 'Procédez au scan du code-barres. Rapprochez-vous, mais assurez-vous qu\'il soit entièrement visible dans le cadre.'}
1355
- </Text>
1356
- </View>
1357
- </View>
1358
- </View>
1359
- )}
1360
1390
  {!isBusy && silentCaptureResult.isAnalyzing && (
1361
1391
  <View style={styles.topAnalyzingPillContainer}>
1362
1392
  <View style={styles.topAnalyzingPill}>
@@ -1622,13 +1652,6 @@ const styles = StyleSheet.create({
1622
1652
  qrCodeWrapper: { padding: 20, backgroundColor: '#FFFFFF', borderRadius: 20, borderWidth: 2, borderColor: '#E2E8F0', marginBottom: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.05, shadowRadius: 10 },
1623
1653
  listeningContainer: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#F0FDF4', paddingVertical: 12, paddingHorizontal: 20, borderRadius: 12, marginBottom: 24, borderWidth: 1, borderColor: '#BBF7D0' },
1624
1654
  listeningText: { marginLeft: 12, color: '#166534', fontSize: 14, fontWeight: '600' },
1625
- barcodePromptContainer: { position: 'absolute', top: Platform.OS === 'android' ? 60 : 75, left: 0, right: 0, alignItems: 'center', zIndex: 150, paddingHorizontal: 24, },
1626
- barcodePromptContent: { flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(15, 23, 42, 0.85)', paddingVertical: 14, paddingHorizontal: 20, borderRadius: 16, borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.15)', shadowColor: '#000', shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.3, shadowRadius: 12, elevation: 10, maxWidth: 400, ...Platform.select({ web: { backdropFilter: 'blur(8px)' } as any, ios: { backdropFilter: 'blur(8px)' } as any, }), },
1627
- barcodeIconContainer: { width: 36, height: 36, borderRadius: 18, backgroundColor: 'rgba(45, 189, 96, 0.2)', justifyContent: 'center', alignItems: 'center', marginRight: 14, borderWidth: 1, borderColor: 'rgba(45, 189, 96, 0.5)', },
1628
- barcodeIcon: { fontSize: 16, color: '#2DBD60', fontWeight: 'bold', },
1629
- barcodeTextContainer: { flex: 1, },
1630
- barcodePromptTitle: { color: '#2DBD60', fontSize: 16, fontWeight: '700', marginBottom: 4, },
1631
- barcodePromptDesc: { color: '#F8FAFC', fontSize: 14, fontWeight: '500', lineHeight: 20, },
1632
1655
  storeLinksContainer: { width: '100%', alignItems: 'center', marginBottom: 24, paddingTop: 16, borderTopWidth: 1, borderTopColor: '#E2E8F0' },
1633
1656
  storeLinksTitle: { fontSize: 14, color: '#64748B', fontWeight: '600', marginBottom: 12 },
1634
1657
  storeButtonsRow: { flexDirection: 'row', gap: 12, width: '100%', justifyContent: 'center' },
@@ -28,6 +28,7 @@ const IdCardOverlay = ({
28
28
  stepperProps,
29
29
  isSuccess,
30
30
  language = 'en',
31
+ mode = 'document',
31
32
  xMin: xMinPercent = 5,
32
33
  xMax: xMaxPercent = 95,
33
34
  yMin: yMinPercent = 34,
@@ -63,18 +64,29 @@ const IdCardOverlay = ({
63
64
 
64
65
  const docTypeFormatted = formatDocType(stepperProps?.selectedDocumentType);
65
66
  const sideText = getSideText(stepperProps?.side);
67
+ const isBarcodeMode = mode === 'barcode';
66
68
 
67
- const bottomTitle = language === 'en'
68
- ? `Position the ${sideText} of your ${docTypeFormatted}`
69
- : `Positionnez le ${sideText} de votre ${docTypeFormatted}`;
69
+ const bottomTitle = isBarcodeMode
70
+ ? (language === 'en' ? 'Center the barcode in the yellow guide' : 'Centrez le code-barres dans le guide jaune')
71
+ : (language === 'en'
72
+ ? `Position the ${sideText} of your ${docTypeFormatted}`
73
+ : `Positionnez le ${sideText} de votre ${docTypeFormatted}`);
70
74
 
71
- const bottomSubtitle = language === 'en'
72
- ? 'Ensure all details are clear and readable.'
73
- : 'Assurez-vous que tous les détails sont lisibles.';
75
+ const bottomSubtitle = isBarcodeMode
76
+ ? (language === 'en'
77
+ ? 'Move closer until it almost fills the guide. Keep both ends visible.'
78
+ : 'Rapprochez-vous jusqu’à presque remplir le guide. Gardez les deux extrémités visibles.')
79
+ : (language === 'en'
80
+ ? 'Ensure all details are clear and readable.'
81
+ : 'Assurez-vous que tous les détails sont lisibles.');
74
82
 
75
- const helperText = language === 'en'
76
- ? 'No glare • All corners visible • Hold steady'
77
- : 'Pas de reflets • Coins visibles • Maintenez stable';
83
+ const helperText = isBarcodeMode
84
+ ? (language === 'en'
85
+ ? 'Barcode only • Keep level • Hold steady'
86
+ : 'Code-barres uniquement • Bien droit • Restez stable')
87
+ : (language === 'en'
88
+ ? 'No glare • All corners visible • Hold steady'
89
+ : 'Pas de reflets • Coins visibles • Maintenez stable');
78
90
 
79
91
  // --- SVG Constants ---
80
92
  const CORNER_SIZE = 40;
@@ -117,8 +129,8 @@ const IdCardOverlay = ({
117
129
  />
118
130
  </Mask>
119
131
  <LinearGradient id="scanBorderGradient" x1="0%" y1="0%" x2="100%" y2="100%">
120
- <Stop offset="0%" stopColor="#4ADE80" />
121
- <Stop offset="100%" stopColor="#22C55E" />
132
+ <Stop offset="0%" stopColor={isBarcodeMode ? '#FDE047' : '#4ADE80'} />
133
+ <Stop offset="100%" stopColor={isBarcodeMode ? '#F59E0B' : '#22C55E'} />
122
134
  </LinearGradient>
123
135
  </Defs>
124
136
 
@@ -133,11 +145,26 @@ const IdCardOverlay = ({
133
145
  height={boxHeight}
134
146
  rx={BORDER_RADIUS}
135
147
  ry={BORDER_RADIUS}
136
- stroke={isSuccess ? '#2DBD60' : "rgba(255,255,255,0.25)"}
137
- strokeWidth={isSuccess ? 3 : 1.5}
148
+ stroke={isSuccess ? '#2DBD60' : (isBarcodeMode ? 'rgba(250, 204, 21, 0.8)' : 'rgba(255,255,255,0.25)')}
149
+ strokeWidth={isSuccess || isBarcodeMode ? 3 : 1.5}
138
150
  fill="transparent"
139
151
  />
140
152
 
153
+ {isBarcodeMode && (
154
+ <Rect
155
+ x={xMin + 8}
156
+ y={yMin + 8}
157
+ width={Math.max(0, boxWidth - 16)}
158
+ height={Math.max(0, boxHeight - 16)}
159
+ rx={Math.max(4, BORDER_RADIUS - 6)}
160
+ ry={Math.max(4, BORDER_RADIUS - 6)}
161
+ stroke="rgba(253, 224, 71, 0.45)"
162
+ strokeWidth={1}
163
+ strokeDasharray="8 7"
164
+ fill="transparent"
165
+ />
166
+ )}
167
+
141
168
  {/* Professional Corner Guides */}
142
169
  <AnimatedG opacity={cornerOpacity || 1}>
143
170
  {/* Top Left */}
@@ -177,7 +204,21 @@ const IdCardOverlay = ({
177
204
 
178
205
  {/* Scanning animation */}
179
206
  {!isSuccess && (
180
- <ScanningLine yMin={yMin} yMax={yMax} screenWidth={container.width} height={container.height} />
207
+ <ScanningLine
208
+ yMin={yMin}
209
+ yMax={yMax}
210
+ screenWidth={container.width}
211
+ height={container.height}
212
+ xMin={isBarcodeMode ? xMin : 0}
213
+ xMax={isBarcodeMode ? xMax : undefined}
214
+ color={isBarcodeMode ? '#FACC15' : '#22C55E'}
215
+ />
216
+ )}
217
+
218
+ {isBarcodeMode && (
219
+ <View style={[styles.barcodeFrameLabel, { left: xMin, top: Math.max(8, yMin - 34) }]} pointerEvents="none">
220
+ <Text style={styles.barcodeFrameLabelText}>{language === 'en' ? 'BARCODE TARGET' : 'ZONE CODE-BARRES'}</Text>
221
+ </View>
181
222
  )}
182
223
 
183
224
  {/* Top UI Zone */}
@@ -287,4 +328,20 @@ const styles = StyleSheet.create({
287
328
  fontSize: 12,
288
329
  fontWeight: '500',
289
330
  },
290
- });
331
+ barcodeFrameLabel: {
332
+ position: 'absolute',
333
+ zIndex: 12,
334
+ backgroundColor: 'rgba(15, 23, 42, 0.82)',
335
+ borderWidth: 1,
336
+ borderColor: 'rgba(250, 204, 21, 0.55)',
337
+ borderRadius: 6,
338
+ paddingHorizontal: 8,
339
+ paddingVertical: 4,
340
+ },
341
+ barcodeFrameLabelText: {
342
+ color: '#FDE047',
343
+ fontSize: 10,
344
+ fontWeight: '800',
345
+ letterSpacing: 1.2,
346
+ },
347
+ });
@@ -15,7 +15,9 @@ export interface IdCardOverlayProps {
15
15
  orientation?: 'center' | 'left' | 'right';
16
16
  isAnalyzing?: boolean;
17
17
  isSuccess?: boolean;
18
- language: string
18
+ language: string;
19
+ /** Changes the guide geometry and copy for the dedicated barcode phase. */
20
+ mode?: 'document' | 'barcode';
19
21
  }
20
22
 
21
23
 
@@ -93,4 +95,4 @@ export interface EnhancedCameraViewProps {
93
95
  export interface CheckTemplateTypeResponse {
94
96
  template_path: string;
95
97
  lpips_score: number;
96
- }
98
+ }
@@ -7,12 +7,18 @@ interface ScanningLineProps {
7
7
  yMax: number;
8
8
  screenWidth: number;
9
9
  height: number;
10
+ xMin?: number;
11
+ xMax?: number;
12
+ color?: string;
10
13
  }
11
14
 
12
- const ScanningLine = ({ yMin, yMax, screenWidth, height }: ScanningLineProps): React.ReactElement => {
15
+ const ScanningLine = ({ yMin, yMax, screenWidth, height, xMin = 0, xMax, color = '#22C55E' }: ScanningLineProps): React.ReactElement => {
13
16
  const animatedValue = useRef(new Animated.Value(0)).current;
14
17
 
15
18
  const boxHeight = yMax - yMin;
19
+ const lineWidth = Math.max(0, (xMax ?? screenWidth) - xMin);
20
+ const glowHeight = Math.min(40, Math.max(12, boxHeight * 0.3));
21
+ const scanEnd = Math.max(yMin, yMax - glowHeight - 4);
16
22
 
17
23
  useEffect(() => {
18
24
  const startAnimation = () => {
@@ -36,7 +42,7 @@ const ScanningLine = ({ yMin, yMax, screenWidth, height }: ScanningLineProps): R
36
42
 
37
43
  const translateY = animatedValue.interpolate({
38
44
  inputRange: [0, 0.5, 1],
39
- outputRange: [yMin, yMax, yMin],
45
+ outputRange: [yMin, scanEnd, yMin],
40
46
  });
41
47
 
42
48
  return (
@@ -44,32 +50,33 @@ const ScanningLine = ({ yMin, yMax, screenWidth, height }: ScanningLineProps): R
44
50
  style={[
45
51
  styles.container,
46
52
  {
47
- width: screenWidth,
53
+ left: xMin,
54
+ width: lineWidth,
48
55
  height: height,
49
56
  transform: [{ translateY }],
50
57
  },
51
58
  ]}
52
59
  pointerEvents="none"
53
60
  >
54
- <Svg height="4" width={screenWidth}>
61
+ <Svg height="4" width={lineWidth}>
55
62
  <Defs>
56
63
  <LinearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">
57
64
  <Stop offset="0%" stopColor="transparent" stopOpacity="0" />
58
- <Stop offset="50%" stopColor="#22C55E" stopOpacity="1" />
65
+ <Stop offset="50%" stopColor={color} stopOpacity="1" />
59
66
  <Stop offset="100%" stopColor="transparent" stopOpacity="0" />
60
67
  </LinearGradient>
61
68
  </Defs>
62
- <Rect x="0" y="0" width={screenWidth} height="4" fill="url(#grad)" />
69
+ <Rect x="0" y="0" width={lineWidth} height="4" fill="url(#grad)" />
63
70
  </Svg>
64
71
 
65
- <Svg height="40" width={screenWidth} style={{ marginTop: -2 }}>
72
+ <Svg height={glowHeight} width={lineWidth} style={{ marginTop: -2 }}>
66
73
  <Defs>
67
74
  <LinearGradient id="glow" x1="0%" y1="0%" x2="0%" y2="100%">
68
- <Stop offset="0%" stopColor="#22C55E" stopOpacity="0.4" />
69
- <Stop offset="100%" stopColor="#22C55E" stopOpacity="0" />
75
+ <Stop offset="0%" stopColor={color} stopOpacity="0.4" />
76
+ <Stop offset="100%" stopColor={color} stopOpacity="0" />
70
77
  </LinearGradient>
71
- </Defs>
72
- <Rect x="0" y="0" width={screenWidth} height="40" fill="url(#glow)" />
78
+ </Defs>
79
+ <Rect x="0" y="0" width={lineWidth} height={glowHeight} fill="url(#glow)" />
73
80
  </Svg>
74
81
  </Animated.View>
75
82
  );
@@ -84,4 +91,4 @@ const styles = StyleSheet.create({
84
91
  },
85
92
  });
86
93
 
87
- export default ScanningLine;
94
+ export default ScanningLine;
@@ -4,6 +4,7 @@ import { TemplateKYCFlow } from './TemplateKYCFlowRefactored';
4
4
  import { KYCTemplate, VerificationState } from '../types/KYC.types';
5
5
  import { KycEnvironment, BackendEnvironment } from '../types/env.types';
6
6
  import { sdkLogger } from '../utils/logger'; // 🚨 IMPORT SDK LOGGER
7
+ import type { DeviceSecurityCheckResult, DeviceSecurityPolicy } from '../security/deviceSecurity';
7
8
 
8
9
  const advancedVerificationTemplate: KYCTemplate = {
9
10
  id: 1,
@@ -60,6 +61,8 @@ export interface TemplateKYCExampleProps {
60
61
  onSessionSave?: (sessionId: string) => void;
61
62
  kyc_session_id?: string;
62
63
  templateConfig?: Record<string, string>;
64
+ deviceSecurityPolicy?: DeviceSecurityPolicy;
65
+ onDeviceSecurityCheck?: (result: DeviceSecurityCheckResult) => void;
63
66
  }
64
67
 
65
68
  export function TemplateKYCExample({
@@ -80,6 +83,8 @@ export function TemplateKYCExample({
80
83
  onSessionSave,
81
84
  kyc_session_id,
82
85
  templateConfig,
86
+ deviceSecurityPolicy,
87
+ onDeviceSecurityCheck,
83
88
  }: TemplateKYCExampleProps): JSX.Element {
84
89
 
85
90
  const handleComplete = (data: VerificationState) => {
@@ -167,8 +172,10 @@ export function TemplateKYCExample({
167
172
  referenceId={referenceId}
168
173
  onSessionSave={onSessionSave}
169
174
  kyc_session_id={kyc_session_id}
175
+ deviceSecurityPolicy={deviceSecurityPolicy}
176
+ onDeviceSecurityCheck={onDeviceSecurityCheck}
170
177
  />
171
178
  </View>
172
179
  </SafeAreaView>
173
180
  );
174
- }
181
+ }