Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: cherry-pick #11935 #11982

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
11 changes: 10 additions & 1 deletion app/components/Nav/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ import OptionsSheet from '../../UI/SelectOptionSheet/OptionsSheet';
import FoxLoader from '../../../components/UI/FoxLoader';
import { AppStateEventProcessor } from '../../../core/AppStateEventListener';
import MultiRpcModal from '../../../components/Views/MultiRpcModal/MultiRpcModal';
import { trace, TraceName, TraceOperation } from '../../../util/trace';

const clearStackNavigatorOptions = {
headerShown: false,
Expand Down Expand Up @@ -579,7 +580,15 @@ const App = (props) => {
setOnboarded(!!existingUser);
try {
if (existingUser) {
await Authentication.appTriggeredAuth();
await trace(
{
name: TraceName.BiometricAuthentication,
op: TraceOperation.BiometricAuthentication,
},
async () => {
await Authentication.appTriggeredAuth();
},
);
// we need to reset the navigator here so that the user cannot go back to the login screen
navigator.reset({ routes: [{ name: Routes.ONBOARDING.HOME_NAV }] });
} else {
Expand Down
18 changes: 14 additions & 4 deletions app/components/Views/LockScreen/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import Routes from '../../../constants/navigation/Routes';
import { CommonActions } from '@react-navigation/native';
import trackErrorAsAnalytics from '../../../util/metrics/TrackError/trackErrorAsAnalytics';
import { trace, TraceName, TraceOperation } from '../../../util/trace';

const LOGO_SIZE = 175;
const createStyles = (colors) =>
Expand Down Expand Up @@ -134,10 +135,19 @@ class LockScreen extends PureComponent {
// Retrieve the credentials
Logger.log('Lockscreen::unlockKeychain - getting credentials');

await Authentication.appTriggeredAuth({
bioStateMachineId,
disableAutoLogout: true,
});
await trace(
{
name: TraceName.BiometricAuthentication,
op: TraceOperation.BiometricAuthentication,
},
async () => {
await Authentication.appTriggeredAuth({
bioStateMachineId,
disableAutoLogout: true,
});
},
);

this.setState({ ready: true });
Logger.log('Lockscreen::unlockKeychain - state: ready');
} catch (error) {
Expand Down
75 changes: 55 additions & 20 deletions app/components/Views/Login/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import Text, {
} from '../../../component-library/components/Texts/Text';
import StorageWrapper from '../../../store/storage-wrapper';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import Button, { ButtonSize, ButtonVariants, ButtonWidthTypes } from '../../../component-library/components/Buttons/Button';
import Button, {
ButtonSize,
ButtonVariants,
ButtonWidthTypes,
} from '../../../component-library/components/Buttons/Button';
import { fontStyles } from '../../../styles/common';
import { strings } from '../../../../locales/i18n';
import FadeOutOverlay from '../../UI/FadeOutOverlay';
Expand Down Expand Up @@ -55,9 +59,19 @@ import { LoginViewSelectors } from '../../../../e2e/selectors/LoginView.selector
import { withMetricsAwareness } from '../../../components/hooks/useMetrics';
import trackErrorAsAnalytics from '../../../util/metrics/TrackError/trackErrorAsAnalytics';
import { downloadStateLogs } from '../../../util/logs';
import TextField, { TextFieldSize } from '../../../component-library/components/Form/TextField';
import {
trace,
endTrace,
TraceName,
TraceOperation,
} from '../../../util/trace';
import TextField, {
TextFieldSize,
} from '../../../component-library/components/Form/TextField';
import Label from '../../../component-library/components/Form/Label';
import HelpText, { HelpTextSeverity } from '../../../component-library/components/Form/HelpText';
import HelpText, {
HelpTextSeverity,
} from '../../../component-library/components/Form/HelpText';

const deviceHeight = Device.getDeviceHeight();
const breakPoint = deviceHeight < 700;
Expand Down Expand Up @@ -107,7 +121,7 @@ const createStyles = (colors) =>
},
footer: {
marginVertical: 40,
alignItems: 'center'
alignItems: 'center',
},
goBack: {
marginVertical: 14,
Expand Down Expand Up @@ -237,6 +251,10 @@ class Login extends PureComponent {
fieldRef = React.createRef();

async componentDidMount() {
trace({
name: TraceName.LoginToPasswordEntry,
op: TraceOperation.LoginToPasswordEntry,
});
this.props.metrics.trackEvent(MetaMetricsEvents.LOGIN_SCREEN_VIEWED);
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);

Expand Down Expand Up @@ -360,7 +378,15 @@ class Login extends PureComponent {
);

try {
await Authentication.userEntryAuth(password, authType);
await trace(
{
name: TraceName.AuthenticateUser,
op: TraceOperation.AuthenticateUser,
},
async () => {
await Authentication.userEntryAuth(password, authType);
},
);

Keyboard.dismiss();

Expand Down Expand Up @@ -428,7 +454,15 @@ class Login extends PureComponent {
const { current: field } = this.fieldRef;
field?.blur();
try {
await Authentication.appTriggeredAuth();
await trace(
{
name: TraceName.BiometricAuthentication,
op: TraceOperation.BiometricAuthentication,
},
async () => {
await Authentication.appTriggeredAuth();
},
);
const onboardingWizard = await StorageWrapper.getItem(ONBOARDING_WIZARD);
if (!onboardingWizard) this.props.setOnboardingWizardStep(1);
this.props.navigation.replace(Routes.ONBOARDING.HOME_NAV);
Expand All @@ -447,6 +481,7 @@ class Login extends PureComponent {
};

triggerLogIn = () => {
endTrace({ name: TraceName.LoginToPasswordEntry });
this.onLogin();
};

Expand Down Expand Up @@ -529,10 +564,7 @@ class Login extends PureComponent {
)}
</TouchableOpacity>

<Text
style={styles.title}
testID={LoginViewSelectors.TITLE_ID}
>
<Text style={styles.title} testID={LoginViewSelectors.TITLE_ID}>
{strings('login.title')}
</Text>
<View style={styles.field}>
Expand Down Expand Up @@ -582,19 +614,22 @@ class Login extends PureComponent {
style={styles.ctaWrapper}
testID={LoginViewSelectors.LOGIN_BUTTON_ID}
>

<Button variant={ButtonVariants.Primary}
<Button
variant={ButtonVariants.Primary}
width={ButtonWidthTypes.Full}
size={ButtonSize.Lg}
onPress={this.triggerLogIn}
label={this.state.loading ? (
<ActivityIndicator
size="small"
color={colors.primary.inverse}
/>
) : (
strings('login.unlock_button')
)}/>
label={
this.state.loading ? (
<ActivityIndicator
size="small"
color={colors.primary.inverse}
/>
) : (
strings('login.unlock_button')
)
}
/>
</View>

<View style={styles.footer}>
Expand Down
10 changes: 7 additions & 3 deletions app/components/Views/Login/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React from 'react';
import Login from './';
import renderWithProvider from '../../../util/test/renderWithProvider';
// eslint-disable-next-line import/no-namespace
import * as traceObj from '../../../util/trace';

describe('Login', () => {
it('should render correctly', () => {
const { toJSON } = renderWithProvider(
<Login />
);
const spyFetch = jest
.spyOn(traceObj, 'trace')
.mockImplementation(() => undefined);
const { toJSON } = renderWithProvider(<Login />);
expect(toJSON()).toMatchSnapshot();
expect(spyFetch).toHaveBeenCalledTimes(1);
});
});
38 changes: 24 additions & 14 deletions app/components/Views/Onboarding/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { OnboardingSelectorIDs } from '../../../../e2e/selectors/Onboarding/Onbo
import Routes from '../../../constants/navigation/Routes';
import { selectAccounts } from '../../../selectors/accountTrackerController';
import trackOnboarding from '../../../util/metrics/TrackOnboarding/trackOnboarding';
import { trace, TraceName, TraceOperation } from '../../../util/trace';

const createStyles = (colors) =>
StyleSheet.create({
Expand Down Expand Up @@ -275,24 +276,33 @@ class Onboarding extends PureComponent {
};

onPressCreate = () => {
const action = async () => {
const { metrics } = this.props;
if (metrics.isEnabled()) {
this.props.navigation.navigate('ChoosePassword', {
[PREVIOUS_SCREEN]: ONBOARDING,
});
this.track(MetaMetricsEvents.WALLET_SETUP_STARTED);
} else {
this.props.navigation.navigate('OptinMetrics', {
onContinue: () => {
this.props.navigation.replace('ChoosePassword', {
const action = () => {
trace(
{
name: TraceName.CreateNewWalletToChoosePassword,
op: TraceOperation.CreateNewWalletToChoosePassword,
},
() => {
const { metrics } = this.props;
if (metrics.isEnabled()) {
this.props.navigation.navigate('ChoosePassword', {
[PREVIOUS_SCREEN]: ONBOARDING,
});
this.track(MetaMetricsEvents.WALLET_SETUP_STARTED);
},
});
}
} else {
this.props.navigation.navigate('OptinMetrics', {
onContinue: () => {
this.props.navigation.replace('ChoosePassword', {
[PREVIOUS_SCREEN]: ONBOARDING,
});
this.track(MetaMetricsEvents.WALLET_SETUP_STARTED);
},
});
}
},
);
};

this.handleExistingUser(action);
};

Expand Down
20 changes: 20 additions & 0 deletions app/components/Views/Onboarding/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { renderScreen } from '../../../util/test/renderWithProvider';
import Onboarding from './';
import { backgroundState } from '../../../util/test/initial-root-state';
import { OnboardingSelectorIDs } from '../../../../e2e/selectors/Onboarding/Onboarding.selectors';
import { fireEvent } from '@testing-library/react-native';
// eslint-disable-next-line import/no-namespace
import * as traceObj from '../../../util/trace';

const mockInitialState = {
engine: {
Expand All @@ -21,4 +25,20 @@ describe('Onboarding', () => {
);
expect(toJSON()).toMatchSnapshot();
});
it('must call trace when press start', () => {
const spyFetch = jest
.spyOn(traceObj, 'trace')
.mockImplementation(() => undefined);
const { getByTestId } = renderScreen(
Onboarding,
{ name: 'Onboarding' },
{
state: mockInitialState,
},
);

const startButton = getByTestId(OnboardingSelectorIDs.NEW_WALLET_BUTTON);
fireEvent.press(startButton);
expect(spyFetch).toHaveBeenCalledTimes(1);
});
});
1 change: 1 addition & 0 deletions app/components/Views/Wallet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import { ButtonVariants } from '../../../component-library/components/Buttons/Bu
import { useListNotifications } from '../../../util/notifications/hooks/useNotifications';
import { PortfolioBalance } from '../../UI/Tokens/TokenList/PortfolioBalance';
import { isObject } from 'lodash';

const createStyles = ({ colors, typography }: Theme) =>
StyleSheet.create({
base: {
Expand Down
38 changes: 35 additions & 3 deletions app/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Authentication } from '../core';
import LockManagerService from '../core/LockManagerService';
import ReadOnlyNetworkStore from '../util/test/network-store';
import { isE2E } from '../util/test/utils';
import { trace, endTrace, TraceName, TraceOperation } from '../util/trace';

import thunk from 'redux-thunk';

import persistConfig from './persistConfig';
Expand Down Expand Up @@ -46,6 +48,11 @@ const createStoreAndPersistor = async () => {
middlewares.push(createReduxFlipperDebugger());
}

trace({
name: TraceName.CreateStore,
op: TraceOperation.CreateStore,
});

store = configureStore({
reducer: pReducer,
middleware: middlewares,
Expand All @@ -54,10 +61,19 @@ const createStoreAndPersistor = async () => {

sagaMiddleware.run(rootSaga);

endTrace({ name: TraceName.CreateStore });

trace({
name: TraceName.StorageRehydration,
op: TraceOperation.StorageRehydration,
});

/**
* Initialize services after persist is completed
*/
const onPersistComplete = () => {
const onPersistComplete = async () => {
endTrace({ name: TraceName.StorageRehydration });

/**
* EngineService.initalizeEngine(store) with SES/lockdown:
* Requires ethjs nested patches (lib->src)
Expand All @@ -73,6 +89,7 @@ const createStoreAndPersistor = async () => {
* - TypeError: undefined is not an object (evaluating 'TokenListController.tokenList')
* - V8: SES_UNHANDLED_REJECTION
*/

store.dispatch({
type: 'TOGGLE_BASIC_FUNCTIONALITY',
basicFunctionalityEnabled:
Expand All @@ -83,7 +100,16 @@ const createStoreAndPersistor = async () => {
store.dispatch({
type: 'FETCH_FEATURE_FLAGS',
});
EngineService.initalizeEngine(store);
trace(
{
name: TraceName.EngineInitialization,
op: TraceOperation.EngineInitialization,
},
() => {
EngineService.initalizeEngine(store);
},
);

Authentication.init(store);
AppStateEventProcessor.init(store);
LockManagerService.init(store);
Expand All @@ -93,7 +119,13 @@ const createStoreAndPersistor = async () => {
};

(async () => {
await createStoreAndPersistor();
await trace(
{
name: TraceName.UIStartup,
op: TraceOperation.UIStartup,
},
async () => await createStoreAndPersistor(),
);
})();

export { store, persistor };
Loading
Loading