@velion-la/onboarding-sdk-react-native 1.0.0-beta.2

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 (557) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE +12 -0
  3. package/README.md +803 -0
  4. package/lib/commonjs/camera/AddressSearchBar.js +304 -0
  5. package/lib/commonjs/camera/AddressSearchBar.js.map +1 -0
  6. package/lib/commonjs/camera/DocumentCapture.js +505 -0
  7. package/lib/commonjs/camera/DocumentCapture.js.map +1 -0
  8. package/lib/commonjs/camera/LivenessCamera.js +534 -0
  9. package/lib/commonjs/camera/LivenessCamera.js.map +1 -0
  10. package/lib/commonjs/camera/MapAddressPicker.js +341 -0
  11. package/lib/commonjs/camera/MapAddressPicker.js.map +1 -0
  12. package/lib/commonjs/core/VelionOnboarding.js +815 -0
  13. package/lib/commonjs/core/VelionOnboarding.js.map +1 -0
  14. package/lib/commonjs/core/sessionDeclinedCopy.js +56 -0
  15. package/lib/commonjs/core/sessionDeclinedCopy.js.map +1 -0
  16. package/lib/commonjs/core/sessionStateMapper.js +137 -0
  17. package/lib/commonjs/core/sessionStateMapper.js.map +1 -0
  18. package/lib/commonjs/core/sseReasonMessages.js +450 -0
  19. package/lib/commonjs/core/sseReasonMessages.js.map +1 -0
  20. package/lib/commonjs/data/iso3166Alpha2Codes.json +1 -0
  21. package/lib/commonjs/data/iso3166CountryNames.json +251 -0
  22. package/lib/commonjs/i18n/index.js +30 -0
  23. package/lib/commonjs/i18n/index.js.map +1 -0
  24. package/lib/commonjs/i18n/strings/en.js +261 -0
  25. package/lib/commonjs/i18n/strings/en.js.map +1 -0
  26. package/lib/commonjs/i18n/strings/es.js +266 -0
  27. package/lib/commonjs/i18n/strings/es.js.map +1 -0
  28. package/lib/commonjs/index.js +213 -0
  29. package/lib/commonjs/index.js.map +1 -0
  30. package/lib/commonjs/package.json +1 -0
  31. package/lib/commonjs/steps/AddressInfoStep.js +650 -0
  32. package/lib/commonjs/steps/AddressInfoStep.js.map +1 -0
  33. package/lib/commonjs/steps/DocumentsOcrStep.js +397 -0
  34. package/lib/commonjs/steps/DocumentsOcrStep.js.map +1 -0
  35. package/lib/commonjs/steps/EmailContactStep.js +145 -0
  36. package/lib/commonjs/steps/EmailContactStep.js.map +1 -0
  37. package/lib/commonjs/steps/EmailOtpStep.js +220 -0
  38. package/lib/commonjs/steps/EmailOtpStep.js.map +1 -0
  39. package/lib/commonjs/steps/FaceMatchStep.js +166 -0
  40. package/lib/commonjs/steps/FaceMatchStep.js.map +1 -0
  41. package/lib/commonjs/steps/FingerprintStep.js +92 -0
  42. package/lib/commonjs/steps/FingerprintStep.js.map +1 -0
  43. package/lib/commonjs/steps/HumanBasicInfoStep.js +243 -0
  44. package/lib/commonjs/steps/HumanBasicInfoStep.js.map +1 -0
  45. package/lib/commonjs/steps/HumanExtendedInfoStep.js +268 -0
  46. package/lib/commonjs/steps/HumanExtendedInfoStep.js.map +1 -0
  47. package/lib/commonjs/steps/LegalBasicInfoStep.js +188 -0
  48. package/lib/commonjs/steps/LegalBasicInfoStep.js.map +1 -0
  49. package/lib/commonjs/steps/LegalExtendedInfoStep.js +166 -0
  50. package/lib/commonjs/steps/LegalExtendedInfoStep.js.map +1 -0
  51. package/lib/commonjs/steps/LivenessMatchStep.js +707 -0
  52. package/lib/commonjs/steps/LivenessMatchStep.js.map +1 -0
  53. package/lib/commonjs/steps/PhoneContactStep.js +146 -0
  54. package/lib/commonjs/steps/PhoneContactStep.js.map +1 -0
  55. package/lib/commonjs/steps/PhoneOtpStep.js +219 -0
  56. package/lib/commonjs/steps/PhoneOtpStep.js.map +1 -0
  57. package/lib/commonjs/steps/SwornDeclarationStep.js +196 -0
  58. package/lib/commonjs/steps/SwornDeclarationStep.js.map +1 -0
  59. package/lib/commonjs/steps/TaxInfoStep.js +244 -0
  60. package/lib/commonjs/steps/TaxInfoStep.js.map +1 -0
  61. package/lib/commonjs/steps/TermsAndConditionsStep.js +238 -0
  62. package/lib/commonjs/steps/TermsAndConditionsStep.js.map +1 -0
  63. package/lib/commonjs/steps/_shared.js +40 -0
  64. package/lib/commonjs/steps/_shared.js.map +1 -0
  65. package/lib/commonjs/steps/types.js +6 -0
  66. package/lib/commonjs/steps/types.js.map +1 -0
  67. package/lib/commonjs/transport/api.js +176 -0
  68. package/lib/commonjs/transport/api.js.map +1 -0
  69. package/lib/commonjs/transport/irisWebSocket.js +121 -0
  70. package/lib/commonjs/transport/irisWebSocket.js.map +1 -0
  71. package/lib/commonjs/transport/secureUrl.js +50 -0
  72. package/lib/commonjs/transport/secureUrl.js.map +1 -0
  73. package/lib/commonjs/transport/sse.js +248 -0
  74. package/lib/commonjs/transport/sse.js.map +1 -0
  75. package/lib/commonjs/types/index.js +391 -0
  76. package/lib/commonjs/types/index.js.map +1 -0
  77. package/lib/commonjs/ui/MapFallbackBoundary.js +42 -0
  78. package/lib/commonjs/ui/MapFallbackBoundary.js.map +1 -0
  79. package/lib/commonjs/ui/StepShell.js +118 -0
  80. package/lib/commonjs/ui/StepShell.js.map +1 -0
  81. package/lib/commonjs/ui/VelionOnboardingScreen.js +217 -0
  82. package/lib/commonjs/ui/VelionOnboardingScreen.js.map +1 -0
  83. package/lib/commonjs/ui/forms/index.js +38 -0
  84. package/lib/commonjs/ui/forms/index.js.map +1 -0
  85. package/lib/commonjs/ui/forms/useInlineValidation.js +88 -0
  86. package/lib/commonjs/ui/forms/useInlineValidation.js.map +1 -0
  87. package/lib/commonjs/ui/forms/validators.js +34 -0
  88. package/lib/commonjs/ui/forms/validators.js.map +1 -0
  89. package/lib/commonjs/ui/icons/HomeHeartIcon.js +38 -0
  90. package/lib/commonjs/ui/icons/HomeHeartIcon.js.map +1 -0
  91. package/lib/commonjs/ui/icons/StepIcon.js +59 -0
  92. package/lib/commonjs/ui/icons/StepIcon.js.map +1 -0
  93. package/lib/commonjs/ui/overlays/AnalyzingOverlay.js +284 -0
  94. package/lib/commonjs/ui/overlays/AnalyzingOverlay.js.map +1 -0
  95. package/lib/commonjs/ui/overlays/LoadingOverlay.js +108 -0
  96. package/lib/commonjs/ui/overlays/LoadingOverlay.js.map +1 -0
  97. package/lib/commonjs/ui/overlays/ProgressBar.js +95 -0
  98. package/lib/commonjs/ui/overlays/ProgressBar.js.map +1 -0
  99. package/lib/commonjs/ui/overlays/RetryDialog.js +125 -0
  100. package/lib/commonjs/ui/overlays/RetryDialog.js.map +1 -0
  101. package/lib/commonjs/ui/overlays/index.js +33 -0
  102. package/lib/commonjs/ui/overlays/index.js.map +1 -0
  103. package/lib/commonjs/ui/primitives/Banner.js +81 -0
  104. package/lib/commonjs/ui/primitives/Banner.js.map +1 -0
  105. package/lib/commonjs/ui/primitives/Button.js +142 -0
  106. package/lib/commonjs/ui/primitives/Button.js.map +1 -0
  107. package/lib/commonjs/ui/primitives/Card.js +50 -0
  108. package/lib/commonjs/ui/primitives/Card.js.map +1 -0
  109. package/lib/commonjs/ui/primitives/Checkbox.js +139 -0
  110. package/lib/commonjs/ui/primitives/Checkbox.js.map +1 -0
  111. package/lib/commonjs/ui/primitives/CountrySelect.js +288 -0
  112. package/lib/commonjs/ui/primitives/CountrySelect.js.map +1 -0
  113. package/lib/commonjs/ui/primitives/DatePicker.js +245 -0
  114. package/lib/commonjs/ui/primitives/DatePicker.js.map +1 -0
  115. package/lib/commonjs/ui/primitives/Input.js +101 -0
  116. package/lib/commonjs/ui/primitives/Input.js.map +1 -0
  117. package/lib/commonjs/ui/primitives/Select.js +209 -0
  118. package/lib/commonjs/ui/primitives/Select.js.map +1 -0
  119. package/lib/commonjs/ui/primitives/Spinner.js +25 -0
  120. package/lib/commonjs/ui/primitives/Spinner.js.map +1 -0
  121. package/lib/commonjs/ui/primitives/index.js +69 -0
  122. package/lib/commonjs/ui/primitives/index.js.map +1 -0
  123. package/lib/commonjs/ui/theme/ThemeProvider.js +74 -0
  124. package/lib/commonjs/ui/theme/ThemeProvider.js.map +1 -0
  125. package/lib/commonjs/ui/theme/index.js +68 -0
  126. package/lib/commonjs/ui/theme/index.js.map +1 -0
  127. package/lib/commonjs/ui/theme/tokens.js +154 -0
  128. package/lib/commonjs/ui/theme/tokens.js.map +1 -0
  129. package/lib/commonjs/utils/EventEmitter.js +144 -0
  130. package/lib/commonjs/utils/EventEmitter.js.map +1 -0
  131. package/lib/commonjs/utils/base64.js +53 -0
  132. package/lib/commonjs/utils/base64.js.map +1 -0
  133. package/lib/commonjs/utils/deviceFingerprint.js +132 -0
  134. package/lib/commonjs/utils/deviceFingerprint.js.map +1 -0
  135. package/lib/commonjs/utils/documentTypeOptions.js +35 -0
  136. package/lib/commonjs/utils/documentTypeOptions.js.map +1 -0
  137. package/lib/commonjs/utils/googleMapsPreflight.js +77 -0
  138. package/lib/commonjs/utils/googleMapsPreflight.js.map +1 -0
  139. package/lib/commonjs/utils/hmac.js +58 -0
  140. package/lib/commonjs/utils/hmac.js.map +1 -0
  141. package/lib/commonjs/utils/iso3166Countries.js +98 -0
  142. package/lib/commonjs/utils/iso3166Countries.js.map +1 -0
  143. package/lib/commonjs/utils/jpegFromUri.js +44 -0
  144. package/lib/commonjs/utils/jpegFromUri.js.map +1 -0
  145. package/lib/commonjs/utils/keepAwake.js +58 -0
  146. package/lib/commonjs/utils/keepAwake.js.map +1 -0
  147. package/lib/commonjs/utils/log.js +42 -0
  148. package/lib/commonjs/utils/log.js.map +1 -0
  149. package/lib/commonjs/utils/osGeocoder.js +70 -0
  150. package/lib/commonjs/utils/osGeocoder.js.map +1 -0
  151. package/lib/commonjs/utils/parseGoogleAddressComponents.js +74 -0
  152. package/lib/commonjs/utils/parseGoogleAddressComponents.js.map +1 -0
  153. package/lib/commonjs/utils/personNameNormalize.js +24 -0
  154. package/lib/commonjs/utils/personNameNormalize.js.map +1 -0
  155. package/lib/commonjs/utils/sdkError.js +34 -0
  156. package/lib/commonjs/utils/sdkError.js.map +1 -0
  157. package/lib/commonjs/utils/sdkVersion.js +13 -0
  158. package/lib/commonjs/utils/sdkVersion.js.map +1 -0
  159. package/lib/commonjs/utils/stepConfig.js +65 -0
  160. package/lib/commonjs/utils/stepConfig.js.map +1 -0
  161. package/lib/commonjs/utils/taxInfoConfig.js +19 -0
  162. package/lib/commonjs/utils/taxInfoConfig.js.map +1 -0
  163. package/lib/module/camera/AddressSearchBar.js +299 -0
  164. package/lib/module/camera/AddressSearchBar.js.map +1 -0
  165. package/lib/module/camera/DocumentCapture.js +500 -0
  166. package/lib/module/camera/DocumentCapture.js.map +1 -0
  167. package/lib/module/camera/LivenessCamera.js +529 -0
  168. package/lib/module/camera/LivenessCamera.js.map +1 -0
  169. package/lib/module/camera/MapAddressPicker.js +337 -0
  170. package/lib/module/camera/MapAddressPicker.js.map +1 -0
  171. package/lib/module/core/VelionOnboarding.js +811 -0
  172. package/lib/module/core/VelionOnboarding.js.map +1 -0
  173. package/lib/module/core/sessionDeclinedCopy.js +52 -0
  174. package/lib/module/core/sessionDeclinedCopy.js.map +1 -0
  175. package/lib/module/core/sessionStateMapper.js +128 -0
  176. package/lib/module/core/sessionStateMapper.js.map +1 -0
  177. package/lib/module/core/sseReasonMessages.js +446 -0
  178. package/lib/module/core/sseReasonMessages.js.map +1 -0
  179. package/lib/module/data/iso3166Alpha2Codes.json +1 -0
  180. package/lib/module/data/iso3166CountryNames.json +251 -0
  181. package/lib/module/i18n/index.js +25 -0
  182. package/lib/module/i18n/index.js.map +1 -0
  183. package/lib/module/i18n/strings/en.js +257 -0
  184. package/lib/module/i18n/strings/en.js.map +1 -0
  185. package/lib/module/i18n/strings/es.js +262 -0
  186. package/lib/module/i18n/strings/es.js.map +1 -0
  187. package/lib/module/index.js +36 -0
  188. package/lib/module/index.js.map +1 -0
  189. package/lib/module/steps/AddressInfoStep.js +646 -0
  190. package/lib/module/steps/AddressInfoStep.js.map +1 -0
  191. package/lib/module/steps/DocumentsOcrStep.js +391 -0
  192. package/lib/module/steps/DocumentsOcrStep.js.map +1 -0
  193. package/lib/module/steps/EmailContactStep.js +140 -0
  194. package/lib/module/steps/EmailContactStep.js.map +1 -0
  195. package/lib/module/steps/EmailOtpStep.js +215 -0
  196. package/lib/module/steps/EmailOtpStep.js.map +1 -0
  197. package/lib/module/steps/FaceMatchStep.js +161 -0
  198. package/lib/module/steps/FaceMatchStep.js.map +1 -0
  199. package/lib/module/steps/FingerprintStep.js +87 -0
  200. package/lib/module/steps/FingerprintStep.js.map +1 -0
  201. package/lib/module/steps/HumanBasicInfoStep.js +238 -0
  202. package/lib/module/steps/HumanBasicInfoStep.js.map +1 -0
  203. package/lib/module/steps/HumanExtendedInfoStep.js +263 -0
  204. package/lib/module/steps/HumanExtendedInfoStep.js.map +1 -0
  205. package/lib/module/steps/LegalBasicInfoStep.js +183 -0
  206. package/lib/module/steps/LegalBasicInfoStep.js.map +1 -0
  207. package/lib/module/steps/LegalExtendedInfoStep.js +161 -0
  208. package/lib/module/steps/LegalExtendedInfoStep.js.map +1 -0
  209. package/lib/module/steps/LivenessMatchStep.js +701 -0
  210. package/lib/module/steps/LivenessMatchStep.js.map +1 -0
  211. package/lib/module/steps/PhoneContactStep.js +141 -0
  212. package/lib/module/steps/PhoneContactStep.js.map +1 -0
  213. package/lib/module/steps/PhoneOtpStep.js +214 -0
  214. package/lib/module/steps/PhoneOtpStep.js.map +1 -0
  215. package/lib/module/steps/SwornDeclarationStep.js +191 -0
  216. package/lib/module/steps/SwornDeclarationStep.js.map +1 -0
  217. package/lib/module/steps/TaxInfoStep.js +239 -0
  218. package/lib/module/steps/TaxInfoStep.js.map +1 -0
  219. package/lib/module/steps/TermsAndConditionsStep.js +233 -0
  220. package/lib/module/steps/TermsAndConditionsStep.js.map +1 -0
  221. package/lib/module/steps/_shared.js +33 -0
  222. package/lib/module/steps/_shared.js.map +1 -0
  223. package/lib/module/steps/types.js +4 -0
  224. package/lib/module/steps/types.js.map +1 -0
  225. package/lib/module/transport/api.js +173 -0
  226. package/lib/module/transport/api.js.map +1 -0
  227. package/lib/module/transport/irisWebSocket.js +115 -0
  228. package/lib/module/transport/irisWebSocket.js.map +1 -0
  229. package/lib/module/transport/secureUrl.js +45 -0
  230. package/lib/module/transport/secureUrl.js.map +1 -0
  231. package/lib/module/transport/sse.js +242 -0
  232. package/lib/module/transport/sse.js.map +1 -0
  233. package/lib/module/types/index.js +457 -0
  234. package/lib/module/types/index.js.map +1 -0
  235. package/lib/module/ui/MapFallbackBoundary.js +37 -0
  236. package/lib/module/ui/MapFallbackBoundary.js.map +1 -0
  237. package/lib/module/ui/StepShell.js +114 -0
  238. package/lib/module/ui/StepShell.js.map +1 -0
  239. package/lib/module/ui/VelionOnboardingScreen.js +212 -0
  240. package/lib/module/ui/VelionOnboardingScreen.js.map +1 -0
  241. package/lib/module/ui/forms/index.js +5 -0
  242. package/lib/module/ui/forms/index.js.map +1 -0
  243. package/lib/module/ui/forms/useInlineValidation.js +84 -0
  244. package/lib/module/ui/forms/useInlineValidation.js.map +1 -0
  245. package/lib/module/ui/forms/validators.js +27 -0
  246. package/lib/module/ui/forms/validators.js.map +1 -0
  247. package/lib/module/ui/icons/HomeHeartIcon.js +33 -0
  248. package/lib/module/ui/icons/HomeHeartIcon.js.map +1 -0
  249. package/lib/module/ui/icons/StepIcon.js +55 -0
  250. package/lib/module/ui/icons/StepIcon.js.map +1 -0
  251. package/lib/module/ui/overlays/AnalyzingOverlay.js +279 -0
  252. package/lib/module/ui/overlays/AnalyzingOverlay.js.map +1 -0
  253. package/lib/module/ui/overlays/LoadingOverlay.js +104 -0
  254. package/lib/module/ui/overlays/LoadingOverlay.js.map +1 -0
  255. package/lib/module/ui/overlays/ProgressBar.js +90 -0
  256. package/lib/module/ui/overlays/ProgressBar.js.map +1 -0
  257. package/lib/module/ui/overlays/RetryDialog.js +121 -0
  258. package/lib/module/ui/overlays/RetryDialog.js.map +1 -0
  259. package/lib/module/ui/overlays/index.js +6 -0
  260. package/lib/module/ui/overlays/index.js.map +1 -0
  261. package/lib/module/ui/primitives/Banner.js +77 -0
  262. package/lib/module/ui/primitives/Banner.js.map +1 -0
  263. package/lib/module/ui/primitives/Button.js +138 -0
  264. package/lib/module/ui/primitives/Button.js.map +1 -0
  265. package/lib/module/ui/primitives/Card.js +46 -0
  266. package/lib/module/ui/primitives/Card.js.map +1 -0
  267. package/lib/module/ui/primitives/Checkbox.js +136 -0
  268. package/lib/module/ui/primitives/Checkbox.js.map +1 -0
  269. package/lib/module/ui/primitives/CountrySelect.js +284 -0
  270. package/lib/module/ui/primitives/CountrySelect.js.map +1 -0
  271. package/lib/module/ui/primitives/DatePicker.js +241 -0
  272. package/lib/module/ui/primitives/DatePicker.js.map +1 -0
  273. package/lib/module/ui/primitives/Input.js +97 -0
  274. package/lib/module/ui/primitives/Input.js.map +1 -0
  275. package/lib/module/ui/primitives/Select.js +205 -0
  276. package/lib/module/ui/primitives/Select.js.map +1 -0
  277. package/lib/module/ui/primitives/Spinner.js +21 -0
  278. package/lib/module/ui/primitives/Spinner.js.map +1 -0
  279. package/lib/module/ui/primitives/index.js +12 -0
  280. package/lib/module/ui/primitives/index.js.map +1 -0
  281. package/lib/module/ui/theme/ThemeProvider.js +67 -0
  282. package/lib/module/ui/theme/ThemeProvider.js.map +1 -0
  283. package/lib/module/ui/theme/index.js +5 -0
  284. package/lib/module/ui/theme/index.js.map +1 -0
  285. package/lib/module/ui/theme/tokens.js +145 -0
  286. package/lib/module/ui/theme/tokens.js.map +1 -0
  287. package/lib/module/utils/EventEmitter.js +139 -0
  288. package/lib/module/utils/EventEmitter.js.map +1 -0
  289. package/lib/module/utils/base64.js +47 -0
  290. package/lib/module/utils/base64.js.map +1 -0
  291. package/lib/module/utils/deviceFingerprint.js +129 -0
  292. package/lib/module/utils/deviceFingerprint.js.map +1 -0
  293. package/lib/module/utils/documentTypeOptions.js +31 -0
  294. package/lib/module/utils/documentTypeOptions.js.map +1 -0
  295. package/lib/module/utils/googleMapsPreflight.js +73 -0
  296. package/lib/module/utils/googleMapsPreflight.js.map +1 -0
  297. package/lib/module/utils/hmac.js +53 -0
  298. package/lib/module/utils/hmac.js.map +1 -0
  299. package/lib/module/utils/iso3166Countries.js +92 -0
  300. package/lib/module/utils/iso3166Countries.js.map +1 -0
  301. package/lib/module/utils/jpegFromUri.js +40 -0
  302. package/lib/module/utils/jpegFromUri.js.map +1 -0
  303. package/lib/module/utils/keepAwake.js +53 -0
  304. package/lib/module/utils/keepAwake.js.map +1 -0
  305. package/lib/module/utils/log.js +37 -0
  306. package/lib/module/utils/log.js.map +1 -0
  307. package/lib/module/utils/osGeocoder.js +65 -0
  308. package/lib/module/utils/osGeocoder.js.map +1 -0
  309. package/lib/module/utils/parseGoogleAddressComponents.js +69 -0
  310. package/lib/module/utils/parseGoogleAddressComponents.js.map +1 -0
  311. package/lib/module/utils/personNameNormalize.js +20 -0
  312. package/lib/module/utils/personNameNormalize.js.map +1 -0
  313. package/lib/module/utils/sdkError.js +29 -0
  314. package/lib/module/utils/sdkError.js.map +1 -0
  315. package/lib/module/utils/sdkVersion.js +9 -0
  316. package/lib/module/utils/sdkVersion.js.map +1 -0
  317. package/lib/module/utils/stepConfig.js +59 -0
  318. package/lib/module/utils/stepConfig.js.map +1 -0
  319. package/lib/module/utils/taxInfoConfig.js +15 -0
  320. package/lib/module/utils/taxInfoConfig.js.map +1 -0
  321. package/lib/typescript/camera/AddressSearchBar.d.ts +37 -0
  322. package/lib/typescript/camera/AddressSearchBar.d.ts.map +1 -0
  323. package/lib/typescript/camera/DocumentCapture.d.ts +34 -0
  324. package/lib/typescript/camera/DocumentCapture.d.ts.map +1 -0
  325. package/lib/typescript/camera/LivenessCamera.d.ts +50 -0
  326. package/lib/typescript/camera/LivenessCamera.d.ts.map +1 -0
  327. package/lib/typescript/camera/MapAddressPicker.d.ts +57 -0
  328. package/lib/typescript/camera/MapAddressPicker.d.ts.map +1 -0
  329. package/lib/typescript/core/VelionOnboarding.d.ts +115 -0
  330. package/lib/typescript/core/VelionOnboarding.d.ts.map +1 -0
  331. package/lib/typescript/core/sessionDeclinedCopy.d.ts +16 -0
  332. package/lib/typescript/core/sessionDeclinedCopy.d.ts.map +1 -0
  333. package/lib/typescript/core/sessionStateMapper.d.ts +33 -0
  334. package/lib/typescript/core/sessionStateMapper.d.ts.map +1 -0
  335. package/lib/typescript/core/sseReasonMessages.d.ts +20 -0
  336. package/lib/typescript/core/sseReasonMessages.d.ts.map +1 -0
  337. package/lib/typescript/i18n/index.d.ts +13 -0
  338. package/lib/typescript/i18n/index.d.ts.map +1 -0
  339. package/lib/typescript/i18n/strings/en.d.ts +3 -0
  340. package/lib/typescript/i18n/strings/en.d.ts.map +1 -0
  341. package/lib/typescript/i18n/strings/es.d.ts +260 -0
  342. package/lib/typescript/i18n/strings/es.d.ts.map +1 -0
  343. package/lib/typescript/index.d.ts +26 -0
  344. package/lib/typescript/index.d.ts.map +1 -0
  345. package/lib/typescript/steps/AddressInfoStep.d.ts +26 -0
  346. package/lib/typescript/steps/AddressInfoStep.d.ts.map +1 -0
  347. package/lib/typescript/steps/DocumentsOcrStep.d.ts +26 -0
  348. package/lib/typescript/steps/DocumentsOcrStep.d.ts.map +1 -0
  349. package/lib/typescript/steps/EmailContactStep.d.ts +15 -0
  350. package/lib/typescript/steps/EmailContactStep.d.ts.map +1 -0
  351. package/lib/typescript/steps/EmailOtpStep.d.ts +21 -0
  352. package/lib/typescript/steps/EmailOtpStep.d.ts.map +1 -0
  353. package/lib/typescript/steps/FaceMatchStep.d.ts +27 -0
  354. package/lib/typescript/steps/FaceMatchStep.d.ts.map +1 -0
  355. package/lib/typescript/steps/FingerprintStep.d.ts +25 -0
  356. package/lib/typescript/steps/FingerprintStep.d.ts.map +1 -0
  357. package/lib/typescript/steps/HumanBasicInfoStep.d.ts +25 -0
  358. package/lib/typescript/steps/HumanBasicInfoStep.d.ts.map +1 -0
  359. package/lib/typescript/steps/HumanExtendedInfoStep.d.ts +23 -0
  360. package/lib/typescript/steps/HumanExtendedInfoStep.d.ts.map +1 -0
  361. package/lib/typescript/steps/LegalBasicInfoStep.d.ts +17 -0
  362. package/lib/typescript/steps/LegalBasicInfoStep.d.ts.map +1 -0
  363. package/lib/typescript/steps/LegalExtendedInfoStep.d.ts +17 -0
  364. package/lib/typescript/steps/LegalExtendedInfoStep.d.ts.map +1 -0
  365. package/lib/typescript/steps/LivenessMatchStep.d.ts +26 -0
  366. package/lib/typescript/steps/LivenessMatchStep.d.ts.map +1 -0
  367. package/lib/typescript/steps/PhoneContactStep.d.ts +15 -0
  368. package/lib/typescript/steps/PhoneContactStep.d.ts.map +1 -0
  369. package/lib/typescript/steps/PhoneOtpStep.d.ts +19 -0
  370. package/lib/typescript/steps/PhoneOtpStep.d.ts.map +1 -0
  371. package/lib/typescript/steps/SwornDeclarationStep.d.ts +20 -0
  372. package/lib/typescript/steps/SwornDeclarationStep.d.ts.map +1 -0
  373. package/lib/typescript/steps/TaxInfoStep.d.ts +19 -0
  374. package/lib/typescript/steps/TaxInfoStep.d.ts.map +1 -0
  375. package/lib/typescript/steps/TermsAndConditionsStep.d.ts +21 -0
  376. package/lib/typescript/steps/TermsAndConditionsStep.d.ts.map +1 -0
  377. package/lib/typescript/steps/_shared.d.ts +11 -0
  378. package/lib/typescript/steps/_shared.d.ts.map +1 -0
  379. package/lib/typescript/steps/types.d.ts +68 -0
  380. package/lib/typescript/steps/types.d.ts.map +1 -0
  381. package/lib/typescript/transport/api.d.ts +35 -0
  382. package/lib/typescript/transport/api.d.ts.map +1 -0
  383. package/lib/typescript/transport/irisWebSocket.d.ts +72 -0
  384. package/lib/typescript/transport/irisWebSocket.d.ts.map +1 -0
  385. package/lib/typescript/transport/secureUrl.d.ts +14 -0
  386. package/lib/typescript/transport/secureUrl.d.ts.map +1 -0
  387. package/lib/typescript/transport/sse.d.ts +54 -0
  388. package/lib/typescript/transport/sse.d.ts.map +1 -0
  389. package/lib/typescript/types/index.d.ts +1010 -0
  390. package/lib/typescript/types/index.d.ts.map +1 -0
  391. package/lib/typescript/ui/MapFallbackBoundary.d.ts +28 -0
  392. package/lib/typescript/ui/MapFallbackBoundary.d.ts.map +1 -0
  393. package/lib/typescript/ui/StepShell.d.ts +19 -0
  394. package/lib/typescript/ui/StepShell.d.ts.map +1 -0
  395. package/lib/typescript/ui/VelionOnboardingScreen.d.ts +19 -0
  396. package/lib/typescript/ui/VelionOnboardingScreen.d.ts.map +1 -0
  397. package/lib/typescript/ui/forms/index.d.ts +3 -0
  398. package/lib/typescript/ui/forms/index.d.ts.map +1 -0
  399. package/lib/typescript/ui/forms/useInlineValidation.d.ts +30 -0
  400. package/lib/typescript/ui/forms/useInlineValidation.d.ts.map +1 -0
  401. package/lib/typescript/ui/forms/validators.d.ts +11 -0
  402. package/lib/typescript/ui/forms/validators.d.ts.map +1 -0
  403. package/lib/typescript/ui/icons/HomeHeartIcon.d.ts +14 -0
  404. package/lib/typescript/ui/icons/HomeHeartIcon.d.ts.map +1 -0
  405. package/lib/typescript/ui/icons/StepIcon.d.ts +26 -0
  406. package/lib/typescript/ui/icons/StepIcon.d.ts.map +1 -0
  407. package/lib/typescript/ui/overlays/AnalyzingOverlay.d.ts +24 -0
  408. package/lib/typescript/ui/overlays/AnalyzingOverlay.d.ts.map +1 -0
  409. package/lib/typescript/ui/overlays/LoadingOverlay.d.ts +19 -0
  410. package/lib/typescript/ui/overlays/LoadingOverlay.d.ts.map +1 -0
  411. package/lib/typescript/ui/overlays/ProgressBar.d.ts +26 -0
  412. package/lib/typescript/ui/overlays/ProgressBar.d.ts.map +1 -0
  413. package/lib/typescript/ui/overlays/RetryDialog.d.ts +17 -0
  414. package/lib/typescript/ui/overlays/RetryDialog.d.ts.map +1 -0
  415. package/lib/typescript/ui/overlays/index.d.ts +4 -0
  416. package/lib/typescript/ui/overlays/index.d.ts.map +1 -0
  417. package/lib/typescript/ui/primitives/Banner.d.ts +11 -0
  418. package/lib/typescript/ui/primitives/Banner.d.ts.map +1 -0
  419. package/lib/typescript/ui/primitives/Button.d.ts +27 -0
  420. package/lib/typescript/ui/primitives/Button.d.ts.map +1 -0
  421. package/lib/typescript/ui/primitives/Card.d.ts +10 -0
  422. package/lib/typescript/ui/primitives/Card.d.ts.map +1 -0
  423. package/lib/typescript/ui/primitives/Checkbox.d.ts +25 -0
  424. package/lib/typescript/ui/primitives/Checkbox.d.ts.map +1 -0
  425. package/lib/typescript/ui/primitives/CountrySelect.d.ts +31 -0
  426. package/lib/typescript/ui/primitives/CountrySelect.d.ts.map +1 -0
  427. package/lib/typescript/ui/primitives/DatePicker.d.ts +42 -0
  428. package/lib/typescript/ui/primitives/DatePicker.d.ts.map +1 -0
  429. package/lib/typescript/ui/primitives/Input.d.ts +17 -0
  430. package/lib/typescript/ui/primitives/Input.d.ts.map +1 -0
  431. package/lib/typescript/ui/primitives/Select.d.ts +26 -0
  432. package/lib/typescript/ui/primitives/Select.d.ts.map +1 -0
  433. package/lib/typescript/ui/primitives/Spinner.d.ts +10 -0
  434. package/lib/typescript/ui/primitives/Spinner.d.ts.map +1 -0
  435. package/lib/typescript/ui/primitives/index.d.ts +10 -0
  436. package/lib/typescript/ui/primitives/index.d.ts.map +1 -0
  437. package/lib/typescript/ui/theme/ThemeProvider.d.ts +23 -0
  438. package/lib/typescript/ui/theme/ThemeProvider.d.ts.map +1 -0
  439. package/lib/typescript/ui/theme/index.d.ts +3 -0
  440. package/lib/typescript/ui/theme/index.d.ts.map +1 -0
  441. package/lib/typescript/ui/theme/tokens.d.ts +42 -0
  442. package/lib/typescript/ui/theme/tokens.d.ts.map +1 -0
  443. package/lib/typescript/utils/EventEmitter.d.ts +98 -0
  444. package/lib/typescript/utils/EventEmitter.d.ts.map +1 -0
  445. package/lib/typescript/utils/base64.d.ts +19 -0
  446. package/lib/typescript/utils/base64.d.ts.map +1 -0
  447. package/lib/typescript/utils/deviceFingerprint.d.ts +42 -0
  448. package/lib/typescript/utils/deviceFingerprint.d.ts.map +1 -0
  449. package/lib/typescript/utils/documentTypeOptions.d.ts +13 -0
  450. package/lib/typescript/utils/documentTypeOptions.d.ts.map +1 -0
  451. package/lib/typescript/utils/googleMapsPreflight.d.ts +44 -0
  452. package/lib/typescript/utils/googleMapsPreflight.d.ts.map +1 -0
  453. package/lib/typescript/utils/hmac.d.ts +39 -0
  454. package/lib/typescript/utils/hmac.d.ts.map +1 -0
  455. package/lib/typescript/utils/iso3166Countries.d.ts +27 -0
  456. package/lib/typescript/utils/iso3166Countries.d.ts.map +1 -0
  457. package/lib/typescript/utils/jpegFromUri.d.ts +29 -0
  458. package/lib/typescript/utils/jpegFromUri.d.ts.map +1 -0
  459. package/lib/typescript/utils/keepAwake.d.ts +16 -0
  460. package/lib/typescript/utils/keepAwake.d.ts.map +1 -0
  461. package/lib/typescript/utils/log.d.ts +18 -0
  462. package/lib/typescript/utils/log.d.ts.map +1 -0
  463. package/lib/typescript/utils/osGeocoder.d.ts +38 -0
  464. package/lib/typescript/utils/osGeocoder.d.ts.map +1 -0
  465. package/lib/typescript/utils/parseGoogleAddressComponents.d.ts +43 -0
  466. package/lib/typescript/utils/parseGoogleAddressComponents.d.ts.map +1 -0
  467. package/lib/typescript/utils/personNameNormalize.d.ts +10 -0
  468. package/lib/typescript/utils/personNameNormalize.d.ts.map +1 -0
  469. package/lib/typescript/utils/sdkError.d.ts +14 -0
  470. package/lib/typescript/utils/sdkError.d.ts.map +1 -0
  471. package/lib/typescript/utils/sdkVersion.d.ts +7 -0
  472. package/lib/typescript/utils/sdkVersion.d.ts.map +1 -0
  473. package/lib/typescript/utils/stepConfig.d.ts +8 -0
  474. package/lib/typescript/utils/stepConfig.d.ts.map +1 -0
  475. package/lib/typescript/utils/taxInfoConfig.d.ts +7 -0
  476. package/lib/typescript/utils/taxInfoConfig.d.ts.map +1 -0
  477. package/package.json +99 -0
  478. package/src/camera/AddressSearchBar.tsx +363 -0
  479. package/src/camera/DocumentCapture.tsx +505 -0
  480. package/src/camera/LivenessCamera.tsx +602 -0
  481. package/src/camera/MapAddressPicker.tsx +397 -0
  482. package/src/core/VelionOnboarding.ts +974 -0
  483. package/src/core/sessionDeclinedCopy.ts +76 -0
  484. package/src/core/sessionStateMapper.ts +167 -0
  485. package/src/core/sseReasonMessages.ts +531 -0
  486. package/src/data/iso3166Alpha2Codes.json +1 -0
  487. package/src/data/iso3166CountryNames.json +251 -0
  488. package/src/i18n/index.ts +26 -0
  489. package/src/i18n/strings/en.ts +289 -0
  490. package/src/i18n/strings/es.ts +291 -0
  491. package/src/index.ts +137 -0
  492. package/src/steps/AddressInfoStep.tsx +726 -0
  493. package/src/steps/DocumentsOcrStep.tsx +472 -0
  494. package/src/steps/EmailContactStep.tsx +159 -0
  495. package/src/steps/EmailOtpStep.tsx +250 -0
  496. package/src/steps/FaceMatchStep.tsx +177 -0
  497. package/src/steps/FingerprintStep.tsx +99 -0
  498. package/src/steps/HumanBasicInfoStep.tsx +274 -0
  499. package/src/steps/HumanExtendedInfoStep.tsx +353 -0
  500. package/src/steps/LegalBasicInfoStep.tsx +205 -0
  501. package/src/steps/LegalExtendedInfoStep.tsx +171 -0
  502. package/src/steps/LivenessMatchStep.tsx +846 -0
  503. package/src/steps/PhoneContactStep.tsx +160 -0
  504. package/src/steps/PhoneOtpStep.tsx +249 -0
  505. package/src/steps/SwornDeclarationStep.tsx +220 -0
  506. package/src/steps/TaxInfoStep.tsx +277 -0
  507. package/src/steps/TermsAndConditionsStep.tsx +261 -0
  508. package/src/steps/_shared.ts +44 -0
  509. package/src/steps/types.ts +72 -0
  510. package/src/transport/api.ts +257 -0
  511. package/src/transport/irisWebSocket.ts +186 -0
  512. package/src/transport/secureUrl.ts +47 -0
  513. package/src/transport/sse.ts +310 -0
  514. package/src/types/index.ts +1198 -0
  515. package/src/ui/MapFallbackBoundary.tsx +46 -0
  516. package/src/ui/StepShell.tsx +137 -0
  517. package/src/ui/VelionOnboardingScreen.tsx +223 -0
  518. package/src/ui/forms/index.ts +12 -0
  519. package/src/ui/forms/useInlineValidation.ts +115 -0
  520. package/src/ui/forms/validators.ts +29 -0
  521. package/src/ui/icons/HomeHeartIcon.tsx +34 -0
  522. package/src/ui/icons/StepIcon.tsx +77 -0
  523. package/src/ui/overlays/AnalyzingOverlay.tsx +323 -0
  524. package/src/ui/overlays/LoadingOverlay.tsx +115 -0
  525. package/src/ui/overlays/ProgressBar.tsx +99 -0
  526. package/src/ui/overlays/RetryDialog.tsx +128 -0
  527. package/src/ui/overlays/index.ts +3 -0
  528. package/src/ui/primitives/Banner.tsx +81 -0
  529. package/src/ui/primitives/Button.tsx +164 -0
  530. package/src/ui/primitives/Card.tsx +55 -0
  531. package/src/ui/primitives/Checkbox.tsx +153 -0
  532. package/src/ui/primitives/CountrySelect.tsx +356 -0
  533. package/src/ui/primitives/DatePicker.tsx +266 -0
  534. package/src/ui/primitives/Input.tsx +110 -0
  535. package/src/ui/primitives/Select.tsx +259 -0
  536. package/src/ui/primitives/Spinner.tsx +17 -0
  537. package/src/ui/primitives/index.ts +9 -0
  538. package/src/ui/theme/ThemeProvider.tsx +102 -0
  539. package/src/ui/theme/index.ts +17 -0
  540. package/src/ui/theme/tokens.ts +159 -0
  541. package/src/utils/EventEmitter.ts +155 -0
  542. package/src/utils/base64.ts +44 -0
  543. package/src/utils/deviceFingerprint.ts +184 -0
  544. package/src/utils/documentTypeOptions.ts +31 -0
  545. package/src/utils/googleMapsPreflight.ts +72 -0
  546. package/src/utils/hmac.ts +61 -0
  547. package/src/utils/iso3166Countries.ts +111 -0
  548. package/src/utils/jpegFromUri.ts +42 -0
  549. package/src/utils/keepAwake.ts +62 -0
  550. package/src/utils/log.ts +37 -0
  551. package/src/utils/osGeocoder.ts +75 -0
  552. package/src/utils/parseGoogleAddressComponents.ts +123 -0
  553. package/src/utils/personNameNormalize.ts +17 -0
  554. package/src/utils/sdkError.ts +40 -0
  555. package/src/utils/sdkVersion.ts +6 -0
  556. package/src/utils/stepConfig.ts +75 -0
  557. package/src/utils/taxInfoConfig.ts +14 -0
@@ -0,0 +1,602 @@
1
+ /**
2
+ * @fileoverview Liveness camera surface — front-facing vision-camera with an
3
+ * oval mask, status pill, and capture loop driven by the parent step.
4
+ *
5
+ * Capture strategy: vision-camera v4 frame processors run on a worklet thread
6
+ * and don't expose the JPEG bytes back to JS without a custom native plugin.
7
+ * We avoid that complication by using `takePhoto({ qualityPrioritization:
8
+ * 'speed' })` on a JS-level interval (matches the `setInterval` pattern in
9
+ * `web/LivenessModule.ts`). Real-world FPS lands around 3–8 fps which is
10
+ * sufficient for Iris's challenge cadence.
11
+ *
12
+ * The parent owns the loop and the WebSocket — this component just exposes a
13
+ * `captureFrame` ref so the step can drive the timing while the camera stays
14
+ * mounted across challenges.
15
+ */
16
+
17
+ import {
18
+ forwardRef,
19
+ useCallback,
20
+ useEffect,
21
+ useImperativeHandle,
22
+ useRef,
23
+ useState,
24
+ } from 'react';
25
+ import {
26
+ ActivityIndicator,
27
+ Animated,
28
+ Easing,
29
+ StyleSheet,
30
+ Text,
31
+ useWindowDimensions,
32
+ View,
33
+ } from 'react-native';
34
+ import Svg, { Defs, Ellipse, Mask, Rect } from 'react-native-svg';
35
+ import {
36
+ Camera,
37
+ useCameraDevice,
38
+ useCameraPermission,
39
+ type PhotoFile,
40
+ } from 'react-native-vision-camera';
41
+ import { Button } from '../ui/primitives/Button';
42
+ import { useTheme, withAlpha } from '../ui/theme';
43
+
44
+ export interface LivenessCameraHandle {
45
+ takeFrame: () => Promise<PhotoFile | null>;
46
+ }
47
+
48
+ /**
49
+ * Visual cue applied to the oval guide. The parent maps the current Iris
50
+ * challenge to one of these so the oval animates in a way that reinforces
51
+ * the instruction (oval grows for MOVE_CLOSER, shrinks back for MOVE_FARTHER,
52
+ * stays neutral otherwise).
53
+ */
54
+ export type LivenessOvalCue = 'NEUTRAL' | 'MOVE_CLOSER' | 'MOVE_FARTHER';
55
+
56
+ export interface LivenessCameraProps {
57
+ /** Status text rendered in the centred pill. Pass `null` to hide it. */
58
+ statusText: string | null;
59
+ /** Active challenge instruction (rendered above the oval). Optional. */
60
+ challengeText?: string | null | undefined;
61
+ /** Visual cue for the oval shape (size animation). Defaults to NEUTRAL. */
62
+ ovalCue?: LivenessOvalCue | undefined;
63
+ /** Toast text — passed in as a `{ kind, message }` so the parent owns timing. */
64
+ toast?: { kind: 'success' | 'warning'; message: string } | null | undefined;
65
+ /** Linear progress 0–1 shown under the oval (CHALLENGE_PROGRESS). */
66
+ progress?: number | null | undefined;
67
+ /** Localized permission denied copy. */
68
+ permissionDeniedLabel: string;
69
+ /** Localized retry label for the permission CTA. */
70
+ retryLabel: string;
71
+ /** Localized cancel / back label. */
72
+ cancelLabel: string;
73
+ onCancel?: (() => void) | undefined;
74
+ }
75
+
76
+ export const LivenessCamera = forwardRef<LivenessCameraHandle, LivenessCameraProps>(
77
+ function LivenessCamera(props, ref) {
78
+ const theme = useTheme();
79
+ const cameraRef = useRef<Camera>(null);
80
+ const device = useCameraDevice('front');
81
+ const { hasPermission, requestPermission } = useCameraPermission();
82
+ const requestedRef = useRef(false);
83
+ const inFlightRef = useRef(false);
84
+ // Same simulator-friendly timeout as DocumentCapture: bail out of the
85
+ // infinite spinner after 4s without a device.
86
+ const [deviceTimeout, setDeviceTimeout] = useState(false);
87
+
88
+ useEffect(() => {
89
+ if (!hasPermission && !requestedRef.current) {
90
+ requestedRef.current = true;
91
+ void requestPermission();
92
+ }
93
+ }, [hasPermission, requestPermission]);
94
+
95
+ useEffect(() => {
96
+ if (device || !hasPermission) {
97
+ setDeviceTimeout(false);
98
+ return;
99
+ }
100
+ const t = setTimeout(() => setDeviceTimeout(true), 4000);
101
+ return () => clearTimeout(t);
102
+ }, [device, hasPermission]);
103
+
104
+ const takeFrame = useCallback(async (): Promise<PhotoFile | null> => {
105
+ if (inFlightRef.current) return null;
106
+ const camera = cameraRef.current;
107
+ if (!camera) return null;
108
+ inFlightRef.current = true;
109
+ try {
110
+ return await camera.takePhoto({
111
+ flash: 'off',
112
+ enableShutterSound: false,
113
+ });
114
+ } catch {
115
+ // Frame failures are non-fatal — the parent loop just retries on the
116
+ // next tick. Keep the camera mounted.
117
+ return null;
118
+ } finally {
119
+ inFlightRef.current = false;
120
+ }
121
+ }, []);
122
+
123
+ useImperativeHandle(ref, () => ({ takeFrame }), [takeFrame]);
124
+
125
+ if (!hasPermission) {
126
+ return (
127
+ <View style={[styles.permission, { backgroundColor: theme.backgroundColor }]}>
128
+ <Text style={[styles.permissionText, { color: theme.textColor }]}>
129
+ {props.permissionDeniedLabel}
130
+ </Text>
131
+ <View style={styles.row}>
132
+ {props.onCancel ? (
133
+ <Button
134
+ variant="ghost"
135
+ label={props.cancelLabel}
136
+ onPress={props.onCancel}
137
+ fullWidth={false}
138
+ style={styles.actionBtn}
139
+ />
140
+ ) : null}
141
+ <Button
142
+ label={props.retryLabel}
143
+ onPress={() => {
144
+ void requestPermission();
145
+ }}
146
+ fullWidth={false}
147
+ style={styles.actionBtn}
148
+ />
149
+ </View>
150
+ </View>
151
+ );
152
+ }
153
+
154
+ if (!device) {
155
+ if (deviceTimeout) {
156
+ return (
157
+ <View style={[styles.permission, { backgroundColor: theme.backgroundColor }]}>
158
+ <Text style={[styles.permissionText, { color: theme.textColor }]}>
159
+ No camera detected. The iOS Simulator does not provide a real
160
+ camera — please run on a physical device to perform the
161
+ liveness check.
162
+ </Text>
163
+ {props.onCancel ? (
164
+ <View style={styles.row}>
165
+ <Button
166
+ variant="ghost"
167
+ label={props.cancelLabel}
168
+ onPress={props.onCancel}
169
+ fullWidth={false}
170
+ style={styles.actionBtn}
171
+ />
172
+ </View>
173
+ ) : null}
174
+ </View>
175
+ );
176
+ }
177
+ return (
178
+ <View style={[styles.permission, { backgroundColor: theme.backgroundColor }]}>
179
+ <ActivityIndicator color={theme.primaryColor} />
180
+ </View>
181
+ );
182
+ }
183
+
184
+ return (
185
+ <View style={styles.root}>
186
+ <Camera
187
+ ref={cameraRef}
188
+ style={StyleSheet.absoluteFill}
189
+ device={device}
190
+ photo
191
+ photoQualityBalance="speed"
192
+ // Sin espejo en el output: el preview sigue mirrored, pero el JPEG enviado a Iris mantiene el yaw real (TURN_LEFT/RIGHT).
193
+ isMirrored={false}
194
+ isActive
195
+ />
196
+ <OvalOverlay
197
+ primaryColor={theme.primaryColor}
198
+ cue={props.ovalCue ?? 'NEUTRAL'}
199
+ />
200
+ {props.challengeText ? (
201
+ <ChallengeBanner
202
+ text={props.challengeText}
203
+ tint={theme.primaryColor}
204
+ />
205
+ ) : null}
206
+ {props.statusText ? (
207
+ <View style={styles.statusPill}>
208
+ <ActivityIndicator color="#FFFFFF" size="small" />
209
+ <Text style={styles.statusText}>{props.statusText}</Text>
210
+ </View>
211
+ ) : null}
212
+ {props.toast ? (
213
+ <View
214
+ style={[
215
+ styles.toast,
216
+ {
217
+ backgroundColor:
218
+ props.toast.kind === 'success'
219
+ ? withAlpha(theme.successColor, 0.92)
220
+ : withAlpha(theme.warningColor, 0.92),
221
+ },
222
+ ]}
223
+ >
224
+ <Text style={styles.toastText}>{props.toast.message}</Text>
225
+ </View>
226
+ ) : null}
227
+ {props.progress != null ? (
228
+ <ProgressBar
229
+ progress={props.progress}
230
+ color={theme.primaryColor}
231
+ />
232
+ ) : null}
233
+ </View>
234
+ );
235
+ },
236
+ );
237
+
238
+ interface ProgressBarProps {
239
+ progress: number;
240
+ color: string;
241
+ }
242
+
243
+ /**
244
+ * Challenge progress bar with an indeterminate fallback.
245
+ *
246
+ * When the orchestrator hasn't sent any CHALLENGE_PROGRESS yet (still
247
+ * collecting baseline, user hasn't started moving, etc.) `progress` is 0
248
+ * and a static empty bar looks broken. We treat the [0, 0.05) range as
249
+ * "no measurable progress yet" and run a left-to-right shimmer instead,
250
+ * so the user can tell the system is still listening.
251
+ */
252
+ function ProgressBar({ progress, color }: ProgressBarProps) {
253
+ const clamped = Math.max(0, Math.min(1, progress));
254
+ const isIndeterminate = clamped < 0.05;
255
+
256
+ const shimmer = useRef(new Animated.Value(0)).current;
257
+ useEffect(() => {
258
+ if (!isIndeterminate) {
259
+ shimmer.stopAnimation();
260
+ return;
261
+ }
262
+ shimmer.setValue(0);
263
+ const loop = Animated.loop(
264
+ Animated.timing(shimmer, {
265
+ toValue: 1,
266
+ duration: 1200,
267
+ easing: Easing.inOut(Easing.ease),
268
+ useNativeDriver: false,
269
+ }),
270
+ );
271
+ loop.start();
272
+ return () => loop.stop();
273
+ }, [isIndeterminate, shimmer]);
274
+
275
+ if (isIndeterminate) {
276
+ // 30 % wide segment sliding from -30 % to +100 % of the track.
277
+ const left = shimmer.interpolate({
278
+ inputRange: [0, 1],
279
+ outputRange: ['-30%', '100%'],
280
+ });
281
+ return (
282
+ <View style={styles.progressTrack}>
283
+ <Animated.View
284
+ style={[
285
+ styles.progressShimmer,
286
+ { backgroundColor: color, left },
287
+ ]}
288
+ />
289
+ </View>
290
+ );
291
+ }
292
+
293
+ return (
294
+ <View style={styles.progressTrack}>
295
+ <View
296
+ style={[
297
+ styles.progressBar,
298
+ {
299
+ width: `${clamped * 100}%`,
300
+ backgroundColor: color,
301
+ },
302
+ ]}
303
+ />
304
+ </View>
305
+ );
306
+ }
307
+
308
+ interface ChallengeBannerProps {
309
+ text: string;
310
+ tint: string;
311
+ }
312
+
313
+ /**
314
+ * Attention-grabbing challenge instruction.
315
+ *
316
+ * The previous small grey pill was easy to miss — users sat confused
317
+ * while Iris's 800-8000 ms BLINK window closed. This banner is bold,
318
+ * sits on a dark translucent surface (less visually heavy than a full
319
+ * primary-tinted fill), and runs a fade-in + scale-up animation every
320
+ * time the `text` prop changes so the eye snaps to the new instruction.
321
+ *
322
+ * The `tint` prop is no longer used for the background (too saturated);
323
+ * it's kept in the signature for future re-introduction of an accent
324
+ * line / icon if needed without changing the call site.
325
+ */
326
+ function ChallengeBanner({ text, tint: _tint }: ChallengeBannerProps) {
327
+ const opacity = useRef(new Animated.Value(0)).current;
328
+ const scale = useRef(new Animated.Value(0.85)).current;
329
+
330
+ useEffect(() => {
331
+ // Reset to invisible/shrunk, then animate in. `text` in deps means each
332
+ // new challenge re-triggers the entrance animation.
333
+ opacity.setValue(0);
334
+ scale.setValue(0.85);
335
+ Animated.parallel([
336
+ Animated.timing(opacity, {
337
+ toValue: 1,
338
+ duration: 240,
339
+ easing: Easing.out(Easing.cubic),
340
+ useNativeDriver: true,
341
+ }),
342
+ Animated.spring(scale, {
343
+ toValue: 1,
344
+ damping: 12,
345
+ stiffness: 180,
346
+ mass: 0.7,
347
+ useNativeDriver: true,
348
+ }),
349
+ ]).start();
350
+ }, [text, opacity, scale]);
351
+
352
+ return (
353
+ <Animated.View
354
+ pointerEvents="none"
355
+ style={[
356
+ styles.challengeBanner,
357
+ {
358
+ opacity,
359
+ transform: [{ scale }],
360
+ },
361
+ ]}
362
+ >
363
+ <Text style={styles.challengeBannerText} numberOfLines={2}>
364
+ {text}
365
+ </Text>
366
+ </Animated.View>
367
+ );
368
+ }
369
+
370
+ interface OvalOverlayProps {
371
+ primaryColor: string;
372
+ cue: LivenessOvalCue;
373
+ }
374
+
375
+ // Face-shaped oval: real human heads have a width-to-height ratio close to
376
+ // ~0.72 (slightly taller than a circle). Sized explicitly from
377
+ // `useWindowDimensions` and rendered as a true ellipse via SVG (NOT a
378
+ // rounded View) so the dim mask can follow the actual curve.
379
+ const OVAL_WIDTH_RATIO = 0.78; // 78 % of screen width
380
+ const OVAL_MAX_HEIGHT_RATIO = 0.62; // never taller than 62 % of screen height
381
+ const OVAL_ASPECT = 0.78; // width / height — face proportion
382
+ // Visual nudge: dim the screen symmetrically around the geometric centre
383
+ // looks slightly low because of the status bar / Dynamic Island at the
384
+ // top. Lift the oval by this many points so the user's natural framing
385
+ // (eyes near the top third of the oval) aligns with the screen's optical
386
+ // centre.
387
+ const OVAL_OPTICAL_OFFSET_UP = 24;
388
+ const OVAL_BORDER_WIDTH = 4;
389
+ // Secondary halo drawn outside the main stroke. Gives the user a clearer
390
+ // "your face should fill this" target without being so heavy that it
391
+ // distracts during the challenges.
392
+ const OVAL_HALO_WIDTH = 2;
393
+ const OVAL_HALO_OFFSET = 6; // px outside the primary stroke
394
+ const DIM_FILL = 'rgba(0, 0, 0, 0.55)';
395
+ // Scale targets per oval cue. The oval visually invites the user to bring
396
+ // their face closer (it grows) on MOVE_CLOSER, and to back away (it shrinks
397
+ // back to neutral size) on MOVE_FARTHER. NEUTRAL is the default oval size.
398
+ const OVAL_SCALE_BY_CUE: Record<LivenessOvalCue, number> = {
399
+ NEUTRAL: 1.0,
400
+ MOVE_CLOSER: 1.25,
401
+ MOVE_FARTHER: 1.0,
402
+ };
403
+ const OVAL_SCALE_ANIM_MS = 600;
404
+
405
+ function OvalOverlay({ primaryColor, cue }: OvalOverlayProps) {
406
+ const { width: screenW, height: screenH } = useWindowDimensions();
407
+
408
+ // Compute width first, then derive height to keep the face aspect ratio.
409
+ // If that height would dominate the screen, clip from the height side
410
+ // instead so the oval stays well within the visible area on tall phones.
411
+ let ovalW = screenW * OVAL_WIDTH_RATIO;
412
+ let ovalH = ovalW / OVAL_ASPECT;
413
+ const maxH = screenH * OVAL_MAX_HEIGHT_RATIO;
414
+ if (ovalH > maxH) {
415
+ ovalH = maxH;
416
+ ovalW = ovalH * OVAL_ASPECT;
417
+ }
418
+ const rx = ovalW / 2;
419
+ const ry = ovalH / 2;
420
+ const cx = screenW / 2;
421
+ const cy = Math.max(ry + 20, screenH / 2 - OVAL_OPTICAL_OFFSET_UP);
422
+
423
+ // Animate the oval scale on cue changes. We scale the entire Svg via an
424
+ // Animated.View transform — that keeps the mask + stroke perfectly
425
+ // aligned (no need to animate every SVG attribute individually). Scaling
426
+ // the dim rectangle past the screen edge is harmless: the user only sees
427
+ // the on-screen portion, which is exactly what we want.
428
+ const ovalScale = useRef(new Animated.Value(OVAL_SCALE_BY_CUE[cue])).current;
429
+ useEffect(() => {
430
+ Animated.timing(ovalScale, {
431
+ toValue: OVAL_SCALE_BY_CUE[cue],
432
+ duration: OVAL_SCALE_ANIM_MS,
433
+ easing: Easing.out(Easing.cubic),
434
+ useNativeDriver: true,
435
+ }).start();
436
+ }, [cue, ovalScale]);
437
+
438
+ // SVG mask trick:
439
+ // - The Mask defines a black/white image where white = "show the masked
440
+ // element" and black = "hide it (transparent)".
441
+ // - We mask a full-screen dim rectangle so the dim shows EVERYWHERE
442
+ // except inside the ellipse (where the mask is black).
443
+ // - On top of the dim, we draw the ellipse stroke as the visual
444
+ // viewfinder. Stroke is inset half its width so it stays exactly on
445
+ // the dim/transparent boundary.
446
+ return (
447
+ <Animated.View
448
+ pointerEvents="none"
449
+ style={[StyleSheet.absoluteFill, { transform: [{ scale: ovalScale }] }]}
450
+ >
451
+ <Svg
452
+ width={screenW}
453
+ height={screenH}
454
+ style={StyleSheet.absoluteFill}
455
+ >
456
+ <Defs>
457
+ <Mask id="ovalCutout">
458
+ <Rect x={0} y={0} width={screenW} height={screenH} fill="white" />
459
+ <Ellipse cx={cx} cy={cy} rx={rx} ry={ry} fill="black" />
460
+ </Mask>
461
+ </Defs>
462
+ <Rect
463
+ x={0}
464
+ y={0}
465
+ width={screenW}
466
+ height={screenH}
467
+ fill={DIM_FILL}
468
+ mask="url(#ovalCutout)"
469
+ />
470
+ {/* Outer halo: lower-opacity white ring that frames the primary
471
+ stroke. The pair reads as "here's the target shape" much more
472
+ clearly than a single 3 px stroke against the live camera feed,
473
+ especially on Android phones with low-contrast OLED panels. */}
474
+ <Ellipse
475
+ cx={cx}
476
+ cy={cy}
477
+ rx={rx + OVAL_HALO_OFFSET}
478
+ ry={ry + OVAL_HALO_OFFSET}
479
+ stroke="rgba(255, 255, 255, 0.45)"
480
+ strokeWidth={OVAL_HALO_WIDTH}
481
+ fill="none"
482
+ />
483
+ <Ellipse
484
+ cx={cx}
485
+ cy={cy}
486
+ rx={rx - OVAL_BORDER_WIDTH / 2}
487
+ ry={ry - OVAL_BORDER_WIDTH / 2}
488
+ stroke={primaryColor}
489
+ strokeWidth={OVAL_BORDER_WIDTH}
490
+ fill="none"
491
+ />
492
+ </Svg>
493
+ </Animated.View>
494
+ );
495
+ }
496
+
497
+ const styles = StyleSheet.create({
498
+ root: {
499
+ flex: 1,
500
+ backgroundColor: '#000',
501
+ },
502
+ permission: {
503
+ flex: 1,
504
+ alignItems: 'center',
505
+ justifyContent: 'center',
506
+ padding: 32,
507
+ gap: 16,
508
+ },
509
+ permissionText: {
510
+ textAlign: 'center',
511
+ fontSize: 15,
512
+ lineHeight: 22,
513
+ },
514
+ row: {
515
+ flexDirection: 'row',
516
+ gap: 12,
517
+ width: '100%',
518
+ maxWidth: 380,
519
+ },
520
+ actionBtn: {
521
+ flex: 1,
522
+ },
523
+ challengeBanner: {
524
+ position: 'absolute',
525
+ top: 76,
526
+ left: 24,
527
+ right: 24,
528
+ paddingHorizontal: 16,
529
+ paddingVertical: 10,
530
+ borderRadius: 18,
531
+ alignItems: 'center',
532
+ justifyContent: 'center',
533
+ backgroundColor: 'rgba(0, 0, 0, 0.62)',
534
+ },
535
+ challengeBannerText: {
536
+ color: '#FFFFFF',
537
+ fontSize: 19,
538
+ fontWeight: '700',
539
+ textAlign: 'center',
540
+ letterSpacing: 0.1,
541
+ lineHeight: 24,
542
+ },
543
+ statusPill: {
544
+ position: 'absolute',
545
+ top: 130,
546
+ left: 0,
547
+ right: 0,
548
+ alignSelf: 'center',
549
+ flexDirection: 'row',
550
+ alignItems: 'center',
551
+ justifyContent: 'center',
552
+ gap: 8,
553
+ backgroundColor: 'rgba(0,0,0,0.55)',
554
+ paddingHorizontal: 14,
555
+ paddingVertical: 8,
556
+ borderRadius: 16,
557
+ marginHorizontal: 60,
558
+ overflow: 'hidden',
559
+ },
560
+ statusText: {
561
+ color: '#FFFFFF',
562
+ fontSize: 13,
563
+ fontWeight: '500',
564
+ },
565
+ toast: {
566
+ position: 'absolute',
567
+ bottom: 100,
568
+ left: 24,
569
+ right: 24,
570
+ paddingVertical: 10,
571
+ paddingHorizontal: 14,
572
+ borderRadius: 14,
573
+ alignItems: 'center',
574
+ },
575
+ toastText: {
576
+ color: '#FFFFFF',
577
+ fontWeight: '600',
578
+ fontSize: 14,
579
+ textAlign: 'center',
580
+ },
581
+ progressTrack: {
582
+ position: 'absolute',
583
+ bottom: 60,
584
+ left: 24,
585
+ right: 24,
586
+ height: 6,
587
+ borderRadius: 3,
588
+ backgroundColor: 'rgba(255,255,255,0.25)',
589
+ overflow: 'hidden',
590
+ },
591
+ progressBar: {
592
+ height: '100%',
593
+ },
594
+ progressShimmer: {
595
+ position: 'absolute',
596
+ top: 0,
597
+ bottom: 0,
598
+ width: '30%',
599
+ opacity: 0.85,
600
+ borderRadius: 3,
601
+ },
602
+ });