mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-02 14:15:06 +01:00
6f47fece56
Implement `eth_decrypt` and `eth_getEncryptionPublicKey`. This allows decryption backed by the user's private key. The message decryption uses a confirmation flow similar to the messaging signing flow, where the message to be decrypted is also able to be decrypted inline for the user to read directly before confirming.
288 lines
8.8 KiB
JavaScript
288 lines
8.8 KiB
JavaScript
import { createSelector } from 'reselect'
|
|
import txHelper from '../../lib/tx-helper'
|
|
import { calcTokenAmount } from '../helpers/utils/token-util'
|
|
import {
|
|
roundExponential,
|
|
getValueFromWeiHex,
|
|
getHexGasTotal,
|
|
getTransactionFee,
|
|
addFiat,
|
|
addEth,
|
|
} from '../helpers/utils/confirm-tx.util'
|
|
import {
|
|
sumHexes,
|
|
} from '../helpers/utils/transactions.util'
|
|
|
|
const unapprovedTxsSelector = (state) => state.metamask.unapprovedTxs
|
|
const unapprovedMsgsSelector = (state) => state.metamask.unapprovedMsgs
|
|
const unapprovedPersonalMsgsSelector = (state) => state.metamask.unapprovedPersonalMsgs
|
|
const unapprovedDecryptMsgsSelector = (state) => state.metamask.unapprovedDecryptMsgs
|
|
const unapprovedEncryptionPublicKeyMsgsSelector = (state) => state.metamask.unapprovedEncryptionPublicKeyMsgs
|
|
const unapprovedTypedMessagesSelector = (state) => state.metamask.unapprovedTypedMessages
|
|
const networkSelector = (state) => state.metamask.network
|
|
|
|
export const unconfirmedTransactionsListSelector = createSelector(
|
|
unapprovedTxsSelector,
|
|
unapprovedMsgsSelector,
|
|
unapprovedPersonalMsgsSelector,
|
|
unapprovedDecryptMsgsSelector,
|
|
unapprovedEncryptionPublicKeyMsgsSelector,
|
|
unapprovedTypedMessagesSelector,
|
|
networkSelector,
|
|
(
|
|
unapprovedTxs = {},
|
|
unapprovedMsgs = {},
|
|
unapprovedPersonalMsgs = {},
|
|
unapprovedDecryptMsgs = {},
|
|
unapprovedEncryptionPublicKeyMsgs = {},
|
|
unapprovedTypedMessages = {},
|
|
network
|
|
) => txHelper(
|
|
unapprovedTxs,
|
|
unapprovedMsgs,
|
|
unapprovedPersonalMsgs,
|
|
unapprovedDecryptMsgs,
|
|
unapprovedEncryptionPublicKeyMsgs,
|
|
unapprovedTypedMessages,
|
|
network
|
|
) || []
|
|
)
|
|
|
|
export const unconfirmedTransactionsHashSelector = createSelector(
|
|
unapprovedTxsSelector,
|
|
unapprovedMsgsSelector,
|
|
unapprovedPersonalMsgsSelector,
|
|
unapprovedDecryptMsgsSelector,
|
|
unapprovedEncryptionPublicKeyMsgsSelector,
|
|
unapprovedTypedMessagesSelector,
|
|
networkSelector,
|
|
(
|
|
unapprovedTxs = {},
|
|
unapprovedMsgs = {},
|
|
unapprovedPersonalMsgs = {},
|
|
unapprovedDecryptMsgs = {},
|
|
unapprovedEncryptionPublicKeyMsgs = {},
|
|
unapprovedTypedMessages = {},
|
|
network
|
|
) => {
|
|
const filteredUnapprovedTxs = Object.keys(unapprovedTxs).reduce((acc, address) => {
|
|
const { metamaskNetworkId } = unapprovedTxs[address]
|
|
const transactions = { ...acc }
|
|
|
|
if (metamaskNetworkId === network) {
|
|
transactions[address] = unapprovedTxs[address]
|
|
}
|
|
|
|
return transactions
|
|
}, {})
|
|
|
|
return {
|
|
...filteredUnapprovedTxs,
|
|
...unapprovedMsgs,
|
|
...unapprovedPersonalMsgs,
|
|
...unapprovedDecryptMsgs,
|
|
...unapprovedEncryptionPublicKeyMsgs,
|
|
...unapprovedTypedMessages,
|
|
}
|
|
}
|
|
)
|
|
|
|
const unapprovedMsgCountSelector = (state) => state.metamask.unapprovedMsgCount
|
|
const unapprovedPersonalMsgCountSelector = (state) => state.metamask.unapprovedPersonalMsgCount
|
|
const unapprovedDecryptMsgCountSelector = (state) => state.metamask.unapprovedDecryptMsgCount
|
|
const unapprovedEncryptionPublicKeyMsgCountSelector = (state) => state.metamask.unapprovedEncryptionPublicKeyMsgCount
|
|
const unapprovedTypedMessagesCountSelector = (state) => state.metamask.unapprovedTypedMessagesCount
|
|
|
|
export const unconfirmedTransactionsCountSelector = createSelector(
|
|
unapprovedTxsSelector,
|
|
unapprovedMsgCountSelector,
|
|
unapprovedPersonalMsgCountSelector,
|
|
unapprovedDecryptMsgCountSelector,
|
|
unapprovedEncryptionPublicKeyMsgCountSelector,
|
|
unapprovedTypedMessagesCountSelector,
|
|
networkSelector,
|
|
(
|
|
unapprovedTxs = {},
|
|
unapprovedMsgCount = 0,
|
|
unapprovedPersonalMsgCount = 0,
|
|
unapprovedDecryptMsgCount = 0,
|
|
unapprovedEncryptionPublicKeyMsgCount = 0,
|
|
unapprovedTypedMessagesCount = 0,
|
|
network
|
|
) => {
|
|
const filteredUnapprovedTxIds = Object.keys(unapprovedTxs).filter((txId) => {
|
|
const { metamaskNetworkId } = unapprovedTxs[txId]
|
|
return metamaskNetworkId === network
|
|
})
|
|
|
|
return filteredUnapprovedTxIds.length + unapprovedTypedMessagesCount + unapprovedMsgCount +
|
|
unapprovedPersonalMsgCount + unapprovedDecryptMsgCount + unapprovedEncryptionPublicKeyMsgCount
|
|
}
|
|
)
|
|
|
|
|
|
export const currentCurrencySelector = (state) => state.metamask.currentCurrency
|
|
export const conversionRateSelector = (state) => state.metamask.conversionRate
|
|
export const getNativeCurrency = (state) => state.metamask.nativeCurrency
|
|
|
|
export const txDataSelector = (state) => state.confirmTransaction.txData
|
|
const tokenDataSelector = (state) => state.confirmTransaction.tokenData
|
|
const tokenPropsSelector = (state) => state.confirmTransaction.tokenProps
|
|
|
|
const contractExchangeRatesSelector = (state) => state.metamask.contractExchangeRates
|
|
|
|
const tokenDecimalsSelector = createSelector(
|
|
tokenPropsSelector,
|
|
(tokenProps) => tokenProps && tokenProps.tokenDecimals
|
|
)
|
|
|
|
const tokenDataParamsSelector = createSelector(
|
|
tokenDataSelector,
|
|
(tokenData) => (tokenData && tokenData.params) || []
|
|
)
|
|
|
|
const txParamsSelector = createSelector(
|
|
txDataSelector,
|
|
(txData) => (txData && txData.txParams) || {}
|
|
)
|
|
|
|
export const tokenAddressSelector = createSelector(
|
|
txParamsSelector,
|
|
(txParams) => txParams && txParams.to
|
|
)
|
|
|
|
const TOKEN_PARAM_SPENDER = '_spender'
|
|
const TOKEN_PARAM_TO = '_to'
|
|
const TOKEN_PARAM_VALUE = '_value'
|
|
|
|
export const tokenAmountAndToAddressSelector = createSelector(
|
|
tokenDataParamsSelector,
|
|
tokenDecimalsSelector,
|
|
(params, tokenDecimals) => {
|
|
let toAddress = ''
|
|
let tokenAmount = 0
|
|
|
|
if (params && params.length) {
|
|
const toParam = params.find((param) => param.name === TOKEN_PARAM_TO)
|
|
const valueParam = params.find((param) => param.name === TOKEN_PARAM_VALUE)
|
|
toAddress = toParam ? toParam.value : params[0].value
|
|
const value = valueParam ? Number(valueParam.value) : Number(params[1].value)
|
|
|
|
if (tokenDecimals) {
|
|
tokenAmount = calcTokenAmount(value, tokenDecimals).toNumber()
|
|
}
|
|
|
|
tokenAmount = roundExponential(tokenAmount)
|
|
}
|
|
|
|
return {
|
|
toAddress,
|
|
tokenAmount,
|
|
}
|
|
}
|
|
)
|
|
|
|
export const approveTokenAmountAndToAddressSelector = createSelector(
|
|
tokenDataParamsSelector,
|
|
tokenDecimalsSelector,
|
|
(params, tokenDecimals) => {
|
|
let toAddress = ''
|
|
let tokenAmount = 0
|
|
|
|
if (params && params.length) {
|
|
toAddress = params.find((param) => param.name === TOKEN_PARAM_SPENDER).value
|
|
const value = Number(params.find((param) => param.name === TOKEN_PARAM_VALUE).value)
|
|
|
|
if (tokenDecimals) {
|
|
tokenAmount = calcTokenAmount(value, tokenDecimals).toNumber()
|
|
}
|
|
|
|
tokenAmount = roundExponential(tokenAmount)
|
|
}
|
|
|
|
return {
|
|
toAddress,
|
|
tokenAmount,
|
|
}
|
|
}
|
|
)
|
|
|
|
export const sendTokenTokenAmountAndToAddressSelector = createSelector(
|
|
tokenDataParamsSelector,
|
|
tokenDecimalsSelector,
|
|
(params, tokenDecimals) => {
|
|
let toAddress = ''
|
|
let tokenAmount = 0
|
|
|
|
if (params && params.length) {
|
|
toAddress = params.find((param) => param.name === TOKEN_PARAM_TO).value
|
|
let value = Number(params.find((param) => param.name === TOKEN_PARAM_VALUE).value)
|
|
|
|
if (tokenDecimals) {
|
|
value = calcTokenAmount(value, tokenDecimals).toNumber()
|
|
}
|
|
|
|
tokenAmount = roundExponential(value)
|
|
}
|
|
|
|
return {
|
|
toAddress,
|
|
tokenAmount,
|
|
}
|
|
}
|
|
)
|
|
|
|
export const contractExchangeRateSelector = createSelector(
|
|
contractExchangeRatesSelector,
|
|
tokenAddressSelector,
|
|
(contractExchangeRates, tokenAddress) => contractExchangeRates[tokenAddress]
|
|
)
|
|
|
|
export const transactionFeeSelector = function (state, txData) {
|
|
const currentCurrency = currentCurrencySelector(state)
|
|
const conversionRate = conversionRateSelector(state)
|
|
const nativeCurrency = getNativeCurrency(state)
|
|
|
|
const { txParams: { value = '0x0', gas: gasLimit = '0x0', gasPrice = '0x0' } = {} } = txData
|
|
|
|
const fiatTransactionAmount = getValueFromWeiHex({
|
|
value, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
|
|
})
|
|
const ethTransactionAmount = getValueFromWeiHex({
|
|
value, fromCurrency: nativeCurrency, toCurrency: nativeCurrency, conversionRate, numberOfDecimals: 6,
|
|
})
|
|
|
|
const hexTransactionFee = getHexGasTotal({ gasLimit, gasPrice })
|
|
|
|
const fiatTransactionFee = getTransactionFee({
|
|
value: hexTransactionFee,
|
|
fromCurrency: nativeCurrency,
|
|
toCurrency: currentCurrency,
|
|
numberOfDecimals: 2,
|
|
conversionRate,
|
|
})
|
|
const ethTransactionFee = getTransactionFee({
|
|
value: hexTransactionFee,
|
|
fromCurrency: nativeCurrency,
|
|
toCurrency: nativeCurrency,
|
|
numberOfDecimals: 6,
|
|
conversionRate,
|
|
})
|
|
|
|
const fiatTransactionTotal = addFiat(fiatTransactionFee, fiatTransactionAmount)
|
|
const ethTransactionTotal = addEth(ethTransactionFee, ethTransactionAmount)
|
|
const hexTransactionTotal = sumHexes(value, hexTransactionFee)
|
|
|
|
return {
|
|
hexTransactionAmount: value,
|
|
fiatTransactionAmount,
|
|
ethTransactionAmount,
|
|
hexTransactionFee,
|
|
fiatTransactionFee,
|
|
ethTransactionFee,
|
|
fiatTransactionTotal,
|
|
ethTransactionTotal,
|
|
hexTransactionTotal,
|
|
}
|
|
}
|