Skip to content

Commit

Permalink
feat: add the ability for all networks to be pre-selected in the chec…
Browse files Browse the repository at this point in the history
…kbox list on initial connect to a dapp. (#13099)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Issue: When the user had connected dapps and switched the global
network, when he went back to the dapp he was asked to grant permission
to that network for that dapp.

Solution: On initial connection, preselect all enabled networks,
reducing the chances the user finds himself on a network he has not
granted permission for yet.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Related issues**

Fixes: MetaMask/MetaMask-planning#3902

## **Manual testing steps**

1. Go to the in-app browser and navigate to a dapp, then click connect
2. Go to the network permissions by clicking the Edit link button
3. All of the user's enabled networks should be preselected

(also see animated gif below for an example of these manual testing
steps)

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

User was prompted often to grant permission.

### **After**

User can more easily grant permission to all enabled networks on initial
connection:

<img width="350" alt="Screenshot 2024-04-18 at 3 56 43 PM"
src="https://github.com/user-attachments/assets/2b081ecb-5408-49a1-8228-755ac4ae5875">

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
EtherWizard33 authored Jan 24, 2025
1 parent e763bc4 commit f7da406
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 19 deletions.
43 changes: 27 additions & 16 deletions app/components/Views/AccountConnect/AccountConnect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,26 +200,37 @@ const AccountConnect = (props: AccountConnectProps) => {

const { chainId } = useNetworkInfo(hostname);

const [selectedChainIds, setSelectedChainIds] = useState<string[]>(() =>
chainId ? [chainId] : [],
);
const [selectedNetworkIds, setSelectedNetworkIds] = useState<string[]>(() =>
chainId ? [chainId] : [],
);
const [selectedChainIds, setSelectedChainIds] = useState<string[]>(() => {
// Get all enabled network chain IDs from networkConfigurations
const enabledChainIds = Object.values(networkConfigurations).map(
(network) => network.chainId,
);
return enabledChainIds;
});

const [selectedNetworkIds, setSelectedNetworkIds] = useState<string[]>(() => {
// Initialize with all enabled network chain IDs
const enabledChainIds = Object.values(networkConfigurations).map(
(network) => network.chainId,
);
return enabledChainIds;
});

useEffect(() => {
if (chainId) {
const initialNetworkAvatar = {
// Create network avatars for all enabled networks
const networkAvatars = Object.values(networkConfigurations).map(
(network) => ({
size: AvatarSize.Xs,
name: networkConfigurations[chainId]?.name || '',
// @ts-expect-error getNetworkImageSourcenot yet typed
imageSource: getNetworkImageSource({ chainId }),
};
setSelectedNetworkAvatars([initialNetworkAvatar]);
name: network.name || '',
// @ts-expect-error getNetworkImageSource not yet typed
imageSource: getNetworkImageSource({ chainId: network.chainId }),
}),
);

setSelectedChainIds([chainId]);
}
}, [chainId, networkConfigurations]);
setSelectedNetworkAvatars(networkAvatars);

// No need to update selectedChainIds here since it's already initialized with all networks
}, [networkConfigurations]);

const handleUpdateNetworkPermissions = useCallback(async () => {
let hasPermittedChains = false;
Expand Down
10 changes: 10 additions & 0 deletions e2e/pages/Network/NetworkNonPemittedBottomSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class NetworkNonPemittedBottomSheet {
);
}

get elysiumTestnetNetworkName() {
return Matchers.getElementByText(
NetworkNonPemittedBottomSheetSelectorsText.ELYSIUM_TESTNET_NETWORK_NAME,
);
}

get chooseFromPermittedNetworksButton() {
return Matchers.getElementByID(
NetworkNonPemittedBottomSheetSelectorsIDs.CHOOSE_FROM_PERMITTED_NETWORKS_BUTTON,
Expand Down Expand Up @@ -69,6 +75,10 @@ class NetworkNonPemittedBottomSheet {
await Gestures.waitAndTap(this.lineaSepoliaNetworkName);
}

async tapElysiumTestnetNetworkName() {
await Gestures.waitAndTap(this.elysiumTestnetNetworkName);
}

async tapChooseFromPermittedNetworksButton() {
await Gestures.waitAndTap(this.chooseFromPermittedNetworksButton);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const NetworkNonPemittedBottomSheetSelectorsText = {
SEPOLIA_NETWORK_NAME: CustomNetworks.Sepolia.providerConfig.nickname,
ETHEREUM_MAIN_NET_NETWORK_NAME: 'Ethereum Main Network',
LINEA_SEPOLIA_NETWORK_NAME: 'Linea Sepolia',
ELYSIUM_TESTNET_NETWORK_NAME: 'Elysium Testnet',
};

export const NetworkNonPemittedBottomSheetSelectorsIDs = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Assertions from '../../../../utils/Assertions';
import { loginToApp } from '../../../../viewHelper';
import ConnectedAccountsModal from '../../../../pages/Browser/ConnectedAccountsModal';
import NetworkConnectMultiSelector from '../../../../pages/Browser/NetworkConnectMultiSelector';
import NetworkNonPemittedBottomSheet from '../../../../pages/Network/NetworkNonPemittedBottomSheet';

describe(SmokeMultiChainPermissions('Chain Permission System'), () => {
beforeAll(async () => {
Expand Down Expand Up @@ -42,6 +43,9 @@ describe(SmokeMultiChainPermissions('Chain Permission System'), () => {
// Connect to test dApp
await Browser.navigateToTestDApp();
await TestDApp.connect();
await ConnectedAccountsModal.tapNavigateToEditNetworksPermissionsButton();
await NetworkNonPemittedBottomSheet.tapElysiumTestnetNetworkName();
await NetworkConnectMultiSelector.tapUpdateButton();
await ConnectBottomSheet.tapConnectButton();

// Grant permission and switch to new chain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ describe(SmokeMultiChainPermissions('Chain Permission Management'), () => {
// First permission modification: Add Linea Sepolia
await TestDApp.connect();
await ConnectedAccountsModal.tapNavigateToEditNetworksPermissionsButton();

await ConnectedAccountsModal.tapDeselectAllNetworksButton();
await NetworkNonPemittedBottomSheet.tapEthereumMainNetNetworkName();
await NetworkNonPemittedBottomSheet.tapLineaSepoliaNetworkName();
await NetworkConnectMultiSelector.tapUpdateButton();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import TestDApp from '../../../../pages/Browser/TestDApp';
import NetworkEducationModal from '../../../../pages/Network/NetworkEducationModal';
import ConnectBottomSheet from '../../../../pages/Browser/ConnectBottomSheet';
import PermissionSummaryBottomSheet from '../../../../pages/Browser/PermissionSummaryBottomSheet';
import NetworkConnectMultiSelector from '../../../../pages/Browser/NetworkConnectMultiSelector';
import NetworkNonPemittedBottomSheet from '../../../../pages/Network/NetworkNonPemittedBottomSheet';
import ConnectedAccountsModal from '../../../../pages/Browser/ConnectedAccountsModal';

describe(SmokeMultiChainPermissions('Chain Permission Management'), () => {
beforeAll(async () => {
Expand All @@ -34,24 +37,28 @@ describe(SmokeMultiChainPermissions('Chain Permission Management'), () => {
restartDevice: true,
},
async () => {
//should navigate to browser
// Setup: Navigate to browser and login
await loginToApp();
await TabBarComponent.tapBrowser();
await Assertions.checkIfVisible(Browser.browserScreenID);

//TODO: should re add connecting to an external swap step after detox has been updated

// Connect to DApp and configure network permissions
await Browser.navigateToTestDApp();
await TestDApp.connect();
await ConnectedAccountsModal.tapNavigateToEditNetworksPermissionsButton();
await NetworkNonPemittedBottomSheet.tapEthereumMainNetNetworkName();
await NetworkConnectMultiSelector.tapUpdateButton();
await ConnectBottomSheet.tapConnectButton();

// Remove network from settings
await TabBarComponent.tapSettings();
await SettingsView.tapNetworks();
await NetworksView.longPressToRemoveNetwork(
PopularNetworksList.Polygon.providerConfig.nickname,
);
await NetworkEducationModal.tapGotItButton();

// Verify permission cleanup
await TabBarComponent.tapBrowser();
await Assertions.checkIfVisible(
PermissionSummaryBottomSheet.addNetworkPermissionContainer,
Expand Down

0 comments on commit f7da406

Please sign in to comment.