2021-03-13 09:11:59 -08:00
|
|
|
import React from "react";
|
|
|
|
import { TableCardBody } from "components/common/TableCardBody";
|
2021-06-21 16:53:06 -07:00
|
|
|
import { SolBalance } from "utils";
|
2021-03-13 09:11:59 -08:00
|
|
|
import { Account, useFetchAccountInfo } from "providers/accounts";
|
|
|
|
import { Address } from "components/common/Address";
|
|
|
|
import {
|
|
|
|
ProgramAccountInfo,
|
|
|
|
ProgramBufferAccountInfo,
|
|
|
|
ProgramDataAccountInfo,
|
|
|
|
UpgradeableLoaderAccount,
|
|
|
|
} from "validators/accounts/upgradeable-program";
|
|
|
|
import { Slot } from "components/common/Slot";
|
|
|
|
import { addressLabel } from "utils/tx";
|
|
|
|
import { useCluster } from "providers/cluster";
|
|
|
|
import { ErrorCard } from "components/common/ErrorCard";
|
2021-08-17 12:07:10 -07:00
|
|
|
import { UnknownAccountCard } from "components/account/UnknownAccountCard";
|
2022-01-16 04:46:02 -08:00
|
|
|
import { Downloadable } from "components/common/Downloadable";
|
2021-03-13 09:11:59 -08:00
|
|
|
|
|
|
|
export function UpgradeableLoaderAccountSection({
|
|
|
|
account,
|
|
|
|
parsedData,
|
|
|
|
programData,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
parsedData: UpgradeableLoaderAccount;
|
|
|
|
programData: ProgramDataAccountInfo | undefined;
|
|
|
|
}) {
|
|
|
|
switch (parsedData.type) {
|
|
|
|
case "program": {
|
|
|
|
if (programData === undefined) {
|
|
|
|
return <ErrorCard text="Invalid Upgradeable Program account" />;
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<UpgradeableProgramSection
|
|
|
|
account={account}
|
|
|
|
programAccount={parsedData.info}
|
|
|
|
programData={programData}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "programData": {
|
|
|
|
return (
|
|
|
|
<UpgradeableProgramDataSection
|
|
|
|
account={account}
|
|
|
|
programData={parsedData.info}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
case "buffer": {
|
|
|
|
return (
|
|
|
|
<UpgradeableProgramBufferSection
|
|
|
|
account={account}
|
|
|
|
programBuffer={parsedData.info}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2021-08-17 12:07:10 -07:00
|
|
|
case "uninitialized": {
|
|
|
|
return <UnknownAccountCard account={account} />;
|
|
|
|
}
|
2021-03-13 09:11:59 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function UpgradeableProgramSection({
|
|
|
|
account,
|
|
|
|
programAccount,
|
|
|
|
programData,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
programAccount: ProgramAccountInfo;
|
|
|
|
programData: ProgramDataAccountInfo;
|
|
|
|
}) {
|
|
|
|
const refresh = useFetchAccountInfo();
|
|
|
|
const { cluster } = useCluster();
|
|
|
|
const label = addressLabel(account.pubkey.toBase58(), cluster);
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Program Account
|
|
|
|
</h3>
|
|
|
|
<button
|
|
|
|
className="btn btn-white btn-sm"
|
|
|
|
onClick={() => refresh(account.pubkey)}
|
|
|
|
>
|
2021-11-28 12:49:22 -08:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2021-03-13 09:11:59 -08:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{label && (
|
|
|
|
<tr>
|
|
|
|
<td>Address Label</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">{label}</td>
|
2021-03-13 09:11:59 -08:00
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
<tr>
|
|
|
|
<td>Balance (SOL)</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end text-uppercase">
|
2021-06-21 16:53:06 -07:00
|
|
|
<SolBalance lamports={account.lamports || 0} />
|
2021-03-13 09:11:59 -08:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Executable</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">Yes</td>
|
2021-03-13 09:11:59 -08:00
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Executable Data</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={programAccount.programData} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Upgradeable</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
{programData.authority !== null ? "Yes" : "No"}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Last Deployed Slot</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Slot slot={programData.slot} link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{programData.authority !== null && (
|
|
|
|
<tr>
|
|
|
|
<td>Upgrade Authority</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={programData.authority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function UpgradeableProgramDataSection({
|
|
|
|
account,
|
|
|
|
programData,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
programData: ProgramDataAccountInfo;
|
|
|
|
}) {
|
|
|
|
const refresh = useFetchAccountInfo();
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Program Executable Data Account
|
|
|
|
</h3>
|
|
|
|
<button
|
|
|
|
className="btn btn-white btn-sm"
|
|
|
|
onClick={() => refresh(account.pubkey)}
|
|
|
|
>
|
2021-11-28 12:49:22 -08:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2021-03-13 09:11:59 -08:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Balance (SOL)</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end text-uppercase">
|
2021-06-21 16:53:06 -07:00
|
|
|
<SolBalance lamports={account.lamports || 0} />
|
2021-03-13 09:11:59 -08:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{account.details?.space !== undefined && (
|
|
|
|
<tr>
|
|
|
|
<td>Data (Bytes)</td>
|
2022-01-16 04:46:02 -08:00
|
|
|
<td className="text-lg-end">
|
|
|
|
<Downloadable
|
|
|
|
data={programData.data[0]}
|
|
|
|
filename={`${account.pubkey.toString()}.bin`}
|
|
|
|
>
|
|
|
|
<span className="me-2">{account.details.space}</span>
|
|
|
|
</Downloadable>
|
|
|
|
</td>
|
2021-03-13 09:11:59 -08:00
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
<tr>
|
|
|
|
<td>Upgradeable</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
{programData.authority !== null ? "Yes" : "No"}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Last Deployed Slot</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Slot slot={programData.slot} link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{programData.authority !== null && (
|
|
|
|
<tr>
|
|
|
|
<td>Upgrade Authority</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={programData.authority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function UpgradeableProgramBufferSection({
|
|
|
|
account,
|
|
|
|
programBuffer,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
programBuffer: ProgramBufferAccountInfo;
|
|
|
|
}) {
|
|
|
|
const refresh = useFetchAccountInfo();
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Program Deploy Buffer Account
|
|
|
|
</h3>
|
|
|
|
<button
|
|
|
|
className="btn btn-white btn-sm"
|
|
|
|
onClick={() => refresh(account.pubkey)}
|
|
|
|
>
|
2021-11-28 12:49:22 -08:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2021-03-13 09:11:59 -08:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Balance (SOL)</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end text-uppercase">
|
2021-06-21 16:53:06 -07:00
|
|
|
<SolBalance lamports={account.lamports || 0} />
|
2021-03-13 09:11:59 -08:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
{account.details?.space !== undefined && (
|
|
|
|
<tr>
|
|
|
|
<td>Data (Bytes)</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">{account.details.space}</td>
|
2021-03-13 09:11:59 -08:00
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{programBuffer.authority !== null && (
|
|
|
|
<tr>
|
|
|
|
<td>Deploy Authority</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={programBuffer.authority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{account.details && (
|
|
|
|
<tr>
|
|
|
|
<td>Owner</td>
|
2021-11-28 12:49:22 -08:00
|
|
|
<td className="text-lg-end">
|
2021-03-13 09:11:59 -08:00
|
|
|
<Address pubkey={account.details.owner} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|