mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
get tokens info from watchlist responce
This commit is contained in:
@@ -480,9 +480,6 @@ export const RESOURCES = {
|
||||
},
|
||||
|
||||
// DEPRECATED
|
||||
old_api: {
|
||||
path: '/api',
|
||||
},
|
||||
csv_export_txs: {
|
||||
path: '/transactions-csv',
|
||||
},
|
||||
|
||||
+4
-3
@@ -1,5 +1,4 @@
|
||||
import type { PublicTag, AddressTag, TransactionTag, ApiKey, CustomAbi, VerifiedAddress, TokenInfoApplication } from 'types/api/account';
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { PublicTag, AddressTag, TransactionTag, ApiKey, CustomAbi, VerifiedAddress, TokenInfoApplication, WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import { ADDRESS_PARAMS, ADDRESS_HASH } from './addressParams';
|
||||
import { TX_HASH } from './tx';
|
||||
@@ -30,7 +29,7 @@ export const PUBLIC_TAG: PublicTag = {
|
||||
website: 'example.com',
|
||||
};
|
||||
|
||||
export const WATCH_LIST_ITEM_WITH_TOKEN_INFO: TWatchlistItem = {
|
||||
export const WATCH_LIST_ITEM_WITH_TOKEN_INFO: WatchlistAddress = {
|
||||
address: ADDRESS_PARAMS,
|
||||
address_balance: '7072643779453701031672',
|
||||
address_hash: ADDRESS_HASH,
|
||||
@@ -55,6 +54,8 @@ export const WATCH_LIST_ITEM_WITH_TOKEN_INFO: TWatchlistItem = {
|
||||
},
|
||||
},
|
||||
tokens_count: 42,
|
||||
tokens_fiat_value: '12345',
|
||||
tokens_overflow: false,
|
||||
};
|
||||
|
||||
export const API_KEY: ApiKey = {
|
||||
|
||||
@@ -66,12 +66,9 @@ export interface WatchlistAddress {
|
||||
notification_methods: NotificationMethods;
|
||||
id: string;
|
||||
address: AddressParam;
|
||||
}
|
||||
|
||||
export interface WatchlistTokensResponse {
|
||||
message: string;
|
||||
result?: Array<unknown>;
|
||||
status: string;
|
||||
tokens_count: number;
|
||||
tokens_fiat_value: string;
|
||||
tokens_overflow: boolean;
|
||||
}
|
||||
|
||||
export interface WatchlistAddressNew {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import type { WatchlistAddress } from '../api/account';
|
||||
|
||||
export type TWatchlistItem = WatchlistAddress & {tokens_count: number};
|
||||
|
||||
export type TWatchlist = Array<TWatchlistItem>;
|
||||
|
||||
export interface CsrfData {
|
||||
token: string;
|
||||
}
|
||||
|
||||
+11
-37
@@ -1,13 +1,11 @@
|
||||
import { Box, Button, Skeleton, useDisclosure } from '@chakra-ui/react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { WatchlistAddress, WatchlistTokensResponse } from 'types/api/account';
|
||||
import type { TWatchlist, TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import type { ResourceError } from 'lib/api/resources';
|
||||
import { resourceKey } from 'lib/api/resources';
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
import useApiQuery from 'lib/api/useApiQuery';
|
||||
import useRedirectForInvalidAuthToken from 'lib/hooks/useRedirectForInvalidAuthToken';
|
||||
import { WATCH_LIST_ITEM_WITH_TOKEN_INFO } from 'stubs/account';
|
||||
import AccountPageDescription from 'ui/shared/AccountPageDescription';
|
||||
@@ -19,45 +17,21 @@ import WatchListItem from 'ui/watchlist/WatchlistTable/WatchListItem';
|
||||
import WatchlistTable from 'ui/watchlist/WatchlistTable/WatchlistTable';
|
||||
|
||||
const WatchList: React.FC = () => {
|
||||
const apiFetch = useApiFetch();
|
||||
const { data, isPlaceholderData, isError } = useQuery<unknown, ResourceError, TWatchlist>(
|
||||
[ resourceKey('watchlist') ],
|
||||
async() => {
|
||||
const watchlistAddresses = await apiFetch<'watchlist', Array<WatchlistAddress>>('watchlist');
|
||||
|
||||
if (!Array.isArray(watchlistAddresses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const watchlistTokens = await Promise.all(watchlistAddresses.map(({ address }) => {
|
||||
if (!address?.hash) {
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
return apiFetch<'old_api', WatchlistTokensResponse>('old_api', { queryParams: { address: address.hash, module: 'account', action: 'tokenlist' } })
|
||||
.then((response) => {
|
||||
if ('result' in response && Array.isArray(response.result)) {
|
||||
return response.result.length;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}));
|
||||
|
||||
return watchlistAddresses.map((item, index) => ({ ...item, tokens_count: watchlistTokens[index] }));
|
||||
},
|
||||
{
|
||||
const { data, isPlaceholderData, isError } = useApiQuery('watchlist', {
|
||||
queryOptions: {
|
||||
placeholderData: Array(3).fill(WATCH_LIST_ITEM_WITH_TOKEN_INFO),
|
||||
},
|
||||
);
|
||||
});
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const addressModalProps = useDisclosure();
|
||||
const deleteModalProps = useDisclosure();
|
||||
useRedirectForInvalidAuthToken();
|
||||
|
||||
const [ addressModalData, setAddressModalData ] = useState<TWatchlistItem>();
|
||||
const [ deleteModalData, setDeleteModalData ] = useState<TWatchlistItem>();
|
||||
const [ addressModalData, setAddressModalData ] = useState<WatchlistAddress>();
|
||||
const [ deleteModalData, setDeleteModalData ] = useState<WatchlistAddress>();
|
||||
|
||||
const onEditClick = useCallback((data: TWatchlistItem) => {
|
||||
const onEditClick = useCallback((data: WatchlistAddress) => {
|
||||
setAddressModalData(data);
|
||||
addressModalProps.onOpen();
|
||||
}, [ addressModalProps ]);
|
||||
@@ -73,7 +47,7 @@ const WatchList: React.FC = () => {
|
||||
addressModalProps.onClose();
|
||||
}, [ addressModalProps, queryClient ]);
|
||||
|
||||
const onDeleteClick = useCallback((data: TWatchlistItem) => {
|
||||
const onDeleteClick = useCallback((data: WatchlistAddress) => {
|
||||
setDeleteModalData(data);
|
||||
deleteModalProps.onOpen();
|
||||
}, [ deleteModalProps ]);
|
||||
@@ -84,7 +58,7 @@ const WatchList: React.FC = () => {
|
||||
}, [ deleteModalProps ]);
|
||||
|
||||
const onDeleteSuccess = useCallback(async() => {
|
||||
queryClient.setQueryData([ resourceKey('watchlist') ], (prevData: TWatchlist | undefined) => {
|
||||
queryClient.setQueryData([ resourceKey('watchlist') ], (prevData: Array<WatchlistAddress> | undefined) => {
|
||||
return prevData?.filter((item) => item.id !== deleteModalData?.id);
|
||||
});
|
||||
}, [ deleteModalData?.id, queryClient ]);
|
||||
|
||||
@@ -9,8 +9,7 @@ import React, { useCallback, useState } from 'react';
|
||||
import type { SubmitHandler, ControllerRenderProps } from 'react-hook-form';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
|
||||
import type { WatchlistErrors } from 'types/api/account';
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress, WatchlistErrors } from 'types/api/account';
|
||||
|
||||
import type { ResourceErrorAccount } from 'lib/api/resources';
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
@@ -28,7 +27,7 @@ const NOTIFICATIONS = [ 'native', 'ERC-20', 'ERC-721' ] as const;
|
||||
const TAG_MAX_LENGTH = 35;
|
||||
|
||||
type Props = {
|
||||
data?: Partial<TWatchlistItem>;
|
||||
data?: Partial<WatchlistAddress>;
|
||||
onSuccess: () => Promise<void>;
|
||||
setAlertVisible: (isAlertVisible: boolean) => void;
|
||||
isAdd: boolean;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import FormModal from 'ui/shared/FormModal';
|
||||
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSuccess: () => Promise<void>;
|
||||
data?: Partial<TWatchlistItem>;
|
||||
data?: Partial<WatchlistAddress>;
|
||||
}
|
||||
|
||||
const AddressModal: React.FC<Props> = ({ isOpen, onClose, onSuccess, data, isAdd }) => {
|
||||
@@ -25,7 +25,7 @@ const AddressModal: React.FC<Props> = ({ isOpen, onClose, onSuccess, data, isAdd
|
||||
}, [ data, isAdd, onSuccess ]);
|
||||
|
||||
return (
|
||||
<FormModal<TWatchlistItem>
|
||||
<FormModal<WatchlistAddress>
|
||||
isOpen={ isOpen }
|
||||
onClose={ onClose }
|
||||
title={ title }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Text } from '@chakra-ui/react';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
@@ -11,7 +11,7 @@ type Props = {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSuccess: () => Promise<void>;
|
||||
data: Pick<TWatchlistItem, 'address_hash' | 'id'>;
|
||||
data: Pick<WatchlistAddress, 'address_hash' | 'id'>;
|
||||
}
|
||||
|
||||
const DeleteAddressModal: React.FC<Props> = ({ isOpen, onClose, onSuccess, data }) => {
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { HStack, VStack, chakra, Flex, Skeleton } from '@chakra-ui/react';
|
||||
import { HStack, VStack, Flex, Skeleton, Text } from '@chakra-ui/react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React from 'react';
|
||||
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import appConfig from 'configs/app/config';
|
||||
import TokensIcon from 'icons/tokens.svg';
|
||||
// import WalletIcon from 'icons/wallet.svg';
|
||||
import WalletIcon from 'icons/wallet.svg';
|
||||
import getCurrencyValue from 'lib/getCurrencyValue';
|
||||
import { nbsp } from 'lib/html-entities';
|
||||
import AddressSnippet from 'ui/shared/AddressSnippet';
|
||||
import Icon from 'ui/shared/chakra/Icon';
|
||||
import CurrencyValue from 'ui/shared/CurrencyValue';
|
||||
import TokenLogo from 'ui/shared/TokenLogo';
|
||||
|
||||
const WatchListAddressItem = ({ item, isLoading }: { item: TWatchlistItem; isLoading?: boolean }) => {
|
||||
const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isLoading?: boolean }) => {
|
||||
const infoItemsPaddingLeft = { base: 1, lg: 8 };
|
||||
|
||||
const nativeTokenData = React.useMemo(() => ({
|
||||
@@ -21,6 +23,8 @@ const WatchListAddressItem = ({ item, isLoading }: { item: TWatchlistItem; isLoa
|
||||
icon_url: '',
|
||||
}), [ ]);
|
||||
|
||||
const { usdBn: usdNative } = getCurrencyValue({ value: item.address_balance, accuracy: 2, accuracyUsd: 2, exchangeRate: item.exchange_rate });
|
||||
|
||||
return (
|
||||
<VStack spacing={ 2 } align="stretch" fontWeight={ 500 }>
|
||||
<AddressSnippet address={ item.address } isLoading={ isLoading }/>
|
||||
@@ -49,21 +53,21 @@ const WatchListAddressItem = ({ item, isLoading }: { item: TWatchlistItem; isLoa
|
||||
<HStack spacing={ 2 } fontSize="sm" pl={ infoItemsPaddingLeft }>
|
||||
<Icon as={ TokensIcon } boxSize={ 5 } isLoading={ isLoading } borderRadius="sm"/>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline-flex">
|
||||
<span>{ `Tokens:${ nbsp }` + item.tokens_count }</span>
|
||||
{ /* api does not provide token prices */ }
|
||||
{ /* <Text variant="secondary">{ `${ nbsp }($${ item.tokensUSD } USD)` }</Text> */ }
|
||||
<chakra.span color="text_secondary">{ `${ nbsp }(N/A)` }</chakra.span>
|
||||
<span>{ `Tokens:${ nbsp }` + item.tokens_count + (item.tokens_overflow ? '+' : '') }</span>
|
||||
<Text variant="secondary" fontWeight={ 400 }>{ `${ nbsp }($${ BigNumber(item.tokens_fiat_value).toFormat(2) })` }</Text>
|
||||
</Skeleton>
|
||||
</HStack>
|
||||
) }
|
||||
{ item.tokens_fiat_value && (
|
||||
<HStack spacing={ 2 } fontSize="sm" pl={ infoItemsPaddingLeft }>
|
||||
<Icon boxSize={ 5 } as={ WalletIcon } isLoading={ isLoading }/>
|
||||
<Skeleton isLoaded={ !isLoading } display="inline-flex">
|
||||
<Text>{ `Net worth:${ nbsp }` }
|
||||
{ `${ item.tokens_overflow ? '>' : '' }$${ BigNumber(item.tokens_fiat_value).plus((BigNumber(usdNative ? usdNative : '0'))).toFormat(2) }` }
|
||||
</Text>
|
||||
</Skeleton>
|
||||
</HStack>
|
||||
) }
|
||||
{ /* api does not provide token prices */ }
|
||||
{ /* { item.address_balance && (
|
||||
<HStack spacing={ 0 } fontSize="sm" h={ 6 } pl={ infoItemsPaddingLeft }>
|
||||
<Icon as={ WalletIcon } mr={ 2 } w="16px" h="16px"/>
|
||||
<Text>{ `Net worth:${ nbsp }` }</Text>
|
||||
<Link href="#">{ `$${ item.totalUSD } USD` }</Link>
|
||||
</HStack>
|
||||
) } */ }
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Box, Switch, Text, HStack, Flex, Skeleton } from '@chakra-ui/react';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
import useToast from 'lib/hooks/useToast';
|
||||
@@ -13,10 +13,10 @@ import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
|
||||
import WatchListAddressItem from './WatchListAddressItem';
|
||||
|
||||
interface Props {
|
||||
item: TWatchlistItem;
|
||||
item: WatchlistAddress;
|
||||
isLoading?: boolean;
|
||||
onEditClick: (data: TWatchlistItem) => void;
|
||||
onDeleteClick: (data: TWatchlistItem) => void;
|
||||
onEditClick: (data: WatchlistAddress) => void;
|
||||
onDeleteClick: (data: WatchlistAddress) => void;
|
||||
}
|
||||
|
||||
const WatchListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props) => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import type { TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import useApiFetch from 'lib/api/useApiFetch';
|
||||
import useToast from 'lib/hooks/useToast';
|
||||
@@ -17,10 +17,10 @@ import TableItemActionButtons from 'ui/shared/TableItemActionButtons';
|
||||
import WatchListAddressItem from './WatchListAddressItem';
|
||||
|
||||
interface Props {
|
||||
item: TWatchlistItem;
|
||||
item: WatchlistAddress;
|
||||
isLoading?: boolean;
|
||||
onEditClick: (data: TWatchlistItem) => void;
|
||||
onDeleteClick: (data: TWatchlistItem) => void;
|
||||
onEditClick: (data: WatchlistAddress) => void;
|
||||
onDeleteClick: (data: WatchlistAddress) => void;
|
||||
}
|
||||
|
||||
const WatchlistTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props) => {
|
||||
|
||||
@@ -7,15 +7,15 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { TWatchlist, TWatchlistItem } from 'types/client/account';
|
||||
import type { WatchlistAddress } from 'types/api/account';
|
||||
|
||||
import WatchlistTableItem from './WatchListTableItem';
|
||||
|
||||
interface Props {
|
||||
data?: TWatchlist;
|
||||
data?: Array<WatchlistAddress>;
|
||||
isLoading?: boolean;
|
||||
onEditClick: (data: TWatchlistItem) => void;
|
||||
onDeleteClick: (data: TWatchlistItem) => void;
|
||||
onEditClick: (data: WatchlistAddress) => void;
|
||||
onDeleteClick: (data: WatchlistAddress) => void;
|
||||
}
|
||||
|
||||
const WatchlistTable = ({ data, isLoading, onDeleteClick, onEditClick }: Props) => {
|
||||
|
||||
Reference in New Issue
Block a user