Commit 600a5fd2 authored by tom's avatar tom

correct error texts

parent f24e2658
...@@ -21,7 +21,7 @@ const AddressVerificationFieldAddress = ({ formState, control }: Props) => { ...@@ -21,7 +21,7 @@ const AddressVerificationFieldAddress = ({ formState, control }: Props) => {
const error = 'address' in formState.errors ? formState.errors.address : undefined; const error = 'address' in formState.errors ? formState.errors.address : undefined;
return ( return (
<FormControl variant="floating" id={ field.name } isRequired size="md" backgroundColor={ backgroundColor }> <FormControl variant="floating" id={ field.name } isRequired size="md" backgroundColor={ backgroundColor } mt={ 8 }>
<Input <Input
{ ...field } { ...field }
required required
......
...@@ -28,7 +28,7 @@ const AddressVerificationFieldMessage = ({ formState, control }: Props) => { ...@@ -28,7 +28,7 @@ const AddressVerificationFieldMessage = ({ formState, control }: Props) => {
isInvalid={ Boolean(error) } isInvalid={ Boolean(error) }
isDisabled isDisabled
autoComplete="off" autoComplete="off"
maxH="105px" maxH={{ base: '140px', lg: '80px' }}
/> />
<InputPlaceholder text="Message to sign" error={ error } isInModal/> <InputPlaceholder text="Message to sign" error={ error } isInModal/>
</FormControl> </FormControl>
......
import { Alert, Box, Button, Flex, Link } from '@chakra-ui/react'; import { Alert, Box, Button, Flex, Link } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import type { SubmitHandler } from 'react-hook-form'; import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
...@@ -14,6 +15,7 @@ import type { ...@@ -14,6 +15,7 @@ import type {
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import type { ResourceError } from 'lib/api/resources'; import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import LinkInternal from 'ui/shared/LinkInternal';
import AddressVerificationFieldAddress from '../fields/AddressVerificationFieldAddress'; import AddressVerificationFieldAddress from '../fields/AddressVerificationFieldAddress';
type Fields = RootFields & AddressVerificationFormFirstStepFields; type Fields = RootFields & AddressVerificationFormFirstStepFields;
...@@ -46,24 +48,9 @@ const AddressVerificationStepAddress = ({ onContinue }: Props) => { ...@@ -46,24 +48,9 @@ const AddressVerificationStepAddress = ({ onContinue }: Props) => {
}); });
if (response.status !== 'SUCCESS') { if (response.status !== 'SUCCESS') {
switch (response.status) { const type = typeof response.status === 'number' ? 'UNKNOWN_ERROR' : response.status;
case 'INVALID_ADDRESS_ERROR': { const message = ('payload' in response ? response.payload?.message : undefined) || 'Oops! Something went wrong';
return setError('root', { type: 'manual', message: 'Specified address either does not exist or is EOA' }); return setError('root', { type, message });
}
case 'IS_OWNER_ERROR': {
return setError('root', { type: 'manual', message: 'User is already an owner of the address' });
}
case 'OWNERSHIP_VERIFIED_ERROR': {
return setError('root', { type: 'manual', message: 'Address ownership has been verified by another account' });
}
case 'SOURCE_CODE_NOT_VERIFIED_ERROR': {
return setError('root', { type: 'manual', message: 'Contract source code has not been verified' });
}
default: {
return setError('root', { type: 'manual', message: response.payload?.message || 'Oops! Something went wrong' });
}
}
} }
onContinue({ ...response.result, address: data.address }); onContinue({ ...response.result, address: data.address });
...@@ -76,10 +63,40 @@ const AddressVerificationStepAddress = ({ onContinue }: Props) => { ...@@ -76,10 +63,40 @@ const AddressVerificationStepAddress = ({ onContinue }: Props) => {
const onSubmit = handleSubmit(onFormSubmit); const onSubmit = handleSubmit(onFormSubmit);
const rootError = (() => {
switch (formState.errors.root?.type) {
case 'INVALID_ADDRESS_ERROR': {
return <span>Specified address either does not exist or is EOA.</span>;
}
case 'IS_OWNER_ERROR': {
return <span>Ownership of this contract address ownership is already verified by this account.</span>;
}
case 'OWNERSHIP_VERIFIED_ERROR': {
return <span>Ownership of this contract address is already verified by another account.</span>;
}
case 'SOURCE_CODE_NOT_VERIFIED_ERROR': {
const href = route({ pathname: '/address/[hash]/contract_verification', query: { hash: address } });
return (
<Box>
<span>The contract source code you entered is not yet verified. Please follow these steps to </span>
<LinkInternal href={ href }>verify the contract</LinkInternal>
<span>.</span>
</Box>
);
}
case undefined: {
return null;
}
default: {
return formState.errors.root?.message;
}
}
})();
return ( return (
<form noValidate onSubmit={ onSubmit }> <form noValidate onSubmit={ onSubmit }>
{ formState.errors.root?.type === 'manual' && <Alert status="warning" mb={ 6 }>{ formState.errors.root?.message }</Alert> } <Box>Let’s check your address...</Box>
<Box mb={ 8 }>Let’s check your address...</Box> { rootError && <Alert status="warning" mt={ 3 }>{ rootError }</Alert> }
<AddressVerificationFieldAddress formState={ formState } control={ control }/> <AddressVerificationFieldAddress formState={ formState } control={ control }/>
<Flex alignItems="center" mt={ 8 } columnGap={ 5 }> <Flex alignItems="center" mt={ 8 } columnGap={ 5 }>
<Button size="lg" type="submit" isDisabled={ formState.isSubmitting }> <Button size="lg" type="submit" isDisabled={ formState.isSubmitting }>
......
...@@ -16,7 +16,6 @@ import type { ...@@ -16,7 +16,6 @@ import type {
import type { VerifiedAddress } from 'types/api/account'; import type { VerifiedAddress } from 'types/api/account';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch'; import useApiFetch from 'lib/api/useApiFetch';
import shortenString from 'lib/shortenString'; import shortenString from 'lib/shortenString';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
...@@ -65,35 +64,15 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre ...@@ -65,35 +64,15 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
}); });
if (response.status !== 'SUCCESS') { if (response.status !== 'SUCCESS') {
switch (response.status) { const type = typeof response.status === 'number' ? 'UNKNOWN_STATUS' : response.status;
case 'INVALID_SIGNATURE_ERROR': { return setError('root', { type, message: response.status === 'INVALID_SIGNER_ERROR' ? response.invalidSigner.signer : undefined });
return setError('root', { type: 'manual', message: 'Invalid signature' });
}
case 'VALIDITY_EXPIRED_ERROR': {
return setError('root', { type: 'manual', message: 'Message validity expired' });
}
case 'INVALID_SIGNER_ERROR': {
const signer = shortenString(response.invalidSigner.signer);
const expectedSigners = [ contractCreator, contractOwner ].filter(Boolean).map(shortenString).join(', ');
const message = `Invalid signer ${ signer }. Expected: ${ expectedSigners }.`;
return setError('root', { type: 'manual', message });
}
case 'UNKNOWN_STATUS': {
return setError('root', { type: 'manual', message: 'Oops! Something went wrong' });
}
default: {
return setError('root', { type: 'manual', message: response.payload?.message || 'Oops! Something went wrong' });
}
}
} }
onContinue(response.result.verifiedAddress); onContinue(response.result.verifiedAddress);
} catch (_error: unknown) { } catch (error) {
const error = _error as ResourceError<AddressVerificationResponseError>; setError('root', { type: 'UNKNOWN_STATUS' });
setError('root', { type: 'manual', message: error.payload?.message || 'Oops! Something went wrong' });
} }
}, [ address, apiFetch, contractCreator, contractOwner, onContinue, setError ]); }, [ address, apiFetch, onContinue, setError ]);
const onSubmit = handleSubmit(onFormSubmit); const onSubmit = handleSubmit(onFormSubmit);
...@@ -103,7 +82,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre ...@@ -103,7 +82,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
onSubmit(); onSubmit();
}, },
onError: (error) => { onError: (error) => {
return setError('root', { type: 'manual', message: (error as Error)?.message || 'Oops! Something went wrong' }); return setError('root', { type: 'SIGNING_FAIL', message: (error as Error)?.message || 'Oops! Something went wrong' });
}, },
}); });
...@@ -154,15 +133,61 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre ...@@ -154,15 +133,61 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
); );
})(); })();
const contactUsLink = <Link>contact us</Link>;
const rootError = (() => {
switch (formState.errors.root?.type) {
case 'INVALID_SIGNATURE_ERROR': {
return <span>The signature could not be processed.</span>;
}
case 'VALIDITY_EXPIRED_ERROR': {
return <span>This verification message has expired. Add the contract address to restart the process.</span>;
}
case 'SIGNING_FAIL': {
return <span>{ formState.errors.root.message }</span>;
}
case 'INVALID_SIGNER_ERROR': {
const signer = shortenString(formState.errors.root.message || '');
const expectedSigners = [ contractCreator, contractOwner ].filter(Boolean).map(shortenString).join(', ');
return (
<Box>
<span>This address </span>
<span>{ signer }</span>
<span> is not a creator/owner of the requested contract and cannot claim ownership. Only </span>
<span>{ expectedSigners }2</span>
<span> can verify ownership of this contract.</span>
</Box>
);
}
case 'UNKNOWN_STATUS': {
return (
<Box>
<span>We are not able to process the verify account ownership for this contract address. Kindly </span>
{ contactUsLink }
<span> for further assistance.</span>
</Box>
);
}
case undefined: {
return null;
}
}
})();
return ( return (
<form noValidate onSubmit={ onSubmit }> <form noValidate onSubmit={ onSubmit }>
{ formState.errors.root?.type === 'manual' && <Alert status="warning" mb={ 6 }>{ formState.errors.root.message }</Alert> } { rootError && <Alert status="warning" mb={ 6 }>{ rootError }</Alert> }
<Box mb={ 8 }> <Box mb={ 8 }>
<span>Please select the address below you will use to sign, copy the message, and sign it using your preferred method. </span> <span>Please select the address to sign and copy the message and sign it using the Blockscout message provider of your choice. </span>
<Link>Additional instructions</Link> <Link href="https://docs.blockscout.com/for-users/my-account/verified-addresses/copy-and-sign-message" target="_blank">
Additional instructions
</Link>
<span>. If you do not see your address here but are sure that you are the owner of the contract, kindly </span>
{ contactUsLink }
<span> for further assistance.</span>
</Box> </Box>
{ (contractOwner || contractCreator) && ( { (contractOwner || contractCreator) && (
<Flex flexDir="column" rowGap={ 4 } mb={ 8 }> <Flex flexDir="column" rowGap={ 4 } mb={ 4 }>
{ contractCreator && ( { contractCreator && (
<Box> <Box>
<chakra.span fontWeight={ 600 }>Contract creator: </chakra.span> <chakra.span fontWeight={ 600 }>Contract creator: </chakra.span>
......
...@@ -34,9 +34,11 @@ const VerifiedAddresses = () => { ...@@ -34,9 +34,11 @@ const VerifiedAddresses = () => {
const handleItemEdit = React.useCallback(() => {}, []); const handleItemEdit = React.useCallback(() => {}, []);
const addButton = ( const addButton = (
<Button size="lg" onClick={ modalProps.onOpen } marginTop={ 8 }> <Box marginTop={ 8 }>
Add address <Button size="lg" onClick={ modalProps.onOpen }>
</Button> Add address
</Button>
</Box>
); );
const skeleton = ( const skeleton = (
...@@ -76,11 +78,9 @@ const VerifiedAddresses = () => { ...@@ -76,11 +78,9 @@ const VerifiedAddresses = () => {
<> <>
<Show below="lg" key="content-mobile" ssr={ false }> <Show below="lg" key="content-mobile" ssr={ false }>
<div>mobile view</div> <div>mobile view</div>
{ addButton }
</Show> </Show>
<Hide below="lg" key="content-desktop" ssr={ false }> <Hide below="lg" key="content-desktop" ssr={ false }>
<VerifiedAddressesTable data={ data.verifiedAddresses } onItemEdit={ handleItemEdit } onItemAdd={ handleItemAdd }/> <VerifiedAddressesTable data={ data.verifiedAddresses } onItemEdit={ handleItemEdit } onItemAdd={ handleItemAdd }/>
{ addButton }
</Hide> </Hide>
</> </>
) : null; ) : null;
...@@ -114,6 +114,7 @@ const VerifiedAddresses = () => { ...@@ -114,6 +114,7 @@ const VerifiedAddresses = () => {
emptyText="" emptyText=""
skeletonProps={{ customSkeleton: skeleton }} skeletonProps={{ customSkeleton: skeleton }}
/> />
{ addButton }
<AddressVerificationModal isOpen={ modalProps.isOpen } onClose={ modalProps.onClose }/> <AddressVerificationModal isOpen={ modalProps.isOpen } onClose={ modalProps.onClose }/>
</Page> </Page>
); );
......
...@@ -68,7 +68,7 @@ const DataListDisplay = (props: Props) => { ...@@ -68,7 +68,7 @@ const DataListDisplay = (props: Props) => {
} }
if (!props.items?.length) { if (!props.items?.length) {
return <Text as="span">{ props.emptyText }</Text>; return props.emptyText ? <Text as="span">{ props.emptyText }</Text> : null;
} }
return ( return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment