Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
627b708
Refactor mobile app utilities into new modules
transphorm Nov 7, 2025
1a96451
prettier
transphorm Nov 7, 2025
09337e3
update lock, feedback from codex
transphorm Nov 7, 2025
78c4cbb
fix path
transphorm Nov 7, 2025
c3115ec
keep some files in utils
transphorm Nov 7, 2025
d15fbdb
fix tests
transphorm Nov 7, 2025
740445f
Merge branch 'dev' into codex/restructure-utils-and-organize-project-…
transphorm Nov 8, 2025
91a0138
Merge branch 'dev' into codex/restructure-utils-and-organize-project-…
transphorm Nov 8, 2025
8ac17b3
update paths
transphorm Nov 8, 2025
ebe307d
remove old docs
transphorm Nov 8, 2025
7ccc282
cr feedback
transphorm Nov 8, 2025
a15d84b
flatten inefficient paths
transphorm Nov 8, 2025
c598c44
better structure
transphorm Nov 8, 2025
4deb1db
update test folder structure
transphorm Nov 8, 2025
e123454
migrate images
transphorm Nov 8, 2025
c9df435
fix import
transphorm Nov 8, 2025
c117d9b
fix Sentry path
transphorm Nov 8, 2025
57b7550
Merge branch 'dev' into codex/restructure-utils-and-organize-project-…
transphorm Nov 11, 2025
54b48e5
Merge branch 'dev' into codex/restructure-utils-and-organize-project-…
transphorm Nov 12, 2025
2c9c71c
update ignore
transphorm Nov 12, 2025
721544e
save wip migration
transphorm Nov 12, 2025
5bcc9c8
more updates
transphorm Nov 12, 2025
961e979
standardize component names
transphorm Nov 12, 2025
02da491
rename assets
transphorm Nov 12, 2025
83d24a6
fix linting
transphorm Nov 12, 2025
a425e22
add barrel exports. final refactor commit
transphorm Nov 12, 2025
df43d65
fix formatting
transphorm Nov 12, 2025
7cf4b1e
fix nav bar
transphorm Nov 12, 2025
652ddcf
reduce bundle size
transphorm Nov 12, 2025
d012c36
remove dupe license
transphorm Nov 12, 2025
7105a66
fix test
transphorm Nov 12, 2025
671eb02
Merge branch 'dev' into codex/restructure-utils-and-organize-project-…
transphorm Nov 12, 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
6 changes: 3 additions & 3 deletions app/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ module.exports = {
'src/components/NavBar/BaseNavBar.tsx',
'src/navigation/index.tsx',
'src/providers/passportDataProvider.tsx',
'src/utils/cloudBackup/helpers.ts',
'src/utils/haptic/index.ts',
'src/services/cloud-backup/helpers.ts',
'src/integrations/haptics/index.ts',
],
rules: {
'sort-exports/sort-exports': 'off',
Expand Down Expand Up @@ -228,7 +228,7 @@ module.exports = {
},
{
// Allow require imports for dynamic imports in proving machine
files: ['src/utils/proving/provingMachine.ts'],
files: ['src/features/proving/provingMachine.ts'],
rules: {
'@typescript-eslint/no-require-imports': 'off',
},
Expand Down
2 changes: 1 addition & 1 deletion app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import App from './App';
import { name as appName } from './app.json';
import tamaguiConfig from './tamagui.config';

import './src/utils/ethers';
import './src/lib/crypto/ethers';
import 'react-native-gesture-handler';

// Set global Buffer before any other imports
Expand Down
6 changes: 3 additions & 3 deletions app/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,8 @@ NativeModules.PassportReader = {
reset: jest.fn(),
};

// Mock @/utils/passportReader to properly expose the interface expected by tests
jest.mock('./src/utils/passportReader', () => {
// Mock @/integrations/nfc/passportReader to properly expose the interface expected by tests
jest.mock('./src/integrations/nfc/passportReader', () => {
const mockScanPassport = jest.fn();
// Mock the parameter count for scanPassport (iOS native method takes 9 parameters)
Object.defineProperty(mockScanPassport, 'length', { value: 9 });
Expand Down Expand Up @@ -776,7 +776,7 @@ jest.mock('react-native-localize', () => ({
}),
}));

jest.mock('./src/utils/notifications/notificationService', () =>
jest.mock('./src/services/notifications/notificationService', () =>
require('./tests/__setup__/notificationServiceMock.js'),
);

Expand Down
15 changes: 9 additions & 6 deletions app/scripts/tests/aliasImports.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,14 @@ describe('alias-imports transform', () => {
const appRoot = tempRoot;
const srcDir = join(appRoot, 'src');
const testsSrcDir = join(appRoot, 'tests', 'src');
const fileHaptic = join(srcDir, 'utils', 'haptic.ts');
const fileHaptic = join(srcDir, 'integrations', 'haptics.ts');
const deepSpecDir = join(testsSrcDir, 'deep');
const deepSpecFile = join(deepSpecDir, 'spec.ts');

writeFileEnsured(fileHaptic, 'export const h = 1;\n');
writeFileEnsured(
deepSpecFile,
"import { h } from '../../../src/utils/haptic';\nexport const v = h;\n",
"import { h } from '../../../src/integrations/haptics';\nexport const v = h;\n",
);

const project = new Project({
Expand All @@ -203,21 +203,24 @@ describe('alias-imports transform', () => {
const specFile = project.getSourceFileOrThrow(deepSpecFile);
const imports = specFile.getImportDeclarations();
assert.strictEqual(imports.length, 1);
assert.strictEqual(imports[0].getModuleSpecifierValue(), '@/utils/haptic');
assert.strictEqual(
imports[0].getModuleSpecifierValue(),
'@/integrations/haptics',
);
});

it("transforms deep relative require '../../../src/...' to @src alias from tests", () => {
const appRoot = tempRoot;
const srcDir = join(appRoot, 'src');
const testsSrcDir = join(appRoot, 'tests', 'src');
const fileHaptic = join(srcDir, 'utils', 'haptic.ts');
const fileHaptic = join(srcDir, 'integrations', 'haptics.ts');
const deepSpecDir = join(testsSrcDir, 'deep');
const deepSpecFile = join(deepSpecDir, 'req.ts');

writeFileEnsured(fileHaptic, 'module.exports = { h: 1 };\n');
writeFileEnsured(
deepSpecFile,
"const h = require('../../../src/utils/haptic');\nexport const v = h;\n",
"const h = require('../../../src/integrations/haptics');\nexport const v = h;\n",
);

const project = new Project({
Expand All @@ -232,7 +235,7 @@ describe('alias-imports transform', () => {
transformProjectToAliasImports(project, appRoot);

const specFile = project.getSourceFileOrThrow(deepSpecFile);
assert.ok(specFile.getText().includes("require('@/utils/haptic')"));
assert.ok(specFile.getText().includes("require('@/integrations/haptics')"));
});

it('aliases export star re-exports with ../ from sibling directory', () => {
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/Disclosures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { SelfAppDisclosureConfig } from '@selfxyz/common/utils';
import { BodyText } from '@selfxyz/mobile-sdk-alpha/components';

import CheckMark from '@/images/icons/checkmark.svg';
import { slate200, slate500 } from '@/utils/colors';
import { slate200, slate500 } from '@/lib/colors';

interface DisclosureProps {
disclosures: SelfAppDisclosureConfig;
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React, { Component } from 'react';
import { Text, View } from 'react-native';

import { captureException } from '@/Sentry';
import { flushAllAnalytics, trackNfcEvent } from '@/utils/analytics';
import { flushAllAnalytics, trackNfcEvent } from '@/services/analytics';

interface Props {
children: React.ReactNode;
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/FeedbackModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { Button, XStack, YStack } from 'tamagui';

import { Caption } from '@selfxyz/mobile-sdk-alpha/components';

import { black, slate400, white, zinc800, zinc900 } from '@/utils/colors';
import { advercase, dinot } from '@/utils/fonts';
import { black, slate400, white, zinc800, zinc900 } from '@/lib/colors';
import { advercase, dinot } from '@/lib/fonts';

interface FeedbackModalProps {
visible: boolean;
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/FeedbackModalScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {

import ModalClose from '@/images/icons/modal_close.svg';
import LogoInversed from '@/images/logo_inversed.svg';
import { white } from '@/utils/colors';
import { confirmTap, impactLight } from '@/utils/haptic';
import { confirmTap, impactLight } from '@/integrations/haptics';
import { white } from '@/lib/colors';

const ModalBackDrop = styled(View, {
display: 'flex',
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/Mnemonic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, { useCallback, useState } from 'react';
import { Button, Text, XStack, YStack } from 'tamagui';
import Clipboard from '@react-native-clipboard/clipboard';

import { useSettingStore } from '@/stores/settingStore';
import { confirmTap } from '@/integrations/haptics';
import {
black,
slate50,
Expand All @@ -15,8 +15,8 @@ import {
slate500,
teal500,
white,
} from '@/utils/colors';
import { confirmTap } from '@/utils/haptic';
} from '@/lib/colors';
import { useSettingStore } from '@/stores/settingStore';

interface MnemonicProps {
words?: string[];
Expand Down
8 changes: 4 additions & 4 deletions app/src/components/NavBar/AadhaarNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { ChevronLeft, HelpCircle } from '@tamagui/lucide-icons';
import { Button, XStack, YStack } from '@selfxyz/mobile-sdk-alpha/components';

import { NavBar } from '@/components/NavBar/BaseNavBar';
import { black, slate100, slate300 } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
import { dinot } from '@/utils/fonts';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { black, slate100, slate300 } from '@/lib/colors';
import { extraYPadding } from '@/lib/constants';
import { dinot } from '@/lib/fonts';

export const AadhaarNavBar = (props: NativeStackHeaderProps) => {
const insets = useSafeAreaInsets();
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/NavBar/DefaultNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
import type { NativeStackHeaderProps } from '@react-navigation/native-stack';

import { NavBar } from '@/components/NavBar/BaseNavBar';
import { white } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { white } from '@/lib/colors';
import { extraYPadding } from '@/lib/constants';

export const DefaultNavBar = (props: NativeStackHeaderProps) => {
const { goBack, canGoBack } = props.navigation;
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/NavBar/DocumentFlowNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { useNavigation } from '@react-navigation/native';
import { HelpCircle } from '@tamagui/lucide-icons';

import { NavBar } from '@/components/NavBar/BaseNavBar';
import { slate100 } from '@/utils/colors';
import { dinot } from '@/utils/fonts';
import { slate100 } from '@/lib/colors';
import { dinot } from '@/lib/fonts';

export const DocumentFlowNavBar = ({
title,
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/NavBar/HomeNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { NavBar } from '@/components/NavBar/BaseNavBar';
import ActivityIcon from '@/images/icons/activity.svg';
import ScanIcon from '@/images/icons/qr_scan.svg';
import SettingsIcon from '@/images/icons/settings.svg';
import { black, charcoal, slate50 } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { black, charcoal, slate50 } from '@/lib/colors';
import { extraYPadding } from '@/lib/constants';

export const HomeNavBar = (props: NativeStackHeaderProps) => {
const selfClient = useSelfClient();
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/NavBar/IdDetailsNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import type { NativeStackHeaderProps } from '@react-navigation/native-stack';
import { Button, Text, View } from '@selfxyz/mobile-sdk-alpha/components';

import { NavBar } from '@/components/NavBar/BaseNavBar';
import { black, charcoal, slate50 } from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { black, charcoal, slate50 } from '@/lib/colors';
import { extraYPadding } from '@/lib/constants';

export const IdDetailsNavBar = (props: NativeStackHeaderProps) => {
const insets = useSafeAreaInsets();
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/NavBar/WebViewNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { ExternalLink, X } from '@tamagui/lucide-icons';

import { Button, XStack } from '@selfxyz/mobile-sdk-alpha/components';

import { black } from '@/utils/colors';
import { dinot } from '@/utils/fonts';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { black } from '@/lib/colors';
import { dinot } from '@/lib/fonts';

export interface WebViewNavBarProps {
title?: string;
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/Tips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Text, View } from 'tamagui';

import { Caption } from '@selfxyz/mobile-sdk-alpha/components';

import { slate500 } from '@/utils/colors';
import { slate500 } from '@/lib/colors';

export interface TipProps {
title: string;
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/WebViewFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { ArrowLeft, ArrowRight, RotateCcw } from '@tamagui/lucide-icons';

import { Button, XStack, YStack } from '@selfxyz/mobile-sdk-alpha/components';

import { black, slate50, slate400 } from '@/utils/colors';
import { buttonTap } from '@/utils/haptic';
import { buttonTap } from '@/integrations/haptics';
import { black, slate50, slate400 } from '@/lib/colors';

export interface WebViewFooterProps {
canGoBack: boolean;
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/homeScreen/idCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import {
slate400,
slate500,
white,
} from '@/utils/colors';
import { dinot, plexMono } from '@/utils/fonts';
} from '@/lib/colors';
import { dinot, plexMono } from '@/lib/fonts';

// Import the logo SVG as a string
const logoSvg = `<svg width="47" height="46" viewBox="0 0 47 46" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/loading/LoadingUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import {
white,
zinc500,
zinc900,
} from '@/utils/colors';
import { extraYPadding } from '@/utils/constants';
import { advercase, dinot } from '@/utils/fonts';
} from '@/lib/colors';
import { extraYPadding } from '@/lib/constants';
import { advercase, dinot } from '@/lib/fonts';

interface LoadingUIProps {
animationSource: LottieView['props']['source'];
Expand Down
7 changes: 7 additions & 0 deletions app/src/devtools/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// 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.

// Re-export all devtools modules
export * from '@/devtools/mocks';
export * from '@/devtools/testing';
6 changes: 6 additions & 0 deletions app/src/devtools/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// 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.

// Re-export all mocks for easier imports
export * from '@/devtools/mocks/nfcScanner';
File renamed without changes.
6 changes: 6 additions & 0 deletions app/src/devtools/testing/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// 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.

// Re-export all testing utilities for easier imports
export * from '@/devtools/testing/utils';
File renamed without changes.
2 changes: 1 addition & 1 deletion app/src/hooks/useAppUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { AppEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';

import { registerModalCallbacks } from '@/lib/ui/modalCallbackRegistry';
import type { RootStackParamList } from '@/navigation';
import { registerModalCallbacks } from '@/utils/modalCallbackRegistry';

export const useAppUpdates = (): [boolean, () => void, boolean] => {
const navigation =
Expand Down
2 changes: 1 addition & 1 deletion app/src/hooks/useAppUpdates.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { AppEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';

import { registerModalCallbacks } from '@/lib/ui/modalCallbackRegistry';
import type { RootStackParamList } from '@/navigation';
import { registerModalCallbacks } from '@/utils/modalCallbackRegistry';

export const useAppUpdates = (): [boolean, () => void, boolean] => {
const navigation =
Expand Down
2 changes: 1 addition & 1 deletion app/src/hooks/useConnectionModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { SettingsEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { useModal } from '@/hooks/useModal';
import { useNetInfo } from '@/hooks/useNetInfo';
import { navigationRef } from '@/navigation';
import analytics from '@/services/analytics';
import { useSettingStore } from '@/stores/settingStore';
import analytics from '@/utils/analytics';

const { trackEvent } = analytics();

Expand Down
6 changes: 5 additions & 1 deletion app/src/hooks/useHapticNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import { useCallback } from 'react';
import type { NavigationProp } from '@react-navigation/native';
import { useNavigation } from '@react-navigation/native';

import {
impactLight,
impactMedium,
selectionChange,
} from '@/integrations/haptics';
import type { RootStackParamList } from '@/navigation/index';
import { impactLight, impactMedium, selectionChange } from '@/utils/haptic';

type NavigationAction = 'default' | 'cancel' | 'confirm';

Expand Down
6 changes: 3 additions & 3 deletions app/src/hooks/useModal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { useCallback, useRef, useState } from 'react';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';

import type { RootStackParamList } from '@/navigation';
import type { ModalParams } from '@/screens/app/ModalScreen';
import {
getModalCallbacks,
registerModalCallbacks,
unregisterModalCallbacks,
} from '@/utils/modalCallbackRegistry';
} from '@/lib/ui/modalCallbackRegistry';
import type { RootStackParamList } from '@/navigation';
import type { ModalParams } from '@/screens/app/ModalScreen';

export const useModal = (params: ModalParams) => {
const [visible, setVisible] = useState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

// Re-export all haptic functionality from the mobile SDK
export type { HapticOptions, HapticType } from '@selfxyz/mobile-sdk-alpha';
export {
buttonTap,
cancelTap,
Expand All @@ -19,4 +20,3 @@ export {
selectionChange,
triggerFeedback,
} from '@selfxyz/mobile-sdk-alpha';
export type { HapticOptions, HapticType } from '@selfxyz/mobile-sdk-alpha';
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import { Platform } from 'react-native';
import type { PassportData } from '@selfxyz/common/types';
import type { NFCScanContext } from '@selfxyz/mobile-sdk-alpha';

import { logNFCEvent } from '@/Sentry';
import {
type AndroidScanResponse,
reset,
scan as scanDocument,
} from '@/utils/passportReader';
import { PassportReader } from '@/utils/passportReader';
} from '@/integrations/nfc/passportReader';
import { PassportReader } from '@/integrations/nfc/passportReader';
import { logNFCEvent } from '@/Sentry';

interface Inputs {
passportNumber: string;
Expand Down
File renamed without changes.
Loading
Loading