Skip to content

Commit

Permalink
feat: add error handling when total > balance, closes #196, #197
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Sep 25, 2020
1 parent 1432251 commit 9f08164
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 12 deletions.
8 changes: 5 additions & 3 deletions app/components/error-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Flex, Box, FlexProps } from '@blockstack/ui';

import { ExclamationMark } from './icons/exclamation-mark';

type ErrorLabelProps = FlexProps;
interface ErrorLabelProps extends FlexProps {
size?: 'sm' | 'md';
}

export const ErrorLabel: React.FC<ErrorLabelProps> = ({ children, ...rest }) => (
export const ErrorLabel: React.FC<ErrorLabelProps> = ({ children, size = 'sm', ...rest }) => (
<Flex mt={3} {...rest}>
<Box mr={2} position="relative" top="1px">
<Box mr={2} position="relative" top={{ sm: '1px', md: '4px' }[size]}>
<ExclamationMark />
</Box>
<Box mr={5}>{children}</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const TransactionListItemPending: FC<TransactionListItemPendingProps> = (
</Box>
<Box textAlign="right">
<Text textStyle="body.large" color="ink.900" display="block">
{toHumanReadableStx(tx.amount)}
{toHumanReadableStx(tx.amount)}
</Text>
<Text textStyle="body.small" color="ink.600">
Pending
Expand Down
2 changes: 1 addition & 1 deletion app/modals/transaction/transaction-modal-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const TxModalFooter: FC = ({ children }) => (
);

export const TxModalPreview: FC = ({ children }) => (
<Flex flexDirection="column" fontSize="14px" mx="extra-loose" mt="tight" mb="extra-loose">
<Flex flexDirection="column" fontSize="14px" mx="extra-loose" mt="tight">
{children}
</Flex>
);
Expand Down
38 changes: 34 additions & 4 deletions app/modals/transaction/transaction-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useFormik } from 'formik';
import * as yup from 'yup';
import BN from 'bn.js';
import { BigNumber } from 'bignumber.js';
import { Modal, Text, Button } from '@blockstack/ui';
import { Modal, Text, Button, Box } from '@blockstack/ui';
import { StacksTransaction } from '@blockstack/stacks-transactions';

import { RootState } from '../../store';
Expand All @@ -25,6 +25,8 @@ import { createStxTransaction } from '../../crypto/create-stx-tx';
import { validateAddressChain } from '../../crypto/validate-address-net';
import { broadcastStxTransaction } from '../../store/transaction';
import { toHumanReadableStx, stxToMicroStx } from '../../utils/unit-convert';
import { ErrorLabel } from '../../components/error-label';
import { ErrorText } from '../../components/error-text';

interface TxModalProps {
balance: string;
Expand Down Expand Up @@ -53,6 +55,8 @@ export const TransactionModal: FC<TxModalProps> = ({ balance, address }) => {
mnemonic: selectMnemonic(state),
}));

const totalIsMoreThanBalance = total.isGreaterThan(balance);

const form = useFormik({
initialValues: {
recipient: '',
Expand All @@ -74,17 +78,28 @@ export const TransactionModal: FC<TxModalProps> = ({ balance, address }) => {
),
amount: yup
.number()
.positive('You cannot send a negative amount of STX')
.typeError('Amount of STX must be described as number')
.positive('You cannot send a negative amount of STX')
.test(
'test-has-less-than-or-equal-to-6-decimal-places',
'STX cannot have more than 6 decimal places',
'STX do not have more than 6 decimal places',
(value: number) => {
// Explicit base ensures BigNumber doesn't use exponential notation
const decimals = new BigNumber(value).toString(10).split('.')[1];
return decimals === undefined || decimals.length <= 6;
}
)
.test(
'test-address-has-enough-balance',
'Cannot send more STX than available balance',
(value: number) => {
// If there's no input, pass this test,
// otherwise it'll render the error for this test
if (value === undefined) return true;
const enteredAmount = stxToMicroStx(value);
return enteredAmount.isLessThanOrEqualTo(balance);
}
)
.required(),
}),
onSubmit: async () => {
Expand Down Expand Up @@ -162,14 +177,29 @@ export const TransactionModal: FC<TxModalProps> = ({ balance, address }) => {
<TxModalPreviewItem label="Total">
{toHumanReadableStx(total.toString())}
</TxModalPreviewItem>
<Box minHeight="24px">
{totalIsMoreThanBalance && (
<ErrorLabel size="md" my="base-loose">
<ErrorText fontSize="14px" lineHeight="20px">
You have insufficient balance to complete this transfer.
</ErrorText>
</ErrorLabel>
)}
</Box>
</TxModalPreview>
),
footer: (
<TxModalFooter>
<Button mode="tertiary" onClick={() => setStep(TxModalStep.DescribeTx)} {...buttonStyle}>
Go back
</Button>
<Button ml="base-tight" {...buttonStyle} isLoading={loading} onClick={broadcastTx}>
<Button
ml="base-tight"
{...buttonStyle}
isLoading={loading}
isDisabled={totalIsMoreThanBalance}
onClick={broadcastTx}
>
Confirm and send
</Button>
</TxModalFooter>
Expand Down
4 changes: 1 addition & 3 deletions app/pages/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ interface RootProps {
}

function Root({ store, history }: RootProps) {
useEffect(() => {
void loadFonts();
}, []);
useEffect(() => void loadFonts(), []);

return (
<Provider store={store}>
Expand Down

0 comments on commit 9f08164

Please sign in to comment.