Skip to content

Commit

Permalink
Merge branch 'main' into release/7.34.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sethkfman authored Nov 12, 2024
2 parents 55fa56f + 3963644 commit 5eaf361
Show file tree
Hide file tree
Showing 68 changed files with 2,972 additions and 1,323 deletions.
3 changes: 3 additions & 0 deletions .js.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,6 @@ export MM_CHAIN_PERMISSIONS=""

#Multichain feature flag specific to UI changes
export MM_MULTICHAIN_V1_ENABLED=""

#Permissions Settings feature flag specific to UI changes
export MM_PERMISSIONS_SETTINGS_V1_ENABLED=""
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,35 @@ git clone [email protected]:MetaMask/metamask-mobile.git && \
cd metamask-mobile
```

**Firebase Messaging Setup**
### **Firebase Messaging Setup**

Before running the app, keep in mind that MetaMask uses FCM (Firebase Cloud Message) to empower communications. Based on this, as an external contributor you would preferably need to provide your own FREE Firebase project config file with a matching client for package name `io.metamask`, and update your `google-services.json` file in the `android/app` or `GoogleService-Info.plist` file in the `ios` directory.
MetaMask uses Firebase Cloud Messaging (FCM) to enable app communications. To integrate FCM, you’ll need configuration files for both iOS and Android platforms.

#### **Configuration Files Required**
- **`GoogleService-Info.plist`** (iOS)
- **`google-services.json`** (Android)

These files are essential for FCM integration and are automatically generated when running: `yarn start:ios` or `yarn start:android`

**External Contributors**
In case you don't have FCM account, you can use `./android/app/google-services-example.json` for Android or `./ios/GoogleServices/GoogleService-Info-example.plist` for iOS and follow the steps below to populate the correct environment variables in the `.env` files (`.ios.env`, `.js.env`, `.android.env`), adding `GOOGLE_SERVICES_B64_ANDROID` or `GOOGLE_SERVICES_B64_IOS` variable depending on the environment you are running the app (ios/android).

As an external contributor, you need to provide your own Firebase project configuration files:

1. Create a Free Firebase Project
* Set up a Firebase project in the Firebase Console.
* Configure the project with a client package name matching `io.metamask`.
2. Add Configuration Files
* Update the `google-services.json` and `GoogleService-Info.plist` files in:
* `android/app` (for Android)
* `ios` directory (for iOS)

In case you don't have FCM account, you can reference the instructions below. These instructions will generate the required `GOOGLE_SERVICES_B64_ANDROID` or `GOOGLE_SERVICES_B64_IOS` environment variables found in: `.ios.env`, `.js.env`, `.android.env`. They can be locally generated from examples files.

**Internal Contributors**

We should access the Firebase project config file from 1Password.
As an internal contributor, you can access the shared Firebase project config file from 1Password. Ask around for the correct vault.

The value you should provide to `GOOGLE_SERVICES_B64_ANDROID` or `GOOGLE_SERVICES_B64_IOS` is the base64 encoded version of your Firebase project config file, which can be generated as follows:
The values you should provide to `GOOGLE_SERVICES_B64_ANDROID` or `GOOGLE_SERVICES_B64_IOS` are the base64 encoded versions of the example Firebase project config files. These can also be generated locally:

**For Android**
```bash
Expand Down
33 changes: 25 additions & 8 deletions app/components/Nav/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import SharedDeeplinkManager from '../../../core/DeeplinkManager/SharedDeeplinkM
import branch from 'react-native-branch';
import AppConstants from '../../../core/AppConstants';
import Logger from '../../../util/Logger';
import { routingInstrumentation } from '../../../util/sentry/utils';
import { connect, useDispatch } from 'react-redux';
import {
CURRENT_APP_VERSION,
Expand Down Expand Up @@ -138,7 +137,13 @@ import Engine from '../../../core/Engine';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { PopularList } from '../../../util/networks/customNetworks';
import { RpcEndpointType } from '@metamask/network-controller';
import { trace, TraceName, TraceOperation } from '../../../util/trace';
import {
endTrace,
trace,
TraceName,
TraceOperation,
} from '../../../util/trace';
import getUIStartupSpan from '../../../core/Performance/UIStartup';

const clearStackNavigatorOptions = {
headerShown: false,
Expand Down Expand Up @@ -584,6 +589,12 @@ const App = (props) => {
const sdkInit = useRef();
const [onboarded, setOnboarded] = useState(false);

trace({
name: TraceName.NavInit,
parentContext: getUIStartupSpan(),
op: TraceOperation.NavInit,
});

const triggerSetCurrentRoute = (route) => {
dispatch(setCurrentRoute(route));
if (route === 'Wallet' || route === 'BrowserView') {
Expand All @@ -599,9 +610,10 @@ const App = (props) => {
setOnboarded(!!existingUser);
try {
if (existingUser) {
// This should only be called if the auth type is not password, which is not the case so consider removing it
await trace(
{
name: TraceName.BiometricAuthentication,
name: TraceName.AppStartBiometricAuthentication,
op: TraceOperation.BiometricAuthentication,
},
async () => {
Expand All @@ -624,6 +636,7 @@ const App = (props) => {
}),
);
}

await Authentication.lockApp({ reset: false });
trackErrorAsAnalytics(
'App: Max Attempts Reached',
Expand All @@ -632,9 +645,15 @@ const App = (props) => {
);
}
};
appTriggeredAuth().catch((error) => {
Logger.error(error, 'App: Error in appTriggeredAuth');
});
appTriggeredAuth()
.catch((error) => {
Logger.error(error, 'App: Error in appTriggeredAuth');
})
.finally(() => {
endTrace({ name: TraceName.NavInit });

endTrace({ name: TraceName.UIStartup });
});
}, [navigator, queueOfHandleDeeplinkFunctions]);

const handleDeeplink = useCallback(({ error, params, uri }) => {
Expand Down Expand Up @@ -684,8 +703,6 @@ const App = (props) => {
});

if (!prevNavigator.current) {
// Setup navigator with Sentry instrumentation
routingInstrumentation.registerNavigationContainer(navigator);
// Subscribe to incoming deeplinks
// Branch.io documentation: https://help.branch.io/developers-hub/docs/react-native
branch.subscribe((opts) => {
Expand Down
51 changes: 48 additions & 3 deletions app/components/UI/AccountSelectorList/AccountSelector.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../../../util/test/accountsControllerTestUtils';
import { mockNetworkState } from '../../../util/test/network';
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { AccountSelectorListProps } from './AccountSelectorList.types';

const BUSINESS_ACCOUNT = '0xC4955C0d639D99699Bfd7Ec54d9FaFEe40e4D272';
const PERSONAL_ACCOUNT = '0xd018538C87232FF95acbCe4870629b75640a78E7';
Expand Down Expand Up @@ -82,8 +83,9 @@ const initialState = {

const onSelectAccount = jest.fn();
const onRemoveImportedAccount = jest.fn();

const AccountSelectorListUseAccounts = () => {
const AccountSelectorListUseAccounts: React.FC<AccountSelectorListProps> = ({
privacyMode = false,
}) => {
const { accounts, ensByAccountAddress } = useAccounts();
return (
<AccountSelectorList
Expand All @@ -92,6 +94,7 @@ const AccountSelectorListUseAccounts = () => {
accounts={accounts}
ensByAccountAddress={ensByAccountAddress}
isRemoveAccountEnabled
privacyMode={privacyMode}
/>
);
};
Expand All @@ -118,7 +121,7 @@ const renderComponent = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
state: any = {},
AccountSelectorListTest = AccountSelectorListUseAccounts,
) => renderWithProvider(<AccountSelectorListTest />, { state });
) => renderWithProvider(<AccountSelectorListTest {...state} />, { state });

describe('AccountSelectorList', () => {
beforeEach(() => {
Expand Down Expand Up @@ -238,4 +241,46 @@ describe('AccountSelectorList', () => {
expect(snapTag).toBeDefined();
});
});
it('Text is not hidden when privacy mode is off', async () => {
const state = {
...initialState,
privacyMode: false,
};

const { queryByTestId } = renderComponent(state);

await waitFor(() => {
const businessAccountItem = queryByTestId(
`${AccountListViewSelectorsIDs.ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}-${BUSINESS_ACCOUNT}`,
);

expect(within(businessAccountItem).getByText(regex.eth(1))).toBeDefined();
expect(
within(businessAccountItem).getByText(regex.usd(3200)),
).toBeDefined();

expect(within(businessAccountItem).queryByText('••••••')).toBeNull();
});
});
it('Text is hidden when privacy mode is on', async () => {
const state = {
...initialState,
privacyMode: true,
};

const { queryByTestId } = renderComponent(state);

await waitFor(() => {
const businessAccountItem = queryByTestId(
`${AccountListViewSelectorsIDs.ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID}-${BUSINESS_ACCOUNT}`,
);

expect(within(businessAccountItem).queryByText(regex.eth(1))).toBeNull();
expect(
within(businessAccountItem).queryByText(regex.usd(3200)),
).toBeNull();

expect(within(businessAccountItem).getByText('••••••')).toBeDefined();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import Cell, {
} from '../../../component-library/components/Cells/Cell';
import { InternalAccount } from '@metamask/keyring-api';
import { useStyles } from '../../../component-library/hooks';
import { selectPrivacyMode } from '../../../selectors/preferencesController';
import { TextColor } from '../../../component-library/components/Texts/Text';
import SensitiveText, {
SensitiveTextLength,
Expand Down Expand Up @@ -52,6 +51,7 @@ const AccountSelectorList = ({
isSelectionDisabled,
isRemoveAccountEnabled = false,
isAutoScrollEnabled = true,
privacyMode = false,
...props
}: AccountSelectorListProps) => {
const { navigate } = useNavigation();
Expand All @@ -72,7 +72,6 @@ const AccountSelectorList = ({
);

const internalAccounts = useSelector(selectInternalAccounts);
const privacyMode = useSelector(selectPrivacyMode);
const getKeyExtractor = ({ address }: Account) => address;

const renderAccountBalances = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ export interface AccountSelectorListProps
* Optional boolean to enable removing accounts.
*/
isRemoveAccountEnabled?: boolean;
/**
* Optional boolean to indicate if privacy mode is enabled.
*/
privacyMode?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const createStyles = (params: {
marginRight: 24,
marginLeft: 24,
},
bottomButtonsContainer: {
marginTop: 16,
},
actionButtonsContainer: {
flex: 0,
flexDirection: 'row',
Expand Down Expand Up @@ -118,7 +121,6 @@ const createStyles = (params: {
walletIcon: { alignSelf: 'flex-start' },
dataIcon: { alignSelf: 'flex-start' },
disconnectAllContainer: {
marginTop: 16,
marginHorizontal: 24,
flexDirection: 'row',
},
Expand Down
6 changes: 4 additions & 2 deletions app/components/UI/PermissionsSummary/PermissionsSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ const PermissionsSummary = ({
{!isNetworkSwitch && renderAccountPermissionsRequestInfoCard()}
{renderNetworkPermissionsRequestInfoCard()}
</View>
<View>
<View style={styles.bottomButtonsContainer}>
{isAlreadyConnected && isDisconnectAllShown && (
<View style={styles.disconnectAllContainer}>
<Button
Expand Down Expand Up @@ -424,7 +424,9 @@ const PermissionsSummary = ({
]}
testID={CommonSelectorsIDs.CONNECT_BUTTON}
>
{strings('accounts.connect')}
{isNetworkSwitch
? strings('confirmation_modal.confirm_cta')
: strings('accounts.connect')}
</StyledButton>
</View>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,18 @@ exports[`PermissionsSummary should render correctly 1`] = `
</View>
</TouchableOpacity>
</View>
<View>
<View
style={
{
"marginTop": 16,
}
}
>
<View
style={
{
"flexDirection": "row",
"marginHorizontal": 24,
"marginTop": 16,
}
}
>
Expand Down Expand Up @@ -1058,13 +1063,18 @@ exports[`PermissionsSummary should render correctly for network switch 1`] = `
</View>
</TouchableOpacity>
</View>
<View>
<View
style={
{
"marginTop": 16,
}
}
>
<View
style={
{
"flexDirection": "row",
"marginHorizontal": 24,
"marginTop": 16,
}
}
>
Expand Down Expand Up @@ -1248,7 +1258,7 @@ exports[`PermissionsSummary should render correctly for network switch 1`] = `
]
}
>
Connect
Confirm
</Text>
</TouchableOpacity>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ exports[`StakeInputView render matches snapshot 1`] = `
accessibilityRole="text"
style={
{
"color": "#9fa6ae",
"color": "#141618",
"fontFamily": "EuclidCircularB-Bold",
"fontSize": 32,
"fontWeight": "700",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ exports[`UnstakeInputView render matches snapshot 1`] = `
accessibilityRole="text"
style={
{
"color": "#9fa6ae",
"color": "#141618",
"fontFamily": "EuclidCircularB-Bold",
"fontSize": 32,
"fontWeight": "700",
Expand Down
6 changes: 1 addition & 5 deletions app/components/UI/Stake/components/InputDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const InputDisplay = ({
isOverMaximum,
balanceText,
balanceValue,
isNonZeroAmount,
isEth,
amountEth,
fiatAmount,
Expand All @@ -70,10 +69,7 @@ const InputDisplay = ({
)}
</View>
<View style={styles.amountRow}>
<Text
color={isNonZeroAmount ? TextColor.Default : TextColor.Muted}
variant={TextVariant.DisplayMD}
>
<Text color={TextColor.Default} variant={TextVariant.DisplayMD}>
{isEth ? amountEth : fiatAmount}
</Text>
<Text color={TextColor.Muted} variant={TextVariant.DisplayMD}>
Expand Down
4 changes: 3 additions & 1 deletion app/components/UI/Stake/components/StakeButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ const StakeButtonContent = ({ asset }: StakeButtonProps) => {
<Text variant={TextVariant.BodyLGMedium}>
{' • '}
<Text color={TextColor.Primary} variant={TextVariant.BodyLGMedium}>
{`${strings('stake.earn')} `}
{isPooledStakingFeatureEnabled()
? `${strings('stake.earn')} `
: `${strings('stake.stake')} `}
</Text>
</Text>
<Icon
Expand Down
Loading

0 comments on commit 5eaf361

Please sign in to comment.