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

Fix account balance discrepancies #5959

Merged
merged 41 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
415e800
fix balance discrepency between bx and app and app and change wallet …
walmat Jul 26, 2024
2f82761
Update src/helpers/buildWalletSections.tsx
walmat Jul 26, 2024
4ff91ef
fix missing import from commit
walmat Jul 26, 2024
d010309
also fix send sheet balance discrepancy
walmat Jul 26, 2024
50df200
fix swap user assets not refetching on pending txn resolution and PTR
walmat Jul 31, 2024
cf6a796
.
walmat Jul 31, 2024
2605a21
update en_US key
walmat Aug 3, 2024
eb8bbe2
rmeove unused hook and bake it into the user assets store
walmat Aug 5, 2024
bc4c6e8
good lord
walmat Aug 5, 2024
148a1eb
separate invalidateQueries because they don't update when grouped for…
walmat Aug 5, 2024
d5a2a67
more instances
walmat Aug 5, 2024
1b4013f
cleanup
walmat Aug 5, 2024
a151992
Merge branch 'develop' into @matthew/APP-1689
walmat Aug 5, 2024
207e811
remove stuff
walmat Aug 7, 2024
1277e6d
cleanup useWatchPendingTxs
walmat Aug 8, 2024
9efc708
code suggestions
walmat Aug 8, 2024
2c018d8
break up useWallets
benisgold Aug 8, 2024
647d1b0
rm latestBackup from useWallets
benisgold Aug 8, 2024
c05f854
useMemo -> useEffect
benisgold Aug 8, 2024
4f05b85
logging
benisgold Aug 8, 2024
bb5cd77
cleanup
benisgold Aug 8, 2024
8061f7a
remove unused withPositions params
benisgold Aug 8, 2024
2aa197b
type
benisgold Aug 8, 2024
f9bf7ab
fix PROFILE_STICKY_HEADER loading value
benisgold Aug 8, 2024
423f6df
Merge branch 'develop' of https://github.com/rainbow-me/rainbow into …
benisgold Aug 8, 2024
5e81f25
fix
benisgold Aug 8, 2024
fc10958
optional chaining
benisgold Aug 9, 2024
b0eb61b
fixes to buildWalletSections + related code
benisgold Aug 9, 2024
943117b
fix accountInfo isLoadingAccountBalance
benisgold Aug 9, 2024
7a11e75
clean up useWalletBalances
benisgold Aug 9, 2024
38e9eb5
stuff is still broken but committing walletsWithBalancesAndNames fix
benisgold Aug 9, 2024
335bb0d
refactor useWalletsWithBalancesAndNames and fix consumers
benisgold Aug 9, 2024
04069ba
fix wallet screen balance loading state
benisgold Aug 9, 2024
4c6855d
Merge branch 'develop' of https://github.com/rainbow-me/rainbow into …
benisgold Aug 9, 2024
4240c4e
console.log
benisgold Aug 13, 2024
cbf63df
switch amount types from string | number -> string
benisgold Aug 13, 2024
e1349b0
align stale/cache times, remove keepPreviousData
benisgold Aug 13, 2024
6acff71
remove spammy isDamaged logging
benisgold Aug 13, 2024
5e06f01
add loading balance copy + remove incorrectly used no balance copy
benisgold Aug 13, 2024
33c8024
Merge branch 'develop' of https://github.com/rainbow-me/rainbow into …
benisgold Aug 13, 2024
3ada8f0
fix i18n mistake
benisgold Aug 14, 2024
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
21 changes: 11 additions & 10 deletions src/components/change-wallet/AddressRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ import { EditWalletContextMenuActions } from '@/screens/ChangeWalletSheet';
import { toChecksumAddress } from '@/handlers/web3';
import { IS_IOS, IS_ANDROID } from '@/env';
import { ContextMenu } from '../context-menu';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';
import { useSelector } from 'react-redux';
import { AppState } from '@/redux/store';
import { useForegroundColor } from '@/design-system';
import { useAssetsBalanceForAddress } from '@/hooks/useAssetsBalanceForAddress';

const maxAccountLabelWidth = deviceUtils.dimensions.width - 88;
const NOOP = () => undefined;
Expand Down Expand Up @@ -121,22 +119,25 @@ interface AddressRowProps {
}

export default function AddressRow({ contextMenuActions, data, editMode, onPress }: AddressRowProps) {
const nativeCurrency = useSelector((state: AppState) => state.settings.nativeCurrency);
const notificationsEnabled = useExperimentalFlag(NOTIFICATIONS);

const { address, balance, color: accountColor, ens, image: accountImage, isSelected, isReadOnly, isLedger, label, walletId } = data;
walmat marked this conversation as resolved.
Show resolved Hide resolved
const { address, color: accountColor, ens, image: accountImage, isSelected, isReadOnly, isLedger, label, walletId } = data;

const { display, isLoading } = useAssetsBalanceForAddress(address);

const { colors, isDarkMode } = useTheme();

const labelQuaternary = useForegroundColor('labelQuaternary');

const cleanedUpBalance = useMemo(() => {
if (balance) {
return convertAmountToNativeDisplay(balance, nativeCurrency);
const balanceOrNoBalance = useMemo(() => {
walmat marked this conversation as resolved.
Show resolved Hide resolved
if (display) {
return display;
} else if (isLoading) {
return lang.t('wallet.change_wallet.loading');
} else {
return lang.t('wallet.change_wallet.no_balance');
}
}, [balance, nativeCurrency]);
}, [isLoading, display]);

const cleanedUpLabel = useMemo(() => removeFirstEmojiFromString(label), [label]);

Expand Down Expand Up @@ -254,7 +255,7 @@ export default function AddressRow({ contextMenuActions, data, editMode, onPress
<StyledTruncatedText color={colors.dark} testID={`change-wallet-address-row-label-${walletName}`}>
{walletName}
</StyledTruncatedText>
<StyledBottomRowText color={labelQuaternary}>{cleanedUpBalance}</StyledBottomRowText>
<StyledBottomRowText color={labelQuaternary}>{balanceOrNoBalance}</StyledBottomRowText>
</ColumnWithMargins>
</Row>
<Column style={sx.rightContent}>
Expand Down
14 changes: 9 additions & 5 deletions src/components/contacts/ContactRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { margin } from '@/styles';
import { addressHashedColorIndex, addressHashedEmoji } from '@/utils/profileUtils';
import * as i18n from '@/languages';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';
import { useAssetsBalanceForAddress } from '@/hooks/useAssetsBalanceForAddress';

const ContactAddress = styled(TruncatedAddress).attrs(({ theme: { colors }, lite }) => ({
align: 'left',
Expand Down Expand Up @@ -58,17 +59,20 @@ const ContactRow = ({ address, color, nickname, symmetricalMargins, ...props },
const profilesEnabled = useExperimentalFlag(PROFILES);
const { width: deviceWidth } = useDimensions();
const { onAddOrUpdateContacts } = useContacts();
const { nativeCurrency } = useAccountSettings();
const { colors } = useTheme();
const { accountType, balance, ens, image, label, network, onPress, showcaseItem, testID } = props;
const { accountType, ens, image, label, network, onPress, showcaseItem, testID } = props;
walmat marked this conversation as resolved.
Show resolved Hide resolved

const { display, isLoading } = useAssetsBalanceForAddress(address);

const cleanedUpBalance = useMemo(() => {
if (balance) {
return convertAmountToNativeDisplay(balance, nativeCurrency);
if (display) {
return display;
} else if (isLoading) {
return i18n.t(i18n.l.wallet.change_wallet.loading);
} else {
return i18n.t(i18n.l.wallet.change_wallet.no_balance);
}
}, [balance, nativeCurrency]);
}, [display, isLoading]);

// show avatar for contact rows that are accounts, not contacts
const avatar = accountType !== 'contacts' ? returnStringFirstEmoji(label) || profileUtils.addressHashedEmoji(address) : null;
Expand Down
31 changes: 13 additions & 18 deletions src/helpers/buildWalletSections.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createSelector } from 'reselect';
import { buildBriefCoinsList, buildBriefUniqueTokenList } from './assets';
import { add, convertAmountToNativeDisplay } from './utilities';
import { NativeCurrencyKey, ParsedAddressAsset } from '@/entities';
import { queryClient } from '@/react-query';
import { positionsQueryKey } from '@/resources/defi/PositionsQuery';
Expand Down Expand Up @@ -39,6 +38,8 @@ const EMPTY_WALLET_CONTENT = [
const ONLY_NFTS_CONTENT = [{ type: 'ETH_CARD', uid: 'eth-card' }];

const sortedAssetsSelector = (state: any) => state.sortedAssets;
const accountBalanceSelector = (state: any) => state.accountBalance;
const isLoadingBalanceSelector = (state: any) => state.isLoadingBalance;
const hiddenCoinsSelector = (state: any) => state.hiddenCoins;
const isCoinListEditedSelector = (state: any) => state.isCoinListEdited;
const isLoadingUserAssetsSelector = (state: any) => state.isLoadingUserAssets;
Expand Down Expand Up @@ -105,23 +106,15 @@ const withPositionsSection = (isLoadingUserAssets: boolean) => {
const withBriefBalanceSection = (
sortedAssets: ParsedAddressAsset[],
isLoadingUserAssets: boolean,
accountBalance: string | undefined,
isLoadingBalance: boolean,
nativeCurrency: NativeCurrencyKey,
isCoinListEdited: boolean,
pinnedCoins: any,
hiddenCoins: any,
collectibles: any,
nftSort: string
collectibles: any
) => {
const { briefAssets, totalBalancesValue } = buildBriefCoinsList(sortedAssets, nativeCurrency, isCoinListEdited, pinnedCoins, hiddenCoins);

const { accountAddress: address } = store.getState().settings;
const positionsObj: RainbowPositions | undefined = queryClient.getQueryData(positionsQueryKey({ address, currency: nativeCurrency }));

const positionsTotal = positionsObj?.totals?.total?.amount || '0';
walmat marked this conversation as resolved.
Show resolved Hide resolved

const totalBalanceWithPositionsValue = add(totalBalancesValue, positionsTotal);

const totalValue = convertAmountToNativeDisplay(totalBalanceWithPositionsValue, nativeCurrency);
const { briefAssets } = buildBriefCoinsList(sortedAssets, nativeCurrency, isCoinListEdited, pinnedCoins, hiddenCoins);

const hasTokens = briefAssets?.length;
const hasNFTs = collectibles?.length;
Expand All @@ -133,8 +126,8 @@ const withBriefBalanceSection = (
{
type: 'PROFILE_STICKY_HEADER',
uid: 'assets-profile-header-compact',
value: totalValue,
isLoadingUserAssets,
value: accountBalance,
isLoadingUserAssets: isLoadingBalance,
},
{
type: 'PROFILE_AVATAR_ROW_SPACE_BEFORE',
Expand Down Expand Up @@ -162,7 +155,7 @@ const withBriefBalanceSection = (
{
type: 'PROFILE_BALANCE_ROW',
uid: 'profile-balance',
value: totalValue,
value: accountBalance,
},
{
type: 'PROFILE_BALANCE_ROW_SPACE_AFTER',
Expand All @@ -172,13 +165,13 @@ const withBriefBalanceSection = (
{
type: 'PROFILE_ACTION_BUTTONS_ROW',
uid: 'profile-action-buttons',
value: totalValue,
value: accountBalance,
},
hasTokens
? {
type: 'PROFILE_ACTION_BUTTONS_ROW_SPACE_AFTER',
uid: 'profile-action-buttons-space-after',
value: totalValue,
value: accountBalance,
}
: { type: 'BIG_EMPTY_WALLET_SPACER', uid: 'big-empty-wallet-spacer-1' },
];
Expand Down Expand Up @@ -226,6 +219,8 @@ const briefBalanceSectionSelector = createSelector(
[
sortedAssetsSelector,
isLoadingUserAssetsSelector,
accountBalanceSelector,
isLoadingBalanceSelector,
nativeCurrencySelector,
isCoinListEditedSelector,
pinnedCoinsSelector,
Expand Down
40 changes: 40 additions & 0 deletions src/hooks/useAssetsBalanceForAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useCallback } from 'react';
import { Address } from 'viem';

import { selectUserAssetsBalance, selectorFilterByUserChains } from '@/__swaps__/screens/Swap/resources/_selectors/assets';
import { useUserAssets } from '@/__swaps__/screens/Swap/resources/assets';
import { EthereumAddress, ParsedAddressAsset } from '@/entities';
import useAccountSettings from './useAccountSettings';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';
import useCoinListEditOptions from './useCoinListEditOptions';

export function useAssetsBalanceForAddress(address: EthereumAddress) {
walmat marked this conversation as resolved.
Show resolved Hide resolved
const { nativeCurrency } = useAccountSettings();
const { hiddenCoinsObj: hidden } = useCoinListEditOptions();
const isHidden = useCallback(
(asset: ParsedAddressAsset) => {
return !!hidden[asset.address];
},
[hidden]
);

const { data: totalAssetsBalance, isLoading } = useUserAssets(
{
address: address as Address,
currency: nativeCurrency,
},
{
select: data =>
selectorFilterByUserChains({
data,
selector: data => selectUserAssetsBalance(data, asset => isHidden(asset as unknown as ParsedAddressAsset)),
}),
}
);

return {
amount: totalAssetsBalance,
display: totalAssetsBalance ? convertAmountToNativeDisplay(totalAssetsBalance, nativeCurrency) : undefined,
isLoading,
};
}
18 changes: 18 additions & 0 deletions src/hooks/useUserAssetsBalance.ts
walmat marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMemo } from 'react';
walmat marked this conversation as resolved.
Show resolved Hide resolved
import { add, convertAmountToNativeDisplay } from '@/helpers/utilities';
import useAccountSettings from './useAccountSettings';
import { userAssetsStore } from '@/state/assets/userAssets';

export function useUserAssetsBalance() {
const { nativeCurrency } = useAccountSettings();
const getUserAssets = userAssetsStore(state => state.getUserAssets);

const amount = useMemo(() => {
return getUserAssets().reduce((prev, curr) => add(prev, curr.balance.amount), '0');
}, [getUserAssets]);

return {
amount,
display: convertAmountToNativeDisplay(amount, nativeCurrency),
};
}
9 changes: 9 additions & 0 deletions src/hooks/useWalletSectionsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { buildBriefWalletSectionsSelector } from '@/helpers/buildWalletSections'
import { useSortedUserAssets } from '@/resources/assets/useSortedUserAssets';
import { useLegacyNFTs } from '@/resources/nfts';
import useNftSort from './useNFTsSortBy';
import { useAssetsBalanceForAddress } from './useAssetsBalanceForAddress';

export default function useWalletSectionsData({
type,
Expand All @@ -27,6 +28,9 @@ export default function useWalletSectionsData({
} = useLegacyNFTs({
address: accountAddress,
});

const { display: accountBalance, isLoading: isLoadingBalance } = useAssetsBalanceForAddress(accountAddress);

jinchung marked this conversation as resolved.
Show resolved Hide resolved
const { showcaseTokens } = useShowcaseTokens();
const { hiddenTokens } = useHiddenTokens();
const { isReadOnlyWallet } = useWallets();
Expand All @@ -48,6 +52,8 @@ export default function useWalletSectionsData({
pinnedCoins,
sendableUniqueTokens,
sortedAssets,
accountBalance,
isLoadingBalance,
// @ts-expect-error ts-migrate(2698) FIXME: Spread types may only be created from object types... Remove this comment to see the full error message
...isWalletEthZero,
hiddenTokens,
Expand All @@ -65,6 +71,7 @@ export default function useWalletSectionsData({
hasNFTs,
isEmpty,
isLoadingUserAssets,
isLoadingBalance,
isWalletEthZero,
briefSectionsData,
};
Expand All @@ -78,6 +85,8 @@ export default function useWalletSectionsData({
pinnedCoins,
sendableUniqueTokens,
sortedAssets,
accountBalance,
isLoadingBalance,
isWalletEthZero,
hiddenTokens,
isReadOnlyWallet,
Expand Down
1 change: 1 addition & 0 deletions src/languages/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,7 @@
"buy": "Buy",
"change_wallet": {
"no_balance": "No Balance",
"loading": "Loading balance",
walmat marked this conversation as resolved.
Show resolved Hide resolved
"balance_eth": "%{balanceEth} ETH",
"watching": "Watching",
"ledger": "Ledger"
Expand Down
8 changes: 4 additions & 4 deletions src/screens/WalletScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const WalletScreen: React.FC<any> = ({ navigation, route }) => {
}, [currentNetwork, revertToMainnet]);

const walletReady = useSelector(({ appState: { walletReady } }: AppState) => walletReady);
const { isWalletEthZero, isLoadingUserAssets, briefSectionsData: walletBriefSectionsData } = useWalletSectionsData();
const { isWalletEthZero, isLoadingUserAssets, isLoadingBalance, briefSectionsData: walletBriefSectionsData } = useWalletSectionsData();

useEffect(() => {
// This is the fix for Android wallet creation problem.
Expand All @@ -86,7 +86,7 @@ const WalletScreen: React.FC<any> = ({ navigation, route }) => {
if (isWelcomeScreen) {
removeFirst();
}
}, [dangerouslyGetState, removeFirst]);
}, [dangerouslyGetParent, dangerouslyGetState, removeFirst]);

useEffect(() => {
const initializeAndSetParams = async () => {
Expand Down Expand Up @@ -132,8 +132,8 @@ const WalletScreen: React.FC<any> = ({ navigation, route }) => {
{/* @ts-expect-error JavaScript component */}
<AssetList
accentColor={highContrastAccentColor}
disableRefreshControl={isLoadingUserAssetsAndAddress}
isLoading={IS_ANDROID && isLoadingUserAssetsAndAddress}
disableRefreshControl={isLoadingUserAssetsAndAddress || isLoadingBalance}
isLoading={IS_ANDROID && (isLoadingUserAssetsAndAddress || isLoadingBalance)}
isWalletEthZero={isWalletEthZero}
network={currentNetwork}
walletBriefSectionsData={walletBriefSectionsData}
Expand Down
Loading