1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-23 18:41:38 +01:00
metamask-extension/ui/app/selectors/selectors.js
Mark Stacey 8225bbe126
Remove unused current view related things (#7843)
* Remove unused functions from `mapDispatchToProps`

The actions import was also updated to import only the two actions
used, rather than all actions.

* Remove unused container component

Well, technically it was the props injected by this container that were
unused. The container served no purpose, so the component it surrounded
is now used directly instead.

* Remove both unused `getCurrentViewContext` selectors

* Remove unused SHOW_CONFIG_PAGE action

* Remove checks for `currentView` with name `config`

Now that the SHOW_CONFIG_PAGE action has been removed, it's no longer
possible for `currentView.name` to be set to that value.

* Remove unused `wallet-view` container props

* Delete unused SHOW_SEND_PAGE and SHOW_ADD_TOKEN_PAGE actions

* Remove unused `account-menu.container` props

* Remove unused SHOW_INFO_PAGE action

* Remove unused SET_NEW_ACCOUNT_FORM action
2020-01-16 13:02:44 -04:00

545 lines
16 KiB
JavaScript

import { NETWORK_TYPES } from '../helpers/constants/common'
import { mapObjectValues } from '../../../app/scripts/lib/util'
import { stripHexPrefix, addHexPrefix } from 'ethereumjs-util'
import { createSelector } from 'reselect'
import abi from 'human-standard-token-abi'
import { multiplyCurrencies } from '../helpers/utils/conversion-util'
import {
addressSlicer,
checksumAddress,
formatDate,
getOriginFromUrl,
} from '../helpers/utils/util'
export function getNetworkIdentifier (state) {
const { metamask: { provider: { type, nickname, rpcTarget } } } = state
return nickname || rpcTarget || type
}
export function getCurrentKeyring (state) {
const identity = getSelectedIdentity(state)
if (!identity) {
return null
}
const simpleAddress = stripHexPrefix(identity.address).toLowerCase()
const keyring = state.metamask.keyrings.find((kr) => {
return kr.accounts.includes(simpleAddress) ||
kr.accounts.includes(identity.address)
})
return keyring
}
export function getAccountType (state) {
const currentKeyring = getCurrentKeyring(state)
const type = currentKeyring && currentKeyring.type
switch (type) {
case 'Trezor Hardware':
case 'Ledger Hardware':
return 'hardware'
case 'Simple Key Pair':
return 'imported'
default:
return 'default'
}
}
export function getSelectedAsset (state) {
const selectedToken = getSelectedToken(state)
return selectedToken && selectedToken.symbol || 'ETH'
}
export function getCurrentNetworkId (state) {
return state.metamask.network
}
export const getMetaMaskAccounts = createSelector(
getMetaMaskAccountsRaw,
getMetaMaskCachedBalances,
(currentAccounts, cachedBalances) => Object.entries(currentAccounts).reduce((selectedAccounts, [accountID, account]) => {
if (account.balance === null || account.balance === undefined) {
return {
...selectedAccounts,
[accountID]: {
...account,
balance: cachedBalances && cachedBalances[accountID],
},
}
} else {
return {
...selectedAccounts,
[accountID]: account,
}
}
}, {})
)
export function getSelectedAddress (state) {
const selectedAddress = state.metamask.selectedAddress || Object.keys(getMetaMaskAccounts(state))[0]
return selectedAddress
}
export function getSelectedIdentity (state) {
const selectedAddress = getSelectedAddress(state)
const identities = state.metamask.identities
return identities[selectedAddress]
}
export function getNumberOfAccounts (state) {
return Object.keys(state.metamask.accounts).length
}
export function getNumberOfTokens (state) {
const tokens = state.metamask.tokens
return tokens ? tokens.length : 0
}
export function getMetaMaskKeyrings (state) {
return state.metamask.keyrings
}
export function getMetaMaskIdentities (state) {
return state.metamask.identities
}
export function getMetaMaskAccountsRaw (state) {
return state.metamask.accounts
}
export function getMetaMaskCachedBalances (state) {
const network = getCurrentNetworkId(state)
return state.metamask.cachedBalances[network]
}
/**
* Get ordered (by keyrings) accounts with identity and balance
*/
export const getMetaMaskAccountsOrdered = createSelector(
getMetaMaskKeyrings,
getMetaMaskIdentities,
getMetaMaskAccounts,
(keyrings, identities, accounts) => keyrings
.reduce((list, keyring) => list.concat(keyring.accounts), [])
.filter(address => !!identities[address])
.map(address => ({ ...identities[address], ...accounts[address] }))
)
export function isBalanceCached (state) {
const selectedAccountBalance = state.metamask.accounts[getSelectedAddress(state)].balance
const cachedBalance = getSelectedAccountCachedBalance(state)
return Boolean(!selectedAccountBalance && cachedBalance)
}
export function getSelectedAccountCachedBalance (state) {
const cachedBalances = state.metamask.cachedBalances[state.metamask.network]
const selectedAddress = getSelectedAddress(state)
return cachedBalances && cachedBalances[selectedAddress]
}
export function getSelectedAccount (state) {
const accounts = getMetaMaskAccounts(state)
const selectedAddress = getSelectedAddress(state)
return accounts[selectedAddress]
}
export function getSelectedToken (state) {
const tokens = state.metamask.tokens || []
const selectedTokenAddress = state.metamask.selectedTokenAddress
const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
const sendToken = state.metamask.send && state.metamask.send.token
return selectedToken || sendToken || null
}
export function getSelectedTokenExchangeRate (state) {
const contractExchangeRates = state.metamask.contractExchangeRates
const selectedToken = getSelectedToken(state) || {}
const { address } = selectedToken
return contractExchangeRates[address] || 0
}
export function getSelectedTokenAssetImage (state) {
const assetImages = state.metamask.assetImages || {}
const selectedToken = getSelectedToken(state) || {}
const { address } = selectedToken
return assetImages[address]
}
export function getAssetImages (state) {
const assetImages = state.metamask.assetImages || {}
return assetImages
}
export function getTokenExchangeRate (state, address) {
const contractExchangeRates = state.metamask.contractExchangeRates
return contractExchangeRates[address] || 0
}
export function conversionRateSelector (state) {
return state.metamask.conversionRate
}
export function getAddressBook (state) {
const network = state.metamask.network
if (!state.metamask.addressBook[network]) {
return []
}
return Object.values(state.metamask.addressBook[network])
}
export function getAddressBookEntry (state, address) {
const addressBook = getAddressBook(state)
const entry = addressBook.find(contact => contact.address === checksumAddress(address))
return entry
}
export function getAddressBookEntryName (state, address) {
const entry = getAddressBookEntry(state, address) || state.metamask.identities[address]
return entry && entry.name !== '' ? entry.name : addressSlicer(address)
}
export function getDaiV1Token (state) {
const OLD_DAI_CONTRACT_ADDRESS = '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
const tokens = state.metamask.tokens || []
return tokens.find(({ address }) => checksumAddress(address) === OLD_DAI_CONTRACT_ADDRESS)
}
export function accountsWithSendEtherInfoSelector (state) {
const accounts = getMetaMaskAccounts(state)
const { identities } = state.metamask
const accountsWithSendEtherInfo = Object.entries(accounts).map(([key, account]) => {
return Object.assign({}, account, identities[key])
})
return accountsWithSendEtherInfo
}
export function getAccountsWithLabels (state) {
const accountsWithoutLabel = accountsWithSendEtherInfoSelector(state)
const accountsWithLabels = accountsWithoutLabel.map(account => {
const { address, name, balance } = account
return {
address,
truncatedAddress: `${address.slice(0, 6)}...${address.slice(-4)}`,
addressLabel: `${name} (...${address.slice(address.length - 4)})`,
label: name,
balance,
}
})
return accountsWithLabels
}
export function getCurrentAccountWithSendEtherInfo (state) {
const currentAddress = getSelectedAddress(state)
const accounts = accountsWithSendEtherInfoSelector(state)
return accounts.find(({ address }) => address === currentAddress)
}
export function getCurrentEthBalance (state) {
return getCurrentAccountWithSendEtherInfo(state).balance
}
export function getGasIsLoading (state) {
return state.appState.gasIsLoading
}
export function getForceGasMin (state) {
return state.metamask.send.forceGasMin
}
export function getSendFrom (state) {
return state.metamask.send.from
}
export function getSendAmount (state) {
return state.metamask.send.amount
}
export function getSendMaxModeState (state) {
return state.metamask.send.maxModeOn
}
export function getCurrentCurrency (state) {
return state.metamask.currentCurrency
}
export function getNativeCurrency (state) {
return state.metamask.nativeCurrency
}
export function getSelectedTokenToFiatRate (state) {
const selectedTokenExchangeRate = getSelectedTokenExchangeRate(state)
const conversionRate = conversionRateSelector(state)
const tokenToFiatRate = multiplyCurrencies(
conversionRate,
selectedTokenExchangeRate,
{ toNumericBase: 'dec' }
)
return tokenToFiatRate
}
export function getSelectedTokenContract (state) {
const selectedToken = getSelectedToken(state)
return selectedToken
? global.eth.contract(abi).at(selectedToken.address)
: null
}
export function getTotalUnapprovedCount ({ metamask }) {
const {
unapprovedTxs = {},
unapprovedMsgCount,
unapprovedPersonalMsgCount,
unapprovedTypedMessagesCount,
} = metamask
return Object.keys(unapprovedTxs).length + unapprovedMsgCount + unapprovedPersonalMsgCount +
unapprovedTypedMessagesCount
}
export function getIsMainnet (state) {
const networkType = getNetworkIdentifier(state)
return networkType === NETWORK_TYPES.MAINNET
}
export function isEthereumNetwork (state) {
const networkType = getNetworkIdentifier(state)
const {
KOVAN,
MAINNET,
RINKEBY,
ROPSTEN,
GOERLI,
} = NETWORK_TYPES
return [ KOVAN, MAINNET, RINKEBY, ROPSTEN, GOERLI].includes(networkType)
}
export function preferencesSelector ({ metamask }) {
return metamask.preferences
}
export function getAdvancedInlineGasShown (state) {
return Boolean(state.metamask.featureFlags.advancedInlineGas)
}
export function getUseNonceField (state) {
return Boolean(state.metamask.useNonceField)
}
export function getCustomNonceValue (state) {
return String(state.metamask.customNonceValue)
}
export function getPermissionsDescriptions (state) {
return state.metamask.permissionsDescriptions
}
export function getPermissionsRequests (state) {
return state.metamask.permissionsRequests
}
export function getDomainMetadata (state) {
return state.metamask.domainMetadata
}
export function getActiveTab (state) {
return state.activeTab
}
export function getMetaMetricState (state) {
return {
network: getCurrentNetworkId(state),
activeCurrency: getSelectedAsset(state),
accountType: getAccountType(state),
metaMetricsId: state.metamask.metaMetricsId,
numberOfTokens: getNumberOfTokens(state),
numberOfAccounts: getNumberOfAccounts(state),
participateInMetaMetrics: state.metamask.participateInMetaMetrics,
}
}
export function getRpcPrefsForCurrentProvider (state) {
const { frequentRpcListDetail, provider } = state.metamask
const selectRpcInfo = frequentRpcListDetail.find(rpcInfo => rpcInfo.rpcUrl === provider.rpcTarget)
const { rpcPrefs = {} } = selectRpcInfo || {}
return rpcPrefs
}
export function getKnownMethodData (state, data) {
if (!data) {
return null
}
const prefixedData = addHexPrefix(data)
const fourBytePrefix = prefixedData.slice(0, 10)
const { knownMethodData } = state.metamask
return knownMethodData && knownMethodData[fourBytePrefix]
}
export function getFeatureFlags (state) {
return state.metamask.featureFlags
}
export function getFirstPermissionRequest (state) {
const requests = getPermissionsRequests(state)
return requests && requests[0] ? requests[0] : null
}
export function hasPermissionRequests (state) {
return Boolean(getFirstPermissionRequest(state))
}
export function getPermissionsDomains (state) {
return state.metamask.domains
}
export function getAddressConnectedDomainMap (state) {
const {
domains,
domainMetadata,
} = state.metamask
const addressConnectedIconMap = {}
if (domains) {
Object.keys(domains).forEach(domainKey => {
const { permissions } = domains[domainKey]
const { icon, name } = domainMetadata[domainKey] || {}
permissions.forEach(perm => {
const caveats = perm.caveats || []
const exposedAccountCaveat = caveats.find(caveat => caveat.name === 'exposedAccounts')
if (exposedAccountCaveat && exposedAccountCaveat.value && exposedAccountCaveat.value.length) {
exposedAccountCaveat.value.forEach(address => {
const nameToRender = name || domainKey
addressConnectedIconMap[address] = addressConnectedIconMap[address]
? { ...addressConnectedIconMap[address], [domainKey]: { icon, name: nameToRender } }
: { [domainKey]: { icon, name: nameToRender } }
})
}
})
})
}
return addressConnectedIconMap
}
export function getDomainToConnectedAddressMap (state) {
const { domains = {} } = state.metamask
const domainToConnectedAddressMap = mapObjectValues(domains, (_, { permissions }) => {
const ethAccountsPermissions = permissions.filter(permission => permission.parentCapability === 'eth_accounts')
const ethAccountsPermissionsExposedAccountAddresses = ethAccountsPermissions.map(permission => {
const caveats = permission.caveats
const exposedAccountsCaveats = caveats.filter(caveat => caveat.name === 'exposedAccounts')
const exposedAccountsAddresses = exposedAccountsCaveats.map(caveat => caveat.value[0])
return exposedAccountsAddresses
})
const allAddressesConnectedToDomain = ethAccountsPermissionsExposedAccountAddresses.reduce((acc, arrayOfAddresses) => {
return [ ...acc, ...arrayOfAddresses ]
}, [])
return allAddressesConnectedToDomain
})
return domainToConnectedAddressMap
}
export function getAddressConnectedToCurrentTab (state) {
const domainToConnectedAddressMap = getDomainToConnectedAddressMap(state)
const originOfCurrentTab = getOriginOfCurrentTab(state)
const addressesConnectedToCurrentTab = domainToConnectedAddressMap[originOfCurrentTab]
const addressConnectedToCurrentTab = addressesConnectedToCurrentTab && addressesConnectedToCurrentTab[0]
return addressConnectedToCurrentTab
}
export function getRenderablePermissionsDomains (state) {
const {
domains = {},
domainMetadata,
permissionsHistory,
permissionsDescriptions,
selectedAddress,
} = state.metamask
const renderableDomains = Object.keys(domains).reduce((acc, domainKey) => {
const { permissions } = domains[domainKey]
const permissionsWithCaveatsForSelectedAddress = permissions.filter(perm => {
const caveats = perm.caveats || []
const exposedAccountCaveat = caveats.find(caveat => caveat.name === 'exposedAccounts')
const exposedAccountCaveatValue = exposedAccountCaveat && exposedAccountCaveat.value && exposedAccountCaveat.value.length
? exposedAccountCaveat.value[0]
: {}
return exposedAccountCaveatValue === selectedAddress
})
if (permissionsWithCaveatsForSelectedAddress.length) {
const permissionKeys = permissions.map(permission => permission.parentCapability)
const {
name,
icon,
extensionId,
} = domainMetadata[domainKey] || {}
const permissionsHistoryForDomain = permissionsHistory[domainKey] || {}
const ethAccountsPermissionsForDomain = permissionsHistoryForDomain['eth_accounts'] || {}
const accountsLastConnectedTime = ethAccountsPermissionsForDomain.accounts || {}
const selectedAddressLastConnectedTime = accountsLastConnectedTime[selectedAddress]
const lastConnectedTime = selectedAddressLastConnectedTime
? formatDate(selectedAddressLastConnectedTime, 'yyyy-M-d')
: ''
return [ ...acc, {
name: name || domainKey,
secondaryName: name ? domainKey : '',
icon,
key: domainKey,
lastConnectedTime,
permissionDescriptions: permissionKeys.map(permissionKey => permissionsDescriptions[permissionKey]),
extensionId,
}]
} else {
return acc
}
}, [])
return renderableDomains
}
export function getOriginOfCurrentTab (state) {
const { activeTab } = state
return activeTab && activeTab.url && getOriginFromUrl(activeTab.url)
}
export function getLastConnectedInfo (state) {
const { permissionsHistory = {} } = state.metamask
const lastConnectedInfoData = Object.keys(permissionsHistory).reduce((acc, origin) => {
const ethAccountsHistory = JSON.parse(JSON.stringify(permissionsHistory[origin]['eth_accounts']))
return {
...acc,
[origin]: ethAccountsHistory.accounts,
}
}, {})
return lastConnectedInfoData
}
export function getIpfsGateway (state) {
return state.metamask.ipfsGateway
}