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 all 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
32 changes: 14 additions & 18 deletions src/__swaps__/screens/Swap/providers/swap-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,24 +300,20 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {
}
}

queryClient.invalidateQueries([
// old user assets invalidation (will cause a re-fetch)
{
queryKey: userAssetsQueryKey({
address: parameters.quote.from,
currency: nativeCurrency,
connectedToHardhat,
}),
},
// new swaps user assets invalidations
{
queryKey: swapsUserAssetsQueryKey({
address: parameters.quote.from as Address,
currency: nativeCurrency,
testnetMode: !!connectedToHardhat,
}),
},
]);
queryClient.invalidateQueries(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

separated all of the instances of invalidateQueries out because Arrays weren't working for whatever reason.

userAssetsQueryKey({
address: parameters.quote.from,
currency: nativeCurrency,
connectedToHardhat,
})
);
queryClient.invalidateQueries(
swapsUserAssetsQueryKey({
address: parameters.quote.from as Address,
currency: nativeCurrency,
testnetMode: !!connectedToHardhat,
})
);

swapsStore.getState().addRecentSwap(parameters.assetToBuy as ExtendedAnimatedAssetWithColors);
clearCustomGasSettings(chainId);
Expand Down
27 changes: 11 additions & 16 deletions src/components/DappBrowser/control-panel/ControlPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ import { RouteProp, useRoute } from '@react-navigation/native';
import { toHex } from 'viem';
import { RainbowNetworks } from '@/networks';
import * as i18n from '@/languages';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';
import { useDispatch, useSelector } from 'react-redux';
import store, { AppState } from '@/redux/store';
import { useDispatch } from 'react-redux';
import store from '@/redux/store';
import { getDappHost } from '@/utils/connectedApps';
import WebView from 'react-native-webview';
import { Navigation, useNavigation } from '@/navigation';
Expand All @@ -64,6 +63,7 @@ import { getRemoteConfig } from '@/model/remoteConfig';
import { SWAPS_V2, useExperimentalFlag } from '@/config';
import { swapsStore } from '@/state/swaps/swapsStore';
import { userAssetsStore } from '@/state/assets/userAssets';
import { greaterThan } from '@/helpers/utilities';

const PAGES = {
HOME: 'home',
Expand All @@ -88,7 +88,6 @@ export const ControlPanel = () => {
const {
params: { activeTabRef },
} = useRoute<RouteProp<ControlPanelParams, 'ControlPanel'>>();
const nativeCurrency = useSelector((state: AppState) => state.settings.nativeCurrency);
const walletsWithBalancesAndNames = useWalletsWithBalancesAndNames();
const activeTabUrl = useBrowserStore(state => state.getActiveTabUrl());
const activeTabHost = getDappHost(activeTabUrl || '') || DEFAULT_TAB_URL;
Expand Down Expand Up @@ -140,33 +139,29 @@ export const ControlPanel = () => {
const bluetoothWallets: ControlPanelMenuItemProps[] = [];
const readOnlyWallets: ControlPanelMenuItemProps[] = [];

const accountBalances: Record<string, number> = {};
const accountBalances: Record<string, string> = {};

Object.values(walletsWithBalancesAndNames).forEach(wallet => {
wallet.addresses
.filter(account => account.visible)
.forEach(account => {
const balanceText = account.balances ? account.balances.totalBalanceDisplay : i18n.t(i18n.l.wallet.change_wallet.loading_balance);

const item: ControlPanelMenuItemProps = {
IconComponent: account.image ? (
<ListAvatar url={account.image} />
) : (
<ListEmojiAvatar address={account.address} color={account.color} label={account.label} />
),
label: removeFirstEmojiFromString(account.label) || address(account.address, 6, 4),
secondaryLabel:
// eslint-disable-next-line no-nested-ternary
wallet.type === WalletTypes.readOnly
? i18n.t(i18n.l.wallet.change_wallet.watching)
: account.balance
? convertAmountToNativeDisplay(account.balance, nativeCurrency)
: i18n.t(i18n.l.wallet.change_wallet.no_balance),
secondaryLabel: wallet.type === WalletTypes.readOnly ? i18n.t(i18n.l.wallet.change_wallet.watching) : balanceText,
uniqueId: account.address,
color: colors.avatarBackgrounds[account.color],
imageUrl: account.image || undefined,
selected: account.address === currentAddress,
};

accountBalances[account.address] = Number(account.balance);
accountBalances[account.address] = account.balances?.totalBalanceAmount;

if ([WalletTypes.mnemonic, WalletTypes.seed, WalletTypes.privateKey].includes(wallet.type)) {
sortedWallets.push(item);
Expand All @@ -178,13 +173,13 @@ export const ControlPanel = () => {
});
});

sortedWallets.sort((a, b) => accountBalances[b.uniqueId] - accountBalances[a.uniqueId]);
bluetoothWallets.sort((a, b) => accountBalances[b.uniqueId] - accountBalances[a.uniqueId]);
sortedWallets.sort((a, b) => (greaterThan(accountBalances[b.uniqueId], accountBalances[a.uniqueId]) ? 1 : -1));
bluetoothWallets.sort((a, b) => (greaterThan(accountBalances[b.uniqueId], accountBalances[a.uniqueId]) ? 1 : -1));

const sortedItems = [...sortedWallets, ...bluetoothWallets, ...readOnlyWallets];

return sortedItems;
}, [walletsWithBalancesAndNames, currentAddress, nativeCurrency]);
}, [walletsWithBalancesAndNames, currentAddress]);

const { testnetsEnabled } = store.getState().settings;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function rowRenderer(type: CellType, { uid }: { uid: string }, _: unknown, exten
<ProfileRowWrapper>
<ProfileBalanceRow
totalValue={(data as AssetsHeaderExtraData).value}
isLoadingUserAssets={(data as AssetsHeaderExtraData).isLoadingUserAssets}
isLoadingBalance={(data as AssetsHeaderExtraData).isLoadingBalance}
/>
</ProfileRowWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ export type AssetListHeaderExtraData = {
};

export type AssetsHeaderExtraData = {
type: CellType.PROFILE_STICKY_HEADER;
type: CellType.PROFILE_BALANCE_ROW;
value: string;
isLoadingUserAssets: boolean;
isLoadingBalance: boolean;
};
export type CoinExtraData = { type: CellType.COIN; uniqueId: string };
export type NFTExtraData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { Box, Heading } from '@/design-system';

export const ProfileBalanceRowHeight = 24;

export function ProfileBalanceRow({ totalValue, isLoadingUserAssets }: { totalValue: string; isLoadingUserAssets: boolean }) {
export function ProfileBalanceRow({ totalValue, isLoadingBalance }: { totalValue: string; isLoadingBalance: boolean }) {
const placeholderHeight = ProfileBalanceRowHeight;
const placeholderWidth = 200;

return (
<>
{isLoadingUserAssets ? (
{isLoadingBalance ? (
<Box height={{ custom: placeholderHeight }} width={{ custom: placeholderWidth }}>
<Skeleton>
<FakeText height={placeholderHeight} width={placeholderWidth} />
Expand Down
7 changes: 4 additions & 3 deletions src/components/backup/useCreateBackup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-promise-executor-return */
import { useCallback, useState } from 'react';
import { backupAllWalletsToCloud, getLocalBackupPassword, saveLocalBackupPassword } from '@/model/backup';
import { useCallback, useMemo, useState } from 'react';
import { backupAllWalletsToCloud, findLatestBackUp, getLocalBackupPassword, saveLocalBackupPassword } from '@/model/backup';
import { useCloudBackups } from './CloudBackupProvider';
import { cloudPlatform } from '@/utils/platform';
import { analytics } from '@/analytics';
Expand Down Expand Up @@ -34,7 +34,8 @@ export const useCreateBackup = ({ walletId, navigateToRoute }: UseCreateBackupPr

const { fetchBackups } = useCloudBackups();
const walletCloudBackup = useWalletCloudBackup();
const { latestBackup, wallets } = useWallets();
const { wallets } = useWallets();
const latestBackup = useMemo(() => findLatestBackUp(wallets), [wallets]);
const [loading, setLoading] = useState<useCreateBackupStateType>('none');

const [password, setPassword] = useState('');
Expand Down
16 changes: 3 additions & 13 deletions src/components/change-wallet/AddressRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ 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';

const maxAccountLabelWidth = deviceUtils.dimensions.width - 88;
Expand Down Expand Up @@ -121,22 +118,15 @@ 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, balances, color: accountColor, ens, image: accountImage, isSelected, isReadOnly, isLedger, label, walletId } = data;

const { colors, isDarkMode } = useTheme();

const labelQuaternary = useForegroundColor('labelQuaternary');

const cleanedUpBalance = useMemo(() => {
if (balance) {
return convertAmountToNativeDisplay(balance, nativeCurrency);
} else {
return lang.t('wallet.change_wallet.no_balance');
}
}, [balance, nativeCurrency]);
const balanceText = balances ? balances.totalBalanceDisplay : lang.t('wallet.change_wallet.loading_balance');

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

Expand Down Expand Up @@ -254,7 +244,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}>{balanceText}</StyledBottomRowText>
</ColumnWithMargins>
</Row>
<Column style={sx.rightContent}>
Expand Down
16 changes: 4 additions & 12 deletions src/components/contacts/ContactRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import useExperimentalFlag, { PROFILES } from '@/config/experimentalHooks';
import { fetchReverseRecord } from '@/handlers/ens';
import { ENS_DOMAIN } from '@/helpers/ens';
import { isENSAddressFormat, isValidDomainFormat } from '@/helpers/validators';
import { useAccountSettings, useContacts, useDimensions, useENSAvatar } from '@/hooks';
import { useContacts, useDimensions, useENSAvatar } from '@/hooks';
import styled from '@/styled-thing';
import { margin } from '@/styles';
import { addressHashedColorIndex, addressHashedEmoji } from '@/utils/profileUtils';
import * as i18n from '@/languages';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';

const ContactAddress = styled(TruncatedAddress).attrs(({ theme: { colors }, lite }) => ({
align: 'left',
Expand Down Expand Up @@ -58,17 +57,10 @@ 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, balances, ens, image, label, network, onPress, showcaseItem, testID } = props;

const cleanedUpBalance = useMemo(() => {
if (balance) {
return convertAmountToNativeDisplay(balance, nativeCurrency);
} else {
return i18n.t(i18n.l.wallet.change_wallet.no_balance);
}
}, [balance, nativeCurrency]);
const balanceText = balances ? balances.totalBalanceDisplay : i18n.t(i18n.l.wallet.change_wallet.loading_balance);

// show avatar for contact rows that are accounts, not contacts
const avatar = accountType !== 'contacts' ? returnStringFirstEmoji(label) || profileUtils.addressHashedEmoji(address) : null;
Expand Down Expand Up @@ -141,7 +133,7 @@ const ContactRow = ({ address, color, nickname, symmetricalMargins, ...props },
</ContactName>
)}
<BottomRowText color={colors.alpha(colors.blueGreyDark, 0.5)} letterSpacing="roundedMedium" weight="medium">
{cleanedUpBalance}
{balanceText}
</BottomRowText>
</Fragment>
) : (
Expand Down
5 changes: 3 additions & 2 deletions src/components/ens-profile/ActionButtons/MoreButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { MenuActionConfig } from 'react-native-ios-context-menu';
import { showDeleteContactActionSheet } from '../../contacts';
import More from '../MoreButton/MoreButton';
import ContextMenuButton from '@/components/native-context-menu/contextMenu';
import { useClipboard, useContacts, useWallets, useWatchWallet } from '@/hooks';
import { useClipboard, useContacts, useSwitchWallet, useWallets, useWatchWallet } from '@/hooks';
import { useNavigation } from '@/navigation';
import { RAINBOW_PROFILES_BASE_URL } from '@/references';
import Routes from '@/navigation/routesNames';
Expand All @@ -24,7 +24,8 @@ const ACTIONS = {
};

export default function MoreButton({ address, ensName }: { address?: string; ensName?: string }) {
const { switchToWalletWithAddress, selectedWallet } = useWallets();
const { selectedWallet } = useWallets();
const { switchToWalletWithAddress } = useSwitchWallet();
const { isWatching } = useWatchWallet({ address });
const { navigate } = useNavigation();
const { setClipboard } = useClipboard();
Expand Down
32 changes: 13 additions & 19 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,9 +38,11 @@ const EMPTY_WALLET_CONTENT = [
const ONLY_NFTS_CONTENT = [{ type: 'ETH_CARD', uid: 'eth-card' }];

const sortedAssetsSelector = (state: any) => state.sortedAssets;
const accountBalanceDisplaySelector = (state: any) => state.accountBalanceDisplay;
const hiddenCoinsSelector = (state: any) => state.hiddenCoins;
const isCoinListEditedSelector = (state: any) => state.isCoinListEdited;
const isLoadingUserAssetsSelector = (state: any) => state.isLoadingUserAssets;
const isLoadingBalanceSelector = (state: any) => state.isLoadingBalance;
const isReadOnlyWalletSelector = (state: any) => state.isReadOnlyWallet;
const nativeCurrencySelector = (state: any) => state.nativeCurrency;
const pinnedCoinsSelector = (state: any) => state.pinnedCoins;
Expand Down Expand Up @@ -105,23 +106,15 @@ const withPositionsSection = (isLoadingUserAssets: boolean) => {
const withBriefBalanceSection = (
sortedAssets: ParsedAddressAsset[],
isLoadingUserAssets: boolean,
isLoadingBalance: boolean,
accountBalanceDisplay: string | undefined,
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,6 @@ const withBriefBalanceSection = (
{
type: 'PROFILE_STICKY_HEADER',
uid: 'assets-profile-header-compact',
value: totalValue,
isLoadingUserAssets,
},
{
type: 'PROFILE_AVATAR_ROW_SPACE_BEFORE',
Expand All @@ -156,13 +147,14 @@ const withBriefBalanceSection = (
type: 'PROFILE_NAME_ROW_SPACE_AFTER',
uid: 'profile-name-space-after',
},
...(!hasTokens && !isLoadingUserAssets
...(!hasTokens && !isLoadingUserAssets && !isLoadingBalance
? []
: [
{
type: 'PROFILE_BALANCE_ROW',
uid: 'profile-balance',
value: totalValue,
value: accountBalanceDisplay,
isLoadingBalance,
},
{
type: 'PROFILE_BALANCE_ROW_SPACE_AFTER',
Expand All @@ -172,13 +164,13 @@ const withBriefBalanceSection = (
{
type: 'PROFILE_ACTION_BUTTONS_ROW',
uid: 'profile-action-buttons',
value: totalValue,
value: accountBalanceDisplay,
},
hasTokens
? {
type: 'PROFILE_ACTION_BUTTONS_ROW_SPACE_AFTER',
uid: 'profile-action-buttons-space-after',
value: totalValue,
value: accountBalanceDisplay,
}
: { type: 'BIG_EMPTY_WALLET_SPACER', uid: 'big-empty-wallet-spacer-1' },
];
Expand Down Expand Up @@ -226,6 +218,8 @@ const briefBalanceSectionSelector = createSelector(
[
sortedAssetsSelector,
isLoadingUserAssetsSelector,
isLoadingBalanceSelector,
accountBalanceDisplaySelector,
nativeCurrencySelector,
isCoinListEditedSelector,
pinnedCoinsSelector,
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export { default as useSwapSettings } from './useSwapSettings';
export { default as useSwapDerivedOutputs } from './useSwapDerivedOutputs';
export { default as useSwapDerivedValues } from './useSwapDerivedValues';
export { default as useSwapRefuel } from './useSwapRefuel';
export { default as useSwitchWallet } from './useSwitchWallet';
export { default as useTimeout } from './useTimeout';
export { default as useTransactionConfirmation } from './useTransactionConfirmation';
export { default as usePendingTransactions } from './usePendingTransactions';
Expand Down
Loading
Loading