Skip to content

Commit

Permalink
Show RPC block number on chain page (#187)
Browse files Browse the repository at this point in the history
* Poll RPCs on chain page

* Log errors temporarily

* Revert

* Improve formatting slightly

* Populate RPC responses as they are received
  • Loading branch information
FrederikBolding authored Jul 26, 2024
1 parent 8e07af6 commit 66bba61
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 17 deletions.
104 changes: 88 additions & 16 deletions src/components/RpcTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useContext } from "react";
import React, { useContext, useEffect, useState } from "react";
import {
Button,
Skeleton,
Table,
TableContainer,
Tbody,
Expand All @@ -10,34 +11,105 @@ import {
Tr,
} from "@chakra-ui/react";
import { Web3Context } from "../context/Web3Context";
import { JsonRpcProvider } from "ethers";
import { ChainData } from "../types/chain";

export const RpcTable = ({ rpcs, handleRpcClick }) => {
interface RpcResult {
rpcUrl: string;
blockNumber?: number;
latency?: number;
error?: unknown;
}

async function checkRpc(chainId: number, rpcUrl: string): Promise<RpcResult> {
try {
const now = Date.now();
const provider = new JsonRpcProvider(rpcUrl, chainId, {
staticNetwork: true,
});
const blockNumber = await provider.getBlockNumber();
return { rpcUrl, blockNumber, latency: Date.now() - now };
} catch (error) {
return { rpcUrl, error };
}
}

export const RpcTable = ({
chainId,
rpcs,
handleRpcClick,
}: Pick<ChainData, "chainId"> & {
rpcs: ChainData["rpc"];
handleRpcClick: (rpc: string) => void;
}) => {
const { isConnected, handleConnect } = useContext(Web3Context);
const [rpcResults, setRpcResults] = useState<RpcResult[] | null>(null);

useEffect(() => {
rpcs.forEach((rpc) =>
checkRpc(chainId, rpc).then((result) => {
setRpcResults((state) => [...(state ?? []), result]);
})
);
}, []);

const mergedRpcs = rpcs
.map((rpcUrl) => {
const rpcResult = rpcResults?.find((result) => result.rpcUrl === rpcUrl);
return rpcResult ?? { rpcUrl };
})
.sort((a, b) => {
if (!a.latency) {
return 1;
}
if (!b.latency) {
return -1;
}
return a.latency < b.latency ? -1 : 1;
});

return (
<TableContainer>
<Table>
<Thead>
<Tr>
<Th pl="0">RPC URL</Th>
<Th>Block Number</Th>
<Th>Latency</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{rpcs.map((rpcUrl) => (
<Tr>
<Td pl="0">{rpcUrl}</Td>
<Td pr="0" textAlign="end">
{!isConnected ? (
<Button onClick={handleConnect}>Connect</Button>
) : (
<Button onClick={() => handleRpcClick(rpcUrl)}>
Add Chain
</Button>
)}
</Td>
</Tr>
))}
{mergedRpcs.map(({ rpcUrl, blockNumber, latency, error }) => {
return (
<Tr key={rpcUrl}>
<Td pl="0">{rpcUrl}</Td>
<Td>
{blockNumber || error ? (
blockNumber ?? "Unavailable"
) : (
<Skeleton height="24px" />
)}
</Td>
<Td>
{latency || error ? (
<>{latency ?? "?"} ms</>
) : (
<Skeleton height="24px" />
)}
</Td>
<Td pr="0" textAlign="end">
{!isConnected ? (
<Button onClick={handleConnect}>Connect</Button>
) : (
<Button onClick={() => handleRpcClick(rpcUrl)}>
Add Chain
</Button>
)}
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</TableContainer>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/chain/{Chain.chainId}.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const ChainPage = ({ data }: { data: { chain: ChainData } }) => {
)}
</StatGroup>
<Divider my="8" />
<RpcTable rpcs={rpc} handleRpcClick={handleRpcClick} />
<RpcTable chainId={chainId} rpcs={rpc} handleRpcClick={handleRpcClick} />
</Flex>
</Layout>
</>
Expand Down

0 comments on commit 66bba61

Please sign in to comment.