Skip to content

Commit

Permalink
Revert "index favorites by uniqueId instead of address (#5972)"
Browse files Browse the repository at this point in the history
This reverts commit 6d28cfc.
  • Loading branch information
ibrahimtaveras00 committed Aug 5, 2024
1 parent d8bea90 commit 90ceb2f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 132 deletions.
21 changes: 14 additions & 7 deletions src/hooks/useLoadGlobalLateData.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getWalletBalances, WALLET_BALANCES_FROM_STORAGE } from '@/handlers/localstorage/walletBalances';
import { queryClient } from '@/react-query';
import { contactsLoadState } from '@/redux/contacts';
import { imageMetadataCacheLoadState } from '@/redux/imageMetadata';
import { keyboardHeightsLoadState } from '@/redux/keyboardHeight';
import { AppState } from '@/redux/store';
import { transactionSignaturesLoadState } from '@/redux/transactionSignatures';
import { promiseUtils } from '@/utils';
import logger from '@/utils/logger';
import { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { imageMetadataCacheLoadState } from '@/redux/imageMetadata';
import { keyboardHeightsLoadState } from '@/redux/keyboardHeight';
import { transactionSignaturesLoadState } from '@/redux/transactionSignatures';
import { contactsLoadState } from '@/redux/contacts';
import { favoritesQueryKey, refreshFavorites } from '@/resources/favorites';

const loadWalletBalanceNamesToCache = () => queryClient.prefetchQuery([WALLET_BALANCES_FROM_STORAGE], getWalletBalances);

Expand All @@ -27,6 +28,12 @@ export default function useLoadGlobalLateData() {
// mainnet eth balances for all wallets
const p2 = loadWalletBalanceNamesToCache();

// favorites
const p3 = queryClient.prefetchQuery({
queryKey: favoritesQueryKey,
queryFn: () => refreshFavorites(),
});

// contacts
const p4 = dispatch(contactsLoadState());

Expand All @@ -39,7 +46,7 @@ export default function useLoadGlobalLateData() {
// tx method names
const p7 = dispatch(transactionSignaturesLoadState());

promises.push(p2, p4, p5, p6, p7);
promises.push(p2, p3, p4, p5, p6, p7);

// @ts-expect-error ts-migrate(2345) FIXME: Argument of type '(Promise<void> | ((dispatch: Dis... Remove this comment to see the full error message
return promiseUtils.PromiseAllWithFails(promises);
Expand Down
12 changes: 5 additions & 7 deletions src/migrations/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { InteractionManager } from 'react-native';

import * as env from '@/env';
import { logger, RainbowError } from '@/logger';
import { Storage } from '@/storage';
import { logger, RainbowError } from '@/logger';

import { MIGRATIONS_DEBUG_CONTEXT, MIGRATIONS_STORAGE_ID, MigrationName, Migration } from '@/migrations/types';
import { deleteImgixMMKVCache } from '@/migrations/migrations/deleteImgixMMKVCache';
import { migrateNotificationSettingsToV2 } from '@/migrations/migrations/migrateNotificationSettingsToV2';
import { prepareDefaultNotificationGroupSettingsState } from '@/migrations/migrations/prepareDefaultNotificationGroupSettingsState';
import { Migration, MigrationName, MIGRATIONS_DEBUG_CONTEXT, MIGRATIONS_STORAGE_ID } from '@/migrations/types';
import { changeLanguageKeys } from './migrations/changeLanguageKeys';
import { fixHiddenUSDC } from './migrations/fixHiddenUSDC';
import { migrateFavoritesToV2 } from './migrations/migrateFavoritesToV2';
import { migratePersistedQueriesToMMKV } from './migrations/migratePersistedQueriesToMMKV';
import { purgeWcConnectionsWithoutAccounts } from './migrations/purgeWcConnectionsWithoutAccounts';
import { migratePinnedAndHiddenTokenUniqueIds } from './migrations/migratePinnedAndHiddenTokenUniqueIds';
import { migrateRemotePromoSheetsToZustand } from './migrations/migrateRemotePromoSheetsToZustand';
import { migrateUnlockableAppIconStorage } from './migrations/migrateUnlockableAppIconStorage';
import { purgeWcConnectionsWithoutAccounts } from './migrations/purgeWcConnectionsWithoutAccounts';
import { migratePersistedQueriesToMMKV } from './migrations/migratePersistedQueriesToMMKV';
import { migrateRemotePromoSheetsToZustand } from './migrations/migrateRemotePromoSheetsToZustand';

/**
* Local storage for migrations only. Should not be exported.
Expand All @@ -42,7 +41,6 @@ const migrations: Migration[] = [
migrateUnlockableAppIconStorage(),
migratePersistedQueriesToMMKV(),
migrateRemotePromoSheetsToZustand(),
migrateFavoritesToV2(),
];

/**
Expand Down
31 changes: 0 additions & 31 deletions src/migrations/migrations/migrateFavoritesToV2.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/migrations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export enum MigrationName {
migrateUnlockableAppIconStorage = 'migration_migrateUnlockableAppIconStorage',
migratePersistedQueriesToMMKV = 'migration_migratePersistedQueriesToMMKV',
migrateRemotePromoSheetsToZustand = 'migration_migrateRemotePromoSheetsToZustand',
migrateFavoritesToV2 = 'migration_migrateFavoritesToV2',
}

export type Migration = {
Expand Down
122 changes: 36 additions & 86 deletions src/resources/favorites.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import { AddressOrEth, UniqueId } from '@/__swaps__/types/assets';
import { ChainId } from '@/__swaps__/types/chains';
import { getStandardizedUniqueIdWorklet } from '@/__swaps__/utils/swaps';
import { NativeCurrencyKeys, RainbowToken } from '@/entities';
import { EthereumAddress, NativeCurrencyKeys, RainbowToken } from '@/entities';
import { Network } from '@/networks/types';
import { createQueryKey, queryClient } from '@/react-query';
import { DAI_ADDRESS, ETH_ADDRESS, SOCKS_ADDRESS, WBTC_ADDRESS, WETH_ADDRESS } from '@/references';
import { promiseUtils } from '@/utils';
import ethereumUtils from '@/utils/ethereumUtils';
import ethereumUtils, { getUniqueId } from '@/utils/ethereumUtils';
import { useQuery } from '@tanstack/react-query';
import { omit } from 'lodash';
import { externalTokenQueryKey, fetchExternalToken } from './assets/externalAssetsQuery';
import { ChainId } from '@/__swaps__/types/chains';
import { promiseUtils } from '@/utils';

export const favoritesQueryKey = createQueryKey('favorites', {}, { persisterVersion: 2 });

const getUniqueId = (address: AddressOrEth, chainId: ChainId) => getStandardizedUniqueIdWorklet({ address, chainId });

const DAI_uniqueId = getUniqueId(DAI_ADDRESS, ChainId.mainnet);
const ETH_uniqueId = getUniqueId(ETH_ADDRESS, ChainId.mainnet);
const SOCKS_uniqueId = getUniqueId(SOCKS_ADDRESS, ChainId.mainnet);
const WBTC_uniqueId = getUniqueId(WBTC_ADDRESS, ChainId.mainnet);
export const favoritesQueryKey = createQueryKey('favorites', {}, { persisterVersion: 1 });

const DEFAULT: Record<UniqueId, RainbowToken> = {
[DAI_uniqueId]: {
const DEFAULT: Record<EthereumAddress, RainbowToken> = {
[DAI_ADDRESS]: {
address: DAI_ADDRESS,
color: '#F0B340',
decimals: 18,
Expand All @@ -32,12 +23,9 @@ const DEFAULT: Record<UniqueId, RainbowToken> = {
name: 'Dai',
symbol: 'DAI',
network: Network.mainnet,
uniqueId: DAI_uniqueId,
networks: {
[ChainId.mainnet]: { address: DAI_ADDRESS },
},
uniqueId: DAI_ADDRESS,
},
[ETH_uniqueId]: {
[ETH_ADDRESS]: {
address: ETH_ADDRESS,
color: '#25292E',
decimals: 18,
Expand All @@ -47,12 +35,9 @@ const DEFAULT: Record<UniqueId, RainbowToken> = {
name: 'Ethereum',
symbol: 'ETH',
network: Network.mainnet,
uniqueId: ETH_uniqueId,
networks: {
[ChainId.mainnet]: { address: ETH_ADDRESS },
},
uniqueId: ETH_ADDRESS,
},
[SOCKS_uniqueId]: {
[SOCKS_ADDRESS]: {
address: SOCKS_ADDRESS,
color: '#E15EE5',
decimals: 18,
Expand All @@ -63,12 +48,9 @@ const DEFAULT: Record<UniqueId, RainbowToken> = {
name: 'Unisocks',
symbol: 'SOCKS',
network: Network.mainnet,
uniqueId: SOCKS_uniqueId,
networks: {
[ChainId.mainnet]: { address: SOCKS_ADDRESS },
},
uniqueId: SOCKS_ADDRESS,
},
[WBTC_uniqueId]: {
[WBTC_ADDRESS]: {
address: WBTC_ADDRESS,
color: '#FF9900',
decimals: 8,
Expand All @@ -79,19 +61,16 @@ const DEFAULT: Record<UniqueId, RainbowToken> = {
name: 'Wrapped Bitcoin',
symbol: 'WBTC',
network: Network.mainnet,
uniqueId: WBTC_uniqueId,
networks: {
[ChainId.mainnet]: { address: WBTC_ADDRESS },
},
uniqueId: WBTC_ADDRESS,
},
};

/**
* Returns a map of the given `addresses` to their corresponding `RainbowToken` metadata.
*/
async function fetchMetadata(addresses: string[], chainId = ChainId.mainnet) {
const favoritesMetadata: Record<UniqueId, RainbowToken> = {};
const newFavoritesMeta: Record<UniqueId, RainbowToken> = {};
const favoritesMetadata: Record<EthereumAddress, RainbowToken> = {};
const newFavoritesMeta: Record<EthereumAddress, RainbowToken> = {};

const network = ethereumUtils.getNetworkFromChainId(chainId);

Expand All @@ -106,14 +85,13 @@ async function fetchMetadata(addresses: string[], chainId = ChainId.mainnet) {
);

if (externalAsset) {
const uniqueId = getUniqueId(externalAsset?.networks[chainId]?.address, chainId);
newFavoritesMeta[uniqueId] = {
newFavoritesMeta[address] = {
...externalAsset,
network,
network: ethereumUtils.getNetworkFromChainId(ChainId.mainnet),
address,
networks: externalAsset.networks,
mainnet_address: externalAsset?.networks[ChainId.mainnet]?.address,
uniqueId,
uniqueId: getUniqueId(externalAsset?.networks[chainId]?.address, Network.mainnet),
isVerified: true,
};
}
Expand All @@ -125,56 +103,32 @@ async function fetchMetadata(addresses: string[], chainId = ChainId.mainnet) {
const ethIsFavorited = addresses.includes(ETH_ADDRESS);
const wethIsFavorited = addresses.includes(WETH_ADDRESS);
if (newFavoritesMeta) {
const WETH_uniqueId = getUniqueId(WETH_ADDRESS, ChainId.mainnet);
if (newFavoritesMeta[WETH_uniqueId] && ethIsFavorited) {
const favorite = newFavoritesMeta[WETH_uniqueId];
const uniqueId = getUniqueId(ETH_ADDRESS, ChainId.mainnet);
newFavoritesMeta[uniqueId] = {
if (newFavoritesMeta[WETH_ADDRESS] && ethIsFavorited) {
const favorite = newFavoritesMeta[WETH_ADDRESS];
newFavoritesMeta[ETH_ADDRESS] = {
...favorite,
address: ETH_ADDRESS,
name: 'Ethereum',
symbol: 'ETH',
uniqueId,
uniqueId: getUniqueId(ETH_ADDRESS, Network.mainnet),
};
}
Object.entries(newFavoritesMeta).forEach(([uniqueId, favorite]) => {
if (favorite.address !== WETH_ADDRESS || wethIsFavorited) {
favoritesMetadata[uniqueId] = { ...favorite, favorite: true };
Object.entries(newFavoritesMeta).forEach(([address, favorite]) => {
if (address !== WETH_ADDRESS || wethIsFavorited) {
favoritesMetadata[address] = { ...favorite, favorite: true };
}
});
}

return favoritesMetadata;
}

/**
* Refreshes the metadata associated with all favorites.
*/
export async function refreshFavorites() {
const favorites = queryClient.getQueryData<Record<UniqueId, RainbowToken>>(favoritesQueryKey) ?? DEFAULT;

const favoritesByNetwork = Object.values(favorites).reduce(
(favoritesByChain, token) => {
favoritesByChain[token.network] ??= [];
favoritesByChain[token.network].push(token.address);
return favoritesByChain;
},
{} as Record<Network, string[]>
);

const updatedMetadataByNetwork = await Promise.all(
Object.entries(favoritesByNetwork).map(async ([network, networkFavorites]) =>
fetchMetadata(networkFavorites, ethereumUtils.getChainIdFromNetwork(network as Network))
)
);

return updatedMetadataByNetwork.reduce(
(updatedMetadata, updatedNetworkMetadata) => ({
...updatedMetadata,
...updatedNetworkMetadata,
}),
{}
);
const favorites = Object.keys(queryClient.getQueryData(favoritesQueryKey) ?? DEFAULT);
const updatedMetadata = await fetchMetadata(favorites, ChainId.mainnet);
return updatedMetadata;
}

/**
Expand All @@ -185,11 +139,10 @@ export async function refreshFavorites() {
* @param chainId - The chain id of the network to toggle the favorite status of @default ChainId.mainnet
*/
export async function toggleFavorite(address: string, chainId = ChainId.mainnet) {
const favorites = queryClient.getQueryData<Record<UniqueId, RainbowToken>>(favoritesQueryKey);
const lowercasedAddress = address.toLowerCase() as AddressOrEth;
const uniqueId = getUniqueId(lowercasedAddress, chainId);
if (Object.keys(favorites || {}).includes(uniqueId)) {
queryClient.setQueryData(favoritesQueryKey, omit(favorites, uniqueId));
const favorites = queryClient.getQueryData<Record<EthereumAddress, RainbowToken>>(favoritesQueryKey);
const lowercasedAddress = address.toLowerCase() as EthereumAddress;
if (Object.keys(favorites || {}).includes(lowercasedAddress)) {
queryClient.setQueryData(favoritesQueryKey, omit(favorites, lowercasedAddress));
} else {
const metadata = await fetchMetadata([lowercasedAddress], chainId);
queryClient.setQueryData(favoritesQueryKey, {
Expand All @@ -206,14 +159,11 @@ export async function toggleFavorite(address: string, chainId = ChainId.mainnet)
*/
export function useFavorites(): {
favorites: string[];
favoritesMetadata: Record<UniqueId, RainbowToken>;
favoritesMetadata: Record<EthereumAddress, RainbowToken>;
} {
const query = useQuery({
queryKey: favoritesQueryKey,
queryFn: refreshFavorites,
staleTime: 24 * 60 * 60 * 1000, // 24hrs
const query = useQuery<Record<EthereumAddress, RainbowToken>>(favoritesQueryKey, refreshFavorites, {
staleTime: Infinity,
cacheTime: Infinity,
initialData: DEFAULT,
});

const favoritesMetadata = query.data ?? {};
Expand Down

0 comments on commit 90ceb2f

Please sign in to comment.