Skip to content

Commit

Permalink
Merge pull request #269 from lidofinance/feature/si-1270-rewards-empt…
Browse files Browse the repository at this point in the history
…y-steth-balance-when-clear-address-input

Empty "stETH balance" when clear address input
  • Loading branch information
jake4take authored Mar 19, 2024
2 parents ca149a2 + 7d76062 commit 67a5b37
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 90 deletions.
65 changes: 16 additions & 49 deletions features/rewards/components/stats/Stats.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,42 @@
import { FC, useCallback, useEffect, useState } from 'react';
import type { BigNumber as EthersBigNumber } from 'ethers';
import { constants } from 'ethers';
import { useStethEthRate } from 'features/rewards/hooks/use-steth-eth-rate';
import { useRewardsHistory } from 'features/rewards/hooks';
import { useRewardsBalanceData } from 'features/rewards/hooks/use-rewards-balance-data';

import { Box, Link } from '@lidofinance/lido-ui';
import { useSDK, useTokenBalance } from '@lido-sdk/react';
import { TOKENS, getTokenAddress } from '@lido-sdk/constants';

import { dynamics } from 'config';
import { stEthEthRequest } from 'features/rewards/fetchers/requesters';
import EthSymbol from 'features/rewards/components/EthSymbol';
import NumberFormat from 'features/rewards/components/NumberFormat';
import { Big, BigDecimal } from 'features/rewards/helpers';
import { ETHER } from 'features/rewards/constants';
import { STRATEGY_LAZY } from 'utils/swrStrategies';
import { useMainnetStaticRpcProvider } from 'shared/hooks/use-mainnet-static-rpc-provider';

import { Item } from './Item';
import { Stat } from './Stat';
import { Title } from './Title';
import { StatsProps } from './types';

// TODO: refactoring to style files
export const Stats: FC<StatsProps> = (props) => {
const { address, data, currency, pending } = props;

const [stEthEth, setStEthEth] = useState<EthersBigNumber>();
const { chainId } = useSDK();

const steth = useTokenBalance(
getTokenAddress(chainId, TOKENS.STETH),
address,
STRATEGY_LAZY,
);
const mainnetStaticRpcProvider = useMainnetStaticRpcProvider();

const getStEthEth = useCallback(async () => {
if (dynamics.defaultChain !== 1) {
setStEthEth(constants.WeiPerEther);
} else {
const stEthEth = await stEthEthRequest(mainnetStaticRpcProvider);

setStEthEth(stEthEth);
}
}, [mainnetStaticRpcProvider]);

useEffect(() => {
void getStEthEth();
}, [getStEthEth]);

const stEthBalanceParsed = steth.data && new Big(steth.data.toString());
const stEthCurrencyBalance =
steth.data &&
data &&
new BigDecimal(steth.data.toString()) // Convert to right BN
.div(ETHER)
.times(data.stETHCurrencyPrice[currency.id]);
export const Stats: React.FC = () => {
const {
currencyObject: currency,
data,
initialLoading: pending,
} = useRewardsHistory();
const { data: stEthEth } = useStethEthRate();
const { data: balanceData } = useRewardsBalanceData();

return (
<>
<Item data-testid="stEthBalanceBlock">
<Title mb="8px">stETH balance</Title>
<Stat data-testid="stEthBalance" mb="6px">
<EthSymbol />
<NumberFormat number={stEthBalanceParsed} pending={pending} />
<NumberFormat
number={balanceData?.stEthBalanceParsed}
pending={pending}
/>
</Stat>
<Title data-testid="stEthBalanceIn$" hideMobile>
<Box display="inline-block" pr="3px">
{currency.symbol}
</Box>
<NumberFormat
number={stEthCurrencyBalance}
number={balanceData?.stEthCurrencyBalance}
currency
pending={pending}
/>
Expand Down
9 changes: 0 additions & 9 deletions features/rewards/components/stats/types.ts

This file was deleted.

18 changes: 3 additions & 15 deletions features/rewards/features/top-card/top-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@ const INPUT_DESC_TEXT =
'Current balance may differ from last balance in the table due to rounding.';

export const TopCard: FC = () => {
const {
address,
isAddressResolving,
currencyObject,
data,
inputValue,
setInputValue,
initialLoading,
} = useRewardsHistory();
const { address, isAddressResolving, inputValue, setInputValue } =
useRewardsHistory();

return (
<Block color="accent" style={{ padding: 0 }}>
Expand All @@ -35,12 +28,7 @@ export const TopCard: FC = () => {
</ThemeProvider>
</InputWrapper>
<StatsWrapper>
<Stats
address={address}
currency={currencyObject}
data={data}
pending={initialLoading}
/>
<Stats />
</StatsWrapper>
</Block>
);
Expand Down
23 changes: 23 additions & 0 deletions features/rewards/hooks/use-laggy-data-wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect, useRef } from 'react';

export const useLaggyDataWrapper = <Data>(data: Data) => {
const laggyDataRef = useRef<Data | undefined>();
const isDataPresented = data !== undefined && data !== null;

useEffect(() => {
if (isDataPresented) {
laggyDataRef.current = data;
}
}, [data, isDataPresented]);

// Return to previous data if current data is not defined.
const dataOrLaggyData = !isDataPresented ? laggyDataRef.current : data;

// Shows previous data.
const isLagging = !isDataPresented && laggyDataRef.current !== undefined;

return {
isLagging,
dataOrLaggyData,
};
};
39 changes: 39 additions & 0 deletions features/rewards/hooks/use-rewards-balance-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useMemo } from 'react';
import { useSDK, useTokenBalance } from '@lido-sdk/react';
import { useRewardsHistory } from './useRewardsHistory';
import { useLaggyDataWrapper } from './use-laggy-data-wrapper';

import { ETHER } from 'features/rewards/constants';
import { TOKENS, getTokenAddress } from '@lido-sdk/constants';
import { STRATEGY_LAZY } from 'utils/swrStrategies';
import { Big, BigDecimal } from '../helpers';

export const useRewardsBalanceData = () => {
const { chainId } = useSDK();
const { address, data, currencyObject } = useRewardsHistory();

const { data: steth } = useTokenBalance(
getTokenAddress(chainId, TOKENS.STETH),
address,
STRATEGY_LAZY,
);

const balanceData = useMemo(
() =>
steth
? {
stEthBalanceParsed: new Big(steth.toString()),
stEthCurrencyBalance:
data &&
new BigDecimal(steth.toString()) // Convert to right BN
.div(ETHER)
.times(data.stETHCurrencyPrice[currencyObject.id]),
}
: null,
[currencyObject.id, data, steth],
);

const { isLagging, dataOrLaggyData } = useLaggyDataWrapper(balanceData);

return { isLagging: !!address && isLagging, data: dataOrLaggyData };
};
26 changes: 26 additions & 0 deletions features/rewards/hooks/use-steth-eth-rate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { STRATEGY_LAZY } from 'utils/swrStrategies';
import { useMainnetStaticRpcProvider } from 'shared/hooks/use-mainnet-static-rpc-provider';
import { useLidoSWR, useSDK } from '@lido-sdk/react';

import { stEthEthRequest } from 'features/rewards/fetchers/requesters';
import { constants } from 'ethers';

export const useStethEthRate = () => {
const { chainId } = useSDK();
const mainnetStaticRpcProvider = useMainnetStaticRpcProvider();

const swrResult = useLidoSWR(
`steth-eth-${chainId}`,
async () => {
if (chainId !== 1) {
return constants.WeiPerEther;
} else {
const stEthEth = await stEthEthRequest(mainnetStaticRpcProvider);
return stEthEth;
}
},
STRATEGY_LAZY,
);

return swrResult;
};
19 changes: 3 additions & 16 deletions features/rewards/hooks/useRewardsDataLoad.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useRef } from 'react';
import { Backend } from 'features/rewards/types';
import { dynamics } from 'config';
import { useLidoSWR } from 'shared/hooks';
import { swrAbortableMiddleware } from 'utils';
import { useLaggyDataWrapper } from './use-laggy-data-wrapper';

type UseRewardsDataLoad = (props: {
address: string;
Expand All @@ -29,8 +29,6 @@ export const useRewardsDataLoad: UseRewardsDataLoad = (props) => {
limit,
} = props;

const laggyDataRef = useRef<Backend | undefined>();

const requestOptions = {
address,
currency,
Expand Down Expand Up @@ -61,18 +59,7 @@ export const useRewardsDataLoad: UseRewardsDataLoad = (props) => {
},
);

useEffect(() => {
if (data !== undefined) {
laggyDataRef.current = data;
}
}, [data]);

// Return to previous data if current data is not defined.
const dataOrLaggyData = data === undefined ? laggyDataRef.current : data;

// Shows previous data.
const isLagging =
!!address && data === undefined && laggyDataRef.current !== undefined;
const { isLagging, dataOrLaggyData } = useLaggyDataWrapper(data);

return { ...rest, isLagging, data: dataOrLaggyData };
return { ...rest, isLagging: !!address && isLagging, data: dataOrLaggyData };
};
2 changes: 1 addition & 1 deletion providers/rewardsHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const RewardsHistoryProvider: FC<PropsWithChildren> = (props) => {
const currencyObject = getCurrency(currency);

const value = useMemo(
() => ({
(): RewardsHistoryValue => ({
data,
error,
loading,
Expand Down

0 comments on commit 67a5b37

Please sign in to comment.