diff --git a/explorer/src/components/account/UpgradeableProgramSection.tsx b/explorer/src/components/account/UpgradeableProgramSection.tsx new file mode 100644 index 0000000000..df2858e9a6 --- /dev/null +++ b/explorer/src/components/account/UpgradeableProgramSection.tsx @@ -0,0 +1,83 @@ +import React from "react"; +import { TableCardBody } from "components/common/TableCardBody"; +import { lamportsToSolString } from "utils"; +import { Account, useFetchAccountInfo } from "providers/accounts"; +import { Address } from "components/common/Address"; +import { + ProgramAccountInfo, + ProgramDataAccountInfo, +} from "validators/accounts/upgradeable-program"; +import { Slot } from "components/common/Slot"; + +export function UpgradeableProgramSection({ + account, + programAccount, + programData, +}: { + account: Account; + programAccount: ProgramAccountInfo; + programData: ProgramDataAccountInfo; +}) { + const refresh = useFetchAccountInfo(); + return ( +
+
+

+ Program Account +

+ +
+ + + + Address + +
+ + + + Balance (SOL) + + {lamportsToSolString(account.lamports || 0)} + + + + Executable + Yes + + + Executable Data + +
+ + + + Upgradeable + + {programData.authority !== null ? "Yes" : "No"} + + + + Last Deployed Slot + + + + + {programData.authority !== null && ( + + Upgrade Authority + +
+ + + )} + +
+ ); +} diff --git a/explorer/src/pages/AccountDetailsPage.tsx b/explorer/src/pages/AccountDetailsPage.tsx index b9b0ae77ce..d21dc312d9 100644 --- a/explorer/src/pages/AccountDetailsPage.tsx +++ b/explorer/src/pages/AccountDetailsPage.tsx @@ -29,6 +29,7 @@ import { StakeHistoryCard } from "components/account/StakeHistoryCard"; import { BlockhashesCard } from "components/account/BlockhashesCard"; import { ConfigAccountSection } from "components/account/ConfigAccountSection"; import { useFlaggedAccounts } from "providers/accounts/flagged-accounts"; +import { UpgradeableProgramSection } from "components/account/UpgradeableProgramSection"; const TABS_LOOKUP: { [id: string]: Tab } = { "spl-token:mint": { @@ -174,7 +175,15 @@ function DetailsSections({ pubkey, tab }: { pubkey: PublicKey; tab?: string }) { function InfoSection({ account }: { account: Account }) { const data = account?.details?.data; - if (data && data.program === "stake") { + if (data && data.program === "bpf-upgradeable-loader") { + return ( + + ); + } else if (data && data.program === "stake") { return ( ; +export const ProgramAccountInfo = pick({ + programData: Pubkey, +}); + +export type ProgramAccount = StructType; +export const ProgramAccount = pick({ + type: literal("program"), + info: ProgramAccountInfo, +}); + +export type ProgramDataAccountInfo = StructType; +export const ProgramDataAccountInfo = pick({ + authority: nullable(Pubkey), + // don't care about data yet + slot: number(), +}); + +export type ProgramDataAccount = StructType; +export const ProgramDataAccount = pick({ + type: literal("programData"), + info: ProgramDataAccountInfo, +});