Skip to content

Commit 0f8ce54

Browse files
gantunesrhmalik88
andauthored
chore: add selector to get account groups by addresses (#35547)
<!-- 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** <!-- 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? --> [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/35547?quickstart=1) Adds a new selector (`getAccountGroupsByAddress`) to get an arrays of account groups given an array of addresses as input. This change can't be tested since the selector is not consumed anywhere yet ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MUL-723 ## **Manual testing steps** None ## **Screenshots/Recordings** None ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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. --------- Co-authored-by: Hassan Malik <41640681+hmalik88@users.noreply.github.com>
1 parent 329ac8c commit 0f8ce54

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

ui/selectors/multichain-accounts/account-tree.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
getWalletsWithAccounts,
3131
getNetworkAddressCount,
3232
getWallet,
33+
getAccountGroupsByAddress,
3334
} from './account-tree';
3435
import { MultichainAccountsState } from './account-tree.types';
3536
import {
@@ -1189,4 +1190,47 @@ describe('Multichain Accounts Selectors', () => {
11891190
expect(result[2].id).toBe('account-2');
11901191
});
11911192
});
1193+
1194+
describe('getAccountGroupsByAddress', () => {
1195+
it('returns the correct account groups without duplicated values', () => {
1196+
const result = getAccountGroupsByAddress(typedMockState, [
1197+
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
1198+
'0xc42edfcc21ed14dda456aa0756c153f7985d8813',
1199+
'0xeb9e64b93097bc15f01f13eae97015c57ab64823',
1200+
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b',
1201+
]);
1202+
1203+
expect(result.length).toBe(3);
1204+
expect(result[0].id).toBe(ENTROPY_GROUP_1_ID);
1205+
expect(result[1].id).toBe(ENTROPY_GROUP_2_ID);
1206+
expect(result[2].id).toBe(LEDGER_GROUP_ID);
1207+
});
1208+
1209+
it('returns an empty array when no addresses match', () => {
1210+
const result = getAccountGroupsByAddress(typedMockState, [
1211+
'nonExistentAddress',
1212+
]);
1213+
1214+
expect(result).toEqual([]);
1215+
});
1216+
1217+
it('returns an empty array when given an empty address list', () => {
1218+
const result = getAccountGroupsByAddress(typedMockState, []);
1219+
1220+
expect(result).toEqual([]);
1221+
});
1222+
1223+
it('handles duplicated addresses in the input list', () => {
1224+
const result = getAccountGroupsByAddress(typedMockState, [
1225+
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
1226+
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', // duplicate
1227+
'0xc42edfcc21ed14dda456aa0756c153f7985d8813',
1228+
'0xc42edfcc21ed14dda456aa0756c153f7985d8813', // duplicate
1229+
]);
1230+
1231+
expect(result.length).toBe(2);
1232+
expect(result[0].id).toBe(ENTROPY_GROUP_1_ID);
1233+
expect(result[1].id).toBe(LEDGER_GROUP_ID);
1234+
});
1235+
});
11921236
});

ui/selectors/multichain-accounts/account-tree.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,3 +698,38 @@ export const getInternalAccountsFromGroupById = createSelector(
698698
.filter((account): account is InternalAccount => Boolean(account));
699699
},
700700
);
701+
702+
/**
703+
* Selector to get account groups by a list of addresses.
704+
* Returns groups that contain at least one account matching any of the provided addresses.
705+
*
706+
* @param _state - Redux state.
707+
* @param addresses - An array of addresses to filter account groups by.
708+
* @returns An array of AccountGroupWithInternalAccounts that contain at least one matching account.
709+
*/
710+
export const getAccountGroupsByAddress = createDeepEqualSelector(
711+
[
712+
getAccountGroupWithInternalAccounts,
713+
(_state: MultichainAccountsState, addresses: string[]) =>
714+
new Set(addresses.map((address) => address.toLowerCase())),
715+
],
716+
(
717+
accountGroupWithInternalAccounts,
718+
addressesSet: Set<string>,
719+
): AccountGroupWithInternalAccounts[] => {
720+
const matchingGroups = new Set<AccountGroupWithInternalAccounts>();
721+
722+
accountGroupWithInternalAccounts.forEach((group) => {
723+
const containsMatchingAccount = group.accounts.some((account) =>
724+
addressesSet.has(account.address.toLowerCase()),
725+
);
726+
727+
if (containsMatchingAccount) {
728+
matchingGroups.add(group);
729+
}
730+
});
731+
732+
// Convert the Set of AccountGroupWithInternalAccounts to an Array
733+
return [...matchingGroups];
734+
},
735+
);

0 commit comments

Comments
 (0)