From 1f9bb3aef48c14c5ed53c3d81bdf73de78fdcd9f Mon Sep 17 00:00:00 2001 From: katspaugh Date: Thu, 20 May 2021 11:09:12 +0200 Subject: [PATCH] Fix the input error message in contract interaction (#2253) (#2297) Co-authored-by: Daniel Sanchez --- src/components/forms/validator.test.ts | 25 ++++++++++++++----- src/components/forms/validator.ts | 19 +++++++++----- .../InputComponent/index.tsx | 4 +-- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/components/forms/validator.test.ts b/src/components/forms/validator.test.ts index cc8352fe..496d93ea 100644 --- a/src/components/forms/validator.test.ts +++ b/src/components/forms/validator.test.ts @@ -6,6 +6,7 @@ import { mustBeUrl, minValue, mustBeEthereumAddress, + mustBeAddressHash, minMaxLength, uniqueAddress, differentFrom, @@ -129,8 +130,24 @@ describe('Forms > Validators', () => { }) }) + describe('mustBeAddressHash validator', () => { + const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Must be a valid address' + + it('Returns undefined for a valid ethereum address', async () => { + expect(await mustBeAddressHash('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined() + }) + + it('Returns an error message for an address with an invalid checksum', async () => { + expect(await mustBeAddressHash('0xde0b295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG) + }) + + it('Returns an error message for non-address and non-domain string', async () => { + expect(await mustBeAddressHash('notanaddress')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG) + }) + }) + describe('mustBeEthereumAddress validator', () => { - const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Must be a valid address, ENS or Unstoppable domain' + const MUST_BE_ETH_ADDRESS_OR_DOMAIN_ERR_MSG = 'Must be a valid address, ENS or Unstoppable domain' it('Returns undefined for a valid ethereum address', async () => { expect(await mustBeEthereumAddress('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined() @@ -138,13 +155,9 @@ describe('Forms > Validators', () => { it('Returns an error message for an address with an invalid checksum', async () => { expect(await mustBeEthereumAddress('0xde0b295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual( - MUST_BE_ETH_ADDRESS_ERR_MSG, + MUST_BE_ETH_ADDRESS_OR_DOMAIN_ERR_MSG, ) }) - - it('Returns an error message for non-address string', async () => { - expect(await mustBeEthereumAddress('notanaddress')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG) - }) }) describe('minMaxLength validator', () => { diff --git a/src/components/forms/validator.ts b/src/components/forms/validator.ts index 28211b89..8b974b01 100644 --- a/src/components/forms/validator.ts +++ b/src/components/forms/validator.ts @@ -63,19 +63,26 @@ export const maxValue = (max: number | string) => (value: string): ValidatorRetu export const ok = (): undefined => undefined -export const mustBeEthereumAddress = memoize( +export const mustBeAddressHash = memoize( (address: string): ValidatorReturnType => { + const errorMessage = 'Must be a valid address' const startsWith0x = address?.startsWith('0x') const isAddress = getWeb3().utils.isAddress(address) - - const errorMessage = `Must be a valid address${ - isFeatureEnabled(FEATURES.DOMAIN_LOOKUP) ? ', ENS or Unstoppable domain' : '' - }` - return startsWith0x && isAddress ? undefined : errorMessage }, ) +export const mustBeEthereumAddress = memoize( + (address: string): ValidatorReturnType => { + const errorMessage = 'Must be a valid address, ENS or Unstoppable domain' + const result = mustBeAddressHash(address) + if (result !== undefined && isFeatureEnabled(FEATURES.DOMAIN_LOOKUP)) { + return errorMessage + } + return result + }, +) + export const mustBeEthereumContractAddress = memoize( async (address: string): Promise => { const contractCode = await getWeb3().eth.getCode(address) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderInputParams/InputComponent/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderInputParams/InputComponent/index.tsx index 548f3c37..aee0d440 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderInputParams/InputComponent/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderInputParams/InputComponent/index.tsx @@ -5,7 +5,7 @@ import Col from 'src/components/layout/Col' import Field from 'src/components/forms/Field' import TextField from 'src/components/forms/TextField' -import { composeValidators, mustBeEthereumAddress, required } from 'src/components/forms/validator' +import { composeValidators, mustBeAddressHash, required } from 'src/components/forms/validator' import { isArrayParameter } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils' import ArrayTypeInput from './ArrayTypeInput' @@ -41,7 +41,7 @@ export const InputComponent = ({ type, keyValue, placeholder }: Props): ReactEle testId={keyValue} text={placeholder} type="text" - validate={composeValidators(required, mustBeEthereumAddress)} + validate={composeValidators(required, mustBeAddressHash)} /> )