Commit 34bc7548 authored by isstuev's avatar isstuev

withdrawals

parent d045fdc5
...@@ -2,7 +2,16 @@ export const data = { ...@@ -2,7 +2,16 @@ export const data = {
items: [ items: [
{ {
challenge_period_end: null, challenge_period_end: null,
from: '0x67aab90c548b284be30b05c376001b4db90b87ba', from: {
hash: '0x67aab90c548b284be30b05c376001b4db90b87ba',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: null, l1_tx_hash: null,
l2_timestamp: '2023-02-15T12:50:02.000000Z', l2_timestamp: '2023-02-15T12:50:02.000000Z',
l2_tx_hash: '0x918cd8c5c24c17e06cd02b0379510c4ad56324bf153578fb9caaaa2fe4e7dc35', l2_tx_hash: '0x918cd8c5c24c17e06cd02b0379510c4ad56324bf153578fb9caaaa2fe4e7dc35',
...@@ -13,7 +22,16 @@ export const data = { ...@@ -13,7 +22,16 @@ export const data = {
}, },
{ {
challenge_period_end: null, challenge_period_end: null,
from: '0x89e73303049ee32919903c09e8de5629b84f59eb', from: {
hash: '0x89e73303049ee32919903c09e8de5629b84f59eb',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: '0xf652ce024516713af6047771cd9a44f43a3edb364dfc0605cf151582ad6704c8', l1_tx_hash: '0xf652ce024516713af6047771cd9a44f43a3edb364dfc0605cf151582ad6704c8',
l2_timestamp: '2023-02-15T08:31:44.000000Z', l2_timestamp: '2023-02-15T08:31:44.000000Z',
l2_tx_hash: '0xc6377fde82ab495b397ee60ab94001df044a9e519662813688d7de8ade9fb3df', l2_tx_hash: '0xc6377fde82ab495b397ee60ab94001df044a9e519662813688d7de8ade9fb3df',
...@@ -24,7 +42,16 @@ export const data = { ...@@ -24,7 +42,16 @@ export const data = {
}, },
{ {
challenge_period_end: null, challenge_period_end: null,
from: '0xa490856fcb168b2a555a237dc86c4166199b1115', from: {
hash: '0xa490856fcb168b2a555a237dc86c4166199b1115',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: '0x392e521ec9519e37434e215720816443c39bfeee871f1f9969c897c649759ee4', l1_tx_hash: '0x392e521ec9519e37434e215720816443c39bfeee871f1f9969c897c649759ee4',
l2_timestamp: '2023-02-15T05:08:56.000000Z', l2_timestamp: '2023-02-15T05:08:56.000000Z',
l2_tx_hash: '0x65b8db3f2b2cc88d61d18bcf8771101b1ad3bd643d4fd556a97ed05fc545a70c', l2_tx_hash: '0x65b8db3f2b2cc88d61d18bcf8771101b1ad3bd643d4fd556a97ed05fc545a70c',
...@@ -35,7 +62,16 @@ export const data = { ...@@ -35,7 +62,16 @@ export const data = {
}, },
{ {
challenge_period_end: null, challenge_period_end: null,
from: '0xa490856fcb168b2a555a237dc86c4166199b1115', from: {
hash: '0xa490856fcb168b2a555a237dc86c4166199b1115',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: '0x41048f9e52f6320a82488acec0f82c35191d8fe683fcc945aa02f3646372d9a1', l1_tx_hash: '0x41048f9e52f6320a82488acec0f82c35191d8fe683fcc945aa02f3646372d9a1',
l2_timestamp: '2023-02-15T04:59:32.000000Z', l2_timestamp: '2023-02-15T04:59:32.000000Z',
l2_tx_hash: '0xdaf9231cd6fe8ec06bec233e9db0010ccd6e2a2004c9ccb5093f532d47d77854', l2_tx_hash: '0xdaf9231cd6fe8ec06bec233e9db0010ccd6e2a2004c9ccb5093f532d47d77854',
...@@ -46,7 +82,16 @@ export const data = { ...@@ -46,7 +82,16 @@ export const data = {
}, },
{ {
challenge_period_end: null, challenge_period_end: null,
from: '0xa490856fcb168b2a555a237dc86c4166199b1115', from: {
hash: '0xa490856fcb168b2a555a237dc86c4166199b1115',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: null, l1_tx_hash: null,
l2_timestamp: '2023-02-15T04:33:08.000000Z', l2_timestamp: '2023-02-15T04:33:08.000000Z',
l2_tx_hash: '0x5a72f0361777bebb0b7866f4a030aaa070b0abf625d9b96ea895d9bfa22de73c', l2_tx_hash: '0x5a72f0361777bebb0b7866f4a030aaa070b0abf625d9b96ea895d9bfa22de73c',
......
...@@ -314,13 +314,14 @@ frontend: ...@@ -314,13 +314,14 @@ frontend:
- "/search-results" - "/search-results"
- "/token" - "/token"
- "/tokens" - "/tokens"
- "/accounts"
- "/visualize"
- "/api-docs"
- "/csv-export" - "/csv-export"
- "/verified-contracts" - "/verified-contracts"
- "/graphiql" - "/graphiql"
- "/accounts"
- "/visualize"
- "/api-docs"
- "/output-roots" - "/output-roots"
- "/withdrawals"
resources: resources:
limits: limits:
memory: memory:
......
...@@ -38,6 +38,7 @@ import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/toke ...@@ -38,6 +38,7 @@ import type { TokenTransferResponse, TokenTransferFilters } from 'types/api/toke
import type { TransactionsResponseValidated, TransactionsResponsePending, Transaction } from 'types/api/transaction'; import type { TransactionsResponseValidated, TransactionsResponsePending, Transaction } from 'types/api/transaction';
import type { TTxsFilters } from 'types/api/txsFilters'; import type { TTxsFilters } from 'types/api/txsFilters';
import type { VisualizedContract } from 'types/api/visualization'; import type { VisualizedContract } from 'types/api/visualization';
import type { WithdrawalsResponse } from 'types/api/withdrawals';
import type ArrayElement from 'types/utils/ArrayElement'; import type ArrayElement from 'types/utils/ArrayElement';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
...@@ -361,7 +362,14 @@ export const RESOURCES = { ...@@ -361,7 +362,14 @@ export const RESOURCES = {
// GraphQL // GraphQL
graphql: { graphql: {
path: '/graphql', path: '/graphql',
}, },
// L2
withdrawals: {
path: '/api/v2/optimism/withdrawals',
paginationFields: [ 'nonce' as const, 'items_count' as const ],
filterFields: [],
},
output_roots: { output_roots: {
path: '/api/v2/optimism/output-roots', path: '/api/v2/optimism/output-roots',
...@@ -428,7 +436,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' | ...@@ -428,7 +436,7 @@ export type PaginatedResources = 'blocks' | 'block_txs' |
'token_transfers' | 'token_holders' | 'token_inventory' | 'tokens' | 'token_transfers' | 'token_holders' | 'token_inventory' | 'tokens' |
'token_instance_transfers' | 'token_instance_transfers' |
'verified_contracts' | 'verified_contracts' |
'output_roots'; 'output_roots' | 'withdrawals';
export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>; export type PaginatedResponse<Q extends PaginatedResources> = ResourcePayload<Q>;
...@@ -491,6 +499,7 @@ Q extends 'verified_contracts_counters' ? VerifiedContractsCounters : ...@@ -491,6 +499,7 @@ Q extends 'verified_contracts_counters' ? VerifiedContractsCounters :
Q extends 'visualize_sol2uml' ? VisualizedContract : Q extends 'visualize_sol2uml' ? VisualizedContract :
Q extends 'contract_verification_config' ? SmartContractVerificationConfig : Q extends 'contract_verification_config' ? SmartContractVerificationConfig :
Q extends 'output_roots' ? OutputRootsResponse : Q extends 'output_roots' ? OutputRootsResponse :
Q extends 'withdrawals' ? WithdrawalsResponse :
never; never;
/* eslint-enable @typescript-eslint/indent */ /* eslint-enable @typescript-eslint/indent */
......
...@@ -38,7 +38,7 @@ dayjs.updateLocale('en', { ...@@ -38,7 +38,7 @@ dayjs.updateLocale('en', {
relativeTime: { relativeTime: {
s: 'a sec', s: 'a sec',
ss: '%d secs', ss: '%d secs',
future: 'in %s', future: '%s left',
past: '%s ago', past: '%s ago',
m: '1 min', m: '1 min',
mm: '%d mins', mm: '%d mins',
......
export const data = {
items: [
{
challenge_period_end: null,
from: {
hash: '0x67aab90c548b284be30b05c376001b4db90b87ba',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
l1_tx_hash: null,
l2_timestamp: '2023-02-15T12:50:02.000000Z',
l2_tx_hash: '0x918cd8c5c24c17e06cd02b0379510c4ad56324bf153578fb9caaaa2fe4e7dc35',
msg_nonce: 396,
msg_nonce_raw: '1766847064778384329583297500742918515827483896875618958121606201292620172',
msg_nonce_version: 1,
status: 'Ready to prove',
},
{
challenge_period_end: null,
from: null,
l1_tx_hash: null,
l2_timestamp: null,
l2_tx_hash: '0x2f117bee32ac10cb7efdad98415737484ca66386e491cde9e17d42b136def593',
msg_nonce: 391,
msg_nonce_raw: '1766847064778384329583297500742918515827483896875618958121606201292620167',
msg_nonce_version: 1,
status: 'Ready to prove',
},
{
challenge_period_end: '2022-11-11T12:50:02.000000Z',
from: null,
l1_tx_hash: null,
l2_timestamp: null,
l2_tx_hash: '0xe14b1f46838176702244a5343629bcecf728ca2d9881d47b4ce46e00c387d7e3',
msg_nonce: 390,
msg_nonce_raw: '1766847064778384329583297500742918515827483896875618958121606201292620166',
msg_nonce_version: 1,
status: 'Ready for Relay',
},
],
next_page_params: {
items_count: 50,
nonce: '1766847064778384329583297500742918515827483896875618958121606201292620123',
},
total: 397,
};
import type { AddressParam } from './addressParams';
export type WithdrawalsItem = { export type WithdrawalsItem = {
'challenge_period_end': string | null; 'challenge_period_end': string | null;
'from': string | null; 'from': AddressParam | null;
'l1_tx_hash': string | null; 'l1_tx_hash': string | null;
'l2_timestamp': string | null; 'l2_timestamp': string | null;
'l2_tx_hash': string; 'l2_tx_hash': string;
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react';
import { data as withdrawalsData } from 'mocks/withdrawals/withdrawals';
import TestApp from 'playwright/TestApp';
import buildApiUrl from 'playwright/utils/buildApiUrl';
import Withdrawals from './Withdrawals';
const WITHDRAWALS_API_URL = buildApiUrl('withdrawals');
test('base view +@dark-mode', async({ mount, page }) => {
await page.route('https://request-global.czilladx.com/serve/native.php?z=19260bf627546ab7242', (route) => route.fulfill({
status: 200,
body: '',
}));
await page.route(WITHDRAWALS_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(withdrawalsData),
}));
const component = await mount(
<TestApp>
<Withdrawals/>
</TestApp>,
);
await expect(component.locator('main')).toHaveScreenshot();
});
import { Flex, Hide, Show, Skeleton, Text } from '@chakra-ui/react'; import { Flex, Hide, Show, Skeleton, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { data as dataMock } from 'data/withdrawals'; import useIsMobile from 'lib/hooks/useIsMobile';
import { rightLineArrow } from 'lib/html-entities'; import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import isBrowser from 'lib/isBrowser'; import { rightLineArrow, nbsp } from 'lib/html-entities';
import ActionBar from 'ui/shared/ActionBar';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import Page from 'ui/shared/Page/Page'; import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import Pagination from 'ui/shared/Pagination';
import SkeletonList from 'ui/shared/skeletons/SkeletonList'; import SkeletonList from 'ui/shared/skeletons/SkeletonList';
import SkeletonTable from 'ui/shared/skeletons/SkeletonTable'; import SkeletonTable from 'ui/shared/skeletons/SkeletonTable';
import WithdrawalsListItem from 'ui/withdrawals/WithdrawalsListItem'; import WithdrawalsListItem from 'ui/withdrawals/WithdrawalsListItem';
import WithdrawalsTable from 'ui/withdrawals/WithdrawalsTable'; import WithdrawalsTable from 'ui/withdrawals/WithdrawalsTable';
const Withdrawals = () => { const Withdrawals = () => {
// request!! const isMobile = useIsMobile();
const [ isLoading, setIsLoading ] = React.useState(true);
React.useEffect(() => {
if (isBrowser()) {
setTimeout(() => setIsLoading(false), 2000);
}
}, []);
const data = dataMock; const { data, isError, isLoading, isPaginationVisible, pagination } = useQueryWithPages({
const isPaginationVisible = false; resourceName: 'withdrawals',
});
const content = (() => { const content = (() => {
if (isError) {
return <DataFetchAlert/>;
}
const text = isLoading ?
<Skeleton w="400px" h="26px" mb={{ base: 6, lg: 0 }}/> :
<Text mb={{ base: 6, lg: 0 }}>A total of { data.total } withdrawals found</Text>;
const bar = (
<>
{ isMobile && text }
<ActionBar mt={ -6 }>
<Flex alignItems="center" justifyContent="space-between" w="100%">
{ !isMobile && text }
{ isPaginationVisible && <Pagination ml="auto" { ...pagination }/> }
</Flex>
</ActionBar>
</>
);
if (isLoading) { if (isLoading) {
return ( return (
<> <>
{ bar }
<SkeletonList display={{ base: 'block', lg: 'none' }}/> <SkeletonList display={{ base: 'block', lg: 'none' }}/>
{ /* !!! */ } <SkeletonTable display={{ base: 'none', lg: 'block' }} columns={ Array(7).fill(`${ 100 / 7 }%`) }/>
<SkeletonTable display={{ base: 'none', lg: 'block' }} columns={ [ '130px', '120px', '15%', '45%', '35%' ] }/>
</> </>
); );
} }
return ( return (
<> <>
{ bar }
<Show below="lg" ssr={ false }>{ data.items.map((item => <WithdrawalsListItem key={ item.l2_tx_hash } { ...item }/>)) }</Show> <Show below="lg" ssr={ false }>{ data.items.map((item => <WithdrawalsListItem key={ item.l2_tx_hash } { ...item }/>)) }</Show>
<Hide below="lg" ssr={ false }><WithdrawalsTable items={ data.items } top={ isPaginationVisible ? 80 : 0 }/></Hide> <Hide below="lg" ssr={ false }><WithdrawalsTable items={ data.items } top={ isPaginationVisible ? 80 : 0 }/></Hide>
</> </>
...@@ -43,9 +61,7 @@ const Withdrawals = () => { ...@@ -43,9 +61,7 @@ const Withdrawals = () => {
return ( return (
<Page> <Page>
<PageTitle text={ `Withdrawals (L2 ${ rightLineArrow } L1)` } withTextAd/> <PageTitle text={ `Withdrawals (L2${ nbsp }${ rightLineArrow }${ nbsp }L1)` } withTextAd/>
{ isLoading ? <Skeleton w="400px" h="26px" mb={ 7 }/> : <Text>A total of { data.total } withdrawals found</Text> }
{ /* Pagination */ }
{ content } { content }
</Page> </Page>
); );
......
import React from "react"; /* eslint-disable @typescript-eslint/naming-convention */
import { Box, Flex, Text, HStack, Icon } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
const WithdrawalsListItem = () => { import type { WithdrawalsItem } from 'types/api/withdrawals';
return null;
}
export default WithdrawalsListItem; import appConfig from 'configs/app/config';
\ No newline at end of file import txIcon from 'icons/transactions.svg';
import dayjs from 'lib/date/dayjs';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink';
import HashStringShorten from 'ui/shared/HashStringShorten';
import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile';
type Props = WithdrawalsItem;
const WithdrawalsListItem = ({
msg_nonce,
msg_nonce_version,
l1_tx_hash,
l2_timestamp,
l2_tx_hash,
from,
status,
challenge_period_end,
}: Props) => {
const timeAgo = useTimeAgoIncrement(l2_timestamp, false);
const timeToEnd = dayjs(challenge_period_end).fromNow();
return (
<ListItemMobile rowGap={ 3 }>
<Flex alignItems="center" justifyContent="space-between" w="100%">
<LinkInternal href={ route({ pathname: '/tx/[hash]', query: { hash: l2_tx_hash } }) } display="flex" alignItems="center">
<Icon as={ txIcon } boxSize={ 6 } mr={ 1 }/>
<Box w="calc(100% - 36px)" overflow="hidden" whiteSpace="nowrap"><HashStringShorten hash={ l2_tx_hash }/></Box>
</LinkInternal>
<Text variant="secondary">{ timeAgo }</Text>
</Flex>
<HStack spacing={ 3 } width="100%">
<Text fontSize="sm" fontWeight={ 500 } whiteSpace="nowrap">Msg nonce</Text>
<Text variant="secondary">{ msg_nonce_version + '-' + msg_nonce }</Text>
</HStack>
<HStack spacing={ 3 } width="100%">
<Text fontSize="sm" fontWeight={ 500 } whiteSpace="nowrap">Status</Text>
{ status === 'Ready for Relay' ?
<LinkExternal href={ appConfig.L2.withdrawalUrl }>{ status }</LinkExternal> :
<Text variant="secondary">{ status }</Text>
}
</HStack>
{ from && (
<HStack spacing={ 3 } width="100%">
<Text fontSize="sm" fontWeight={ 500 } whiteSpace="nowrap">From</Text>
<Address>
<AddressIcon address={ from }/>
<AddressLink hash={ from.hash } type="address" truncation="constant" ml={ 2 }/>
</Address>
</HStack>
) }
{ l1_tx_hash && (
<HStack spacing={ 3 } width="100%">
<Text fontSize="sm" fontWeight={ 500 } whiteSpace="nowrap">L1 txn hash</Text>
<LinkExternal href={ appConfig.L2.withdrawalUrl }><HashStringShorten hash={ l1_tx_hash }/></LinkExternal>
</HStack>
) }
{ challenge_period_end && (
<HStack spacing={ 3 } width="100%">
<Text fontSize="sm" fontWeight={ 500 } whiteSpace="nowrap">Time left</Text>
<Text variant="secondary">{ timeToEnd }</Text>
</HStack>
) }
</ListItemMobile>
);
};
export default WithdrawalsListItem;
...@@ -14,7 +14,7 @@ import WithdrawalsTableItem from './WithdrawalsTableItem'; ...@@ -14,7 +14,7 @@ import WithdrawalsTableItem from './WithdrawalsTableItem';
const WithdrawalsTable = ({ items, top }: Props) => { const WithdrawalsTable = ({ items, top }: Props) => {
return ( return (
<Table variant="simple" size="sm" style={{ tableLayout: 'auto' }}> <Table variant="simple" size="sm" style={{ tableLayout: 'auto' }} minW="950px">
<Thead top={ top }> <Thead top={ top }>
<Tr> <Tr>
<Th>Msg nonce</Th> <Th>Msg nonce</Th>
......
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { Box, Flex, Td, Tr, Text, Icon } from '@chakra-ui/react'; import { Box, Td, Tr, Text, Icon } from '@chakra-ui/react';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import React from 'react'; import React from 'react';
...@@ -7,20 +7,17 @@ import type { WithdrawalsItem } from 'types/api/withdrawals'; ...@@ -7,20 +7,17 @@ import type { WithdrawalsItem } from 'types/api/withdrawals';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import txIcon from 'icons/transactions.svg'; import txIcon from 'icons/transactions.svg';
import txBatchIcon from 'icons/txBatch.svg';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address'; import Address from 'ui/shared/address/Address';
import AddressIcon from 'ui/shared/address/AddressIcon'; import AddressIcon from 'ui/shared/address/AddressIcon';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
import LinkInternal from 'ui/shared/LinkInternal'; import LinkInternal from 'ui/shared/LinkInternal';
type Props = WithdrawalsItem; type Props = WithdrawalsItem;
const OutputRootsTableItem = ({ const WithdrawalsTableItem = ({
msg_nonce, msg_nonce,
msg_nonce_version, msg_nonce_version,
l1_tx_hash, l1_tx_hash,
...@@ -30,7 +27,10 @@ const OutputRootsTableItem = ({ ...@@ -30,7 +27,10 @@ const OutputRootsTableItem = ({
status, status,
challenge_period_end, challenge_period_end,
}: Props) => { }: Props) => {
const timeAgo = l2_timestamp ? useTimeAgoIncrement(l2_timestamp, false) : 'N/A'; const timeAgo = useTimeAgoIncrement(l2_timestamp, false) || 'N/A';
const timeToEnd = useTimeAgoIncrement(challenge_period_end, false) || '-';
// const timeToEnd = challenge_period_end ? dayjs(challenge_period_end).fromNow() : '-';
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle" fontWeight={ 600 }> <Td verticalAlign="middle" fontWeight={ 600 }>
...@@ -39,9 +39,8 @@ const OutputRootsTableItem = ({ ...@@ -39,9 +39,8 @@ const OutputRootsTableItem = ({
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ from ? ( { from ? (
<Address> <Address>
{ /* address info?? */ } <AddressIcon address={ from }/>
<AddressIcon address={{ hash: from, is_contract: false, implementation_name: null }}/> <AddressLink hash={ from.hash } type="address" truncation="constant" ml={ 2 }/>
<AddressLink hash={ from } type="address" truncation="constant" ml={ 2 }/>
</Address> </Address>
) : 'N/A' } ) : 'N/A' }
</Td> </Td>
...@@ -56,22 +55,21 @@ const OutputRootsTableItem = ({ ...@@ -56,22 +55,21 @@ const OutputRootsTableItem = ({
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ status === 'Ready for Relay' ? { status === 'Ready for Relay' ?
<LinkExternal title={ status } href={ appConfig.l2.withdrawalUrl }/> : <LinkExternal href={ appConfig.L2.withdrawalUrl }>{ status }</LinkExternal> :
<Text>{ status }</Text> <Text>{ status }</Text>
} }
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ l1_tx_hash ? { l1_tx_hash ?
//!!! <LinkExternal href={ appConfig.L2.withdrawalUrl }><HashStringShorten hash={ l1_tx_hash }/></LinkExternal> :
<LinkExternal title='aaa' href={ appConfig.l2.withdrawalUrl }/> :
'N/A' 'N/A'
} }
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ challenge_period_end ? challenge_period_end : '-'} { timeToEnd }
</Td> </Td>
</Tr> </Tr>
); );
}; };
export default OutputRootsTableItem; export default WithdrawalsTableItem;
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