Commit 341acb38 authored by tom's avatar tom

user ops

parent d13f87b4
...@@ -5,12 +5,12 @@ import React from 'react'; ...@@ -5,12 +5,12 @@ import React from 'react';
import type { Props } from 'nextjs/getServerSideProps'; import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs'; import PageNextJs from 'nextjs/PageNextJs';
// const UserOp = dynamic(() => import('ui/pages/UserOp'), { ssr: false }); const UserOp = dynamic(() => import('ui/pages/UserOp'), { ssr: false });
const Page: NextPage<Props> = (props: Props) => { const Page: NextPage<Props> = (props: Props) => {
return ( return (
<PageNextJs pathname="/op/[hash]" query={ props.query }> <PageNextJs pathname="/op/[hash]" query={ props.query }>
{ /* <UserOp/> */ } <UserOp/>
</PageNextJs> </PageNextJs>
); );
}; };
......
...@@ -4,12 +4,12 @@ import React from 'react'; ...@@ -4,12 +4,12 @@ import React from 'react';
import PageNextJs from 'nextjs/PageNextJs'; import PageNextJs from 'nextjs/PageNextJs';
// const UserOps = dynamic(() => import('ui/pages/UserOps'), { ssr: false }); const UserOps = dynamic(() => import('ui/pages/UserOps'), { ssr: false });
const Page: NextPage = () => { const Page: NextPage = () => {
return ( return (
<PageNextJs pathname="/ops"> <PageNextJs pathname="/ops">
{ /* <UserOps/> */ } <UserOps/>
</PageNextJs> </PageNextJs>
); );
}; };
......
...@@ -3,6 +3,7 @@ import * as React from 'react'; ...@@ -3,6 +3,7 @@ import * as React from 'react';
export interface SwitchProps extends ChakraSwitch.RootProps { export interface SwitchProps extends ChakraSwitch.RootProps {
inputProps?: React.InputHTMLAttributes<HTMLInputElement>; inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
labelProps?: ChakraSwitch.LabelProps;
rootRef?: React.Ref<HTMLLabelElement>; rootRef?: React.Ref<HTMLLabelElement>;
trackLabel?: { on: React.ReactNode; off: React.ReactNode }; trackLabel?: { on: React.ReactNode; off: React.ReactNode };
thumbLabel?: { on: React.ReactNode; off: React.ReactNode }; thumbLabel?: { on: React.ReactNode; off: React.ReactNode };
...@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps { ...@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps {
export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
function Switch(props, ref) { function Switch(props, ref) {
const { inputProps, children, rootRef, trackLabel, thumbLabel, ...rest } = const { inputProps, children, rootRef, trackLabel, thumbLabel, labelProps, ...rest } =
props; props;
return ( return (
...@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>( ...@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
) } ) }
</ChakraSwitch.Control > </ChakraSwitch.Control >
{ children != null && ( { children != null && (
<ChakraSwitch.Label>{ children }</ChakraSwitch.Label> <ChakraSwitch.Label { ...labelProps }>{ children }</ChakraSwitch.Label>
) } ) }
</ChakraSwitch.Root> </ChakraSwitch.Root>
); );
......
...@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit'; ...@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import type { TabItemRegular } from 'toolkit/components/AdaptiveTabs/types';
import type { Log } from 'types/api/log'; import type { Log } from 'types/api/log';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import type { RoutedTab } from 'ui/shared/Tabs/types';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/contexts/app'; import { useAppContext } from 'lib/contexts/app';
...@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError'; ...@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError';
import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { USER_OP } from 'stubs/userOps'; import { USER_OP } from 'stubs/userOps';
import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import RoutedTabsSkeleton from 'toolkit/components/RoutedTabs/RoutedTabsSkeleton';
import useActiveTabFromQuery from 'toolkit/components/RoutedTabs/useActiveTabFromQuery';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import useTabIndexFromQuery from 'ui/shared/Tabs/useTabIndexFromQuery';
import TxLogs from 'ui/tx/TxLogs'; import TxLogs from 'ui/tx/TxLogs';
import TxTokenTransfer from 'ui/tx/TxTokenTransfer'; import TxTokenTransfer from 'ui/tx/TxTokenTransfer';
import useTxQuery from 'ui/tx/useTxQuery'; import useTxQuery from 'ui/tx/useTxQuery';
...@@ -65,7 +65,7 @@ const UserOp = () => { ...@@ -65,7 +65,7 @@ const UserOp = () => {
} }
}, [ userOpQuery.data ]); }, [ userOpQuery.data ]);
const tabs: Array<RoutedTab> = React.useMemo(() => ([ const tabs: Array<TabItemRegular> = React.useMemo(() => ([
{ id: 'index', title: 'Details', component: <UserOpDetails query={ userOpQuery }/> }, { id: 'index', title: 'Details', component: <UserOpDetails query={ userOpQuery }/> },
{ {
id: 'token_transfers', id: 'token_transfers',
...@@ -76,7 +76,7 @@ const UserOp = () => { ...@@ -76,7 +76,7 @@ const UserOp = () => {
{ id: 'raw', title: 'Raw', component: <UserOpRaw rawData={ userOpQuery.data?.raw } isLoading={ userOpQuery.isPlaceholderData }/> }, { id: 'raw', title: 'Raw', component: <UserOpRaw rawData={ userOpQuery.data?.raw } isLoading={ userOpQuery.isPlaceholderData }/> },
]), [ userOpQuery, txQuery, filterTokenTransfersByLogIndex, filterLogsByLogIndex ]); ]), [ userOpQuery, txQuery, filterTokenTransfersByLogIndex, filterLogsByLogIndex ]);
const tabIndex = useTabIndexFromQuery(tabs); const activeTab = useActiveTabFromQuery(tabs);
const backLink = React.useMemo(() => { const backLink = React.useMemo(() => {
const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/ops'); const hasGoBackLink = appProps.referrer && appProps.referrer.includes('/ops');
...@@ -106,8 +106,8 @@ const UserOp = () => { ...@@ -106,8 +106,8 @@ const UserOp = () => {
/> />
{ userOpQuery.isPlaceholderData ? ( { userOpQuery.isPlaceholderData ? (
<> <>
<TabsSkeleton tabs={ tabs } mt={ 6 }/> <RoutedTabsSkeleton tabs={ tabs } mt={ 6 }/>
{ tabs[tabIndex]?.component } { activeTab?.component }
</> </>
) : ) :
<RoutedTabs tabs={ tabs }/> } <RoutedTabs tabs={ tabs }/> }
......
import type { FlexProps } from '@chakra-ui/react'; import type { FlexProps } from '@chakra-ui/react';
import { Flex, chakra } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
export interface Props extends FlexProps { export interface Props extends FlexProps {
...@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan ...@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan
); );
}; };
export default chakra(ContainerWithScrollY); export default ContainerWithScrollY;
...@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => { ...@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => {
); );
}; };
export const ItemValueWithScroll = ({ children, gradientHeight, onScrollVisibilityChange, className }: ContainerWithScrollY.Props) => { export const ItemValueWithScroll = ({ children, gradientHeight, onScrollVisibilityChange, ...rest }: ContainerWithScrollY.Props) => {
return ( return (
<ItemValue position="relative"> <ItemValue position="relative" >
<ContainerWithScrollY.default <ContainerWithScrollY.default
className={ className } { ...rest }
gradientHeight={ gradientHeight } gradientHeight={ gradientHeight }
onScrollVisibilityChange={ onScrollVisibilityChange } onScrollVisibilityChange={ onScrollVisibilityChange }
> >
......
...@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps { ...@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
const UserOpEntity = (props: EntityProps) => { const UserOpEntity = (props: EntityProps) => {
const partsProps = distributeEntityProps(props); const partsProps = distributeEntityProps(props);
const content = <Content { ...partsProps.content }/>;
return ( return (
<Container { ...partsProps.container }> <Container { ...partsProps.container }>
<Icon { ...partsProps.icon }/> <Icon { ...partsProps.icon }/>
<Link { ...partsProps.link }> { props.noLink ? content : <Link { ...partsProps.link }>{ content }</Link> }
<Content { ...partsProps.content }/>
</Link>
<Copy { ...partsProps.copy }/> <Copy { ...partsProps.copy }/>
</Container> </Container>
); );
......
...@@ -125,7 +125,7 @@ const TxInterpretationElementByType = ( ...@@ -125,7 +125,7 @@ const TxInterpretationElementByType = (
case 'method': { case 'method': {
return ( return (
<Badge <Badge
colorScheme={ value === 'Multicall' ? 'teal' : 'gray' } colorPalette={ value === 'Multicall' ? 'teal' : 'gray' }
truncated truncated
ml={ 1 } ml={ 1 }
mr={ 2 } mr={ 2 }
......
import { Tag } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { UserOpSponsorType as TUserOpSponsorType } from 'types/api/userOps'; import type { UserOpSponsorType as TUserOpSponsorType } from 'types/api/userOps';
import { Badge } from 'toolkit/chakra/badge';
type Props = { type Props = {
sponsorType: TUserOpSponsorType; sponsorType: TUserOpSponsorType;
}; };
...@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => { ...@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => {
case 'wallet_deposit': case 'wallet_deposit':
text = 'Wallet deposit'; text = 'Wallet deposit';
} }
return <Tag>{ text }</Tag>; return <Badge>{ text }</Badge>;
}; };
export default UserOpSponsorType; export default UserOpSponsorType;
import { chakra, FormLabel, FormControl, Switch } from '@chakra-ui/react'; import { chakra, Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { Switch } from 'toolkit/chakra/switch';
import Hint from 'ui/shared/Hint'; import Hint from 'ui/shared/Hint';
interface Props { interface Props {
...@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }: ...@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }:
}, [ onChange ]); }, [ onChange ]);
return ( return (
<FormControl className={ className } display="flex" columnGap={ 2 } ml="auto" w="fit-content"> <Flex ml="auto" alignItems="center" gap={ 2 }>
<FormLabel htmlFor="isExternal" fontSize="sm" lineHeight={ 5 } fontWeight={ 600 } m={ 0 }> <Switch
Show external call data className={ className }
</FormLabel> id="call-data-switch"
<Switch id="isExternal" isChecked={ isChecked } isDisabled={ isDisabled } onChange={ handleChange }/> checked={ isChecked }
disabled={ isDisabled }
onCheckedChange={ handleChange }
flexDirection="row-reverse"
size="md"
gap={ 2 }
labelProps={{ fontWeight: '600', fontSize: 'sm' }}
>
<chakra.span hideBelow="lg">Show external call data</chakra.span>
<chakra.span hideFrom="lg">External call data</chakra.span>
</Switch>
<Hint label="Inner call data is a predicted decoded call from this user operation"/> <Hint label="Inner call data is a predicted decoded call from this user operation"/>
</FormControl> </Flex>
); );
}; };
......
import { Grid, GridItem, Text, Link } from '@chakra-ui/react'; import { Grid, GridItem, Text } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query'; import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
import { scroller, Element } from 'react-scroll';
import type { UserOp } from 'types/api/userOps'; import type { UserOp } from 'types/api/userOps';
...@@ -12,12 +11,12 @@ import { WEI, WEI_IN_GWEI } from 'lib/consts'; ...@@ -12,12 +11,12 @@ import { WEI, WEI_IN_GWEI } from 'lib/consts';
import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError'; import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import { Skeleton } from 'toolkit/chakra/skeleton';
import CutLinkDetails from 'toolkit/components/CutLink/CutLinkDetails';
import isCustomAppError from 'ui/shared/AppError/isCustomAppError'; import isCustomAppError from 'ui/shared/AppError/isCustomAppError';
import Skeleton from 'ui/shared/chakra/Skeleton';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo'; import * as DetailedInfo from 'ui/shared/DetailedInfo/DetailedInfo';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp'; import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
...@@ -35,21 +34,9 @@ interface Props { ...@@ -35,21 +34,9 @@ interface Props {
query: UseQueryResult<UserOp, ResourceError>; query: UseQueryResult<UserOp, ResourceError>;
} }
const CUT_LINK_NAME = 'UserOpDetails__cutLink';
const UserOpDetails = ({ query }: Props) => { const UserOpDetails = ({ query }: Props) => {
const [ isExpanded, setIsExpanded ] = React.useState(false);
const { data, isPlaceholderData, isError, error } = query; const { data, isPlaceholderData, isError, error } = query;
const handleCutClick = React.useCallback(() => {
setIsExpanded((flag) => !flag);
scroller.scrollTo(CUT_LINK_NAME, {
duration: 500,
smooth: true,
});
}, []);
if (isError) { if (isError) {
if (error?.status === 400 || isCustomAppError(error)) { if (error?.status === 400 || isCustomAppError(error)) {
throwOnResourceLoadError({ isError, error }); throwOnResourceLoadError({ isError, error });
...@@ -76,7 +63,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -76,7 +63,7 @@ const UserOpDetails = ({ query }: Props) => {
User operation hash User operation hash
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue> <DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData } overflow="hidden"> <Skeleton loading={ isPlaceholderData } overflow="hidden">
<UserOpEntity hash={ data.hash } noIcon noLink noCopy={ false }/> <UserOpEntity hash={ data.hash } noIcon noLink noCopy={ false }/>
</Skeleton> </Skeleton>
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
...@@ -113,7 +100,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -113,7 +100,7 @@ const UserOpDetails = ({ query }: Props) => {
wordBreak="break-all" wordBreak="break-all"
whiteSpace="normal" whiteSpace="normal"
> >
<Skeleton isLoaded={ !isPlaceholderData }> <Skeleton loading={ isPlaceholderData }>
{ data.revert_reason } { data.revert_reason }
</Skeleton> </Skeleton>
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
...@@ -159,7 +146,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -159,7 +146,7 @@ const UserOpDetails = ({ query }: Props) => {
Gas limit Gas limit
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue> <DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }> <Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.gas).toFormat() } { BigNumber(data.gas).toFormat() }
</Skeleton> </Skeleton>
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
...@@ -171,7 +158,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -171,7 +158,7 @@ const UserOpDetails = ({ query }: Props) => {
Gas used Gas used
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue> <DetailedInfo.ItemValue>
<Skeleton isLoaded={ !isPlaceholderData }> <Skeleton loading={ isPlaceholderData }>
{ BigNumber(data.gas_used).toFormat() } { BigNumber(data.gas_used).toFormat() }
</Skeleton> </Skeleton>
<Utilization <Utilization
...@@ -214,25 +201,8 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -214,25 +201,8 @@ const UserOpDetails = ({ query }: Props) => {
{ config.features.txInterpretation.isEnabled && <UserOpDetailsActions hash={ data.hash } isUserOpDataLoading={ isPlaceholderData }/> } { config.features.txInterpretation.isEnabled && <UserOpDetailsActions hash={ data.hash } isUserOpDataLoading={ isPlaceholderData }/> }
{ /* CUT */ }
<GridItem colSpan={{ base: undefined, lg: 2 }}>
<Element name={ CUT_LINK_NAME }>
<Skeleton isLoaded={ !isPlaceholderData } mt={ 6 } display="inline-block">
<Link
fontSize="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
onClick={ handleCutClick }
>
{ isExpanded ? 'Hide details' : 'View details' }
</Link>
</Skeleton>
</Element>
</GridItem>
{ /* ADDITIONAL INFO */ } { /* ADDITIONAL INFO */ }
{ isExpanded && !isPlaceholderData && ( <CutLinkDetails loading={ isPlaceholderData } mt={ 6 } gridColumn={{ base: undefined, lg: '1 / 3' }}>
<>
<GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/> <GridItem colSpan={{ base: undefined, lg: 2 }} mt={{ base: 1, lg: 4 }}/>
<DetailedInfo.ItemLabel <DetailedInfo.ItemLabel
...@@ -271,7 +241,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -271,7 +241,7 @@ const UserOpDetails = ({ query }: Props) => {
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue> <DetailedInfo.ItemValue>
<Text>{ BigNumber(data.max_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text> <Text>{ BigNumber(data.max_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text variant="secondary" whiteSpace="pre"> <Text color="text.secondary" whiteSpace="pre">
{ space }({ BigNumber(data.max_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei }) { space }({ BigNumber(data.max_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text> </Text>
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
...@@ -283,7 +253,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -283,7 +253,7 @@ const UserOpDetails = ({ query }: Props) => {
</DetailedInfo.ItemLabel> </DetailedInfo.ItemLabel>
<DetailedInfo.ItemValue> <DetailedInfo.ItemValue>
<Text>{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text> <Text>{ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI).toFixed() } { currencyUnits.ether } </Text>
<Text variant="secondary" whiteSpace="pre"> <Text color="text.secondary" whiteSpace="pre">
{ space }({ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei }) { space }({ BigNumber(data.max_priority_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() } { currencyUnits.gwei })
</Text> </Text>
</DetailedInfo.ItemValue> </DetailedInfo.ItemValue>
...@@ -391,8 +361,7 @@ const UserOpDetails = ({ query }: Props) => { ...@@ -391,8 +361,7 @@ const UserOpDetails = ({ query }: Props) => {
<UserOpCallData data={ data }/> <UserOpCallData data={ data }/>
<UserOpDecodedCallData data={ data }/> <UserOpDecodedCallData data={ data }/>
</> </CutLinkDetails>
) }
</Grid> </Grid>
); );
}; };
......
...@@ -2,7 +2,7 @@ import React from 'react'; ...@@ -2,7 +2,7 @@ import React from 'react';
import type { UserOp } from 'types/api/userOps'; import type { UserOp } from 'types/api/userOps';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
import RawDataSnippet from 'ui/shared/RawDataSnippet'; import RawDataSnippet from 'ui/shared/RawDataSnippet';
// order is taken from the ERC-4337 standard // order is taken from the ERC-4337 standard
...@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => { ...@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => {
return res; return res;
}, {} as UserOp['raw']), undefined, 4); }, {} as UserOp['raw']), undefined, 4);
return <Skeleton isLoaded={ !isLoading }><RawDataSnippet data={ text }/></Skeleton>; return <Skeleton loading={ isLoading }><RawDataSnippet data={ text }/></Skeleton>;
}; };
export default UserOpRaw; export default UserOpRaw;
import { Flex, Link } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
// import type { UseQueryResult } from '@tanstack/react-query'; // import type { UseQueryResult } from '@tanstack/react-query';
import React from 'react'; import React from 'react';
...@@ -8,6 +8,7 @@ import config from 'configs/app'; ...@@ -8,6 +8,7 @@ import config from 'configs/app';
// import type { ResourceError } from 'lib/api/resources'; // import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery'; import useApiQuery from 'lib/api/useApiQuery';
import { TX_INTERPRETATION } from 'stubs/txInterpretation'; import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import { Link } from 'toolkit/chakra/link';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper'; import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailedInfo/DetailedInfoActionsWrapper';
import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity'; import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import TxInterpretation from 'ui/shared/tx/interpretation/TxInterpretation'; 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