diff --git a/app/src/screens/ProveFlow/ProofRequestStatusScreen.tsx b/app/src/screens/ProveFlow/ProofRequestStatusScreen.tsx
index 6e6680337..d0a32d280 100644
--- a/app/src/screens/ProveFlow/ProofRequestStatusScreen.tsx
+++ b/app/src/screens/ProveFlow/ProofRequestStatusScreen.tsx
@@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { StatusBar, StyleSheet, View } from 'react-native';
import LottieView from 'lottie-react-native';
-import { Spinner } from 'tamagui';
+import { ScrollView, Spinner } from 'tamagui';
import loadingAnimation from '../../assets/animations/loading/misc.json';
import failAnimation from '../../assets/animations/proof_failed.json';
@@ -23,7 +23,8 @@ import {
} from '../../utils/haptic';
const SuccessScreen: React.FC = () => {
- const { selectedApp, disclosureStatus, cleanSelfApp } = useProofInfo();
+ const { selectedApp, disclosureStatus, discloseError, cleanSelfApp } =
+ useProofInfo();
const appName = selectedApp?.appName;
const goHome = useHapticNavigation('Home');
@@ -69,6 +70,7 @@ const SuccessScreen: React.FC = () => {
- Unable to prove your identity to{' '}
- {appName}
- {status === 'error' && '. Due to technical issues.'}
-
+
+
+ Unable to prove your identity to{' '}
+ {appName}
+ {status === 'error' && '. Due to technical issues.'}
+
+ {status === 'failure' && reason && (
+ <>
+
+
+ Reason:
+
+
+
+
+
+
+ {reason}
+
+
+
+
+ >
+ )}
+
);
} else {
return (
diff --git a/app/src/screens/ProveFlow/ProveScreen.tsx b/app/src/screens/ProveFlow/ProveScreen.tsx
index d5f22ea3b..ef152ed56 100644
--- a/app/src/screens/ProveFlow/ProveScreen.tsx
+++ b/app/src/screens/ProveFlow/ProveScreen.tsx
@@ -168,7 +168,9 @@ const ProveScreen: React.FC = () => {
);
handleProofResult(
currentApp.sessionId,
- status === ProofStatusEnum.SUCCESS,
+ status?.status === ProofStatusEnum.SUCCESS,
+ status?.error_code,
+ status?.reason,
);
} catch (e) {
console.log('Error in verification process');
diff --git a/app/src/stores/appProvider.tsx b/app/src/stores/appProvider.tsx
index 8ff2c32dc..ef017be59 100644
--- a/app/src/stores/appProvider.tsx
+++ b/app/src/stores/appProvider.tsx
@@ -28,7 +28,12 @@ interface IAppContext {
* @param sessionId - The session ID from the scanned QR code.
* @param success - Whether the proof was verified successfully.
*/
- handleProofResult: (sessionId: string, success: boolean) => void;
+ handleProofResult: (
+ sessionId: string,
+ success: boolean,
+ error_code?: string,
+ reason?: string,
+ ) => void;
}
const AppContext = createContext({
@@ -120,7 +125,12 @@ export const AppProvider: React.FC<{ children: React.ReactNode }> = ({
}
};
- const handleProofResult = (sessionId: string, proof_verified: boolean) => {
+ const handleProofResult = (
+ sessionId: string,
+ proof_verified: boolean,
+ error_code?: string,
+ reason?: string,
+ ) => {
console.log(
'[AppProvider] handleProofResult called with sessionId:',
sessionId,
@@ -143,11 +153,15 @@ export const AppProvider: React.FC<{ children: React.ReactNode }> = ({
'[AppProvider] Emitting proof_generation_failed event with data:',
{
session_id: sessionId,
+ error_code,
+ reason,
},
);
socketRef.current.emit('proof_generation_failed', {
session_id: sessionId,
+ error_code,
+ reason,
});
}
};
diff --git a/app/src/stores/proofProvider.tsx b/app/src/stores/proofProvider.tsx
index a4cd2c797..bfe278608 100644
--- a/app/src/stores/proofProvider.tsx
+++ b/app/src/stores/proofProvider.tsx
@@ -16,9 +16,15 @@ export enum ProofStatusEnum {
ERROR = 'error',
}
+export type DiscloseError = {
+ error_code?: string;
+ reason?: string;
+};
+
interface IProofContext {
registrationStatus: ProofStatusEnum;
disclosureStatus: ProofStatusEnum;
+ discloseError: DiscloseError | undefined;
selectedApp: SelfApp;
setSelectedApp: (app: SelfApp) => void;
cleanSelfApp: () => void;
@@ -28,6 +34,7 @@ interface IProofContext {
const defaults: IProofContext = {
registrationStatus: ProofStatusEnum.PENDING,
disclosureStatus: ProofStatusEnum.PENDING,
+ discloseError: undefined,
selectedApp: {
appName: '',
logoBase64: '',
@@ -52,7 +59,7 @@ export let globalSetRegistrationStatus:
| ((status: ProofStatusEnum) => void)
| null = null;
export let globalSetDisclosureStatus:
- | ((status: ProofStatusEnum) => void)
+ | ((status: ProofStatusEnum, error?: DiscloseError) => void)
| null = null;
/*
@@ -66,6 +73,10 @@ export function ProofProvider({ children }: PropsWithChildren<{}>) {
ProofStatusEnum.PENDING,
);
+ const [discloseError, setDiscloseError] = useState(
+ undefined,
+ );
+
const [selectedApp, setSelectedAppInternal] = useState(
defaults.selectedApp,
);
@@ -75,6 +86,7 @@ export function ProofProvider({ children }: PropsWithChildren<{}>) {
return;
}
setRegistrationStatus(ProofStatusEnum.PENDING);
+ setDiscloseError(undefined);
setSelectedAppInternal(app);
}, []);
@@ -87,11 +99,15 @@ export function ProofProvider({ children }: PropsWithChildren<{}>) {
const resetProof = useCallback(() => {
setRegistrationStatus(ProofStatusEnum.PENDING);
setDisclosureStatus(ProofStatusEnum.PENDING);
+ setDiscloseError(undefined);
}, []);
useEffect(() => {
globalSetRegistrationStatus = setRegistrationStatus;
- globalSetDisclosureStatus = setDisclosureStatus;
+ globalSetDisclosureStatus = (status, error) => {
+ setDisclosureStatus(status);
+ setDiscloseError(error);
+ };
return () => {
globalSetRegistrationStatus = null;
globalSetDisclosureStatus = null;
@@ -102,6 +118,7 @@ export function ProofProvider({ children }: PropsWithChildren<{}>) {
() => ({
registrationStatus,
disclosureStatus,
+ discloseError,
selectedApp,
setSelectedApp,
cleanSelfApp,
@@ -110,8 +127,10 @@ export function ProofProvider({ children }: PropsWithChildren<{}>) {
[
registrationStatus,
disclosureStatus,
+ discloseError,
selectedApp,
setSelectedApp,
+ setDiscloseError,
cleanSelfApp,
resetProof,
],
diff --git a/app/src/utils/proving/payload.ts b/app/src/utils/proving/payload.ts
index 850f6fdf6..00241f791 100644
--- a/app/src/utils/proving/payload.ts
+++ b/app/src/utils/proving/payload.ts
@@ -120,7 +120,7 @@ async function checkIdPassportDscIsInTree(
circuitDNSMapping,
endpointType,
);
- if (dscStatus !== ProofStatusEnum.SUCCESS) {
+ if (dscStatus.status !== ProofStatusEnum.SUCCESS) {
console.log('DSC proof failed');
return false;
}
@@ -140,9 +140,9 @@ export async function sendDscPayload(
passportData: PassportData,
circuitDNSMapping: Record,
endpointType: EndpointType,
-): Promise {
+): Promise<{ status: ProofStatusEnum; error_code?: string; reason?: string }> {
if (!passportData) {
- return false;
+ return { status: ProofStatusEnum.FAILURE };
}
// const isSupported = checkPassportSupported(passportData);
// if (!isSupported) {
diff --git a/app/src/utils/proving/tee.ts b/app/src/utils/proving/tee.ts
index dcd68b1c6..4f0a9a020 100644
--- a/app/src/utils/proving/tee.ts
+++ b/app/src/utils/proving/tee.ts
@@ -10,6 +10,7 @@ import {
} from '../../../../common/src/constants/constants';
import { EndpointType } from '../../../../common/src/utils/appType';
import {
+ DiscloseError,
ProofStatusEnum,
globalSetDisclosureStatus,
globalSetRegistrationStatus,
@@ -67,7 +68,7 @@ export async function sendPayload(
updateGlobalOnFailure?: boolean;
flow?: 'registration' | 'disclosure';
},
-): Promise {
+): Promise<{ status: ProofStatusEnum; error_code?: string; reason?: string }> {
const opts = {
updateGlobalOnSuccess: true,
updateGlobalOnFailure: true,
@@ -75,7 +76,11 @@ export async function sendPayload(
};
return new Promise(resolve => {
let finalized = false;
- function finalize(status: ProofStatusEnum) {
+ function finalize(
+ status: ProofStatusEnum,
+ error_code?: string,
+ reason?: string,
+ ) {
if (!finalized) {
finalized = true;
clearTimeout(timer);
@@ -84,12 +89,15 @@ export async function sendPayload(
(status !== ProofStatusEnum.SUCCESS && opts.updateGlobalOnFailure)
) {
if (options?.flow === 'disclosure') {
- globalSetDisclosureStatus && globalSetDisclosureStatus(status);
+ let discloseError: DiscloseError | undefined =
+ error_code || reason ? { error_code, reason } : undefined;
+ globalSetDisclosureStatus &&
+ globalSetDisclosureStatus(status, discloseError);
} else {
globalSetRegistrationStatus && globalSetRegistrationStatus(status);
}
}
- resolve(status);
+ resolve({ status, error_code, reason });
}
}
const uuid = v4();
@@ -201,7 +209,7 @@ export async function sendPayload(
if (ws.readyState === WebSocket.OPEN) {
ws.close();
}
- finalize(ProofStatusEnum.FAILURE);
+ finalize(ProofStatusEnum.FAILURE, data.error_code, data.reason);
}
});
socket.on('disconnect', reason => {
diff --git a/sdk/qrcode/SelfQRcode.tsx b/sdk/qrcode/SelfQRcode.tsx
index 0cba341ee..e82ce93c6 100644
--- a/sdk/qrcode/SelfQRcode.tsx
+++ b/sdk/qrcode/SelfQRcode.tsx
@@ -15,6 +15,7 @@ import { getUniversalLink, SelfApp, SelfAppBuilder } from '../../common/src/util
interface SelfQRcodeProps {
selfApp: SelfApp;
onSuccess: () => void;
+ onError: (data: {error_code?: string, reason?: string}) => void;
type?: 'websocket' | 'deeplink';
websocketUrl?: string;
size?: number;
@@ -37,6 +38,7 @@ const SelfQRcodeWrapper = (props: SelfQRcodeProps) => {
const SelfQRcode = ({
selfApp,
onSuccess,
+ onError,
type = 'websocket',
websocketUrl = WS_DB_RELAYER,
size = 300,
@@ -58,7 +60,8 @@ const SelfQRcode = ({
},
type,
setProofStep,
- onSuccess
+ onSuccess,
+ onError,
);
}
diff --git a/sdk/qrcode/utils/websocket.ts b/sdk/qrcode/utils/websocket.ts
index c36012ca9..202e80461 100644
--- a/sdk/qrcode/utils/websocket.ts
+++ b/sdk/qrcode/utils/websocket.ts
@@ -28,7 +28,8 @@ const handleWebSocketMessage =
selfApp: SelfApp,
type: 'websocket' | 'deeplink',
setProofStep: (step: number) => void,
- onSuccess: () => void
+ onSuccess: () => void,
+ onError: (data: {error_code?: string, reason?: string}) => void
) =>
async (data: any) => {
console.log('[WebSocket] Received mobile status:', data.status, 'for session:', sessionId);
@@ -55,6 +56,7 @@ const handleWebSocketMessage =
case 'proof_generation_failed':
console.log('[WebSocket] Proof generation failed.');
setProofStep(QRcodeSteps.PROOF_GENERATION_FAILED);
+ onError(data);
break;
case 'proof_verified':
console.log('[WebSocket] Proof verified.');
@@ -73,7 +75,8 @@ export function initWebSocket(
selfApp: SelfApp,
type: 'websocket' | 'deeplink',
setProofStep: (step: number) => void,
- onSuccess: () => void
+ onSuccess: () => void,
+ onError: (data: {error_code?: string, reason?: string}) => void,
) {
const sessionId = selfApp.sessionId;
console.log(`[WebSocket] Initializing WebSocket connection for sessionId: ${sessionId}`);
@@ -95,7 +98,8 @@ export function initWebSocket(
selfApp,
type,
setProofStep,
- onSuccess
+ onSuccess,
+ onError
)(data);
});