Commit 2f780ab3 authored by isstuev's avatar isstuev

tx state changes changes!

parent eeeae759
...@@ -214,6 +214,7 @@ export const RESOURCES = { ...@@ -214,6 +214,7 @@ export const RESOURCES = {
tx_state_changes: { tx_state_changes: {
path: '/api/v2/transactions/:hash/state-changes', path: '/api/v2/transactions/:hash/state-changes',
pathParams: [ 'hash' as const ], pathParams: [ 'hash' as const ],
filterFields: [],
}, },
withdrawals: { withdrawals: {
path: '/api/v2/withdrawals', path: '/api/v2/withdrawals',
...@@ -507,7 +508,7 @@ export type ResourceErrorAccount<T> = ResourceError<{ errors: T }> ...@@ -507,7 +508,7 @@ export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>
export type PaginatedResources = 'blocks' | 'block_txs' | export type PaginatedResources = 'blocks' | 'block_txs' |
'txs_validated' | 'txs_pending' | 'txs_watchlist' | 'txs_validated' | 'txs_pending' | 'txs_watchlist' |
'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_state_changes' |
'addresses' | 'addresses' |
'address_txs' | 'address_internal_txs' | 'address_token_transfers' | 'address_blocks_validated' | 'address_coin_balance' | 'address_txs' | 'address_internal_txs' | 'address_token_transfers' | 'address_blocks_validated' | 'address_coin_balance' |
'search' | 'search' |
......
...@@ -72,6 +72,36 @@ export const receiveMintedToken: TxStateChange = { ...@@ -72,6 +72,36 @@ export const receiveMintedToken: TxStateChange = {
type: 'token', type: 'token',
}; };
export const transfer1155Token: TxStateChange = {
address: {
hash: '0x51243E83Db20F8FC2761D894067A2A9eb7B158DE',
implementation_name: null,
is_contract: false,
is_verified: false,
name: null,
private_tags: [],
public_tags: [],
watchlist_names: [],
},
balance_after: '1',
balance_before: '0',
change: '1',
is_miner: false,
token: {
address: '0x56Cc277717106E528A9FcC2CD342Ff98db758041',
decimals: null,
exchange_rate: null,
holders: '50413',
icon_url: null,
name: null,
symbol: null,
total_supply: null,
type: 'ERC-1155',
},
token_id: '1',
type: 'token',
};
export const receiveCoin: TxStateChange = { export const receiveCoin: TxStateChange = {
address: { address: {
hash: '0x8dC847Af872947Ac18d5d63fA646EB65d4D99560', hash: '0x8dC847Af872947Ac18d5d63fA646EB65d4D99560',
...@@ -110,9 +140,16 @@ export const sendCoin: TxStateChange = { ...@@ -110,9 +140,16 @@ export const sendCoin: TxStateChange = {
type: 'coin', type: 'coin',
}; };
export const baseResponse = [ export const baseResponse = {
mintToken, items: [
receiveMintedToken, mintToken,
sendCoin, receiveMintedToken,
receiveCoin, sendCoin,
]; receiveCoin,
transfer1155Token,
],
next_page_params: {
items_count: 50,
state_changes: null,
},
};
import type { TxStateChange, TxStateChanges } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import { ADDRESS_PARAMS } from './addressParams'; import { ADDRESS_PARAMS } from './addressParams';
import { TOKEN_INFO_ERC_721 } from './token'; import { TOKEN_INFO_ERC_721 } from './token';
...@@ -40,7 +40,7 @@ export const STATE_CHANGE_TOKEN: TxStateChange = { ...@@ -40,7 +40,7 @@ export const STATE_CHANGE_TOKEN: TxStateChange = {
type: 'token', type: 'token',
}; };
export const TX_STATE_CHANGES: TxStateChanges = [ export const TX_STATE_CHANGES: Array<TxStateChange> = [
STATE_CHANGE_MINER, STATE_CHANGE_MINER,
STATE_CHANGE_COIN, STATE_CHANGE_COIN,
STATE_CHANGE_TOKEN, STATE_CHANGE_TOKEN,
......
import type { AddressParam } from './addressParams'; import type { AddressParam } from './addressParams';
import type { TokenInfo } from './token'; import type { TokenInfo } from './token';
import type { Erc1155TotalPayload, Erc721TotalPayload } from './tokenTransfer'; import type { Erc721TotalPayload } from './tokenTransfer';
export type TxStateChange = (TxStateChangeCoin | TxStateChangeToken) & { export type TxStateChange = (TxStateChangeCoin | TxStateChangeToken) & {
address: AddressParam; address: AddressParam;
...@@ -34,24 +34,18 @@ export interface TxStateChangeTokenErc721 { ...@@ -34,24 +34,18 @@ export interface TxStateChangeTokenErc721 {
}>; }>;
} }
export type TxStateChangeTokenErc1155 = TxStateChangeTokenErc1155Single | TxStateChangeTokenErc1155Batch; export interface TxStateChangeTokenErc1155 {
export interface TxStateChangeTokenErc1155Single {
type: 'token';
token: TokenInfo<'ERC-1155'>;
change: Array<{
direction: ChangeDirection;
total: Erc1155TotalPayload;
}>;
}
export interface TxStateChangeTokenErc1155Batch {
type: 'token'; type: 'token';
token: TokenInfo<'ERC-1155'>; token: TokenInfo<'ERC-1155'>;
change: Array<{ change: string;
direction: ChangeDirection; token_id: string;
total: Array<Erc1155TotalPayload>;
}>;
} }
export type TxStateChanges = Array<TxStateChange>; export type TxStateChanges = {
items: Array<TxStateChange>;
next_page_params: {
items_count: number;
// ???
state_changes: null;
};
};
import { Accordion, Hide, Show, Text } from '@chakra-ui/react'; import { Accordion, Hide, Show, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useApiQuery from 'lib/api/useApiQuery';
import { SECOND } from 'lib/consts'; import { SECOND } from 'lib/consts';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import { TX_STATE_CHANGES } from 'stubs/txStateChanges'; import { TX_STATE_CHANGES } from 'stubs/txStateChanges';
import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay'; import DataListDisplay from 'ui/shared/DataListDisplay';
import Pagination from 'ui/shared/Pagination';
import TxStateList from 'ui/tx/state/TxStateList'; import TxStateList from 'ui/tx/state/TxStateList';
import TxStateTable from 'ui/tx/state/TxStateTable'; import TxStateTable from 'ui/tx/state/TxStateTable';
import useFetchTxInfo from 'ui/tx/useFetchTxInfo'; import useFetchTxInfo from 'ui/tx/useFetchTxInfo';
...@@ -14,11 +16,18 @@ import TxSocketAlert from './TxSocketAlert'; ...@@ -14,11 +16,18 @@ import TxSocketAlert from './TxSocketAlert';
const TxState = () => { const TxState = () => {
const txInfo = useFetchTxInfo({ updateDelay: 5 * SECOND }); const txInfo = useFetchTxInfo({ updateDelay: 5 * SECOND });
const { data, isPlaceholderData, isError } = useApiQuery('tx_state_changes', { const { data, isPlaceholderData, isError, isPaginationVisible, pagination } = useQueryWithPages({
resourceName: 'tx_state_changes',
pathParams: { hash: txInfo.data?.hash }, pathParams: { hash: txInfo.data?.hash },
queryOptions: { options: {
enabled: Boolean(txInfo.data?.hash) && Boolean(txInfo.data?.status), enabled: !txInfo.isPlaceholderData && Boolean(txInfo.data?.hash) && Boolean(txInfo.data?.status),
placeholderData: TX_STATE_CHANGES, placeholderData: {
items: TX_STATE_CHANGES,
next_page_params: {
items_count: 1,
state_changes: null,
},
},
}, },
}); });
...@@ -29,14 +38,20 @@ const TxState = () => { ...@@ -29,14 +38,20 @@ const TxState = () => {
const content = data ? ( const content = data ? (
<Accordion allowMultiple defaultIndex={ [] }> <Accordion allowMultiple defaultIndex={ [] }>
<Hide below="lg" ssr={ false }> <Hide below="lg" ssr={ false }>
<TxStateTable data={ data } isLoading={ isPlaceholderData }/> <TxStateTable data={ data.items } isLoading={ isPlaceholderData } top={ isPaginationVisible ? 80 : 0 }/>
</Hide> </Hide>
<Show below="lg" ssr={ false }> <Show below="lg" ssr={ false }>
<TxStateList data={ data } isLoading={ isPlaceholderData }/> <TxStateList data={ data.items } isLoading={ isPlaceholderData }/>
</Show> </Show>
</Accordion> </Accordion>
) : null; ) : null;
const actionBar = isPaginationVisible ? (
<ActionBar mt={ -6 } showShadow>
<Pagination ml="auto" { ...pagination }/>
</ActionBar>
) : null;
return ( return (
<> <>
<Text mb={ 6 }> <Text mb={ 6 }>
...@@ -45,9 +60,10 @@ const TxState = () => { ...@@ -45,9 +60,10 @@ const TxState = () => {
</Text> </Text>
<DataListDisplay <DataListDisplay
isError={ isError } isError={ isError }
items={ data } items={ data?.items }
emptyText="There are no state changes for this transaction." emptyText="There are no state changes for this transaction."
content={ content } content={ content }
actionBar={ actionBar }
/> />
</> </>
); );
......
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxStateChanges } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import TxStateListItem from 'ui/tx/state/TxStateListItem'; import TxStateListItem from 'ui/tx/state/TxStateListItem';
interface Props { interface Props {
data: TxStateChanges; data: Array<TxStateChange>;
isLoading?: boolean; isLoading?: boolean;
} }
......
...@@ -6,20 +6,21 @@ import { ...@@ -6,20 +6,21 @@ import {
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { TxStateChanges } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import { default as Thead } from 'ui/shared/TheadSticky'; import { default as Thead } from 'ui/shared/TheadSticky';
import TxStateTableItem from 'ui/tx/state/TxStateTableItem'; import TxStateTableItem from 'ui/tx/state/TxStateTableItem';
interface Props { interface Props {
data: TxStateChanges; data: Array<TxStateChange>;
isLoading?: boolean; isLoading?: boolean;
top: number;
} }
const TxStateTable = ({ data, isLoading }: Props) => { const TxStateTable = ({ data, isLoading, top }: Props) => {
return ( return (
<Table variant="simple" minWidth="1000px" size="sm" w="auto"> <Table variant="simple" minWidth="1000px" size="sm" w="auto">
<Thead top={ 0 }> <Thead top={ top }>
<Tr> <Tr>
<Th width="140px">Type</Th> <Th width="140px">Type</Th>
<Th width="146px">Address</Th> <Th width="146px">Address</Th>
......
...@@ -3,10 +3,8 @@ import React from 'react'; ...@@ -3,10 +3,8 @@ import React from 'react';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft'; import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import type { TxStateChangeNftItemFlatten } from './utils';
interface Props { interface Props {
items: Array<TxStateChangeNftItemFlatten>; items: Array<{total: { token_id: string} }>;
tokenAddress: string; tokenAddress: string;
isLoading?: boolean; isLoading?: boolean;
} }
......
...@@ -2,8 +2,7 @@ import { Flex, Skeleton, Tooltip } from '@chakra-ui/react'; ...@@ -2,8 +2,7 @@ import { Flex, Skeleton, Tooltip } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import React from 'react'; import React from 'react';
import type { TxStateChange, TxStateChangeTokenErc1155, TxStateChangeTokenErc1155Single, TxStateChangeTokenErc721 } from 'types/api/txStateChanges'; import type { TxStateChange } from 'types/api/txStateChanges';
import type { ArrayElement } from 'types/utils';
import appConfig from 'configs/app/config'; import appConfig from 'configs/app/config';
import { ZERO_ADDRESS } from 'lib/consts'; import { ZERO_ADDRESS } from 'lib/consts';
...@@ -12,6 +11,7 @@ import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; ...@@ -12,6 +11,7 @@ import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import trimTokenSymbol from 'lib/token/trimTokenSymbol'; import trimTokenSymbol from 'lib/token/trimTokenSymbol';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxStateTokenIdList from './TxStateTokenIdList'; import TxStateTokenIdList from './TxStateTokenIdList';
...@@ -98,11 +98,22 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -98,11 +98,22 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
const tokenId = (() => { const tokenId = (() => {
if (!Array.isArray(data.change)) { if (!Array.isArray(data.change)) {
return null; if ('token_id' in data && data.token_id) {
return (
<TokenTransferNft
hash={ data.token.address }
id={ data.token_id }
w="auto"
truncation="constant"
isLoading={ isLoading }
/>
);
} else {
return null;
}
} }
const items = (data.change as Array<TxStateChangeNftItem>).reduce(flattenTotal, []); return <TxStateTokenIdList items={ data.change } tokenAddress={ data.token.address } isLoading={ isLoading }/>;
return <TxStateTokenIdList items={ items } tokenAddress={ data.token.address } isLoading={ isLoading }/>;
})(); })();
return { return {
...@@ -127,16 +138,3 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) { ...@@ -127,16 +138,3 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
} }
} }
} }
export type TxStateChangeNftItem = ArrayElement<TxStateChangeTokenErc721['change'] | TxStateChangeTokenErc1155['change']>;
export type TxStateChangeNftItemFlatten = ArrayElement<TxStateChangeTokenErc721['change'] | TxStateChangeTokenErc1155Single['change']>;
function flattenTotal(result: Array<TxStateChangeNftItemFlatten>, item: TxStateChangeNftItem): Array<TxStateChangeNftItemFlatten> {
if (Array.isArray(item.total)) {
result.push(...item.total.map((total) => ({ ...item, total })));
} else {
result.push({ ...item, total: item.total });
}
return result;
}
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