feat: use SelfClient for MRZ parsing (#930)

* feat: add Self SDK provider

* test: cover passport camera and self client provider

* allow this to fail for now cuz the runner doesn't support 16.4

* sort imports

* upgrade and fix

* fix header issue

* pr feedback

* fix linter

* Update app/scripts/check-license-headers.mjs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update app/scripts/check-license-headers.mjs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* update extensions and lock file

* simplify call

* use caching

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Justin Hernandez
2025-08-19 22:30:40 -07:00
committed by GitHub
parent d34ce431f4
commit cc628a79d2
13 changed files with 539 additions and 103 deletions

View File

@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
import type { NativeSyntheticEvent, StyleProp, ViewStyle } from 'react-native';
import { PixelRatio, Platform, requireNativeComponent } from 'react-native';
import { extractMRZInfo } from '@selfxyz/mobile-sdk-alpha';
import { type SelfClient, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { RCTFragment } from '@/components/native/RCTFragment';
@@ -47,7 +47,7 @@ export interface PassportCameraProps {
isMounted: boolean;
onPassportRead: (
error: Error | null,
mrzData?: ReturnType<typeof extractMRZInfo>,
mrzData?: ReturnType<SelfClient['extractMRZInfo']>,
) => void;
}
@@ -55,6 +55,7 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
onPassportRead,
isMounted,
}) => {
const selfClient = useSelfClient();
const _onError = useCallback(
(
event: NativeSyntheticEvent<{
@@ -93,7 +94,7 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
return;
}
if (typeof event.nativeEvent.data === 'string') {
onPassportRead(null, extractMRZInfo(event.nativeEvent.data));
onPassportRead(null, selfClient.extractMRZInfo(event.nativeEvent.data));
} else {
onPassportRead(null, {
passportNumber: event.nativeEvent.data.documentNumber,
@@ -117,7 +118,7 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
});
}
},
[onPassportRead, isMounted],
[onPassportRead, isMounted, selfClient],
);
if (Platform.OS === 'ios') {

View File

@@ -2,7 +2,7 @@
import React, { useCallback, useEffect } from 'react';
import type { extractMRZInfo } from '@selfxyz/mobile-sdk-alpha';
import { type SelfClient, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
// TODO: Web find a lightweight ocr or mrz scanner.
@@ -10,7 +10,7 @@ export interface PassportCameraProps {
isMounted: boolean;
onPassportRead: (
error: Error | null,
mrzData?: ReturnType<typeof extractMRZInfo>,
mrzData?: ReturnType<SelfClient['extractMRZInfo']>,
) => void;
}
@@ -18,6 +18,16 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
onPassportRead,
isMounted,
}) => {
const selfClient = useSelfClient();
const _onPassportRead = useCallback(
(mrz: string) => {
if (!isMounted) {
return;
}
onPassportRead(null, selfClient.extractMRZInfo(mrz));
},
[onPassportRead, isMounted, selfClient],
);
const handleError = useCallback(() => {
if (!isMounted) {
return;
@@ -28,6 +38,7 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
// Web stub - no functionality yet
useEffect(() => {
void _onPassportRead; // noop until web implementation exists
// Simulate that the component is not ready for web
if (isMounted) {
console.warn('PassportCamera: Web implementation not yet available');
@@ -37,7 +48,7 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
}, 100);
return () => clearTimeout(timer);
}
}, [isMounted, handleError]);
}, [isMounted, handleError, _onPassportRead]);
return (
<div