Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 app/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ GEM
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.4.0)
aws-partitions (1.1151.0)
aws-sdk-core (3.230.0)
aws-partitions (1.1152.0)
aws-sdk-core (3.231.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
bigdecimal
jmespath (~> 1, >= 1.6.1)
logger
aws-sdk-kms (1.110.0)
aws-sdk-core (~> 3, >= 3.228.0)
aws-sdk-kms (1.112.0)
aws-sdk-core (~> 3, >= 3.231.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.197.0)
aws-sdk-core (~> 3, >= 3.228.0)
aws-sdk-s3 (1.198.0)
aws-sdk-core (~> 3, >= 3.231.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1)
Expand Down
3 changes: 2 additions & 1 deletion app/android/react-native-passport-reader/index.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const DATE_REGEX = /^\d{6}$/

module.exports = {
...RNPassportReader,
scan
scan,
reset: RNPassportReader.reset
}

function scan({ documentNumber, dateOfBirth, dateOfExpiry, canNumber, useCan, quality=1 }) {
Expand Down
4 changes: 2 additions & 2 deletions app/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2089,7 +2089,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- segment-analytics-react-native (2.21.1):
- segment-analytics-react-native (2.21.2):
- React-Core
- sovran-react-native
- Sentry/HybridSDK (8.52.1)
Expand Down Expand Up @@ -2531,7 +2531,7 @@ SPEC CHECKSUMS:
RNScreens: 224dba0e9e7674d911ebf3931eddca686f133e8a
RNSentry: d240d406990e08d9b1fa967aaac67b7cb61b32e2
RNSVG: e1a716d635c65297c86e874eeb6adf3704a2e50a
segment-analytics-react-native: 5c3e8a4ee6d7532a011ed862d7c7d4fb5e5303e2
segment-analytics-react-native: bad4c2c7b63818bd493caa2b5759fca59e4ae9a7
Sentry: 2cbbe3592f30050c60e916c63c7f5a2fa584005e
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
sovran-react-native: a3ad3f8ff90c2002b2aa9790001a78b0b0a38594
Expand Down
24 changes: 23 additions & 1 deletion app/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ jest.mock(
{ virtual: true },
);

jest.mock('@env', () => ({
ENABLE_DEBUG_LOGS: 'false',
MIXPANEL_NFC_PROJECT_TOKEN: 'test-token',
}));

global.FileReader = class {
constructor() {
this.onload = null;
Expand Down Expand Up @@ -202,13 +207,30 @@ jest.mock('react-native-nfc-manager', () => ({
// Mock react-native-passport-reader
jest.mock('react-native-passport-reader', () => ({
default: {
initialize: jest.fn(),
configure: jest.fn(),
scanPassport: jest.fn(),
readPassport: jest.fn(),
cancelPassportRead: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
reset: jest.fn(),
},
}));
Comment on lines 208 to 218
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

Mock parity with types: add scan alias to match d.ts and potential callsites

The default export for react-native-passport-reader only exposes scanPassport, while the d.ts (and likely some callsites) reference scan. This will cause test failures or undefined calls in environments that import the default module instead of NativeModules.

Apply this diff to add a scan alias:

 jest.mock('react-native-passport-reader', () => ({
   default: {
     configure: jest.fn(),
-    scanPassport: jest.fn(),
+    scanPassport: jest.fn(),
+    // Alias to align with TS types/callsites
+    scan: jest.fn(),
     readPassport: jest.fn(),
     cancelPassportRead: jest.fn(),
     trackEvent: jest.fn(),
     flush: jest.fn(),
     reset: jest.fn(),
   },
 }));

Run to spot any lingering scanPassport( vs scan( mismatches:


🏁 Script executed:

#!/bin/bash
rg -nP -C2 --type=ts --type=tsx '\bPassportReader\b.*\bscan(Passport)?\s*\('
rg -nP -C2 --type=ts --type=tsx '\bNativeModules\.PassportReader\b.*\bscan(Passport)?\s*\('

Length of output: 228


🏁 Script executed:

#!/bin/bash
# Search for both scanPassport and scan callsites across TS/TSX/JS/JSX files
rg -nP -C2 '\bPassportReader\b.*\bscan(?:Passport)?\s*\(' -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx'
rg -nP -C2 '\bNativeModules\.PassportReader\b.*\bscan(?:Passport)?\s*\(' -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx'

Length of output: 1200


Add scan alias to the PassportReader mock to cover Android callsites

Your Android scanner helper calls PassportReader.scan(…) (app/src/utils/nfcScanner.ts line 128), but your Jest setup only mocks scanPassport. Without a scan mock, tests hitting scanAndroid will fail with undefined is not a function.

Apply this diff in app/jest.setup.js (around lines 203–213):

 jest.mock('react-native-passport-reader', () => ({
   default: {
     configure: jest.fn(),
     scanPassport: jest.fn(),
+    // Alias to align with TS types/callsites (e.g. scanAndroid)
+    scan: jest.fn(),
     readPassport: jest.fn(),
     cancelPassportRead: jest.fn(),
     trackEvent: jest.fn(),
     flush: jest.fn(),
     reset: jest.fn(),
   },
 }));

— without this, any PassportReader.scan(...) calls will be unmocked and break your Android tests.

📝 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
jest.mock('react-native-passport-reader', () => ({
default: {
initialize: jest.fn(),
configure: jest.fn(),
scanPassport: jest.fn(),
readPassport: jest.fn(),
cancelPassportRead: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
reset: jest.fn(),
},
}));
jest.mock('react-native-passport-reader', () => ({
default: {
configure: jest.fn(),
scanPassport: jest.fn(),
// Alias to align with TS types/callsites (e.g. scanAndroid)
scan: jest.fn(),
readPassport: jest.fn(),
cancelPassportRead: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
reset: jest.fn(),
},
}));
🤖 Prompt for AI Agents
In app/jest.setup.js around lines 203 to 213, the PassportReader mock only
provides scanPassport/readPassport/etc. but not the Android alias scan, so tests
calling PassportReader.scan(...) will fail; update the mock to add a scan
property that points to the same jest.fn() used by scanPassport (i.e., add scan:
jest.fn() or set scan: mock.scanPassport) so PassportReader.scan(...) is defined
and uses the existing mock behavior.


const { NativeModules } = require('react-native');

NativeModules.PassportReader = {
configure: jest.fn(),
scanPassport: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
};

Comment on lines +220 to +228
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

Keep NativeModules mock consistent and complete

NativeModules.PassportReader mirrors only some methods. To avoid drift between the default export and NativeModules, provide a scan alias here too (and, ideally, share the same jest.fn where practical).

Apply this diff:

 const { NativeModules } = require('react-native');

 NativeModules.PassportReader = {
   configure: jest.fn(),
-  scanPassport: jest.fn(),
+  scanPassport: jest.fn(),
+  // Alias for parity with d.ts and default export
+  scan: jest.fn(),
   trackEvent: jest.fn(),
   flush: jest.fn(),
 };
📝 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
const { NativeModules } = require('react-native');
NativeModules.PassportReader = {
configure: jest.fn(),
scanPassport: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
};
const { NativeModules } = require('react-native');
NativeModules.PassportReader = {
configure: jest.fn(),
scanPassport: jest.fn(),
// Alias for parity with d.ts and default export
scan: jest.fn(),
trackEvent: jest.fn(),
flush: jest.fn(),
};
🤖 Prompt for AI Agents
In app/jest.setup.js around lines 215 to 223, NativeModules.PassportReader
defines configure, scanPassport, trackEvent, and flush but is missing the scan
alias; update the mock to include scan and make it reference the same jest.fn()
as scanPassport (i.e., create one jest.fn for the passport scan and assign it to
both scanPassport and scan) so the mock stays consistent and methods remain in
sync.

jest.mock('@react-native-community/netinfo', () => ({
addEventListener: jest.fn(() => jest.fn()),
fetch: jest.fn(() => Promise.resolve({ isConnected: true })),
}));
Comment on lines +229 to +232
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Duplicate NetInfo mock overrides earlier one (breaks useNetInfo/behavior)

This second jest.mock('@react-native-community/netinfo', ...) overrides the earlier mock (Lines 147–160), dropping useNetInfo and changing method shapes. That can cause test flakiness or crashes.

Apply this diff to remove the duplicate:

-jest.mock('@react-native-community/netinfo', () => ({
-  addEventListener: jest.fn(() => jest.fn()),
-  fetch: jest.fn(() => Promise.resolve({ isConnected: true })),
-}));

Then, update the first NetInfo mock (Lines 147–160) to return an unsubscribe from addEventListener and a resolved value from fetch:

// In the first mock block (existing):
addEventListener: jest.fn(() => jest.fn()), // returns unsubscribe
fetch: jest.fn().mockResolvedValue({ isConnected: true, isInternetReachable: true }),

If you want, I can push a combined single mock that covers useNetInfo, addEventListener, and fetch consistently.

🤖 Prompt for AI Agents
In app/jest.setup.js around lines 224–227 there is a duplicate
jest.mock('@react-native-community/netinfo') that overrides the earlier mock and
drops useNetInfo/changes method shapes; remove this second mock block and
instead update the first mock block (around lines 147–160) so addEventListener
returns an unsubscribe function (e.g., jest.fn(() => jest.fn())) and fetch is a
resolved promise (e.g., jest.fn().mockResolvedValue({ isConnected: true,
isInternetReachable: true })), ensuring the single mock covers useNetInfo,
addEventListener, and fetch consistently.


// Mock @stablelib packages
jest.mock('@stablelib/cbor', () => ({
encode: jest.fn(),
Expand Down
4 changes: 2 additions & 2 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"mobile-local-deploy": "FORCE_UPLOAD_LOCAL_DEV=true node scripts/mobile-deploy-confirm.cjs both",
"mobile-local-deploy:android": "FORCE_UPLOAD_LOCAL_DEV=true node scripts/mobile-deploy-confirm.cjs android",
"mobile-local-deploy:ios": "FORCE_UPLOAD_LOCAL_DEV=true node scripts/mobile-deploy-confirm.cjs ios",
"nice": "yarn imports:fix && yarn lint:fix && yarn fmt:fix",
"nice": "yarn build:deps && yarn imports:fix && yarn lint:fix && yarn fmt:fix",
"reinstall": "yarn clean && yarn install && yarn install-app",
"release": "./scripts/release.sh",
"release:major": "./scripts/release.sh major",
Expand Down Expand Up @@ -82,7 +82,7 @@
"@react-navigation/native": "^7.0.14",
"@react-navigation/native-stack": "^7.2.0",
"@robinbobin/react-native-google-drive-api-wrapper": "^2.2.3",
"@segment/analytics-react-native": "^2.21.0",
"@segment/analytics-react-native": "^2.21.2",
"@segment/sovran-react-native": "^1.1.3",
"@selfxyz/common": "workspace:^",
"@selfxyz/mobile-sdk-alpha": "workspace:^",
Expand Down
5 changes: 4 additions & 1 deletion app/src/Segment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createClient,
EventPlugin,
PluginType,
StartupFlushPolicy,
} from '@segment/analytics-react-native';

import '@ethersproject/shims';
Expand Down Expand Up @@ -48,14 +49,16 @@ export const createSegmentClient = () => {
return segmentClient;
}

const flushPolicies = [new BackgroundFlushPolicy()];
const flushPolicies = [new BackgroundFlushPolicy(), new StartupFlushPolicy()];

const client = createClient({
writeKey: SEGMENT_KEY,
trackAppLifecycleEvents: true,
trackDeepLinks: true,
debug: __DEV__,
collectDeviceId: false,
flushAt: 20, // Flush every 20 events
flushInterval: 20000, // Flush every 20 seconds
defaultSettings: {
integrations: {
'Segment.io': {
Expand Down
12 changes: 7 additions & 5 deletions app/src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import React, { Component } from 'react';
import { Text, View } from 'react-native';

import { captureException } from '@/Sentry';
import analytics from '@/utils/analytics';

const { flush: flushAnalytics } = analytics();
import { flushAllAnalytics, trackNfcEvent } from '@/utils/analytics';

interface Props {
children: React.ReactNode;
Expand All @@ -30,8 +28,12 @@ class ErrorBoundary extends Component<Props, State> {
}

componentDidCatch(error: Error, info: ErrorInfo) {
// Flush analytics before the app crashes
flushAnalytics();
trackNfcEvent('error_boundary', {
message: error.message,
stack: info.componentStack,
});
// Flush all analytics before the app crashes
flushAllAnalytics();
captureException(error, {
componentStack: info.componentStack,
errorBoundary: true,
Expand Down
13 changes: 13 additions & 0 deletions app/src/mocks/react-native-passport-reader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.

// Web mock for react-native-passport-reader
export const reset = async () => {
// No-op for web
return Promise.resolve();
};

export const scan = async () => {
throw new Error('NFC scanning is not supported on web');
};
35 changes: 28 additions & 7 deletions app/src/screens/passport/PassportNFCScanScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { useFeedback } from '@/providers/feedbackProvider';
import { storePassportData } from '@/providers/passportDataProvider';
import useUserStore from '@/stores/userStore';
import { flushAllAnalytics, trackNfcEvent } from '@/utils/analytics';
import { black, slate100, slate400, slate500, white } from '@/utils/colors';
import { sendFeedbackEmail } from '@/utils/email';
import { dinot } from '@/utils/fonts';
Expand Down Expand Up @@ -79,6 +80,7 @@ type PassportNFCScanRoute = RouteProp<
const PassportNFCScanScreen: React.FC = () => {
const selfClient = useSelfClient();
const { trackEvent } = selfClient;

const navigation = useNavigation();
const route = useRoute<PassportNFCScanRoute>();
const { showModal } = useFeedback();
Expand Down Expand Up @@ -137,6 +139,7 @@ const PassportNFCScanScreen: React.FC = () => {

const openErrorModal = useCallback(
(message: string) => {
flushAllAnalytics();
showModal({
titleText: 'NFC Scan Error',
bodyText: message,
Expand Down Expand Up @@ -206,6 +209,9 @@ const PassportNFCScanScreen: React.FC = () => {
trackEvent(PassportEvents.NFC_SCAN_FAILED, {
error: 'timeout',
});
trackNfcEvent(PassportEvents.NFC_SCAN_FAILED, {
error: 'timeout',
});
openErrorModal('Scan timed out. Please try again.');
setIsNfcSheetOpen(false);
}, 30000);
Expand Down Expand Up @@ -249,10 +255,14 @@ const PassportNFCScanScreen: React.FC = () => {
passportData = parseScanResponse(scanResponse);
} catch (e: unknown) {
console.error('Parsing NFC Response Unsuccessful');
const errMsg = sanitizeErrorMessage(
e instanceof Error ? e.message : String(e),
);
trackEvent(PassportEvents.NFC_RESPONSE_PARSE_FAILED, {
error: sanitizeErrorMessage(
e instanceof Error ? e.message : String(e),
),
error: errMsg,
});
trackNfcEvent(PassportEvents.NFC_RESPONSE_PARSE_FAILED, {
error: errMsg,
});
return;
}
Expand Down Expand Up @@ -317,10 +327,14 @@ const PassportNFCScanScreen: React.FC = () => {
return;
}
console.error('Passport Parsed Failed:', e);
const errMsg = sanitizeErrorMessage(
e instanceof Error ? e.message : String(e),
);
trackEvent(PassportEvents.PASSPORT_PARSE_FAILED, {
error: sanitizeErrorMessage(
e instanceof Error ? e.message : String(e),
),
error: errMsg,
});
trackNfcEvent(PassportEvents.PASSPORT_PARSE_FAILED, {
error: errMsg,
});
return;
}
Expand All @@ -335,8 +349,13 @@ const PassportNFCScanScreen: React.FC = () => {
).toFixed(2);
console.error('NFC Scan Unsuccessful:', e);
const message = e instanceof Error ? e.message : String(e);
const sanitized = sanitizeErrorMessage(message);
trackEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitizeErrorMessage(message),
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
trackNfcEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
Comment on lines +352 to 360
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

Use the sanitized message for the error modal to prevent accidental PII exposure

You're sanitizing the message for analytics but still passing the raw message to the user-facing modal. Surface the sanitized version there too to avoid exposing MRZ or other sensitive values.

Apply this change near the existing code:

-        const message = e instanceof Error ? e.message : String(e);
-        const sanitized = sanitizeErrorMessage(message);
+        const message = e instanceof Error ? e.message : String(e);
+        const sanitized = sanitizeErrorMessage(message);
...
-        openErrorModal(message);
+        openErrorModal(sanitized);
📝 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
const sanitized = sanitizeErrorMessage(message);
trackEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitizeErrorMessage(message),
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
trackNfcEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
const message = e instanceof Error ? e.message : String(e);
const sanitized = sanitizeErrorMessage(message);
trackEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
trackNfcEvent(PassportEvents.NFC_SCAN_FAILED, {
error: sanitized,
duration_seconds: parseFloat(scanDurationSeconds),
});
openErrorModal(sanitized);
🤖 Prompt for AI Agents
In app/src/screens/passport/PassportNFCScanScreen.tsx around lines 358 to 366,
the code logs a sanitized error for analytics but still shows the raw message in
the user-facing modal; replace the raw message with the sanitized variable when
invoking the error modal so the displayed content uses
sanitizeErrorMessage(message) (sanitized) instead of the original message,
ensuring any modal props or state that currently use the raw message are updated
to use sanitized and keeping analytics tracking as-is.

openErrorModal(message);
Expand All @@ -350,6 +369,7 @@ const PassportNFCScanScreen: React.FC = () => {
setIsNfcSheetOpen(false);
}
} else if (isNfcSupported) {
flushAllAnalytics();
if (Platform.OS === 'ios') {
Linking.openURL('App-Prefs:root=General&path=About');
} else {
Expand All @@ -376,6 +396,7 @@ const PassportNFCScanScreen: React.FC = () => {
});

const onCancelPress = async () => {
flushAllAnalytics();
const hasValidDocument = await hasAnyValidRegisteredDocument(selfClient);
if (hasValidDocument) {
navigateToHome();
Expand Down
6 changes: 2 additions & 4 deletions app/src/screens/passport/PassportNFCTroubleScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ import { Caption } from '@/components/typography/Caption';
import { useFeedbackAutoHide } from '@/hooks/useFeedbackAutoHide';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout';
import analytics from '@/utils/analytics';
import analytics, { flushAllAnalytics } from '@/utils/analytics';
import { slate500 } from '@/utils/colors';
import { sendFeedbackEmail } from '@/utils/email';

const { flush: flushAnalytics } = analytics();

const tips: TipProps[] = [
{
title: 'Know Your Chip Location',
Expand Down Expand Up @@ -55,7 +53,7 @@ const PassportNFCTrouble: React.FC = () => {

// error screen, flush analytics
useEffect(() => {
flushAnalytics();
flushAllAnalytics();
}, []);

// 5-taps with a single finger
Expand Down
7 changes: 7 additions & 0 deletions app/src/screens/prove/ConfirmBelongingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { Title } from '@/components/typography/Title';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import { ExpandableBottomLayout } from '@/layouts/ExpandableBottomLayout';
import { styles } from '@/screens/prove/ProofRequestStatusScreen';
import analytics, { flushAllAnalytics, trackNfcEvent } from '@/utils/analytics';
import { black, white } from '@/utils/colors';
import { notificationSuccess } from '@/utils/haptic';
import {
Expand Down Expand Up @@ -52,6 +53,7 @@ const ConfirmBelongingScreen: React.FC<ConfirmBelongingScreenProps> = () => {
try {
setRequestingPermission(true);
trackEvent(ProofEvents.NOTIFICATION_PERMISSION_REQUESTED);
trackNfcEvent(ProofEvents.NOTIFICATION_PERMISSION_REQUESTED);

// Request notification permission
const permissionGranted = await requestNotificationPermission();
Expand All @@ -74,6 +76,11 @@ const ConfirmBelongingScreen: React.FC<ConfirmBelongingScreenProps> = () => {
trackEvent(ProofEvents.PROVING_PROCESS_ERROR, {
error: message,
});
trackNfcEvent(ProofEvents.PROVING_PROCESS_ERROR, {
error: message,
});

flushAllAnalytics();
} finally {
setRequestingPermission(false);
}
Expand Down
6 changes: 2 additions & 4 deletions app/src/screens/prove/QRCodeTroubleScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import Tips from '@/components/Tips';
import { Caption } from '@/components/typography/Caption';
import useHapticNavigation from '@/hooks/useHapticNavigation';
import SimpleScrolledTitleLayout from '@/layouts/SimpleScrolledTitleLayout';
import analytics from '@/utils/analytics';
import analytics, { flushAllAnalytics } from '@/utils/analytics';
import { slate500 } from '@/utils/colors';

const { flush: flushAnalytics } = analytics();

const tips: TipProps[] = [
{
title: 'Ensure Valid QR Code',
Expand Down Expand Up @@ -49,7 +47,7 @@ const QRCodeTrouble: React.FC = () => {

// error screen, flush analytics
useEffect(() => {
flushAnalytics();
flushAllAnalytics();
}, []);

return (
Expand Down
Loading
Loading