import React from "react"; import { useClusterModal } from "providers/cluster"; import { PublicKey, StakeProgram } from "@solana/web3.js"; import ClusterStatusButton from "components/ClusterStatusButton"; import { useHistory, useLocation } from "react-router-dom"; import { Status, useFetchAccountInfo, useFetchAccountHistory, useAccountInfo, Account } from "providers/accounts"; import { lamportsToSolString } from "utils"; import Copyable from "./Copyable"; import { displayAddress } from "utils/tx"; import { StakeAccountCards } from "components/account/StakeAccountCards"; import ErrorCard from "components/common/ErrorCard"; import LoadingCard from "components/common/LoadingCard"; import TableCardBody from "components/common/TableCardBody"; type Props = { address: string }; export default function AccountDetails({ address }: Props) { const fetchAccount = useFetchAccountInfo(); const [, setShow] = useClusterModal(); const [search, setSearch] = React.useState(address); const history = useHistory(); const location = useLocation(); let pubkey: PublicKey | undefined; try { pubkey = new PublicKey(address); } catch (err) { console.error(err); // TODO handle bad addresses } const updateAddress = () => { history.push({ ...location, pathname: "/account/" + search }); }; // Fetch account on load React.useEffect(() => { if (pubkey) fetchAccount(pubkey); }, [pubkey?.toBase58()]); // eslint-disable-line react-hooks/exhaustive-deps const searchInput = ( setSearch(e.target.value)} onKeyUp={e => e.key === "Enter" && updateAddress()} className="form-control form-control-prepended search text-monospace" placeholder="Search for address" /> ); return (
Details

Account

setShow(true)} />
{searchInput}
{searchInput}
{pubkey && } {pubkey && }
); } function AccountCards({ pubkey }: { pubkey: PublicKey }) { const address = pubkey.toBase58(); const info = useAccountInfo(address); const refresh = useFetchAccountInfo(); if (!info || info.status === Status.Checking) { return ; } else if ( info.status === Status.CheckFailed || info.lamports === undefined ) { return refresh(pubkey)} text="Fetch Failed" />; } const owner = info.details?.owner; const data = info.details?.data; if (data && owner && owner.equals(StakeProgram.programId)) { return ; } else { return ; } } function UnknownAccountCard({ account }: { account: Account }) { const refresh = useFetchAccountInfo(); const { details, lamports, pubkey } = account; if (lamports === undefined) return null; return (

Account Overview

Balance (SOL) {lamportsToSolString(lamports)} {details && ( Data (Bytes) {details.space} )} {details && ( Owner {displayAddress(details.owner.toBase58())} )} {details && ( Executable {details.executable ? "Yes" : "No"} )}
); } function HistoryCard({ pubkey }: { pubkey: PublicKey }) { const address = pubkey.toBase58(); const info = useAccountInfo(address); const refresh = useFetchAccountHistory(); if (!info || !info.details) { return null; } else if (info.status === Status.FetchingHistory) { return ; } else if (info.history === undefined) { return ( refresh(pubkey)} text="Failed to fetch transaction history" /> ); } if (info.history.size === 0) { return ( refresh(pubkey)} text="No recent transaction history found" /> ); } const detailsList: React.ReactNode[] = []; info.history.forEach((slotTransactions, slot) => { const signatures = Array.from(slotTransactions.entries()).map( ([signature, err]) => { return {signature}; } ); detailsList.push( Slot {slot}
{signatures}
); }); return (

Transaction History

{detailsList}
); }