explorer: Pretty print instruction data hex strings (#19813)
This commit is contained in:
parent
d9674f7ff0
commit
ab152f1319
|
@ -0,0 +1,44 @@
|
|||
import React, { ReactNode } from "react";
|
||||
import { Buffer } from "buffer";
|
||||
import { Copyable } from "./Copyable";
|
||||
|
||||
export function HexData({ raw }: { raw: Buffer }) {
|
||||
if (!raw) {
|
||||
return <span>No data</span>;
|
||||
}
|
||||
|
||||
const chunks = [];
|
||||
const hexString = raw.toString("hex");
|
||||
for (let i = 0; i < hexString.length; i += 2) {
|
||||
chunks.push(hexString.slice(i, i + 2));
|
||||
}
|
||||
|
||||
const spans: ReactNode[] = [];
|
||||
for (let i = 0; i < chunks.length; i += 4) {
|
||||
const color = i % 8 === 0 ? "text-white" : "text-gray-500";
|
||||
spans.push(
|
||||
<span key={i} className={color}>
|
||||
{chunks.slice(i, i + 4).join(" ")} 
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function Content() {
|
||||
return (
|
||||
<Copyable text={hexString}>
|
||||
<pre className="d-inline-block text-left mb-0 data-wrap">{spans}</pre>
|
||||
</Copyable>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="d-none d-lg-flex align-items-center justify-content-end">
|
||||
<Content />
|
||||
</div>
|
||||
<div className="d-flex d-lg-none align-items-center">
|
||||
<Content />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import React from "react";
|
||||
import { TransactionInstruction } from "@solana/web3.js";
|
||||
import { Address } from "components/common/Address";
|
||||
import { HexData } from "components/common/HexData";
|
||||
|
||||
export function RawDetails({ ix }: { ix: TransactionInstruction }) {
|
||||
const data = ix.data.toString("hex");
|
||||
return (
|
||||
<>
|
||||
{ix.keys.map(({ pubkey, isSigner, isWritable }, keyIndex) => (
|
||||
|
@ -28,7 +28,7 @@ export function RawDetails({ ix }: { ix: TransactionInstruction }) {
|
|||
Instruction Data <span className="text-muted">(Hex)</span>
|
||||
</td>
|
||||
<td className="text-lg-right">
|
||||
<pre className="d-inline-block text-left mb-0 data-wrap">{data}</pre>
|
||||
<HexData raw={ix.data} />
|
||||
</td>
|
||||
</tr>
|
||||
</>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { TableCardBody } from "components/common/TableCardBody";
|
|||
import { AddressWithContext, programValidator } from "./AddressWithContext";
|
||||
import { useCluster } from "providers/cluster";
|
||||
import { programLabel } from "utils/tx";
|
||||
import { HexData } from "components/common/HexData";
|
||||
|
||||
export function InstructionsSection({ message }: { message: Message }) {
|
||||
return (
|
||||
|
@ -30,19 +31,6 @@ function InstructionCard({
|
|||
const programId = message.accountKeys[ix.programIdIndex];
|
||||
const programName = programLabel(programId.toBase58(), cluster) || "Unknown";
|
||||
|
||||
let data: string = "No data";
|
||||
if (ix.data) {
|
||||
data = "";
|
||||
|
||||
const chunks = [];
|
||||
const hexString = bs58.decode(ix.data).toString("hex");
|
||||
for (let i = 0; i < hexString.length; i += 2) {
|
||||
chunks.push(hexString.slice(i, i + 2));
|
||||
}
|
||||
|
||||
data = chunks.join(" ");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="card" id={`instruction-index-${index + 1}`} key={index}>
|
||||
<div className={`card-header${!expanded ? " border-bottom-none" : ""}`}>
|
||||
|
@ -104,9 +92,7 @@ function InstructionCard({
|
|||
Instruction Data <span className="text-muted">(Hex)</span>
|
||||
</td>
|
||||
<td className="text-lg-right">
|
||||
<pre className="d-inline-block text-left mb-0 data-wrap">
|
||||
{data}
|
||||
</pre>
|
||||
<HexData raw={bs58.decode(ix.data)} />
|
||||
</td>
|
||||
</tr>
|
||||
</TableCardBody>
|
||||
|
|
|
@ -350,7 +350,7 @@ div.inner-cards {
|
|||
|
||||
pre.data-wrap,
|
||||
pre.json-wrap {
|
||||
max-width: 23rem;
|
||||
max-width: 22rem;
|
||||
white-space: pre-wrap;
|
||||
white-space: -moz-pre-wrap;
|
||||
white-space: -pre-wrap;
|
||||
|
|
Loading…
Reference in New Issue