diff --git a/.env b/.env index 1ac58868f..6e3e44d3c 100644 --- a/.env +++ b/.env @@ -12,3 +12,5 @@ RIF_WALLET_KEY=RIF_WALLET WALLETCONNECT2_PROJECT_ID=d9224e919473fd749ba8298879ce7569 USE_RELAY=true + +TRACE_ID= diff --git a/.env.local b/.env.local index 55d9794df..99410e6dc 100644 --- a/.env.local +++ b/.env.local @@ -10,3 +10,5 @@ DEFAULT_CHAIN_TYPE=TESTNET RIF_WALLET_KEY=RIF_WALLET WALLETCONNECT2_PROJECT_ID=d9224e919473fd749ba8298879ce7569 + +TRACE_ID= \ No newline at end of file diff --git a/.env.local.android b/.env.local.android index 7ab42acf9..f985a006d 100644 --- a/.env.local.android +++ b/.env.local.android @@ -10,3 +10,5 @@ DEFAULT_CHAIN_TYPE=TESTNET RIF_WALLET_KEY=RIF_WALLET WALLETCONNECT2_PROJECT_ID=d9224e919473fd749ba8298879ce7569 + +TRACE_ID= \ No newline at end of file diff --git a/.env.test b/.env.test index f33ed37ae..549e153c8 100644 --- a/.env.test +++ b/.env.test @@ -10,3 +10,5 @@ DEFAULT_CHAIN_TYPE=TESTNET RIF_WALLET_KEY=RIF_WALLET WALLETCONNECT2_PROJECT_ID=d9224e919473fd749ba8298879ce7569 + +TRACE_ID= \ No newline at end of file diff --git a/README.md b/README.md index a046d0130..342833d95 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ The main use case of the RIF Wallet using account abstraction is to pay the gas - Install the dependecies using yarn. This will also run the postinstall script that shims the missing packages: `yarn` - The postinstall script runs the `rn-nodeify` package which adds packages that are native to the browser but not to react native. - For **iOS** you need to run the additional installation steps: `cd ios` and then `pod install` +- Set the environment variable `TRACE_ID` in `.env` file to connect with backend server with an identifier, i.e. your company name. - Run the app using the desired platform: - `yarn ios` - `yarn android` diff --git a/env.d.ts b/env.d.ts index 8d8e30f30..5f54d75d5 100644 --- a/env.d.ts +++ b/env.d.ts @@ -7,6 +7,7 @@ declare module 'react-native-config' { RIF_WALLET_KEY: string WALLETCONNECT2_PROJECT_ID: string USE_RELAY: string + TRACE_ID: string } export const Config: NativeConfig diff --git a/src/components/GlobalErrorHandler/GlobalErrorHandlerView.tsx b/src/components/GlobalErrorHandler/GlobalErrorHandlerView.tsx index 69647868a..468d9dcb2 100644 --- a/src/components/GlobalErrorHandler/GlobalErrorHandlerView.tsx +++ b/src/components/GlobalErrorHandler/GlobalErrorHandlerView.tsx @@ -1,6 +1,7 @@ import Clipboard from '@react-native-community/clipboard' import React from 'react' import { Image, StyleSheet, TouchableOpacity, View } from 'react-native' +import { useTranslation } from 'react-i18next' import { sharedColors, sharedStyles } from 'src/shared/constants' import { castStyle } from 'shared/utils' @@ -19,6 +20,7 @@ const GlobalErrorHandlerView: React.FC = ({ message, }) => { const { handleReload, globalError } = useGlobalErrorContext() + const { t } = useTranslation() const messageToShow: string = message || globalError || '' const onCopyError = React.useCallback(() => { @@ -36,10 +38,10 @@ const GlobalErrorHandlerView: React.FC = ({ - {'Oops... Something went wrong!'} + {t('global_error_title')} - {'We are working hard to fix it.'} + {t('global_error_subtitle')} {messageToShow !== '' && ( @@ -48,7 +50,7 @@ const GlobalErrorHandlerView: React.FC = ({ type={'body2'} color={sharedColors.white} style={styles.errorDetailsText}> - {'error details'} + {t('global_error_details_title')} = ({ type={'body3'} color={sharedColors.white} style={sharedStyles.flex}> - {messageToShow} + {t(messageToShow)} diff --git a/src/core/Core.tsx b/src/core/Core.tsx index 6f136b0d1..19ac2429e 100644 --- a/src/core/Core.tsx +++ b/src/core/Core.tsx @@ -21,6 +21,7 @@ import { import { sharedStyles } from 'shared/constants' import { WalletConnect2Provider } from 'screens/walletConnect/WalletConnect2Context' import { WalletContext } from 'shared/wallet' +import { useSetGlobalError } from 'components/GlobalErrorHandler' import { useStateSubscription } from './hooks/useStateSubscription' import { Cover } from './components/Cover' @@ -33,17 +34,20 @@ export const Core = () => { const dispatch = useAppDispatch() const requests = useAppSelector(selectRequests) const topColor = useAppSelector(selectTopColor) + const setGlobalError = useSetGlobalError() const isOffline = useIsOffline() const { active } = useStateSubscription() const { wallet, initializeWallet } = useContext(WalletContext) const unlockAppFn = useCallback(async () => { try { - await dispatch(unlockApp({ isOffline, initializeWallet })).unwrap() + await dispatch( + unlockApp({ isOffline, initializeWallet, setGlobalError }), + ).unwrap() } catch (err) { console.log('ERR CORE', err) } - }, [dispatch, isOffline, initializeWallet]) + }, [dispatch, isOffline, initializeWallet, setGlobalError]) useEffect(() => { unlockAppFn() diff --git a/src/core/hooks/useStateSubscription.ts b/src/core/hooks/useStateSubscription.ts index 0236703c7..261256c67 100644 --- a/src/core/hooks/useStateSubscription.ts +++ b/src/core/hooks/useStateSubscription.ts @@ -11,6 +11,7 @@ import { import { useAppDispatch, useAppSelector } from 'store/storeUtils' import { SocketsEvents, socketsEvents } from 'src/subscriptions/rifSockets' import { useWalletStateSetters } from 'shared/wallet' +import { useSetGlobalError } from 'components/GlobalErrorHandler' import { useAppState } from './useAppState' import { useIsOffline } from './useIsOffline' @@ -21,6 +22,7 @@ let timer: TimeoutId export const useStateSubscription = () => { const { setWallet, setWalletIsDeployed, initializeWallet } = useWalletStateSetters() + const setGlobalError = useSetGlobalError() const dispatch = useAppDispatch() const isOffline = useIsOffline() @@ -61,7 +63,7 @@ export const useStateSubscription = () => { previousAppState.current === 'background' && active ) { - dispatch(unlockApp({ isOffline, initializeWallet })) + dispatch(unlockApp({ isOffline, initializeWallet, setGlobalError })) } return () => { socketsEvents.emit(SocketsEvents.DISCONNECT) @@ -77,6 +79,7 @@ export const useStateSubscription = () => { initializeWallet, setWallet, setWalletIsDeployed, + setGlobalError, ]) useEffect(() => { diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index 971249435..7ac880057 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -398,6 +398,10 @@ const resources = { wallet_backup_title: 'Warning!', wallet_backup_message: 'We have disabled the ability to take a picture of the mnemonic because it is important that you keep it private. Please write it down instead', + global_error_title: 'Oops... Something went wrong!', + global_error_subtitle: 'We are working hard to fix it.', + global_error_details_title: 'error details', + global_trace_id_error: 'Trace Id is not valid', }, }, es: { diff --git a/src/redux/slices/settingsSlice/index.ts b/src/redux/slices/settingsSlice/index.ts index c73dc0fdf..2e5692040 100644 --- a/src/redux/slices/settingsSlice/index.ts +++ b/src/redux/slices/settingsSlice/index.ts @@ -5,6 +5,7 @@ import { initializeSslPinning } from 'react-native-ssl-public-key-pinning' import { RifWalletServicesFetcher } from '@rsksmart/rif-wallet-services' import { providers } from 'ethers' import { RifRelayConfig } from '@rsksmart/rif-relay-light-sdk' +import Config from 'react-native-config' import { ChainID, WalletState } from 'lib/eoaWallet' @@ -228,6 +229,13 @@ export const unlockApp = createAsyncThunk< AsyncThunkWithTypes >('settings/unlockApp', async (payload, thunkAPI) => { try { + if (!Config.TRACE_ID) { + const { setGlobalError } = payload + const errorMessage = 'global_trace_id_error' + setGlobalError(errorMessage) + return thunkAPI.rejectWithValue(errorMessage) + } + const { persistentData: { isFirstLaunch }, settings: { chainId }, diff --git a/src/redux/slices/settingsSlice/types.ts b/src/redux/slices/settingsSlice/types.ts index be3b247df..0f97db5a4 100644 --- a/src/redux/slices/settingsSlice/types.ts +++ b/src/redux/slices/settingsSlice/types.ts @@ -37,6 +37,7 @@ export interface UnlockAppAction { initializeWallet: InitializeWallet isOffline?: boolean pinUnlocked?: boolean + setGlobalError: (value: string) => void } export interface SetKeysAction { diff --git a/src/screens/createKeys/retryLogin/index.tsx b/src/screens/createKeys/retryLogin/index.tsx index d422ff6df..daf4459c2 100644 --- a/src/screens/createKeys/retryLogin/index.tsx +++ b/src/screens/createKeys/retryLogin/index.tsx @@ -7,15 +7,17 @@ import { sharedColors, sharedStyles } from 'shared/constants' import { resetApp, unlockApp } from 'store/slices/settingsSlice' import { useAppDispatch } from 'store/storeUtils' import { useInitializeWallet } from 'shared/wallet' +import { useSetGlobalError } from 'components/GlobalErrorHandler' export const RetryLogin = () => { const initializeWallet = useInitializeWallet() + const setGlobalError = useSetGlobalError() const dispatch = useAppDispatch() const { t } = useTranslation() const retryLogin = useCallback(() => { - dispatch(unlockApp({ initializeWallet })) - }, [dispatch, initializeWallet]) + dispatch(unlockApp({ initializeWallet, setGlobalError })) + }, [dispatch, initializeWallet, setGlobalError]) return ( diff --git a/src/screens/pinScreen/index.tsx b/src/screens/pinScreen/index.tsx index 45bfff9c2..9758ce535 100644 --- a/src/screens/pinScreen/index.tsx +++ b/src/screens/pinScreen/index.tsx @@ -37,6 +37,7 @@ import { CreateKeysScreenProps, } from 'navigation/createKeysNavigator' import { useInitializeWallet } from 'shared/wallet' +import { useSetGlobalError } from 'components/GlobalErrorHandler' type PIN = Array const defaultPin = [null, null, null, null] @@ -123,6 +124,7 @@ type Props = export const PinScreen = ({ navigation, route }: Props) => { const initializeWallet = useInitializeWallet() + const setGlobalError = useSetGlobalError() const insets = useSafeAreaInsets() const isFocused = useIsFocused() // const isVisible = useKeyboardIsVisible() @@ -282,7 +284,9 @@ export const PinScreen = ({ navigation, route }: Props) => { const handleLastDigit = useCallback(() => { if (!isChangeRequested && isPinEqual) { // if pin exists unlocks the app - dispatch(unlockApp({ pinUnlocked: true, initializeWallet })) + dispatch( + unlockApp({ pinUnlocked: true, initializeWallet, setGlobalError }), + ) } else if (isChangeRequested && isPinEqual) { // if pin change requested set new pin setTimeout(() => { @@ -302,6 +306,7 @@ export const PinScreen = ({ navigation, route }: Props) => { PIN, navigation, initializeWallet, + setGlobalError, ]) useEffect(() => { diff --git a/src/subscriptions/rifSockets.ts b/src/subscriptions/rifSockets.ts index 4567d89f6..13fbe6860 100644 --- a/src/subscriptions/rifSockets.ts +++ b/src/subscriptions/rifSockets.ts @@ -4,6 +4,7 @@ import { RifWalletServicesSocket, } from '@rsksmart/rif-wallet-services' import DeviceInfo from 'react-native-device-info' +import Config from 'react-native-config' import { ChainID } from 'lib/eoaWallet' @@ -95,6 +96,7 @@ export const rifSockets = ({ chainId, { 'User-Agent': DeviceInfo.getUserAgentSync(), + 'x-trace-id': Config.TRACE_ID, }, blockNumber, )