Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
12 changes: 6 additions & 6 deletions .github/workflows/circuits-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ on:
workflow_dispatch:
inputs:
circuit-type:
description: 'Circuits to build (comma-separated: register, register_id, register_aadhaar, disclose, dsc). Leave empty to build all.'
description: "Circuits to build (comma-separated: register, register_id, register_aadhaar, disclose, dsc). Leave empty to build all."
required: false
type: string
default: ''
default: ""
circuit-name:
description: 'Circuit names to build (comma-separated: register_sha256_sha224_sha224_ecdsa_secp224r1, dsc_sha256_rsa_65537_4096). Cannot be used with circuit-type.'
description: "Circuit names to build (comma-separated: register_sha256_sha224_sha224_ecdsa_secp224r1, dsc_sha256_rsa_65537_4096). Cannot be used with circuit-type."
required: false
type: string
default: ''
default: ""
run-id:
description: 'Run ID to download artifacts .'
description: "Run ID to download artifacts ."
required: false
type: string
default: ''
default: ""

concurrency:
group: circuits-build-${{ github.workflow }}-${{ github.ref }}
Expand Down
10 changes: 10 additions & 0 deletions app/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,16 @@ module.exports = {
'@typescript-eslint/ban-ts-comment': 'off',
'no-empty': 'off',

// TypeScript Import Rules

'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: false,
},
],

// Override rules conflicting with TypeScript union formatting

'@typescript-eslint/indent': 'off',
Expand Down
3 changes: 2 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@
"@testing-library/react-native": "^13.3.3",
"@tsconfig/react-native": "^3.0.6",
"@types/add": "^2",
"@types/bn.js": "^5.2.0",
"@types/dompurify": "^3.2.0",
"@types/elliptic": "^6",
"@types/elliptic": "^6.4.18",
"@types/jest": "^29.5.14",
"@types/node": "^22.18.3",
"@types/node-forge": "^1.3.14",
Expand Down
150 changes: 102 additions & 48 deletions app/scripts/alias-imports.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,124 @@ function transformProjectToAliasImports(project, appRootPath) {

// Handle import declarations
for (const declaration of sourceFile.getImportDeclarations()) {
const spec = declaration.getModuleSpecifierValue();
try {
// Skip if no module specifier or not a string literal
const moduleSpecifier = declaration.getModuleSpecifier();
if (
!moduleSpecifier ||
moduleSpecifier.getKind() !== SyntaxKind.StringLiteral
) {
continue;
}

// Skip existing alias imports
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
continue;
}
const spec = declaration.getModuleSpecifierValue();

// Handle relative imports
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
const abs = path.resolve(dir, spec);
let baseDir = null;
let baseAlias = null;
// Skip existing alias imports
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
continue;
}

// Determine containment safely using path.relative to avoid startsWith false positives
const relFromSrc = path.relative(srcDir, abs);
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
baseDir = srcDir;
baseAlias = '@';
} else {
const relFromTests = path.relative(testsDir, abs);
if (!relFromTests.startsWith('..') && !path.isAbsolute(relFromTests)) {
baseDir = testsDir;
baseAlias = '@tests';
// Handle relative imports
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
const abs = path.resolve(dir, spec);
let baseDir = null;
let baseAlias = null;

// Determine containment safely using path.relative to avoid startsWith false positives
const relFromSrc = path.relative(srcDir, abs);
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
baseDir = srcDir;
baseAlias = '@';
} else {
continue;
const relFromTests = path.relative(testsDir, abs);
if (
!relFromTests.startsWith('..') &&
!path.isAbsolute(relFromTests)
) {
baseDir = testsDir;
baseAlias = '@tests';
} else {
continue;
}
}
}

const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
declaration.setModuleSpecifier(newSpec);
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
declaration.setModuleSpecifier(newSpec);
} catch (error) {
// Skip declarations that can't be processed (e.g., type-only imports with issues)
const msg = error instanceof Error ? error.message : String(error);
console.warn(
`Skipping import declaration in ${sourceFile.getFilePath()}: ${msg}`,
);
try {
console.debug('Import declaration text:', declaration.getText());
} catch {}
if (error && typeof error === 'object' && 'stack' in error) {
console.debug('Error stack:', error.stack);
}
continue;
}
}

// Handle export declarations like: export * from '../x' or export {A} from '../x'
for (const declaration of sourceFile.getExportDeclarations()) {
const spec = declaration.getModuleSpecifierValue();
if (!spec) continue;
try {
// Skip if no module specifier or not a string literal
const moduleSpecifier = declaration.getModuleSpecifier();
if (
!moduleSpecifier ||
moduleSpecifier.getKind() !== SyntaxKind.StringLiteral
) {
continue;
}

// Skip existing alias exports
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
continue;
}
const spec = declaration.getModuleSpecifierValue();
if (!spec) continue;

// Handle relative exports
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
const abs = path.resolve(dir, spec);
let baseDir = null;
let baseAlias = null;
// Skip existing alias exports
if (spec.startsWith('@/') || spec.startsWith('@tests/')) {
continue;
}

const relFromSrc = path.relative(srcDir, abs);
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
baseDir = srcDir;
baseAlias = '@';
} else {
const relFromTests = path.relative(testsDir, abs);
if (!relFromTests.startsWith('..') && !path.isAbsolute(relFromTests)) {
baseDir = testsDir;
baseAlias = '@tests';
// Handle relative exports
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
const abs = path.resolve(dir, spec);
let baseDir = null;
let baseAlias = null;

const relFromSrc = path.relative(srcDir, abs);
if (!relFromSrc.startsWith('..') && !path.isAbsolute(relFromSrc)) {
baseDir = srcDir;
baseAlias = '@';
} else {
continue;
const relFromTests = path.relative(testsDir, abs);
if (
!relFromTests.startsWith('..') &&
!path.isAbsolute(relFromTests)
) {
baseDir = testsDir;
baseAlias = '@tests';
} else {
continue;
}
}
}

const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
declaration.setModuleSpecifier(newSpec);
const newSpec = determineAliasStrategy(dir, abs, baseDir, baseAlias);
declaration.setModuleSpecifier(newSpec);
} catch (error) {
// Skip declarations that can't be processed
const msg = error instanceof Error ? error.message : String(error);
console.warn(
`Skipping export declaration in ${sourceFile.getFilePath()}: ${msg}`,
);
try {
console.debug('Export declaration text:', declaration.getText());
} catch {}
if (error && typeof error === 'object' && 'stack' in error) {
console.debug('Error stack:', error.stack);
}
continue;
}
}

// Handle require() calls
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/DelayedLottieView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import type { LottieViewProps } from 'lottie-react-native';
import LottieView from 'lottie-react-native';
import React, { useEffect, useRef } from 'react';
import React, { forwardRef, useEffect, useRef } from 'react';

/**
* Wrapper around LottieView that fixes iOS native module initialization timing.
Expand All @@ -20,7 +20,7 @@ import React, { useEffect, useRef } from 'react';
* @example
* <DelayedLottieView autoPlay loop source={animation} style={styles.animation} />
*/
export const DelayedLottieView = React.forwardRef<LottieView, LottieViewProps>(
export const DelayedLottieView = forwardRef<LottieView, LottieViewProps>(
(props, forwardedRef) => {
const internalRef = useRef<LottieView>(null);
const ref = (forwardedRef as React.RefObject<LottieView>) || internalRef;
Expand Down
7 changes: 6 additions & 1 deletion app/src/components/buttons/AbstractButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

import React from 'react';
import type { GestureResponderEvent, ViewStyle } from 'react-native';
import type {
GestureResponderEvent,
LayoutChangeEvent,
ViewStyle,
} from 'react-native';
import { Platform, StyleSheet } from 'react-native';
import type { ViewProps } from 'tamagui';
import { Button, Text } from 'tamagui';
Expand All @@ -16,6 +20,7 @@ export interface ButtonProps extends ViewProps {
children: React.ReactNode;
animatedComponent?: React.ReactNode;
trackEvent?: string;
onLayout?: (event: LayoutChangeEvent) => void;
}

interface AbstractButtonProps extends ButtonProps {
Expand Down
1 change: 0 additions & 1 deletion app/src/components/buttons/PrimaryButtonLongHold.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export function HeldPrimaryButton({
{...props}
onPressIn={onPressIn}
onPressOut={onPressOut}
// @ts-expect-error actually it is there
onLayout={getButtonSize}
animatedComponent={renderAnimatedComponent()}
>
Expand Down
1 change: 0 additions & 1 deletion app/src/components/buttons/PrimaryButtonLongHold.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ export function HeldPrimaryButton({
{...props}
onPressIn={onPressIn}
onPressOut={onPressOut}
// @ts-expect-error actually it is there
onLayout={getButtonSize}
animatedComponent={renderAnimatedComponent()}
>
Expand Down
13 changes: 4 additions & 9 deletions app/src/components/homeScreen/SvgXmlWrapper.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

import React, { forwardRef } from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import type { ComponentProps } from 'react';
import React from 'react';
import { SvgXml as RNSvgXml } from 'react-native-svg';

type Props = {
xml: string;
width?: number;
height?: number;
style?: StyleProp<ViewStyle>;
};
type Props = ComponentProps<typeof RNSvgXml>;

export const SvgXml = forwardRef<any, Props>((p, _ref) => <RNSvgXml {...p} />);
export const SvgXml: React.FC<Props> = props => <RNSvgXml {...props} />;
SvgXml.displayName = 'SvgXml';
export default SvgXml;
4 changes: 2 additions & 2 deletions app/src/components/homeScreen/SvgXmlWrapper.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

import DOMPurify from 'dompurify';
import createDOMPurify from 'dompurify';
import {
createElement,
type CSSProperties,
Expand All @@ -20,7 +20,7 @@ type Props = {
export const SvgXml = forwardRef<HTMLDivElement, Props>(
({ xml, width, height, style, ...props }, ref) => {
// Initialize DOMPurify for web browser environment
const purify = DOMPurify(window);
const purify = createDOMPurify(window);
const safe = purify.sanitize(xml, {
USE_PROFILES: { svg: true, svgFilters: true },
});
Expand Down
3 changes: 2 additions & 1 deletion app/src/components/homeScreen/idCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.

import React, { type FC } from 'react';
import type { FC } from 'react';
import React from 'react';
import { Dimensions } from 'react-native';
import { Separator, Text, XStack, YStack } from 'tamagui';

Expand Down
11 changes: 8 additions & 3 deletions app/src/components/native/PassportCamera.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import React, { useCallback } from 'react';
import type { NativeSyntheticEvent, StyleProp, ViewStyle } from 'react-native';
import { PixelRatio, Platform, requireNativeComponent } from 'react-native';

import { type SelfClient, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import type { SelfClient } from '@selfxyz/mobile-sdk-alpha';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';

import { RCTFragment } from '@/components/native/RCTFragment';

Expand Down Expand Up @@ -69,9 +70,13 @@ export const PassportCamera: React.FC<PassportCameraProps> = ({
if (!isMounted) {
return;
}
/* eslint-disable @typescript-eslint/no-unused-vars */
const { error, errorMessage, stackTrace } = event.nativeEvent;
const {
error: nativeError,
errorMessage,
stackTrace,
} = event.nativeEvent;
const e = new Error(errorMessage);
e.name = nativeError;
e.stack = stackTrace;
onPassportRead(e);
},
Expand Down
3 changes: 2 additions & 1 deletion app/src/components/native/PassportCamera.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

import React, { useCallback, useEffect } from 'react';

import { type SelfClient, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import type { SelfClient } from '@selfxyz/mobile-sdk-alpha';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';

// TODO: Web find a lightweight ocr or mrz scanner.

Expand Down
8 changes: 6 additions & 2 deletions app/src/components/native/QRCodeScanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ export const QRCodeScannerView: React.FC<QRCodeScannerViewProps> = ({
if (!isMounted) {
return;
}
/* eslint-disable @typescript-eslint/no-unused-vars */
const { error, errorMessage, stackTrace } = event.nativeEvent;
const {
error: nativeError,
errorMessage,
stackTrace,
} = event.nativeEvent;
const e = new Error(errorMessage);
e.name = nativeError;
e.stack = stackTrace;
onQRData(e);
},
Expand Down
Loading
Loading