bridge_ui: minimal transaction count metrics on stats page

Change-Id: I197284b33514b0eb4ece281d982b541dbc5dc015
This commit is contained in:
Chase Moran 2021-10-29 08:53:51 -04:00 committed by Evan Gray
parent 93a09e01aa
commit d8a00e65e4
4 changed files with 276 additions and 0 deletions

View File

@ -0,0 +1,156 @@
import {
CircularProgress,
Link,
makeStyles,
Typography,
} from "@material-ui/core";
import clsx from "clsx";
import useTransactionCount from "../../hooks/useTransactionCount";
import { WORMHOLE_EXPLORER_BASE } from "../../utils/consts";
const useStyles = makeStyles((theme) => ({
logoPositioner: {
height: "30px",
width: "30px",
maxWidth: "30px",
marginRight: theme.spacing(1),
display: "flex",
alignItems: "center",
},
logo: {
maxHeight: "100%",
maxWidth: "100%",
},
tokenContainer: {
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
},
flexBox: {
display: "flex",
alignItems: "flex-end",
marginBottom: theme.spacing(1),
textAlign: "left",
[theme.breakpoints.down("sm")]: {
flexDirection: "column",
alignItems: "unset",
},
},
grower: {
flexGrow: 1,
},
alignCenter: {
margin: "0 auto",
display: "block",
textAlign: "center",
},
totalsBox: {
display: "flex",
width: "100%",
justifyContent: "space-evenly",
alignItems: "center",
},
totalContainer: {
display: "flex",
alignItems: "flex-end",
paddingBottom: 1, // line up with left text bottom
[theme.breakpoints.down("sm")]: {
marginTop: theme.spacing(1),
},
},
totalValue: {
marginLeft: theme.spacing(0.5),
marginBottom: "-.125em", // line up number with label
},
typog: {
marginTop: theme.spacing(3),
},
}));
const TransactionMetrics: React.FC<any> = () => {
const transactionCount = useTransactionCount();
const classes = useStyles();
const isFetching = transactionCount.isFetching;
const header = (
<div className={classes.flexBox}>
<div>
<Typography variant="h5">Transaction Count</Typography>
<Typography variant="subtitle2" color="textSecondary">
This is how many transactions the Token Bridge has processed.
</Typography>
</div>
<div className={classes.grower} />
</div>
);
const content = (
<div className={classes.totalsBox}>
<div className={classes.totalContainer}>
<Typography
variant="body2"
color="textSecondary"
component="div"
noWrap
>
{"Last 48 Hours"}
</Typography>
<Typography
variant="h3"
component="div"
noWrap
className={classes.totalValue}
>
{transactionCount.data?.total24h || "0"}
</Typography>
</div>
<div className={classes.totalContainer}>
<Typography
variant="body2"
color="textSecondary"
component="div"
noWrap
>
{"All Time"}
</Typography>
<Typography
variant="h3"
component="div"
noWrap
className={classes.totalValue}
>
{transactionCount.data?.totalAllTime || "0"}
</Typography>
</div>
</div>
);
const networkExplorer = (
<Typography
variant="subtitle1"
className={clsx(classes.alignCenter, classes.typog)}
>
To see metrics for the entire Wormhole Network (not just this bridge),
check out the{" "}
<Link href={WORMHOLE_EXPLORER_BASE} target="_blank">
Wormhole Network Explorer
</Link>
</Typography>
);
return (
<>
{header}
{isFetching ? (
<CircularProgress className={classes.alignCenter} />
) : (
<>
{content}
{networkExplorer}
</>
)}
</>
);
};
export default TransactionMetrics;

View File

@ -17,6 +17,7 @@ import { balancePretty } from "../TokenSelectors/TokenPicker";
import CustodyAddresses from "./CustodyAddresses";
import NFTStats from "./NFTStats";
import MuiReactTable from "./tableComponents/MuiReactTable";
import TransactionMetrics from "./TransactionMetrics";
const useStyles = makeStyles((theme) => ({
logoPositioner: {
@ -252,6 +253,9 @@ const StatsRoot: React.FC<any> = () => {
<Paper className={classes.mainPaper}>
<NFTStats />
</Paper>
<Paper className={classes.mainPaper}>
<TransactionMetrics />
</Paper>
<Paper className={classes.mainPaper}>
<CustodyAddresses />
</Paper>

View File

@ -0,0 +1,100 @@
import axios from "axios";
import { useEffect, useMemo, useState } from "react";
import { DataWrapper } from "../store/helpers";
import {
RECENT_TRANSACTIONS_WORMHOLE,
TOTAL_TRANSACTIONS_WORMHOLE,
VAA_EMITTER_ADDRESSES,
} from "../utils/consts";
export type TransactionCount = {
totalAllTime: number;
total24h: number;
mostRecent: any; //This will be a signedVAA
};
const mergeResults = (totals: any, recents: any): TransactionCount | null => {
let totalAllTime = 0;
let total24h = 0;
VAA_EMITTER_ADDRESSES.forEach((address: string) => {
let totalAll = (totals?.TotalCount && totals.TotalCount[address]) || 0;
let total24 = (totals?.LastDayCount && totals.LastDayCount[address]) || 0;
totalAllTime += totalAll;
total24h += total24;
});
return {
totalAllTime,
total24h,
mostRecent: null,
};
};
const useTransactionCount = (): DataWrapper<TransactionCount> => {
const [totals, setTotals] = useState(null);
const [recents, setRecents] = useState(null);
const [loadingTotals, setLoadingTotals] = useState(false);
const [loadingRecents, setLoadingRecents] = useState(false);
const [totalsError, setTotalsError] = useState("");
const [recentsError, setRecentsError] = useState("");
useEffect(() => {
let cancelled = false;
setLoadingTotals(true);
axios.get(TOTAL_TRANSACTIONS_WORMHOLE).then(
(results) => {
if (!cancelled) {
setTotals(results.data);
setLoadingTotals(false);
}
},
(error) => {
if (!cancelled) {
setTotalsError("Unable to retrieve transaction totals.");
setLoadingTotals(false);
}
}
);
}, []);
useEffect(() => {
let cancelled = false;
setLoadingRecents(true);
axios.get(RECENT_TRANSACTIONS_WORMHOLE).then(
(results) => {
if (!cancelled) {
setRecents(results.data);
setLoadingRecents(false);
}
},
(error) => {
if (!cancelled) {
setRecentsError("Unable to retrieve recent transactions.");
setLoadingRecents(false);
}
}
);
}, []);
return useMemo(() => {
const data = mergeResults(totals, recents);
return {
isFetching: loadingRecents || loadingTotals,
error: totalsError || recentsError,
receivedAt: null,
data: data,
};
}, [
totals,
recents,
loadingRecents,
loadingTotals,
recentsError,
totalsError,
]);
};
export default useTransactionCount;

View File

@ -612,3 +612,19 @@ export const TERRA_FCD_BASE =
? "https://bombay-fcd.terra.dev"
: "http://localhost:3060";
export const TERRA_GAS_PRICES_URL = `${TERRA_FCD_BASE}/v1/txs/gas_prices`;
export const TOTAL_TRANSACTIONS_WORMHOLE = `https://europe-west3-wormhole-315720.cloudfunctions.net/mainnet/totals?groupBy=address`;
export const RECENT_TRANSACTIONS_WORMHOLE = `https://europe-west3-wormhole-315720.cloudfunctions.net/mainnet/recent?groupBy=address&numRows=2`;
export const VAA_EMITTER_ADDRESSES = [
`${CHAIN_ID_SOLANA}:ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5`, //SOLANA TOKEN
`${CHAIN_ID_SOLANA}:0def15a24423e1edd1a5ab16f557b9060303ddbab8c803d2ee48f4b78a1cfd6b`, //SOLAN NFT
`${CHAIN_ID_ETH}:0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585`, //ETH token
`${CHAIN_ID_ETH}:0000000000000000000000006ffd7ede62328b3af38fcd61461bbfc52f5651fe`, //ETH NFT
`${CHAIN_ID_TERRA}:0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2`, //terra
`${CHAIN_ID_BSC}:000000000000000000000000b6f6d86a8f9879a9c87f643768d9efc38c1da6e7`, //bsc
`${CHAIN_ID_BSC}:0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde`, //bsc nft
];
export const WORMHOLE_EXPLORER_BASE = "https://wormholenetwork.com/en/explorer";