Commit eb0b8e25 authored by tom's avatar tom

rewrite useNetwork

parent 7e905443
...@@ -10,8 +10,12 @@ const config = Object.freeze({ ...@@ -10,8 +10,12 @@ const config = Object.freeze({
logo: process.env.NEXT_PUBLIC_NETWORK_LOGO, logo: process.env.NEXT_PUBLIC_NETWORK_LOGO,
name: process.env.NEXT_PUBLIC_NETWORK_NAME, name: process.env.NEXT_PUBLIC_NETWORK_NAME,
shortName: process.env.NEXT_PUBLIC_NETWORK_SHORT_NAME, shortName: process.env.NEXT_PUBLIC_NETWORK_SHORT_NAME,
currency: process.env.NEXT_PUBLIC_NETWORK_CURRENCY,
assetsPathname: process.env.NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME,
nativeTokenAddress: process.env.NEXT_PUBLIC_NETWORK_TOKEN_ADDRESS,
basePath: '/' + [ process.env.NEXT_PUBLIC_NETWORK_TYPE, process.env.NEXT_PUBLIC_NETWORK_SUBTYPE ].filter(Boolean).join('/'), basePath: '/' + [ process.env.NEXT_PUBLIC_NETWORK_TYPE, process.env.NEXT_PUBLIC_NETWORK_SUBTYPE ].filter(Boolean).join('/'),
}, },
isAccountSupported: process.env.NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED === 'true',
// TODO domain should be passed in CI during runtime // TODO domain should be passed in CI during runtime
domain: isDev ? 'http://localhost:3000' : 'https://blockscout.com', domain: isDev ? 'http://localhost:3000' : 'https://blockscout.com',
}); });
......
import { useRouter } from 'next/router';
import findNetwork from 'lib/networks/findNetwork';
export default function useNetwork() {
const router = useRouter();
const selectedNetwork = findNetwork({
network_type: typeof router.query.network_type === 'string' ? router.query.network_type : '',
network_sub_type: typeof router.query.network_sub_type === 'string' ? router.query.network_sub_type : undefined,
});
return selectedNetwork;
}
// todo_tom delete this
import type { Network } from 'types/networks';
import arbitrumIcon from 'icons/networks/icons/arbitrum.svg';
import artisIcon from 'icons/networks/icons/artis.svg';
import ethereumClassicIcon from 'icons/networks/icons/ethereum-classic.svg';
import ethereumIcon from 'icons/networks/icons/ethereum.svg';
import gnosisIcon from 'icons/networks/icons/gnosis.svg';
import optimismIcon from 'icons/networks/icons/optimism.svg';
import poaSokolIcon from 'icons/networks/icons/poa-sokol.svg';
import poaIcon from 'icons/networks/icons/poa.svg';
import rskIcon from 'icons/networks/icons/rsk.svg';
import parseNetworkConfig from './parseNetworkConfig';
// will change later when we agree how to host network icons
const ICONS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGElement>>> = {
'xdai/mainnet': gnosisIcon,
'xdai/optimism': optimismIcon,
'xdai/aox': arbitrumIcon,
'eth/mainnet': ethereumIcon,
'etc/mainnet': ethereumClassicIcon,
'poa/core': poaIcon,
'rsk/mainnet': rskIcon,
'xdai/testnet': arbitrumIcon,
'poa/sokol': poaSokolIcon,
'artis/sigma1': artisIcon,
};
const LOGOS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGElement>>> = {
'xdai/mainnet': require('icons/networks/logos/gnosis.svg'),
'eth/mainnet': require('icons/networks/logos/eth.svg'),
'etc/mainnet': require('icons/networks/logos/etc.svg'),
'poa/core': require('icons/networks/logos/poa.svg'),
'rsk/mainnet': require('icons/networks/logos/rsk.svg'),
'xdai/testnet': require('icons/networks/logos/gnosis.svg'),
'poa/sokol': require('icons/networks/logos/sokol.svg'),
'artis/sigma1': require('icons/networks/logos/artis.svg'),
'lukso/l14': require('icons/networks/logos/lukso.svg'),
astar: require('icons/networks/logos/astar.svg'),
shiden: require('icons/networks/logos/shiden.svg'),
shibuya: require('icons/networks/logos/shibuya.svg'),
};
const NETWORKS: Array<Network> = (() => {
const networksFromConfig: Array<Network> = parseNetworkConfig();
return networksFromConfig.map((network) => ({
...network,
logo: network.logo || LOGOS[network.type + (network.subType ? `/${ network.subType }` : '')],
icon: network.icon || ICONS[network.type + (network.subType ? `/${ network.subType }` : '')],
}));
})();
export default NETWORKS;
// for easy .env.example update
// const FEATURED_CHAINS = JSON.stringify([
// {
// title: 'Gnosis Chain',
// basePath: '/xdai/mainnet',
// group: 'mainnets',
// },
// {
// name: 'Optimism on Gnosis Chain',
// basePath: '/xdai/optimism',
// group: 'mainnets',
// icon: 'https://www.fillmurray.com/60/60',
// },
// {
// name: 'Arbitrum on xDai',
// basePath: '/xdai/aox',
// group: 'mainnets',
// },
// {
// name: 'Ethereum',
// basePath: '/eth/mainnet',
// group: 'mainnets',
// },
// {
// name: 'Ethereum Classic',
// basePath: '/etx/mainnet',
// group: 'mainnets',
// },
// {
// name: 'POA',
// basePath: '/poa/core',
// group: 'mainnets',
// },
// {
// name: 'RSK',
// basePath: '/rsk/mainnet',
// group: 'mainnets',
// },
// {
// name: 'Gnosis Chain Testnet',
// basePath: '/xdai/testnet',
// group: 'testnets',
// },
// {
// name: 'POA Sokol',
// basePath: '/poa/sokol',
// group: 'testnets',
// },
// {
// name: 'ARTIS Σ1',
// basePath: '/artis/sigma1',
// group: 'other',
// },
// {
// name: 'LUKSO L14',
// basePath: '/lukso/l14',
// group: 'other',
// },
// {
// name: 'Astar',
// basePath: '/astar',
// group: 'other',
// },
// ]);
// todo_tom delete this
import availableNetworks from 'lib/networks/availableNetworks';
interface Params {
network_type: string;
network_sub_type?: string;
}
export default function findNetwork(params: Params) {
return availableNetworks.find((network) =>
network.type === params.network_type &&
network.subType ? network.subType === params.network_sub_type : network.type === params.network_type,
);
}
...@@ -2,26 +2,9 @@ import type { FunctionComponent, SVGAttributes } from 'react'; ...@@ -2,26 +2,9 @@ import type { FunctionComponent, SVGAttributes } from 'react';
export type NetworkGroup = 'mainnets' | 'testnets' | 'other'; export type NetworkGroup = 'mainnets' | 'testnets' | 'other';
// todo_tom delete this
export interface Network {
name: string;
chainId: number; // https://chainlist.org/
currency: string;
nativeTokenAddress: string;
shortName?: string;
// basePath = /<type>/<subType>, e.g. /xdai/mainnet
type: string;
subType?: string;
group: 'mainnets' | 'testnets' | 'other';
icon?: FunctionComponent<SVGAttributes<SVGElement>> | string;
logo?: FunctionComponent<SVGAttributes<SVGElement>> | string;
isAccountSupported?: boolean;
assetsNamePath?: string;
}
export interface FeaturedNetwork { export interface FeaturedNetwork {
title: string; title: string;
basePath: string; basePath: string;
group: 'mainnets' | 'testnets' | 'other'; group: NetworkGroup;
icon?: FunctionComponent<SVGAttributes<SVGElement>> | string; icon?: FunctionComponent<SVGAttributes<SVGElement>> | string;
} }
import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react'; import { Grid, GridItem, Text, Icon, Link, Box, Tooltip } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
...@@ -7,7 +8,6 @@ import { block } from 'data/block'; ...@@ -7,7 +8,6 @@ import { block } from 'data/block';
import clockIcon from 'icons/clock.svg'; import clockIcon from 'icons/clock.svg';
import flameIcon from 'icons/flame.svg'; import flameIcon from 'icons/flame.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useNetwork from 'lib/hooks/useNetwork';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
...@@ -23,7 +23,6 @@ const BlockDetails = () => { ...@@ -23,7 +23,6 @@ const BlockDetails = () => {
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
const link = useLink(); const link = useLink();
const router = useRouter(); const router = useRouter();
const network = useNetwork();
const handleCutClick = React.useCallback(() => { const handleCutClick = React.useCallback(() => {
setIsExpanded((flag) => !flag); setIsExpanded((flag) => !flag);
...@@ -79,7 +78,7 @@ const BlockDetails = () => { ...@@ -79,7 +78,7 @@ const BlockDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Block reward" title="Block reward"
hint={ hint={
`For each block, the miner is rewarded with a finite amount of ${ network?.currency || 'native token' } `For each block, the miner is rewarded with a finite amount of ${ appConfig.network.currency || 'native token' }
on top of the fees paid for all transactions in the block.` on top of the fees paid for all transactions in the block.`
} }
columnGap={ 1 } columnGap={ 1 }
...@@ -120,15 +119,16 @@ const BlockDetails = () => { ...@@ -120,15 +119,16 @@ const BlockDetails = () => {
title="Base fee per gas" title="Base fee per gas"
hint="Minimum fee required per unit of gas. Fee adjusts based on network congestion." hint="Minimum fee required per unit of gas. Fee adjusts based on network congestion."
> >
<Text>{ (block.base_fee_per_gas / 10 ** 9).toLocaleString('en', { minimumFractionDigits: 18 }) } { network?.currency } </Text> <Text>{ (block.base_fee_per_gas / 10 ** 9).toLocaleString('en', { minimumFractionDigits: 18 }) } { appConfig.network.currency } </Text>
<Text variant="secondary" whiteSpace="pre">{ space }({ block.base_fee_per_gas.toLocaleString('en', { minimumFractionDigits: 9 }) } Gwei)</Text> <Text variant="secondary" whiteSpace="pre">{ space }({ block.base_fee_per_gas.toLocaleString('en', { minimumFractionDigits: 9 }) } Gwei)</Text>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Burnt fees" title="Burnt fees"
hint={ `Amount of ${ network?.currency || 'native token' } burned from transactions included in the block. Equals Block Base Fee per Gas * Gas Used.` } hint={ `Amount of ${ appConfig.network.currency || 'native token' } burned from transactions included in the block.
Equals Block Base Fee per Gas * Gas Used.` }
> >
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/> <Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/>
<Text ml={ 1 }>{ block.burnt_fees.toLocaleString('en', { minimumFractionDigits: 18 }) } { network?.currency }</Text> <Text ml={ 1 }>{ block.burnt_fees.toLocaleString('en', { minimumFractionDigits: 18 }) } { appConfig.network.currency }</Text>
<Tooltip label="Burnt fees / Txn fees * 100%"> <Tooltip label="Burnt fees / Txn fees * 100%">
<Box> <Box>
<Utilization ml={ 4 } value={ block.burnt_fees / block.reward.tx_fee }/> <Utilization ml={ 4 } value={ block.burnt_fees / block.reward.tx_fee }/>
......
import { Flex, Link, Spinner, Text, Box, Icon, useColorModeValue } from '@chakra-ui/react'; import { Flex, Link, Spinner, Text, Box, Icon, useColorModeValue } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type ArrayElement from 'types/utils/ArrayElement'; import type ArrayElement from 'types/utils/ArrayElement';
...@@ -6,7 +7,6 @@ import type ArrayElement from 'types/utils/ArrayElement'; ...@@ -6,7 +7,6 @@ import type ArrayElement from 'types/utils/ArrayElement';
import type { blocks } from 'data/blocks'; import type { blocks } from 'data/blocks';
import flameIcon from 'icons/flame.svg'; import flameIcon from 'icons/flame.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useNetwork from 'lib/hooks/useNetwork';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import AccountListItemMobile from 'ui/shared/AccountListItemMobile'; import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
...@@ -21,7 +21,6 @@ interface Props { ...@@ -21,7 +21,6 @@ interface Props {
const BlocksListItem = ({ data, isPending }: Props) => { const BlocksListItem = ({ data, isPending }: Props) => {
const spinnerEmptyColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200'); const spinnerEmptyColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
const link = useLink(); const link = useLink();
const network = useNetwork();
return ( return (
<AccountListItemMobile rowGap={ 3 }> <AccountListItemMobile rowGap={ 3 }>
...@@ -58,7 +57,7 @@ const BlocksListItem = ({ data, isPending }: Props) => { ...@@ -58,7 +57,7 @@ const BlocksListItem = ({ data, isPending }: Props) => {
</Flex> </Flex>
</Box> </Box>
<Flex columnGap={ 2 }> <Flex columnGap={ 2 }>
<Text fontWeight={ 500 }>Reward { network?.currency }</Text> <Text fontWeight={ 500 }>Reward { appConfig.network.currency }</Text>
<Text variant="secondary">{ (data.reward.static + data.reward.tx_fee - data.burnt_fees).toLocaleString('en', { maximumFractionDigits: 5 }) }</Text> <Text variant="secondary">{ (data.reward.static + data.reward.tx_fee - data.burnt_fees).toLocaleString('en', { maximumFractionDigits: 5 }) }</Text>
</Flex> </Flex>
<Flex> <Flex>
......
import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react'; import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import { blocks } from 'data/blocks'; import { blocks } from 'data/blocks';
import useNetwork from 'lib/hooks/useNetwork';
import BlocksTableItem from 'ui/blocks/BlocksTableItem'; import BlocksTableItem from 'ui/blocks/BlocksTableItem';
const BlocksTable = () => { const BlocksTable = () => {
const network = useNetwork();
return ( return (
<TableContainer width="100%" mt={ 8 }> <TableContainer width="100%" mt={ 8 }>
...@@ -18,8 +17,8 @@ const BlocksTable = () => { ...@@ -18,8 +17,8 @@ const BlocksTable = () => {
<Th width="144px">Miner</Th> <Th width="144px">Miner</Th>
<Th width="64px" isNumeric>Txn</Th> <Th width="64px" isNumeric>Txn</Th>
<Th width="40%">Gas used</Th> <Th width="40%">Gas used</Th>
<Th width="30%">Reward { network?.currency }</Th> <Th width="30%">Reward { appConfig.network.currency }</Th>
<Th width="30%">Burnt fees { network?.currency }</Th> <Th width="30%">Burnt fees { appConfig.network.currency }</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
......
import { VStack, Textarea, Button, Alert, AlertTitle, AlertDescription, Link, Code } from '@chakra-ui/react'; import { VStack, Textarea, Button, Alert, AlertTitle, AlertDescription, Link, Code } from '@chakra-ui/react';
import * as Sentry from '@sentry/react'; import * as Sentry from '@sentry/react';
import appConfig from 'configs/app/config';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import type { ChangeEvent } from 'react'; import type { ChangeEvent } from 'react';
import React from 'react'; import React from 'react';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useNetwork from 'lib/hooks/useNetwork';
import useToast from 'lib/hooks/useToast'; import useToast from 'lib/hooks/useToast';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
const Home = () => { const Home = () => {
const router = useRouter(); const router = useRouter();
const selectedNetwork = useNetwork();
const toast = useToast(); const toast = useToast();
const [ isFormVisible, setFormVisibility ] = React.useState(false); const [ isFormVisible, setFormVisibility ] = React.useState(false);
...@@ -20,8 +19,8 @@ const Home = () => { ...@@ -20,8 +19,8 @@ const Home = () => {
React.useEffect(() => { React.useEffect(() => {
const token = cookies.get(cookies.NAMES.API_TOKEN); const token = cookies.get(cookies.NAMES.API_TOKEN);
setFormVisibility(Boolean(!token && selectedNetwork?.isAccountSupported)); setFormVisibility(Boolean(!token && appConfig.isAccountSupported));
}, [ selectedNetwork?.isAccountSupported ]); }, []);
const checkSentry = React.useCallback(() => { const checkSentry = React.useCallback(() => {
Sentry.captureException(new Error('Test error'), { extra: { foo: 'bar' }, tags: { source: 'test' } }); Sentry.captureException(new Error('Test error'), { extra: { foo: 'bar' }, tags: { source: 'test' } });
...@@ -53,7 +52,7 @@ const Home = () => { ...@@ -53,7 +52,7 @@ const Home = () => {
<Page> <Page>
<VStack gap={ 4 } alignItems="flex-start" maxW="800px"> <VStack gap={ 4 } alignItems="flex-start" maxW="800px">
<PageTitle text={ <PageTitle text={
`Home Page for ${ selectedNetwork?.name } network` `Home Page for ${ appConfig.network.name } network`
}/> }/>
<Button colorScheme="red" onClick={ checkSentry }>Check Sentry</Button> <Button colorScheme="red" onClick={ checkSentry }>Check Sentry</Button>
{ /* will be deleted when we move to new CI */ } { /* will be deleted when we move to new CI */ }
......
import { Image, chakra } from '@chakra-ui/react'; import { Image, chakra } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type { Network } from 'types/networks';
import useNetwork from 'lib/hooks/useNetwork';
const EmptyElement = () => null; const EmptyElement = () => null;
const ASSETS_PATH_MAP: Record<string, string> = {
'xdai/mainnet': 'xdai',
'xdai/testnet': 'xdai',
'xdai/optimism': 'optimism',
'xdai/aox': 'arbitrum',
'eth/mainnet': 'ethereum',
'etc/mainnet': 'classic',
'poa/core': 'poa',
};
const getAssetsPath = (network: Network) => {
if (network.assetsNamePath) {
return network.assetsNamePath;
}
const key = [ network.type, network.subType ].filter(Boolean).join('/');
const nameFromMap = ASSETS_PATH_MAP[key];
return nameFromMap || network.type;
};
interface Props { interface Props {
hash: string; hash: string;
name: string; name?: string;
className?: string; className?: string;
} }
const TokenLogo = ({ hash, name, className }: Props) => { const TokenLogo = ({ hash, name, className }: Props) => {
const network = useNetwork(); const logoSrc = `https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/${ appConfig.network.assetsPathname }/assets/${ hash }/logo.png`;
if (!network) {
return null;
}
const assetsPath = getAssetsPath(network);
const logoSrc = `https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/${ assetsPath }/assets/${ hash }/logo.png`;
return <Image className={ className } src={ logoSrc } alt={ `${ name } logo` } fallback={ <EmptyElement/> }/>; return <Image className={ className } src={ logoSrc } alt={ `${ name || 'token' } logo` } fallback={ <EmptyElement/> }/>;
}; };
export default React.memo(chakra(TokenLogo)); export default React.memo(chakra(TokenLogo));
import { Flex, Box, VStack, Icon, useColorModeValue } from '@chakra-ui/react'; import { Flex, Box, VStack, Icon, useColorModeValue } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import chevronIcon from 'icons/arrows/east-mini.svg'; import chevronIcon from 'icons/arrows/east-mini.svg';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useNavItems from 'lib/hooks/useNavItems'; import useNavItems from 'lib/hooks/useNavItems';
import useNetwork from 'lib/hooks/useNetwork';
import isBrowser from 'lib/isBrowser'; import isBrowser from 'lib/isBrowser';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo';
...@@ -15,7 +15,6 @@ import NavLink from './NavLink'; ...@@ -15,7 +15,6 @@ import NavLink from './NavLink';
const NavigationDesktop = () => { const NavigationDesktop = () => {
const { mainNavItems, accountNavItems } = useNavItems(); const { mainNavItems, accountNavItems } = useNavItems();
const selectedNetwork = useNetwork();
const isInBrowser = isBrowser(); const isInBrowser = isBrowser();
const [ hasAccount, setHasAccount ] = React.useState(false); const [ hasAccount, setHasAccount ] = React.useState(false);
...@@ -31,9 +30,9 @@ const NavigationDesktop = () => { ...@@ -31,9 +30,9 @@ const NavigationDesktop = () => {
if (navBarCollapsedCookie === 'false') { if (navBarCollapsedCookie === 'false') {
setCollapsedState(false); setCollapsedState(false);
} }
setHasAccount(Boolean(selectedNetwork?.isAccountSupported && isAuth && isInBrowser)); setHasAccount(Boolean(appConfig.isAccountSupported && isAuth && isInBrowser));
} }
}, [ isInBrowser, selectedNetwork?.isAccountSupported ]); }, [ isInBrowser ]);
const handleTogglerClick = React.useCallback(() => { const handleTogglerClick = React.useCallback(() => {
setCollapsedState((flag) => !flag); setCollapsedState((flag) => !flag);
......
import { Box, VStack } from '@chakra-ui/react'; import { Box, VStack } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useNavItems from 'lib/hooks/useNavItems'; import useNavItems from 'lib/hooks/useNavItems';
import useNetwork from 'lib/hooks/useNetwork';
import NavFooter from 'ui/snippets/navigation/NavFooter'; import NavFooter from 'ui/snippets/navigation/NavFooter';
import NavLink from 'ui/snippets/navigation/NavLink'; import NavLink from 'ui/snippets/navigation/NavLink';
const NavigationMobile = () => { const NavigationMobile = () => {
const { mainNavItems, accountNavItems } = useNavItems(); const { mainNavItems, accountNavItems } = useNavItems();
const selectedNetwork = useNetwork();
const isAuth = Boolean(cookies.get(cookies.NAMES.API_TOKEN)); const isAuth = Boolean(cookies.get(cookies.NAMES.API_TOKEN));
const hasAccount = selectedNetwork?.isAccountSupported && isAuth; const hasAccount = appConfig.isAccountSupported && isAuth;
return ( return (
<> <>
......
import { Icon, Box, Image, useColorModeValue } from '@chakra-ui/react'; import { Icon, Box, Image, useColorModeValue } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import NextLink from 'next/link'; import NextLink from 'next/link';
import React from 'react'; import React from 'react';
import type { FunctionComponent, SVGAttributes } from 'react'; import type { FunctionComponent, SVGAttributes } from 'react';
import blockscoutLogo from 'icons/logo.svg'; import blockscoutLogo from 'icons/logo.svg';
import useNetwork from 'lib/hooks/useNetwork';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
// predefined network logos
const LOGOS: Record<string, React.FunctionComponent<React.SVGAttributes<SVGElement>>> = {
'/xdai/mainnet': require('icons/networks/logos/gnosis.svg'),
'/eth/mainnet': require('icons/networks/logos/eth.svg'),
'/etc/mainnet': require('icons/networks/logos/etc.svg'),
'/poa/core': require('icons/networks/logos/poa.svg'),
'/rsk/mainnet': require('icons/networks/logos/rsk.svg'),
'/xdai/testnet': require('icons/networks/logos/gnosis.svg'),
'/poa/sokol': require('icons/networks/logos/sokol.svg'),
'/artis/sigma1': require('icons/networks/logos/artis.svg'),
'/lukso/l14': require('icons/networks/logos/lukso.svg'),
'/astar': require('icons/networks/logos/astar.svg'),
'/shiden': require('icons/networks/logos/shiden.svg'),
'/shibuya': require('icons/networks/logos/shibuya.svg'),
};
interface Props { interface Props {
isCollapsed?: boolean; isCollapsed?: boolean;
onClick?: (event: React.SyntheticEvent) => void; onClick?: (event: React.SyntheticEvent) => void;
...@@ -17,8 +33,7 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => { ...@@ -17,8 +33,7 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
const logoColor = useColorModeValue('blue.600', 'white'); const logoColor = useColorModeValue('blue.600', 'white');
const link = useLink(); const link = useLink();
const href = link('network_index'); const href = link('network_index');
const network = useNetwork(); const logo = appConfig.network.logo || LOGOS[appConfig.network.basePath];
const logo = network?.logo;
const style = useColorModeValue({}, { filter: 'brightness(0) invert(1)' }); const style = useColorModeValue({}, { filter: 'brightness(0) invert(1)' });
...@@ -29,7 +44,7 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => { ...@@ -29,7 +44,7 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
<Image <Image
h="20px" h="20px"
src={ logo } src={ logo }
alt={ `${ network.type } ${ network.subType ? network.subType : '' } network icon` } alt={ `${ appConfig.network.name } network icon` }
/> />
); );
} else if (typeof logo !== undefined) { } else if (typeof logo !== undefined) {
......
import { PopoverContent, PopoverBody, Text, Tabs, TabList, TabPanels, TabPanel, Tab, VStack } from '@chakra-ui/react'; import { PopoverContent, PopoverBody, Text, Tabs, TabList, TabPanels, TabPanel, Tab, VStack } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type { NetworkGroup } from 'types/networks'; import type { NetworkGroup } from 'types/networks';
import useNetwork from 'lib/hooks/useNetwork';
import featuredNetworks from 'lib/networks/featuredNetworks'; import featuredNetworks from 'lib/networks/featuredNetworks';
import useNetworkNavigationItems from 'lib/networks/useNetworkNavigationItems'; import useNetworkNavigationItems from 'lib/networks/useNetworkNavigationItems';
...@@ -13,8 +13,8 @@ const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ]; ...@@ -13,8 +13,8 @@ const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ];
const availableTabs = TABS.filter((tab) => featuredNetworks.some(({ group }) => group === tab)); const availableTabs = TABS.filter((tab) => featuredNetworks.some(({ group }) => group === tab));
const NetworkMenuPopup = () => { const NetworkMenuPopup = () => {
const selectedNetwork = useNetwork();
const items = useNetworkNavigationItems(); const items = useNetworkNavigationItems();
const selectedNetwork = featuredNetworks.find((network) => network.basePath === appConfig.network.basePath);
const selectedTab = availableTabs.findIndex((tab) => selectedNetwork?.group === tab); const selectedTab = availableTabs.findIndex((tab) => selectedNetwork?.group === tab);
return ( return (
......
import { Box, Select, VStack } from '@chakra-ui/react'; import { Box, Select, VStack } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import capitalize from 'lodash/capitalize'; import capitalize from 'lodash/capitalize';
import React from 'react'; import React from 'react';
import type { NetworkGroup } from 'types/networks'; import type { NetworkGroup } from 'types/networks';
import useNetwork from 'lib/hooks/useNetwork'; import featuredNetworks from 'lib/networks/featuredNetworks';
import useNetworkNavigationItems from 'lib/networks/useNetworkNavigationItems'; import useNetworkNavigationItems from 'lib/networks/useNetworkNavigationItems';
import NetworkMenuLink from './NetworkMenuLink'; import NetworkMenuLink from './NetworkMenuLink';
...@@ -12,7 +13,7 @@ import NetworkMenuLink from './NetworkMenuLink'; ...@@ -12,7 +13,7 @@ import NetworkMenuLink from './NetworkMenuLink';
const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ]; const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ];
const NetworkMenuContentMobile = () => { const NetworkMenuContentMobile = () => {
const selectedNetwork = useNetwork(); const selectedNetwork = featuredNetworks.find((network) => network.basePath === appConfig.network.basePath);
const [ selectedTab, setSelectedTab ] = React.useState<NetworkGroup>(TABS.find((tab) => selectedNetwork?.group === tab) || 'mainnets'); const [ selectedTab, setSelectedTab ] = React.useState<NetworkGroup>(TABS.find((tab) => selectedNetwork?.group === tab) || 'mainnets');
const items = useNetworkNavigationItems(); const items = useNetworkNavigationItems();
......
import { Grid, GridItem, Text, Box, Icon, Link, Tag, Flex, Tooltip, chakra } from '@chakra-ui/react'; import { Grid, GridItem, Text, Box, Icon, Link, Tag, Flex, Tooltip, chakra } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll'; import { scroller, Element } from 'react-scroll';
...@@ -8,7 +9,6 @@ import flameIcon from 'icons/flame.svg'; ...@@ -8,7 +9,6 @@ import flameIcon from 'icons/flame.svg';
import errorIcon from 'icons/status/error.svg'; import errorIcon from 'icons/status/error.svg';
import successIcon from 'icons/status/success.svg'; import successIcon from 'icons/status/success.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useNetwork from 'lib/hooks/useNetwork';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
...@@ -26,8 +26,6 @@ import TokenTransfer from 'ui/tx/TokenTransfer'; ...@@ -26,8 +26,6 @@ import TokenTransfer from 'ui/tx/TokenTransfer';
import TxDecodedInputData from 'ui/tx/TxDecodedInputData'; import TxDecodedInputData from 'ui/tx/TxDecodedInputData';
const TxDetails = () => { const TxDetails = () => {
const selectedNetwork = useNetwork();
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
const handleCutClick = React.useCallback(() => { const handleCutClick = React.useCallback(() => {
...@@ -126,21 +124,21 @@ const TxDetails = () => { ...@@ -126,21 +124,21 @@ const TxDetails = () => {
title="Value" title="Value"
hint="Value sent in the native token (and USD) if applicable." hint="Value sent in the native token (and USD) if applicable."
> >
<Text>{ tx.amount.value } { selectedNetwork?.currency }</Text> <Text>{ tx.amount.value } { appConfig.network.currency }</Text>
<Text variant="secondary" ml={ 1 }>(${ tx.amount.value_usd.toFixed(2) })</Text> <Text variant="secondary" ml={ 1 }>(${ tx.amount.value_usd.toFixed(2) })</Text>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Transaction fee" title="Transaction fee"
hint="Total transaction fee." hint="Total transaction fee."
> >
<Text>{ tx.fee.value } { selectedNetwork?.currency }</Text> <Text>{ tx.fee.value } { appConfig.network.currency }</Text>
<Text variant="secondary" ml={ 1 }>(${ tx.fee.value_usd.toFixed(2) })</Text> <Text variant="secondary" ml={ 1 }>(${ tx.fee.value_usd.toFixed(2) })</Text>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas price" title="Gas price"
hint="Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage." hint="Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage."
> >
<Text mr={ 1 }>{ tx.gas_price.toLocaleString('en', { minimumFractionDigits: 18 }) } { selectedNetwork?.currency }</Text> <Text mr={ 1 }>{ tx.gas_price.toLocaleString('en', { minimumFractionDigits: 18 }) } { appConfig.network.currency }</Text>
<Text variant="secondary">({ (tx.gas_price * Math.pow(10, 18)).toFixed(0) } Gwei)</Text> <Text variant="secondary">({ (tx.gas_price * Math.pow(10, 18)).toFixed(0) } Gwei)</Text>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
...@@ -174,10 +172,10 @@ const TxDetails = () => { ...@@ -174,10 +172,10 @@ const TxDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Burnt fees" title="Burnt fees"
hint={ `Amount of ${ selectedNetwork?.currency } burned for this transaction. Equals Block Base Fee per Gas * Gas Used.` } hint={ `Amount of ${ appConfig.network.currency } burned for this transaction. Equals Block Base Fee per Gas * Gas Used.` }
> >
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/> <Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/>
<Text ml={ 1 } mr={ 1 }>{ tx.burnt_fees.value.toLocaleString('en', { minimumFractionDigits: 18 }) } { selectedNetwork?.currency }</Text> <Text ml={ 1 } mr={ 1 }>{ tx.burnt_fees.value.toLocaleString('en', { minimumFractionDigits: 18 }) } { appConfig.network.currency }</Text>
<Text variant="secondary">(${ tx.burnt_fees.value_usd.toFixed(2) })</Text> <Text variant="secondary">(${ tx.burnt_fees.value_usd.toFixed(2) })</Text>
</DetailsInfoItem> </DetailsInfoItem>
<GridItem colSpan={{ base: undefined, lg: 2 }}> <GridItem colSpan={{ base: undefined, lg: 2 }}>
......
...@@ -2,15 +2,12 @@ import { Box } from '@chakra-ui/react'; ...@@ -2,15 +2,12 @@ import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { data as txData } from 'data/txInternal'; import type { data as txData } from 'data/txInternal';
import useNetwork from 'lib/hooks/useNetwork';
import TxInternalsListItem from 'ui/tx/internals/TxInternalsListItem'; import TxInternalsListItem from 'ui/tx/internals/TxInternalsListItem';
const TxInternalsList = ({ data }: { data: typeof txData}) => { const TxInternalsList = ({ data }: { data: typeof txData}) => {
const selectedNetwork = useNetwork();
return ( return (
<Box mt={ 6 }> <Box mt={ 6 }>
{ data.map((item) => <TxInternalsListItem key={ item.id } { ...item } currency={ selectedNetwork?.currency }/>) } { data.map((item) => <TxInternalsListItem key={ item.id } { ...item }/>) }
</Box> </Box>
); );
}; };
......
import { Flex, Tag, Icon, Box, HStack, Text } from '@chakra-ui/react'; import { Flex, Tag, Icon, Box, HStack, Text } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import capitalize from 'lodash/capitalize'; import capitalize from 'lodash/capitalize';
import React from 'react'; import React from 'react';
...@@ -12,9 +13,9 @@ import AddressIcon from 'ui/shared/address/AddressIcon'; ...@@ -12,9 +13,9 @@ import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
type Props = ArrayElement<typeof data> & { currency?: string }; type Props = ArrayElement<typeof data>;
const TxInternalsListItem = ({ type, status, from, to, value, gasLimit, currency }: Props) => { const TxInternalsListItem = ({ type, status, from, to, value, gasLimit }: Props) => {
return ( return (
<AccountListItemMobile rowGap={ 3 }> <AccountListItemMobile rowGap={ 3 }>
<Flex> <Flex>
...@@ -33,7 +34,7 @@ const TxInternalsListItem = ({ type, status, from, to, value, gasLimit, currency ...@@ -33,7 +34,7 @@ const TxInternalsListItem = ({ type, status, from, to, value, gasLimit, currency
</Address> </Address>
</Box> </Box>
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
<Text fontSize="sm" fontWeight={ 500 }>Value { currency }</Text> <Text fontSize="sm" fontWeight={ 500 }>Value { appConfig.network.currency }</Text>
<Text fontSize="sm" variant="secondary">{ value }</Text> <Text fontSize="sm" variant="secondary">{ value }</Text>
</HStack> </HStack>
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
......
import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react'; import { Table, Thead, Tbody, Tr, Th, TableContainer } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type { data as txData } from 'data/txInternal'; import type { data as txData } from 'data/txInternal';
import useNetwork from 'lib/hooks/useNetwork';
import TxInternalsTableItem from 'ui/tx/internals/TxInternalsTableItem'; import TxInternalsTableItem from 'ui/tx/internals/TxInternalsTableItem';
const TxInternalsTable = ({ data }: { data: typeof txData}) => { const TxInternalsTable = ({ data }: { data: typeof txData}) => {
const selectedNetwork = useNetwork();
return ( return (
<TableContainer width="100%" mt={ 6 }> <TableContainer width="100%" mt={ 6 }>
...@@ -17,7 +16,7 @@ const TxInternalsTable = ({ data }: { data: typeof txData}) => { ...@@ -17,7 +16,7 @@ const TxInternalsTable = ({ data }: { data: typeof txData}) => {
<Th width="20%">From</Th> <Th width="20%">From</Th>
<Th width="24px" px={ 0 }/> <Th width="24px" px={ 0 }/>
<Th width="20%">To</Th> <Th width="20%">To</Th>
<Th width="16%" isNumeric>Value { selectedNetwork?.currency }</Th> <Th width="16%" isNumeric>Value { appConfig.network.currency }</Th>
<Th width="16%" isNumeric>Gas limit</Th> <Th width="16%" isNumeric>Gas limit</Th>
</Tr> </Tr>
</Thead> </Thead>
......
import { AccordionItem, AccordionButton, AccordionIcon, Button, Flex, Text, Link, StatArrow, Stat, AccordionPanel } from '@chakra-ui/react'; import { AccordionItem, AccordionButton, AccordionIcon, Button, Flex, Text, Link, StatArrow, Stat, AccordionPanel } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type ArrayElement from 'types/utils/ArrayElement'; import type ArrayElement from 'types/utils/ArrayElement';
import type { data } from 'data/txState'; import type { data } from 'data/txState';
import useNetwork from 'lib/hooks/useNetwork';
import { nbsp } from 'lib/html-entities'; import { nbsp } from 'lib/html-entities';
import AccountListItemMobile from 'ui/shared/AccountListItemMobile'; import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
...@@ -17,7 +17,6 @@ import TxStateStorageItem from './TxStateStorageItem'; ...@@ -17,7 +17,6 @@ import TxStateStorageItem from './TxStateStorageItem';
type Props = ArrayElement<typeof data>; type Props = ArrayElement<typeof data>;
const TxStateListItem = ({ storage, address, miner, after, before, diff }: Props) => { const TxStateListItem = ({ storage, address, miner, after, before, diff }: Props) => {
const selectedNetwork = useNetwork();
const hasStorageData = Boolean(storage?.length); const hasStorageData = Boolean(storage?.length);
...@@ -62,20 +61,20 @@ const TxStateListItem = ({ storage, address, miner, after, before, diff }: Props ...@@ -62,20 +61,20 @@ const TxStateListItem = ({ storage, address, miner, after, before, diff }: Props
<Flex rowGap={ 2 } flexDir="column" fontSize="sm"> <Flex rowGap={ 2 } flexDir="column" fontSize="sm">
<Text fontWeight={ 600 }>Before</Text> <Text fontWeight={ 600 }>Before</Text>
<Flex> <Flex>
<Text>{ before.balance } { selectedNetwork?.currency }</Text> <Text>{ before.balance } { appConfig.network.currency }</Text>
<TextSeparator/> <TextSeparator/>
{ typeof before.nonce !== 'undefined' && <Text>Nonce:{ nbsp }{ before.nonce }</Text> } { typeof before.nonce !== 'undefined' && <Text>Nonce:{ nbsp }{ before.nonce }</Text> }
</Flex> </Flex>
</Flex> </Flex>
<Flex rowGap={ 2 } flexDir="column" fontSize="sm"> <Flex rowGap={ 2 } flexDir="column" fontSize="sm">
<Text fontWeight={ 600 }>After</Text> <Text fontWeight={ 600 }>After</Text>
<Text>{ after.balance } { selectedNetwork?.currency }</Text> <Text>{ after.balance } { appConfig.network.currency }</Text>
{ typeof after.nonce !== 'undefined' && <Text>Nonce:{ nbsp }{ after.nonce }</Text> } { typeof after.nonce !== 'undefined' && <Text>Nonce:{ nbsp }{ after.nonce }</Text> }
</Flex> </Flex>
<Flex rowGap={ 2 } flexDir="column" fontSize="sm"> <Flex rowGap={ 2 } flexDir="column" fontSize="sm">
<Text fontWeight={ 600 }>State difference</Text> <Text fontWeight={ 600 }>State difference</Text>
<Stat> <Stat>
{ diff } { selectedNetwork?.currency } { diff } { appConfig.network.currency }
<StatArrow ml={ 2 } type={ Number(diff) > 0 ? 'increase' : 'decrease' }/> <StatArrow ml={ 2 } type={ Number(diff) > 0 ? 'increase' : 'decrease' }/>
</Stat> </Stat>
</Flex> </Flex>
......
...@@ -6,15 +6,13 @@ import { ...@@ -6,15 +6,13 @@ import {
Th, Th,
TableContainer, TableContainer,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import { data } from 'data/txState'; import { data } from 'data/txState';
import useNetwork from 'lib/hooks/useNetwork';
import TxStateTableItem from 'ui/tx/state/TxStateTableItem'; import TxStateTableItem from 'ui/tx/state/TxStateTableItem';
const TxStateTable = () => { const TxStateTable = () => {
const selectedNetwork = useNetwork();
return ( return (
<TableContainer width="100%" mt={ 6 }> <TableContainer width="100%" mt={ 6 }>
<Table variant="simple" minWidth="950px" size="sm"> <Table variant="simple" minWidth="950px" size="sm">
...@@ -23,9 +21,9 @@ const TxStateTable = () => { ...@@ -23,9 +21,9 @@ const TxStateTable = () => {
<Th width="92px">Storage</Th> <Th width="92px">Storage</Th>
<Th width="146px">Address</Th> <Th width="146px">Address</Th>
<Th width="120px">Miner</Th> <Th width="120px">Miner</Th>
<Th width="33%" isNumeric>{ `After ${ selectedNetwork?.currency }` }</Th> <Th width="33%" isNumeric>{ `After ${ appConfig.network.currency }` }</Th>
<Th width="33%" isNumeric>{ `Before ${ selectedNetwork?.currency }` }</Th> <Th width="33%" isNumeric>{ `Before ${ appConfig.network.currency }` }</Th>
<Th width="33%" isNumeric>{ `State difference ${ selectedNetwork?.currency }` }</Th> <Th width="33%" isNumeric>{ `State difference ${ appConfig.network.currency }` }</Th>
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
......
import { Box, Heading, Text, Flex, Link, useColorModeValue } from '@chakra-ui/react'; import { Box, Heading, Text, Flex, Link, useColorModeValue } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type ArrayElement from 'types/utils/ArrayElement'; import type ArrayElement from 'types/utils/ArrayElement';
import type { txs } from 'data/txs'; import type { txs } from 'data/txs';
import useNetwork from 'lib/hooks/useNetwork';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import TextSeparator from 'ui/shared/TextSeparator'; import TextSeparator from 'ui/shared/TextSeparator';
import Utilization from 'ui/shared/Utilization'; import Utilization from 'ui/shared/Utilization';
const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => { const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => {
const selectedNetwork = useNetwork();
const sectionBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200'); const sectionBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200');
const sectionProps = { const sectionProps = {
borderBottom: '1px solid', borderBottom: '1px solid',
...@@ -33,7 +31,7 @@ const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => { ...@@ -33,7 +31,7 @@ const TxAdditionalInfo = ({ tx }: { tx: ArrayElement<typeof txs> }) => {
<Box { ...sectionProps } mb={ 4 }> <Box { ...sectionProps } mb={ 4 }>
<Text { ...sectionTitleProps }>Transaction fee</Text> <Text { ...sectionTitleProps }>Transaction fee</Text>
<Flex> <Flex>
<Text>{ tx.fee.value } { selectedNetwork?.currency }</Text> <Text>{ tx.fee.value } { appConfig.network.currency }</Text>
<Text variant="secondary" ml={ 1 }>(${ tx.fee.value_usd.toFixed(2) })</Text> <Text variant="secondary" ml={ 1 }>(${ tx.fee.value_usd.toFixed(2) })</Text>
</Flex> </Flex>
</Box> </Box>
......
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
Text, Text,
useColorModeValue, useColorModeValue,
useDisclosure } from '@chakra-ui/react'; useDisclosure } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type ArrayElement from 'types/utils/ArrayElement'; import type ArrayElement from 'types/utils/ArrayElement';
...@@ -18,7 +19,6 @@ import type { txs } from 'data/txs'; ...@@ -18,7 +19,6 @@ import type { txs } from 'data/txs';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import transactionIcon from 'icons/transactions.svg'; import transactionIcon from 'icons/transactions.svg';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import useNetwork from 'lib/hooks/useNetwork';
import useLink from 'lib/link/useLink'; import useLink from 'lib/link/useLink';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
...@@ -30,7 +30,6 @@ import TxType from 'ui/txs/TxType'; ...@@ -30,7 +30,6 @@ import TxType from 'ui/txs/TxType';
const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => { const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const selectedNetwork = useNetwork();
const iconColor = useColorModeValue('blue.600', 'blue.300'); const iconColor = useColorModeValue('blue.600', 'blue.300');
const borderColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200'); const borderColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
...@@ -108,11 +107,11 @@ const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => { ...@@ -108,11 +107,11 @@ const TxsListItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
</Address> </Address>
</Flex> </Flex>
<Box mt={ 2 }> <Box mt={ 2 }>
<Text as="span">Value { selectedNetwork?.currency } </Text> <Text as="span">Value { appConfig.network.currency } </Text>
<Text as="span" variant="secondary">{ tx.amount.value.toFixed(8) }</Text> <Text as="span" variant="secondary">{ tx.amount.value.toFixed(8) }</Text>
</Box> </Box>
<Box mt={ 2 } mb={ 3 }> <Box mt={ 2 } mb={ 3 }>
<Text as="span">Fee { selectedNetwork?.currency } </Text> <Text as="span">Fee { appConfig.network.currency } </Text>
<Text as="span" variant="secondary">{ tx.fee.value.toFixed(8) }</Text> <Text as="span" variant="secondary">{ tx.fee.value.toFixed(8) }</Text>
</Box> </Box>
</Box> </Box>
......
import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, Icon } from '@chakra-ui/react'; import { Link, Table, Thead, Tbody, Tr, Th, TableContainer, Icon } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type { Sort } from 'types/client/txs-sort'; import type { Sort } from 'types/client/txs-sort';
import type { txs as data } from 'data/txs'; import type { txs as data } from 'data/txs';
import rightArrowIcon from 'icons/arrows/east.svg'; import rightArrowIcon from 'icons/arrows/east.svg';
import useNetwork from 'lib/hooks/useNetwork';
import TxsTableItem from './TxsTableItem'; import TxsTableItem from './TxsTableItem';
...@@ -16,8 +16,6 @@ type Props = { ...@@ -16,8 +16,6 @@ type Props = {
} }
const TxsTable = ({ txs, sort, sorting }: Props) => { const TxsTable = ({ txs, sort, sorting }: Props) => {
const selectedNetwork = useNetwork();
return ( return (
<TableContainer width="100%" mt={ 6 }> <TableContainer width="100%" mt={ 6 }>
<Table variant="simple" minWidth="810px" size="xs"> <Table variant="simple" minWidth="810px" size="xs">
...@@ -35,14 +33,14 @@ const TxsTable = ({ txs, sort, sorting }: Props) => { ...@@ -35,14 +33,14 @@ const TxsTable = ({ txs, sort, sorting }: Props) => {
<Link onClick={ sort('val') } display="flex" justifyContent="end"> <Link onClick={ sort('val') } display="flex" justifyContent="end">
{ sorting === 'val-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> } { sorting === 'val-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> }
{ sorting === 'val-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> } { sorting === 'val-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> }
{ `Value ${ selectedNetwork?.currency }` } { `Value ${ appConfig.network.currency }` }
</Link> </Link>
</Th> </Th>
<Th width="18%" isNumeric pr={ 5 }> <Th width="18%" isNumeric pr={ 5 }>
<Link onClick={ sort('fee') } display="flex" justifyContent="end"> <Link onClick={ sort('fee') } display="flex" justifyContent="end">
{ sorting === 'fee-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> } { sorting === 'fee-asc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(-90deg)"/> }
{ sorting === 'fee-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> } { sorting === 'fee-desc' && <Icon boxSize={ 5 } as={ rightArrowIcon } transform="rotate(90deg)"/> }
{ `Fee ${ selectedNetwork?.currency }` } { `Fee ${ appConfig.network.currency }` }
</Link> </Link>
</Th> </Th>
</Tr> </Tr>
......
import { Grid, GridItem } from '@chakra-ui/react'; import { Grid, GridItem } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { Controller } from 'react-hook-form'; import { Controller } from 'react-hook-form';
import type { Path, ControllerRenderProps, FieldValues, Control } from 'react-hook-form'; import type { Path, ControllerRenderProps, FieldValues, Control } from 'react-hook-form';
import useNetwork from 'lib/hooks/useNetwork';
import CheckboxInput from 'ui/shared/CheckboxInput'; import CheckboxInput from 'ui/shared/CheckboxInput';
// does it depend on the network? // does it depend on the network?
const NOTIFICATIONS = [ 'native', 'ERC-20', 'ERC-721' ] as const; const NOTIFICATIONS = [ 'native', 'ERC-20', 'ERC-721' ] as const;
const NOTIFICATIONS_NAMES = [ appConfig.network.currency, 'ERC-20', 'ERC-721, ERC-1155 (NFT)' ];
type Props<Inputs extends FieldValues> = { type Props<Inputs extends FieldValues> = {
control: Control<Inputs>; control: Control<Inputs>;
} }
export default function AddressFormNotifications<Inputs extends FieldValues, Checkboxes extends Path<Inputs>>({ control }: Props<Inputs>) { export default function AddressFormNotifications<Inputs extends FieldValues, Checkboxes extends Path<Inputs>>({ control }: Props<Inputs>) {
const selectedNetwork = useNetwork();
const NOTIFICATIONS_NAMES = React.useMemo(() => {
return [ selectedNetwork?.currency, 'ERC-20', 'ERC-721, ERC-1155 (NFT)' ];
}, [ selectedNetwork?.currency ]);
// eslint-disable-next-line react/display-name // eslint-disable-next-line react/display-name
const renderCheckbox = useCallback((text: string) => ({ field }: {field: ControllerRenderProps<Inputs, Checkboxes>}) => ( const renderCheckbox = useCallback((text: string) => ({ field }: {field: ControllerRenderProps<Inputs, Checkboxes>}) => (
<CheckboxInput<Inputs, Checkboxes> text={ text } field={ field }/> <CheckboxInput<Inputs, Checkboxes> text={ text } field={ field }/>
......
import { HStack, VStack, Text, Icon, useColorModeValue } from '@chakra-ui/react'; import { HStack, VStack, Text, Icon, useColorModeValue } from '@chakra-ui/react';
import appConfig from 'configs/app/config';
import React from 'react'; import React from 'react';
import type { TWatchlistItem } from 'types/client/account'; import type { TWatchlistItem } from 'types/client/account';
import TokensIcon from 'icons/tokens.svg'; import TokensIcon from 'icons/tokens.svg';
// import WalletIcon from 'icons/wallet.svg'; // import WalletIcon from 'icons/wallet.svg';
import useNetwork from 'lib/hooks/useNetwork';
import { nbsp } from 'lib/html-entities'; import { nbsp } from 'lib/html-entities';
import AddressSnippet from 'ui/shared/AddressSnippet'; import AddressSnippet from 'ui/shared/AddressSnippet';
import TokenLogo from 'ui/shared/TokenLogo'; import TokenLogo from 'ui/shared/TokenLogo';
...@@ -14,7 +14,6 @@ const DECIMALS = 18; ...@@ -14,7 +14,6 @@ const DECIMALS = 18;
const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => { const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
const mainTextColor = useColorModeValue('gray.700', 'gray.50'); const mainTextColor = useColorModeValue('gray.700', 'gray.50');
const selectedNetwork = useNetwork();
const nativeBalance = ((item.address_balance || 0) / 10 ** DECIMALS).toFixed(1); const nativeBalance = ((item.address_balance || 0) / 10 ** DECIMALS).toFixed(1);
const nativeBalanceUSD = item.exchange_rate ? `$${ Number(nativeBalance) * item.exchange_rate } USD` : 'N/A'; const nativeBalanceUSD = item.exchange_rate ? `$${ Number(nativeBalance) * item.exchange_rate } USD` : 'N/A';
...@@ -24,8 +23,9 @@ const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => { ...@@ -24,8 +23,9 @@ const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
<VStack spacing={ 2 } align="stretch" overflow="hidden" fontWeight={ 500 } color="gray.700"> <VStack spacing={ 2 } align="stretch" overflow="hidden" fontWeight={ 500 } color="gray.700">
<AddressSnippet address={ item.address_hash }/> <AddressSnippet address={ item.address_hash }/>
<HStack spacing={ 0 } fontSize="sm" h={ 6 } pl={ infoItemsPaddingLeft }> <HStack spacing={ 0 } fontSize="sm" h={ 6 } pl={ infoItemsPaddingLeft }>
{ selectedNetwork && <TokenLogo hash={ selectedNetwork.nativeTokenAddress } name={ selectedNetwork.name } boxSize={ 4 } mr="10px"/> } { appConfig.network.nativeTokenAddress &&
<Text color={ mainTextColor }>{ `${ selectedNetwork?.currency } balance:${ nbsp }` + nativeBalance }</Text> <TokenLogo hash={ appConfig.network.nativeTokenAddress } name={ appConfig.network.name } boxSize={ 4 } mr="10px"/> }
<Text color={ mainTextColor }>{ `${ appConfig.network.currency } balance:${ nbsp }` + nativeBalance }</Text>
<Text variant="secondary">{ `${ nbsp }(${ nativeBalanceUSD })` }</Text> <Text variant="secondary">{ `${ nbsp }(${ nativeBalanceUSD })` }</Text>
</HStack> </HStack>
{ item.tokens_count && ( { item.tokens_count && (
......
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