Skip to content

Commit

Permalink
User assets migration (#6038)
Browse files Browse the repository at this point in the history
  • Loading branch information
benisgold authored Dec 19, 2024
1 parent 29ec1a0 commit a3547f3
Show file tree
Hide file tree
Showing 28 changed files with 228 additions and 557 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
import { ExtendedAnimatedAssetWithColors } from '@/__swaps__/types/assets';
import { ChainId } from '@/state/backendNetworks/types';
import { ParsedAddressAsset } from '@/entities';
import { useUserNativeNetworkAsset } from '@/resources/assets/useUserAsset';
import { CrosschainQuote, Quote, QuoteError } from '@rainbow-me/swaps';
import { deepEqualWorklet } from '@/worklets/comparisons';
import { debounce } from 'lodash';
Expand All @@ -26,7 +25,10 @@ import { GasSettings } from '../hooks/useCustomGas';
import { useSelectedGas } from '../hooks/useSelectedGas';
import { useSwapEstimatedGasLimit } from '../hooks/useSwapEstimatedGasLimit';
import { useSwapContext } from './swap-provider';
import { useUserAssetsStore } from '@/state/assets/userAssets';
import { getUniqueId } from '@/utils/ethereumUtils';
import { useSwapsStore } from '@/state/swaps/swapsStore';
import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks';

const BUFFER_RATIO = 0.5;

Expand Down Expand Up @@ -143,7 +145,12 @@ export function SyncGasStateToSharedValues() {
const { assetToSell, chainId = initialChainId, quote } = useSyncedSwapQuoteStore();

const gasSettings = useSelectedGas(chainId);
const { data: userNativeNetworkAsset, isLoading: isLoadingNativeNetworkAsset } = useUserNativeNetworkAsset(chainId);

const { userNativeNetworkAsset, isLoadingNativeNetworkAsset } = useUserAssetsStore(state => {
const { address: nativeCurrencyAddress } = useBackendNetworksStore.getState().getChainsNativeAsset()[chainId];
const uniqueId = getUniqueId(nativeCurrencyAddress, chainId);
return { userNativeNetworkAsset: state.getLegacyUserAsset(uniqueId), isLoadingNativeNetworkAsset: state.isLoadingUserAssets };
});
const { data: estimatedGasLimit } = useSwapEstimatedGasLimit({ chainId, assetToSell, quote });

const gasFeeRange = useSharedValue<[string, string] | null>(null);
Expand Down
12 changes: 2 additions & 10 deletions src/__swaps__/screens/Swap/providers/swap-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { NavigationSteps, useSwapNavigation } from '@/__swaps__/screens/Swap/hoo
import { useSwapSettings } from '@/__swaps__/screens/Swap/hooks/useSwapSettings';
import { useSwapTextStyles } from '@/__swaps__/screens/Swap/hooks/useSwapTextStyles';
import { SwapWarningType, useSwapWarning } from '@/__swaps__/screens/Swap/hooks/useSwapWarning';
import { userAssetsQueryKey as swapsUserAssetsQueryKey } from '@/__swaps__/screens/Swap/resources/assets/userAssets';
import { userAssetsQueryKey } from '@/__swaps__/screens/Swap/resources/assets/userAssets';
import { AddressOrEth, ExtendedAnimatedAssetWithColors, ParsedSearchAsset } from '@/__swaps__/types/assets';
import { ChainId } from '@/state/backendNetworks/types';
import { SwapAssetType, inputKeys } from '@/__swaps__/types/swap';
Expand All @@ -41,7 +41,6 @@ import Routes from '@/navigation/routesNames';
import { walletExecuteRap } from '@/raps/execute';
import { QuoteTypeMap, RapSwapActionParameters } from '@/raps/references';
import { queryClient } from '@/react-query';
import { userAssetsQueryKey } from '@/resources/assets/UserAssetsQuery';
import { userAssetsStore } from '@/state/assets/userAssets';
import { swapsStore } from '@/state/swaps/swapsStore';
import { getNextNonce } from '@/state/nonces';
Expand Down Expand Up @@ -342,14 +341,7 @@ export const SwapProvider = ({ children }: SwapProviderProps) => {
userAssetsQueryKey({
address: parameters.quote.from,
currency: nativeCurrency,
connectedToHardhat,
})
);
queryClient.invalidateQueries(
swapsUserAssetsQueryKey({
address: parameters.quote.from as Address,
currency: nativeCurrency,
testnetMode: !!connectedToHardhat,
testnetMode: connectedToHardhat,
})
);

Expand Down
21 changes: 13 additions & 8 deletions src/__swaps__/screens/Swap/resources/assets/userAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { fetchUserAssetsByChain } from './userAssetsByChain';
import { fetchHardhatBalancesByChainId } from '@/resources/assets/hardhatAssets';
import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks';
import { useConnectedToHardhatStore } from '@/state/connectedToHardhat';
import { staleBalancesStore } from '@/state/staleBalances';
import { IS_TEST } from '@/env';
import store from '@/redux/store';

const addysHttp = new RainbowFetchClient({
Expand All @@ -28,7 +30,7 @@ const addysHttp = new RainbowFetchClient({

const USER_ASSETS_REFETCH_INTERVAL = 60000;
const USER_ASSETS_TIMEOUT_DURATION = 20000;
export const USER_ASSETS_STALE_INTERVAL = 30000;
const USER_ASSETS_STALE_INTERVAL = 30000;

// ///////////////////////////////////////////////
// Query Types
Expand Down Expand Up @@ -123,20 +125,23 @@ async function userAssetsQueryFunction({

return parsedAssetsDict;
}

const cache = queryClient.getQueryCache();
const cachedUserAssets = (cache.find(userAssetsQueryKey({ address, currency, testnetMode }))?.state?.data ||
{}) as ParsedAssetsDictByChain;
try {
const url = `/${useBackendNetworksStore.getState().getSupportedChainIds().join(',')}/${address}/assets`;
staleBalancesStore.getState().clearExpiredData(address);
const staleBalanceParam = staleBalancesStore.getState().getStaleBalancesQueryParam(address);
let url = `/${useBackendNetworksStore.getState().getSupportedChainIds().join(',')}/${address}/assets?currency=${currency.toLowerCase()}`;
if (staleBalanceParam) {
url += staleBalanceParam;
}
const res = await addysHttp.get<AddressAssetsReceivedMessage>(url, {
params: {
currency: currency.toLowerCase(),
},
timeout: USER_ASSETS_TIMEOUT_DURATION,
});
const chainIdsInResponse = res?.data?.meta?.chain_ids || [];
const chainIdsWithErrorsInResponse = res?.data?.meta?.chain_ids_with_errors || [];
const assets = res?.data?.payload?.assets || [];
const assets = res?.data?.payload?.assets?.filter(asset => !asset.asset.defi_position) || [];
if (address) {
if (chainIdsWithErrorsInResponse.length) {
userAssetsQueryFunctionRetryByChain({
Expand Down Expand Up @@ -170,7 +175,7 @@ async function userAssetsQueryFunction({
}
}

type UserAssetsResult = QueryFunctionResult<typeof userAssetsQueryFunction>;
export type UserAssetsResult = QueryFunctionResult<typeof userAssetsQueryFunction>;

async function userAssetsQueryFunctionRetryByChain({
address,
Expand Down Expand Up @@ -258,6 +263,6 @@ export function useUserAssets<TSelectResult = UserAssetsResult>(
...config,
enabled: !!address && !!currency,
refetchInterval: USER_ASSETS_REFETCH_INTERVAL,
staleTime: process.env.IS_TESTING === 'true' ? 0 : 1000,
staleTime: IS_TEST ? 0 : USER_ASSETS_STALE_INTERVAL,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function userAssetsByChainQueryFunction({
},
});
const chainIdsInResponse = res?.data?.meta?.chain_ids || [];
const assets = res?.data?.payload?.assets || [];
const assets = res?.data?.payload?.assets?.filter(asset => !asset.asset.defi_position) || [];
if (assets.length && chainIdsInResponse.length) {
const parsedAssetsDict = await parseUserAssets({
assets,
Expand Down
1 change: 1 addition & 0 deletions src/__swaps__/types/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export interface ZerionAsset {
bridgeable: boolean;
networks: { [id in ChainId]?: { bridgeable: boolean } };
};
defi_position?: boolean;
}

// protocols https://github.com/rainbow-me/go-utils-lib/blob/master/pkg/enums/token_type.go#L44
Expand Down
31 changes: 0 additions & 31 deletions src/__swaps__/utils/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,37 +234,6 @@ export function parseUserAssetBalances({
};
}

export function parseParsedUserAsset({
parsedAsset,
currency,
quantity,
}: {
parsedAsset: ParsedUserAsset;
currency: SupportedCurrencyKey;
quantity: string;
}): ParsedUserAsset {
const amount = convertRawAmountToDecimalFormat(quantity, parsedAsset?.decimals);
return {
...parsedAsset,
balance: {
amount,
display: convertAmountToBalanceDisplay(amount, {
decimals: parsedAsset?.decimals,
symbol: parsedAsset?.symbol,
}),
},
native: {
...parsedAsset.native,
balance: getNativeAssetBalance({
currency,
decimals: parsedAsset?.decimals,
priceUnit: parsedAsset?.price?.value || 0,
value: amount,
}),
},
};
}

export const parseSearchAsset = ({
assetWithPrice,
searchAsset,
Expand Down
4 changes: 2 additions & 2 deletions src/components/asset-list/AssetListHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import { StickyHeader } from './RecyclerAssetList2/core/StickyHeaders';
import { useAccountProfile, useDimensions } from '@/hooks';
import { useNavigation } from '@/navigation';
import Routes from '@/navigation/routesNames';
import { useUserAssetCount } from '@/resources/assets/useUserAssetCount';
import styled from '@/styled-thing';
import { fonts, position } from '@/styles';
import { useTheme } from '@/theme';
import * as lang from '@/languages';
import { useUserAssetsStore } from '@/state/assets/userAssets';

export const AssetListHeaderHeight = ListHeaderHeight;

Expand Down Expand Up @@ -104,7 +104,7 @@ const AssetListHeader = ({ contextMenuOptions, isCoinListEdited, title, totalVal
const { width: deviceWidth } = useDimensions();
const { accountName } = useAccountProfile();
const { navigate } = useNavigation();
const { isLoading: isLoadingUserAssets } = useUserAssetCount();
const { isLoadingUserAssets } = useUserAssetsStore(state => state.isLoadingUserAssets);

const onChangeWallet = useCallback(() => {
navigate(Routes.CHANGE_WALLET_SHEET);
Expand Down
4 changes: 2 additions & 2 deletions src/components/list/NoResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { neverRerender } from '@/utils';
import { Inset, Stack, Text } from '@/design-system';
import { useTheme } from '@/theme';
import { logger } from '@/logger';
import { useUserAssetCount } from '@/resources/assets/useUserAssetCount';
import { useUserAssetsStore } from '@/state/assets/userAssets';

export enum NoResultsType {
Discover = 'discover',
Expand All @@ -14,7 +14,7 @@ export enum NoResultsType {

export const NoResults = ({ onL2, type }: { onL2?: boolean; type: NoResultsType }) => {
const { colors } = useTheme();
const { data: assetCount } = useUserAssetCount();
const assetCount = useUserAssetsStore(state => state.userAssets.size);

let title;
let description;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { selectorFilterByUserChains, selectUserAssetsList } from '@/__swaps__/screens/Swap/resources/_selectors/assets';
import { userAssetsFetchQuery } from '@/__swaps__/screens/Swap/resources/assets/userAssets';
import store from '@/redux/store';
import { fetchUserAssets } from '@/resources/assets/UserAssetsQuery';
import { useConnectedToHardhatStore } from '@/state/connectedToHardhat';

export const hasNonZeroTotalBalance = async (): Promise<boolean> => {
const { accountAddress, nativeCurrency } = store.getState().settings;

const assets = await fetchUserAssets({
const userAssetsDictByChain = await userAssetsFetchQuery({
address: accountAddress,
currency: nativeCurrency,
connectedToHardhat: false,
testnetMode: useConnectedToHardhatStore.getState().connectedToHardhat,
});

if (!assets || Object.keys(assets).length === 0) return false;
const assets = selectorFilterByUserChains({ data: userAssetsDictByChain, selector: selectUserAssetsList });

return Object.values(assets).some(asset => Number(asset.balance?.amount) > 0);
if (!assets?.length) return false;

return assets.some(asset => Number(asset.balance?.amount) > 0);
};
2 changes: 1 addition & 1 deletion src/helpers/buildWalletSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ const withBriefBalanceSection = (
type: 'PROFILE_NAME_ROW_SPACE_AFTER',
uid: 'profile-name-space-after',
},
...(!hasTokens && !isLoadingUserAssets && !isLoadingBalance
...(!hasTokens && !isLoadingBalance
? []
: [
{
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useAccountAsset.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { NativeCurrencyKey } from '@/entities';
import useAccountSettings from './useAccountSettings';
import { parseAssetNative } from '@/parsers';
import { useUserAsset } from '@/resources/assets/useUserAsset';
import { useUserAssetsStore } from '@/state/assets/userAssets';

// this is meant to be used for assets contained in the current wallet
export default function useAccountAsset(uniqueId: string, nativeCurrency: NativeCurrencyKey | undefined = undefined) {
const { data: accountAsset } = useUserAsset(uniqueId);
const accountAsset = useUserAssetsStore(state => state.getLegacyUserAsset(uniqueId));

// this is temporary for FastBalanceCoinRow to make a tiny bit faster
// we pass nativeCurrency only in that case
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/useColorForAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export default function useColorForAsset(
const isDarkMode = forceLightMode || isDarkModeTheme;

const colorDerivedFromAddress = useMemo(() => {
if (!resolvedAddress) {
return undefined;
}

const color = isETH(resolvedAddress)
? isDarkMode
? forceETHColor
Expand Down
6 changes: 2 additions & 4 deletions src/hooks/useRefreshAccountData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import useAccountSettings from './useAccountSettings';
import { PROFILES, useExperimentalFlag } from '@/config';
import { logger, RainbowError } from '@/logger';
import { queryClient } from '@/react-query';
import { userAssetsQueryKey } from '@/resources/assets/UserAssetsQuery';
import { userAssetsQueryKey as swapsUserAssetsQueryKey } from '@/__swaps__/screens/Swap/resources/assets/userAssets';
import { userAssetsQueryKey } from '@/__swaps__/screens/Swap/resources/assets/userAssets';
import { invalidateAddressNftsQueries } from '@/resources/nfts';
import { positionsQueryKey } from '@/resources/defi/PositionsQuery';
import { Address } from 'viem';
Expand Down Expand Up @@ -35,9 +34,8 @@ export default function useRefreshAccountData() {
queryClient.invalidateQueries(positionsQueryKey({ address: accountAddress as Address, currency: nativeCurrency }));
queryClient.invalidateQueries(claimablesQueryKey({ address: accountAddress, currency: nativeCurrency }));
queryClient.invalidateQueries(addysSummaryQueryKey({ addresses: allAddresses, currency: nativeCurrency }));
queryClient.invalidateQueries(userAssetsQueryKey({ address: accountAddress, currency: nativeCurrency, connectedToHardhat }));
queryClient.invalidateQueries(
swapsUserAssetsQueryKey({ address: accountAddress as Address, currency: nativeCurrency, testnetMode: !!connectedToHardhat })
userAssetsQueryKey({ address: accountAddress, currency: nativeCurrency, testnetMode: connectedToHardhat })
);

try {
Expand Down
10 changes: 6 additions & 4 deletions src/hooks/useWalletSectionsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import useSendableUniqueTokens from './useSendableUniqueTokens';
import useShowcaseTokens from './useShowcaseTokens';
import useWallets from './useWallets';
import { buildBriefWalletSectionsSelector } from '@/helpers/buildWalletSections';
import { useSortedUserAssets } from '@/resources/assets/useSortedUserAssets';
import { useLegacyNFTs } from '@/resources/nfts';
import useWalletsWithBalancesAndNames from './useWalletsWithBalancesAndNames';
import { useUserAssetsStore } from '@/state/assets/userAssets';
import { useRemoteConfig } from '@/model/remoteConfig';
import { usePositions } from '@/resources/defi/PositionsQuery';
import { useClaimables } from '@/resources/addys/claimables/query';
import { useExperimentalConfig } from '@/config/experimentalHooks';
import { useUserAssetsStore } from '@/state/assets/userAssets';
import { analyticsV2 } from '@/analytics';
import { Claimable } from '@/resources/addys/claimables/types';
import { throttle } from 'lodash';
Expand Down Expand Up @@ -55,13 +54,16 @@ export default function useWalletSectionsData({
}: {
type?: string;
} = {}) {
const { accountAddress, language, network, nativeCurrency } = useAccountSettings();
const { selectedWallet, isReadOnlyWallet } = useWallets();
const { isLoading: isLoadingUserAssets, data: sortedAssets = [] } = useSortedUserAssets();
const { isLoadingUserAssets, sortedAssets = [] } = useUserAssetsStore(state => ({
sortedAssets: state.legacyUserAssets,
isLoadingUserAssets: state.isLoadingUserAssets,
}));
const isWalletEthZero = useIsWalletEthZero();

const { nftSort, nftSortDirection } = useNftSort();

const { accountAddress, language, network, nativeCurrency } = useAccountSettings();
const { sendableUniqueTokens } = useSendableUniqueTokens();
const {
data: { nfts: allUniqueTokens },
Expand Down
Loading

0 comments on commit a3547f3

Please sign in to comment.