From b50b9be502e24f94d3cedc66bf13f55c7035b1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Regadas?= Date: Mon, 17 Apr 2023 09:22:53 +0100 Subject: [PATCH] [MMI] moves mmi selectors to institutional folder (#18542) * adds the initial selectors * adds more selectors * adds tests * fix lint and prettier --- ui/selectors/institutional/selectors.js | 64 ++++++++ ui/selectors/institutional/selectors.test.js | 151 +++++++++++++++++++ ui/selectors/selectors.js | 6 + 3 files changed, 221 insertions(+) create mode 100644 ui/selectors/institutional/selectors.js create mode 100644 ui/selectors/institutional/selectors.test.js diff --git a/ui/selectors/institutional/selectors.js b/ui/selectors/institutional/selectors.js new file mode 100644 index 000000000..6fe4a7918 --- /dev/null +++ b/ui/selectors/institutional/selectors.js @@ -0,0 +1,64 @@ +import { toChecksumAddress } from 'ethereumjs-util'; +import { getSelectedIdentity, getAccountType, getProvider } from '../selectors'; + +export function getWaitForConfirmDeepLinkDialog(state) { + return state.metamask.waitForConfirmDeepLinkDialog; +} + +export function getTransactionStatusMap(state) { + return state.metamask.custodyStatusMaps; +} + +export function getCustodyAccountDetails(state) { + return state.metamask.custodyAccountDetails; +} + +export function getCustodyAccountSupportedChains(state, address) { + return state.metamask.custodianSupportedChains + ? state.metamask.custodianSupportedChains[toChecksumAddress(address)] + : []; +} + +export function getMmiPortfolioEnabled(state) { + return state.metamask.mmiConfiguration?.portfolio?.enabled; +} + +export function getMmiPortfolioUrl(state) { + return state.metamask.mmiConfiguration?.portfolio?.url; +} + +export function getConfiguredCustodians(state) { + return state.metamask.mmiConfiguration?.custodians || []; +} + +export function getCustodianIconForAddress(state, address) { + let custodianIcon; + + const checksummedAddress = toChecksumAddress(address); + if (state.metamask.custodyAccountDetails?.[checksummedAddress]) { + const { custodianName } = + state.metamask.custodyAccountDetails[checksummedAddress]; + custodianIcon = state.metamask.mmiConfiguration?.custodians?.find( + (custodian) => custodian.name === custodianName, + )?.iconUrl; + } + + return custodianIcon; +} + +export function getIsCustodianSupportedChain(state) { + const selectedIdentity = getSelectedIdentity(state); + const accountType = getAccountType(state); + const provider = getProvider(state); + + const supportedChains = + accountType === 'custody' + ? getCustodyAccountSupportedChains(state, selectedIdentity.address) + : null; + + return supportedChains?.supportedChains + ? supportedChains.supportedChains.includes( + Number(provider.chainId).toString(), + ) + : true; +} diff --git a/ui/selectors/institutional/selectors.test.js b/ui/selectors/institutional/selectors.test.js new file mode 100644 index 000000000..1cbf02213 --- /dev/null +++ b/ui/selectors/institutional/selectors.test.js @@ -0,0 +1,151 @@ +import { toChecksumAddress } from 'ethereumjs-util'; +import { + getConfiguredCustodians, + getCustodianIconForAddress, + getCustodyAccountDetails, + getCustodyAccountSupportedChains, + getMmiPortfolioEnabled, + getMmiPortfolioUrl, + getTransactionStatusMap, + getWaitForConfirmDeepLinkDialog, + getIsCustodianSupportedChain, +} from './selectors'; + +describe('Institutional selectors', () => { + const state = { + metamask: { + provider: { + type: 'test', + chainId: '1', + }, + identities: { + '0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275': { + name: 'Custody Account A', + address: '0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275', + }, + }, + selectedAddress: '0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275', + waitForConfirmDeepLinkDialog: '123', + keyrings: [ + { + type: 'Custody', + accounts: ['0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275'], + }, + ], + custodyStatusMaps: '123', + custodyAccountDetails: { + '0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275': { + custodianName: 'saturn', + }, + }, + custodianSupportedChains: { + '0x5Ab19e7091dD208F352F8E727B6DCC6F8aBB6275': { + supportedChains: ['1', '2'], + custodianName: 'saturn', + }, + }, + mmiConfiguration: { + portfolio: { + enabled: true, + url: 'https://dashboard.metamask-institutional.io', + }, + custodians: [ + { + type: 'saturn', + name: 'saturn', + apiUrl: 'https://saturn-custody.dev.metamask-institutional.io', + iconUrl: 'images/saturn.svg', + displayName: 'Saturn Custody', + production: true, + refreshTokenUrl: null, + isNoteToTraderSupported: false, + version: 1, + }, + ], + }, + }, + }; + + describe('getWaitForConfirmDeepLinkDialog', () => { + it('extracts a state property', () => { + const result = getWaitForConfirmDeepLinkDialog(state); + expect(result).toStrictEqual(state.metamask.waitForConfirmDeepLinkDialog); + }); + }); + + describe('getCustodyAccountDetails', () => { + it('extracts a state property', () => { + const result = getCustodyAccountDetails(state); + expect(result).toStrictEqual(state.metamask.custodyAccountDetails); + }); + }); + + describe('getTransactionStatusMap', () => { + it('extracts a state property', () => { + const result = getTransactionStatusMap(state); + expect(result).toStrictEqual(state.metamask.custodyStatusMaps); + }); + }); + + describe('getCustodianSupportedChains', () => { + it('extracts a state property', () => { + const result = getCustodyAccountSupportedChains( + state, + '0x5ab19e7091dd208f352f8e727b6dcc6f8abb6275', + ); + expect(result).toStrictEqual( + state.metamask.custodianSupportedChains[ + toChecksumAddress('0x5ab19e7091dd208f352f8e727b6dcc6f8abb6275') + ], + ); + }); + }); + + describe('getMmiPortfolioEnabled', () => { + it('extracts a state property', () => { + const result = getMmiPortfolioEnabled(state); + expect(result).toStrictEqual( + state.metamask.mmiConfiguration.portfolio.enabled, + ); + }); + }); + + describe('getMmiPortfolioUrl', () => { + it('extracts a state property', () => { + const result = getMmiPortfolioUrl(state); + expect(result).toStrictEqual( + state.metamask.mmiConfiguration.portfolio.url, + ); + }); + }); + + describe('getConfiguredCustodians', () => { + it('extracts a state property', () => { + const result = getConfiguredCustodians(state); + expect(result).toStrictEqual(state.metamask.mmiConfiguration.custodians); + }); + }); + + describe('getCustodianIconForAddress', () => { + it('extracts a state property', () => { + const result = getCustodianIconForAddress( + state, + '0x5ab19e7091dd208f352f8e727b6dcc6f8abb6275', + ); + + expect(result).toStrictEqual( + state.metamask.mmiConfiguration.custodians[0].iconUrl, + ); + }); + }); + + describe('getIsCustodianSupportedChain', () => { + it('extracts a state property', () => { + const result = getIsCustodianSupportedChain( + state, + '0x5ab19e7091dd208f352f8e727b6dcc6f8abb6275', + ); + expect(result).toStrictEqual(true); + }); + }); +}); diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 7c3f6bf6d..4b4c3aba8 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -228,6 +228,12 @@ export function getAccountType(state) { const currentKeyring = getCurrentKeyring(state); const type = currentKeyring && currentKeyring.type; + ///: BEGIN:ONLY_INCLUDE_IN(mmi) + if (type.startsWith('Custody')) { + return 'custody'; + } + ///: END:ONLY_INCLUDE_IN + switch (type) { case KeyringType.trezor: case KeyringType.ledger: