@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.
- package/CHANGELOG.md +66 -0
- package/LICENSE +12 -0
- package/README.md +803 -0
- package/lib/commonjs/camera/AddressSearchBar.js +304 -0
- package/lib/commonjs/camera/AddressSearchBar.js.map +1 -0
- package/lib/commonjs/camera/DocumentCapture.js +505 -0
- package/lib/commonjs/camera/DocumentCapture.js.map +1 -0
- package/lib/commonjs/camera/LivenessCamera.js +534 -0
- package/lib/commonjs/camera/LivenessCamera.js.map +1 -0
- package/lib/commonjs/camera/MapAddressPicker.js +341 -0
- package/lib/commonjs/camera/MapAddressPicker.js.map +1 -0
- package/lib/commonjs/core/VelionOnboarding.js +815 -0
- package/lib/commonjs/core/VelionOnboarding.js.map +1 -0
- package/lib/commonjs/core/sessionDeclinedCopy.js +56 -0
- package/lib/commonjs/core/sessionDeclinedCopy.js.map +1 -0
- package/lib/commonjs/core/sessionStateMapper.js +137 -0
- package/lib/commonjs/core/sessionStateMapper.js.map +1 -0
- package/lib/commonjs/core/sseReasonMessages.js +450 -0
- package/lib/commonjs/core/sseReasonMessages.js.map +1 -0
- package/lib/commonjs/data/iso3166Alpha2Codes.json +1 -0
- package/lib/commonjs/data/iso3166CountryNames.json +251 -0
- package/lib/commonjs/i18n/index.js +30 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/strings/en.js +261 -0
- package/lib/commonjs/i18n/strings/en.js.map +1 -0
- package/lib/commonjs/i18n/strings/es.js +266 -0
- package/lib/commonjs/i18n/strings/es.js.map +1 -0
- package/lib/commonjs/index.js +213 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/steps/AddressInfoStep.js +650 -0
- package/lib/commonjs/steps/AddressInfoStep.js.map +1 -0
- package/lib/commonjs/steps/DocumentsOcrStep.js +397 -0
- package/lib/commonjs/steps/DocumentsOcrStep.js.map +1 -0
- package/lib/commonjs/steps/EmailContactStep.js +145 -0
- package/lib/commonjs/steps/EmailContactStep.js.map +1 -0
- package/lib/commonjs/steps/EmailOtpStep.js +220 -0
- package/lib/commonjs/steps/EmailOtpStep.js.map +1 -0
- package/lib/commonjs/steps/FaceMatchStep.js +166 -0
- package/lib/commonjs/steps/FaceMatchStep.js.map +1 -0
- package/lib/commonjs/steps/FingerprintStep.js +92 -0
- package/lib/commonjs/steps/FingerprintStep.js.map +1 -0
- package/lib/commonjs/steps/HumanBasicInfoStep.js +243 -0
- package/lib/commonjs/steps/HumanBasicInfoStep.js.map +1 -0
- package/lib/commonjs/steps/HumanExtendedInfoStep.js +268 -0
- package/lib/commonjs/steps/HumanExtendedInfoStep.js.map +1 -0
- package/lib/commonjs/steps/LegalBasicInfoStep.js +188 -0
- package/lib/commonjs/steps/LegalBasicInfoStep.js.map +1 -0
- package/lib/commonjs/steps/LegalExtendedInfoStep.js +166 -0
- package/lib/commonjs/steps/LegalExtendedInfoStep.js.map +1 -0
- package/lib/commonjs/steps/LivenessMatchStep.js +707 -0
- package/lib/commonjs/steps/LivenessMatchStep.js.map +1 -0
- package/lib/commonjs/steps/PhoneContactStep.js +146 -0
- package/lib/commonjs/steps/PhoneContactStep.js.map +1 -0
- package/lib/commonjs/steps/PhoneOtpStep.js +219 -0
- package/lib/commonjs/steps/PhoneOtpStep.js.map +1 -0
- package/lib/commonjs/steps/SwornDeclarationStep.js +196 -0
- package/lib/commonjs/steps/SwornDeclarationStep.js.map +1 -0
- package/lib/commonjs/steps/TaxInfoStep.js +244 -0
- package/lib/commonjs/steps/TaxInfoStep.js.map +1 -0
- package/lib/commonjs/steps/TermsAndConditionsStep.js +238 -0
- package/lib/commonjs/steps/TermsAndConditionsStep.js.map +1 -0
- package/lib/commonjs/steps/_shared.js +40 -0
- package/lib/commonjs/steps/_shared.js.map +1 -0
- package/lib/commonjs/steps/types.js +6 -0
- package/lib/commonjs/steps/types.js.map +1 -0
- package/lib/commonjs/transport/api.js +176 -0
- package/lib/commonjs/transport/api.js.map +1 -0
- package/lib/commonjs/transport/irisWebSocket.js +121 -0
- package/lib/commonjs/transport/irisWebSocket.js.map +1 -0
- package/lib/commonjs/transport/secureUrl.js +50 -0
- package/lib/commonjs/transport/secureUrl.js.map +1 -0
- package/lib/commonjs/transport/sse.js +248 -0
- package/lib/commonjs/transport/sse.js.map +1 -0
- package/lib/commonjs/types/index.js +391 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/ui/MapFallbackBoundary.js +42 -0
- package/lib/commonjs/ui/MapFallbackBoundary.js.map +1 -0
- package/lib/commonjs/ui/StepShell.js +118 -0
- package/lib/commonjs/ui/StepShell.js.map +1 -0
- package/lib/commonjs/ui/VelionOnboardingScreen.js +217 -0
- package/lib/commonjs/ui/VelionOnboardingScreen.js.map +1 -0
- package/lib/commonjs/ui/forms/index.js +38 -0
- package/lib/commonjs/ui/forms/index.js.map +1 -0
- package/lib/commonjs/ui/forms/useInlineValidation.js +88 -0
- package/lib/commonjs/ui/forms/useInlineValidation.js.map +1 -0
- package/lib/commonjs/ui/forms/validators.js +34 -0
- package/lib/commonjs/ui/forms/validators.js.map +1 -0
- package/lib/commonjs/ui/icons/HomeHeartIcon.js +38 -0
- package/lib/commonjs/ui/icons/HomeHeartIcon.js.map +1 -0
- package/lib/commonjs/ui/icons/StepIcon.js +59 -0
- package/lib/commonjs/ui/icons/StepIcon.js.map +1 -0
- package/lib/commonjs/ui/overlays/AnalyzingOverlay.js +284 -0
- package/lib/commonjs/ui/overlays/AnalyzingOverlay.js.map +1 -0
- package/lib/commonjs/ui/overlays/LoadingOverlay.js +108 -0
- package/lib/commonjs/ui/overlays/LoadingOverlay.js.map +1 -0
- package/lib/commonjs/ui/overlays/ProgressBar.js +95 -0
- package/lib/commonjs/ui/overlays/ProgressBar.js.map +1 -0
- package/lib/commonjs/ui/overlays/RetryDialog.js +125 -0
- package/lib/commonjs/ui/overlays/RetryDialog.js.map +1 -0
- package/lib/commonjs/ui/overlays/index.js +33 -0
- package/lib/commonjs/ui/overlays/index.js.map +1 -0
- package/lib/commonjs/ui/primitives/Banner.js +81 -0
- package/lib/commonjs/ui/primitives/Banner.js.map +1 -0
- package/lib/commonjs/ui/primitives/Button.js +142 -0
- package/lib/commonjs/ui/primitives/Button.js.map +1 -0
- package/lib/commonjs/ui/primitives/Card.js +50 -0
- package/lib/commonjs/ui/primitives/Card.js.map +1 -0
- package/lib/commonjs/ui/primitives/Checkbox.js +139 -0
- package/lib/commonjs/ui/primitives/Checkbox.js.map +1 -0
- package/lib/commonjs/ui/primitives/CountrySelect.js +288 -0
- package/lib/commonjs/ui/primitives/CountrySelect.js.map +1 -0
- package/lib/commonjs/ui/primitives/DatePicker.js +245 -0
- package/lib/commonjs/ui/primitives/DatePicker.js.map +1 -0
- package/lib/commonjs/ui/primitives/Input.js +101 -0
- package/lib/commonjs/ui/primitives/Input.js.map +1 -0
- package/lib/commonjs/ui/primitives/Select.js +209 -0
- package/lib/commonjs/ui/primitives/Select.js.map +1 -0
- package/lib/commonjs/ui/primitives/Spinner.js +25 -0
- package/lib/commonjs/ui/primitives/Spinner.js.map +1 -0
- package/lib/commonjs/ui/primitives/index.js +69 -0
- package/lib/commonjs/ui/primitives/index.js.map +1 -0
- package/lib/commonjs/ui/theme/ThemeProvider.js +74 -0
- package/lib/commonjs/ui/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/ui/theme/index.js +68 -0
- package/lib/commonjs/ui/theme/index.js.map +1 -0
- package/lib/commonjs/ui/theme/tokens.js +154 -0
- package/lib/commonjs/ui/theme/tokens.js.map +1 -0
- package/lib/commonjs/utils/EventEmitter.js +144 -0
- package/lib/commonjs/utils/EventEmitter.js.map +1 -0
- package/lib/commonjs/utils/base64.js +53 -0
- package/lib/commonjs/utils/base64.js.map +1 -0
- package/lib/commonjs/utils/deviceFingerprint.js +132 -0
- package/lib/commonjs/utils/deviceFingerprint.js.map +1 -0
- package/lib/commonjs/utils/documentTypeOptions.js +35 -0
- package/lib/commonjs/utils/documentTypeOptions.js.map +1 -0
- package/lib/commonjs/utils/googleMapsPreflight.js +77 -0
- package/lib/commonjs/utils/googleMapsPreflight.js.map +1 -0
- package/lib/commonjs/utils/hmac.js +58 -0
- package/lib/commonjs/utils/hmac.js.map +1 -0
- package/lib/commonjs/utils/iso3166Countries.js +98 -0
- package/lib/commonjs/utils/iso3166Countries.js.map +1 -0
- package/lib/commonjs/utils/jpegFromUri.js +44 -0
- package/lib/commonjs/utils/jpegFromUri.js.map +1 -0
- package/lib/commonjs/utils/keepAwake.js +58 -0
- package/lib/commonjs/utils/keepAwake.js.map +1 -0
- package/lib/commonjs/utils/log.js +42 -0
- package/lib/commonjs/utils/log.js.map +1 -0
- package/lib/commonjs/utils/osGeocoder.js +70 -0
- package/lib/commonjs/utils/osGeocoder.js.map +1 -0
- package/lib/commonjs/utils/parseGoogleAddressComponents.js +74 -0
- package/lib/commonjs/utils/parseGoogleAddressComponents.js.map +1 -0
- package/lib/commonjs/utils/personNameNormalize.js +24 -0
- package/lib/commonjs/utils/personNameNormalize.js.map +1 -0
- package/lib/commonjs/utils/sdkError.js +34 -0
- package/lib/commonjs/utils/sdkError.js.map +1 -0
- package/lib/commonjs/utils/sdkVersion.js +13 -0
- package/lib/commonjs/utils/sdkVersion.js.map +1 -0
- package/lib/commonjs/utils/stepConfig.js +65 -0
- package/lib/commonjs/utils/stepConfig.js.map +1 -0
- package/lib/commonjs/utils/taxInfoConfig.js +19 -0
- package/lib/commonjs/utils/taxInfoConfig.js.map +1 -0
- package/lib/module/camera/AddressSearchBar.js +299 -0
- package/lib/module/camera/AddressSearchBar.js.map +1 -0
- package/lib/module/camera/DocumentCapture.js +500 -0
- package/lib/module/camera/DocumentCapture.js.map +1 -0
- package/lib/module/camera/LivenessCamera.js +529 -0
- package/lib/module/camera/LivenessCamera.js.map +1 -0
- package/lib/module/camera/MapAddressPicker.js +337 -0
- package/lib/module/camera/MapAddressPicker.js.map +1 -0
- package/lib/module/core/VelionOnboarding.js +811 -0
- package/lib/module/core/VelionOnboarding.js.map +1 -0
- package/lib/module/core/sessionDeclinedCopy.js +52 -0
- package/lib/module/core/sessionDeclinedCopy.js.map +1 -0
- package/lib/module/core/sessionStateMapper.js +128 -0
- package/lib/module/core/sessionStateMapper.js.map +1 -0
- package/lib/module/core/sseReasonMessages.js +446 -0
- package/lib/module/core/sseReasonMessages.js.map +1 -0
- package/lib/module/data/iso3166Alpha2Codes.json +1 -0
- package/lib/module/data/iso3166CountryNames.json +251 -0
- package/lib/module/i18n/index.js +25 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/strings/en.js +257 -0
- package/lib/module/i18n/strings/en.js.map +1 -0
- package/lib/module/i18n/strings/es.js +262 -0
- package/lib/module/i18n/strings/es.js.map +1 -0
- package/lib/module/index.js +36 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/steps/AddressInfoStep.js +646 -0
- package/lib/module/steps/AddressInfoStep.js.map +1 -0
- package/lib/module/steps/DocumentsOcrStep.js +391 -0
- package/lib/module/steps/DocumentsOcrStep.js.map +1 -0
- package/lib/module/steps/EmailContactStep.js +140 -0
- package/lib/module/steps/EmailContactStep.js.map +1 -0
- package/lib/module/steps/EmailOtpStep.js +215 -0
- package/lib/module/steps/EmailOtpStep.js.map +1 -0
- package/lib/module/steps/FaceMatchStep.js +161 -0
- package/lib/module/steps/FaceMatchStep.js.map +1 -0
- package/lib/module/steps/FingerprintStep.js +87 -0
- package/lib/module/steps/FingerprintStep.js.map +1 -0
- package/lib/module/steps/HumanBasicInfoStep.js +238 -0
- package/lib/module/steps/HumanBasicInfoStep.js.map +1 -0
- package/lib/module/steps/HumanExtendedInfoStep.js +263 -0
- package/lib/module/steps/HumanExtendedInfoStep.js.map +1 -0
- package/lib/module/steps/LegalBasicInfoStep.js +183 -0
- package/lib/module/steps/LegalBasicInfoStep.js.map +1 -0
- package/lib/module/steps/LegalExtendedInfoStep.js +161 -0
- package/lib/module/steps/LegalExtendedInfoStep.js.map +1 -0
- package/lib/module/steps/LivenessMatchStep.js +701 -0
- package/lib/module/steps/LivenessMatchStep.js.map +1 -0
- package/lib/module/steps/PhoneContactStep.js +141 -0
- package/lib/module/steps/PhoneContactStep.js.map +1 -0
- package/lib/module/steps/PhoneOtpStep.js +214 -0
- package/lib/module/steps/PhoneOtpStep.js.map +1 -0
- package/lib/module/steps/SwornDeclarationStep.js +191 -0
- package/lib/module/steps/SwornDeclarationStep.js.map +1 -0
- package/lib/module/steps/TaxInfoStep.js +239 -0
- package/lib/module/steps/TaxInfoStep.js.map +1 -0
- package/lib/module/steps/TermsAndConditionsStep.js +233 -0
- package/lib/module/steps/TermsAndConditionsStep.js.map +1 -0
- package/lib/module/steps/_shared.js +33 -0
- package/lib/module/steps/_shared.js.map +1 -0
- package/lib/module/steps/types.js +4 -0
- package/lib/module/steps/types.js.map +1 -0
- package/lib/module/transport/api.js +173 -0
- package/lib/module/transport/api.js.map +1 -0
- package/lib/module/transport/irisWebSocket.js +115 -0
- package/lib/module/transport/irisWebSocket.js.map +1 -0
- package/lib/module/transport/secureUrl.js +45 -0
- package/lib/module/transport/secureUrl.js.map +1 -0
- package/lib/module/transport/sse.js +242 -0
- package/lib/module/transport/sse.js.map +1 -0
- package/lib/module/types/index.js +457 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/ui/MapFallbackBoundary.js +37 -0
- package/lib/module/ui/MapFallbackBoundary.js.map +1 -0
- package/lib/module/ui/StepShell.js +114 -0
- package/lib/module/ui/StepShell.js.map +1 -0
- package/lib/module/ui/VelionOnboardingScreen.js +212 -0
- package/lib/module/ui/VelionOnboardingScreen.js.map +1 -0
- package/lib/module/ui/forms/index.js +5 -0
- package/lib/module/ui/forms/index.js.map +1 -0
- package/lib/module/ui/forms/useInlineValidation.js +84 -0
- package/lib/module/ui/forms/useInlineValidation.js.map +1 -0
- package/lib/module/ui/forms/validators.js +27 -0
- package/lib/module/ui/forms/validators.js.map +1 -0
- package/lib/module/ui/icons/HomeHeartIcon.js +33 -0
- package/lib/module/ui/icons/HomeHeartIcon.js.map +1 -0
- package/lib/module/ui/icons/StepIcon.js +55 -0
- package/lib/module/ui/icons/StepIcon.js.map +1 -0
- package/lib/module/ui/overlays/AnalyzingOverlay.js +279 -0
- package/lib/module/ui/overlays/AnalyzingOverlay.js.map +1 -0
- package/lib/module/ui/overlays/LoadingOverlay.js +104 -0
- package/lib/module/ui/overlays/LoadingOverlay.js.map +1 -0
- package/lib/module/ui/overlays/ProgressBar.js +90 -0
- package/lib/module/ui/overlays/ProgressBar.js.map +1 -0
- package/lib/module/ui/overlays/RetryDialog.js +121 -0
- package/lib/module/ui/overlays/RetryDialog.js.map +1 -0
- package/lib/module/ui/overlays/index.js +6 -0
- package/lib/module/ui/overlays/index.js.map +1 -0
- package/lib/module/ui/primitives/Banner.js +77 -0
- package/lib/module/ui/primitives/Banner.js.map +1 -0
- package/lib/module/ui/primitives/Button.js +138 -0
- package/lib/module/ui/primitives/Button.js.map +1 -0
- package/lib/module/ui/primitives/Card.js +46 -0
- package/lib/module/ui/primitives/Card.js.map +1 -0
- package/lib/module/ui/primitives/Checkbox.js +136 -0
- package/lib/module/ui/primitives/Checkbox.js.map +1 -0
- package/lib/module/ui/primitives/CountrySelect.js +284 -0
- package/lib/module/ui/primitives/CountrySelect.js.map +1 -0
- package/lib/module/ui/primitives/DatePicker.js +241 -0
- package/lib/module/ui/primitives/DatePicker.js.map +1 -0
- package/lib/module/ui/primitives/Input.js +97 -0
- package/lib/module/ui/primitives/Input.js.map +1 -0
- package/lib/module/ui/primitives/Select.js +205 -0
- package/lib/module/ui/primitives/Select.js.map +1 -0
- package/lib/module/ui/primitives/Spinner.js +21 -0
- package/lib/module/ui/primitives/Spinner.js.map +1 -0
- package/lib/module/ui/primitives/index.js +12 -0
- package/lib/module/ui/primitives/index.js.map +1 -0
- package/lib/module/ui/theme/ThemeProvider.js +67 -0
- package/lib/module/ui/theme/ThemeProvider.js.map +1 -0
- package/lib/module/ui/theme/index.js +5 -0
- package/lib/module/ui/theme/index.js.map +1 -0
- package/lib/module/ui/theme/tokens.js +145 -0
- package/lib/module/ui/theme/tokens.js.map +1 -0
- package/lib/module/utils/EventEmitter.js +139 -0
- package/lib/module/utils/EventEmitter.js.map +1 -0
- package/lib/module/utils/base64.js +47 -0
- package/lib/module/utils/base64.js.map +1 -0
- package/lib/module/utils/deviceFingerprint.js +129 -0
- package/lib/module/utils/deviceFingerprint.js.map +1 -0
- package/lib/module/utils/documentTypeOptions.js +31 -0
- package/lib/module/utils/documentTypeOptions.js.map +1 -0
- package/lib/module/utils/googleMapsPreflight.js +73 -0
- package/lib/module/utils/googleMapsPreflight.js.map +1 -0
- package/lib/module/utils/hmac.js +53 -0
- package/lib/module/utils/hmac.js.map +1 -0
- package/lib/module/utils/iso3166Countries.js +92 -0
- package/lib/module/utils/iso3166Countries.js.map +1 -0
- package/lib/module/utils/jpegFromUri.js +40 -0
- package/lib/module/utils/jpegFromUri.js.map +1 -0
- package/lib/module/utils/keepAwake.js +53 -0
- package/lib/module/utils/keepAwake.js.map +1 -0
- package/lib/module/utils/log.js +37 -0
- package/lib/module/utils/log.js.map +1 -0
- package/lib/module/utils/osGeocoder.js +65 -0
- package/lib/module/utils/osGeocoder.js.map +1 -0
- package/lib/module/utils/parseGoogleAddressComponents.js +69 -0
- package/lib/module/utils/parseGoogleAddressComponents.js.map +1 -0
- package/lib/module/utils/personNameNormalize.js +20 -0
- package/lib/module/utils/personNameNormalize.js.map +1 -0
- package/lib/module/utils/sdkError.js +29 -0
- package/lib/module/utils/sdkError.js.map +1 -0
- package/lib/module/utils/sdkVersion.js +9 -0
- package/lib/module/utils/sdkVersion.js.map +1 -0
- package/lib/module/utils/stepConfig.js +59 -0
- package/lib/module/utils/stepConfig.js.map +1 -0
- package/lib/module/utils/taxInfoConfig.js +15 -0
- package/lib/module/utils/taxInfoConfig.js.map +1 -0
- package/lib/typescript/camera/AddressSearchBar.d.ts +37 -0
- package/lib/typescript/camera/AddressSearchBar.d.ts.map +1 -0
- package/lib/typescript/camera/DocumentCapture.d.ts +34 -0
- package/lib/typescript/camera/DocumentCapture.d.ts.map +1 -0
- package/lib/typescript/camera/LivenessCamera.d.ts +50 -0
- package/lib/typescript/camera/LivenessCamera.d.ts.map +1 -0
- package/lib/typescript/camera/MapAddressPicker.d.ts +57 -0
- package/lib/typescript/camera/MapAddressPicker.d.ts.map +1 -0
- package/lib/typescript/core/VelionOnboarding.d.ts +115 -0
- package/lib/typescript/core/VelionOnboarding.d.ts.map +1 -0
- package/lib/typescript/core/sessionDeclinedCopy.d.ts +16 -0
- package/lib/typescript/core/sessionDeclinedCopy.d.ts.map +1 -0
- package/lib/typescript/core/sessionStateMapper.d.ts +33 -0
- package/lib/typescript/core/sessionStateMapper.d.ts.map +1 -0
- package/lib/typescript/core/sseReasonMessages.d.ts +20 -0
- package/lib/typescript/core/sseReasonMessages.d.ts.map +1 -0
- package/lib/typescript/i18n/index.d.ts +13 -0
- package/lib/typescript/i18n/index.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/en.d.ts +3 -0
- package/lib/typescript/i18n/strings/en.d.ts.map +1 -0
- package/lib/typescript/i18n/strings/es.d.ts +260 -0
- package/lib/typescript/i18n/strings/es.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +26 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/steps/AddressInfoStep.d.ts +26 -0
- package/lib/typescript/steps/AddressInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/DocumentsOcrStep.d.ts +26 -0
- package/lib/typescript/steps/DocumentsOcrStep.d.ts.map +1 -0
- package/lib/typescript/steps/EmailContactStep.d.ts +15 -0
- package/lib/typescript/steps/EmailContactStep.d.ts.map +1 -0
- package/lib/typescript/steps/EmailOtpStep.d.ts +21 -0
- package/lib/typescript/steps/EmailOtpStep.d.ts.map +1 -0
- package/lib/typescript/steps/FaceMatchStep.d.ts +27 -0
- package/lib/typescript/steps/FaceMatchStep.d.ts.map +1 -0
- package/lib/typescript/steps/FingerprintStep.d.ts +25 -0
- package/lib/typescript/steps/FingerprintStep.d.ts.map +1 -0
- package/lib/typescript/steps/HumanBasicInfoStep.d.ts +25 -0
- package/lib/typescript/steps/HumanBasicInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/HumanExtendedInfoStep.d.ts +23 -0
- package/lib/typescript/steps/HumanExtendedInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/LegalBasicInfoStep.d.ts +17 -0
- package/lib/typescript/steps/LegalBasicInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/LegalExtendedInfoStep.d.ts +17 -0
- package/lib/typescript/steps/LegalExtendedInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/LivenessMatchStep.d.ts +26 -0
- package/lib/typescript/steps/LivenessMatchStep.d.ts.map +1 -0
- package/lib/typescript/steps/PhoneContactStep.d.ts +15 -0
- package/lib/typescript/steps/PhoneContactStep.d.ts.map +1 -0
- package/lib/typescript/steps/PhoneOtpStep.d.ts +19 -0
- package/lib/typescript/steps/PhoneOtpStep.d.ts.map +1 -0
- package/lib/typescript/steps/SwornDeclarationStep.d.ts +20 -0
- package/lib/typescript/steps/SwornDeclarationStep.d.ts.map +1 -0
- package/lib/typescript/steps/TaxInfoStep.d.ts +19 -0
- package/lib/typescript/steps/TaxInfoStep.d.ts.map +1 -0
- package/lib/typescript/steps/TermsAndConditionsStep.d.ts +21 -0
- package/lib/typescript/steps/TermsAndConditionsStep.d.ts.map +1 -0
- package/lib/typescript/steps/_shared.d.ts +11 -0
- package/lib/typescript/steps/_shared.d.ts.map +1 -0
- package/lib/typescript/steps/types.d.ts +68 -0
- package/lib/typescript/steps/types.d.ts.map +1 -0
- package/lib/typescript/transport/api.d.ts +35 -0
- package/lib/typescript/transport/api.d.ts.map +1 -0
- package/lib/typescript/transport/irisWebSocket.d.ts +72 -0
- package/lib/typescript/transport/irisWebSocket.d.ts.map +1 -0
- package/lib/typescript/transport/secureUrl.d.ts +14 -0
- package/lib/typescript/transport/secureUrl.d.ts.map +1 -0
- package/lib/typescript/transport/sse.d.ts +54 -0
- package/lib/typescript/transport/sse.d.ts.map +1 -0
- package/lib/typescript/types/index.d.ts +1010 -0
- package/lib/typescript/types/index.d.ts.map +1 -0
- package/lib/typescript/ui/MapFallbackBoundary.d.ts +28 -0
- package/lib/typescript/ui/MapFallbackBoundary.d.ts.map +1 -0
- package/lib/typescript/ui/StepShell.d.ts +19 -0
- package/lib/typescript/ui/StepShell.d.ts.map +1 -0
- package/lib/typescript/ui/VelionOnboardingScreen.d.ts +19 -0
- package/lib/typescript/ui/VelionOnboardingScreen.d.ts.map +1 -0
- package/lib/typescript/ui/forms/index.d.ts +3 -0
- package/lib/typescript/ui/forms/index.d.ts.map +1 -0
- package/lib/typescript/ui/forms/useInlineValidation.d.ts +30 -0
- package/lib/typescript/ui/forms/useInlineValidation.d.ts.map +1 -0
- package/lib/typescript/ui/forms/validators.d.ts +11 -0
- package/lib/typescript/ui/forms/validators.d.ts.map +1 -0
- package/lib/typescript/ui/icons/HomeHeartIcon.d.ts +14 -0
- package/lib/typescript/ui/icons/HomeHeartIcon.d.ts.map +1 -0
- package/lib/typescript/ui/icons/StepIcon.d.ts +26 -0
- package/lib/typescript/ui/icons/StepIcon.d.ts.map +1 -0
- package/lib/typescript/ui/overlays/AnalyzingOverlay.d.ts +24 -0
- package/lib/typescript/ui/overlays/AnalyzingOverlay.d.ts.map +1 -0
- package/lib/typescript/ui/overlays/LoadingOverlay.d.ts +19 -0
- package/lib/typescript/ui/overlays/LoadingOverlay.d.ts.map +1 -0
- package/lib/typescript/ui/overlays/ProgressBar.d.ts +26 -0
- package/lib/typescript/ui/overlays/ProgressBar.d.ts.map +1 -0
- package/lib/typescript/ui/overlays/RetryDialog.d.ts +17 -0
- package/lib/typescript/ui/overlays/RetryDialog.d.ts.map +1 -0
- package/lib/typescript/ui/overlays/index.d.ts +4 -0
- package/lib/typescript/ui/overlays/index.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Banner.d.ts +11 -0
- package/lib/typescript/ui/primitives/Banner.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Button.d.ts +27 -0
- package/lib/typescript/ui/primitives/Button.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Card.d.ts +10 -0
- package/lib/typescript/ui/primitives/Card.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Checkbox.d.ts +25 -0
- package/lib/typescript/ui/primitives/Checkbox.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/CountrySelect.d.ts +31 -0
- package/lib/typescript/ui/primitives/CountrySelect.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/DatePicker.d.ts +42 -0
- package/lib/typescript/ui/primitives/DatePicker.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Input.d.ts +17 -0
- package/lib/typescript/ui/primitives/Input.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Select.d.ts +26 -0
- package/lib/typescript/ui/primitives/Select.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/Spinner.d.ts +10 -0
- package/lib/typescript/ui/primitives/Spinner.d.ts.map +1 -0
- package/lib/typescript/ui/primitives/index.d.ts +10 -0
- package/lib/typescript/ui/primitives/index.d.ts.map +1 -0
- package/lib/typescript/ui/theme/ThemeProvider.d.ts +23 -0
- package/lib/typescript/ui/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/ui/theme/index.d.ts +3 -0
- package/lib/typescript/ui/theme/index.d.ts.map +1 -0
- package/lib/typescript/ui/theme/tokens.d.ts +42 -0
- package/lib/typescript/ui/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/utils/EventEmitter.d.ts +98 -0
- package/lib/typescript/utils/EventEmitter.d.ts.map +1 -0
- package/lib/typescript/utils/base64.d.ts +19 -0
- package/lib/typescript/utils/base64.d.ts.map +1 -0
- package/lib/typescript/utils/deviceFingerprint.d.ts +42 -0
- package/lib/typescript/utils/deviceFingerprint.d.ts.map +1 -0
- package/lib/typescript/utils/documentTypeOptions.d.ts +13 -0
- package/lib/typescript/utils/documentTypeOptions.d.ts.map +1 -0
- package/lib/typescript/utils/googleMapsPreflight.d.ts +44 -0
- package/lib/typescript/utils/googleMapsPreflight.d.ts.map +1 -0
- package/lib/typescript/utils/hmac.d.ts +39 -0
- package/lib/typescript/utils/hmac.d.ts.map +1 -0
- package/lib/typescript/utils/iso3166Countries.d.ts +27 -0
- package/lib/typescript/utils/iso3166Countries.d.ts.map +1 -0
- package/lib/typescript/utils/jpegFromUri.d.ts +29 -0
- package/lib/typescript/utils/jpegFromUri.d.ts.map +1 -0
- package/lib/typescript/utils/keepAwake.d.ts +16 -0
- package/lib/typescript/utils/keepAwake.d.ts.map +1 -0
- package/lib/typescript/utils/log.d.ts +18 -0
- package/lib/typescript/utils/log.d.ts.map +1 -0
- package/lib/typescript/utils/osGeocoder.d.ts +38 -0
- package/lib/typescript/utils/osGeocoder.d.ts.map +1 -0
- package/lib/typescript/utils/parseGoogleAddressComponents.d.ts +43 -0
- package/lib/typescript/utils/parseGoogleAddressComponents.d.ts.map +1 -0
- package/lib/typescript/utils/personNameNormalize.d.ts +10 -0
- package/lib/typescript/utils/personNameNormalize.d.ts.map +1 -0
- package/lib/typescript/utils/sdkError.d.ts +14 -0
- package/lib/typescript/utils/sdkError.d.ts.map +1 -0
- package/lib/typescript/utils/sdkVersion.d.ts +7 -0
- package/lib/typescript/utils/sdkVersion.d.ts.map +1 -0
- package/lib/typescript/utils/stepConfig.d.ts +8 -0
- package/lib/typescript/utils/stepConfig.d.ts.map +1 -0
- package/lib/typescript/utils/taxInfoConfig.d.ts +7 -0
- package/lib/typescript/utils/taxInfoConfig.d.ts.map +1 -0
- package/package.json +99 -0
- package/src/camera/AddressSearchBar.tsx +363 -0
- package/src/camera/DocumentCapture.tsx +505 -0
- package/src/camera/LivenessCamera.tsx +602 -0
- package/src/camera/MapAddressPicker.tsx +397 -0
- package/src/core/VelionOnboarding.ts +974 -0
- package/src/core/sessionDeclinedCopy.ts +76 -0
- package/src/core/sessionStateMapper.ts +167 -0
- package/src/core/sseReasonMessages.ts +531 -0
- package/src/data/iso3166Alpha2Codes.json +1 -0
- package/src/data/iso3166CountryNames.json +251 -0
- package/src/i18n/index.ts +26 -0
- package/src/i18n/strings/en.ts +289 -0
- package/src/i18n/strings/es.ts +291 -0
- package/src/index.ts +137 -0
- package/src/steps/AddressInfoStep.tsx +726 -0
- package/src/steps/DocumentsOcrStep.tsx +472 -0
- package/src/steps/EmailContactStep.tsx +159 -0
- package/src/steps/EmailOtpStep.tsx +250 -0
- package/src/steps/FaceMatchStep.tsx +177 -0
- package/src/steps/FingerprintStep.tsx +99 -0
- package/src/steps/HumanBasicInfoStep.tsx +274 -0
- package/src/steps/HumanExtendedInfoStep.tsx +353 -0
- package/src/steps/LegalBasicInfoStep.tsx +205 -0
- package/src/steps/LegalExtendedInfoStep.tsx +171 -0
- package/src/steps/LivenessMatchStep.tsx +846 -0
- package/src/steps/PhoneContactStep.tsx +160 -0
- package/src/steps/PhoneOtpStep.tsx +249 -0
- package/src/steps/SwornDeclarationStep.tsx +220 -0
- package/src/steps/TaxInfoStep.tsx +277 -0
- package/src/steps/TermsAndConditionsStep.tsx +261 -0
- package/src/steps/_shared.ts +44 -0
- package/src/steps/types.ts +72 -0
- package/src/transport/api.ts +257 -0
- package/src/transport/irisWebSocket.ts +186 -0
- package/src/transport/secureUrl.ts +47 -0
- package/src/transport/sse.ts +310 -0
- package/src/types/index.ts +1198 -0
- package/src/ui/MapFallbackBoundary.tsx +46 -0
- package/src/ui/StepShell.tsx +137 -0
- package/src/ui/VelionOnboardingScreen.tsx +223 -0
- package/src/ui/forms/index.ts +12 -0
- package/src/ui/forms/useInlineValidation.ts +115 -0
- package/src/ui/forms/validators.ts +29 -0
- package/src/ui/icons/HomeHeartIcon.tsx +34 -0
- package/src/ui/icons/StepIcon.tsx +77 -0
- package/src/ui/overlays/AnalyzingOverlay.tsx +323 -0
- package/src/ui/overlays/LoadingOverlay.tsx +115 -0
- package/src/ui/overlays/ProgressBar.tsx +99 -0
- package/src/ui/overlays/RetryDialog.tsx +128 -0
- package/src/ui/overlays/index.ts +3 -0
- package/src/ui/primitives/Banner.tsx +81 -0
- package/src/ui/primitives/Button.tsx +164 -0
- package/src/ui/primitives/Card.tsx +55 -0
- package/src/ui/primitives/Checkbox.tsx +153 -0
- package/src/ui/primitives/CountrySelect.tsx +356 -0
- package/src/ui/primitives/DatePicker.tsx +266 -0
- package/src/ui/primitives/Input.tsx +110 -0
- package/src/ui/primitives/Select.tsx +259 -0
- package/src/ui/primitives/Spinner.tsx +17 -0
- package/src/ui/primitives/index.ts +9 -0
- package/src/ui/theme/ThemeProvider.tsx +102 -0
- package/src/ui/theme/index.ts +17 -0
- package/src/ui/theme/tokens.ts +159 -0
- package/src/utils/EventEmitter.ts +155 -0
- package/src/utils/base64.ts +44 -0
- package/src/utils/deviceFingerprint.ts +184 -0
- package/src/utils/documentTypeOptions.ts +31 -0
- package/src/utils/googleMapsPreflight.ts +72 -0
- package/src/utils/hmac.ts +61 -0
- package/src/utils/iso3166Countries.ts +111 -0
- package/src/utils/jpegFromUri.ts +42 -0
- package/src/utils/keepAwake.ts +62 -0
- package/src/utils/log.ts +37 -0
- package/src/utils/osGeocoder.ts +75 -0
- package/src/utils/parseGoogleAddressComponents.ts +123 -0
- package/src/utils/personNameNormalize.ts +17 -0
- package/src/utils/sdkError.ts +40 -0
- package/src/utils/sdkVersion.ts +6 -0
- package/src/utils/stepConfig.ts +75 -0
- package/src/utils/taxInfoConfig.ts +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,803 @@
|
|
|
1
|
+
# Velion Onboarding SDK — React Native
|
|
2
|
+
|
|
3
|
+
`@velion-la/onboarding-sdk-react-native` is the native React Native SDK that
|
|
4
|
+
runs the complete Velion KYC flow inside an iOS or Android app:
|
|
5
|
+
|
|
6
|
+
- Device fingerprint.
|
|
7
|
+
- Personal / legal information forms.
|
|
8
|
+
- Email and SMS OTP.
|
|
9
|
+
- Sworn declaration and terms & conditions.
|
|
10
|
+
- Document OCR (front + back) with a native camera.
|
|
11
|
+
- Active liveness with face mesh challenges.
|
|
12
|
+
- Face match against the captured ID document.
|
|
13
|
+
- Optional map-assisted address picker.
|
|
14
|
+
|
|
15
|
+
The SDK uses the same Onboarding backend contract (REST + SSE events + step
|
|
16
|
+
state machine) as Velion's web SDK and adds a fully native UI and camera.
|
|
17
|
+
|
|
18
|
+
## Table of contents
|
|
19
|
+
|
|
20
|
+
- [Quickstart](#quickstart)
|
|
21
|
+
- [Installation](#installation)
|
|
22
|
+
- [Native setup](#native-setup)
|
|
23
|
+
- [Permissions](#permissions)
|
|
24
|
+
- [Using the component](#using-the-component)
|
|
25
|
+
- [`VelionConfig`](#velionconfig)
|
|
26
|
+
- [Callbacks](#callbacks)
|
|
27
|
+
- [Theming](#theming)
|
|
28
|
+
- [Locales](#locales)
|
|
29
|
+
- [Errors](#errors)
|
|
30
|
+
- [Assisted address mode (Google Maps)](#assisted-address-mode-google-maps)
|
|
31
|
+
- [Supported steps](#supported-steps)
|
|
32
|
+
- [Stack and architecture](#stack-and-architecture)
|
|
33
|
+
- [Local development](#local-development)
|
|
34
|
+
- [Publishing](#publishing)
|
|
35
|
+
- [License](#license)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { VelionOnboardingScreen } from '@velion-la/onboarding-sdk-react-native';
|
|
43
|
+
|
|
44
|
+
export function KycScreen({ navigation }) {
|
|
45
|
+
return (
|
|
46
|
+
<VelionOnboardingScreen
|
|
47
|
+
config={{
|
|
48
|
+
sessionId: 'ses_abc123', // returned by your backend
|
|
49
|
+
sessionToken: 'eyJ...', // returned by your backend
|
|
50
|
+
apiUrl: 'https://api.velion.la/gateway/api/v1/onboarding/public/sdk',
|
|
51
|
+
locale: 'es',
|
|
52
|
+
colorMode: 'auto',
|
|
53
|
+
onSuccess: (result) => console.log('done', result.status),
|
|
54
|
+
onError: (err) => console.error(err.code, err.message),
|
|
55
|
+
}}
|
|
56
|
+
onComplete={(result) => navigation.replace('Home', { kyc: result })}
|
|
57
|
+
onFail={() => navigation.goBack()}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The component is full-screen and takes care of:
|
|
64
|
+
|
|
65
|
+
1. Loading the session (`GET /sessions/:id`).
|
|
66
|
+
2. Opening the SSE stream for backend-driven events.
|
|
67
|
+
3. Rendering each step requested by the backend in order.
|
|
68
|
+
4. Resolving the flow at the end (`onSuccess` / `onError`).
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
### 1. The SDK
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm install @velion-la/onboarding-sdk-react-native
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 2. Required peer dependencies
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npm install \
|
|
84
|
+
react-native-vision-camera \
|
|
85
|
+
react-native-svg \
|
|
86
|
+
react-native-sse \
|
|
87
|
+
expo-application expo-crypto expo-device expo-image-manipulator expo-keep-awake expo-location \
|
|
88
|
+
@noble/hashes
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Optional peer dependencies (assisted address mode)
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm install react-native-maps
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
When `react-native-maps` is not installed, the `ADDRESS_INFO` step falls back
|
|
98
|
+
to a manual form and nothing else is required. The SDK does **not** depend on
|
|
99
|
+
`react-native-google-places-autocomplete`; the address search uses the
|
|
100
|
+
OS-native geocoder via `expo-location`.
|
|
101
|
+
|
|
102
|
+
### Supported versions
|
|
103
|
+
|
|
104
|
+
| Package | Minimum | Tested against |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| `react` | `>=19.0.0` | `19.1.0` |
|
|
107
|
+
| `react-native` | `>=0.81.0` | `0.81.5` |
|
|
108
|
+
| `expo` | `>=54.0.0` | `~54.0.34` |
|
|
109
|
+
| `react-native-vision-camera` | `>=4.6.0` | `4.7.x` |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Native setup
|
|
114
|
+
|
|
115
|
+
Vision Camera **does not run inside Expo Go**. Your app must have the `ios/`
|
|
116
|
+
and `android/` folders generated (either a bare React Native project or
|
|
117
|
+
`npx expo prebuild`).
|
|
118
|
+
|
|
119
|
+
### Expo plugins (`app.json` / `app.config.js`)
|
|
120
|
+
|
|
121
|
+
```jsonc
|
|
122
|
+
{
|
|
123
|
+
"expo": {
|
|
124
|
+
"plugins": [
|
|
125
|
+
"expo-dev-client",
|
|
126
|
+
[
|
|
127
|
+
"react-native-vision-camera",
|
|
128
|
+
{
|
|
129
|
+
"cameraPermissionText": "$(PRODUCT_NAME) needs access to your camera to capture your ID document and run the liveness check.",
|
|
130
|
+
"enableMicrophonePermission": false,
|
|
131
|
+
"enableCodeScanner": false
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
[
|
|
135
|
+
"expo-location",
|
|
136
|
+
{
|
|
137
|
+
"locationWhenInUsePermission": "We use your location to suggest your home address."
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> Do **not** include `"expo-image-manipulator"` in `plugins[]`. From Expo SDK
|
|
146
|
+
> 54 onwards it is a runtime-only module, not a config plugin.
|
|
147
|
+
|
|
148
|
+
Then run:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx expo prebuild --clean
|
|
152
|
+
npx expo run:ios # or run:android
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Bare React Native (no Expo)
|
|
156
|
+
|
|
157
|
+
Follow each library's own setup guide:
|
|
158
|
+
|
|
159
|
+
- Vision Camera: <https://react-native-vision-camera.com/docs/guides>
|
|
160
|
+
- React Native Maps (only if used): <https://github.com/react-native-maps/react-native-maps#installation>
|
|
161
|
+
- Expo modules inside a bare project: <https://docs.expo.dev/bare/installing-expo-modules/>
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Permissions
|
|
166
|
+
|
|
167
|
+
### iOS — `Info.plist`
|
|
168
|
+
|
|
169
|
+
```xml
|
|
170
|
+
<key>NSCameraUsageDescription</key>
|
|
171
|
+
<string>We need access to your camera to capture your ID document and run the liveness check.</string>
|
|
172
|
+
|
|
173
|
+
<!-- Only when googleMapsApiKey is set -->
|
|
174
|
+
<key>NSLocationWhenInUseUsageDescription</key>
|
|
175
|
+
<string>We use your location to suggest your home address.</string>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
With Expo, the Vision Camera and `expo-location` plugins inject these
|
|
179
|
+
automatically from `app.json`.
|
|
180
|
+
|
|
181
|
+
### Android — `AndroidManifest.xml`
|
|
182
|
+
|
|
183
|
+
```xml
|
|
184
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
185
|
+
|
|
186
|
+
<!-- Only when googleMapsApiKey is set -->
|
|
187
|
+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
188
|
+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
With Expo, declare them in `app.json`:
|
|
192
|
+
|
|
193
|
+
```jsonc
|
|
194
|
+
{
|
|
195
|
+
"expo": {
|
|
196
|
+
"android": {
|
|
197
|
+
"permissions": [
|
|
198
|
+
"android.permission.CAMERA",
|
|
199
|
+
"android.permission.ACCESS_COARSE_LOCATION",
|
|
200
|
+
"android.permission.ACCESS_FINE_LOCATION"
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Using the component
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
import {
|
|
213
|
+
VelionOnboardingScreen,
|
|
214
|
+
type VelionConfig,
|
|
215
|
+
type OnboardingResult,
|
|
216
|
+
type SdkError,
|
|
217
|
+
} from '@velion-la/onboarding-sdk-react-native';
|
|
218
|
+
|
|
219
|
+
const config: VelionConfig = {
|
|
220
|
+
sessionId: '<sessionId from your backend>',
|
|
221
|
+
sessionToken: '<sessionToken from your backend>',
|
|
222
|
+
apiUrl: 'https://<your-host>/public/sdk',
|
|
223
|
+
locale: 'es',
|
|
224
|
+
colorMode: 'auto',
|
|
225
|
+
onSuccess: (result) => { /* flow completed */ },
|
|
226
|
+
onError: (err) => { /* flow failed */ },
|
|
227
|
+
onStepChange: (step, idx) => { /* analytics */ },
|
|
228
|
+
onStepComplete: (step) => { /* analytics */ },
|
|
229
|
+
onSessionEvent: (evt) => { /* raw SSE events */ },
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
<VelionOnboardingScreen
|
|
233
|
+
config={config}
|
|
234
|
+
onComplete={(result) => navigation.replace('Home')}
|
|
235
|
+
onFail={(err) => navigation.goBack()}
|
|
236
|
+
/>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Lifecycle
|
|
240
|
+
|
|
241
|
+
| Event | When it fires |
|
|
242
|
+
|---|---|
|
|
243
|
+
| Mount | The SDK opens the session, connects SSE, and starts the first step. |
|
|
244
|
+
| `onStepChange` | The orchestrator transitions into a new step. |
|
|
245
|
+
| `onStepComplete` | The current step was successfully submitted. |
|
|
246
|
+
| `onSessionEvent` | Every SSE event received (useful for debugging). |
|
|
247
|
+
| `onSuccess` / `onComplete` | The flow finished: `APPROVED`, `MANUAL_REVIEW`, `REJECTED` or `DECLINED`. |
|
|
248
|
+
| `onError` / `onFail` | Unrecoverable error (token expired, fatal network error, backend decline, …). |
|
|
249
|
+
| Unmount | The SDK aborts in-flight requests, closes SSE, and releases the camera. |
|
|
250
|
+
|
|
251
|
+
> Use the component props `onComplete` / `onFail` **or** the config callbacks
|
|
252
|
+
> `onSuccess` / `onError`. Both do the same thing. The config callbacks are
|
|
253
|
+
> exposed for imperative integrations as well.
|
|
254
|
+
|
|
255
|
+
### Manual dismissal (modal usage)
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
function KycModal({ visible, onClose }) {
|
|
259
|
+
return (
|
|
260
|
+
<Modal visible={visible} onRequestClose={onClose}>
|
|
261
|
+
<VelionOnboardingScreen config={config} onComplete={onClose} onFail={onClose} />
|
|
262
|
+
</Modal>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
When the modal unmounts, the SDK runs its internal cleanup automatically
|
|
268
|
+
(aborts in-flight `fetch` calls, closes SSE, releases the camera).
|
|
269
|
+
|
|
270
|
+
### Imperative usage (advanced)
|
|
271
|
+
|
|
272
|
+
If you need to control the lifecycle outside React (custom navigation
|
|
273
|
+
container, headless mode, etc.):
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { VelionOnboarding } from '@velion-la/onboarding-sdk-react-native';
|
|
277
|
+
|
|
278
|
+
const sdk = new VelionOnboarding(config);
|
|
279
|
+
sdk.attachView({
|
|
280
|
+
setLoading: (text) => /* show overlay */,
|
|
281
|
+
setStepNode: (node) => /* render the step UI */,
|
|
282
|
+
setError: (err) => /* show error */,
|
|
283
|
+
setResult: (r) => /* show result */,
|
|
284
|
+
});
|
|
285
|
+
await sdk.start();
|
|
286
|
+
// …later:
|
|
287
|
+
sdk.destroy();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`<VelionOnboardingScreen>` is a thin wrapper over this API.
|
|
291
|
+
|
|
292
|
+
### Mount once per session
|
|
293
|
+
|
|
294
|
+
`<VelionOnboardingScreen>` opens an SSE stream and drives a state machine on
|
|
295
|
+
mount. If React unmounts and remounts the component, the SDK starts a fresh
|
|
296
|
+
session, re-opens SSE, and discards in-memory progress. To avoid this:
|
|
297
|
+
|
|
298
|
+
- Keep `config.sessionId` and `config.apiUrl` stable. The SDK uses them as
|
|
299
|
+
identity; changing either tears down the inner instance and starts over
|
|
300
|
+
(intentional, to support session rotation).
|
|
301
|
+
- Don't declare component wrappers (Provider, layout, frame) inside the body
|
|
302
|
+
of your screen. A new function on each render is a new component type for
|
|
303
|
+
React and forces the entire subtree to unmount.
|
|
304
|
+
- If your `config` includes dynamic callbacks, memoize it with `useMemo` or
|
|
305
|
+
stash the callbacks in a `useRef` to avoid identity churn.
|
|
306
|
+
- Don't pass a `key` that changes per render.
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
import { useMemo, useRef } from 'react';
|
|
310
|
+
import { VelionOnboardingScreen } from '@velion-la/onboarding-sdk-react-native';
|
|
311
|
+
|
|
312
|
+
export function KycScreen({ sessionId, sessionToken, navigation }) {
|
|
313
|
+
const navRef = useRef(navigation);
|
|
314
|
+
navRef.current = navigation;
|
|
315
|
+
|
|
316
|
+
const config = useMemo(
|
|
317
|
+
() => ({
|
|
318
|
+
sessionId,
|
|
319
|
+
sessionToken,
|
|
320
|
+
locale: 'es',
|
|
321
|
+
onSuccess: (result) => navRef.current.replace('Home', { kyc: result }),
|
|
322
|
+
onError: () => navRef.current.goBack(),
|
|
323
|
+
}),
|
|
324
|
+
[sessionId, sessionToken],
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
return <VelionOnboardingScreen config={config} />;
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Symptom of a misconfigured mount: repeated `[SSE] Opening stream` log lines
|
|
332
|
+
every few hundred milliseconds, or the first step (typically
|
|
333
|
+
`DEVICE_FINGERPRINT`) never completing.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## `VelionConfig`
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
interface VelionConfig {
|
|
341
|
+
// Session
|
|
342
|
+
sessionId: string; // generated by your backend
|
|
343
|
+
sessionToken: string; // bearer token for this session
|
|
344
|
+
apiUrl: string; // base URL ending in `/public/sdk`
|
|
345
|
+
expiresAt?: string; // ISO-8601, optional client-side check
|
|
346
|
+
|
|
347
|
+
// UI
|
|
348
|
+
locale?: 'es' | 'en';
|
|
349
|
+
colorMode?: 'light' | 'dark' | 'auto';
|
|
350
|
+
theme?: VelionTheme;
|
|
351
|
+
showProgressBar?: boolean;
|
|
352
|
+
showFinalResultScreen?: boolean;
|
|
353
|
+
finalResultScreenTexts?: VelionFinalResultScreenTexts;
|
|
354
|
+
sessionDeclinedReasonTexts?: VelionSessionDeclinedReasonTexts;
|
|
355
|
+
|
|
356
|
+
// Liveness
|
|
357
|
+
livenessShowIntro?: boolean; // default true
|
|
358
|
+
livenessShowBackButton?: boolean; // default true
|
|
359
|
+
|
|
360
|
+
// Address (assisted)
|
|
361
|
+
googleMapsApiKey?: string;
|
|
362
|
+
|
|
363
|
+
// Fingerprint
|
|
364
|
+
fingerprintEndpoint?: string;
|
|
365
|
+
fingerprintApiKey?: string;
|
|
366
|
+
fingerprintTimeoutMs?: number;
|
|
367
|
+
|
|
368
|
+
// Debug
|
|
369
|
+
debug?: boolean;
|
|
370
|
+
|
|
371
|
+
// Callbacks
|
|
372
|
+
onSuccess?: (result: OnboardingResult) => void;
|
|
373
|
+
onError?: (err: SdkError) => void;
|
|
374
|
+
onStepChange?: (step: OnboardingStep, index: number) => void;
|
|
375
|
+
onStepComplete?: (step: OnboardingStep) => void;
|
|
376
|
+
onSessionEvent?: (event: OnboardingSessionEvent) => void;
|
|
377
|
+
onFinalResultScreenDismiss?: () => void;
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Critical fields
|
|
382
|
+
|
|
383
|
+
- **`apiUrl`** must be HTTPS (or `http://localhost:*` for development). The
|
|
384
|
+
SDK refuses insecure URLs so the `sessionToken` is never sent in cleartext.
|
|
385
|
+
- **`sessionId` + `sessionToken`** are issued by your backend when the
|
|
386
|
+
session is created. The token is single-use for that session.
|
|
387
|
+
- **`apiUrl`** must end with `/public/sdk`; all relative endpoints are
|
|
388
|
+
resolved against it.
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Callbacks
|
|
393
|
+
|
|
394
|
+
```ts
|
|
395
|
+
onSuccess: (result: OnboardingResult) => void;
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
interface OnboardingResult {
|
|
400
|
+
sessionId: string;
|
|
401
|
+
completedAt: string; // ISO-8601
|
|
402
|
+
status: 'APPROVED' | 'MANUAL_REVIEW' | 'REJECTED' | 'DECLINED';
|
|
403
|
+
referenceId?: string; // for support / audit trail
|
|
404
|
+
terminalReason?: string; // backend-supplied reason
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
onError: (err: SdkError) => void;
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
```ts
|
|
413
|
+
interface SdkError {
|
|
414
|
+
code: SdkErrorCode;
|
|
415
|
+
message: string;
|
|
416
|
+
declineReason?: string; // when code === SESSION_DECLINED
|
|
417
|
+
stepCode?: string;
|
|
418
|
+
declineTitle?: string; // localized copy
|
|
419
|
+
declineMessage?: string;
|
|
420
|
+
cameraCode?: CameraErrorCode;
|
|
421
|
+
httpStatus?: number;
|
|
422
|
+
cause?: unknown;
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Possible `SdkErrorCode` values:
|
|
427
|
+
|
|
428
|
+
| Code | When |
|
|
429
|
+
|---|---|
|
|
430
|
+
| `SESSION_INVALID` | Token rejected (403). |
|
|
431
|
+
| `SESSION_EXPIRED` | Token expired (401) — request a fresh one. |
|
|
432
|
+
| `SESSION_FETCH_FAILED` | Could not load the initial session. |
|
|
433
|
+
| `SESSION_DECLINED` | Backend sent `SESSION_DECLINED` over SSE. |
|
|
434
|
+
| `FINGERPRINT_FAILED` | Visitor id could not be generated. |
|
|
435
|
+
| `DOCUMENT_UPLOAD_FAILED` | `PUT` to the signed URL or `verify` step failed. |
|
|
436
|
+
| `LIVENESS_FAILED` | Liveness service closed the WebSocket with a terminal warning. |
|
|
437
|
+
| `LIVENESS_INIT_FAILED` | `/liveness-init` failed. |
|
|
438
|
+
| `CAMERA_ERROR` | Camera denied or unavailable. |
|
|
439
|
+
| `NETWORK_ERROR` | Connectivity lost. |
|
|
440
|
+
| `API_ERROR` | Backend returned 5xx or an unexpected response. |
|
|
441
|
+
| `ALREADY_STARTED`, `INSTANCE_DESTROYED` | Lifecycle misuse. |
|
|
442
|
+
| `UNKNOWN` | Anything else. |
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
onStepChange: (step: OnboardingStep, index: number) => void;
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
`step` is one of `'DEVICE_FINGERPRINT' | 'HUMAN_BASIC_INFO' | 'EMAIL_OTP' | …`
|
|
449
|
+
(see [Supported steps](#supported-steps)).
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
onSessionEvent: (event: OnboardingSessionEvent) => void;
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
You receive every raw SSE event for analytics or debugging. The SDK already
|
|
456
|
+
handles everything internally; this callback is optional.
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Theming
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
import type { VelionTheme } from '@velion-la/onboarding-sdk-react-native';
|
|
464
|
+
|
|
465
|
+
const theme: VelionTheme = {
|
|
466
|
+
primaryColor: '#0052CC',
|
|
467
|
+
secondaryColor: '#1D4ED8',
|
|
468
|
+
backgroundColor: '#FFFFFF',
|
|
469
|
+
textColor: '#111827',
|
|
470
|
+
textSecondaryColor: '#6B7280',
|
|
471
|
+
errorColor: '#DC2626',
|
|
472
|
+
successColor: '#16A34A',
|
|
473
|
+
warningColor: '#D97706',
|
|
474
|
+
borderColor: '#E5E7EB',
|
|
475
|
+
borderRadius: '8px',
|
|
476
|
+
fontFamily: 'System',
|
|
477
|
+
hideStepIcons: false, // hide the colored round icon next to step titles
|
|
478
|
+
hideProgressBar: false, // hide the sticky top progress bar
|
|
479
|
+
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Layout switches
|
|
483
|
+
|
|
484
|
+
`VelionTheme` exposes two layout flags controlled alongside the visual theme:
|
|
485
|
+
|
|
486
|
+
```tsx
|
|
487
|
+
config={{
|
|
488
|
+
...config,
|
|
489
|
+
theme: {
|
|
490
|
+
...theme,
|
|
491
|
+
hideStepIcons: true,
|
|
492
|
+
hideProgressBar: true,
|
|
493
|
+
},
|
|
494
|
+
}}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Equivalences:
|
|
498
|
+
|
|
499
|
+
- `theme.hideProgressBar = true` and `config.showProgressBar = false` both
|
|
500
|
+
hide the bar.
|
|
501
|
+
- `theme.hideStepIcons = true` hides the per-step icons (no equivalent in
|
|
502
|
+
`VelionConfig`; theme-only).
|
|
503
|
+
|
|
504
|
+
### Step header icons
|
|
505
|
+
|
|
506
|
+
Each step renders a themed icon (Material Icons) inside a circle of
|
|
507
|
+
`primaryColor` next to the title. They come from `@expo/vector-icons`, which
|
|
508
|
+
Expo SDK 54+ ships by default. In bare React Native projects without Expo,
|
|
509
|
+
install it separately (`npm install @expo/vector-icons`) or enable
|
|
510
|
+
`hideStepIcons` to skip the dependency.
|
|
511
|
+
|
|
512
|
+
### Color mode
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
<VelionOnboardingScreen
|
|
516
|
+
config={{ ...config, theme, colorMode: 'light' }}
|
|
517
|
+
/>
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
With `colorMode: 'auto'` (default), the SDK follows `useColorScheme()` from
|
|
521
|
+
the system. `'light'` or `'dark'` force the mode.
|
|
522
|
+
|
|
523
|
+
If you pass a `theme` whose `backgroundColor` has the opposite luminance to
|
|
524
|
+
the active `colorMode`, the SDK detects the conflict and switches its icons
|
|
525
|
+
and SVGs to the correct tone. This avoids the case where
|
|
526
|
+
`colorMode: 'light'` + `backgroundColor: '#0B1220'` leaves dark icons on a
|
|
527
|
+
dark background.
|
|
528
|
+
|
|
529
|
+
### Reduced motion
|
|
530
|
+
|
|
531
|
+
The SDK honours `AccessibilityInfo.isReduceMotionEnabled()` automatically.
|
|
532
|
+
There is nothing to configure — animations are disabled when the OS asks for
|
|
533
|
+
reduced motion.
|
|
534
|
+
|
|
535
|
+
---
|
|
536
|
+
|
|
537
|
+
## Locales
|
|
538
|
+
|
|
539
|
+
`locale: 'es' | 'en'`. Any other value falls back to `'es'`.
|
|
540
|
+
|
|
541
|
+
To override specific copy (e.g. the final result screen for
|
|
542
|
+
`SESSION_DECLINED`):
|
|
543
|
+
|
|
544
|
+
```tsx
|
|
545
|
+
config={{
|
|
546
|
+
...config,
|
|
547
|
+
finalResultScreenTexts: {
|
|
548
|
+
approved: { title: 'Done!', message: 'Your account is active.' },
|
|
549
|
+
manualReview: { title: 'Under review', message: 'We will reach out within 24h.' },
|
|
550
|
+
},
|
|
551
|
+
sessionDeclinedReasonTexts: {
|
|
552
|
+
LIVENESS_FAILED: {
|
|
553
|
+
es: { title: 'No pudimos verificarte', message: 'Probá de nuevo con buena luz.' },
|
|
554
|
+
en: { title: 'We could not verify you', message: 'Please retry under good light.' },
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
}}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Errors
|
|
563
|
+
|
|
564
|
+
```tsx
|
|
565
|
+
import { SdkErrorCode, CameraErrorCode } from '@velion-la/onboarding-sdk-react-native';
|
|
566
|
+
|
|
567
|
+
onError: (err) => {
|
|
568
|
+
if (err.code === SdkErrorCode.SESSION_EXPIRED) {
|
|
569
|
+
refreshSessionToken().then((newConfig) => remountSdk(newConfig));
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
if (err.code === SdkErrorCode.SESSION_DECLINED) {
|
|
573
|
+
// err.declineTitle / declineMessage already come localized
|
|
574
|
+
showDeclineScreen(err);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (err.code === SdkErrorCode.CAMERA_ERROR) {
|
|
578
|
+
if (err.cameraCode === CameraErrorCode.PERMISSION_DENIED) {
|
|
579
|
+
showCameraPermissionDialog();
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
// Fallback
|
|
584
|
+
showRetry(err.message);
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
## Assisted address mode (map + search)
|
|
591
|
+
|
|
592
|
+
`ADDRESS_INFO` has two modes:
|
|
593
|
+
|
|
594
|
+
- **Manual** (default fallback): full structured form (country, state, city,
|
|
595
|
+
district, neighbourhood, street, number, postal code, floor, apartment,
|
|
596
|
+
references).
|
|
597
|
+
- **Assisted**: fullscreen map with a floating search bar on top and a
|
|
598
|
+
floating "Next" button on the bottom. The user searches for their address
|
|
599
|
+
by typing, picks a suggestion, or drags the pin manually. On confirm, the
|
|
600
|
+
structured fields are filled automatically and `lat`/`lng` are added to
|
|
601
|
+
the payload.
|
|
602
|
+
|
|
603
|
+
### Map provider per platform
|
|
604
|
+
|
|
605
|
+
| Platform | Map provider | API key required? |
|
|
606
|
+
|---|---|---|
|
|
607
|
+
| **iOS** | Apple Maps (system) | **No.** No GCP setup, no `AirGoogleMaps` target, no extra plugin. |
|
|
608
|
+
| **Android** | Google Maps SDK | **Yes.** Maps SDK for Android, application restriction `Android apps` + package + SHA-1. |
|
|
609
|
+
|
|
610
|
+
### Geocoding and search — fully OS-native, no Google REST
|
|
611
|
+
|
|
612
|
+
The SDK does **not** call Google's HTTP APIs (Geocoding / Places Web
|
|
613
|
+
Service) from the client. Those APIs do not honour application restrictions
|
|
614
|
+
(bundle ID / package + SHA-1), so a tightly restricted key would fail with
|
|
615
|
+
`REQUEST_DENIED` on mobile. Instead:
|
|
616
|
+
|
|
617
|
+
- **Reverse geocoding** (pin → street / number / postal code / city /
|
|
618
|
+
state / country) uses `expo-location.reverseGeocodeAsync`. On iOS that is
|
|
619
|
+
`CLGeocoder` (Apple Maps); on Android it is `android.location.Geocoder`
|
|
620
|
+
(Google Play Services on-device). No key, no quota, no external Google
|
|
621
|
+
network call.
|
|
622
|
+
- **Search bar** uses `expo-location.geocodeAsync` with a 400 ms debounce,
|
|
623
|
+
plus a reverse-geocode fan-out on the top 5 candidates to build the
|
|
624
|
+
visible label ("Av. Corrientes 1234, CABA, Argentina"). Suggestions
|
|
625
|
+
appear when the user pauses typing.
|
|
626
|
+
|
|
627
|
+
### When the assisted mode activates
|
|
628
|
+
|
|
629
|
+
```
|
|
630
|
+
1) Is `react-native-maps` linked?
|
|
631
|
+
no → manual
|
|
632
|
+
yes → ↓
|
|
633
|
+
2) Platform?
|
|
634
|
+
iOS → assisted (Apple Maps, no key)
|
|
635
|
+
Android → is `googleMapsApiKey` set in VelionConfig?
|
|
636
|
+
yes → assisted (Google Maps with that key)
|
|
637
|
+
no → manual (Android MapView without a key renders blank)
|
|
638
|
+
3) Does the MapView throw at runtime?
|
|
639
|
+
yes → manual (an error boundary captures it and falls back)
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
In practice:
|
|
643
|
+
|
|
644
|
+
- On **iOS** it is enough to have `react-native-maps` installed.
|
|
645
|
+
`googleMapsApiKey` can be omitted.
|
|
646
|
+
- On **Android** you need `googleMapsApiKey` in `VelionConfig` **and** the
|
|
647
|
+
same key declared in `AndroidManifest.xml` (Expo handles this via
|
|
648
|
+
`app.config.js` → `android.config.googleMaps.apiKey`). Google Maps SDK
|
|
649
|
+
reads the key from the manifest, not from JS, so both places are required.
|
|
650
|
+
|
|
651
|
+
### Google Cloud setup (Android only)
|
|
652
|
+
|
|
653
|
+
If you want assisted mode on Android:
|
|
654
|
+
|
|
655
|
+
1. Enable **`Maps SDK for Android`** on your GCP project.
|
|
656
|
+
2. **Application restriction**: `Android apps`. Add your package name plus
|
|
657
|
+
the SHA-1 fingerprint of the signing certificate. For debug builds:
|
|
658
|
+
```bash
|
|
659
|
+
cd example/android && ./gradlew signingReport
|
|
660
|
+
# look for "Variant: debug" → SHA1
|
|
661
|
+
```
|
|
662
|
+
3. **API restriction**: restrict the key to `Maps SDK for Android` (do not
|
|
663
|
+
leave it as "Don't restrict key").
|
|
664
|
+
4. **Billing enabled** on the GCP project (required even for the free tier).
|
|
665
|
+
|
|
666
|
+
### Extra permissions (assisted mode only)
|
|
667
|
+
|
|
668
|
+
- iOS: `NSLocationWhenInUseUsageDescription`.
|
|
669
|
+
- Android: `ACCESS_COARSE_LOCATION` + `ACCESS_FINE_LOCATION`.
|
|
670
|
+
|
|
671
|
+
If the user rejects location, the map opens at a default centre and the
|
|
672
|
+
user can move the pin or use the search bar — the flow is not broken.
|
|
673
|
+
|
|
674
|
+
### Automatic fallback when something fails
|
|
675
|
+
|
|
676
|
+
When mounting `ADDRESS_INFO`, the SDK checks:
|
|
677
|
+
|
|
678
|
+
1. That `react-native-maps` is importable. If not → manual.
|
|
679
|
+
2. On Android, that `googleMapsApiKey` is in `VelionConfig`. If not →
|
|
680
|
+
manual. Additionally, when `expo-constants` is available, the SDK checks
|
|
681
|
+
that the same key is declared in the Expo config; otherwise the
|
|
682
|
+
`MapView` would crash natively. If missing → manual with an
|
|
683
|
+
`[address]` warning explaining the fix.
|
|
684
|
+
3. The `<MapAddressPicker>` is wrapped in an error boundary that catches a
|
|
685
|
+
throwing `MapView` at runtime (typical example: `AirGoogleMaps dir must
|
|
686
|
+
be added` on iOS if someone forces `provider="google"`). If it fires →
|
|
687
|
+
manual.
|
|
688
|
+
|
|
689
|
+
In every fallback path the SDK logs a warning prefixed with `[address]` and
|
|
690
|
+
renders the manual form. The user keeps completing the address, just
|
|
691
|
+
without `lat`/`lng`.
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
695
|
+
## Supported steps
|
|
696
|
+
|
|
697
|
+
| Step | Backend endpoint | UI |
|
|
698
|
+
|---|---|---|
|
|
699
|
+
| `DEVICE_FINGERPRINT` | `POST /sessions/:id/fingerprint` | Loading overlay |
|
|
700
|
+
| `HUMAN_BASIC_INFO` | `POST /basic-info/human` | Form |
|
|
701
|
+
| `LEGAL_BASIC_INFO` | `POST /basic-info/legal` | Form |
|
|
702
|
+
| `HUMAN_EXTENDED_INFO` | `POST /extended-info/human` | Form (fields per `stepConfig`) |
|
|
703
|
+
| `LEGAL_EXTENDED_INFO` | `POST /extended-info/legal` | Form (date + country) |
|
|
704
|
+
| `EMAIL_CONTACT` | `POST /contact/email` | Form |
|
|
705
|
+
| `PHONE_CONTACT` | `POST /contact/phone` | Form (E.164) |
|
|
706
|
+
| `EMAIL_OTP` | `POST /email/send-otp` + `verify-otp` | Two-stage form |
|
|
707
|
+
| `PHONE_OTP` | `POST /phone/send-otp` + `verify-otp` | Two-stage form |
|
|
708
|
+
| `TAX_INFO` | `POST /tax-info` | Form (selects from `stepConfig`) |
|
|
709
|
+
| `SWORN_DECLARATION` | `POST /sworn-declaration` | Cards with checkbox |
|
|
710
|
+
| `TERMS_AND_CONDITIONS` | `POST /terms-and-conditions` | Checkbox list + link |
|
|
711
|
+
| `ADDRESS_INFO` | `POST /address-info` | Manual or assisted (Maps) |
|
|
712
|
+
| `DOCUMENTS_OCR` | `POST /documents-init` + `PUT` × 2 + `verify` | Camera + intro tips |
|
|
713
|
+
| `LIVENESS_MATCH` | `POST /liveness-init` + WebSocket + `verify` | Front camera + oval mask |
|
|
714
|
+
| `FACE_MATCH` | (backend-only, no POST) | Loading + poll |
|
|
715
|
+
|
|
716
|
+
The order is determined dynamically by the backend via `current_step` and
|
|
717
|
+
the SSE `ROUTING_COMMAND` events. The SDK does no client-side routing.
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## Stack and architecture
|
|
722
|
+
|
|
723
|
+
```
|
|
724
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
725
|
+
│ <VelionOnboardingScreen config /> │
|
|
726
|
+
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
|
727
|
+
│ │ ThemeProvider │ │
|
|
728
|
+
│ │ ┌────────────────────────────────────────────────────────────┐ │ │
|
|
729
|
+
│ │ │ ProgressBar (sticky top) │ │ │
|
|
730
|
+
│ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │
|
|
731
|
+
│ │ │ │ Step slot (driven by orchestrator) │ │ │ │
|
|
732
|
+
│ │ │ │ HumanBasicInfo / EmailOtp / Documents / Liveness… │ │ │ │
|
|
733
|
+
│ │ │ └──────────────────────────────────────────────────────┘ │ │ │
|
|
734
|
+
│ │ │ LoadingOverlay / RetryDialog │ │ │
|
|
735
|
+
│ │ └────────────────────────────────────────────────────────────┘ │ │
|
|
736
|
+
│ └──────────────────────────────────────────────────────────────────┘ │
|
|
737
|
+
└────────────────────────────┬────────────────────────────────────────────┘
|
|
738
|
+
│
|
|
739
|
+
VelionOnboarding (orchestrator, plain TS)
|
|
740
|
+
│
|
|
741
|
+
┌────────────────────┼────────────────────────────┐
|
|
742
|
+
│ │ │
|
|
743
|
+
ApiCaller (fetch) SSE (react-native-sse) Liveness WS (binary + HMAC)
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
- **Types**: shipped inside the package (`lib/typescript/`). They mirror
|
|
747
|
+
the Onboarding backend contract.
|
|
748
|
+
- **Build**: `react-native-builder-bob` emits CommonJS, ESM and TypeScript
|
|
749
|
+
declarations.
|
|
750
|
+
- **No `Buffer`**: base64 helpers use `btoa` / `atob` globals (Hermes-
|
|
751
|
+
compatible).
|
|
752
|
+
- **HMAC-SHA256**: pure JavaScript via `@noble/hashes`, no native bridge.
|
|
753
|
+
|
|
754
|
+
---
|
|
755
|
+
|
|
756
|
+
## Local development
|
|
757
|
+
|
|
758
|
+
```bash
|
|
759
|
+
git clone <repo>
|
|
760
|
+
cd onboarding-sdk-react-native
|
|
761
|
+
npm install
|
|
762
|
+
npm run typecheck # both workspaces
|
|
763
|
+
npm run build # build the SDK with bob → sdk/lib/
|
|
764
|
+
|
|
765
|
+
# Demo on a simulator (vision-camera requires prebuild, no Expo Go)
|
|
766
|
+
npm run prebuild
|
|
767
|
+
npm run ios # or npm run android
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
The `example/` app consumes the SDK by path resolution (via the
|
|
771
|
+
`react-native` field in `package.json`); there is no need for `npm link` or
|
|
772
|
+
`npm pack` while iterating.
|
|
773
|
+
|
|
774
|
+
---
|
|
775
|
+
|
|
776
|
+
## Publishing
|
|
777
|
+
|
|
778
|
+
```bash
|
|
779
|
+
cd sdk
|
|
780
|
+
|
|
781
|
+
# 1. Inspect what would be published
|
|
782
|
+
npm pack --dry-run
|
|
783
|
+
|
|
784
|
+
# 2. Publish
|
|
785
|
+
npm publish
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
The `prepare` script runs `bob build` automatically, so a fresh build is
|
|
789
|
+
guaranteed before publishing.
|
|
790
|
+
|
|
791
|
+
To bump the version:
|
|
792
|
+
|
|
793
|
+
```bash
|
|
794
|
+
cd sdk
|
|
795
|
+
npm version patch # or minor / major
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
---
|
|
799
|
+
|
|
800
|
+
## License
|
|
801
|
+
|
|
802
|
+
Proprietary. This package is distributed under a commercial agreement with
|
|
803
|
+
Velion. Contact `dev@velion.la` for licensing terms.
|