Skip to content

Commit

Permalink
fix: min amount handling fix
Browse files Browse the repository at this point in the history
  • Loading branch information
nikarm22 committed Sep 23, 2024
1 parent 10d5727 commit e17c09a
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
2 changes: 2 additions & 0 deletions wormhole-connect/src/components/InputTransparent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Props = {
disabled?: boolean;
value?: string | number;
testId?: string;
pattern?: string;
};

const NUMBER_FORMAT_REGEX = /^\d*\.?\d*$/;
Expand Down Expand Up @@ -78,6 +79,7 @@ function InputTransparent(props: Props) {
readOnly={props.disabled}
value={props.value}
data-testid={props.testId}
pattern={props.pattern}
/>
);
}
Expand Down
12 changes: 8 additions & 4 deletions wormhole-connect/src/hooks/useAmountValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ export const useAmountValidation = (props: Props): HookReturn => {
// All quotes fail.
if (allRoutesFailed) {
if (minAmount) {
const amountDisplay = sdkAmount.display(minAmount);
const formattedAmount = sdkAmount.whole(minAmount).toLocaleString('en', {
maximumFractionDigits: 4,
});
return {
error: `Amount too small (min ~${amountDisplay} ${props.tokenSymbol})`,
error: `Amount too small (min ~${formattedAmount} ${props.tokenSymbol})`,
};
} else {
return {
Expand All @@ -95,9 +97,11 @@ export const useAmountValidation = (props: Props): HookReturn => {

// MinQuote warnings information
if (minAmount) {
const amountDisplay = sdkAmount.display(minAmount);
const formattedAmount = sdkAmount.whole(minAmount).toLocaleString('en', {
maximumFractionDigits: 4,
});
return {
warning: `More routes available for amounts exceeding ${amountDisplay} ${props.tokenSymbol}`,
warning: `More routes available for amounts exceeding ${formattedAmount} ${props.tokenSymbol}`,
};
}

Expand Down
2 changes: 1 addition & 1 deletion wormhole-connect/src/utils/sdkv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,5 +445,5 @@ export const isMinAmountError = (
error?: Error,
): error is routes.MinAmountError => {
const unsafeCastError = error as routes.MinAmountError;
return isAmount(unsafeCastError?.min?.amount);
return isAmount(unsafeCastError?.min);
};
94 changes: 94 additions & 0 deletions wormhole-connect/src/views/Bridge/Inputs/AmountInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { useMemo, useRef } from 'react';
import { useSelector } from 'react-redux';

import { RootState } from 'store';
import { toFixedDecimals } from 'utils/balance';
import { NO_INPUT } from 'utils/style';

import InputTransparent from 'components/InputTransparent';
import Input from './Input';
import config from 'config';
import Price from 'components/Price';
import { getTokenPrice, getUSDFormat } from 'utils';
import { TransferSide } from 'config/types';

type Props = {
handleAmountChange: (value: string) => void;
value: string;
disabled?: boolean;
label?: string;
side: TransferSide;
};
function AmountInput(props: Props) {
const amountEl = useRef(null);
const {
showValidationState: showErrors,
validations,
token,
isTransactionInProgress,
} = useSelector((state: RootState) => state.transferInput);
const {
usdPrices: { data },
} = useSelector((state: RootState) => state.tokenPrices);
const prices = data || {};

function handleAmountChange(
e:
| React.ChangeEvent<HTMLInputElement>
| React.ChangeEvent<HTMLTextAreaElement>
| undefined,
) {
let value = e!.target.value;
const index = value.indexOf('.');
if (index > 0 && value.length - index - 8 > 0) {
value = toFixedDecimals(value, 8);
}

props.handleAmountChange(value);
}

const focus = () => {
if (amountEl.current) {
(amountEl.current as any).focus();
}
};

const price = useMemo(() => {
const tokenPrice = getTokenPrice(prices, config.tokens[token]) || 0;
if (!tokenPrice) return undefined;
return getUSDFormat(Number(props.value) * tokenPrice);
}, [props.value, token, prices]);

return (
<Input
label={props.label ?? 'Amount'}
error={!!(showErrors && validations.amount)}
editable
disabled
onClick={focus}
cursor="text"
>
{token ? (
<>
<InputTransparent
inputRef={amountEl}
placeholder="0.00"
type="number"
min={0}
step={0.1}
onChange={handleAmountChange}
disabled={isTransactionInProgress || props.disabled}
value={props.value}
testId={props.side + '-section-amount-input'}
pattern="[0-9]+([\.|,][0-9]{1,2})?"
/>
{price && <Price>{price}</Price>}
</>
) : (
<div>{NO_INPUT}</div>
)}
</Input>
);
}

export default AmountInput;

0 comments on commit e17c09a

Please sign in to comment.