Commit 67311929 authored by tom's avatar tom

final part

parent bd79698a
......@@ -12,10 +12,13 @@ import type {
AddressTokenTransferFilters,
} from 'types/api/address';
import type { BlocksResponse, BlockTransactionsResponse, Block, BlockFilters } from 'types/api/block';
import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/charts';
import type { IndexingStatus } from 'types/api/indexingStatus';
import type { InternalTransactionsResponse } from 'types/api/internalTransaction';
import type { JsonRpcUrlResponse } from 'types/api/jsonRpcUrl';
import type { LogsResponse } from 'types/api/log';
import type { RawTracesResponse } from 'types/api/rawTrace';
import type { Stats, Charts } from 'types/api/stats';
import type { Stats, Charts, HomeStats } from 'types/api/stats';
import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/tokenTransfer';
import type { TransactionsResponseValidated, TransactionsResponsePending, Transaction } from 'types/api/transaction';
import type { TTxsFilters } from 'types/api/txsFilters';
......@@ -147,6 +150,31 @@ export const RESOURCES = {
filterFields: [ ],
},
// HOMEPAGE
homepage_stats: {
path: '/api/v2/stats',
},
homepage_chart_txs: {
path: '/api/v2/stats/charts/transactions',
},
homepage_chart_market: {
path: '/api/v2/stats/charts/market',
},
homepage_blocks: {
path: '/api/v2/main-page/blocks',
},
homepage_txs: {
path: '/api/v2/main-page/transactions',
},
homepage_indexing_status: {
path: '/api/v2/main-page/indexing-status',
},
// CONFIG
config_json_rpc: {
path: '/api/v2/config/json-rpc-url',
},
// DEPRECATED
old_api: {
path: '/api',
......@@ -190,6 +218,12 @@ Q extends 'private_tags_address' ? AddressTags :
Q extends 'private_tags_tx' ? TransactionTags :
Q extends 'api_keys' ? ApiKeys :
Q extends 'watchlist' ? Array<WatchlistAddress> :
Q extends 'homepage_stats' ? HomeStats :
Q extends 'homepage_chart_txs' ? ChartTransactionResponse :
Q extends 'homepage_chart_market' ? ChartMarketResponse :
Q extends 'homepage_blocks' ? Array<Block> :
Q extends 'homepage_txs' ? Array<Transaction> :
Q extends 'homepage_indexing_status' ? IndexingStatus :
Q extends 'stats_counters' ? Stats :
Q extends 'stats_charts' ? Charts :
Q extends 'blocks' ? BlocksResponse :
......@@ -210,6 +244,7 @@ Q extends 'address_internal_txs' ? AddressInternalTxsResponse :
Q extends 'address_token_transfers' ? AddressTokenTransferResponse :
Q extends 'address_blocks_validated' ? AddressBlocksValidatedResponse :
Q extends 'address_coin_balance' ? AddressCoinBalanceHistoryResponse :
Q extends 'config_json_rpc' ? JsonRpcUrlResponse :
never;
/* eslint-enable @typescript-eslint/indent */
......
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/addresses/${ req.query.id }/blocks-validated${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/addresses/${ req.query.id }/coin-balance-history-by-day`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/addresses/${ req.query.id }/coin-balance-history${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/addresses/${ req.query.id }/counters`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/addresses/${ req.query.id }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/addresses/${ req.query.id }/internal-transactions${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/addresses/${ req.query.id }/token-balances`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/addresses/${ req.query.id }/token-transfers${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/addresses/${ req.query.id }/transactions${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/blocks/${ req.query.id }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/blocks/${ req.query.id }/transactions${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/blocks${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => {
return `/v2/config/json-rpc-url`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/stats/charts/market';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/stats/charts/transactions';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/stats';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/main-page/blocks';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/main-page/indexing-status';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import handler from 'lib/api/handler';
const getUrl = () => '/v2/main-page/transactions';
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/transactions/${ req.query.id }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/transactions/${ req.query.id }/internal-transactions`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/transactions/${ req.query.id }/logs`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
return `/v2/transactions/${ req.query.id }/raw-trace`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/transactions/${ req.query.id }/token-transfers${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
import type { NextApiRequest } from 'next';
import getSearchParams from 'lib/api/getSearchParams';
import handler from 'lib/api/handler';
const getUrl = (req: NextApiRequest) => {
const searchParamsStr = getSearchParams(req);
return `/v2/transactions/${ searchParamsStr ? '?' + searchParamsStr : '' }`;
};
const requestHandler = handler(getUrl, [ 'GET' ]);
export default requestHandler;
// todo_tom DELETE
export enum QueryKeys {
homeStats='homeStats',
indexingStatus='indexingStatus',
stats='stats',
charts='stats',
chartsTxs = 'charts-txs',
chartsMarket = 'charts-market',
indexBlocks='indexBlocks',
indexTxs='indexTxs',
jsonRpcUrl='json-rpc-url',
}
import { Flex, Box, Text, Skeleton } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { HomeStats } from 'types/api/stats';
import { QueryKeys } from 'types/client/queries';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp } from 'lib/html-entities';
import type { Props as PaginationProps } from 'ui/shared/Pagination';
......@@ -18,12 +14,7 @@ interface Props {
const BlocksTabSlot = ({ pagination, isPaginationVisible }: Props) => {
const isMobile = useIsMobile();
const fetch = useFetch();
const statsQuery = useQuery<unknown, unknown, HomeStats>(
[ QueryKeys.homeStats ],
() => fetch('/node-api/home-stats'),
);
const statsQuery = useApiQuery('homepage_stats');
if (isMobile) {
return null;
......
import { Alert, AlertIcon, AlertTitle, chakra } from '@chakra-ui/react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useQueryClient } from '@tanstack/react-query';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { IndexingStatus } from 'types/api/indexingStatus';
import { QueryKeys } from 'types/client/queries';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp, ndash } from 'lib/html-entities';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
const IndexingAlert = ({ className }: { className?: string }) => {
const fetch = useFetch();
const isMobile = useIsMobile();
const { data } = useQuery<unknown, unknown, IndexingStatus>(
[ QueryKeys.indexingStatus ],
async() => await fetch(`/node-api/index/indexing-status`),
);
const { data } = useApiQuery('homepage_indexing_status');
const queryClient = useQueryClient();
const handleBlocksIndexStatus: SocketMessage.BlocksIndexStatus['handler'] = React.useCallback((payload) => {
queryClient.setQueryData([ QueryKeys.indexingStatus ], (prevData: IndexingStatus | undefined) => {
queryClient.setQueryData(getResourceKey('homepage_indexing_status'), (prevData: IndexingStatus | undefined) => {
const newData = prevData ? { ...prevData } : {} as IndexingStatus;
newData.finished_indexing_blocks = payload.finished;
......@@ -46,7 +41,7 @@ const IndexingAlert = ({ className }: { className?: string }) => {
});
const handleIntermalTxsIndexStatus: SocketMessage.InternalTxsIndexStatus['handler'] = React.useCallback((payload) => {
queryClient.setQueryData([ QueryKeys.indexingStatus ], (prevData: IndexingStatus | undefined) => {
queryClient.setQueryData(getResourceKey('homepage_indexing_status'), (prevData: IndexingStatus | undefined) => {
const newData = prevData ? { ...prevData } : {} as IndexingStatus;
newData.finished_indexing = payload.finished;
......
import { Box, Heading, Flex, Link, Text, VStack, Skeleton } from '@chakra-ui/react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useQueryClient } from '@tanstack/react-query';
import { AnimatePresence } from 'framer-motion';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { Block } from 'types/api/block';
import type { HomeStats } from 'types/api/stats';
import { QueryKeys } from 'types/client/queries';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp } from 'lib/html-entities';
import link from 'lib/link/link';
......@@ -24,20 +22,13 @@ const BLOCK_MARGIN = 12;
const LatestBlocks = () => {
const isMobile = useIsMobile();
const blocksMaxCount = isMobile ? 2 : 3;
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, Array<Block>>(
[ QueryKeys.indexBlocks ],
async() => await fetch(`/node-api/index/blocks`),
);
const { data, isLoading, isError } = useApiQuery('homepage_blocks');
const queryClient = useQueryClient();
const statsQueryResult = useQuery<unknown, unknown, HomeStats>(
[ QueryKeys.homeStats ],
() => fetch('/node-api/home-stats'),
);
const statsQueryResult = useApiQuery('homepage_stats');
const handleNewBlockMessage: SocketMessage.NewBlock['handler'] = React.useCallback((payload) => {
queryClient.setQueryData([ QueryKeys.indexBlocks ], (prevData: Array<Block> | undefined) => {
queryClient.setQueryData(getResourceKey('homepage_blocks'), (prevData: Array<Block> | undefined) => {
const newData = prevData ? [ ...prevData ] : [];
......
import { Box, Heading, Flex, Link, Text, Skeleton } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { Transaction } from 'types/api/transaction';
import { QueryKeys } from 'types/client/queries';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
import link from 'lib/link/link';
import TxsNewItemNotice from 'ui/txs/TxsNewItemNotice';
......@@ -16,11 +12,7 @@ import LatestTxsItemSkeleton from './LatestTxsItemSkeleton';
const LatestTransactions = () => {
const isMobile = useIsMobile();
const txsCount = isMobile ? 2 : 6;
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, Array<Transaction>>(
[ QueryKeys.indexTxs ],
async() => await fetch(`/node-api/index/txs`),
);
const { data, isLoading, isError } = useApiQuery('homepage_txs');
let content;
......
import { Grid } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { HomeStats } from 'types/api/stats';
import { QueryKeys } from 'types/client/queries';
import appConfig from 'configs/app/config';
import blockIcon from 'icons/block.svg';
import clockIcon from 'icons/clock-light.svg';
import gasIcon from 'icons/gas.svg';
import txIcon from 'icons/transactions.svg';
import walletIcon from 'icons/wallet.svg';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import link from 'lib/link/link';
import StatsGasPrices from './StatsGasPrices';
......@@ -26,12 +22,7 @@ let itemsCount = 5;
!hasAvgBlockTime && itemsCount--;
const Stats = () => {
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, HomeStats>(
[ QueryKeys.homeStats ],
async() => await fetch(`/node-api/home-stats`),
);
const { data, isLoading, isError } = useApiQuery('homepage_stats');
if (isError) {
return null;
......
import { Box, Flex, Icon, Skeleton, Text, Tooltip, useColorModeValue } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { HomeStats } from 'types/api/stats';
import { QueryKeys } from 'types/client/queries';
import appConfig from 'configs/app/config';
import infoIcon from 'icons/info.svg';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import ChainIndicatorChartContainer from './ChainIndicatorChartContainer';
import ChainIndicatorItem from './ChainIndicatorItem';
......@@ -32,13 +28,8 @@ const ChainIndicators = () => {
const [ selectedIndicator, selectIndicator ] = React.useState(indicators[0]?.id);
const indicator = indicators.find(({ id }) => id === selectedIndicator);
const queryResult = useFetchChartData(indicator);
const fetch = useFetch();
const statsQueryResult = useQuery<unknown, unknown, HomeStats>(
[ QueryKeys.homeStats ],
() => fetch('/node-api/home-stats'),
);
const queryResult = useFetchChartData(indicator!);
const statsQueryResult = useApiQuery('homepage_stats');
const bgColorDesktop = useColorModeValue('white', 'gray.900');
const bgColorMobile = useColorModeValue('white', 'black');
......
import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/charts';
import type { HomeStats } from 'types/api/stats';
import type { QueryKeys } from 'types/client/queries';
import type { TimeChartData } from 'ui/shared/chart/types';
export type ChartsQueryKeys = QueryKeys.chartsTxs | QueryKeys.chartsMarket;
import type { ResourcePayload } from 'lib/api/resources';
export type ChartsResources = 'homepage_chart_txs' | 'homepage_chart_market';
export type ChainIndicatorId = 'daily_txs' | 'coin_price' | 'market_cup';
export interface TChainIndicator<Q extends ChartsQueryKeys> {
export interface TChainIndicator<R extends ChartsResources> {
id: ChainIndicatorId;
title: string;
value: (stats: HomeStats) => string;
icon: React.ReactNode;
hint?: string;
api: {
queryName: Q;
path: string;
dataFn: (response: ChartsResponse<Q>) => TimeChartData;
resourceName: R;
dataFn: (response: ResourcePayload<R>) => TimeChartData;
};
}
export type ChartsResponse<Q extends ChartsQueryKeys> =
Q extends QueryKeys.chartsTxs ? ChartTransactionResponse :
Q extends QueryKeys.chartsMarket ? ChartMarketResponse :
never;
import type { UseQueryResult } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { TChainIndicator, ChartsResponse, ChartsQueryKeys } from './types';
import type { TChainIndicator, ChartsResources } from './types';
import type { TimeChartData } from 'ui/shared/chart/types';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
type NotUndefined<T> = T extends undefined ? never : T;
export default function useFetchChartData<Q extends ChartsQueryKeys>(indicator: TChainIndicator<Q> | undefined): UseQueryResult<TimeChartData> {
const fetch = useFetch();
type ResponseType = ChartsResponse<NotUndefined<typeof indicator>['api']['queryName']>;
const queryResult = useQuery<unknown, unknown, ResponseType>(
[ indicator?.api.queryName ],
() => fetch(indicator?.api.path || ''),
{ enabled: Boolean(indicator) },
);
export default function useFetchChartData<R extends ChartsResources>(indicator: TChainIndicator<R>): UseQueryResult<TimeChartData> {
const queryResult = useApiQuery(indicator.api.resourceName, {
queryOptions: { enabled: Boolean(indicator) },
});
return React.useMemo(() => {
return {
......
......@@ -2,7 +2,6 @@ import { Icon } from '@chakra-ui/react';
import React from 'react';
import type { TChainIndicator } from '../types';
import { QueryKeys } from 'types/client/queries';
import appConfig from 'configs/app/config';
import globeIcon from 'icons/globe.svg';
......@@ -11,15 +10,14 @@ import { shortenNumberWithLetter } from 'lib/formatters';
import { sortByDateDesc } from 'ui/shared/chart/utils/sorts';
import TokenLogo from 'ui/shared/TokenLogo';
const dailyTxsIndicator: TChainIndicator<QueryKeys.chartsTxs> = {
const dailyTxsIndicator: TChainIndicator<'homepage_chart_txs'> = {
id: 'daily_txs',
title: 'Daily transactions',
value: (stats) => shortenNumberWithLetter(Number(stats.transactions_today), undefined, { maximumFractionDigits: 2 }),
icon: <Icon as={ txIcon } boxSize={ 6 } bgColor="#56ACD1" borderRadius="base" color="white"/>,
hint: `The total daily number of transactions on the blockchain for the last month.`,
api: {
queryName: QueryKeys.chartsTxs,
path: '/node-api/home-stats/charts/transactions',
resourceName: 'homepage_chart_txs',
dataFn: (response) => ([ {
items: response.chart_data
.map((item) => ({ date: new Date(item.date), value: item.tx_count }))
......@@ -30,15 +28,14 @@ const dailyTxsIndicator: TChainIndicator<QueryKeys.chartsTxs> = {
},
};
const coinPriceIndicator: TChainIndicator<QueryKeys.chartsMarket> = {
const coinPriceIndicator: TChainIndicator<'homepage_chart_market'> = {
id: 'coin_price',
title: `${ appConfig.network.currency.symbol } price`,
value: (stats) => '$' + Number(stats.coin_price).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 6 }),
icon: <TokenLogo hash={ appConfig.network.currency.address || '' } name={ appConfig.network.currency.name } boxSize={ 6 }/>,
hint: `${ appConfig.network.currency.symbol } token daily price in USD.`,
api: {
queryName: QueryKeys.chartsMarket,
path: '/node-api/home-stats/charts/market',
resourceName: 'homepage_chart_market',
dataFn: (response) => ([ {
items: response.chart_data
.map((item) => ({ date: new Date(item.date), value: Number(item.closing_price) }))
......@@ -49,7 +46,7 @@ const coinPriceIndicator: TChainIndicator<QueryKeys.chartsMarket> = {
},
};
const marketPriceIndicator: TChainIndicator<QueryKeys.chartsMarket> = {
const marketPriceIndicator: TChainIndicator<'homepage_chart_market'> = {
id: 'market_cup',
title: 'Market cap',
value: (stats) => '$' + shortenNumberWithLetter(Number(stats.market_cap), undefined, { maximumFractionDigits: 0 }),
......@@ -57,8 +54,7 @@ const marketPriceIndicator: TChainIndicator<QueryKeys.chartsMarket> = {
// eslint-disable-next-line max-len
hint: 'The total market value of a cryptocurrency\'s circulating supply. It is analogous to the free-float capitalization in the stock market. Market Cap = Current Price x Circulating Supply.',
api: {
queryName: QueryKeys.chartsMarket,
path: '/node-api/home-stats/charts/market',
resourceName: 'homepage_chart_market',
dataFn: (response) => ([ {
items: response.chart_data
.map((item) => ({ date: new Date(item.date), value: Number(item.closing_price) * Number(response.available_supply) }))
......
import { Box, Icon, Link } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React from 'react';
import type { JsonRpcUrlResponse } from 'types/api/jsonRpcUrl';
import config from 'configs/app/config';
import PlusIcon from 'icons/plus.svg';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import AppList from 'ui/apps/AppList';
import AppListSkeleton from 'ui/apps/AppListSkeleton';
import CategoriesMenu from 'ui/apps/CategoriesMenu';
......@@ -15,8 +12,6 @@ import FilterInput from 'ui/shared/FilterInput';
import useMarketplaceApps from '../apps/useMarketplaceApps';
const Apps = () => {
const fetch = useFetch();
const {
isLoading,
category,
......@@ -30,10 +25,7 @@ const Apps = () => {
handleFavoriteClick,
} = useMarketplaceApps();
useQuery<unknown, unknown, JsonRpcUrlResponse>(
[ 'json-rpc-url' ],
async() => await fetch(`/node-api/config/json-rpc-url`),
);
useApiQuery('config_json_rpc');
return (
<>
......
import { Box, Center, useColorMode } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import type { JsonRpcUrlResponse } from 'types/api/jsonRpcUrl';
import type { AppItemOverview } from 'types/client/apps';
import { QueryKeys } from 'types/client/queries';
import appConfig from 'configs/app/config';
import useFetch from 'lib/hooks/useFetch';
import useApiQuery from 'lib/api/useApiQuery';
import link from 'lib/link/link';
import ContentLoader from 'ui/shared/ContentLoader';
import Page from 'ui/shared/Page/Page';
......@@ -20,18 +17,15 @@ type Props = {
const MarketplaceApp = ({ app, isLoading }: Props) => {
const [ isFrameLoading, setIsFrameLoading ] = useState(isLoading);
const { colorMode } = useColorMode();
const fetch = useFetch();
const ref = useRef<HTMLIFrameElement>(null);
const handleIframeLoad = useCallback(() => {
setIsFrameLoading(false);
}, []);
const { data: jsonRpcUrlResponse } = useQuery<unknown, unknown, JsonRpcUrlResponse>(
[ QueryKeys.jsonRpcUrl ],
async() => await fetch(`/node-api/config/json-rpc-url`),
{ refetchOnMount: false },
);
const { data: jsonRpcUrlResponse } = useApiQuery('config_json_rpc', {
queryOptions: { refetchOnMount: false },
});
useEffect(() => {
if (app && !isFrameLoading) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment