Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b49e2c9
WIP: Read document catalog from selfClient
shazarre Aug 21, 2025
9806373
remove console.log
shazarre Aug 21, 2025
1a371e6
refactor all calls to `hasAnyValidRegisteredDocument`
shazarre Aug 22, 2025
95e8e88
refactor proving machine methods that need to to take their own self …
aaronmgdr Aug 22, 2025
65cebe1
expose loadDocumentById + getAllDocuments via PassportContext now use…
shazarre Aug 22, 2025
0eb0514
fix wrong hook usage
shazarre Aug 25, 2025
bbc24cd
Merge branch 'dev' into shazarre/read_document_catalog_from_the_self_…
shazarre Aug 25, 2025
dd117ff
yarn lint
shazarre Aug 25, 2025
167a172
Merge branch 'shazarre/read_document_catalog_from_the_self_client' of…
shazarre Aug 25, 2025
aef32dc
sdk: yarn lint
shazarre Aug 25, 2025
55b22e1
formatting + test fixes
shazarre Aug 25, 2025
77f8766
rename explicit keychain access + restore ability to work without sel…
shazarre Aug 25, 2025
231e42a
fix testingUtils
shazarre Aug 25, 2025
92ce174
fix tests
shazarre Aug 25, 2025
3e7c0fa
lint
shazarre Aug 25, 2025
d0f1d92
fix web build
shazarre Aug 25, 2025
974f76b
remove TODO
shazarre Aug 25, 2025
f76f9e2
Merge branch 'dev' into shazarre/read_document_catalog_from_the_self_…
shazarre Aug 26, 2025
ba6a315
remove animation + lint
shazarre Aug 26, 2025
f856ddf
Merge branch 'dev' into shazarre/read_document_catalog_from_the_self_…
shazarre Aug 26, 2025
8293f92
lint
shazarre Aug 26, 2025
2c36f32
missing license
shazarre Aug 26, 2025
65c1d74
fix test
shazarre Aug 26, 2025
5b9601c
lint
shazarre Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions app/src/providers/passportDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@
* - Display format determined by documentCategory
*/

import { sha256 } from 'js-sha256';

Check failure on line 41 in app/src/providers/passportDataProvider.tsx

View workflow job for this annotation

GitHub Actions / lint

Run autofix to sort these imports!
import type { PropsWithChildren } from 'react';
import React, { createContext, useCallback, useContext, useMemo } from 'react';
import Keychain from 'react-native-keychain';

import type { DocumentCategory, PassportData } from '@selfxyz/common/types';
import type {
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
Expand All @@ -52,8 +51,15 @@
brutforceSignatureAlgorithmDsc,
parseCertificateSimple,
} from '@selfxyz/common/utils';
import type {
DocumentCatalog,
DocumentCategory,
DocumentMetadata,
PassportData,
} from '@selfxyz/common/utils/types';

import { unsafe_getPrivateKey, useAuth } from '@/providers/authProvider';
import { SelfClient } from '@selfxyz/mobile-sdk-alpha';

// Create safe wrapper functions to prevent undefined errors during early initialization
// These need to be declared early to avoid dependency issues
Expand Down Expand Up @@ -81,20 +87,6 @@
}
};

export interface DocumentMetadata {
id: string; // contentHash as ID for deduplication
documentType: string; // passport, mock_passport, id_card, etc.
documentCategory: DocumentCategory; // passport, id_card, aadhaar
data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
mock: boolean; // whether this is a mock document
isRegistered?: boolean; // whether the document is registered onChain
}

export interface DocumentCatalog {
documents: DocumentMetadata[];
selectedDocumentId?: string; // This is now a contentHash
}

type DocumentChangeCallback = (isMock: boolean) => void;

const documentChangeCallbacks: DocumentChangeCallback[] = [];
Expand Down Expand Up @@ -402,9 +394,11 @@
}
}

export async function hasAnyValidRegisteredDocument(): Promise<boolean> {
// TODO: move to utils?
export async function hasAnyValidRegisteredDocument(client: SelfClient): Promise<boolean> {
try {
const catalog = await loadDocumentCatalog();
const catalog = await client.loadDocumentCatalog();

return catalog.documents.some(doc => doc.isRegistered === true);
} catch (error) {
console.error('Error loading document catalog:', error);
Expand Down Expand Up @@ -671,12 +665,14 @@
} | null>;
clearPassportData: () => Promise<void>;
clearSpecificData: (documentType: string) => Promise<void>;

loadDocumentCatalog: () => Promise<DocumentCatalog>;
getAllDocuments: () => Promise<{
[documentId: string]: { data: PassportData; metadata: DocumentMetadata };
}>;
setSelectedDocument: (documentId: string) => Promise<void>;
deleteDocument: (documentId: string) => Promise<void>;

migrateFromLegacyStorage: () => Promise<void>;
getCurrentDocumentType: () => Promise<string | null>;
clearDocumentCatalogForMigrationTesting: () => Promise<void>;
Expand All @@ -686,7 +682,7 @@
isRegistered: boolean,
) => Promise<void>;
checkIfAnyDocumentsNeedMigration: () => Promise<boolean>;
hasAnyValidRegisteredDocument: () => Promise<boolean>;
hasAnyValidRegisteredDocument: (client: SelfClient) => Promise<boolean>;
checkAndUpdateRegistrationStates: () => Promise<void>;
}

Expand Down
4 changes: 3 additions & 1 deletion app/src/screens/misc/SplashScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11

import LottieView from 'lottie-react-native';

Check failure on line 3 in app/src/screens/misc/SplashScreen.tsx

View workflow job for this annotation

GitHub Actions / lint

Run autofix to sort these imports!
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
Expand All @@ -19,6 +19,7 @@
import { useSettingStore } from '@/stores/settingStore';
import { black } from '@/utils/colors';
import { impactLight } from '@/utils/haptic';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';

const SplashScreen: React.FC = ({}) => {
const navigation =
Expand All @@ -30,6 +31,7 @@
null,
);
const dataLoadInitiatedRef = useRef(false);
const selfClient = useSelfClient();

useEffect(() => {
if (!dataLoadInitiatedRef.current) {
Expand Down Expand Up @@ -58,7 +60,7 @@
await checkAndUpdateRegistrationStates();
}

const hasValid = await hasAnyValidRegisteredDocument();
const hasValid = await hasAnyValidRegisteredDocument(selfClient);
setNextScreen(hasValid ? 'Home' : 'Launch');
} catch (error) {
console.error(`Error in SplashScreen data loading: ${error}`);
Expand Down
14 changes: 14 additions & 0 deletions common/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ import type { PassportMetadata } from './passports/passport_parsing/parsePasspor
export type DocumentCategory = 'passport' | 'id_card';

export type DocumentType = 'passport' | 'id_card' | 'mock_passport' | 'mock_id_card';

export interface DocumentCatalog {
documents: DocumentMetadata[];
selectedDocumentId?: string; // This is now a contentHash
}
export interface DocumentMetadata {
id: string; // contentHash as ID for deduplication
documentType: string; // passport, mock_passport, id_card, etc.
documentCategory: DocumentCategory; // passport, id_card, aadhaar
data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
Comment on lines +16 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Inconsistent category usage (‘aadhaar’) vs. declared DocumentCategory union

Comments and downstream code (ManageDocumentsScreen.extractCountryFromData) handle 'aadhaar', but DocumentCategory only allows 'passport' | 'id_card'. This mismatch will lead to unreachable branches and ad-hoc string typing elsewhere.

Two options:

  • Expand DocumentCategory to include 'aadhaar' (and align all switch/case and validations), or
  • Remove 'aadhaar' handling here and in app code until the category is formally supported.

Run this to locate all usages and scope the change:

If you decide to include 'aadhaar', add it in the shared union and update comments accordingly.


🏁 Script executed:

#!/bin/bash
rg -nP -C2 "\baadhaar\b|\\bDocumentCategory\\b" --type=ts --type=tsx

Length of output: 96


I’ll re-run the search across all .ts/.tsx files, including the typedef for DocumentCategory, to verify where (and how) “aadhaar” is used versus what the union actually contains:


🏁 Script executed:

#!/bin/bash
# Search for DocumentCategory usages and aadhaar occurrences in TS/TSX files
rg -nP -C2 "\baadhaar\b|\bDocumentCategory\b" -g "*.ts" -g "*.tsx"

# Locate the definition of the DocumentCategory union
rg -nP "type\s+DocumentCategory\b" -g "*.ts"

Length of output: 13827


Add ‘aadhaar’ to the DocumentCategory union to match its usage

The codebase is already treating “aadhaar” as a first-class documentCategory (inference logic, screen branches, proving inputs, etc.), but the shared type only allows ‘passport’ or ‘id_card’. This mismatch forces pervasive casts (as DocumentCategory) and risks undetected bugs or unreachable branches.

Required refactor:

  • In common/src/utils/types.ts, update the union at the top of the file
    - export type DocumentCategory = 'passport' | 'id_card';
    + export type DocumentCategory = 'passport' | 'id_card' | 'aadhaar';
  • Remove or correct the inline comment on lines 16–17 to reflect the updated union (no more “passport, id_card, aadhaar” mismatch)
  • Remove any as DocumentCategory assertions in inferDocumentCategory, ManageDocumentsScreen, and proving/validation modules—they should now type-check cleanly
  • Audit switch/case statements over DocumentCategory (e.g. in getSelectorDg1, extractCountryFromData) to ensure they include an “aadhaar” branch and handle it appropriately

This change is critical to maintain type safety and prevent runtime surprises.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
documentCategory: DocumentCategory; // passport, id_card, aadhaar
data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
export type DocumentCategory = 'passport' | 'id_card' | 'aadhaar';
🤖 Prompt for AI Agents
In common/src/utils/types.ts around lines 16 to 17, the DocumentCategory union
currently omits 'aadhaar' causing casts and broken typechecks; update the union
to include 'aadhaar' (e.g., 'passport' | 'id_card' | 'aadhaar'), adjust the
inline comment to accurately list all allowed values, then remove unnecessary
`as DocumentCategory` assertions in inferDocumentCategory,
ManageDocumentsScreen, and proving/validation modules so they type-check without
casts; finally audit all switch/case branches that depend on DocumentCategory
(getSelectorDg1, extractCountryFromData, etc.) and add or update an 'aadhaar'
branch with the correct handling logic.

mock: boolean; // whether this is a mock document
isRegistered?: boolean; // whether the document is registered onChain
}
Comment on lines +13 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Type safety: use the existing DocumentType instead of string for documentType

documentType is declared as string even though DocumentType is defined in this module. This weakens compile-time guarantees and risks drift with getDisplayName and other consumers.

Apply this diff:

 export interface DocumentMetadata {
   id: string; // contentHash as ID for deduplication
-  documentType: string; // passport, mock_passport, id_card, etc.
+  documentType: DocumentType; // passport, mock_passport, id_card, etc.
   documentCategory: DocumentCategory; // passport, id_card, aadhaar
   data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
   mock: boolean; // whether this is a mock document
   isRegistered?: boolean; // whether the document is registered onChain
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export interface DocumentMetadata {
id: string; // contentHash as ID for deduplication
documentType: string; // passport, mock_passport, id_card, etc.
documentCategory: DocumentCategory; // passport, id_card, aadhaar
data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
mock: boolean; // whether this is a mock document
isRegistered?: boolean; // whether the document is registered onChain
}
export interface DocumentMetadata {
id: string; // contentHash as ID for deduplication
documentType: DocumentType; // passport, mock_passport, id_card, etc.
documentCategory: DocumentCategory; // passport, id_card, aadhaar
data: string; // DG1/MRZ data for passports/IDs, relevant data for aadhaar
mock: boolean; // whether this is a mock document
isRegistered?: boolean; // whether the document is registered onChain
}
🤖 Prompt for AI Agents
In common/src/utils/types.ts around lines 13 to 20, the DocumentMetadata
interface currently types documentType as string; change it to use the existing
DocumentType type to ensure compile-time safety and avoid drift with consumers
like getDisplayName. Update the documentType field's type to DocumentType,
ensure DocumentType is imported or available in the module, and run TypeScript
checks to fix any downstream type mismatches affected by this stronger type.


export type PassportData = {
mrz: string;
dg1Hash?: number[];
Expand Down
7 changes: 7 additions & 0 deletions packages/mobile-sdk-alpha/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,12 @@ export function createSelfClient({ config, adapters }: { config: Config; adapter
extractMRZInfo: parseMRZInfo,
on,
emit,

// TODO: inline for now
loadDocumentCatalog: async () => {
// TODO: should it be done via adapters? If so, should we use StorageAdapter or
// a new one like KeychainAdapter?
return { documents: [] };
},
};
}
4 changes: 4 additions & 0 deletions packages/mobile-sdk-alpha/src/types/public.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DocumentCatalog } from '@selfxyz/common/utils/types';

export type { PassportData } from '@selfxyz/common/utils/types';
export type { PassportValidationCallbacks } from '../validation/document';
export interface Config {
Expand Down Expand Up @@ -132,6 +134,8 @@ export interface SelfClient {
extractMRZInfo(mrz: string): MRZInfo;
on<E extends SDKEvent>(event: E, cb: (payload: SDKEventMap[E]) => void): Unsubscribe;
emit<E extends SDKEvent>(event: E, payload: SDKEventMap[E]): void;

loadDocumentCatalog(): Promise<DocumentCatalog>;
}
export type Unsubscribe = () => void;
export interface StorageAdapter {
Expand Down
Loading