diff --git a/app/components/UI/TransactionEdit/index.js b/app/components/UI/TransactionEdit/index.js index 75e2dee083f..ffbbb51ffa9 100644 --- a/app/components/UI/TransactionEdit/index.js +++ b/app/components/UI/TransactionEdit/index.js @@ -81,6 +81,13 @@ const styles = StyleSheet.create({ lineHeight: 12, paddingTop: 6 }, + warning: { + ...fontStyles.bold, + color: colors.warning, + fontSize: 12, + lineHeight: 12, + paddingTop: 6 + }, form: { flex: 1, padding: 16, @@ -110,6 +117,10 @@ class TransactionEdit extends Component { * List of accounts from the AccountTrackerController */ accounts: PropTypes.object, + /** + * Callback to warn if transaction to is a known contract address + */ + checkForAssetAddress: PropTypes.func, /** * react-navigation object used for switching between screens */ @@ -181,6 +192,7 @@ class TransactionEdit extends Component { amountError: '', addressError: '', toAddressError: '', + toAddressWarning: '', gasError: '', fillMax: false, ensRecipient: undefined, @@ -312,9 +324,10 @@ class TransactionEdit extends Component { updateAndValidateToAddress = async (to, ensRecipient) => { await this.props.handleUpdateToAddress(to, ensRecipient); - let { toAddressError } = this.state; + let { toAddressError, toAddressWarning } = this.state; toAddressError = toAddressError || this.props.validateToAddress(); - this.setState({ toAddressError, ensRecipient }); + toAddressWarning = toAddressWarning || this.props.checkForAssetAddress(); + this.setState({ toAddressError, toAddressWarning, ensRecipient }); }; renderAmountLabel = () => { @@ -348,7 +361,7 @@ class TransactionEdit extends Component { transaction: { value, gas, gasPrice, from, to, selectedAsset, readableValue, ensRecipient }, showHexData } = this.props; - const { gasError, toAddressError, data, accountSelectIsOpen, ethInputIsOpen } = this.state; + const { gasError, toAddressError, toAddressWarning, data, accountSelectIsOpen, ethInputIsOpen } = this.state; const totalGas = isBN(gas) && isBN(gasPrice) ? gas.mul(gasPrice) : toBN('0x0'); return ( @@ -383,6 +396,9 @@ class TransactionEdit extends Component { {strings('transaction.to')}: {toAddressError ? {toAddressError} : null} + {!toAddressError && toAddressWarning ? ( + {toAddressWarning} + ) : null} { + const { + tokens, + collectibles, + transaction: { to }, + networkType + } = this.props; + const address = toChecksumAddress(to); + if (networkType === 'mainnet') { + const contractMapToken = contractMap[address]; + if (contractMapToken) return strings('transaction.known_asset_contract'); + } + const tokenAddress = tokens.find(token => token.address === address); + if (tokenAddress) return strings('transaction.known_asset_contract'); + const collectibleAddress = collectibles.find(collectible => collectible.address === address); + if (collectibleAddress) return strings('transaction.known_asset_contract'); + return undefined; + }; + handleNewTxMeta = async ({ target_address, chain_id = null, // eslint-disable-line no-unused-vars @@ -487,6 +525,7 @@ class TransactionEditor extends Component { validateGas={this.validateGas} validateToAddress={this.validateToAddress} handleUpdateAsset={this.handleUpdateAsset} + checkForAssetAddress={this.checkForAssetAddress} handleUpdateReadableValue={this.handleUpdateReadableValue} /> )} @@ -506,8 +545,11 @@ class TransactionEditor extends Component { const mapStateToProps = state => ({ accounts: state.engine.backgroundState.AccountTrackerController.accounts, + collectibles: state.engine.backgroundState.AssetsController.collectibles, contractBalances: state.engine.backgroundState.TokenBalancesController.contractBalances, + networkType: state.engine.backgroundState.NetworkController.provider.type, selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, + tokens: state.engine.backgroundState.AssetsController.tokens, transaction: state.transaction }); diff --git a/app/components/UI/TransactionEditor/index.test.js b/app/components/UI/TransactionEditor/index.test.js index b02715ee0fa..7f3e4eb880b 100644 --- a/app/components/UI/TransactionEditor/index.test.js +++ b/app/components/UI/TransactionEditor/index.test.js @@ -19,6 +19,15 @@ describe('TransactionEditor', () => { }, PreferencesController: { selectedAddress: '0x0' + }, + AssetsController: { + tokens: [], + collectibles: [] + }, + NetworkController: { + provider: { + type: 'mainnet' + } } } } diff --git a/locales/en.json b/locales/en.json index 9b0f6f53388..169a1afd5f5 100644 --- a/locales/en.json +++ b/locales/en.json @@ -324,6 +324,7 @@ "invalid_gas": "Invalid gas amount", "invalid_gas_price": "Invalid gas price", "invalid_collectible_ownership": "You don't own this collectible", + "known_asset_contract": "Known asset contract address", "max": "Max", "recipient_address": "Recipient Address", "required": "Required", diff --git a/locales/es.json b/locales/es.json index 8c39be5350a..dbd5a66be66 100644 --- a/locales/es.json +++ b/locales/es.json @@ -328,6 +328,7 @@ "review_function_type": "TIPO DE FUNCIÓN", "review_hex_data": "DATOS HEX ", "invalid_collectible_ownership": "No eres el dueño de este coleccionable", + "known_asset_contract": "Dirección de contrato de un activo conocido", "conversion_not_available": "Datos de conversión no disponibles", "value_not_available": "No disponible", "rate_not_available": "Conversión no disponible",