[SELF-700] feat: add mock document generator demo (#995)

* feat: add mock document generator demo

* feat: add mock document generator

* fixes

* chore: refresh workflow cache

* update lock

* build

* updates

* more fixes

* code rabbit feedback

* compiles

* save wip

* updates

* merge with dev and fixes

* fix: align hoisting and demo Jest resolver (#1003)

* chore(app): map common src paths and declare svg flag module

* ci fix

* update lock

* save wip

* chore: address yarn lock issues (#1004)

* address yarn lock issues

* fix postinstall

* fix ci

* use metro js proxy

* android build working for /app

* save wip

* fix merge

* pipeline fixes

* format

* fix pipelines

* bump limit and split

* fix pipeline issues

* chore: decouple demo app build (#1013)

* chore: decouple demo app build

* chore: move demo app to workspace

* chore: unpublish demo workspace

* fix mobile sdk tests

* updates

* remove polyfills

* update merge

* update resolutions

* update resolutions

* fix merge

* fix paths

* save wip

* save wip fixes rd2

* working android

* update lock

* save wip ios building

* fix merge

* readd public key

* fixes

* ci fixes

* fixes

* fix web building

* fix ci

* fix tests

* update lock

* fix ci rd2

* formatting and fix ci

* fix

* finalize ci fixes

* fix tests and metro config paths for building

* save wip

* install missing package for pipeline

* fix wip app building

* wip react config

* save working emulator compile

* first round of pr fixes and feedback

* clean up demo app artifacts from sdk

* Add Gradle wrapper files for mobile-sdk-demo Android build

- Added gradlew, gradlew.bat, and gradle/wrapper/ directory
- Updated .gitignore to allow committing Gradle wrapper files
- Fixes Android build error: spawn ./gradlew ENOENT

* codex feedback and fixes

* fix tests

* file renames

* revert back to dev

* add types

* coderabbit fixes

* fix tests

* fix tests

* fix test

* fixes

* fix wip coderabbit issues

* coderabbit suggestions rd 2

* fix ci pipelines and addresss warnings

* cr fixes

* convert kebab to camelCase

* save wip fixes

* update reinstall and lock files

* fixes

* remove file

* fix lint

* fix polyfill fallback issues

* ensure that mock document is not on ofac list

* prettier
This commit is contained in:
Justin Hernandez
2025-09-27 13:59:47 -07:00
committed by GitHub
parent 0dc8b18d40
commit 20fa5c5adc
183 changed files with 4316 additions and 1454 deletions

View File

@@ -6,16 +6,13 @@ import type { FC } from 'react';
import { Dimensions } from 'react-native';
import { Separator, Text, XStack, YStack } from 'tamagui';
import {
AadhaarData,
isAadhaarDocument,
isMRZDocument,
PassportData,
} from '@selfxyz/common';
import type { AadhaarData } from '@selfxyz/common';
import {
attributeToPosition,
attributeToPosition_ID,
} from '@selfxyz/common/constants';
import type { PassportData } from '@selfxyz/common/types/passport';
import { isAadhaarDocument, isMRZDocument } from '@selfxyz/common/utils/types';
import { SvgXml } from '@/components/homeScreen/SvgXmlWrapper';
import AadhaarIcon from '@/images/icons/aadhaar.svg';

View File

@@ -14,12 +14,12 @@ export const useMockDataForm = () => {
const [selectedDocumentType, setSelectedDocumentType] = useState<
'mock_passport' | 'mock_id_card' | 'mock_aadhaar'
>('mock_passport');
const [isInOfacList, setIsInOfacList] = useState(true);
const [isInOfacList, setIsInOfacList] = useState(false);
const resetFormValues = () => {
setAge(21);
setExpiryYears(5);
setIsInOfacList(true);
setIsInOfacList(false);
setSelectedDocumentType('mock_passport');
setSelectedAlgorithm('sha256 rsa 65537 2048');
setSelectedCountry('USA');

View File

@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
// Web mock for NFC scanner functionality
// NFC passport scanning is not supported on web browsers
export const parseScanResponse = (_response: unknown) => {
throw new Error('NFC passport scanning is not supported on web browsers');
};
export const scan = async (_inputs: unknown) => {
throw new Error('NFC passport scanning is not supported on web browsers');
};

View File

@@ -44,17 +44,16 @@ import type { PropsWithChildren } from 'react';
import React, { createContext, useCallback, useContext, useMemo } from 'react';
import Keychain from 'react-native-keychain';
import { isMRZDocument } from '@selfxyz/common';
import type {
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
} from '@selfxyz/common/utils';
} from '@selfxyz/common/types/certificates';
import {
brutforceSignatureAlgorithmDsc,
calculateContentHash,
inferDocumentCategory,
parseCertificateSimple,
} from '@selfxyz/common/utils';
import { parseCertificateSimple } from '@selfxyz/common/utils/certificate_parsing/parseCertificateSimple';
import type {
AadhaarData,
DocumentCatalog,
@@ -62,6 +61,7 @@ import type {
IDDocument,
PassportData,
} from '@selfxyz/common/utils/types';
import { isMRZDocument } from '@selfxyz/common/utils/types';
import type { DocumentsAdapter, SelfClient } from '@selfxyz/mobile-sdk-alpha';
import { getAllDocuments, useSelfClient } from '@selfxyz/mobile-sdk-alpha';

View File

@@ -628,9 +628,7 @@ const DocumentNFCScanScreen: React.FC = () => {
width="$8"
alignSelf="center"
borderRadius={1000}
source={{
uri: NFC_IMAGE,
}}
source={NFC_IMAGE}
margin={20}
/>
</>

View File

@@ -55,9 +55,7 @@ const DocumentNFCScanScreen: React.FC = () => {
width="$8"
alignSelf="center"
borderRadius={1000}
source={{
uri: NFC_IMAGE,
}}
source={NFC_IMAGE}
margin={20}
/>
</>

View File

@@ -259,7 +259,7 @@ const AadhaarUploadScreen: React.FC = () => {
paddingVertical={20}
>
<Image
source={AadhaarImage}
source={AadhaarImage as any}
width="100%"
height="100%"
objectFit="contain"

View File

@@ -12,7 +12,6 @@ import {
usePreventRemove,
} from '@react-navigation/native';
import { PassportData } from '@selfxyz/common/types';
import { DocumentCatalog, IDDocument } from '@selfxyz/common/utils/types';
import { DocumentMetadata, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { DocumentEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';

View File

@@ -8,7 +8,6 @@ import { Button, Text, XStack, YStack, ZStack } from 'tamagui';
import { BlurView } from '@react-native-community/blur';
import { useNavigation } from '@react-navigation/native';
import { PassportData } from '@selfxyz/common/types';
import { DocumentCatalog, IDDocument } from '@selfxyz/common/utils/types';
import IdCardLayout from '@/components/homeScreen/idCard';

View File

@@ -7,8 +7,8 @@ import { ScrollView, StyleSheet } from 'react-native';
import { Card, Image, Text, XStack, YStack } from 'tamagui';
import { CheckSquare2, Info, Wallet } from '@tamagui/lucide-icons';
import type { ProofHistory } from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import type { ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
import {
black,
blue100,

View File

@@ -14,9 +14,9 @@ import { useNavigation } from '@react-navigation/native';
import { CheckSquare2, Wallet, XCircle } from '@tamagui/lucide-icons';
import { BodyText } from '@/components/typography/BodyText';
import type { ProofHistory } from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import type { ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
import {
black,
blue100,

View File

@@ -15,9 +15,9 @@ import { useNavigation } from '@react-navigation/native';
import { CheckSquare2, Wallet, XCircle } from '@tamagui/lucide-icons';
import { BodyText } from '@/components/typography/BodyText';
import type { ProofHistory } from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import type { ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
import {
black,
blue100,

View File

@@ -23,8 +23,8 @@ import { typography } from '@/components/typography/styles';
import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { ProofStatus } from '@/stores/proof-types';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import { ProofStatus } from '@/stores/proofTypes';
import { black, white } from '@/utils/colors';
import {
buttonTap,

View File

@@ -36,8 +36,8 @@ import {
setDefaultDocumentTypeIfNeeded,
usePassport,
} from '@/providers/passportDataProvider';
import { ProofStatus } from '@/stores/proof-types';
import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import { ProofStatus } from '@/stores/proofTypes';
import { black, slate300, white } from '@/utils/colors';
import { formatUserId } from '@/utils/formatUserId';
import { buttonTap } from '@/utils/haptic';

View File

@@ -36,10 +36,6 @@ const QRCodeViewFinderScreen: React.FC = () => {
const isFocused = useIsFocused();
const [doneScanningQR, setDoneScanningQR] = useState(false);
const navigateToProve = useHapticNavigation('Prove');
const navigateToHome = useHapticNavigation('Home');
const onCancelPress = useCallback(() => {
navigateToHome();
}, [navigateToHome]);
// This resets to the default state when we navigate back to this screen
useFocusEffect(

View File

@@ -66,8 +66,13 @@ const AccountRecoveryChoiceScreen: React.FC = () => {
return useProtocolStore.getState()[docCategory].commitment_tree;
},
getAltCSCA(docCategory) {
if (passportData.documentCategory === 'aadhaar') {
return useProtocolStore.getState().aadhaar.public_keys;
if (docCategory === 'aadhaar') {
const publicKeys =
useProtocolStore.getState().aadhaar.public_keys;
// Convert string[] to Record<string, string> format expected by AlternativeCSCA
return publicKeys
? Object.fromEntries(publicKeys.map(key => [key, key]))
: {};
}
return useProtocolStore.getState()[docCategory].alternative_csca;
},

View File

@@ -72,7 +72,11 @@ const RecoverWithPhraseScreen: React.FC = () => {
},
getAltCSCA(docCategory) {
if (docCategory === 'aadhaar') {
return useProtocolStore.getState()[docCategory].public_keys;
const publicKeys = useProtocolStore.getState().aadhaar.public_keys;
// Convert string[] to Record<string, string> format expected by AlternativeCSCA
return publicKeys
? Object.fromEntries(publicKeys.map(key => [key, key]))
: {};
}
return useProtocolStore.getState()[docCategory].alternative_csca;
},

View File

@@ -10,12 +10,10 @@ import { Text, YStack } from 'tamagui';
import type { StaticScreenProps } from '@react-navigation/native';
import { useIsFocused } from '@react-navigation/native';
import { IDDocument } from '@selfxyz/common/dist/esm/src/utils/types';
import type { PassportData } from '@selfxyz/common/types';
import { IDDocument } from '@selfxyz/common/utils/types';
import failAnimation from '@/assets/animations/loading/fail.json';
import proveLoadingAnimation from '@/assets/animations/loading/prove.json';
import successAnimation from '@/assets/animations/loading/success.json';
import CloseWarningIcon from '@/images/icons/close-warning.svg';
import { loadPassportDataAndSecret } from '@/providers/passportDataProvider';
import { black, slate400, white, zinc500, zinc900 } from '@/utils/colors';

View File

@@ -4,12 +4,8 @@
import SQLite from 'react-native-sqlite-storage';
import type {
ProofDB,
ProofDBResult,
ProofHistory,
} from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import type { ProofDB, ProofDBResult, ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
const PAGE_SIZE = 20;
const DB_NAME = 'proof_history.db';

View File

@@ -2,12 +2,8 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import type {
ProofDB,
ProofDBResult,
ProofHistory,
} from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import type { ProofDB, ProofDBResult, ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
export const DB_NAME = 'proof_history_db';
const STORE_NAME = 'proof_history';

View File

@@ -8,8 +8,8 @@ import { create } from 'zustand';
import { WS_DB_RELAYER } from '@selfxyz/common/constants';
import { database } from '@/stores/database';
import type { ProofHistory } from '@/stores/proof-types';
import { ProofStatus } from '@/stores/proof-types';
import type { ProofHistory } from '@/stores/proofTypes';
import { ProofStatus } from '@/stores/proofTypes';
interface ProofHistoryState {
proofHistory: ProofHistory[];

8
app/src/types/elliptic.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2025 Social Connect Labs, Inc.
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
declare module 'elliptic' {
const elliptic: any;
export = elliptic;
}

View File

@@ -3,6 +3,8 @@
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
declare module '*.png' {
const content: any;
export default content;
import type { ImageSourcePropType } from 'react-native';
const pngContent: ImageSourcePropType;
export default pngContent;
}

View File

@@ -6,6 +6,6 @@ declare module '*.svg' {
import type React from 'react';
import type { SvgProps } from 'react-native-svg';
const content: React.FC<SvgProps>;
export default content;
const svgContent: React.FC<SvgProps>;
export default svgContent;
}

View File

@@ -136,6 +136,11 @@ const _generateCircuitInputs = async (
circuitTypeWithDocumentExtension = `${circuitType}${document === 'passport' ? '' : '_id'}`;
break;
case 'dsc':
if (document === 'aadhaar') {
throw new Error(
'DSC circuit type is not supported for Aadhaar documents',
);
}
({ inputs, circuitName, endpointType, endpoint } = generateTEEInputsDSC(
passportData as PassportData,
protocolStore[document].csca_tree as string[][],
@@ -1014,7 +1019,7 @@ export const useProvingStore = create<ProvingState>((set, get) => {
step: 'protocol_store_fetch',
document,
});
await useProtocolStore.getState()[document].fetch_all(env!);
await useProtocolStore.getState().aadhaar.fetch_all(env!);
break;
}
logProofEvent('info', 'Data fetch succeeded', context, {
@@ -1114,10 +1119,17 @@ export const useProvingStore = create<ProvingState>((set, get) => {
secret as string,
{
getCommitmentTree,
getAltCSCA: (docType: DocumentCategory) =>
docType === 'aadhaar'
? useProtocolStore.getState().aadhaar.public_keys
: useProtocolStore.getState()[docType].alternative_csca,
getAltCSCA: (docType: DocumentCategory) => {
if (docType === 'aadhaar') {
const publicKeys =
useProtocolStore.getState().aadhaar.public_keys;
// Convert string[] to Record<string, string> format expected by AlternativeCSCA
return publicKeys
? Object.fromEntries(publicKeys.map(key => [key, key]))
: {};
}
return useProtocolStore.getState()[docType].alternative_csca;
},
},
);
logProofEvent(