Skip to content

Commit

Permalink
feat: Add info to the Bedeem from Backstop pool UI (#291)
Browse files Browse the repository at this point in the history
* feat: backstop pool withdraw info

* refactor: fee

* feat: token price on redeem ui

---------

Co-authored-by: Gonza Montiel <[email protected]>
  • Loading branch information
Nejc and gonzamontiel authored Nov 15, 2023
1 parent cdf598e commit 208dacd
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 40 deletions.
42 changes: 20 additions & 22 deletions src/components/Asset/Price/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { usePriceFetcher } from '../../../hooks/usePriceFetcher';
import { Skeleton } from '../../Skeleton';

export type TokenPriceProps = {
address: string;
address?: string;
symbol: string;
//amount?: number;
prefix?: ReactNode;
Expand All @@ -13,26 +13,24 @@ export type TokenPriceProps = {
fallback?: ReactNode;
};

const TokenPrice = memo(
({ address, symbol, prefix = '', loader, fallback = null }: TokenPriceProps): JSX.Element | null => {
const { pricesCache } = usePriceFetcher();
const [price, setPrice] = useState<number | undefined | null>(null);
useEffect(() => {
const run = async () => {
const p = (await pricesCache)[symbol];
setPrice(p);
};
run();
}, [pricesCache, symbol]);
const TokenPrice = memo(({ symbol, prefix = null, loader, fallback = null }: TokenPriceProps): JSX.Element | null => {
const { pricesCache } = usePriceFetcher();
const [price, setPrice] = useState<number | undefined | null>(null);
useEffect(() => {
const run = async () => {
const p = (await pricesCache)[symbol];
setPrice(p);
};
run();
}, [pricesCache, symbol]);

const isLoading = price === null;
if (isLoading) return <>{loader}</> || <Skeleton className="inline-flex">10000</Skeleton>;
if (!price) return <>{fallback}</>;
return (
<span>
{prefix}${price}
</span>
);
},
);
const isLoading = price === null;
if (isLoading) return <>{loader}</> || <Skeleton className="inline-flex">10000</Skeleton>;
if (!price) return <>{fallback}</>;
return (
<span>
{prefix}${price}
</span>
);
});
export default TokenPrice;
17 changes: 14 additions & 3 deletions src/components/nabla/Pools/Backstop/WithdrawLiquidity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { ChangeEvent } from 'preact/compat';
import { Button, Range } from 'react-daisyui';
import { PoolProgress } from '../..';
import { BackstopPool } from '../../../../../../gql/graphql';
import { backstopPoolAbi } from '../../../../../contracts/nabla/BackstopPool';
import { calcSharePercentage, minMax } from '../../../../../helpers/calc';
import { FixedU128Decimals, nativeToDecimal, roundNumber } from '../../../../../shared/parseNumbers';
import { numberLoader } from '../../../../Loader';
import TransactionProgress from '../../../../Transaction/Progress';
import TokenAmount from '../../TokenAmount';
import { useWithdrawLiquidity } from './useWithdrawLiquidity';

export type WithdrawLiquidityProps = {
Expand All @@ -22,7 +24,8 @@ const WithdrawLiquidity = ({ data }: WithdrawLiquidityProps): JSX.Element | null
depositQuery,
amount,
form: { register, setValue },
} = useWithdrawLiquidity(data.id, data.token.id);
selectedPool,
} = useWithdrawLiquidity(data);
const deposit = depositQuery.balance || 0;

const hideCss = !mutation.isIdle ? 'hidden' : '';
Expand Down Expand Up @@ -86,8 +89,16 @@ const WithdrawLiquidity = ({ data }: WithdrawLiquidityProps): JSX.Element | null
</div>
<div className="relative flex w-full flex-col gap-4 rounded-lg bg-neutral-100 dark:bg-neutral-700 text-neutral-500 dark:text-neutral-300 p-4 mt-4">
<div className="flex items-center justify-between">
<div>Fee</div>
<div>{'! TODO'}</div>
<div>Amount</div>
<div>
<TokenAmount
address={data.id}
abi={backstopPoolAbi}
amount={amount}
symbol={` ${data.token.symbol}`}
fallback={0}
/>
</div>
</div>
<div className="flex items-center justify-between">
<div>Deposit</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { transformNumber } from '../../../../../helpers/yup';
import { WithdrawLiquidityValues } from './types';

const schema = Yup.object<WithdrawLiquidityValues>().shape({
address: Yup.string().nullable().min(5),
slippage: Yup.number().nullable().transform(transformNumber),
amount: Yup.number().positive().required().transform(transformNumber),
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export type WithdrawLiquidityValues = {
amount: number;
address: string;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { yupResolver } from '@hookform/resolvers/yup';
import { useQueryClient } from '@tanstack/react-query';
import { useMemo } from 'preact/compat';
import { useForm, useWatch } from 'react-hook-form';
import { BackstopPool, SwapPool } from '../../../../../../gql/graphql';
import { cacheKeys } from '../../../../../constants/cache';
import { backstopPoolAbi } from '../../../../../contracts/nabla/BackstopPool';
import { subtractPercentage } from '../../../../../helpers/calc';
Expand All @@ -12,7 +14,10 @@ import { useContractWrite } from '../../../../../shared/useContractWrite';
import schema from './schema';
import { WithdrawLiquidityValues } from './types';

export const useWithdrawLiquidity = (poolAddress: string, tokenAddress: string) => {
export const useWithdrawLiquidity = (pool: BackstopPool) => {
const { id: poolAddress, token, router } = pool;
const tokenAddress = token.id;
const swapPools = router?.swapPools;
const queryClient = useQueryClient();
const { indexerUrl } = useGetAppDataByTenant('nabla').data || {};
const toggle = useModalToggle();
Expand All @@ -25,6 +30,20 @@ export const useWithdrawLiquidity = (poolAddress: string, tokenAddress: string)
defaultValues: {},
});

const amount =
Number(
useWatch({
control: form.control,
name: 'amount',
defaultValue: 0,
}),
) || 0;

const address = useWatch({
control: form.control,
name: 'address',
});

const mutation = useContractWrite({
abi: backstopPoolAbi,
address: poolAddress,
Expand All @@ -47,14 +66,20 @@ export const useWithdrawLiquidity = (poolAddress: string, tokenAddress: string)
]),
);

const amount =
Number(
useWatch({
control: form.control,
name: 'amount',
defaultValue: 0,
}),
) || 0;
const pools = useMemo(
() =>
[
{
id: '',
token: {
...token,
id: '',
},
} as SwapPool,
].concat(swapPools || []),
[swapPools, token],
);
const selectedPool = useMemo(() => pools.find((t) => t.id === address) || pools[0], [address, pools]);

return { form, amount, mutation, onSubmit, toggle, balanceQuery, depositQuery };
return { form, amount, mutation, onSubmit, toggle, balanceQuery, depositQuery, selectedPool, pools };
};
2 changes: 1 addition & 1 deletion src/components/nabla/Pools/Backstop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const BackstopPoolsBody = (): JSX.Element | null => {
const { data, isLoading } = useBackstopPools();

if (isLoading) return <Skeleton className="bg-neutral-200 h-48 w-full" />;
const pool = data?.[0];
const pool = data?.[data.length - 1];
if (!pool) return null; // TODO: empty state UI
return (
<>
Expand Down
17 changes: 15 additions & 2 deletions src/components/nabla/Pools/Swap/Redeem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { ArrowLeftIcon } from '@heroicons/react/24/outline';
import { ChangeEvent } from 'preact/compat';
import { Button, Range } from 'react-daisyui';
import { PoolProgress } from '../..';
import { config } from '../../../../../config';
import { calcSharePercentage, minMax } from '../../../../../helpers/calc';
import { FixedU128Decimals, nativeToDecimal, roundNumber } from '../../../../../shared/parseNumbers';
import TokenPrice from '../../../../Asset/Price';
import { numberLoader } from '../../../../Loader';
import TransactionProgress from '../../../../Transaction/Progress';
import { TransactionSettingsDropdown } from '../../../../Transaction/Settings';
Expand Down Expand Up @@ -100,8 +102,19 @@ const Redeem = ({ data }: RedeemProps): JSX.Element | null => {
</div>
<div className="relative flex w-full flex-col gap-4 rounded-lg bg-neutral-100 dark:bg-neutral-700 text-neutral-500 dark:text-neutral-300 p-4 mt-4">
<div className="flex items-center justify-between">
<div>Fee</div>
<div>{'! TODO'}</div>
<div>Security fee</div>
<div>{config.backstop.securityFee * 100}%</div>
</div>
<div className="flex items-center justify-between">
<div>Price</div>
<div>
<TokenPrice
address={data.token.id}
symbol={data.token.symbol}
prefix={`1 ${data.token.symbol} = `}
fallback="-"
/>
</div>
</div>
<div className="flex items-center justify-between">
<div>Deposit</div>
Expand Down
14 changes: 12 additions & 2 deletions src/components/nabla/Pools/Swap/WithdrawLiquidity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { ArrowLeftIcon } from '@heroicons/react/24/outline';
import { ChangeEvent } from 'preact/compat';
import { Button, Range } from 'react-daisyui';
import { PoolProgress } from '../..';
import { swapPoolAbi } from '../../../../../contracts/nabla/SwapPool';
import { calcSharePercentage, minMax } from '../../../../../helpers/calc';
import { FixedU128Decimals, nativeToDecimal, roundNumber } from '../../../../../shared/parseNumbers';
import { numberLoader } from '../../../../Loader';
import TransactionProgress from '../../../../Transaction/Progress';
import TokenAmount from '../../TokenAmount';
import { SwapPoolColumn } from '../columns';
import { ModalTypes } from '../Modals/types';
import { useWithdrawLiquidity } from './useWithdrawLiquidity';
Expand Down Expand Up @@ -86,8 +88,16 @@ const WithdrawLiquidity = ({ data }: WithdrawLiquidityProps): JSX.Element | null
</div>
<div className="relative flex w-full flex-col gap-4 rounded-lg bg-neutral-100 dark:bg-neutral-700 text-neutral-500 dark:text-neutral-300 p-4 mt-4">
<div className="flex items-center justify-between">
<div>Fee</div>
<div>{'! TODO'}</div>
<div>Amount</div>
<div>
<TokenAmount
address={data.id}
abi={swapPoolAbi}
amount={amount}
symbol={` ${data.token.symbol}`}
fallback={0}
/>
</div>
</div>
<div className="flex items-center justify-between">
<div>Deposit</div>
Expand Down
44 changes: 44 additions & 0 deletions src/components/nabla/Pools/TokenAmount/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Abi } from '@polkadot/api-contract';
import { useSharesTargetWorth } from '../../../../hooks/nabla/useSharesTargetWorth';
import { useDebouncedValue } from '../../../../hooks/useDebouncedValue';
import { FixedU128Decimals, nativeToDecimal, prettyNumbers } from '../../../../shared/parseNumbers';
import { Skeleton } from '../../../Skeleton';

export interface TokenAmountProps {
address: string;
abi?: Abi | Record<string, unknown>;
amount?: number;
debounce?: number;
loader?: boolean;
symbol?: ReactNode;
fallback?: string | number;
}

const TokenAmount = ({
symbol,
abi,
fallback,
address,
amount = 0,
loader = true,
debounce = 800,
}: TokenAmountProps): JSX.Element | null => {
const debouncedAmount = useDebouncedValue(amount, debounce);
const arg = debounce ? debouncedAmount : amount;
const { isLoading, data } = useSharesTargetWorth({
address,
abi,
amount: arg,
});
if (isLoading || (!!debounce && amount !== debouncedAmount)) {
return loader ? <Skeleton className="inline-flex">10000</Skeleton> : null;
}

return (
<span title={data?.toString()}>
{data ? prettyNumbers(nativeToDecimal(data || '0', FixedU128Decimals).toNumber()) : fallback ?? null}
{symbol ? symbol : null}
</span>
);
};
export default TokenAmount;
1 change: 1 addition & 0 deletions src/constants/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const cacheKeys = {
walletBalance: 'walletBalance',
walletBalances: 'walletBalances',
tokenOutAmount: 'tokenOutAmount',
sharesTargetWorth: 'sharesTargetWorth',
};

export type QueryOptions = Partial<
Expand Down
26 changes: 26 additions & 0 deletions src/hooks/nabla/useSharesTargetWorth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Abi } from '@polkadot/api-contract';
import { cacheKeys, inactiveOptions } from '../../constants/cache';
import { swapPoolAbi } from '../../contracts/nabla/SwapPool';
import { QueryOptions } from '../../shared/helpers';
import { useContract } from '../../shared/useContract';

export type UseSharesTargetWorthProps = {
address: string | undefined;
amount: number | undefined;
abi?: Abi | Dict;
};

export const useSharesTargetWorth = (
{ address, amount, abi = swapPoolAbi }: UseSharesTargetWorthProps,
options?: QueryOptions,
) => {
return useContract([cacheKeys.sharesTargetWorth], {
...inactiveOptions['1m'],
...options,
address,
abi,
method: 'sharesTargetWorth',
args: [amount],
enabled: Boolean(address && amount && options?.enabled !== false),
});
};

0 comments on commit 208dacd

Please sign in to comment.