1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Ensure smart contract interactions are properly represented on the confirm screen (#15446)

* Ensure smart contract interactions are properly represented on the confirm screen

* Fix unit tests

* Code cleanup

* Cleanup

* Code cleanup

* Fix test
This commit is contained in:
Dan J Miller 2022-08-03 17:05:34 -02:30
parent 1073b4adfb
commit a4f0944517
7 changed files with 57 additions and 17 deletions

View File

@ -74,6 +74,7 @@ const VALID_UNAPPROVED_TRANSACTION_TYPES = [
TRANSACTION_TYPES.SIMPLE_SEND, TRANSACTION_TYPES.SIMPLE_SEND,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER,
TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM,
TRANSACTION_TYPES.CONTRACT_INTERACTION,
]; ];
/** /**

View File

@ -13,6 +13,7 @@ export default function UserPreferencedCurrencyDisplay({
showEthLogo, showEthLogo,
type, type,
showFiat, showFiat,
showCurrencySuffix,
...restProps ...restProps
}) { }) {
const { currency, numberOfDecimals } = useUserPreferencedCurrency(type, { const { currency, numberOfDecimals } = useUserPreferencedCurrency(type, {
@ -43,6 +44,7 @@ export default function UserPreferencedCurrencyDisplay({
data-testid={dataTestId} data-testid={dataTestId}
numberOfDecimals={numberOfDecimals} numberOfDecimals={numberOfDecimals}
prefixComponent={prefixComponent} prefixComponent={prefixComponent}
suffix={showCurrencySuffix && !showEthLogo && currency}
/> />
); );
} }
@ -68,4 +70,5 @@ UserPreferencedCurrencyDisplay.propTypes = {
PropTypes.number, PropTypes.number,
]), ]),
showFiat: PropTypes.bool, showFiat: PropTypes.bool,
showCurrencySuffix: PropTypes.bool,
}; };

View File

@ -18,6 +18,7 @@ import {
INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR, INVALID_RECIPIENT_ADDRESS_NOT_ETH_NETWORK_ERROR,
KNOWN_RECIPIENT_ADDRESS_WARNING, KNOWN_RECIPIENT_ADDRESS_WARNING,
NEGATIVE_ETH_ERROR, NEGATIVE_ETH_ERROR,
RECIPIENT_TYPES,
} from '../../pages/send/send.constants'; } from '../../pages/send/send.constants';
import { import {
@ -82,6 +83,10 @@ import {
getTokens, getTokens,
getUnapprovedTxs, getUnapprovedTxs,
} from '../metamask/metamask'; } from '../metamask/metamask';
import {
isSmartContractAddress,
sumHexes,
} from '../../helpers/utils/transactions.util';
import { resetEnsResolution } from '../ens'; import { resetEnsResolution } from '../ens';
import { import {
@ -89,7 +94,7 @@ import {
isValidHexAddress, isValidHexAddress,
toChecksumHexAddress, toChecksumHexAddress,
} from '../../../shared/modules/hexstring-utils'; } from '../../../shared/modules/hexstring-utils';
import { sumHexes } from '../../helpers/utils/transactions.util';
import fetchEstimatedL1Fee from '../../helpers/utils/optimism/fetchEstimatedL1Fee'; import fetchEstimatedL1Fee from '../../helpers/utils/optimism/fetchEstimatedL1Fee';
import { TOKEN_STANDARDS, ETH } from '../../helpers/constants/common'; import { TOKEN_STANDARDS, ETH } from '../../helpers/constants/common';
@ -383,6 +388,7 @@ export const draftTransactionInitialState = {
error: null, error: null,
nickname: '', nickname: '',
warning: null, warning: null,
type: '',
recipientWarningAcknowledged: false, recipientWarningAcknowledged: false,
}, },
status: SEND_STATUSES.VALID, status: SEND_STATUSES.VALID,
@ -1172,6 +1178,12 @@ const slice = createSlice({
draftTransaction.recipient.warning = action.payload; draftTransaction.recipient.warning = action.payload;
}, },
updateRecipientType: (state, action) => {
const draftTransaction =
state.draftTransactions[state.currentTransactionUUID];
draftTransaction.recipient.type = action.payload;
},
updateDraftTransactionStatus: (state, action) => { updateDraftTransactionStatus: (state, action) => {
const draftTransaction = const draftTransaction =
state.draftTransactions[state.currentTransactionUUID]; state.draftTransactions[state.currentTransactionUUID];
@ -1876,19 +1888,24 @@ export function updateRecipientUserInput(userInput) {
const inputIsValidHexAddress = isValidHexAddress(userInput); const inputIsValidHexAddress = isValidHexAddress(userInput);
let isProbablyAnAssetContract = false; let isProbablyAnAssetContract = false;
if (inputIsValidHexAddress) { if (inputIsValidHexAddress) {
const { symbol, decimals } = getTokenMetadata(userInput, tokenMap) || {}; const smartContractAddress = await isSmartContractAddress(userInput);
if (smartContractAddress) {
dispatch(actions.updateRecipientType(RECIPIENT_TYPES.SMART_CONTRACT));
const { symbol, decimals } =
getTokenMetadata(userInput, tokenMap) || {};
isProbablyAnAssetContract = symbol && decimals !== undefined; isProbablyAnAssetContract = symbol && decimals !== undefined;
if (!isProbablyAnAssetContract) { if (!isProbablyAnAssetContract) {
try { try {
const { standard } = await getTokenStandardAndDetails( const { standard } = await getTokenStandardAndDetails(
userInput, userInput,
sendingAddress, sendingAddress,
); );
isProbablyAnAssetContract = Boolean(standard); isProbablyAnAssetContract = Boolean(standard);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
}
} }
} }
} }
@ -2259,7 +2276,10 @@ export function signTransaction() {
updateTransactionGasFees(draftTransaction.id, editingTx.txParams), updateTransactionGasFees(draftTransaction.id, editingTx.txParams),
); );
} else { } else {
let transactionType = TRANSACTION_TYPES.SIMPLE_SEND; let transactionType =
draftTransaction.recipient.type === RECIPIENT_TYPES.SMART_CONTRACT
? TRANSACTION_TYPES.CONTRACT_INTERACTION
: TRANSACTION_TYPES.SIMPLE_SEND;
if (draftTransaction.asset.type !== ASSET_TYPES.NATIVE) { if (draftTransaction.asset.type !== ASSET_TYPES.NATIVE) {
transactionType = transactionType =

View File

@ -2412,6 +2412,7 @@ describe('Send Slice', () => {
nickname: '', nickname: '',
warning: null, warning: null,
recipientWarningAcknowledged: false, recipientWarningAcknowledged: false,
type: '',
}, },
status: SEND_STATUSES.VALID, status: SEND_STATUSES.VALID,
transactionType: '0x0', transactionType: '0x0',
@ -2554,6 +2555,7 @@ describe('Send Slice', () => {
error: null, error: null,
nickname: '', nickname: '',
warning: null, warning: null,
type: '',
recipientWarningAcknowledged: false, recipientWarningAcknowledged: false,
}, },
status: SEND_STATUSES.VALID, status: SEND_STATUSES.VALID,
@ -2740,6 +2742,7 @@ describe('Send Slice', () => {
error: null, error: null,
warning: null, warning: null,
nickname: '', nickname: '',
type: '',
recipientWarningAcknowledged: false, recipientWarningAcknowledged: false,
}, },
status: SEND_STATUSES.VALID, status: SEND_STATUSES.VALID,

View File

@ -144,8 +144,11 @@ export function getLatestSubmittedTxWithNonce(
} }
export async function isSmartContractAddress(address) { export async function isSmartContractAddress(address) {
const { isContractCode } = await readAddressAsContract(global.eth, address); const { isContractAddress } = await readAddressAsContract(
return isContractCode; global.eth,
address,
);
return isContractAddress;
} }
export function sumHexes(...args) { export function sumHexes(...args) {

View File

@ -864,20 +864,24 @@ export default class ConfirmTransactionBase extends Component {
} }
renderTitleComponent() { renderTitleComponent() {
const { title, hexTransactionAmount } = this.props; const { title, hexTransactionAmount, txData } = this.props;
// Title string passed in by props takes priority // Title string passed in by props takes priority
if (title) { if (title) {
return null; return null;
} }
const isContractInteraction =
txData.type === TRANSACTION_TYPES.CONTRACT_INTERACTION;
return ( return (
<UserPreferencedCurrencyDisplay <UserPreferencedCurrencyDisplay
value={hexTransactionAmount} value={hexTransactionAmount}
type={PRIMARY} type={PRIMARY}
showEthLogo showEthLogo
ethLogoHeight={24} ethLogoHeight={24}
hideLabel hideLabel={!isContractInteraction}
showCurrencySuffix={isContractInteraction}
/> />
); );
} }

View File

@ -47,6 +47,11 @@ const ENS_ILLEGAL_CHARACTER = 'ensIllegalCharacter';
const ENS_UNKNOWN_ERROR = 'ensUnknownError'; const ENS_UNKNOWN_ERROR = 'ensUnknownError';
const ENS_REGISTRATION_ERROR = 'ensRegistrationError'; const ENS_REGISTRATION_ERROR = 'ensRegistrationError';
const RECIPIENT_TYPES = {
SMART_CONTRACT: 'SMART_CONTRACT',
NON_CONTRACT: 'NON_CONTRACT',
};
export { export {
MAX_GAS_LIMIT_DEC, MAX_GAS_LIMIT_DEC,
HIGH_FEE_WARNING_MULTIPLIER, HIGH_FEE_WARNING_MULTIPLIER,
@ -73,4 +78,5 @@ export {
CONFUSING_ENS_ERROR, CONFUSING_ENS_ERROR,
TOKEN_TRANSFER_FUNCTION_SIGNATURE, TOKEN_TRANSFER_FUNCTION_SIGNATURE,
COLLECTIBLE_TRANSFER_FROM_FUNCTION_SIGNATURE, COLLECTIBLE_TRANSFER_FROM_FUNCTION_SIGNATURE,
RECIPIENT_TYPES,
}; };