Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal transactions list page #2553

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ export const RESOURCES = {
withdrawals_counters: {
path: '/api/v2/withdrawals/counters',
},
internal_txs: {
path: '/api/v2/internal-transactions',
},

// ADDRESSES
addresses: {
Expand Down Expand Up @@ -1219,7 +1222,7 @@ export interface ResourceError<T = unknown> {
export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>;

export type PaginatedResources = 'blocks' | 'block_txs' | 'block_election_rewards' |
'txs_validated' | 'txs_pending' | 'txs_with_blobs' | 'txs_watchlist' | 'txs_execution_node' |
'txs_validated' | 'txs_pending' | 'txs_with_blobs' | 'txs_watchlist' | 'txs_execution_node' | 'internal_txs' |
'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_state_changes' | 'tx_blobs' |
'addresses' | 'addresses_metadata_search' |
'address_txs' | 'address_internal_txs' | 'address_token_transfers' | 'address_blocks_validated' | 'address_coin_balance' |
Expand Down Expand Up @@ -1288,6 +1291,7 @@ Q extends 'txs_pending' ? TransactionsResponsePending :
Q extends 'txs_with_blobs' ? TransactionsResponseWithBlobs :
Q extends 'txs_watchlist' ? TransactionsResponseWatchlist :
Q extends 'txs_execution_node' ? TransactionsResponseValidated :
Q extends 'internal_txs' ? InternalTransactionsResponse :
Q extends 'tx' ? Transaction :
Q extends 'tx_internal_txs' ? InternalTransactionsResponse :
Q extends 'tx_logs' ? LogsResponseTx :
Expand Down
10 changes: 10 additions & 0 deletions lib/hooks/useNavItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ export default function useNavItems(): ReturnType {
icon: 'transactions',
isActive: pathname === '/txs' || pathname === '/tx/[hash]',
};
const internalTxs: NavItem | null = {
text: 'Internal transactions',
nextRoute: { pathname: '/internal-txs' as const },
icon: 'transactions',
isActive: pathname === '/internal-txs',
};
const userOps: NavItem | null = config.features.userOps.isEnabled ? {
text: 'User operations',
nextRoute: { pathname: '/ops' as const },
Expand Down Expand Up @@ -118,6 +124,7 @@ export default function useNavItems(): ReturnType {
blockchainNavItems = [
[
txs,
internalTxs,
rollupDeposits,
rollupWithdrawals,
],
Expand All @@ -140,6 +147,7 @@ export default function useNavItems(): ReturnType {
blockchainNavItems = [
[
txs,
internalTxs,
rollupDeposits,
rollupWithdrawals,
],
Expand All @@ -155,6 +163,7 @@ export default function useNavItems(): ReturnType {
blockchainNavItems = [
[
txs,
internalTxs,
userOps,
blocks,
rollupTxnBatches,
Expand All @@ -169,6 +178,7 @@ export default function useNavItems(): ReturnType {
} else {
blockchainNavItems = [
txs,
internalTxs,
userOps,
blocks,
topAccounts,
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type OGPageType = 'Homepage' | 'Root page' | 'Regular page';
const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/': 'Homepage',
'/txs': 'Root page',
'/internal-txs': 'Root page',
'/txs/kettle/[hash]': 'Regular page',
'/tx/[hash]': 'Regular page',
'/blocks': 'Root page',
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const DEFAULT_TEMPLATE = 'Open-source block explorer by Blockscout. Search trans
const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/': DEFAULT_TEMPLATE,
'/txs': DEFAULT_TEMPLATE,
'/internal-txs': DEFAULT_TEMPLATE,
'/txs/kettle/[hash]': DEFAULT_TEMPLATE,
'/tx/[hash]': 'View transaction %hash% on %network_title%',
'/blocks': DEFAULT_TEMPLATE,
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import config from 'configs/app';
const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/': '%network_name% blockchain explorer - View %network_name% stats',
'/txs': '%network_name% transactions - %network_name% explorer',
'/internal-txs': '%network_name% internal transactions - %network_name% explorer',
'/txs/kettle/[hash]': '%network_name% kettle %hash% transactions',
'/tx/[hash]': '%network_name% transaction %hash%',
'/blocks': '%network_name% blocks',
Expand Down
1 change: 1 addition & 0 deletions lib/mixpanel/getPageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Route } from 'nextjs-routes';
export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/': 'Homepage',
'/txs': 'Transactions',
'/internal-txs': 'Internal transactions',
'/txs/kettle/[hash]': 'Kettle transactions',
'/tx/[hash]': 'Transaction details',
'/blocks': 'Blocks',
Expand Down
1 change: 1 addition & 0 deletions nextjs/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ declare module "nextjs-routes" {
| StaticRoute<"/gas-tracker">
| StaticRoute<"/graphiql">
| StaticRoute<"/">
| StaticRoute<"/internal-txs">
| StaticRoute<"/login">
| StaticRoute<"/mud-worlds">
| DynamicRoute<"/name-domains/[name]", { "name": string }>
Expand Down
19 changes: 19 additions & 0 deletions pages/internal-txs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';

import PageNextJs from 'nextjs/PageNextJs';

const InternalTxs = dynamic(() => import('ui/pages/InternalTxs'), { ssr: false });

const Page: NextPage = () => {
return (
<PageNextJs pathname="/internal-txs">
<InternalTxs/>
</PageNextJs>
);
};

export default Page;

export { base as getServerSideProps } from 'nextjs/getServerSideProps';
8 changes: 4 additions & 4 deletions ui/address/AddressInternalTxs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import { apos } from 'lib/html-entities';
import getQueryParamString from 'lib/router/getQueryParamString';
import { INTERNAL_TX } from 'stubs/internalTx';
import { generateListStub } from 'stubs/utils';
import AddressIntTxsTable from 'ui/address/internals/AddressIntTxsTable';
import InternalTxsList from 'ui/internalTxs/InternalTxsList';
import InternalTxsTable from 'ui/internalTxs/InternalTxsTable';
import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay';
import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';

import AddressCsvExportLink from './AddressCsvExportLink';
import AddressTxsFilter from './AddressTxsFilter';
import AddressIntTxsList from './internals/AddressIntTxsList';

const getFilterValue = (getFilterValueFromQuery<AddressFromToFilter>).bind(null, AddressFromToFilterValues);

Expand Down Expand Up @@ -71,10 +71,10 @@ const AddressInternalTxs = ({ scrollRef, shouldRender = true, isQueryEnabled = t
const content = data?.items ? (
<>
<Show below="lg" ssr={ false }>
<AddressIntTxsList data={ data.items } currentAddress={ hash } isLoading={ isPlaceholderData }/>
<InternalTxsList data={ data.items } currentAddress={ hash } isLoading={ isPlaceholderData }/>
</Show>
<Hide below="lg" ssr={ false }>
<AddressIntTxsTable data={ data.items } currentAddress={ hash } isLoading={ isPlaceholderData }/>
<InternalTxsTable data={ data.items } currentAddress={ hash } isLoading={ isPlaceholderData }/>
</Hide>
</>
) : null ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import React from 'react';

import type { InternalTransaction } from 'types/api/internalTransaction';

import AddressIntTxsListItem from 'ui/address/internals/AddressIntTxsListItem';
import InternalTxsListItem from './InternalTxsListItem';

type Props = {
data: Array<InternalTransaction>;
currentAddress: string;
currentAddress?: string;
isLoading?: boolean;
};

const AddressIntTxsList = ({ data, currentAddress, isLoading }: Props) => {
const InternalTxsList = ({ data, currentAddress, isLoading }: Props) => {
return (
<Box>
{ data.map((item, index) => (
<AddressIntTxsListItem
<InternalTxsListItem
key={ item.transaction_hash + '_' + index }
{ ...item }
currentAddress={ currentAddress }
Expand All @@ -26,4 +26,4 @@ const AddressIntTxsList = ({ data, currentAddress, isLoading }: Props) => {
);
};

export default AddressIntTxsList;
export default InternalTxsList;
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';

type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean };
type Props = InternalTransaction & { currentAddress?: string; isLoading?: boolean };

const TxInternalsListItem = ({
const InternalTxsListItem = ({
type,
from,
to,
Expand Down Expand Up @@ -83,4 +83,4 @@ const TxInternalsListItem = ({
);
};

export default TxInternalsListItem;
export default InternalTxsListItem;
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { AddressHighlightProvider } from 'lib/contexts/addressHighlight';
import { currencyUnits } from 'lib/units';
import { default as Thead } from 'ui/shared/TheadSticky';

import AddressIntTxsTableItem from './AddressIntTxsTableItem';
import InternalTxsTableItem from './InternalTxsTableItem';

interface Props {
data: Array<InternalTransaction>;
currentAddress: string;
currentAddress?: string;
isLoading?: boolean;
}

const AddressIntTxsTable = ({ data, currentAddress, isLoading }: Props) => {
const InternalTxsTable = ({ data, currentAddress, isLoading }: Props) => {
return (
<AddressHighlightProvider>
<Table>
Expand All @@ -32,7 +32,7 @@ const AddressIntTxsTable = ({ data, currentAddress, isLoading }: Props) => {
</Thead>
<Tbody>
{ data.map((item, index) => (
<AddressIntTxsTableItem
<InternalTxsTableItem
key={ item.transaction_hash + '_' + index }
{ ...item }
currentAddress={ currentAddress }
Expand All @@ -46,4 +46,4 @@ const AddressIntTxsTable = ({ data, currentAddress, isLoading }: Props) => {
);
};

export default AddressIntTxsTable;
export default InternalTxsTable;
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';

type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean };
type Props = InternalTransaction & { currentAddress?: string; isLoading?: boolean };

const AddressIntTxsTableItem = ({
const InternalTxsTableItem = ({
type,
from,
to,
Expand All @@ -36,7 +36,7 @@ const AddressIntTxsTableItem = ({
return (
<Tr alignItems="top">
<Td verticalAlign="middle">
<Flex rowGap={ 3 } flexWrap="wrap">
<Flex rowGap={ 3 } flexDir="column">
<TxEntity
hash={ txnHash }
isLoading={ isLoading }
Expand Down Expand Up @@ -91,4 +91,4 @@ const AddressIntTxsTableItem = ({
);
};

export default React.memo(AddressIntTxsTableItem);
export default React.memo(InternalTxsTableItem);
71 changes: 71 additions & 0 deletions ui/pages/InternalTxs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Hide, Show } from '@chakra-ui/react';
import React from 'react';

import useIsMobile from 'lib/hooks/useIsMobile';
import { INTERNAL_TX } from 'stubs/internalTx';
import { generateListStub } from 'stubs/utils';
import InternalTxsList from 'ui/internalTxs/InternalTxsList';
import InternalTxsTable from 'ui/internalTxs/InternalTxsTable';
import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay';
import PageTitle from 'ui/shared/Page/PageTitle';
import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';

const InternalTxs = () => {
const isMobile = useIsMobile();

const { isError, isPlaceholderData, data, pagination } = useQueryWithPages({
resourceName: 'internal_txs',
options: {
placeholderData: generateListStub<'internal_txs'>(
INTERNAL_TX,
50,
{
next_page_params: {
items_count: 50,
block_number: 1,
index: 1,
transaction_hash: '0x123',
transaction_index: 1,
},
},
),
},
});

const actionBar = (!isMobile || pagination.isVisible) ? (
<ActionBar mt={ -6 }>
<Pagination ml="auto" { ...pagination }/>
</ActionBar>
) : null;

const content = data?.items ? (
<>
<Show below="lg" ssr={ false }>
<InternalTxsList data={ data.items } isLoading={ isPlaceholderData }/>
</Show>
<Hide below="lg" ssr={ false }>
<InternalTxsTable data={ data.items } isLoading={ isPlaceholderData }/>
</Hide>
</>
) : null;

return (
<>
<PageTitle
title="Internal transactions"
withTextAd
/>
<DataListDisplay
isError={ isError }
items={ data?.items }
emptyText="There are no internal transactions."
content={ content }
actionBar={ actionBar }
/>
</>
);
};

export default InternalTxs;
Loading