import React, {
useMemo,
useCallback,
useState,
useEffect,
useContext,
} from "react";
import {
OverlayTrigger,
Tooltip,
Card,
Row as BRow,
Col as BCol,
Container,
Spinner,
} from "react-bootstrap";
import { useParams } from "react-router-dom";
import { Row } from "react-table";
import HashDisp from "src/components/Misc/Disp/HashDisp/HashDisp";
import ToAddrDisp from "src/components/Misc/Disp/ToAddrDisp/ToAddrDisp";
import ViewAllTable from "src/components/ViewAllPages/ViewAllTable/ViewAllTable";
import {
NetworkContext,
QueryPreservingLink,
} from "src/services/network/networkProvider";
import { TransactionDetails } from "src/typings/api";
import {
qaToZil,
timestampToTimeago,
hexAddrToZilAddr,
timestampToDisplay,
pubKeyToZilAddr,
} from "src/utils/Utils";
import { Transaction } from "@zilliqa-js/account/src/transaction";
import { TxBlockObj } from "@zilliqa-js/core/src/types";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCaretSquareLeft,
faCaretSquareRight,
} from "@fortawesome/free-regular-svg-icons";
import {
faCubes,
faExclamationCircle,
} from "@fortawesome/free-solid-svg-icons";
import LabelStar from "../Misc/LabelComponent/LabelStar";
import NotFoundPage from "../../ErrorPages/NotFoundPage";
import "./TxBlockDetailsPage.css";
const TxBlockDetailsPage: React.FC = () => {
const { blockNum } = useParams<{ blockNum: string }>();
const networkContext = useContext(NetworkContext);
if (!networkContext) {
return (
);
}
const { dataService, isIsolatedServer } = networkContext;
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [isLoadingTrans, setIsLoadingTrans] = useState(false);
const [txBlockObj, setTxBlockObj] = useState(null);
const [txBlockTxns, setTxBlockTxns] = useState(null);
const [latestTxBlockNum, setLatestTxBlockNum] = useState(null);
const [transactionData, setTransactionData] = useState<
TransactionDetails[] | null
>(null);
// Fetch data
useEffect(() => {
setIsLoading(true);
if (!dataService || isIsolatedServer === null) return;
let latestTxBlockNum: number;
let txBlockObj: TxBlockObj;
let txBlockTxns: string[];
const getData = async () => {
try {
if (isNaN(parseInt(blockNum)))
throw new Error("Not a valid block number");
if (isIsolatedServer) {
txBlockTxns = await dataService.getISTransactionsForTxBlock(
parseInt(blockNum)
);
latestTxBlockNum = await dataService.getISBlockNum();
} else {
txBlockObj = await dataService.getTxBlockObj(parseInt(blockNum));
latestTxBlockNum = await dataService.getNumTxBlocks();
try {
txBlockTxns = await dataService.getTransactionsForTxBlock(
parseInt(blockNum)
);
} catch (e) {
console.log(e);
}
}
if (txBlockObj) setTxBlockObj(txBlockObj);
if (txBlockTxns) setTxBlockTxns(txBlockTxns);
if (latestTxBlockNum) setLatestTxBlockNum(latestTxBlockNum);
} catch (e) {
console.error(e);
setError("An error occurred - please see console");
// TODO: Extract error and set error message
// setError(e);
} finally {
setIsLoading(false);
}
};
getData();
return () => {
setTxBlockObj(null);
setTxBlockTxns(null);
setLatestTxBlockNum(null);
setError(null);
};
}, [blockNum, dataService, isIsolatedServer]);
const columns = useMemo(
() => [
{
id: "from-col",
Header: "From",
accessor: "txn.senderAddress",
Cell: ({ value }: { value: string }) => (
{hexAddrToZilAddr(value)}
),
},
{
id: "to-col",
Header: "To",
Cell: ({ row }: { row: Row }) => {
return ;
},
},
{
id: "hash-col",
Header: "Hash",
Cell: ({ row }: { row: Row }) => {
console.log(row);
return (
{row.original.txn.txParams.receipt &&
!row.original.txn.txParams.receipt.success && (
)}
{"0x" + row.original.hash}
);
},
},
{
id: "amount-col",
Header: "Amount",
accessor: "txn.amount",
Cell: ({ value }: { value: string }) => (
{qaToZil(value)}}
>
{qaToZil(value, 10)}
),
},
{
id: "fee-col",
Header: "Fee",
accessor: "txn",
Cell: ({ value }: { value: Transaction }) => {
let fee = 0;
if (value.txParams.receipt) {
fee =
Number(value.txParams.gasPrice) *
value.txParams.receipt.cumulative_gas;
}
return (
{qaToZil(fee)}}
>
{qaToZil(fee, 4)}
);
},
},
],
[]
);
const fetchData = useCallback(
({ pageIndex }: { pageIndex: number }) => {
if (!txBlockTxns || !dataService) return;
let receivedData: TransactionDetails[];
const getData = async () => {
try {
setIsLoadingTrans(true);
receivedData = await dataService.getTransactionsDetails(
txBlockTxns.slice(pageIndex * 10, pageIndex * 10 + 10)
);
if (receivedData) setTransactionData(receivedData);
} catch (e) {
console.log(e);
} finally {
setIsLoadingTrans(false);
}
};
getData();
},
[dataService, txBlockTxns]
);
return (
<>
{isLoading ? (
) : null}
{error ? (
) : (
<>
{latestTxBlockNum && (
Tx Block{" "}
#{blockNum}
)}
{txBlockObj && (
<>
Date:
{timestampToDisplay(txBlockObj.header.Timestamp)} (
{timestampToTimeago(txBlockObj.header.Timestamp)})
Transactions:
{txBlockObj.header.NumTxns}
Gas Limit:
{txBlockObj.header.GasLimit}
Gas Used:
{txBlockObj.header.GasUsed}
Txn Fees:
{qaToZil(txBlockObj.header.TxnFees)}
Rewards Fees:
{qaToZil(txBlockObj.header.Rewards)}
DS Block:
{txBlockObj.header.DSBlockNum}
DS Leader:
{pubKeyToZilAddr(txBlockObj.header.MinerPubKey)}
{txBlockObj.body.MicroBlockInfos.length > 0 && (
Micro Blocks
{txBlockObj.body.MicroBlockInfos.map((x) => (
[{x.MicroBlockShardId}] {x.MicroBlockHash}
))}
)}
>
)}
{txBlockTxns && txBlockTxns.length > 0 && (
<>
Transactions
>
)}
>
)}
>
);
};
export default TxBlockDetailsPage;