Commit f00d3b38 authored by isstuev's avatar isstuev

token transfers and call data

parent a6ab591b
......@@ -47,4 +47,6 @@ export type UserOp = {
signature: string;
nonce: string;
call_data: string;
user_logs_start_index: number;
user_logs_count: number;
}
import { inRange } from 'lodash';
import { useRouter } from 'next/router';
import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer';
import type { RoutedTab } from 'ui/shared/Tabs/types';
import useApiQuery from 'lib/api/useApiQuery';
......@@ -13,6 +15,8 @@ import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import TxTokenTransfer from 'ui/tx/TxTokenTransfer';
import UserOpCallData from 'ui/userOp/UserOpCallData';
import UserOpDetails from 'ui/userOp/UserOpDetails';
const TAB_LIST_PROPS = {
......@@ -35,14 +39,28 @@ const BlockPageContent = () => {
},
});
const filterTokenTransfersByLogIndex = React.useCallback((tt: TokenTransfer) => {
if (!userOpQuery.data) {
return true;
} else {
if (inRange(Number(tt.log_index), userOpQuery.data.user_logs_start_index, userOpQuery.data.user_logs_start_index + userOpQuery.data.user_logs_count)) {
return true;
}
return false;
}
}, [ userOpQuery.data ]);
const tabs: Array<RoutedTab> = React.useMemo(() => ([
{ id: 'index', title: 'Details', component: <UserOpDetails query={ userOpQuery }/> },
{ id: 'token_transfers', title: 'Token transfers', component: null },
// { id: 'token_transfers', title: 'Token transfers', component: <UserOpTokenTransfers txHash={ userOpQuery.data?.transaction_hash }/> },
// { id: 'call_data', title: 'Call data', component: <UserOpCallData callData={ userOpQuery.data?.call_data }/> }
{
id: 'token_transfers',
title: 'Token transfers',
component: <TxTokenTransfer txHash={ userOpQuery.data?.transaction_hash } tokenTransferFilter={ filterTokenTransfersByLogIndex }/>,
},
{ id: 'call_data', title: 'Call data', component: <UserOpCallData rawCallData={ userOpQuery.data?.call_data }/> },
// { id: 'logs', title: 'Logs', component: <UserOpLogs txHash={ userOpQuery.data?.transaction_hash }/> }
// { id: 'raw', title: 'Raw', component: <UserOpRaw txHash={ userOpQuery.data?.transaction_hash }/> }
].filter(Boolean)), [ userOpQuery ]);
].filter(Boolean)), [ userOpQuery, filterTokenTransfersByLogIndex ]);
if (!hash) {
throw new Error('User operation not found', { cause: { status: 404 } });
......
......@@ -3,6 +3,7 @@ import { useRouter } from 'next/router';
import React from 'react';
import type { TokenType } from 'types/api/token';
import type { TokenTransfer } from 'types/api/tokenTransfer';
import { SECOND } from 'lib/consts';
import getFilterValuesFromQuery from 'lib/getFilterValuesFromQuery';
......@@ -23,8 +24,13 @@ import useFetchTxInfo from 'ui/tx/useFetchTxInfo';
const getTokenFilterValue = (getFilterValuesFromQuery<TokenType>).bind(null, TOKEN_TYPE_IDS);
const TxTokenTransfer = () => {
const txsInfo = useFetchTxInfo({ updateDelay: 5 * SECOND });
type Props = {
txHash?: string;
tokenTransferFilter?: (tt: TokenTransfer) => boolean;
}
const TxTokenTransfer = ({ txHash, tokenTransferFilter }: Props) => {
const txsInfo = useFetchTxInfo({ updateDelay: 5 * SECOND, txHash });
const router = useRouter();
......@@ -56,13 +62,23 @@ const TxTokenTransfer = () => {
const numActiveFilters = typeFilter.length;
const isActionBarHidden = !numActiveFilters && !tokenTransferQuery.data?.items.length;
let items: Array<TokenTransfer> = [];
if (tokenTransferQuery.data?.items) {
if (tokenTransferQuery.isPlaceholderData) {
items = tokenTransferQuery.data?.items;
} else {
items = tokenTransferFilter ? tokenTransferQuery.data.items.filter(tokenTransferFilter) : tokenTransferQuery.data.items;
}
}
const content = tokenTransferQuery.data?.items ? (
<>
<Hide below="lg" ssr={ false }>
<TokenTransferTable data={ tokenTransferQuery.data?.items } top={ isActionBarHidden ? 0 : 80 } isLoading={ tokenTransferQuery.isPlaceholderData }/>
<TokenTransferTable data={ items } top={ isActionBarHidden ? 0 : 80 } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Hide>
<Show below="lg" ssr={ false }>
<TokenTransferList data={ tokenTransferQuery.data?.items } isLoading={ tokenTransferQuery.isPlaceholderData }/>
<TokenTransferList data={ items } isLoading={ tokenTransferQuery.isPlaceholderData }/>
</Show>
</>
) : null;
......@@ -82,7 +98,7 @@ const TxTokenTransfer = () => {
return (
<DataListDisplay
isError={ txsInfo.isError || tokenTransferQuery.isError }
items={ tokenTransferQuery.data?.items }
items={ items }
emptyText="There are no token transfers."
filterProps={{
emptyFilteredText: `Couldn${ apos }t find any token transfer that matches your query.`,
......
......@@ -18,17 +18,18 @@ import { TX, TX_ZKEVM_L2 } from 'stubs/tx';
interface Params {
onTxStatusUpdate?: () => void;
updateDelay?: number;
txHash?: string;
}
type ReturnType = UseQueryResult<Transaction, ResourceError<{ status: number }>> & {
socketStatus: 'close' | 'error' | undefined;
}
export default function useFetchTxInfo({ onTxStatusUpdate, updateDelay }: Params | undefined = {}): ReturnType {
export default function useFetchTxInfo({ onTxStatusUpdate, updateDelay, txHash }: Params | undefined = {}): ReturnType {
const router = useRouter();
const queryClient = useQueryClient();
const [ socketStatus, setSocketStatus ] = React.useState<'close' | 'error'>();
const hash = getQueryParamString(router.query.hash);
const hash = txHash || getQueryParamString(router.query.hash);
const queryResult = useApiQuery<'tx', { status: number }>('tx', {
pathParams: { hash },
......
import React from 'react';
import RawInputData from 'ui/shared/RawInputData';
// decoded calldata will be added later
type Props = {
rawCallData?: string;
}
const UserOpCallData = ({ rawCallData }: Props) => {
if (!rawCallData) {
return null;
}
return <RawInputData hex={ rawCallData }/>;
};
export default UserOpCallData;
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