Commit e755b443 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #620 from blockscout/contract-write-custom

contract tab fixes
parents 9f333f82 b845888c
...@@ -106,7 +106,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -106,7 +106,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.is_contract && data.creation_tx_hash && data.creator_address_hash && ( { data.is_contract && data.creation_tx_hash && data.creator_address_hash && (
<DetailsInfoItem <DetailsInfoItem
title="Creator" title="Creator"
hint="Transaction and address of creation." hint="Transaction and address of creation"
> >
<AddressLink type="address" hash={ data.creator_address_hash } truncation="constant"/> <AddressLink type="address" hash={ data.creator_address_hash } truncation="constant"/>
<Text whiteSpace="pre"> at txn </Text> <Text whiteSpace="pre"> at txn </Text>
...@@ -116,7 +116,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -116,7 +116,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.is_contract && data.implementation_address && ( { data.is_contract && data.implementation_address && (
<DetailsInfoItem <DetailsInfoItem
title="Implementation" title="Implementation"
hint="Implementation address of the proxy contract." hint="Implementation address of the proxy contract"
columnGap={ 1 } columnGap={ 1 }
> >
<LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: data.implementation_address } }) } overflow="hidden"> <LinkInternal href={ route({ pathname: '/address/[hash]', query: { hash: data.implementation_address } }) } overflow="hidden">
...@@ -133,7 +133,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -133,7 +133,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.has_tokens && ( { data.has_tokens && (
<DetailsInfoItem <DetailsInfoItem
title="Tokens" title="Tokens"
hint="All tokens in the account and total value." hint="All tokens in the account and total value"
alignSelf="center" alignSelf="center"
py={ 0 } py={ 0 }
> >
...@@ -142,7 +142,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -142,7 +142,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
) } ) }
<DetailsInfoItem <DetailsInfoItem
title="Transactions" title="Transactions"
hint="Number of transactions related to this address." hint="Number of transactions related to this address"
> >
{ addressQuery.data ? { addressQuery.data ?
<AddressCounterItem prop="transactions_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> : <AddressCounterItem prop="transactions_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> :
...@@ -151,7 +151,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -151,7 +151,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.has_token_transfers && ( { data.has_token_transfers && (
<DetailsInfoItem <DetailsInfoItem
title="Transfers" title="Transfers"
hint="Number of transfers to/from this address." hint="Number of transfers to/from this address"
> >
{ addressQuery.data ? { addressQuery.data ?
<AddressCounterItem prop="token_transfers_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> : <AddressCounterItem prop="token_transfers_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> :
...@@ -160,7 +160,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -160,7 +160,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
) } ) }
<DetailsInfoItem <DetailsInfoItem
title="Gas used" title="Gas used"
hint="Gas used by the address." hint="Gas used by the address"
> >
{ addressQuery.data ? { addressQuery.data ?
<AddressCounterItem prop="gas_usage_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> : <AddressCounterItem prop="gas_usage_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> :
...@@ -169,7 +169,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -169,7 +169,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.has_validated_blocks && ( { data.has_validated_blocks && (
<DetailsInfoItem <DetailsInfoItem
title="Blocks validated" title="Blocks validated"
hint="Number of blocks validated by this validator." hint="Number of blocks validated by this validator"
> >
{ addressQuery.data ? { addressQuery.data ?
<AddressCounterItem prop="validations_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> : <AddressCounterItem prop="validations_count" query={ countersQuery } address={ data.hash } onClick={ handleCounterItemClick }/> :
...@@ -179,7 +179,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => { ...@@ -179,7 +179,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.block_number_balance_updated_at && ( { data.block_number_balance_updated_at && (
<DetailsInfoItem <DetailsInfoItem
title="Last balance update" title="Last balance update"
hint="Block number in which the address was updated." hint="Block number in which the address was updated"
alignSelf="center" alignSelf="center"
py={{ base: '2px', lg: 1 }} py={{ base: '2px', lg: 1 }}
> >
......
...@@ -4,6 +4,7 @@ import { route } from 'nextjs-routes'; ...@@ -4,6 +4,7 @@ import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
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';
...@@ -15,12 +16,12 @@ import RawDataSnippet from 'ui/shared/RawDataSnippet'; ...@@ -15,12 +16,12 @@ import RawDataSnippet from 'ui/shared/RawDataSnippet';
import ContractSourceCode from './ContractSourceCode'; import ContractSourceCode from './ContractSourceCode';
const InfoItem = ({ label, value }: { label: string; value: string }) => ( const InfoItem = chakra(({ label, value, className }: { label: string; value: string; className?: string }) => (
<GridItem display="flex" columnGap={ 6 }> <GridItem display="flex" columnGap={ 6 } wordBreak="break-all" className={ className }>
<Text w="170px" flexShrink={ 0 } fontWeight={ 500 }>{ label }</Text> <Text w="170px" flexShrink={ 0 } fontWeight={ 500 }>{ label }</Text>
<Text wordBreak="break-all">{ value }</Text> <Text>{ value }</Text>
</GridItem> </GridItem>
); ));
const ContractCode = () => { const ContractCode = () => {
const router = useRouter(); const router = useRouter();
...@@ -153,10 +154,10 @@ const ContractCode = () => { ...@@ -153,10 +154,10 @@ const ContractCode = () => {
<Grid templateColumns={{ base: '1fr', lg: '1fr 1fr' }} rowGap={ 4 } columnGap={ 6 } mb={ 8 }> <Grid templateColumns={{ base: '1fr', lg: '1fr 1fr' }} rowGap={ 4 } columnGap={ 6 } mb={ 8 }>
{ data.name && <InfoItem label="Contract name" value={ data.name }/> } { data.name && <InfoItem label="Contract name" value={ data.name }/> }
{ data.compiler_version && <InfoItem label="Compiler version" value={ data.compiler_version }/> } { data.compiler_version && <InfoItem label="Compiler version" value={ data.compiler_version }/> }
{ data.evm_version && <InfoItem label="EVM version" value={ data.evm_version }/> } { data.evm_version && <InfoItem label="EVM version" value={ data.evm_version } textTransform="capitalize"/> }
{ typeof data.optimization_enabled === 'boolean' && <InfoItem label="Optimization enabled" value={ data.optimization_enabled ? 'true' : 'false' }/> } { typeof data.optimization_enabled === 'boolean' && <InfoItem label="Optimization enabled" value={ data.optimization_enabled ? 'true' : 'false' }/> }
{ data.optimization_runs && <InfoItem label="Optimization runs" value={ String(data.optimization_runs) }/> } { data.optimization_runs && <InfoItem label="Optimization runs" value={ String(data.optimization_runs) }/> }
{ data.verified_at && <InfoItem label="Verified at" value={ data.verified_at }/> } { data.verified_at && <InfoItem label="Verified at" value={ dayjs(data.verified_at).format('LLLL') } wordBreak="break-word"/> }
</Grid> </Grid>
) } ) }
<Flex flexDir="column" rowGap={ 6 }> <Flex flexDir="column" rowGap={ 6 }>
......
...@@ -9,7 +9,7 @@ import ContractRead from './ContractRead'; ...@@ -9,7 +9,7 @@ import ContractRead from './ContractRead';
const addressHash = 'hash'; const addressHash = 'hash';
const CONTRACT_READ_METHODS_API_URL = buildApiUrl('contract_methods_read', { hash: addressHash }) + '?is_custom_abi=false'; const CONTRACT_READ_METHODS_API_URL = buildApiUrl('contract_methods_read', { hash: addressHash }) + '?is_custom_abi=false';
const CONTRACT_QUERY_METHOD_API_URL = buildApiUrl('contract_method_query', { hash: addressHash }); const CONTRACT_QUERY_METHOD_API_URL = buildApiUrl('contract_method_query', { hash: addressHash }) + '?is_custom_abi=false';
const hooksConfig = { const hooksConfig = {
router: { router: {
query: { hash: addressHash }, query: { hash: addressHash },
......
...@@ -35,6 +35,7 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => { ...@@ -35,6 +35,7 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => {
pathParams: { hash: addressHash }, pathParams: { hash: addressHash },
queryParams: { queryParams: {
is_custom_abi: isCustomAbi ? 'true' : 'false', is_custom_abi: isCustomAbi ? 'true' : 'false',
from: userAddress,
}, },
queryOptions: { queryOptions: {
enabled: Boolean(addressHash), enabled: Boolean(addressHash),
...@@ -44,6 +45,9 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => { ...@@ -44,6 +45,9 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => {
const handleMethodFormSubmit = React.useCallback(async(item: SmartContractReadMethod, args: Array<string | Array<string>>) => { const handleMethodFormSubmit = React.useCallback(async(item: SmartContractReadMethod, args: Array<string | Array<string>>) => {
return apiFetch<'contract_method_query', SmartContractQueryMethodRead>('contract_method_query', { return apiFetch<'contract_method_query', SmartContractQueryMethodRead>('contract_method_query', {
pathParams: { hash: addressHash }, pathParams: { hash: addressHash },
queryParams: {
is_custom_abi: isCustomAbi ? 'true' : 'false',
},
fetchParams: { fetchParams: {
method: 'POST', method: 'POST',
body: { body: {
...@@ -54,11 +58,11 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => { ...@@ -54,11 +58,11 @@ const ContractRead = ({ isProxy, isCustomAbi }: Props) => {
}, },
}, },
}); });
}, [ addressHash, apiFetch, isProxy, userAddress ]); }, [ addressHash, apiFetch, isCustomAbi, isProxy, userAddress ]);
const renderContent = React.useCallback((item: SmartContractReadMethod, index: number, id: number) => { const renderContent = React.useCallback((item: SmartContractReadMethod, index: number, id: number) => {
if (item.error) { if (item.error) {
return <Alert status="error" fontSize="sm">{ item.error }</Alert>; return <Alert status="error" fontSize="sm" wordBreak="break-word">{ item.error }</Alert>;
} }
if (item.outputs.some(({ value }) => value)) { if (item.outputs.some(({ value }) => value)) {
......
...@@ -18,12 +18,12 @@ const ContractReadResult = ({ item, result, onSettle }: Props) => { ...@@ -18,12 +18,12 @@ const ContractReadResult = ({ item, result, onSettle }: Props) => {
}, [ onSettle ]); }, [ onSettle ]);
if ('status' in result) { if ('status' in result) {
return <Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" fontSize="sm">{ result.statusText }</Alert>; return <Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" fontSize="sm" wordBreak="break-word">{ result.statusText }</Alert>;
} }
if (result.is_error) { if (result.is_error) {
const message = 'error' in result.result ? result.result.error : result.result.message; const message = 'error' in result.result ? result.result.error : result.result.message;
return <Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" fontSize="sm">{ message }</Alert>; return <Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" fontSize="sm" wordBreak="break-word">{ message }</Alert>;
} }
return ( return (
......
...@@ -42,8 +42,18 @@ const ContractWrite = ({ isProxy, isCustomAbi }: Props) => { ...@@ -42,8 +42,18 @@ const ContractWrite = ({ isProxy, isCustomAbi }: Props) => {
}, },
}); });
const { contract, proxy } = useContractContext(); const { contract, proxy, custom } = useContractContext();
const _contract = isProxy ? proxy : contract; const _contract = (() => {
if (isProxy) {
return proxy;
}
if (isCustomAbi) {
return custom;
}
return contract;
})();
const handleMethodFormSubmit = React.useCallback(async(item: SmartContractWriteMethod, args: Array<string | Array<string>>) => { const handleMethodFormSubmit = React.useCallback(async(item: SmartContractWriteMethod, args: Array<string | Array<string>>) => {
if (!isConnected) { if (!isConnected) {
...@@ -52,7 +62,7 @@ const ContractWrite = ({ isProxy, isCustomAbi }: Props) => { ...@@ -52,7 +62,7 @@ const ContractWrite = ({ isProxy, isCustomAbi }: Props) => {
try { try {
if (!_contract) { if (!_contract) {
return; throw new Error('Something went wrong. Try again later.');
} }
if (item.type === 'receive') { if (item.type === 'receive') {
......
...@@ -15,11 +15,13 @@ type ProviderProps = { ...@@ -15,11 +15,13 @@ type ProviderProps = {
type TContractContext = { type TContractContext = {
contract: Contract | null; contract: Contract | null;
proxy: Contract | null; proxy: Contract | null;
custom: Contract | null;
}; };
const ContractContext = React.createContext<TContractContext>({ const ContractContext = React.createContext<TContractContext>({
contract: null, contract: null,
proxy: null, proxy: null,
custom: null,
}); });
export function ContractContextProvider({ children }: ProviderProps) { export function ContractContextProvider({ children }: ProviderProps) {
...@@ -49,21 +51,36 @@ export function ContractContextProvider({ children }: ProviderProps) { ...@@ -49,21 +51,36 @@ export function ContractContextProvider({ children }: ProviderProps) {
}, },
}); });
const { data: customInfo } = useApiQuery('contract_methods_write', {
pathParams: { hash: addressHash },
queryParams: { is_custom_abi: 'true' },
queryOptions: {
enabled: Boolean(addressInfo?.has_custom_methods_write),
refetchOnMount: false,
},
});
const contract = useContract({ const contract = useContract({
address: addressHash, address: addressHash,
abi: contractInfo?.abi || undefined, abi: contractInfo?.abi ?? undefined,
signerOrProvider: signer || provider, signerOrProvider: signer ?? provider,
}); });
const proxy = useContract({ const proxy = useContract({
address: addressInfo?.implementation_address ?? undefined, address: addressInfo?.implementation_address ?? undefined,
abi: proxyInfo?.abi ?? undefined, abi: proxyInfo?.abi ?? undefined,
signerOrProvider: signer ?? provider, signerOrProvider: signer ?? provider,
}); });
const custom = useContract({
address: addressHash,
abi: customInfo ?? undefined,
signerOrProvider: signer ?? provider,
});
const value = React.useMemo(() => ({ const value = React.useMemo(() => ({
contract, contract,
proxy, proxy,
}), [ contract, proxy ]); custom,
}), [ contract, proxy, custom ]);
return ( return (
<ContractContext.Provider value={ value }> <ContractContext.Provider value={ value }>
......
...@@ -66,7 +66,7 @@ const AddressBalance = ({ data }: Props) => { ...@@ -66,7 +66,7 @@ const AddressBalance = ({ data }: Props) => {
return ( return (
<DetailsInfoItem <DetailsInfoItem
title="Balance" title="Balance"
hint={ `Address balance in ${ appConfig.network.currency.symbol }. Doesn't include ERC20, ERC721 and ERC1155 tokens.` } hint={ `Address balance in ${ appConfig.network.currency.symbol }. Doesn't include ERC20, ERC721 and ERC1155 tokens` }
flexWrap="nowrap" flexWrap="nowrap"
alignItems="flex-start" alignItems="flex-start"
> >
......
...@@ -86,7 +86,7 @@ const BlockDetails = () => { ...@@ -86,7 +86,7 @@ const BlockDetails = () => {
<Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }} overflow="hidden"> <Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }} overflow="hidden">
<DetailsInfoItem <DetailsInfoItem
title="Block height" title="Block height"
hint="The block height of a particular block is defined as the number of blocks preceding it in the blockchain." hint="The block height of a particular block is defined as the number of blocks preceding it in the blockchain"
> >
{ data.height } { data.height }
{ data.height === 0 && <Text whiteSpace="pre"> - Genesis Block</Text> } { data.height === 0 && <Text whiteSpace="pre"> - Genesis Block</Text> }
...@@ -100,7 +100,7 @@ const BlockDetails = () => { ...@@ -100,7 +100,7 @@ const BlockDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Size" title="Size"
hint="Size of the block in bytes." hint="Size of the block in bytes"
> >
{ data.size.toLocaleString('en') } { data.size.toLocaleString('en') }
</DetailsInfoItem> </DetailsInfoItem>
...@@ -115,7 +115,7 @@ const BlockDetails = () => { ...@@ -115,7 +115,7 @@ const BlockDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Transactions" title="Transactions"
hint="The number of transactions in the block." hint="The number of transactions in the block"
> >
<LinkInternal href={ route({ pathname: '/block/[height]', query: { height, tab: 'txs' } }) }> <LinkInternal href={ route({ pathname: '/block/[height]', query: { height, tab: 'txs' } }) }>
{ data.tx_count } transactions { data.tx_count } transactions
...@@ -123,7 +123,7 @@ const BlockDetails = () => { ...@@ -123,7 +123,7 @@ const BlockDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title={ appConfig.network.verificationType === 'validation' ? 'Validated by' : 'Mined by' } title={ appConfig.network.verificationType === 'validation' ? 'Validated by' : 'Mined by' }
hint="A block producer who successfully included the block onto the blockchain." hint="A block producer who successfully included the block onto the blockchain"
columnGap={ 1 } columnGap={ 1 }
> >
<AddressLink type="address" hash={ data.miner.hash }/> <AddressLink type="address" hash={ data.miner.hash }/>
...@@ -136,7 +136,7 @@ const BlockDetails = () => { ...@@ -136,7 +136,7 @@ const BlockDetails = () => {
title="Block reward" title="Block reward"
hint={ hint={
`For each block, the ${ validatorTitle } is rewarded with a finite amount of ${ appConfig.network.currency.symbol || 'native token' } `For each block, the ${ validatorTitle } is rewarded with a finite amount of ${ appConfig.network.currency.symbol || '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 }
> >
...@@ -173,7 +173,7 @@ const BlockDetails = () => { ...@@ -173,7 +173,7 @@ const BlockDetails = () => {
key={ type } key={ type }
title={ type } title={ type }
// is this text correct for validators? // is this text correct for validators?
hint={ `Amount of distributed reward. ${ capitalize(validatorTitle) }s receive a static block reward + Tx fees + uncle fees.` } hint={ `Amount of distributed reward. ${ capitalize(validatorTitle) }s receive a static block reward + Tx fees + uncle fees` }
> >
{ BigNumber(reward).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol } { BigNumber(reward).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }
</DetailsInfoItem> </DetailsInfoItem>
...@@ -184,7 +184,7 @@ const BlockDetails = () => { ...@@ -184,7 +184,7 @@ const BlockDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Gas used" title="Gas used"
hint="The total gas amount used in the block and its percentage of gas filled in the block." hint="The total gas amount used in the block and its percentage of gas filled in the block"
> >
<Text>{ BigNumber(data.gas_used || 0).toFormat() }</Text> <Text>{ BigNumber(data.gas_used || 0).toFormat() }</Text>
<Utilization <Utilization
...@@ -197,14 +197,14 @@ const BlockDetails = () => { ...@@ -197,14 +197,14 @@ const BlockDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas limit" title="Gas limit"
hint="Total gas limit provided by all transactions in the block." hint="Total gas limit provided by all transactions in the block"
> >
<Text>{ BigNumber(data.gas_limit).toFormat() }</Text> <Text>{ BigNumber(data.gas_limit).toFormat() }</Text>
</DetailsInfoItem> </DetailsInfoItem>
{ data.base_fee_per_gas && ( { data.base_fee_per_gas && (
<DetailsInfoItem <DetailsInfoItem
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>{ BigNumber(data.base_fee_per_gas).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol } </Text> <Text>{ BigNumber(data.base_fee_per_gas).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol } </Text>
<Text variant="secondary" whiteSpace="pre"> <Text variant="secondary" whiteSpace="pre">
...@@ -217,7 +217,7 @@ const BlockDetails = () => { ...@@ -217,7 +217,7 @@ const BlockDetails = () => {
hint={ hint={
`Amount of ${ appConfig.network.currency.symbol || 'native token' } burned from transactions included in the block. `Amount of ${ appConfig.network.currency.symbol || 'native token' } burned from transactions included in the block.
Equals Block Base Fee per Gas * Gas Used.` Equals Block Base Fee per Gas * Gas Used`
} }
> >
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/> <Icon as={ flameIcon } boxSize={ 5 } color="gray.500"/>
...@@ -236,7 +236,7 @@ const BlockDetails = () => { ...@@ -236,7 +236,7 @@ const BlockDetails = () => {
{ data.priority_fee !== null && BigNumber(data.priority_fee).gt(ZERO) && ( { data.priority_fee !== null && BigNumber(data.priority_fee).gt(ZERO) && (
<DetailsInfoItem <DetailsInfoItem
title="Priority fee / Tip" title="Priority fee / Tip"
hint="User-defined tips sent to validator for transaction priority/inclusion." hint="User-defined tips sent to validator for transaction priority/inclusion"
> >
{ BigNumber(data.priority_fee).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol } { BigNumber(data.priority_fee).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }
</DetailsInfoItem> </DetailsInfoItem>
...@@ -244,7 +244,7 @@ const BlockDetails = () => { ...@@ -244,7 +244,7 @@ const BlockDetails = () => {
{ /* api doesn't support extra data yet */ } { /* api doesn't support extra data yet */ }
{ /* <DetailsInfoItem { /* <DetailsInfoItem
title="Extra data" title="Extra data"
hint={ `Any data that can be included by the ${ validatorTitle } in the block.` } hint={ `Any data that can be included by the ${ validatorTitle } in the block` }
> >
<Text whiteSpace="pre">{ data.extra_data } </Text> <Text whiteSpace="pre">{ data.extra_data } </Text>
<Text variant="secondary">(Hex: { data.extra_data })</Text> <Text variant="secondary">(Hex: { data.extra_data })</Text>
...@@ -273,7 +273,7 @@ const BlockDetails = () => { ...@@ -273,7 +273,7 @@ const BlockDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Difficulty" title="Difficulty"
hint={ `Block difficulty for ${ validatorTitle }, used to calibrate block generation time.` } hint={ `Block difficulty for ${ validatorTitle }, used to calibrate block generation time` }
whiteSpace="normal" whiteSpace="normal"
wordBreak="break-all" wordBreak="break-all"
> >
...@@ -281,7 +281,7 @@ const BlockDetails = () => { ...@@ -281,7 +281,7 @@ const BlockDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Total difficulty" title="Total difficulty"
hint="Total difficulty of the chain until this block." hint="Total difficulty of the chain until this block"
whiteSpace="normal" whiteSpace="normal"
wordBreak="break-all" wordBreak="break-all"
> >
...@@ -292,7 +292,7 @@ const BlockDetails = () => { ...@@ -292,7 +292,7 @@ const BlockDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Hash" title="Hash"
hint="The SHA256 hash of the block." hint="The SHA256 hash of the block"
flexWrap="nowrap" flexWrap="nowrap"
> >
<Box overflow="hidden"> <Box overflow="hidden">
...@@ -303,7 +303,7 @@ const BlockDetails = () => { ...@@ -303,7 +303,7 @@ const BlockDetails = () => {
{ data.height > 0 && ( { data.height > 0 && (
<DetailsInfoItem <DetailsInfoItem
title="Parent hash" title="Parent hash"
hint="The hash of the block from which this block was generated." hint="The hash of the block from which this block was generated"
flexWrap="nowrap" flexWrap="nowrap"
> >
<AddressLink hash={ data.parent_hash } type="block" id={ String(data.height - 1) }/> <AddressLink hash={ data.parent_hash } type="block" id={ String(data.height - 1) }/>
...@@ -313,13 +313,13 @@ const BlockDetails = () => { ...@@ -313,13 +313,13 @@ const BlockDetails = () => {
{ /* api doesn't support state root yet */ } { /* api doesn't support state root yet */ }
{ /* <DetailsInfoItem { /* <DetailsInfoItem
title="State root" title="State root"
hint="The root of the state trie." hint="The root of the state trie"
> >
<Text wordBreak="break-all" whiteSpace="break-spaces">{ data.state_root }</Text> <Text wordBreak="break-all" whiteSpace="break-spaces">{ data.state_root }</Text>
</DetailsInfoItem> */ } </DetailsInfoItem> */ }
<DetailsInfoItem <DetailsInfoItem
title="Nonce" title="Nonce"
hint="Block nonce is a value used during mining to demonstrate proof of work for a block." hint="Block nonce is a value used during mining to demonstrate proof of work for a block"
> >
{ data.nonce } { data.nonce }
</DetailsInfoItem> </DetailsInfoItem>
......
...@@ -86,7 +86,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -86,7 +86,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
{ exchangeRate && ( { exchangeRate && (
<DetailsInfoItem <DetailsInfoItem
title="Price" title="Price"
hint="Price per token on the exchanges." hint="Price per token on the exchanges"
alignSelf="center" alignSelf="center"
> >
{ `$${ exchangeRate }` } { `$${ exchangeRate }` }
...@@ -95,7 +95,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -95,7 +95,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
{ totalValue?.usd && ( { totalValue?.usd && (
<DetailsInfoItem <DetailsInfoItem
title="Fully diluted market cap" title="Fully diluted market cap"
hint="Total supply * Price." hint="Total supply * Price"
alignSelf="center" alignSelf="center"
> >
{ `$${ totalValue?.usd }` } { `$${ totalValue?.usd }` }
...@@ -103,7 +103,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -103,7 +103,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
) } ) }
<DetailsInfoItem <DetailsInfoItem
title="Max total supply" title="Max total supply"
hint="The total amount of tokens issued." hint="The total amount of tokens issued"
alignSelf="center" alignSelf="center"
wordBreak="break-word" wordBreak="break-word"
whiteSpace="pre-wrap" whiteSpace="pre-wrap"
...@@ -112,7 +112,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -112,7 +112,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Holders" title="Holders"
hint="Number of accounts holding the token." hint="Number of accounts holding the token"
alignSelf="center" alignSelf="center"
> >
{ tokenCountersQuery.isLoading && <Skeleton w={ 20 } h={ 4 }/> } { tokenCountersQuery.isLoading && <Skeleton w={ 20 } h={ 4 }/> }
...@@ -120,7 +120,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -120,7 +120,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Transfers" title="Transfers"
hint="Number of transfer for the token." hint="Number of transfer for the token"
alignSelf="center" alignSelf="center"
> >
{ tokenCountersQuery.isLoading && <Skeleton w={ 20 } h={ 4 }/> } { tokenCountersQuery.isLoading && <Skeleton w={ 20 } h={ 4 }/> }
...@@ -129,7 +129,7 @@ const TokenDetails = ({ tokenQuery }: Props) => { ...@@ -129,7 +129,7 @@ const TokenDetails = ({ tokenQuery }: Props) => {
{ decimals && ( { decimals && (
<DetailsInfoItem <DetailsInfoItem
title="Decimals" title="Decimals"
hint="Number of digits that come after the decimal place when displaying token value." hint="Number of digits that come after the decimal place when displaying token value"
alignSelf="center" alignSelf="center"
> >
{ decimals } { decimals }
......
...@@ -38,13 +38,13 @@ const TokenInstanceDetails = ({ data, scrollRef }: Props) => { ...@@ -38,13 +38,13 @@ const TokenInstanceDetails = ({ data, scrollRef }: Props) => {
> >
<DetailsInfoItem <DetailsInfoItem
title="Token" title="Token"
hint="Token name." hint="Token name"
> >
<TokenSnippet hash={ data.token.address } name={ data.token.name }/> <TokenSnippet hash={ data.token.address } name={ data.token.name }/>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Owner" title="Owner"
hint="Current owner of this token instance." hint="Current owner of this token instance"
> >
<Address> <Address>
<AddressIcon address={ data.owner }/> <AddressIcon address={ data.owner }/>
...@@ -55,7 +55,7 @@ const TokenInstanceDetails = ({ data, scrollRef }: Props) => { ...@@ -55,7 +55,7 @@ const TokenInstanceDetails = ({ data, scrollRef }: Props) => {
<TokenInstanceCreatorAddress hash={ data.token.address }/> <TokenInstanceCreatorAddress hash={ data.token.address }/>
<DetailsInfoItem <DetailsInfoItem
title="Token ID" title="Token ID"
hint="This token instance unique token ID." hint="This token instance unique token ID"
> >
<Flex alignItems="center" overflow="hidden"> <Flex alignItems="center" overflow="hidden">
<Box overflow="hidden" display="inline-block" w="100%"> <Box overflow="hidden" display="inline-block" w="100%">
......
...@@ -36,7 +36,7 @@ const TokenInstanceTransfersCount = ({ hash, id, onClick }: Props) => { ...@@ -36,7 +36,7 @@ const TokenInstanceTransfersCount = ({ hash, id, onClick }: Props) => {
return ( return (
<DetailsInfoItem <DetailsInfoItem
title="Transfers" title="Transfers"
hint="Number of transfer for the token instance." hint="Number of transfer for the token instance"
> >
<LinkInternal <LinkInternal
href={ url } href={ url }
......
...@@ -126,7 +126,7 @@ const TxDetails = () => { ...@@ -126,7 +126,7 @@ const TxDetails = () => {
) } ) }
<DetailsInfoItem <DetailsInfoItem
title="Transaction hash" title="Transaction hash"
hint="Unique character string (TxID) assigned to every verified transaction." hint="Unique character string (TxID) assigned to every verified transaction"
flexWrap="nowrap" flexWrap="nowrap"
> >
{ data.status === null && <Spinner mr={ 2 } size="sm" flexShrink={ 0 }/> } { data.status === null && <Spinner mr={ 2 } size="sm" flexShrink={ 0 }/> }
...@@ -146,14 +146,14 @@ const TxDetails = () => { ...@@ -146,14 +146,14 @@ const TxDetails = () => {
{ data.revert_reason && ( { data.revert_reason && (
<DetailsInfoItem <DetailsInfoItem
title="Revert reason" title="Revert reason"
hint="The revert reason of the transaction." hint="The revert reason of the transaction"
> >
<TxRevertReason { ...data.revert_reason }/> <TxRevertReason { ...data.revert_reason }/>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
<DetailsInfoItem <DetailsInfoItem
title="Block" title="Block"
hint="Block number containing the transaction." hint="Block number containing the transaction"
> >
<Text>{ data.block === null ? 'Pending' : data.block }</Text> <Text>{ data.block === null ? 'Pending' : data.block }</Text>
{ Boolean(data.confirmations) && ( { Boolean(data.confirmations) && (
...@@ -168,7 +168,7 @@ const TxDetails = () => { ...@@ -168,7 +168,7 @@ const TxDetails = () => {
{ data.timestamp && ( { data.timestamp && (
<DetailsInfoItem <DetailsInfoItem
title="Timestamp" title="Timestamp"
hint="Date & time of transaction inclusion, including length of time for confirmation." hint="Date & time of transaction inclusion, including length of time for confirmation"
> >
<Icon as={ clockIcon } boxSize={ 5 } color="gray.500"/> <Icon as={ clockIcon } boxSize={ 5 } color="gray.500"/>
<Text ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Text> <Text ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Text>
...@@ -205,7 +205,7 @@ const TxDetails = () => { ...@@ -205,7 +205,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="From" title="From"
hint="Address (external or contract) sending the transaction." hint="Address (external or contract) sending the transaction"
columnGap={ 3 } columnGap={ 3 }
> >
<Address> <Address>
...@@ -222,7 +222,7 @@ const TxDetails = () => { ...@@ -222,7 +222,7 @@ const TxDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title={ data.to?.is_contract ? 'Interacted with contract' : 'To' } title={ data.to?.is_contract ? 'Interacted with contract' : 'To' }
hint="Address (external or contract) receiving the transaction." hint="Address (external or contract) receiving the transaction"
flexWrap={{ base: 'wrap', lg: 'nowrap' }} flexWrap={{ base: 'wrap', lg: 'nowrap' }}
columnGap={ 3 } columnGap={ 3 }
> >
...@@ -257,13 +257,13 @@ const TxDetails = () => { ...@@ -257,13 +257,13 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
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"
> >
<CurrencyValue value={ data.value } currency={ appConfig.network.currency.symbol } exchangeRate={ data.exchange_rate }/> <CurrencyValue value={ data.value } currency={ appConfig.network.currency.symbol } exchangeRate={ data.exchange_rate }/>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Transaction fee" title="Transaction fee"
hint="Total transaction fee." hint="Total transaction fee"
> >
<CurrencyValue <CurrencyValue
value={ data.fee.value } value={ data.fee.value }
...@@ -274,14 +274,14 @@ const TxDetails = () => { ...@@ -274,14 +274,14 @@ const TxDetails = () => {
</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 }>{ BigNumber(data.gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }</Text> <Text mr={ 1 }>{ BigNumber(data.gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }</Text>
<Text variant="secondary">({ BigNumber(data.gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</Text> <Text variant="secondary">({ BigNumber(data.gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</Text>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas limit & usage by txn" title="Gas limit & usage by txn"
hint="Actual gas amount used by the transaction." hint="Actual gas amount used by the transaction"
> >
<Text>{ BigNumber(data.gas_used || 0).toFormat() }</Text> <Text>{ BigNumber(data.gas_used || 0).toFormat() }</Text>
<TextSeparator/> <TextSeparator/>
...@@ -292,7 +292,7 @@ const TxDetails = () => { ...@@ -292,7 +292,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Gas fees (Gwei)" title="Gas fees (Gwei)"
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
hint="Base Fee refers to the network Base Fee at the time of the block, while Max Fee & Max Priority Fee refer to the max amount a user is willing to pay for their tx & to give to the miner respectively." hint="Base Fee refers to the network Base Fee at the time of the block, while Max Fee & Max Priority Fee refer to the max amount a user is willing to pay for their tx & to give to the miner respectively"
> >
{ data.base_fee_per_gas && ( { data.base_fee_per_gas && (
<Box> <Box>
...@@ -319,7 +319,7 @@ const TxDetails = () => { ...@@ -319,7 +319,7 @@ const TxDetails = () => {
{ data.tx_burnt_fee && ( { data.tx_burnt_fee && (
<DetailsInfoItem <DetailsInfoItem
title="Burnt fees" title="Burnt fees"
hint={ `Amount of ${ appConfig.network.currency.symbol } burned for this transaction. Equals Block Base Fee per Gas * Gas Used.` } hint={ `Amount of ${ appConfig.network.currency.symbol } burned for this transaction. Equals Block Base Fee per Gas * Gas Used` }
> >
<Icon as={ flameIcon } mr={ 1 } boxSize={ 5 } color="gray.500"/> <Icon as={ flameIcon } mr={ 1 } boxSize={ 5 } color="gray.500"/>
<CurrencyValue <CurrencyValue
...@@ -349,7 +349,7 @@ const TxDetails = () => { ...@@ -349,7 +349,7 @@ const TxDetails = () => {
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/> <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
<DetailsInfoItem <DetailsInfoItem
title="Other" title="Other"
hint="Other data related to this transaction." hint="Other data related to this transaction"
> >
{ {
[ [
...@@ -382,7 +382,7 @@ const TxDetails = () => { ...@@ -382,7 +382,7 @@ const TxDetails = () => {
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Raw input" title="Raw input"
hint="Binary data included with the transaction. See logs tab for additional info." hint="Binary data included with the transaction. See logs tab for additional info"
> >
<RawInputData hex={ data.raw_input }/> <RawInputData hex={ data.raw_input }/>
</DetailsInfoItem> </DetailsInfoItem>
......
...@@ -17,10 +17,10 @@ interface Props { ...@@ -17,10 +17,10 @@ interface Props {
} }
const TOKEN_TRANSFERS_TYPES = [ const TOKEN_TRANSFERS_TYPES = [
{ title: 'Tokens transferred', hint: 'List of tokens transferred in the transaction.', type: 'token_transfer' }, { title: 'Tokens transferred', hint: 'List of tokens transferred in the transaction', type: 'token_transfer' },
{ title: 'Tokens minted', hint: 'List of tokens minted in the transaction.', type: 'token_minting' }, { title: 'Tokens minted', hint: 'List of tokens minted in the transaction', type: 'token_minting' },
{ title: 'Tokens burnt', hint: 'List of tokens burnt in the transaction.', type: 'token_burning' }, { title: 'Tokens burnt', hint: 'List of tokens burnt in the transaction', type: 'token_burning' },
{ title: 'Tokens created', hint: 'List of tokens created in the transaction.', type: 'token_spawning' }, { title: 'Tokens created', hint: 'List of tokens created in the transaction', type: 'token_spawning' },
]; ];
const VISIBLE_ITEMS_NUM = 3; const VISIBLE_ITEMS_NUM = 3;
......
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