feat(kyc): register fcm token for sumsub verification (#1673)

* feat(kyc): register fcm token for sumsub verification

* fix tests

* remove unused import

* fix lint
This commit is contained in:
Leszek Stachowski
2026-01-30 18:35:32 +01:00
committed by GitHub
parent f11e860659
commit a6c84d80f7
6 changed files with 240 additions and 21 deletions

View File

@@ -79,6 +79,7 @@ export type RootStackParamList = Omit<
| 'Home'
| 'IDPicker'
| 'IdDetails'
| 'KycSuccess'
| 'RegistrationFallback'
| 'Loading'
| 'Modal'
@@ -201,7 +202,11 @@ export type RootStackParamList = Omit<
// Onboarding screens
Disclaimer: undefined;
KycSuccess: undefined;
KycSuccess:
| {
userId?: string;
}
| undefined;
// Dev screens
CreateMock: undefined;

View File

@@ -380,7 +380,9 @@ export const SelfClientProvider = ({ children }: PropsWithChildren) => {
// Success case: navigate to KYC success screen
if (navigationRef.isReady()) {
navigationRef.navigate('KycSuccess');
navigationRef.navigate('KycSuccess', {
userId: accessToken.userId,
});
}
} catch (error) {
const safeInitError = sanitizeErrorMessage(

View File

@@ -2,37 +2,70 @@
// SPDX-License-Identifier: BUSL-1.1
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import React from 'react';
import React, { useCallback } from 'react';
import { StyleSheet, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { YStack } from 'tamagui';
import { v5 as uuidv5 } from 'uuid';
import type { StaticScreenProps } from '@react-navigation/native';
import { useNavigation } from '@react-navigation/native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { DelayedLottieView } from '@selfxyz/mobile-sdk-alpha';
import { DelayedLottieView, useSelfClient } from '@selfxyz/mobile-sdk-alpha';
import loadingAnimation from '@selfxyz/mobile-sdk-alpha/animations/loading/misc.json';
import {
AbstractButton,
Description,
Title,
} from '@selfxyz/mobile-sdk-alpha/components';
import { ProofEvents } from '@selfxyz/mobile-sdk-alpha/constants/analytics';
import { black, white } from '@selfxyz/mobile-sdk-alpha/constants/colors';
import { buttonTap } from '@/integrations/haptics';
import type { RootStackParamList } from '@/navigation';
import { requestNotificationPermission } from '@/services/notifications/notificationService';
import {
getFCMToken,
getSelfUuidNamespace,
registerDeviceToken,
requestNotificationPermission,
} from '@/services/notifications/notificationService';
import { useSettingStore } from '@/stores/settingStore';
const KycSuccessScreen: React.FC = () => {
type KycSuccessRouteParams = StaticScreenProps<
| {
userId?: string;
}
| undefined
>;
const KycSuccessScreen: React.FC<KycSuccessRouteParams> = ({
route: { params },
}) => {
const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
const userId = params?.userId;
const insets = useSafeAreaInsets();
const setFcmToken = useSettingStore(state => state.setFcmToken);
const selfClient = useSelfClient();
const { trackEvent } = selfClient;
const handleReceiveUpdates = async () => {
const handleReceiveUpdates = useCallback(async () => {
buttonTap();
await requestNotificationPermission();
if ((await requestNotificationPermission()) && userId) {
const token = await getFCMToken();
if (token) {
setFcmToken(token);
trackEvent(ProofEvents.FCM_TOKEN_STORED);
const sessionId = uuidv5(userId, getSelfUuidNamespace());
await registerDeviceToken(sessionId, token);
}
}
// Navigate to Home regardless of permission result
navigation.navigate('Home', {});
};
}, [navigation, setFcmToken, trackEvent, userId]);
const handleCheckLater = () => {
buttonTap();

View File

@@ -3,6 +3,7 @@
// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
import { PermissionsAndroid, Platform } from 'react-native';
import { SELF_UUID_NAMESPACE } from '@env';
import type { FirebaseMessagingTypes } from '@react-native-firebase/messaging';
import messaging from '@react-native-firebase/messaging';
@@ -36,6 +37,10 @@ const error = (...args: unknown[]) => {
if (!isTestEnv) console.error(...args);
};
export function getSelfUuidNamespace(): string {
return SELF_UUID_NAMESPACE ?? '';
}
export { getStateMessage };
export async function isNotificationSystemReady(): Promise<{