Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Phase 6b #44

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "error",
"react/prop-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"prefer-const": "warn",
"@typescript-eslint/no-unused-vars": [
"warn",
{
Expand Down
1 change: 1 addition & 0 deletions config/babel.jest.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = babelJest.createTransformer({
},
],
'@babel/preset-env',
'babel-preset-vite'
],
plugins: [
[
Expand Down
3 changes: 0 additions & 3 deletions jest.config.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
module.exports = {
roots: ['<rootDir>/src'],
transform: {
'\\.(ts|tsx)?$': 'babel-jest',
},
testMatch: ['**/?(*.)+(spec|test).{ts,tsx}'],
testEnvironment: 'jsdom',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"@types/testing-library__jest-dom": "^5.14.5",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
"babel-preset-vite": "^1.1.3",
"esbuild-plugin-polyfill-node": "^0.3.0",
"eslint": "^8.34.0",
"eslint-plugin-jest": "^27.2.1",
Expand Down
8 changes: 1 addition & 7 deletions src/components/InputKeys/AmountSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,12 @@ export function AmountSelector<FormFieldValues extends FieldValues, TFieldName e
if (maxBalance === undefined) return;
// If we don't want to show the quote result if the balance is lower that the selected at from,
// we can do so uncommenting this line.
//if (amountBigDecimal.gt(maxBalance.preciseBigDecimal)) return 'Amount exceeds maximum';
if (amountBigDecimal.gt(maxBalance.preciseBigDecimal)) return 'Amount exceeds maximum';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure we don't want the user to check the swap options even if they don't have the balance?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user can still check the swap options.

I understand that the only result here is that the UX will show an error message and will not process the offramp. So I think it has only upsides, no downsides.


if (amountBigDecimal.c[0] !== 0) {
if (amountBigDecimal.e + 1 + maxBalance.decimals < amountBigDecimal.c.length)
return `The number you entered must have at most ${maxBalance.decimals} decimal places`;
}

// To big numbers will break BigNumber.toString() since they return a string with a scientific notation
// this happens beyond 1e+20, so we can check if the number is bigger than that
if (amountBigDecimal.c[0] !== 0) {
if (amountBigDecimal.e + maxBalance.decimals > 20) return `The number you entered is too large`;
}
};

const errorMessage = determineErrorMessage();
Expand Down
76 changes: 34 additions & 42 deletions src/components/InputKeys/From.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface FromProps<FormFieldValues extends FieldValues, TFieldName extends Fiel
inputHasError: boolean;
fromFormFieldName: TFieldName;
form: UseFormReturn<FormFieldValues>;
fromTokenBalances: { [key: string]: BalanceInfo };
tokenBalances: { [key: string]: BalanceInfo };
offrampStarted: boolean;
}

Expand All @@ -27,11 +27,11 @@ export function From<FormFieldValues extends FieldValues, TFieldName extends Fie
inputHasError,
fromFormFieldName,
form,
fromTokenBalances,
tokenBalances,
offrampStarted,
}: FromProps<FormFieldValues, TFieldName>) {
const { setValue } = useFormContext<SwapFormValues>();
const fromTokenBalance = tokenId ? fromTokenBalances[tokenId] : undefined;
const fromTokenBalance = tokenId ? tokenBalances[tokenId] : undefined;

return (
<div
Expand All @@ -54,51 +54,43 @@ export function From<FormFieldValues extends FieldValues, TFieldName extends Fie
type="button"
>
<span className="rounded-full bg-[rgba(0,0,0,0.15)] h-full p-px mr-1">
{fromToken && (
<img
src={`/assets/coins/${fromToken.assetCode.toUpperCase()}.png`}
alt="Pendulum"
className="h-full w-auto"
/>
)}
{fromToken && <img src={fromToken.icon} alt="Pendulum" className="h-full w-auto" />}
{!fromToken && <img src={pendulumIcon} alt="Pendulum" className="h-full w-auto" />}
</span>
<strong className="font-bold">{fromToken?.assetCode || 'Select'}</strong>
<ChevronDownIcon className="w-4 h-4 inline ml-px" />
</Button>
</div>
<div className="flex justify-between items-center mt-1 dark:text-neutral-400 text-neutral-500">
<div className="flex gap-1 text-sm">
{fromTokenBalance !== undefined && (
<>
<span className="mr-1">
Your Balance: <TokenBalance query={fromTokenBalance} symbol={fromToken?.assetCode}></TokenBalance>
</span>
<button
className="text-primary hover:underline"
onClick={() => {
if (fromTokenBalance.approximateNumber !== undefined) {
setValue('fromAmount', (fromTokenBalance.approximateNumber * 0.5).toString());
}
}}
type="button"
>
50%
</button>
<button
className="text-primary hover:underline"
onClick={() => {
if (fromTokenBalance.approximateNumber !== undefined) {
setValue('fromAmount', fromTokenBalance.approximateNumber.toString());
}
}}
type="button"
>
MAX
</button>
</>
)}
</div>
<div className="justify-between items-center mt-1 dark:text-neutral-400 text-neutral-500">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just changed the rendering of the flex box here to get better spacing between the 50% and MAX buttons.

{fromTokenBalance !== undefined && (
<div className="flex text-sm gap-4">
<span className="mr-1 grow">
Your Balance: <TokenBalance query={fromTokenBalance} symbol={fromToken?.assetCode}></TokenBalance>
</span>
<button
className="text-primary hover:underline"
onClick={() => {
if (fromTokenBalance.approximateNumber !== undefined) {
setValue('fromAmount', (fromTokenBalance.approximateNumber * 0.5).toString());
}
}}
type="button"
>
50%
</button>
<button
className="text-primary hover:underline"
onClick={() => {
if (fromTokenBalance.approximateNumber !== undefined) {
setValue('fromAmount', fromTokenBalance.approximateNumber.toString());
}
}}
type="button"
>
MAX
</button>
</div>
)}
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/InputKeys/SelectionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function PoolList({ onSelect, selected, mode }: PoolListProps) {
<Avatar
size={'xs' as AvatarProps['size']}
letters={TokenDetails.assetCode}
src={`/assets/coins/${TokenDetails.assetCode.toUpperCase()}.png`}
src={TokenDetails.icon}
shape="circle"
className="text-xs"
/>
Expand Down
41 changes: 12 additions & 29 deletions src/components/InputKeys/To.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { ArrowPathRoundedSquareIcon, ChevronDownIcon } from '@heroicons/react/20
import { useEffect } from 'preact/compat';
import { Button } from 'react-daisyui';
import { useFormContext } from 'react-hook-form';
import Big from 'big.js';

import pendulumIcon from '../../assets/pendulum-icon.svg';
import { NumberLoader } from '../Nabla/TokenBalance';
import { NumberLoader, TokenBalance } from '../Nabla/TokenBalance';
import { Skeleton } from '../Skeleton';
import { SwapFormValues } from '../Nabla/schema';
import { UseTokenOutAmountResult } from '../../hooks/nabla/useTokenAmountOut';
Expand All @@ -18,9 +19,8 @@ export interface ToProps {
fromToken: TokenDetails | undefined;
toToken: TokenDetails | undefined;
toAmountQuote: UseTokenOutAmountResult;
fromAmount: number | undefined;
slippage: number;
fromTokenBalances: { [key: string]: BalanceInfo };
fromAmount: Big | undefined;
tokenBalances: { [key: string]: BalanceInfo };
}

export function To({
Expand All @@ -30,11 +30,9 @@ export function To({
onOpenSelector,
toAmountQuote,
fromAmount,
slippage,
fromTokenBalances,
tokenBalances,
}: ToProps): JSX.Element | null {
const toTokenBalance =
fromTokenBalances && tokenId && fromTokenBalances[tokenId] ? fromTokenBalances[tokenId].approximateNumber : 0;
const toTokenBalance = tokenBalances && tokenId ? tokenBalances[tokenId] : undefined;

// replace with use state
const [isOpen, { toggle }] = useBoolean(true);
Expand All @@ -56,7 +54,7 @@ export function To({
<NumberLoader />
) : toAmountQuote.data !== undefined ? (
`${toAmountQuote.data.amountOut.approximateStrings.atLeast4Decimals}`
) : fromAmount !== undefined && fromAmount > 0 ? (
) : fromAmount !== undefined && fromAmount.gt(0) ? (
<button
type="button"
onClick={() => toAmountQuote.refetch?.()}
Expand All @@ -76,13 +74,7 @@ export function To({
type="button"
>
<span className="rounded-full bg-[rgba(0,0,0,0.15)] h-full p-px mr-1">
{toToken && (
<img
src={`/assets/coins/${toToken.assetCode.toUpperCase()}.png`}
alt="Pendulum"
className="h-full w-auto"
/>
)}
{toToken && <img src={toToken.icon} alt="Pendulum" className="h-full w-auto" />}
{!toToken && <img src={pendulumIcon} alt="Pendulum" className="h-full w-auto" />}
</span>
<strong className="font-bold">{toToken?.assetCode || 'Select'}</strong>
Expand All @@ -91,7 +83,10 @@ export function To({
</div>
<div className="flex justify-between items-center mt-1 dark:text-neutral-300 text-neutral-500">
{/* <div className="text-sm mt-px">{toToken ? <NablaTokenPrice address={toToken.id} fallback="$ -" /> : '$ -'}</div> */}
<div className="flex gap-1 text-sm">Your balance: {toTokenBalance}</div>
<div className="flex gap-1 text-sm">
Your balance:{' '}
{toTokenBalance ? <TokenBalance query={toTokenBalance} symbol={toToken?.assetCode}></TokenBalance> : '0'}
</div>
</div>
<div className="mt-4 h-px -mx-4 bg-[rgba(0,0,0,0.15)]" />
<div
Expand Down Expand Up @@ -132,18 +127,6 @@ export function To({
<div>N/A</div>
)}
</div>
<div className="flex justify-between">
<div>Minimum received after slippage ({slippage}%)</div>
{toAmountQuote.data !== undefined && toToken !== undefined ? (
<div>
<Skeleton isLoading={toAmountQuote.isLoading || toAmountQuote.data === undefined}>
{toAmountQuote.data !== undefined ? toAmountQuote.data.minAmountOut : ''} {toToken?.assetCode || ''}
</Skeleton>
</div>
) : (
<div>N/A</div>
)}
</div>
<div className="flex justify-between">
<div>Swap fee:</div>
<div>
Expand Down
Loading