Commit 1f8e6709 authored by tom's avatar tom

DetailedInfo refactoring

parent 6c0e4529
......@@ -14,10 +14,6 @@ interface Props extends LinkProps {
const ID = 'CutLink';
// TODO @tom2drum another variant of CutLink
// ui/tx/TxAllowedPeekers.tsx
// ui/tx/state/TxStateTokenIdList.tsx
const CutLink = (props: Props) => {
const { children, id = ID, onClick, isExpanded: isExpandedProp = false, ...rest } = props;
......
......@@ -5,7 +5,6 @@ import config from 'configs/app';
const heroBannerButton = config.UI.homepage.heroBanner?.button;
const semanticTokens: ThemingConfig['semanticTokens'] = {
// TODO @tom2drum remove *_hover in favor of conditional selectors
colors: {
// NEW TOKENS
button: {
......
......@@ -12,8 +12,8 @@ import ServiceDegradationWarning from 'ui/shared/alerts/ServiceDegradationWarnin
import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
......@@ -103,45 +103,45 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.filecoin?.id && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Short identifier of an address that may change with chain state updates"
>
ID
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ data.filecoin.id }</Text>
<CopyToClipboard text={ data.filecoin.id }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.filecoin?.actor_type && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Identifies the purpose and behavior of the address on the Filecoin network"
>
Actor
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<FilecoinActorTag actorType={ data.filecoin.actor_type }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (data.filecoin?.actor_type === 'evm' || data.filecoin?.actor_type === 'ethaccount') && data?.filecoin?.robust && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="0x-style address to which the Filecoin address is assigned by the Ethereum Address Manager"
>
Ethereum Address
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<AddressEntity
address={{ hash: data.hash }}
noIcon
noLink
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -149,13 +149,13 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.is_contract && data.creation_transaction_hash && (creatorAddressHash) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Transaction and address of creation"
isLoading={ addressQuery.isPlaceholderData }
>
Creator
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={{ hash: creatorAddressHash, filecoin: { robust: data.creator_filecoin_robust_address } }}
truncation="constant"
......@@ -163,7 +163,7 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
/>
<Text whiteSpace="pre"> at txn </Text>
<TxEntity hash={ data.creation_transaction_hash } truncation="constant" noIcon noCopy={ false }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.is_contract && data.implementations && data.implementations?.length > 0 && (
......@@ -177,38 +177,38 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
{ data.has_tokens && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="All tokens in the account and total value"
>
Tokens
</DetailsInfoItem.Label>
<DetailsInfoItem.Value py={ addressQuery.data ? 0 : undefined }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue py={ addressQuery.data ? 0 : undefined }>
{ addressQuery.data ? <TokenSelect onClick={ handleCounterItemClick }/> : <Box>0</Box> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (config.features.multichainButton.isEnabled || (data.exchange_rate && data.has_tokens)) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total net worth in USD of all tokens for the address"
isLoading={ addressQuery.isPlaceholderData }
>
Net worth
</DetailsInfoItem.Label>
<DetailsInfoItem.Value alignSelf="center" py={ 0 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue alignSelf="center" py={ 0 }>
<AddressNetWorth addressData={ addressQuery.data } addressHash={ addressHash } isLoading={ addressQuery.isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
)
}
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of transactions related to this address"
isLoading={ addressQuery.isPlaceholderData || countersQuery.isPlaceholderData }
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ addressQuery.data ? (
<AddressCounterItem
prop="transactions_count"
......@@ -220,17 +220,17 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
/>
) :
0 }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.has_token_transfers && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of transfers to/from this address"
isLoading={ addressQuery.isPlaceholderData || countersQuery.isPlaceholderData }
>
Transfers
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ addressQuery.data ? (
<AddressCounterItem
prop="token_transfers_count"
......@@ -242,19 +242,19 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
/>
) :
0 }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ countersQuery.data?.gas_usage_count && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas used by the address"
isLoading={ addressQuery.isPlaceholderData || countersQuery.isPlaceholderData }
>
Gas used
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ addressQuery.data ? (
<AddressCounterItem
prop="gas_usage_count"
......@@ -272,19 +272,19 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
address={ data.hash }
/>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.has_validated_blocks && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Number of blocks ${ getNetworkValidationActionText() } by this ${ getNetworkValidatorTitle() }` }
isLoading={ addressQuery.isPlaceholderData || countersQuery.isPlaceholderData }
>
{ `Blocks ${ getNetworkValidationActionText() }` }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ addressQuery.data ? (
<AddressCounterItem
prop="validations_count"
......@@ -296,28 +296,28 @@ const AddressDetails = ({ addressQuery, scrollRef }: Props) => {
/>
) :
0 }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.block_number_balance_updated_at && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Block number in which the address was updated"
isLoading={ addressQuery.isPlaceholderData }
>
Last balance update
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BlockEntity
number={ data.block_number_balance_updated_at }
isLoading={ addressQuery.isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsSponsoredItem isLoading={ addressQuery.isPlaceholderData }/>
<DetailedInfoSponsoredItem isLoading={ addressQuery.isPlaceholderData }/>
</Grid>
</>
);
......
......@@ -3,7 +3,7 @@ import React from 'react';
import config from 'configs/app';
import { BECH_32_SEPARATOR, toBech32Address } from 'lib/address/bech32';
import { useSettingsContext } from 'lib/contexts/settings';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
interface Props {
......@@ -24,13 +24,13 @@ const AddressAlternativeFormat = ({ isLoading, addressHash }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ hint }
isLoading={ isLoading }
>
{ label }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={{ hash: altHash }}
isLoading={ isLoading }
......@@ -38,7 +38,7 @@ const AddressAlternativeFormat = ({ isLoading, addressHash }: Props) => {
noLink
noAltHash
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -10,7 +10,7 @@ import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import { currencyUnits } from 'lib/units';
import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import NativeTokenIcon from 'ui/shared/NativeTokenIcon';
interface Props {
......@@ -67,13 +67,13 @@ const AddressBalance = ({ data, isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `${ currencyUnits.ether } balance` }
isLoading={ isLoading }
>
Balance
</DetailsInfoItem.Label>
<DetailsInfoItem.Value alignSelf="center" flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue alignSelf="center" flexWrap="nowrap">
<NativeTokenIcon boxSize={ 6 } mr={ 2 } isLoading={ isLoading }/>
<CurrencyValue
value={ data.coin_balance || '0' }
......@@ -85,7 +85,7 @@ const AddressBalance = ({ data, isLoading }: Props) => {
flexWrap="wrap"
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -2,7 +2,7 @@ import React from 'react';
import type { AddressImplementation } from 'types/api/addressParams';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
interface Props {
......@@ -16,13 +16,13 @@ const AddressImplementations = ({ data, isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Implementation${ hasManyItems ? 's' : '' } address${ hasManyItems ? 'es' : '' } of the proxy contract` }
isLoading={ isLoading }
hasScroll={ hasScroll }
>
{ `Implementation${ hasManyItems ? 's' : '' }` }
</DetailsInfoItem.Label>
</DetailedInfo.ItemLabel>
<DetailsInfoItem.ValueWithScroll
gradientHeight={ 48 }
onScrollVisibilityChange={ setHasScroll }
......
......@@ -3,7 +3,7 @@ import React from 'react';
import type { Address } from 'types/api/address';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
interface Props {
......@@ -15,20 +15,20 @@ const AddressNameInfo = ({ data, isLoading }: Props) => {
if (data.token) {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Token name and symbol"
isLoading={ isLoading }
>
Token name
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenEntity
token={ data.token }
isLoading={ isLoading }
noIcon
noCopy
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
}
......@@ -36,17 +36,17 @@ const AddressNameInfo = ({ data, isLoading }: Props) => {
if (data.is_contract && data.name) {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The name found in the source code of the Contract"
isLoading={ isLoading }
>
Contract name
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isLoading }>
{ data.name }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
}
......@@ -54,17 +54,17 @@ const AddressNameInfo = ({ data, isLoading }: Props) => {
if (data.name) {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The name of the validator"
isLoading={ isLoading }
>
Validator name
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isLoading }>
{ data.name }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
}
......
......@@ -5,9 +5,9 @@ import type { Blob } from 'types/api/blobs';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import BlobData from './BlobData';
......@@ -34,75 +34,75 @@ const BlobInfo = ({ data, isLoading }: Props) => {
{ data.kzg_proof && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Zero knowledge proof. Allows for quick verification of commitment"
isLoading={ isLoading }
>
Proof
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isLoading } overflow="hidden" whiteSpace="pre-wrap" wordBreak="break-all" lineHeight={ 6 } my="-2px">
{ data.kzg_proof }
<CopyToClipboard text={ data.kzg_proof } isLoading={ isLoading }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.kzg_commitment && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Commitment to the data in the blob"
isLoading={ isLoading }
>
Commitment
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isLoading } overflow="hidden" whiteSpace="pre-wrap" wordBreak="break-all" lineHeight={ 6 } my="-2px">
{ data.kzg_commitment }
<CopyToClipboard text={ data.kzg_commitment } isLoading={ isLoading }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.blob_data && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Blob size in bytes"
isLoading={ isLoading }
>
Size, bytes
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isLoading } overflow="hidden" whiteSpace="pre-wrap" wordBreak="break-all">
{ (data.blob_data.replace('0x', '').length / 2).toLocaleString() }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.blob_data && <DetailsInfoItemDivider/> }
{ data.blob_data && <DetailedInfo.ItemDivider/> }
{ data.transaction_hashes[0] && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Hash of the transaction with this blob"
isLoading={ isLoading }
>
Transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntity hash={ data.transaction_hashes[0].transaction_hash } isLoading={ isLoading } noIcon noCopy={ false }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsSponsoredItem isLoading={ isLoading }/>
<DetailedInfoSponsoredItem isLoading={ isLoading }/>
{ data.blob_data && (
<>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<BlobData data={ data.blob_data } hash={ data.hash } isLoading={ isLoading }/>
</>
) }
......
import { Grid, GridItem, Text, Box } from '@chakra-ui/react';
import { GridItem, Text, Box } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { capitalize } from 'es-toolkit';
import { useRouter } from 'next/router';
......@@ -24,9 +24,8 @@ import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
......@@ -149,19 +148,14 @@ const BlockDetails = ({ query }: Props) => {
})();
return (
<Grid
columnGap={ 8 }
rowGap={{ base: 3, lg: 3 }}
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.Container templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }} >
<DetailedInfo.ItemLabel
hint="The block height of a particular block is defined as the number of blocks preceding it in the blockchain"
isLoading={ isPlaceholderData }
>
{ blockTypeLabel } height
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ data.height }
</Skeleton>
......@@ -174,47 +168,47 @@ const BlockDetails = ({ query }: Props) => {
isPrevDisabled={ data.height === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ rollupFeature.isEnabled && rollupFeature.type === 'arbitrum' && data.arbitrum && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The most recent L1 block height as of this L2 block"
isLoading={ isPlaceholderData }
>
L1 block height
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BlockEntityL1 isLoading={ isPlaceholderData } number={ data.arbitrum.l1_block_height }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ rollupFeature.isEnabled && rollupFeature.type === 'arbitrum' && data.arbitrum && !config.UI.views.block.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch number"
isLoading={ isPlaceholderData }
>
Batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.batch_number ?
<BatchEntityL2 isLoading={ isPlaceholderData } number={ data.arbitrum.batch_number }/> :
<Skeleton loading={ isPlaceholderData }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ rollupFeature.isEnabled && rollupFeature.type === 'optimistic' && data.optimism && !config.UI.views.block.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch number"
isLoading={ isPlaceholderData }
>
Batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value columnGap={ 3 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue columnGap={ 3 }>
{ data.optimism.internal_id ?
<BatchEntityL2 isLoading={ isPlaceholderData } number={ data.optimism.internal_id }/> :
<Skeleton loading={ isPlaceholderData }>Pending</Skeleton> }
......@@ -224,88 +218,88 @@ const BlockDetails = ({ query }: Props) => {
isLoading={ isPlaceholderData }
/>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Size of the block in bytes"
isLoading={ isPlaceholderData }
>
Size
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ data.size.toLocaleString() }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Date & time at which block was produced."
isLoading={ isPlaceholderData }
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<DetailsTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<DetailedInfoTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The number of transactions in the block"
isLoading={ isPlaceholderData }
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ txsNum }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ config.features.beaconChain.isEnabled && Boolean(data.withdrawals_count) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The number of beacon withdrawals in the block"
isLoading={ isPlaceholderData }
>
Withdrawals
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
<Link href={ route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: heightOrHash, tab: 'withdrawals' } }) }>
{ data.withdrawals_count } withdrawal{ data.withdrawals_count === 1 ? '' : 's' }
</Link>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ rollupFeature.isEnabled && rollupFeature.type === 'zkSync' && data.zksync && !config.UI.views.block.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch number"
isLoading={ isPlaceholderData }
>
Batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.zksync.batch_number ?
<BatchEntityL2 isLoading={ isPlaceholderData } number={ data.zksync.batch_number }/> :
<Skeleton loading={ isPlaceholderData }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.block.hiddenFields?.L1_status && rollupFeature.isEnabled &&
((rollupFeature.type === 'zkSync' && data.zksync) || (rollupFeature.type === 'arbitrum' && data.arbitrum)) &&
(
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Status is the short interpretation of the batch lifecycle"
isLoading={ isPlaceholderData }
>
Status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ rollupFeature.type === 'zkSync' && data.zksync &&
<VerificationSteps steps={ ZKSYNC_L2_TX_BATCH_STATUSES } currentStep={ data.zksync.status } isLoading={ isPlaceholderData }/> }
{ rollupFeature.type === 'arbitrum' && data.arbitrum && (
......@@ -316,24 +310,24 @@ const BlockDetails = ({ query }: Props) => {
isLoading={ isPlaceholderData }
/>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.block.hiddenFields?.miner && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="A block producer who successfully included the block onto the blockchain"
isLoading={ isPlaceholderData }
>
{ verificationTitle }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={ data.miner }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -341,33 +335,33 @@ const BlockDetails = ({ query }: Props) => {
(data.arbitrum?.commitment_transaction.hash || data.arbitrum?.confirmation_transaction.hash) &&
(
<>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ data.arbitrum?.commitment_transaction.hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 transaction containing this batch commitment"
isLoading={ isPlaceholderData }
>
Commitment tx
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1 hash={ data.arbitrum?.commitment_transaction.hash } isLoading={ isPlaceholderData }/>
{ data.arbitrum?.commitment_transaction.status === 'finalized' && <StatusTag type="ok" text="Finalized" ml={ 2 }/> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.arbitrum?.confirmation_transaction.hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 transaction containing confirmation of this batch"
isLoading={ isPlaceholderData }
>
Confirmation tx
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1 hash={ data.arbitrum?.confirmation_transaction.hash } isLoading={ isPlaceholderData }/>
{ data.arbitrum?.commitment_transaction.status === 'finalized' && <StatusTag type="ok" text="Finalized" ml={ 2 }/> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</>
......@@ -375,7 +369,7 @@ const BlockDetails = ({ query }: Props) => {
{ !rollupFeature.isEnabled && !totalReward.isEqualTo(ZERO) && !config.UI.views.block.hiddenFields?.total_reward && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={
`For each block, the ${ validatorTitle } is rewarded with a finite amount of ${ config.chain.currency.symbol || 'native token' }
on top of the fees paid for all transactions in the block`
......@@ -383,13 +377,13 @@ const BlockDetails = ({ query }: Props) => {
isLoading={ isPlaceholderData }
>
Block reward
</DetailsInfoItem.Label>
<DetailsInfoItem.Value columnGap={ 1 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue columnGap={ 1 }>
<Skeleton loading={ isPlaceholderData }>
{ totalReward.dividedBy(WEI).toFixed() } { currencyUnits.ether }
</Skeleton>
{ rewardBreakDown }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -397,45 +391,45 @@ const BlockDetails = ({ query }: Props) => {
?.filter(({ type }) => type !== 'Validator Reward' && type !== 'Miner Reward')
.map(({ type, reward }) => (
<React.Fragment key={ type }>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Amount of distributed reward. ${ capitalize(validatorTitle) }s receive a static block reward + Tx fees + uncle fees` }
>
{ type }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(reward).dividedBy(WEI).toFixed() } { currencyUnits.ether }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</React.Fragment>
))
}
{ typeof data.zilliqa?.view === 'number' && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The iteration of the consensus round in which the block was proposed"
isLoading={ isPlaceholderData }
>
View
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ data.zilliqa.view }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ data.celo?.base_fee && <BlockDetailsBaseFeeCelo data={ data.celo.base_fee }/> }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The total gas amount used in the block and its percentage of gas filled in the block"
isLoading={ isPlaceholderData }
>
Gas used
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.gas_used || 0).toFormat() }
</Skeleton>
......@@ -446,45 +440,45 @@ const BlockDetails = ({ query }: Props) => {
ml={ 4 }
gasTarget={ data.gas_target_percentage || undefined }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total gas limit provided by all transactions in the block"
isLoading={ isPlaceholderData }
>
Gas limit
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.gas_limit).toFormat() }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.minimum_gas_price && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The minimum gas price a transaction should have in order to be included in this block"
isLoading={ isPlaceholderData }
>
Minimum gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.minimum_gas_price).dividedBy(GWEI).toFormat() } { currencyUnits.gwei }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.base_fee_per_gas && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Minimum fee required per unit of gas. Fee adjusts based on network congestion"
isLoading={ isPlaceholderData }
>
Base fee per gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ isPlaceholderData ? (
<Skeleton loading={ isPlaceholderData } h="20px" maxW="380px" w="100%"/>
) : (
......@@ -495,13 +489,13 @@ const BlockDetails = ({ query }: Props) => {
</Text>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.block.hiddenFields?.burnt_fees && !burntFees.isEqualTo(ZERO) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={
`Amount of ${ config.chain.currency.symbol || 'native token' } burned from transactions included in the block.
Equals Block Base Fee per Gas * Gas Used`
......@@ -509,8 +503,8 @@ const BlockDetails = ({ query }: Props) => {
isLoading={ isPlaceholderData }
>
Burnt fees
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<IconSvg name="flame" boxSize={ 5 } color="gray.500" isLoading={ isPlaceholderData }/>
<Skeleton loading={ isPlaceholderData } ml={ 2 }>
{ burntFees.dividedBy(WEI).toFixed() } { currencyUnits.ether }
......@@ -524,23 +518,23 @@ const BlockDetails = ({ query }: Props) => {
/>
</Tooltip>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.priority_fee !== null && BigNumber(data.priority_fee).gt(ZERO) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="User-defined tips sent to validator for transaction priority/inclusion"
isLoading={ isPlaceholderData }
>
Priority fee / Tip
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.priority_fee).dividedBy(WEI).toFixed() } { currencyUnits.ether }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -555,12 +549,12 @@ const BlockDetails = ({ query }: Props) => {
{ data.bitcoin_merged_mining_header && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Merged-mining field: Bitcoin header"
>
Bitcoin merged mining header
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
alignSelf="flex-start"
>
......@@ -568,54 +562,54 @@ const BlockDetails = ({ query }: Props) => {
<HashStringShortenDynamic hash={ data.bitcoin_merged_mining_header }/>
</Box>
<CopyToClipboard text={ data.bitcoin_merged_mining_header }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.bitcoin_merged_mining_coinbase_transaction && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Merged-mining field: Coinbase transaction"
>
Bitcoin merged mining coinbase transaction
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<RawDataSnippet
data={ data.bitcoin_merged_mining_coinbase_transaction }
isLoading={ isPlaceholderData }
showCopy={ false }
textareaMaxHeight="100px"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.bitcoin_merged_mining_merkle_proof && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Merged-mining field: Merkle proof"
>
Bitcoin merged mining Merkle proof
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<RawDataSnippet
data={ data.bitcoin_merged_mining_merkle_proof }
isLoading={ isPlaceholderData }
showCopy={ false }
textareaMaxHeight="100px"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.hash_for_merged_mining && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Merged-mining field: Rootstock block header hash"
>
Hash for merged mining
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
alignSelf="flex-start"
>
......@@ -623,54 +617,54 @@ const BlockDetails = ({ query }: Props) => {
<HashStringShortenDynamic hash={ data.hash_for_merged_mining }/>
</Box>
<CopyToClipboard text={ data.hash_for_merged_mining }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Block difficulty for ${ validatorTitle }, used to calibrate block generation time` }
>
Difficulty
</DetailsInfoItem.Label>
<DetailsInfoItem.Value overflow="hidden">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue overflow="hidden">
<HashStringShortenDynamic hash={ BigNumber(data.difficulty).toFormat() }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.total_difficulty && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total difficulty of the chain until this block"
>
Total difficulty
</DetailsInfoItem.Label>
<DetailsInfoItem.Value overflow="hidden">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue overflow="hidden">
<HashStringShortenDynamic hash={ BigNumber(data.total_difficulty).toFormat() }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The SHA256 hash of the block"
>
Hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<Box overflow="hidden" >
<HashStringShortenDynamic hash={ data.hash }/>
</Box>
<CopyToClipboard text={ data.hash }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.height > 0 && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The hash of the block from which this block was generated"
>
Parent hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<Link
href={ route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: String(data.height - 1) } }) }
overflow="hidden"
......@@ -681,60 +675,60 @@ const BlockDetails = ({ query }: Props) => {
/>
</Link>
<CopyToClipboard text={ data.parent_hash }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ rollupFeature.isEnabled && rollupFeature.type === 'arbitrum' && data.arbitrum && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The cumulative number of L2 to L1 transactions as of this block"
isLoading={ isPlaceholderData }
>
Send count
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.send_count.toLocaleString() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The root of the Merkle accumulator representing all L2 to L1 transactions as of this block"
isLoading={ isPlaceholderData }
>
Send root
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.send_root }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The number of delayed L1 to L2 messages read as of this block"
isLoading={ isPlaceholderData }
>
Delayed messages
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.delayed_messages.toLocaleString() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.block.hiddenFields?.nonce && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Block nonce is a value used during mining to demonstrate proof of work for a block"
>
Nonce
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.nonce }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zilliqa && (
<>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<BlockDetailsZilliqaQuorumCertificate data={ data.zilliqa?.quorum_certificate }/>
{ data.zilliqa?.aggregate_quorum_certificate && (
<>
......@@ -746,7 +740,7 @@ const BlockDetails = ({ query }: Props) => {
) }
</CutLinkDetails>
</Grid>
</DetailedInfo.Container>
);
};
......
......@@ -9,8 +9,8 @@ import type { TokenInfo } from 'types/api/token';
import { WEI, ZERO_ADDRESS } from 'lib/consts';
import { Link } from 'toolkit/chakra/link';
import AddressFromTo from 'ui/shared/address/AddressFromTo';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import IconSvg from 'ui/shared/IconSvg';
......@@ -58,18 +58,18 @@ const BlockDetailsBaseFeeCelo = ({ data }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The contract receiving the base fee, responsible for handling fee usage. This contract is controlled by governance process."
>
Base fee handler
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity address={ data.recipient }/>
</DetailsInfoItem.Value>
<DetailsInfoItem.Label hint={ totalFeeLabel }>
</DetailedInfo.ItemValue>
<DetailedInfo.ItemLabel hint={ totalFeeLabel }>
Base fee total
</DetailsInfoItem.Label>
<DetailsInfoItem.Value display="block">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue display="block">
<Flex columnGap={ 2 }>
{ totalBaseFee }
<TokenEntity token={ data.token } noCopy onlySymbol/>
......@@ -86,8 +86,8 @@ const BlockDetailsBaseFeeCelo = ({ data }: Props) => {
)) }
</Flex>
) }
</DetailsInfoItem.Value>
<DetailsInfoItemDivider/>
</DetailedInfo.ItemValue>
<DetailedInfo.ItemDivider/>
</>
);
};
......
......@@ -8,8 +8,8 @@ import { WEI, WEI_IN_GWEI, ZERO } from 'lib/consts';
import { space } from 'lib/html-entities';
import { currencyUnits } from 'lib/units';
import { Tooltip } from 'toolkit/chakra/tooltip';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import IconSvg from 'ui/shared/IconSvg';
import Utilization from 'ui/shared/Utilization/Utilization';
......@@ -35,40 +35,40 @@ const BlockDetailsBlobInfo = ({ data }: Props) => {
{ data.blob_gas_price && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
// eslint-disable-next-line max-len
hint="Price per unit of gas used for for blob deployment. Blob gas is independent of normal gas. Both gas prices can affect the priority of transaction execution."
>
Blob gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.blob_gas_price).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text color="text.secondary" whiteSpace="pre">
{ space }({ BigNumber(data.blob_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.blob_gas_used && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Actual amount of gas used by the blobs in this block"
>
Blob gas used
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.blob_gas_used).toFormat() }</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !burntBlobFees.isEqualTo(ZERO) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Amount of ${ currencyUnits.ether } used for blobs in this block` }
>
Blob burnt fees
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<IconSvg name="flame" boxSize={ 5 } color="gray.500" mr={ 2 }/>
{ burntBlobFees.dividedBy(WEI).toFixed() } { currencyUnits.ether }
{ !blobFees.isEqualTo(ZERO) && (
......@@ -76,25 +76,25 @@ const BlockDetailsBlobInfo = ({ data }: Props) => {
<Utilization ml={ 4 } value={ burntBlobFees.dividedBy(blobFees).toNumber() }/>
</Tooltip>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.excess_blob_gas && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="A running total of blob gas consumed in excess of the target, prior to the block."
>
Excess blob gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.excess_blob_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text color="text.secondary" whiteSpace="pre">
{ space }({ BigNumber(data.excess_blob_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
</>
);
};
......
......@@ -5,8 +5,8 @@ import type { ZilliqaNestedQuorumCertificate, ZilliqaQuorumCertificate } from 't
import { apos, ndash } from 'lib/html-entities';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import Hint from 'ui/shared/Hint';
function formatSigners(signers: Array<number>) {
......@@ -39,12 +39,12 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ hint() }
>
{ data.nested_quorum_certificates ? 'Aggregate quorum certificate' : 'Quorum certificate' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value rowGap={ 0 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue rowGap={ 0 }>
<Grid
fontSize="sm"
lineHeight={ 5 }
......@@ -53,13 +53,13 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
>
<GridItem fontWeight={ 600 }>View</GridItem>
<GridItem>{ data.view }</GridItem>
<DetailsInfoItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/>
<DetailedInfo.ItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/>
<GridItem fontWeight={ 600 }>Signature</GridItem>
<GridItem whiteSpace="pre-wrap" wordBreak="break-word" display="flex" alignItems="flex-start" columnGap={ 5 }>
{ data.signature }
<CopyToClipboard text={ data.signature }/>
</GridItem>
<DetailsInfoItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/>
<DetailedInfo.ItemDivider my={{ base: 2, lg: 2 }} colSpan={ 2 }/>
<GridItem fontWeight={ 600 }>Signers</GridItem>
<GridItem >{ formatSigners(data.signers) }</GridItem>
</Grid>
......@@ -123,7 +123,7 @@ const BlockDetailsZilliqaQuorumCertificate = ({ data }: Props) => {
</Accordion>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -4,7 +4,7 @@ import React from 'react';
import type { BlockEpoch } from 'types/api/block';
import useIsMobile from 'lib/hooks/useIsMobile';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TokenTransferSnippet from 'ui/shared/TokenTransferSnippet/TokenTransferSnippet';
interface Props {
......@@ -28,41 +28,41 @@ const BlockEpochRewardsDistribution = ({ data, isLoading }: Props) => {
>
{ data.distribution.community_transfer && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Funds allocation to support Celo projects and community initiatives"
isLoading={ isLoading }
>
Community fund
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenTransferSnippet data={ data.distribution.community_transfer } isLoading={ isLoading } noAddressIcons={ isMobile }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.distribution.carbon_offsetting_transfer && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Funds allocation to support projects that make Celo carbon-negative"
isLoading={ isLoading }
>
Carbon offset fund
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenTransferSnippet data={ data.distribution.carbon_offsetting_transfer } isLoading={ isLoading } noAddressIcons={ isMobile }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.distribution.reserve_bolster_transfer && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Funds allocation to strengthen Celo’s reserve for network stability and security"
isLoading={ isLoading }
>
Reserve bolster
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenTransferSnippet data={ data.distribution.reserve_bolster_transfer } isLoading={ isLoading } noAddressIcons={ isMobile }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</Grid>
......
......@@ -11,7 +11,7 @@ import type { ResourceError } from 'lib/api/resources';
import dayjs from 'lib/date/dayjs';
import stripTrailingSlash from 'lib/stripTrailingSlash';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import IconSvg from 'ui/shared/IconSvg';
......@@ -37,31 +37,31 @@ const NameDomainDetails = ({ query }: Props) => {
<Grid columnGap={ 8 } rowGap={ 3 } templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
{ query.data?.registration_date && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The date the name was registered"
isLoading={ isLoading }
>
Registration date
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 }/>
<Skeleton isLoaded={ !isLoading } display="inline" whiteSpace="pre-wrap" lineHeight="20px">
{ dayjs(query.data.registration_date).format('llll') }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ query.data?.expiry_date && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
// eslint-disable-next-line max-len
hint="The date the name expires, upon which there is a grace period for the owner to renew. After grace period ends, the name is released to the market"
isLoading={ isLoading }
>
Expiration date
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<IconSvg name="clock" boxSize={ 5 } color="gray.500" verticalAlign="middle" isLoading={ isLoading } mr={ 2 } mt="-2px"/>
{ hasExpired && (
<>
......@@ -78,37 +78,37 @@ const NameDomainDetails = ({ query }: Props) => {
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline">
<NameDomainExpiryStatus date={ query.data?.expiry_date }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ query.data?.resolver_address && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The resolver contract provides information about a domain name"
isLoading={ isLoading }
>
Resolver
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
>
<AddressEntity
address={ query.data.resolver_address }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ query.data?.registrant && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The account that owns the domain name and has the rights to edit its ownership and records"
isLoading={ isLoading }
>
Registrant
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
columnGap={ 2 }
flexWrap="nowrap"
>
......@@ -125,19 +125,19 @@ const NameDomainDetails = ({ query }: Props) => {
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal>
</Tooltip>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ query.data?.owner && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The account that owns the rights to edit the records of this domain name"
isLoading={ isLoading }
>
Owner
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
columnGap={ 2 }
flexWrap="nowrap"
>
......@@ -154,19 +154,19 @@ const NameDomainDetails = ({ query }: Props) => {
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal>
</Tooltip>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ query.data?.wrapped_owner && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Owner of this NFT domain in NameWrapper contract"
isLoading={ isLoading }
>
Manager
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
columnGap={ 2 }
flexWrap="nowrap"
>
......@@ -183,7 +183,7 @@ const NameDomainDetails = ({ query }: Props) => {
<IconSvg name="search" boxSize={ 5 } isLoading={ isLoading }/>
</LinkInternal>
</Tooltip>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -199,31 +199,31 @@ const NameDomainDetails = ({ query }: Props) => {
return (
<React.Fragment key={ token.type }>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `The ${ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'wrapped ' : '' }token ID of this domain name NFT` }
isLoading={ isLoading }
>
{ token.type === bens.TokenType.WRAPPED_DOMAIN_TOKEN ? 'Wrapped token ID' : 'Token ID' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
wordBreak="break-all"
whiteSpace="pre-wrap"
>
<NftEntity { ...entityProps } hash={ token.contract_hash } id={ token.id } isLoading={ isLoading } noIcon/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</React.Fragment>
);
}) }
{ otherAddresses.length > 0 && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Other cryptocurrency addresses added to this domain name"
isLoading={ isLoading }
>
Other addresses
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexDir="column"
alignItems="flex-start"
>
......@@ -238,7 +238,7 @@ const NameDomainDetails = ({ query }: Props) => {
/>
</Flex>
)) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</Grid>
......
......@@ -4,8 +4,8 @@ import React from 'react';
import type { Pool } from 'types/api/pools';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
type Props = {
......@@ -21,13 +21,13 @@ const PoolInfo = ({ data, isPlaceholderData }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="The base token in a liquidity pool pair"
>
Base token
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenEntity
token={{
type: 'ERC-20',
......@@ -38,15 +38,15 @@ const PoolInfo = ({ data, isPlaceholderData }: Props) => {
}}
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="The quote token in a liquidity pool pair"
>
Quote token
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TokenEntity
token={{
type: 'ERC-20',
......@@ -57,57 +57,57 @@ const PoolInfo = ({ data, isPlaceholderData }: Props) => {
}}
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Fully Diluted Valuation: theoretical market cap if all tokens were in circulation"
>
FDV
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
${ Number(data.fully_diluted_valuation_usd).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }) }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Current market capitalization of the pool"
>
Market cap
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
${ Number(data.market_cap_usd).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }) }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Current liquidity of the pool"
>
Liquidity
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
${ Number(data.liquidity).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }) }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="DEX where the pool is traded"
>
DEX
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.dex.name }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsSponsoredItem isLoading={ isPlaceholderData }/>
<DetailedInfoSponsoredItem isLoading={ isPlaceholderData }/>
</Grid>
);
};
......
import type { FlexProps } from '@chakra-ui/react';
import { Flex, chakra } from '@chakra-ui/react';
import React from 'react';
export type Props = {
children: React.ReactNode;
export interface Props extends FlexProps {
gradientHeight: number;
className?: string;
onScrollVisibilityChange?: (isVisible: boolean) => void;
};
const ContainerWithScrollY = ({ className, gradientHeight, children, onScrollVisibilityChange }: Props) => {
const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChange, ...rest }: Props) => {
const ref = React.useRef<HTMLDivElement>(null);
const [ hasScroll, setHasScroll ] = React.useState(false);
......@@ -25,7 +24,6 @@ const ContainerWithScrollY = ({ className, gradientHeight, children, onScrollVis
return (
<Flex
flexDirection="column"
className={ className }
overflowY={ hasScroll ? 'scroll' : 'auto' }
ref={ ref }
_after={ hasScroll ? {
......@@ -39,6 +37,7 @@ const ContainerWithScrollY = ({ className, gradientHeight, children, onScrollVis
} : undefined }
pr={ hasScroll ? 5 : 0 }
pb={ hasScroll ? `${ gradientHeight }px` : 0 }
{ ...rest }
>
{ children }
</Flex>
......
import { chakra, GridItem, Flex, Text } from '@chakra-ui/react';
import type { GridItemProps, GridProps } from '@chakra-ui/react';
import { Flex, Grid, GridItem, Text } from '@chakra-ui/react';
import React from 'react';
import { Skeleton } from 'toolkit/chakra/skeleton';
import * as ContainerWithScrollY from 'ui/shared/ContainerWithScrollY';
import Hint from 'ui/shared/Hint';
const LabelScrollText = () => (
<Text fontWeight={ 500 } color="text.secondary" fontSize="xs" className="note" textAlign="right">
Scroll to see more
</Text>
);
export const Container = (props: GridProps) => {
return (
<Grid
columnGap={ 8 }
rowGap={{ base: 1, lg: 3 }}
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }}
{ ...props }
/>
);
};
interface LabelProps {
interface ItemLabelProps extends GridItemProps {
hint?: React.ReactNode;
children: React.ReactNode;
isLoading?: boolean;
className?: string;
id?: string;
hasScroll?: boolean;
}
const Label = chakra(({ hint, children, isLoading, id, className, hasScroll }: LabelProps) => {
const ItemLabelScrollText = () => (
<Text fontWeight={ 500 } color="text.secondary" textStyle="xs" className="note" textAlign="right">
Scroll to see more
</Text>
);
export const ItemLabel = ({ hint, children, isLoading, id, hasScroll, ...rest }: ItemLabelProps) => {
return (
<GridItem
id={ id }
className={ className }
py={ 1 }
textStyle="md"
_notFirst={{ mt: { base: 3, lg: 0 } }}
{ ...rest }
>
<Flex columnGap={ 2 } alignItems="flex-start">
{ hint && <Hint label={ hint } isLoading={ isLoading } my={{ lg: '2px' }}/> }
{ hint && <Hint label={ hint } isLoading={ isLoading } my="2px"/> }
<Skeleton loading={ isLoading } fontWeight={{ base: 700, lg: 500 }}>
{ children }
{ hasScroll && <LabelScrollText/> }
{ hasScroll && <ItemLabelScrollText/> }
</Skeleton>
</Flex>
</GridItem>
);
});
};
interface ValueProps {
interface ItemValueProps extends GridItemProps {
children: React.ReactNode;
className?: string;
}
const Value = chakra(({ children, className }: ValueProps) => {
export const ItemValue = ({ children, ...rest }: ItemValueProps) => {
return (
<GridItem
className={ className }
display="flex"
alignItems="center"
flexWrap="wrap"
......@@ -57,15 +66,16 @@ const Value = chakra(({ children, className }: ValueProps) => {
py={ 1 }
textStyle="md"
whiteSpace="nowrap"
{ ...rest }
>
{ children }
</GridItem>
);
});
};
const ValueWithScroll = chakra(({ children, gradientHeight, onScrollVisibilityChange, className }: ContainerWithScrollY.Props) => {
export const ItemValueWithScroll = ({ children, gradientHeight, onScrollVisibilityChange, className }: ContainerWithScrollY.Props) => {
return (
<Value position="relative">
<ItemValue position="relative">
<ContainerWithScrollY.default
className={ className }
gradientHeight={ gradientHeight }
......@@ -73,12 +83,20 @@ const ValueWithScroll = chakra(({ children, gradientHeight, onScrollVisibilityCh
>
{ children }
</ContainerWithScrollY.default>
</Value>
</ItemValue>
);
});
};
export {
Label,
Value,
ValueWithScroll,
export const ItemDivider = (props: GridItemProps) => {
const { colSpan = { base: undefined, lg: 2 }, ...rest } = props;
return (
<GridItem
colSpan={ colSpan }
mt={{ base: 2, lg: 3 }}
mb={{ base: 0, lg: 3 }}
borderBottom="1px solid"
borderColor="border.divider"
{ ...rest }
/>
);
};
import React from 'react';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from './DetailedInfo';
export const TX_ACTIONS_BLOCK_ID = 'tx-actions';
......@@ -10,20 +10,20 @@ type Props = {
type: 'tx' | 'user_op';
};
const DetailsActionsWrapper = ({ children, isLoading, type }: Props) => {
const DetailedInfoActionsWrapper = ({ children, isLoading, type }: Props) => {
const [ hasScroll, setHasScroll ] = React.useState(false);
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
id={ TX_ACTIONS_BLOCK_ID }
hint={ `Highlighted events of the ${ type === 'tx' ? 'transaction' : 'user operation' }` }
isLoading={ isLoading }
hasScroll={ hasScroll }
>
<span>{ `${ type === 'tx' ? 'Transaction' : 'User operation' } action` }</span>
</DetailsInfoItem.Label>
<DetailsInfoItem.ValueWithScroll
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValueWithScroll
gradientHeight={ 48 }
onScrollVisibilityChange={ setHasScroll }
alignItems="stretch"
......@@ -32,10 +32,10 @@ const DetailsActionsWrapper = ({ children, isLoading, type }: Props) => {
maxH="200px"
>
{ children }
</DetailsInfoItem.ValueWithScroll>
</DetailedInfo.ItemValueWithScroll>
</>
);
};
export default React.memo(DetailsActionsWrapper);
export default React.memo(DetailedInfoActionsWrapper);
......@@ -5,7 +5,8 @@ import config from 'configs/app';
import * as cookies from 'lib/cookies';
import useIsMobile from 'lib/hooks/useIsMobile';
import AdBanner from 'ui/shared/ad/AdBanner';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from './DetailedInfo';
const feature = config.features.adsBanner;
......@@ -13,7 +14,7 @@ interface Props {
isLoading?: boolean;
}
const DetailsSponsoredItem = ({ isLoading }: Props) => {
const DetailedInfoSponsoredItem = ({ isLoading }: Props) => {
const isMobile = useIsMobile();
const hasAdblockCookie = cookies.get(cookies.NAMES.ADBLOCK_DETECTED);
......@@ -31,17 +32,17 @@ const DetailsSponsoredItem = ({ isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Sponsored banner advertisement"
isLoading={ isLoading }
>
Sponsored
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AdBanner isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
export default React.memo(DetailsSponsoredItem);
export default React.memo(DetailedInfoSponsoredItem);
......@@ -11,7 +11,7 @@ type Props = {
isLoading?: boolean;
};
const DetailsTimestamp = ({ timestamp, isLoading }: Props) => {
const DetailedInfoTimestamp = ({ timestamp, isLoading }: Props) => {
return (
<>
<IconSvg name="clock" boxSize={ 5 } color="gray.500" isLoading={ isLoading }/>
......@@ -26,4 +26,4 @@ const DetailsTimestamp = ({ timestamp, isLoading }: Props) => {
);
};
export default DetailsTimestamp;
export default DetailedInfoTimestamp;
import type { GridItemProps } from '@chakra-ui/react';
import { GridItem, chakra } from '@chakra-ui/react';
import React from 'react';
interface Props {
className?: string;
id?: string;
colSpan?: GridItemProps['colSpan'];
}
const DetailsInfoItemDivider = ({ className, id, colSpan }: Props) => {
return (
<GridItem
id={ id }
className={ className }
colSpan={ colSpan || { base: undefined, lg: 2 } }
mt={{ base: 2, lg: 3 }}
mb={{ base: 0, lg: 3 }}
borderBottom="1px solid"
borderColor="border.divider"
/>
);
};
export default chakra(DetailsInfoItemDivider);
......@@ -2,7 +2,6 @@ import { chakra } from '@chakra-ui/react';
import React from 'react';
import { IconButton } from 'toolkit/chakra/icon-button';
import { Skeleton } from 'toolkit/chakra/skeleton';
import type { TooltipProps } from 'toolkit/chakra/tooltip';
import { Tooltip } from 'toolkit/chakra/tooltip';
import IconSvg from 'ui/shared/IconSvg';
......@@ -15,19 +14,6 @@ interface Props {
}
const Hint = ({ label, className, tooltipProps, isLoading }: Props) => {
// TODO @tom2drum check and remove this
// have to implement controlled tooltip because of the issue - https://github.com/chakra-ui/chakra-ui/issues/7107
// const { open, onOpen, onToggle, onClose } = useDisclosure();
// const handleClick = React.useCallback((event: React.MouseEvent) => {
// event.stopPropagation();
// onToggle();
// }, [ onToggle ]);
if (isLoading) {
return <Skeleton className={ className } boxSize={ 5 } borderRadius="sm"/>;
}
return (
<Tooltip
content={ label }
......@@ -39,9 +25,8 @@ const Hint = ({ label, className, tooltipProps, isLoading }: Props) => {
aria-label="hint"
boxSize={ 5 }
className={ className }
// onMouseEnter={ onOpen }
// onMouseLeave={ onClose }
// onClick={ handleClick }
loading={ isLoading }
borderRadius="sm"
>
<IconSvg name="info" w="100%" h="100%" color="icon_info" _hover={{ color: 'link.primary.hover' }}/>
</IconButton>
......
......@@ -18,8 +18,8 @@ import type { TokenTabs } from 'ui/pages/Token';
import AppActionButton from 'ui/shared/AppActionButton/AppActionButton';
import useAppActionData from 'ui/shared/AppActionButton/useAppActionData';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import TruncatedValue from 'ui/shared/TruncatedValue';
import TokenNftMarketplaces from './TokenNftMarketplaces';
......@@ -105,43 +105,43 @@ const TokenDetails = ({ tokenQuery }: Props) => {
>
{ exchangeRate && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Price per token on the exchanges"
isLoading={ tokenQuery.isPlaceholderData }
>
Price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !tokenQuery.isPlaceholderData } display="inline-block">
<span>{ `$${ Number(exchangeRate).toLocaleString(undefined, { minimumSignificantDigits: 4 }) }` }</span>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ marketCap && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total supply * Price"
isLoading={ tokenQuery.isPlaceholderData }
>
Fully diluted market cap
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !tokenQuery.isPlaceholderData } display="inline-block">
<span>{ `$${ BigNumber(marketCap).toFormat() }` }</span>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The total amount of tokens issued"
isLoading={ tokenQuery.isPlaceholderData }
>
Max total supply
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
alignSelf="center"
wordBreak="break-word"
whiteSpace="pre-wrap"
......@@ -151,45 +151,45 @@ const TokenDetails = ({ tokenQuery }: Props) => {
<Box flexShrink={ 0 }> </Box>
<TruncatedValue value={ symbol || '' }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of accounts holding the token"
isLoading={ tokenQuery.isPlaceholderData }
>
Holders
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !tokenCountersQuery.isPlaceholderData }>
{ countersItem('token_holders_count') }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of transfer for the token"
isLoading={ tokenQuery.isPlaceholderData }
>
Transfers
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !tokenCountersQuery.isPlaceholderData }>
{ countersItem('transfers_count') }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ decimals && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of digits that come after the decimal place when displaying token value"
isLoading={ tokenQuery.isPlaceholderData }
>
Decimals
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !tokenQuery.isPlaceholderData } minW={ 6 }>
{ decimals }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -204,20 +204,20 @@ const TokenDetails = ({ tokenQuery }: Props) => {
{ (type !== 'ERC-20' && config.UI.views.nft.marketplaces.length === 0 && appActionData) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Link to the dapp"
>
Dapp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
py="1px"
>
<AppActionButton data={ appActionData } height="30px" source="NFT collection"/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsSponsoredItem isLoading={ tokenQuery.isPlaceholderData }/>
<DetailedInfoSponsoredItem isLoading={ tokenQuery.isPlaceholderData }/>
</Grid>
);
};
......
......@@ -6,7 +6,7 @@ import type { AddressMetadataTagFormatted } from 'types/client/addressMetadata';
import config from 'configs/app';
import AppActionButton from 'ui/shared/AppActionButton/AppActionButton';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TextSeparator from 'ui/shared/TextSeparator';
interface Props {
......@@ -24,13 +24,13 @@ const TokenNftMarketplaces = ({ hash, id, isLoading, appActionData, source }: Pr
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Marketplaces trading this NFT"
isLoading={ isLoading }
>
Marketplaces
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
py={ appActionData ? '1px' : '6px' }
>
<Skeleton isLoaded={ !isLoading } display="flex" columnGap={ 3 } flexWrap="wrap" alignItems="center">
......@@ -59,7 +59,7 @@ const TokenNftMarketplaces = ({ hash, id, isLoading, appActionData, source }: Pr
</>
) }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -9,9 +9,9 @@ import AppActionButton from 'ui/shared/AppActionButton/AppActionButton';
import useAppActionData from 'ui/shared/AppActionButton/useAppActionData';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import NftMedia from 'ui/shared/nft/NftMedia';
......@@ -55,37 +55,37 @@ const TokenInstanceDetails = ({ data, token, scrollRef, isLoading }: Props) => {
>
{ data.is_unique && data.owner && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Current owner of this token instance"
isLoading={ isLoading }
>
Owner
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={ data.owner }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<TokenInstanceCreatorAddress hash={ isLoading ? '' : token.address }/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="This token instance unique token ID"
isLoading={ isLoading }
>
Token ID
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Flex alignItems="center" overflow="hidden">
<Skeleton isLoaded={ !isLoading } overflow="hidden" display="inline-block" w="100%">
<HashStringShortenDynamic hash={ data.id }/>
</Skeleton>
<CopyToClipboard text={ data.id } isLoading={ isLoading }/>
</Flex>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<TokenInstanceTransfersCount hash={ isLoading ? '' : token.address } id={ isLoading ? '' : data.id } onClick={ handleCounterItemClick }/>
......@@ -99,14 +99,14 @@ const TokenInstanceDetails = ({ data, token, scrollRef, isLoading }: Props) => {
{ (config.UI.views.nft.marketplaces.length === 0 && appActionData) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Link to the dapp"
>
Dapp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value py="1px">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue py="1px">
<AppActionButton data={ appActionData } height="30px" source="NFT item"/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</Grid>
......@@ -127,8 +127,8 @@ const TokenInstanceDetails = ({ data, token, scrollRef, isLoading }: Props) => {
overflow="hidden"
>
<TokenInstanceMetadataInfo data={ data } isLoading={ isLoading }/>
<DetailsInfoItemDivider/>
<DetailsSponsoredItem isLoading={ isLoading }/>
<DetailedInfo.ItemDivider/>
<DetailedInfoSponsoredItem isLoading={ isLoading }/>
</Grid>
</>
);
......
......@@ -2,7 +2,7 @@ import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import { ADDRESS_INFO } from 'stubs/address';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
interface Props {
......@@ -37,18 +37,18 @@ const TokenInstanceCreatorAddress = ({ hash }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Address that deployed this token contract"
isLoading={ addressQuery.isPlaceholderData }
>
Creator
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={ creatorAddress }
isLoading={ addressQuery.isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -6,8 +6,8 @@ import type { MetadataAttributes } from 'types/client/token';
import parseMetadata from 'lib/token/parseMetadata';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import LinkExternal from 'ui/shared/links/LinkExternal';
import TruncatedValue from 'ui/shared/TruncatedValue';
......@@ -87,58 +87,58 @@ const TokenInstanceMetadataInfo = ({ data, isLoading: isLoadingProp }: Props) =>
return (
<>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ metadata?.name && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="NFT name"
isLoading={ isLoading }
>
Name
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
whiteSpace="normal"
wordBreak="break-word"
>
<Skeleton isLoaded={ !isLoading }>
{ metadata.name }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ metadata?.description && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="NFT description"
isLoading={ isLoading }
>
Description
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
whiteSpace="normal"
wordBreak="break-word"
>
<Skeleton isLoaded={ !isLoading }>
{ metadata.description }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ metadata?.attributes && metadata.attributes.length > 0 && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="NFT attributes"
isLoading={ isLoading }
>
Attributes
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Grid gap={ 2 } templateColumns="repeat(auto-fill,minmax(160px, 1fr))" w="100%" whiteSpace="normal">
{ metadata.attributes
.filter((attribute) => attribute.value)
.map((attribute, index) => <Item key={ index } data={ attribute } isLoading={ isLoading }/>) }
</Grid>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</>
......
......@@ -4,7 +4,7 @@ import { route } from 'nextjs-routes';
import useApiQuery from 'lib/api/useApiQuery';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import LinkInternal from 'ui/shared/links/LinkInternal';
interface Props {
......@@ -38,13 +38,13 @@ const TokenInstanceTransfersCount = ({ hash, id, onClick }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of transfer for the token instance"
isLoading={ transfersCountQuery.isPlaceholderData }
>
Transfers
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !transfersCountQuery.isPlaceholderData } display="inline-block">
<LinkInternal
href={ url }
......@@ -53,7 +53,7 @@ const TokenInstanceTransfersCount = ({ hash, id, onClick }: Props) => {
{ transfersCountQuery.data.transfers_count.toLocaleString() }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
import React from 'react';
import CutLinkList from 'toolkit/components/CutLink/CutLinkList';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
interface Props {
......@@ -15,19 +15,19 @@ const TxAllowedPeekers = ({ items }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Smart contracts allowed to interact with confidential data"
>
Allowed peekers
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CutLinkList
items={ items }
renderItem={ renderItem }
cutLength={ 2 }
rowGap={ 3 }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -8,8 +8,8 @@ import type { ExcludeUndefined } from 'types/utils';
import { currencyUnits } from 'lib/units';
import { Badge } from 'toolkit/chakra/badge';
import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
......@@ -25,68 +25,68 @@ interface Props {
const TxDetailsWrapped = ({ data }: Props) => {
return (
<Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'auto minmax(0, 1fr)' }}>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Unique character string (TxID) assigned to every verified transaction"
>
Transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<TxEntity hash={ data.hash } noIcon noLink noCopy={ false }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Transaction method name"
>
Method
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Badge colorPalette="gray">
{ data.method }
</Badge>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ data.to && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Address (external or contract) receiving the transaction"
>
{ data.to.is_contract ? 'Interacted with contract' : 'To' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Flex flexWrap="nowrap" alignItems="center" maxW="100%">
<AddressEntity address={ data.to }/>
</Flex>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Value sent in the native token (and USD) if applicable"
>
Value
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.value }
currency={ currencyUnits.ether }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.fee.value !== null && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total transaction fee"
>
Transaction fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxFee tx={ data } withUsd/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -94,40 +94,40 @@ const TxDetailsWrapped = ({ data }: Props) => {
{ data.gas_limit && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Maximum amount of gas that can be used by the transaction"
>
Gas limit
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(data.gas_limit).toFormat() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<TxDetailsOther type={ data.type } nonce={ data.nonce } position={ null }/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Binary data included with the transaction. See logs tab for additional info"
>
Raw input
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<RawInputData hex={ data.raw_input }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.decoded_input && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Decoded input data"
>
Decoded input data
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<LogDecodedInputData data={ data.decoded_input }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</Grid>
......
......@@ -11,7 +11,7 @@ import { Link } from 'toolkit/chakra/link';
import AccountActionsMenu from 'ui/shared/AccountActionsMenu/AccountActionsMenu';
import AppActionButton from 'ui/shared/AppActionButton/AppActionButton';
import useAppActionData from 'ui/shared/AppActionButton/useAppActionData';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailsActionsWrapper';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import NetworkExplorers from 'ui/shared/NetworkExplorers';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
......
......@@ -7,7 +7,7 @@ import config from 'configs/app';
import { ZERO } from 'lib/consts';
import { currencyUnits } from 'lib/units';
import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import IconSvg from 'ui/shared/IconSvg';
const rollupFeature = config.features.rollup;
......@@ -31,7 +31,7 @@ const TxDetailsBurntFees = ({ data, isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `
Amount of ${ currencyUnits.ether } burned for this transaction. Equals Block Base Fee per Gas * Gas Used
${ data.blob_gas_price && data.blob_gas_used ? ' + Blob Gas Price * Blob Gas Used' : '' }
......@@ -39,8 +39,8 @@ const TxDetailsBurntFees = ({ data, isLoading }: Props) => {
isLoading={ isLoading }
>
Burnt fees
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<IconSvg name="flame" boxSize={ 5 } color="gray.500" isLoading={ isLoading }/>
<CurrencyValue
value={ value.toString() }
......@@ -50,7 +50,7 @@ const TxDetailsBurntFees = ({ data, isLoading }: Props) => {
ml={ 2 }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -4,7 +4,7 @@ import React from 'react';
import config from 'configs/app';
import { currencyUnits } from 'lib/units';
import { Skeleton } from 'toolkit/chakra/skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
interface Props {
txFee: string | null;
......@@ -19,18 +19,18 @@ const TxDetailsFeePerGas = ({ txFee, gasUsed, isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Fee per gas"
isLoading={ isLoading }
>
Fee per gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading } mr={ 1 }>
{ BigNumber(txFee).dividedBy(10 ** config.chain.currency.decimals).dividedBy(gasUsed).toFixed() }
{ config.UI.views.tx.hiddenFields?.fee_currency ? '' : ` ${ currencyUnits.ether }` }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -7,7 +7,7 @@ import config from 'configs/app';
import { WEI, WEI_IN_GWEI } from 'lib/consts';
import { currencyUnits } from 'lib/units';
import { Skeleton } from 'toolkit/chakra/skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
interface Props {
......@@ -45,15 +45,15 @@ const TxDetailsGasPrice = ({ gasPrice, gasToken, isLoading }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage"
isLoading={ isLoading }
>
Gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ content }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -3,7 +3,7 @@ import React from 'react';
import type { Transaction } from 'types/api/transaction';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TextSeparator from 'ui/shared/TextSeparator';
type Props = Pick<Transaction, 'nonce' | 'type' | 'position'> & { queueIndex?: number };
......@@ -11,12 +11,12 @@ type Props = Pick<Transaction, 'nonce' | 'type' | 'position'> & { queueIndex?: n
const TxDetailsOther = ({ nonce, type, position, queueIndex }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Other data related to this transaction"
>
Other
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{
[
typeof type === 'number' && (
......@@ -53,7 +53,7 @@ const TxDetailsOther = ({ nonce, type, position, queueIndex }: Props) => {
</React.Fragment>
))
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -6,7 +6,7 @@ import type { TokenTransfer } from 'types/api/tokenTransfer';
import { route } from 'nextjs-routes';
import { Link } from 'toolkit/chakra/link';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import IconSvg from 'ui/shared/IconSvg';
import TokenTransferSnippet from 'ui/shared/TokenTransferSnippet/TokenTransferSnippet';
interface Props {
......@@ -39,12 +39,12 @@ const TxDetailsTokenTransfers = ({ data, txHash, isOverflow }: Props) => {
return (
<React.Fragment key={ type }>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ hint }
>
{ title }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value position="relative">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue position="relative">
<Flex
flexDirection="column"
alignItems="flex-start"
......@@ -54,7 +54,7 @@ const TxDetailsTokenTransfers = ({ data, txHash, isOverflow }: Props) => {
>
{ items.map((item, index) => <TokenTransferSnippet key={ index } data={ item }/>) }
</Flex>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</React.Fragment>
);
}) }
......
import {
Box,
Grid,
GridItem,
Text,
Spinner,
......@@ -32,10 +31,9 @@ import { Tooltip } from 'toolkit/chakra/tooltip';
import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoSponsoredItem from 'ui/shared/DetailedInfo/DetailedInfoSponsoredItem';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
......@@ -117,13 +115,13 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
) : null;
return (
<Grid columnGap={ 8 } rowGap={{ base: 3, lg: 3 }} templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
<DetailedInfo.Container templateColumns={{ base: 'minmax(0, 1fr)', lg: 'max-content minmax(728px, auto)' }}>
{ config.features.metasuites.isEnabled && (
<>
<Box display="none" id="meta-suites__tx-info-label" data-status={ data.status } data-ready={ !isLoading }/>
<Box display="none" id="meta-suites__tx-info-value"/>
<DetailsInfoItemDivider display="none" id="meta-suites__details-info-item-divider"/>
<DetailedInfo.ItemDivider display="none" id="meta-suites__details-info-item-divider"/>
</>
) }
......@@ -133,13 +131,13 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</GridItem>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Unique character string (TxID) assigned to every verified transaction"
isLoading={ isLoading }
>
Transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
{ data.status === null && <Spinner mr={ 2 } size="sm" flexShrink={ 0 }/> }
<Skeleton loading={ isLoading } overflow="hidden">
<HashStringShortenDynamic hash={ data.hash }/>
......@@ -152,9 +150,9 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<Box display="none" flexShrink={ 0 } id="meta-suites__tx-explorer-link"/>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Current transaction state: Success, Failed (Error), or Pending (In Process)"
isLoading={ isLoading }
>
......@@ -164,8 +162,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
'L2 status and method' :
'Status and method'
}
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxStatus status={ data.status } errorText={ data.status === 'error' ? data.result : undefined } isLoading={ isLoading }/>
{ data.method && (
<Badge colorPalette={ data.method === 'Multicall' ? 'teal' : 'gray' } loading={ isLoading } truncated ml={ 3 }>
......@@ -179,17 +177,17 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</Link>
</Skeleton>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ rollupFeature.isEnabled && rollupFeature.type === 'optimistic' && data.op_withdrawals && data.op_withdrawals.length > 0 &&
!config.UI.views.tx.hiddenFields?.L1_status && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Detailed status progress of the transaction"
>
Withdrawal status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Flex flexDir="column" rowGap={ 2 }>
{ data.op_withdrawals.map((withdrawal) => (
<Box key={ withdrawal.nonce }>
......@@ -204,77 +202,77 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</Box>
)) }
</Flex>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zkevm_status && !config.UI.views.tx.hiddenFields?.L1_status && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Status of the transaction confirmation path to L1"
isLoading={ isLoading }
>
Confirmation status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<VerificationSteps currentStep={ data.zkevm_status } steps={ ZKEVM_L2_TX_STATUSES } isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.arbitrum?.status && !config.UI.views.tx.hiddenFields?.L1_status && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Status of the transaction confirmation path to L1"
isLoading={ isLoading }
>
L1 status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<VerificationSteps
currentStep={ arbitrum.VERIFICATION_STEPS_MAP[data.arbitrum.status] }
currentStepPending={ arbitrum.getVerificationStepStatus(data.arbitrum) === 'pending' }
steps={ arbitrum.verificationSteps }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.revert_reason && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The revert reason of the transaction"
>
Revert reason
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxRevertReason { ...data.revert_reason }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zksync && !config.UI.views.tx.hiddenFields?.L1_status && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Status is the short interpretation of the batch lifecycle"
isLoading={ isLoading }
>
L1 status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<VerificationSteps steps={ ZKSYNC_L2_TX_BATCH_STATUSES } currentStep={ data.zksync.status } isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Block number containing the transaction"
isLoading={ isLoading }
>
Block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.block_number === null ?
<Text>Pending</Text> : (
<BlockEntity
......@@ -297,70 +295,70 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<VerificationSteps steps={ SCROLL_L2_BLOCK_STATUSES } currentStep={ data.scroll.l2_block_status } isLoading={ isLoading }/>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.zkevm_batch_number && !config.UI.views.tx.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch index for this transaction"
isLoading={ isLoading }
>
Txn batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BatchEntityL2
isLoading={ isLoading }
number={ data.zkevm_batch_number }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zksync && !config.UI.views.tx.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch number"
isLoading={ isLoading }
>
Batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.zksync.batch_number ? (
<BatchEntityL2
isLoading={ isLoading }
number={ data.zksync.batch_number }
/>
) : <Skeleton loading={ isLoading }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.arbitrum && !config.UI.views.tx.hiddenFields?.batch && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Index of the batch containing this transaction"
isLoading={ isLoading }
>
Batch
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.batch_number ?
<BatchEntityL2 isLoading={ isLoading } number={ data.arbitrum.batch_number }/> :
<Skeleton loading={ isLoading }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.timestamp && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Date & time of transaction inclusion, including length of time for confirmation"
isLoading={ isLoading }
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<DetailsTimestamp timestamp={ data.timestamp } isLoading={ isLoading }/>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<DetailedInfoTimestamp timestamp={ data.timestamp } isLoading={ isLoading }/>
{ data.confirmation_duration && (
<>
<TextSeparator color="gray.500"/>
......@@ -369,24 +367,24 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</Skeleton>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.execution_node && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Node that carried out the confidential computation"
isLoading={ isLoading }
>
Kettle
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressEntity
address={ data.execution_node }
href={ route({ pathname: '/txs/kettle/[hash]', query: { hash: data.execution_node.hash } }) }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -394,19 +392,19 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<TxAllowedPeekers items={ data.allowed_peekers }/>
) }
<DetailsSponsoredItem isLoading={ isLoading }/>
<DetailedInfoSponsoredItem isLoading={ isLoading }/>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<TxDetailsActions hash={ data.hash } actions={ data.actions } isTxDataLoading={ isLoading }/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Address (external or contract) sending the transaction"
isLoading={ isLoading }
>
From
</DetailsInfoItem.Label>
<DetailsInfoItem.Value columnGap={ 3 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue columnGap={ 3 }>
<AddressEntity
address={ data.from }
isLoading={ isLoading }
......@@ -417,15 +415,15 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
{ addressFromTags }
</Flex>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Address (external or contract) receiving the transaction"
isLoading={ isLoading }
>
{ data.to?.is_contract ? 'Interacted with contract' : 'To' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap={{ base: 'wrap', lg: 'nowrap' }}
columnGap={ 3 }
>
......@@ -462,91 +460,91 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
) : (
<span>[ Contract creation ]</span>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.token_transfers && <TxDetailsTokenTransfers data={ data.token_transfers } txHash={ data.hash } isOverflow={ data.token_transfers_overflow }/> }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ (data.arbitrum?.commitment_transaction.hash || data.arbitrum?.confirmation_transaction.hash) &&
(
<>
{ data.arbitrum?.commitment_transaction.hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 transaction containing this batch commitment"
isLoading={ isLoading }
>
Commitment tx
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1 hash={ data.arbitrum?.commitment_transaction.hash } isLoading={ isLoading }/>
{ data.arbitrum?.commitment_transaction.status === 'finalized' && <StatusTag type="ok" text="Finalized" ml={ 2 }/> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.arbitrum?.confirmation_transaction.hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 transaction containing confirmation of this batch"
isLoading={ isLoading }
>
Confirmation tx
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1 hash={ data.arbitrum?.confirmation_transaction.hash } isLoading={ isLoading }/>
{ data.arbitrum?.commitment_transaction.status === 'finalized' && <StatusTag type="ok" text="Finalized" ml={ 2 }/> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
</>
) }
{ data.zkevm_sequence_hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isLoading }
>
Sequence tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<Skeleton loading={ isLoading } overflow="hidden">
<HashStringShortenDynamic hash={ data.zkevm_sequence_hash }/>
</Skeleton>
<CopyToClipboard text={ data.zkevm_sequence_hash } isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zkevm_verify_hash && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isLoading }
>
Verify tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexWrap="nowrap">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexWrap="nowrap">
<Skeleton loading={ isLoading } overflow="hidden">
<HashStringShortenDynamic hash={ data.zkevm_verify_hash }/>
</Skeleton>
<CopyToClipboard text={ data.zkevm_verify_hash } isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (data.zkevm_batch_number || data.zkevm_verify_hash) && <DetailsInfoItemDivider/> }
{ (data.zkevm_batch_number || data.zkevm_verify_hash) && <DetailedInfo.ItemDivider/> }
{ !config.UI.views.tx.hiddenFields?.value && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Value sent in the native token (and USD) if applicable"
isLoading={ isLoading }
>
Value
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.value }
currency={ currencyUnits.ether }
......@@ -554,33 +552,33 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
isLoading={ isLoading }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.tx.hiddenFields?.tx_fee && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ data.blob_gas_used ? 'Transaction fee without blob fee' : 'Total transaction fee' }
isLoading={ isLoading }
>
Transaction fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxFee tx={ data } isLoading={ isLoading } withUsd/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ rollupFeature.isEnabled && rollupFeature.type === 'arbitrum' && data.arbitrum && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Fee paid to the poster for L1 resources"
isLoading={ isLoading }
>
Poster fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.arbitrum.poster_fee }
currency={ currencyUnits.ether }
......@@ -588,15 +586,15 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
flexWrap="wrap"
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Fee paid to the network for L2 resources"
isLoading={ isLoading }
>
Network fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.arbitrum.network_fee }
currency={ currencyUnits.ether }
......@@ -604,7 +602,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
flexWrap="wrap"
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -612,28 +610,28 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<TxDetailsFeePerGas txFee={ data.fee.value } gasUsed={ data.gas_used } isLoading={ isLoading }/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Actual gas amount used by the transaction"
isLoading={ isLoading }
>
Gas usage & limit by txn
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading }>{ BigNumber(data.gas_used || 0).toFormat() }</Skeleton>
<TextSeparator/>
<Skeleton loading={ isLoading }>{ BigNumber(data.gas_limit).toFormat() }</Skeleton>
<Utilization ml={ 4 } value={ BigNumber(data.gas_used || 0).dividedBy(BigNumber(data.gas_limit)).toNumber() } isLoading={ isLoading }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ rollupFeature.isEnabled && rollupFeature.type === 'arbitrum' && data.arbitrum && data.gas_used && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L2 gas set aside for L1 data charges"
isLoading={ isLoading }
>
Gas used for L1
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading }>{ BigNumber(data.arbitrum.gas_used_for_l1 || 0).toFormat() }</Skeleton>
<TextSeparator/>
<Utilization
......@@ -641,15 +639,15 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
value={ BigNumber(data.arbitrum.gas_used_for_l1 || 0).dividedBy(BigNumber(data.gas_used)).toNumber() }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L2 gas spent on L2 resources"
isLoading={ isLoading }
>
Gas used for L2
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading }>{ BigNumber(data.arbitrum.gas_used_for_l2 || 0).toFormat() }</Skeleton>
<TextSeparator/>
<Utilization
......@@ -657,28 +655,28 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
value={ BigNumber(data.arbitrum.gas_used_for_l2 || 0).dividedBy(BigNumber(data.gas_used)).toNumber() }
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.scroll?.l1_gas_used !== undefined && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total gas used on L1"
isLoading={ isLoading }
>
L1 Gas used
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading }>{ BigNumber(data.scroll?.l1_gas_used || 0).toFormat() }</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.tx.hiddenFields?.gas_fees &&
(data.base_fee_per_gas || data.max_fee_per_gas || data.max_priority_fee_per_gas) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
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
......@@ -687,8 +685,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
isLoading={ isLoading }
>
{ `Gas fees (${ currencyUnits.gwei })` }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.base_fee_per_gas && (
<Skeleton loading={ isLoading }>
<Text as="span" fontWeight="500">Base: </Text>
......@@ -709,7 +707,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<Text fontWeight="600" as="span">{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
</Skeleton>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -719,64 +717,64 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<>
{ data.l1_gas_used && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 gas used by transaction"
isLoading={ isLoading }
>
L1 gas used by txn
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.l1_gas_used).toFormat() }</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.l1_gas_price && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 gas price"
isLoading={ isLoading }
>
L1 gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text mr={ 1 }>{ BigNumber(data.l1_gas_price).dividedBy(WEI).toFixed() } { currencyUnits.ether }</Text>
<Text color="text.secondary">({ BigNumber(data.l1_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.l1_fee && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
// eslint-disable-next-line max-len
hint={ `L1 Data Fee which is used to cover the L1 "security" cost from the batch submission mechanism. In combination with L2 execution fee, L1 fee makes the total amount of fees that a transaction pays.` }
isLoading={ isLoading }
>
L1 fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.l1_fee }
currency={ currencyUnits.ether }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.l1_fee_scalar && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="A Dynamic overhead (fee scalar) premium, which serves as a buffer in case L1 prices rapidly increase."
isLoading={ isLoading }
>
L1 fee scalar
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ data.l1_fee_scalar }</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</>
......@@ -788,15 +786,15 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
{ data.arbitrum?.contains_message && data.arbitrum?.message_related_info && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ data.arbitrum.contains_message === 'incoming' ?
'The hash of the transaction that originated the message from the base layer' :
'The hash of the transaction that completed the message on the base layer'
}
>
{ data.arbitrum.contains_message === 'incoming' ? 'Originating L1 txn hash' : 'Completion L1 txn hash' }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.arbitrum.message_related_info.associated_l1_transaction ?
<TxEntityL1 hash={ data.arbitrum.message_related_info.associated_l1_transaction }/> : (
<HStack gap={ 2 }>
......@@ -805,7 +803,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</HStack>
)
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
......@@ -813,12 +811,12 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<>
{ data.blob_gas_used && data.blob_gas_price && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Blob fee for this transaction"
>
Blob fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ BigNumber(data.blob_gas_used).multipliedBy(data.blob_gas_price).toString() }
currency={ config.UI.views.tx.hiddenFields?.fee_currency ? '' : currencyUnits.ether }
......@@ -826,31 +824,31 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
flexWrap="wrap"
isLoading={ isLoading }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.blob_gas_used && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Amount of gas used by the blobs in this transaction"
>
Blob gas usage
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(data.blob_gas_used).toFormat() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (data.max_fee_per_blob_gas || data.blob_gas_price) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ `Amount of ${ currencyUnits.ether } used for blobs in this transaction` }
>
{ `Blob gas fees (${ currencyUnits.gwei })` }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.blob_gas_price && (
<Text fontWeight="600" as="span">{ BigNumber(data.blob_gas_price).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
) }
......@@ -861,40 +859,40 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<Text fontWeight="600" as="span">{ BigNumber(data.max_fee_per_blob_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
</>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
</>
) }
<TxDetailsOther nonce={ data.nonce } type={ data.type } position={ data.position } queueIndex={ data.scroll?.queue_index }/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Binary data included with the transaction. See logs tab for additional info"
>
Raw input
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<RawInputData hex={ data.raw_input } defaultDataType={ data.zilliqa?.is_scilla ? 'UTF-8' : 'Hex' }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.decoded_input && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Decoded input data"
>
Decoded input data
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<LogDecodedInputData data={ data.decoded_input }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.zksync && <ZkSyncL2TxnBatchHashesInfo data={ data.zksync } isLoading={ isLoading }/> }
</CutLinkDetails>
</Grid>
</DetailedInfo.Container>
);
};
......
......@@ -8,7 +8,7 @@ import { WEI_IN_GWEI } from 'lib/consts';
import { currencyUnits } from 'lib/units';
import { Skeleton } from 'toolkit/chakra/skeleton';
import CurrencyValue from 'ui/shared/CurrencyValue';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import TextSeparator from 'ui/shared/TextSeparator';
type Props = {
......@@ -21,71 +21,71 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
<>
{ data.scroll?.l1_fee !== undefined && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 fee that pays for rollup costs"
isLoading={ isLoading }
>
L1 data fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.scroll?.l1_fee }
currency={ currencyUnits.ether }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.scroll?.l2_fee !== undefined && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L2 execution fee"
isLoading={ isLoading }
>
Execution fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.scroll?.l2_fee.value }
currency={ currencyUnits.ether }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.scroll?.l1_fee_commit_scalar !== undefined && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Commitment scalar"
isLoading={ isLoading }
>
L1 commit scalar
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ String(data.scroll?.l1_fee_commit_scalar) }
currency={ currencyUnits.ether }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.scroll?.l1_fee_overhead !== undefined && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Additional gas overhead of a data commitment transaction"
isLoading={ isLoading }
>
L1 Fee Overhead
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton loading={ isLoading }>
<CurrencyValue
value={ String(data.scroll?.l1_fee_overhead) }
......@@ -94,18 +94,18 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
flexWrap="wrap"
/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (data.scroll?.l1_base_fee !== undefined || data.scroll?.l1_fee_scalar !== undefined) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 gas fees"
isLoading={ isLoading }
>
L1 gas fees
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.scroll?.l1_base_fee !== undefined && (
<Skeleton loading={ isLoading }>
<Text as="span" fontWeight="500">Base: </Text>
......@@ -119,18 +119,18 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
<Text fontWeight="600" as="span">{ BigNumber(data.scroll?.l1_fee_scalar || 0).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
</Skeleton>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ (data.scroll?.l1_blob_base_fee !== undefined || data.scroll?.l1_fee_blob_scalar !== undefined) && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 blob fees"
isLoading={ isLoading }
>
L1 blob fees
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.scroll?.l1_blob_base_fee !== undefined && (
<Skeleton loading={ isLoading }>
<Text as="span" fontWeight="500">Base: </Text>
......@@ -144,7 +144,7 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
<Text fontWeight="600" as="span">{ BigNumber(data.scroll?.l1_fee_blob_scalar || 0).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
</Skeleton>
) }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</>
......
......@@ -2,8 +2,8 @@ import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import DetailsActionsWrapper from 'ui/shared/DetailsActionsWrapper';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoActionsWrapper from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
interface Props {
......@@ -29,7 +29,7 @@ const TxDetailsActionsInterpretation = ({ hash, isTxDataLoading }: Props) => {
return (
<>
<DetailsActionsWrapper isLoading={ isTxDataLoading || txInterpretationQuery.isPlaceholderData } type="tx">
<DetailedInfoActionsWrapper isLoading={ isTxDataLoading || txInterpretationQuery.isPlaceholderData } type="tx">
{ actions.map((action, index: number) => (
<TxInterpretation
key={ index }
......@@ -38,8 +38,8 @@ const TxDetailsActionsInterpretation = ({ hash, isTxDataLoading }: Props) => {
/>
),
) }
</DetailsActionsWrapper>
<DetailsInfoItemDivider/>
</DetailedInfoActionsWrapper>
<DetailedInfo.ItemDivider/>
</>
);
};
......
......@@ -2,8 +2,8 @@ import React from 'react';
import type { TxAction } from 'types/api/txAction';
import DetailsActionsWrapper from 'ui/shared/DetailsActionsWrapper';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoActionsWrapper from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import TxDetailsAction from './TxDetailsAction';
......@@ -15,10 +15,10 @@ interface Props {
const TxDetailsActionsRaw = ({ actions, isLoading }: Props) => {
return (
<>
<DetailsActionsWrapper isLoading={ isLoading } type="tx">
<DetailedInfoActionsWrapper isLoading={ isLoading } type="tx">
{ actions.map((action, index: number) => <TxDetailsAction key={ index } action={ action }/>) }
</DetailsActionsWrapper>
<DetailsInfoItemDivider/>
</DetailedInfoActionsWrapper>
<DetailedInfo.ItemDivider/>
</>
);
};
......
......@@ -15,8 +15,8 @@ import ArbitrumL2TxnBatchDA from 'ui/shared/batch/ArbitrumL2TxnBatchDA';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
......@@ -74,13 +74,13 @@ const ArbitrumL2TxnBatchDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Batch number indicates the length of batches produced by grouping L2 blocks to be proven on L1"
>
Txn batch number
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.number }
</Skeleton>
......@@ -92,114 +92,114 @@ const ArbitrumL2TxnBatchDetails = ({ query }: Props) => {
isPrevDisabled={ data.number === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Date and time at which batch is submitted to L1"
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.commitment_transaction.timestamp ?
<DetailsTimestamp timestamp={ data.commitment_transaction.timestamp }isLoading={ isPlaceholderData }/> :
<DetailedInfoTimestamp timestamp={ data.commitment_transaction.timestamp }isLoading={ isPlaceholderData }/> :
'Undefined'
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of transactions in this batch"
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'txs' } }) }>
{ data.transactions_count.toLocaleString() } transaction{ data.transactions_count === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of L2 blocks in this batch"
>
Blocks
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'blocks' } }) }>
{ blocksCount.toLocaleString() } block{ blocksCount === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Hash of L1 transaction in which transactions was committed"
>
L1 transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1
isLoading={ isPlaceholderData }
hash={ data.commitment_transaction.hash }
maxW="100%"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Heigh of L1 block which includes L1 transactions"
>
L1 block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BlockEntityL1
isLoading={ isPlaceholderData }
number={ data.commitment_transaction.block_number }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.data_availability.batch_data_container && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Where the batch data is stored"
>
Batch data container
</DetailsInfoItem.Label><DetailsInfoItem.Value>
</DetailedInfo.ItemLabel><DetailedInfo.ItemValue>
<ArbitrumL2TxnBatchDA dataContainer={ data.data_availability.batch_data_container } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="The hash of the state before the batch"
>
Before acc
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.before_acc }/>
<CopyToClipboard text={ data.before_acc }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="The hash of the state after the batch"
>
After acc
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.after_acc }/>
<CopyToClipboard text={ data.after_acc }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.data_availability.batch_data_container === 'in_anytrust' && (
<>
......
......@@ -5,8 +5,8 @@ import type { ArbitrumL2TxnBatchDAAnytrust } from 'types/api/arbitrumL2';
import dayjs from 'lib/date/dayjs';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import HashStringShorten from 'ui/shared/HashStringShorten';
import IconSvg from 'ui/shared/IconSvg';
import TextSeparator from 'ui/shared/TextSeparator';
......@@ -20,26 +20,26 @@ const ArbitrumL2TxnBatchDetailsDA = ({ dataAvailability }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Aggregated BLS signature of AnyTrust committee members"
>
Signature
</DetailsInfoItem.Label><DetailsInfoItem.Value wordBreak="break-all" whiteSpace="break-spaces">
</DetailedInfo.ItemLabel><DetailedInfo.ItemValue wordBreak="break-all" whiteSpace="break-spaces">
{ dataAvailability.bls_signature }
</DetailsInfoItem.Value><DetailsInfoItem.Label
</DetailedInfo.ItemValue><DetailedInfo.ItemLabel
hint="The hash of the data blob stored by the AnyTrust committee"
>
Data hash
</DetailsInfoItem.Label><DetailsInfoItem.Value>
</DetailedInfo.ItemLabel><DetailedInfo.ItemValue>
{ dataAvailability.data_hash }
<CopyToClipboard text={ dataAvailability.data_hash } ml={ 2 }/>
</DetailsInfoItem.Value><DetailsInfoItem.Label
</DetailedInfo.ItemValue><DetailedInfo.ItemLabel
hint="Expiration timeout for the data blob"
>
Timeout
</DetailsInfoItem.Label><DetailsInfoItem.Value>
</DetailedInfo.ItemLabel><DetailedInfo.ItemValue>
{ dayjs(dataAvailability.timeout) < dayjs() ?
<DetailsTimestamp timestamp={ dataAvailability.timeout }/> :
<DetailedInfoTimestamp timestamp={ dataAvailability.timeout }/> :
(
<>
<Text>{ dayjs(dataAvailability.timeout).format('llll') }</Text>
......@@ -47,13 +47,13 @@ const ArbitrumL2TxnBatchDetailsDA = ({ dataAvailability }: Props) => {
<Text color="red.500">{ dayjs(dataAvailability.timeout).diff(dayjs(), 'day') } days left</Text>
</>
) }
</DetailsInfoItem.Value>
<DetailsInfoItem.Label
</DetailedInfo.ItemValue>
<DetailedInfo.ItemLabel
hint="Members of AnyTrust committee"
>
Signers
</DetailsInfoItem.Label>
<DetailsInfoItem.Value overflowX="scroll" fontSize="sm">
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue overflowX="scroll" fontSize="sm">
<Show above="lg" ssr={ false }>
<Grid
templateColumns="1fr auto auto"
......@@ -114,7 +114,7 @@ const ArbitrumL2TxnBatchDetailsDA = ({ dataAvailability }: Props) => {
)) }
</Box>
</Hide>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -13,8 +13,8 @@ import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import OptimisticL2TxnBatchDA from 'ui/shared/batch/OptimisticL2TxnBatchDA';
import Skeleton from 'ui/shared/chakra/Skeleton';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import LinkInternal from 'ui/shared/links/LinkInternal';
import PrevNext from 'ui/shared/PrevNext';
......@@ -63,13 +63,13 @@ const OptimisticL2TxnBatchDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Batch ID indicates the length of batches produced by grouping L2 blocks to be proven on L1"
>
Batch ID
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.internal_id }
</Skeleton>
......@@ -81,58 +81,58 @@ const OptimisticL2TxnBatchDetails = ({ query }: Props) => {
isPrevDisabled={ data.internal_id === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Date and time at which batch is submitted to L1"
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.l1_timestamp ?
<DetailsTimestamp timestamp={ data.l1_timestamp }isLoading={ isPlaceholderData }/> :
<DetailedInfoTimestamp timestamp={ data.l1_timestamp }isLoading={ isPlaceholderData }/> :
'Undefined'
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of transactions in this batch"
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.internal_id.toString(), tab: 'txs' } }) }>
{ data.transaction_count.toLocaleString() } transaction{ data.transaction_count === 1 ? '' : 's' }
</LinkInternal>
{ ' ' }in this batch
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of L2 blocks in this batch"
>
Blocks
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.internal_id.toString(), tab: 'blocks' } }) }>
{ blocksCount.toLocaleString() } block{ blocksCount === 1 ? '' : 's' }
</LinkInternal>
{ ' ' }in this batch
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Where the batch data is stored"
>
Batch data container
</DetailsInfoItem.Label>
<DetailsInfoItem.Value flexDir="column" alignItems="flex-start" rowGap={ 2 }>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue flexDir="column" alignItems="flex-start" rowGap={ 2 }>
<OptimisticL2TxnBatchDA container={ data.batch_data_container } isLoading={ isPlaceholderData }/>
{ data.batch_data_container === 'in_blob4844' && data.blobs &&
<OptimisticL2TxnBatchBlobEip4844 blobs={ data.blobs } isLoading={ isPlaceholderData }/> }
......@@ -145,7 +145,7 @@ const OptimisticL2TxnBatchDetails = ({ query }: Props) => {
) }
{ data.batch_data_container === 'in_celestia' && data.blobs &&
<OptimisticL2TxnBatchBlobCelestia blobs={ data.blobs } isLoading={ isPlaceholderData }/> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</Grid>
);
};
......
......@@ -13,8 +13,8 @@ import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import ScrollL2TxnBatchDA from 'ui/shared/batch/ScrollL2TxnBatchDA';
import Skeleton from 'ui/shared/chakra/Skeleton';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal';
......@@ -62,13 +62,13 @@ const ScrollL2TxnBatchDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Batch number indicates the length of batches produced by grouping L2 blocks to be proven on L1"
>
Txn batch number
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.number }
</Skeleton>
......@@ -80,116 +80,116 @@ const ScrollL2TxnBatchDetails = ({ query }: Props) => {
isPrevDisabled={ data.number === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Data availability container"
>
Container
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<ScrollL2TxnBatchDA container={ data.data_availability.batch_data_container } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Status of this batch"
>
Status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<ScrollL2TxnBatchStatus status={ data.confirmation_transaction.hash ? 'Finalized' : 'Committed' } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Date and time at which batch is finalized to L1"
>
Finalized timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.confirmation_transaction.timestamp ?
<DetailsTimestamp timestamp={ data.confirmation_transaction.timestamp }isLoading={ isPlaceholderData }/> :
<DetailedInfoTimestamp timestamp={ data.confirmation_transaction.timestamp }isLoading={ isPlaceholderData }/> :
<Skeleton isLoaded={ !isPlaceholderData } display="inline-block">Pending</Skeleton>
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of transactions in this batch"
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'txs' } }) }>
{ data.transaction_count.toLocaleString() } transaction{ data.transaction_count === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Number of L2 blocks in this batch"
>
Blocks
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'blocks' } }) }>
{ blocksCount.toLocaleString() } block{ blocksCount === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Date and time at which batch is committed to L1"
>
Committed timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.commitment_transaction.timestamp ?
<DetailsTimestamp timestamp={ data.commitment_transaction.timestamp }isLoading={ isPlaceholderData }/> :
<DetailedInfoTimestamp timestamp={ data.commitment_transaction.timestamp }isLoading={ isPlaceholderData }/> :
<Skeleton isLoaded={ !isPlaceholderData } display="inline-block">Pending</Skeleton>
}
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Hash of L1 transaction this batch was committed in"
>
Committed transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntityL1
isLoading={ isPlaceholderData }
hash={ data.commitment_transaction.hash }
maxW="100%"
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="L1 block that includes transaction with this batch commitment"
>
Committed block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BlockEntityL1
isLoading={ isPlaceholderData }
number={ data.commitment_transaction.block_number }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="Hash of L1 transaction this batch was finalized in"
>
Finalized transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.confirmation_transaction.hash ? (
<TxEntityL1
isLoading={ isPlaceholderData }
......@@ -197,22 +197,22 @@ const ScrollL2TxnBatchDetails = ({ query }: Props) => {
maxW="100%"
/>
) : <Skeleton isLoaded={ !isPlaceholderData } display="inline-block">Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
hint="L1 block that includes transaction with this batch finalization data"
>
Finalized block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.confirmation_transaction.block_number ? (
<BlockEntityL1
isLoading={ isPlaceholderData }
number={ data.confirmation_transaction.block_number }
/>
) : <Skeleton isLoaded={ !isPlaceholderData } display="inline-block">Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</Grid>
);
};
......
......@@ -14,9 +14,9 @@ import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/links/LinkInternal';
......@@ -62,12 +62,12 @@ const ZkEvmL2TxnBatchDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Txn batch number
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.number }
</Skeleton>
......@@ -79,32 +79,32 @@ const ZkEvmL2TxnBatchDetails = ({ query }: Props) => {
isPrevDisabled={ data.number === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<VerificationSteps steps={ ZKEVM_L2_TX_BATCH_STATUSES } currentStep={ data.status } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
{ data.timestamp ? <DetailsTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/> : 'Undefined' }
</DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.timestamp ? <DetailedInfoTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/> : 'Undefined' }
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Verify tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.verify_transaction_hash ? (
<TxEntityL1
isLoading={ isPlaceholderData }
......@@ -112,57 +112,57 @@ const ZkEvmL2TxnBatchDetails = ({ query }: Props) => {
maxW="100%"
/>
) : <Text>Pending</Text> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'txs' } }) }>
{ data.transactions.length } transaction{ data.transactions.length === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Global exit root
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.global_exit_root }/>
</Skeleton>
<CopyToClipboard text={ data.global_exit_root } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Acc input hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.acc_input_hash }/>
</Skeleton>
<CopyToClipboard text={ data.acc_input_hash } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
Sequence tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.sequence_transaction_hash ? (
<TxEntityL1
isLoading={ isPlaceholderData }
......@@ -170,21 +170,21 @@ const ZkEvmL2TxnBatchDetails = ({ query }: Props) => {
maxW="100%"
/>
) : <Text>Pending</Text> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
isLoading={ isPlaceholderData }
>
State root
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.state_root }/>
</Skeleton>
<CopyToClipboard text={ data.state_root } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</Grid>
);
};
......
......@@ -17,9 +17,9 @@ import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import LinkInternal from 'ui/shared/links/LinkInternal';
import PrevNext from 'ui/shared/PrevNext';
import TruncatedValue from 'ui/shared/TruncatedValue';
......@@ -77,13 +77,13 @@ const ZkSyncL2TxnBatchDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 200px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Batch number indicates the length of batches produced by grouping L2 blocks to be proven on Ethereum."
isLoading={ isPlaceholderData }
>
Txn batch number
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.number }
</Skeleton>
......@@ -95,43 +95,43 @@ const ZkSyncL2TxnBatchDetails = ({ query }: Props) => {
isPrevDisabled={ data.number === 0 }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Status is the short interpretation of the batch lifecycle"
isLoading={ isPlaceholderData }
>
Status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<VerificationSteps steps={ ZKSYNC_L2_TX_BATCH_STATUSES.slice(1) } currentStep={ data.status } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Date and time at which batch is produced"
isLoading={ isPlaceholderData }
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
{ data.timestamp ? <DetailsTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/> : 'Undefined' }
</DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.timestamp ? <DetailedInfoTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/> : 'Undefined' }
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Number of transactions inside the batch."
isLoading={ isPlaceholderData }
>
Transactions
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/batches/[number]', query: { number: data.number.toString(), tab: 'txs' } }) }>
{ txNum } transaction{ txNum === 1 ? '' : 's' }
</LinkInternal>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<ZkSyncL2TxnBatchHashesInfo isLoading={ isPlaceholderData } data={ data }/>
......@@ -155,38 +155,38 @@ const ZkSyncL2TxnBatchDetails = ({ query }: Props) => {
<>
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="L1 batch root is a hash that summarizes batch data and submitted to the L1"
>
Root hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexWrap="nowrap"
alignSelf="flex-start"
>
<TruncatedValue value={ data.root_hash }/>
<CopyToClipboard text={ data.root_hash }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas price for the batch settlement transaction on L1"
>
L1 gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text mr={ 1 }>{ BigNumber(data.l1_gas_price).dividedBy(WEI).toFixed() } { currencyUnits.ether }</Text>
<Text variant="secondary">({ BigNumber(data.l1_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint='The gas price below which the "baseFee" of the batch should not fall'
>
L2 fair gas price
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text mr={ 1 }>{ BigNumber(data.l2_fair_gas_price).dividedBy(WEI).toFixed() } { currencyUnits.ether }</Text>
<Text variant="secondary">({ BigNumber(data.l2_fair_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
</Grid>
......
......@@ -4,8 +4,8 @@ import React from 'react';
import type { ZkSyncBatch } from 'types/api/zkSyncL2';
import { Skeleton } from 'toolkit/chakra/skeleton';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
interface Props {
......@@ -24,13 +24,13 @@ interface Props {
const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Hash of L1 tx on which the batch was committed"
isLoading={ isLoading }
>
Commit tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexDir="column"
alignItems="flex-start"
>
......@@ -44,20 +44,20 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
/>
{ data.commit_transaction_timestamp && (
<Flex alignItems="center" flexWrap="wrap" rowGap={ 3 }>
<DetailsTimestamp timestamp={ data.commit_transaction_timestamp } isLoading={ isLoading }/>
<DetailedInfoTimestamp timestamp={ data.commit_transaction_timestamp } isLoading={ isLoading }/>
</Flex>
) }
</>
) : <Skeleton loading={ isLoading }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Hash of L1 tx on which the batch was proven"
isLoading={ isLoading }
>
Prove tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexDir="column"
alignItems="flex-start"
>
......@@ -71,20 +71,20 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
/>
{ data.prove_transaction_timestamp && (
<Flex alignItems="center" flexWrap="wrap" rowGap={ 3 }>
<DetailsTimestamp timestamp={ data.prove_transaction_timestamp } isLoading={ isLoading }/>
<DetailedInfoTimestamp timestamp={ data.prove_transaction_timestamp } isLoading={ isLoading }/>
</Flex>
) }
</>
) : <Skeleton loading={ isLoading }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Hash of L1 tx on which the batch was executed and finalized"
isLoading={ isLoading }
>
Execute tx hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexDir="column"
alignItems="flex-start"
>
......@@ -98,12 +98,12 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
/>
{ data.execute_transaction_timestamp && (
<Flex alignItems="center" flexWrap="wrap" rowGap={ 3 }>
<DetailsTimestamp timestamp={ data.execute_transaction_timestamp } isLoading={ isLoading }/>
<DetailedInfoTimestamp timestamp={ data.execute_transaction_timestamp } isLoading={ isLoading }/>
</Flex>
) }
</>
) : <Skeleton loading={ isLoading }>Pending</Skeleton> }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -2,7 +2,7 @@ import React from 'react';
import type { UserOp } from 'types/api/userOps';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import RawInputData from 'ui/shared/RawInputData';
import UserOpCallDataSwitch from './UserOpCallDataSwitch';
......@@ -35,14 +35,14 @@ const UserOpDecodedCallData = ({ data }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Data that’s passed to the sender for execution"
>
{ labelText }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<RawInputData hex={ callData } rightSlot={ toggler }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -2,7 +2,7 @@ import React from 'react';
import type { UserOp } from 'types/api/userOps';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
import UserOpCallDataSwitch from './UserOpCallDataSwitch';
......@@ -35,17 +35,17 @@ const UserOpDecodedCallData = ({ data }: Props) => {
return (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint={ labelText }
>
{ labelText }
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
flexDir={{ base: 'column', lg: 'row' }}
alignItems={{ base: 'flex-start', lg: 'center' }}
>
<LogDecodedInputData data={ callData } rightSlot={ toggler }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
);
};
......
......@@ -16,9 +16,9 @@ import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CurrencyValue from 'ui/shared/CurrencyValue';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
......@@ -69,108 +69,108 @@ const UserOpDetails = ({ query }: Props) => {
templateColumns={{ base: 'minmax(0, 1fr)', lg: 'minmax(min-content, 220px) minmax(0, 1fr)' }}
overflow="hidden"
>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Unique character string assigned to every User operation"
isLoading={ isPlaceholderData }
>
User operation hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<UserOpEntity hash={ data.hash } noIcon noLink noCopy={ false }/>
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The address of the smart contract account"
isLoading={ isPlaceholderData }
>
Sender
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.sender } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Current User operation state"
isLoading={ isPlaceholderData }
>
Status
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<UserOpStatus status={ data.status } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.revert_reason && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="The revert reason of the User operation"
isLoading={ isPlaceholderData }
>
Revert reason
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
wordBreak="break-all"
whiteSpace="normal"
>
<Skeleton isLoaded={ !isPlaceholderData }>
{ data.revert_reason }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.timestamp && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Date and time of User operation"
isLoading={ isPlaceholderData }
>
Timestamp
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
<DetailsTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<DetailedInfoTimestamp timestamp={ data.timestamp } isLoading={ isPlaceholderData }/>
</DetailedInfo.ItemValue>
</>
) }
{ !config.UI.views.tx.hiddenFields?.tx_fee && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Total User operation fee"
isLoading={ isPlaceholderData }
>
Fee
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<CurrencyValue
value={ data.fee }
currency={ currencyUnits.ether }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas limit for the User operation"
isLoading={ isPlaceholderData }
>
Gas limit
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ BigNumber(data.gas).toFormat() }
</Skeleton>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Actual gas amount used by the User operation"
isLoading={ isPlaceholderData }
>
Gas used
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }>
{ BigNumber(data.gas_used).toFormat() }
</Skeleton>
......@@ -180,37 +180,37 @@ const UserOpDetails = ({ query }: Props) => {
value={ BigNumber(data.gas_used).dividedBy(BigNumber(data.gas)).toNumber() }
isLoading={ isPlaceholderData }
/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Hash of the transaction this User operation belongs to"
isLoading={ isPlaceholderData }
>
Transaction hash
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<TxEntity hash={ data.transaction_hash } isLoading={ isPlaceholderData } noCopy={ false }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Block number containing this User operation"
isLoading={ isPlaceholderData }
>
Block
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<BlockEntity number={ Number(data.block_number) } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Contract that executes bundles of User operations"
isLoading={ isPlaceholderData }
>
Entry point
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.entry_point } isLoading={ isPlaceholderData }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ config.features.txInterpretation.isEnabled && <UserOpDetailsActions hash={ data.hash } isUserOpDataLoading={ isPlaceholderData }/> }
......@@ -235,158 +235,158 @@ const UserOpDetails = ({ query }: Props) => {
<>
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas limit for execution phase"
>
Call gas limit
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(data.call_gas_limit).toFormat() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas limit for verification phase"
>
Verification gas limit
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(data.verification_gas_limit).toFormat() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Gas to compensate the bundler"
>
Pre-verification gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ BigNumber(data.pre_verification_gas).toFormat() }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ !config.UI.views.tx.hiddenFields?.gas_fees && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Maximum fee per gas "
>
Max fee per gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.max_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text variant="secondary" whiteSpace="pre">
{ space }({ BigNumber(data.max_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Maximum priority fee per gas"
>
Max priority fee per gas
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<Text>{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text variant="secondary" whiteSpace="pre">
{ space }({ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
{ data.aggregator && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Helper contract to validate an aggregated signature"
>
Aggregator
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.aggregator }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.aggregator_signature && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Aggregator signature"
>
Aggregator signature
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
{ data.aggregator_signature }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="A node (block builder) that handles User operations"
>
Bundler
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.bundler }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
{ data.factory && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Smart contract that deploys new smart contract wallets for users"
>
Factory
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.factory }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
{ data.paymaster && (
<>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Contract to sponsor the gas fees for User operations"
>
Paymaster
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<AddressStringOrParam address={ data.paymaster }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
</>
) }
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Type of the gas fees sponsor"
>
Sponsor type
</DetailsInfoItem.Label>
<DetailsInfoItem.Value>
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue>
<UserOpSponsorType sponsorType={ data.sponsor_type }/>
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItemDivider/>
<DetailedInfo.ItemDivider/>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Used to validate a User operation along with the nonce during verification"
>
Signature
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
wordBreak="break-all"
whiteSpace="normal"
>
{ data.signature }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<DetailsInfoItem.Label
<DetailedInfo.ItemLabel
hint="Anti-replay protection; also used as the salt for first-time account creation"
>
Nonce
</DetailsInfoItem.Label>
<DetailsInfoItem.Value
</DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue
wordBreak="break-all"
whiteSpace="normal"
>
{ data.nonce }
</DetailsInfoItem.Value>
</DetailedInfo.ItemValue>
<UserOpCallData data={ data }/>
......
......@@ -2,8 +2,8 @@ import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import DetailsActionsWrapper from 'ui/shared/DetailsActionsWrapper';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoActionsWrapper from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
interface Props {
......@@ -29,7 +29,7 @@ const TxDetailsActionsInterpretation = ({ hash, isUserOpDataLoading }: Props) =>
return (
<>
<DetailsActionsWrapper isLoading={ isUserOpDataLoading || interpretationQuery.isPlaceholderData } type="user_op">
<DetailedInfoActionsWrapper isLoading={ isUserOpDataLoading || interpretationQuery.isPlaceholderData } type="user_op">
{ actions.map((action, index: number) => (
<TxInterpretation
key={ index }
......@@ -38,8 +38,8 @@ const TxDetailsActionsInterpretation = ({ hash, isUserOpDataLoading }: Props) =>
/>
),
) }
</DetailsActionsWrapper>
<DetailsInfoItemDivider/>
</DetailedInfoActionsWrapper>
<DetailedInfo.ItemDivider/>
</>
);
};
......
......@@ -8,7 +8,7 @@ import config from 'configs/app';
// import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery';
import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailsActionsWrapper';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation';
......
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