feat(explorer): load and display transaction details when commitment is confirmed (#20053)
* feat(explorer): load and display transaction details when commitment is confirmed * feat: rename DetailsCard to DetailsSection * fix: prevent details from showing when transaction unavailable
This commit is contained in:
parent
0bd3ae063e
commit
5c35ab619d
|
@ -105,10 +105,7 @@ export function TransactionDetailsPage({ signature: raw }: SignatureProps) {
|
||||||
) : (
|
) : (
|
||||||
<SignatureContext.Provider value={signature}>
|
<SignatureContext.Provider value={signature}>
|
||||||
<StatusCard signature={signature} autoRefresh={autoRefresh} />
|
<StatusCard signature={signature} autoRefresh={autoRefresh} />
|
||||||
<AccountsCard signature={signature} autoRefresh={autoRefresh} />
|
<DetailsSection signature={signature} />
|
||||||
<TokenBalancesCard signature={signature} />
|
|
||||||
<InstructionsSection signature={signature} />
|
|
||||||
<ProgramLogSection signature={signature} />
|
|
||||||
</SignatureContext.Provider>
|
</SignatureContext.Provider>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -307,40 +304,29 @@ function StatusCard({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountsCard({
|
function DetailsSection({ signature }: SignatureProps) {
|
||||||
signature,
|
|
||||||
autoRefresh,
|
|
||||||
}: SignatureProps & AutoRefreshProps) {
|
|
||||||
const details = useTransactionDetails(signature);
|
const details = useTransactionDetails(signature);
|
||||||
const fetchDetails = useFetchTransactionDetails();
|
const fetchDetails = useFetchTransactionDetails();
|
||||||
const fetchStatus = useFetchTransactionStatus();
|
const status = useTransactionStatus(signature);
|
||||||
const refreshDetails = () => fetchDetails(signature);
|
|
||||||
const refreshStatus = () => fetchStatus(signature);
|
|
||||||
const transaction = details?.data?.transaction?.transaction;
|
const transaction = details?.data?.transaction?.transaction;
|
||||||
const message = transaction?.message;
|
const message = transaction?.message;
|
||||||
const status = useTransactionStatus(signature);
|
const { status: clusterStatus } = useCluster();
|
||||||
|
const refreshDetails = () => fetchDetails(signature);
|
||||||
|
|
||||||
// Fetch details on load
|
// Fetch details on load
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (status?.data?.info?.confirmations === "max" && !details) {
|
if (
|
||||||
|
!details &&
|
||||||
|
clusterStatus === ClusterStatus.Connected &&
|
||||||
|
status?.status === FetchStatus.Fetched
|
||||||
|
) {
|
||||||
fetchDetails(signature);
|
fetchDetails(signature);
|
||||||
}
|
}
|
||||||
}, [signature, details, status, fetchDetails]);
|
}, [signature, clusterStatus, status]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
if (!status?.data?.info) {
|
if (!status?.data?.info) {
|
||||||
return null;
|
return null;
|
||||||
} else if (autoRefresh === AutoRefresh.BailedOut) {
|
} else if (!details) {
|
||||||
return (
|
|
||||||
<ErrorCard
|
|
||||||
text="Details are not available until the transaction reaches MAX confirmations"
|
|
||||||
retry={refreshStatus}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else if (autoRefresh === AutoRefresh.Active) {
|
|
||||||
return (
|
|
||||||
<ErrorCard text="Details are not available until the transaction reaches MAX confirmations" />
|
|
||||||
);
|
|
||||||
} else if (!details || details.status === FetchStatus.Fetching) {
|
|
||||||
return <LoadingCard />;
|
return <LoadingCard />;
|
||||||
} else if (details.status === FetchStatus.FetchFailed) {
|
} else if (details.status === FetchStatus.FetchFailed) {
|
||||||
return <ErrorCard retry={refreshDetails} text="Failed to fetch details" />;
|
return <ErrorCard retry={refreshDetails} text="Failed to fetch details" />;
|
||||||
|
@ -348,7 +334,26 @@ function AccountsCard({
|
||||||
return <ErrorCard text="Details are not available" />;
|
return <ErrorCard text="Details are not available" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { meta } = details.data.transaction;
|
return (
|
||||||
|
<>
|
||||||
|
<AccountsCard signature={signature} />
|
||||||
|
<TokenBalancesCard signature={signature} />
|
||||||
|
<InstructionsSection signature={signature} />
|
||||||
|
<ProgramLogSection signature={signature} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AccountsCard({ signature }: SignatureProps) {
|
||||||
|
const details = useTransactionDetails(signature);
|
||||||
|
|
||||||
|
if (!details?.data?.transaction) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { meta, transaction } = details.data.transaction;
|
||||||
|
const { message } = transaction;
|
||||||
|
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
return <ErrorCard text="Transaction metadata is missing" />;
|
return <ErrorCard text="Transaction metadata is missing" />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,8 @@ async function fetchDetails(
|
||||||
let transaction;
|
let transaction;
|
||||||
try {
|
try {
|
||||||
transaction = await new Connection(url).getParsedConfirmedTransaction(
|
transaction = await new Connection(url).getParsedConfirmedTransaction(
|
||||||
signature
|
signature,
|
||||||
|
"confirmed"
|
||||||
);
|
);
|
||||||
fetchStatus = FetchStatus.Fetched;
|
fetchStatus = FetchStatus.Fetched;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
Loading…
Reference in New Issue