Revert "Mobile SDK: move provingMachine from the app (#1052)" (#1084)

This reverts commit 8983ac2268.
This commit is contained in:
Justin Hernandez
2025-09-17 12:48:42 -07:00
committed by GitHub
parent 8983ac2268
commit 3397fcf43b
40 changed files with 1158 additions and 1125 deletions

View File

@@ -15,11 +15,13 @@ import {
wrap,
} from '@sentry/react-native';
import type {
BaseContext,
NFCScanContext,
ProofContext,
} from '@selfxyz/mobile-sdk-alpha';
interface BaseContext {
sessionId: string;
userId?: string;
platform: 'ios' | 'android';
stage: string;
}
// Security: Whitelist of allowed tag keys to prevent XSS
const ALLOWED_TAG_KEYS = new Set([
'session_id',
@@ -87,6 +89,15 @@ const sanitizeTagKey = (key: string): string | null => {
return key;
};
export interface NFCScanContext extends BaseContext, Record<string, unknown> {
scanType: 'mrz' | 'can';
}
export interface ProofContext extends BaseContext, Record<string, unknown> {
circuitType: 'register' | 'dsc' | 'disclose' | null;
currentState: string;
}
export const captureException = (
error: Error,
context?: Record<string, unknown>,

View File

@@ -19,7 +19,6 @@ import {
import { navigationRef } from '@/navigation';
import { unsafe_getPrivateKey } from '@/providers/authProvider';
import { selfClientDocumentsAdapter } from '@/providers/passportDataProvider';
import { logNFCEvent, logProofEvent } from '@/Sentry';
import analytics from '@/utils/analytics';
type GlobalCrypto = { crypto?: { subtle?: Crypto['subtle'] } };
@@ -95,15 +94,6 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => {
auth: {
getPrivateKey: () => unsafe_getPrivateKey(),
},
notification: {
registerDeviceToken: async (sessionId, deviceToken, isMock) => {
// Forward to our app-level function which handles staging vs production
// and also fetches the token if not provided
const { registerDeviceToken: registerFirebaseDeviceToken } =
await import('@/utils/notifications/notificationService');
return registerFirebaseDeviceToken(sessionId, deviceToken, isMock);
},
},
}),
[],
);
@@ -158,16 +148,6 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => {
}
});
addListener(SdkEvents.PROOF_EVENT, ({ level, context, event, details }) => {
// Log proof events for monitoring/debugging
logProofEvent(level, event, context, details);
});
addListener(SdkEvents.NFC_EVENT, ({ level, context, event, details }) => {
// Log nfc events for monitoring/debugging
logNFCEvent(level, event, context, details);
});
return map;
}, []);

View File

@@ -8,7 +8,7 @@ import { ActivityIndicator, View } from 'react-native';
import type { StaticScreenProps } from '@react-navigation/native';
import { usePreventRemove } from '@react-navigation/native';
import { useProvingStore, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import {
PassportEvents,
ProofEvents,
@@ -28,6 +28,7 @@ import {
getFCMToken,
requestNotificationPermission,
} from '@/utils/notifications/notificationService';
import { useProvingStore } from '@/utils/proving/provingMachine';
type ConfirmBelongingScreenProps = StaticScreenProps<Record<string, never>>;

View File

@@ -9,7 +9,7 @@ import { SystemBars } from 'react-native-edge-to-edge';
import { ScrollView, Spinner } from 'tamagui';
import { useIsFocused } from '@react-navigation/native';
import { useProvingStore, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { useSelfAppStore } from '@selfxyz/mobile-sdk-alpha/stores';
@@ -31,6 +31,7 @@ import {
notificationError,
notificationSuccess,
} from '@/utils/haptic';
import { useProvingStore } from '@/utils/proving/provingMachine';
const SuccessScreen: React.FC = () => {
const { trackEvent } = useSelfClient();

View File

@@ -22,7 +22,7 @@ import { Eye, EyeOff } from '@tamagui/lucide-icons';
import type { SelfAppDisclosureConfig } from '@selfxyz/common/utils/appType';
import { formatEndpoint } from '@selfxyz/common/utils/scope';
import { useProvingStore, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { useSelfAppStore } from '@selfxyz/mobile-sdk-alpha/stores';
@@ -41,6 +41,7 @@ import { useProofHistoryStore } from '@/stores/proofHistoryStore';
import { black, slate300, white } from '@/utils/colors';
import { formatUserId } from '@/utils/formatUserId';
import { buttonTap } from '@/utils/haptic';
import { useProvingStore } from '@/utils/proving/provingMachine';
const ProveScreen: React.FC = () => {
const selfClient = useSelfClient();

View File

@@ -11,10 +11,6 @@ import type { StaticScreenProps } from '@react-navigation/native';
import { useIsFocused } from '@react-navigation/native';
import type { PassportData } from '@selfxyz/common/types';
import {
type ProvingStateType,
useProvingStore,
} from '@selfxyz/mobile-sdk-alpha';
import failAnimation from '@/assets/animations/loading/fail.json';
import proveLoadingAnimation from '@/assets/animations/loading/prove.json';
@@ -27,6 +23,8 @@ import { advercase, dinot } from '@/utils/fonts';
import { loadingScreenProgress } from '@/utils/haptic';
import { setupNotifications } from '@/utils/notifications/notificationService';
import { getLoadingScreenText } from '@/utils/proving/loadingScreenStateText';
import type { ProvingStateType } from '@/utils/proving/provingMachine';
import { useProvingStore } from '@/utils/proving/provingMachine';
type LoadingScreenProps = StaticScreenProps<Record<string, never>>;

View File

@@ -13,8 +13,7 @@ export const loadCryptoUtils = async () => {
export const loadProvingUtils = async () => {
return Promise.all([
// TODO: can it be safely removed?
// import('@/utils/proving/provingMachine'),
import('@/utils/proving/provingMachine'),
import('@/utils/proving/validateDocument'),
]);
};

View File

@@ -6,9 +6,8 @@ import { Buffer } from 'buffer';
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 { logNFCEvent, type NFCScanContext } from '@/Sentry';
import { configureNfcAnalytics } from '@/utils/analytics';
import {
PassportReader,

View File

@@ -5,7 +5,7 @@
// Only export what's actually used elsewhere to enable proper tree shaking
// From provingMachine - used in screens and tests
export type { ProvingStateType } from '@selfxyz/mobile-sdk-alpha';
export type { ProvingStateType } from '@/utils/proving/provingMachine';
// From provingUtils - used in tests (keeping these for testing purposes)
export {
encryptAES256GCM,
@@ -16,4 +16,4 @@ export {
// From loadingScreenStateText - used in loading screen
export { getLoadingScreenText } from '@/utils/proving/loadingScreenStateText';
export { useProvingStore } from '@selfxyz/mobile-sdk-alpha';
export { useProvingStore } from '@/utils/proving/provingMachine';

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import type { ProvingStateType } from '@selfxyz/mobile-sdk-alpha';
import type { ProvingStateType } from '@/utils/proving/provingMachine';
interface LoadingScreenText {
actionText: string;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
// 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.
export interface StatusHandlerResult {
shouldDisconnect: boolean;
stateUpdate?: {
error_code?: string;
reason?: string;
socketConnection?: null;
};
actorEvent?: {
type: 'PROVE_FAILURE' | 'PROVE_SUCCESS';
};
analytics?: Array<{
event: string;
data?: Record<string, unknown>;
}>;
}
/**
* Pure functions for handling Socket.IO status messages
* These can be tested independently without mocking complex dependencies
*/
export interface StatusMessage {
status: number;
error_code?: string;
reason?: string;
}
/**
* Determine actions to take based on status code
*/
export function handleStatusCode(
data: StatusMessage,
circuitType: string,
): StatusHandlerResult {
const result: StatusHandlerResult = {
shouldDisconnect: false,
analytics: [],
};
// Failure statuses (3 or 5)
if (data.status === 3 || data.status === 5) {
result.shouldDisconnect = true;
result.stateUpdate = {
error_code: data.error_code,
reason: data.reason,
socketConnection: null,
};
result.actorEvent = { type: 'PROVE_FAILURE' };
result.analytics = [
{
event: 'SOCKETIO_PROOF_FAILURE',
data: {
error_code: data.error_code,
reason: data.reason,
},
},
];
return result;
}
// Success status (4)
if (data.status === 4) {
result.shouldDisconnect = true;
result.stateUpdate = {
socketConnection: null,
};
result.actorEvent = { type: 'PROVE_SUCCESS' };
result.analytics = [
{
event: 'SOCKETIO_PROOF_SUCCESS',
},
];
// Additional tracking for register circuit
if (circuitType === 'register') {
result.analytics.push({
event: 'REGISTER_COMPLETED',
});
}
return result;
}
// Other statuses - no action needed
return result;
}
/**
* Parse incoming socket message into structured data
*/
export function parseStatusMessage(message: unknown): StatusMessage {
if (typeof message === 'string') {
try {
return JSON.parse(message) as StatusMessage;
} catch {
throw new Error('Invalid JSON message received');
}
}
if (typeof message === 'object' && message !== null) {
return message as StatusMessage;
}
throw new Error('Invalid message format');
}