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 React from "react";
|
||||||
import { TransactionInstruction } from "@solana/web3.js";
|
import { TransactionInstruction } from "@solana/web3.js";
|
||||||
import { Address } from "components/common/Address";
|
import { Address } from "components/common/Address";
|
||||||
|
import { HexData } from "components/common/HexData";
|
||||||
|
|
||||||
export function RawDetails({ ix }: { ix: TransactionInstruction }) {
|
export function RawDetails({ ix }: { ix: TransactionInstruction }) {
|
||||||
const data = ix.data.toString("hex");
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ix.keys.map(({ pubkey, isSigner, isWritable }, keyIndex) => (
|
{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>
|
Instruction Data <span className="text-muted">(Hex)</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-lg-right">
|
<td className="text-lg-right">
|
||||||
<pre className="d-inline-block text-left mb-0 data-wrap">{data}</pre>
|
<HexData raw={ix.data} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { TableCardBody } from "components/common/TableCardBody";
|
||||||
import { AddressWithContext, programValidator } from "./AddressWithContext";
|
import { AddressWithContext, programValidator } from "./AddressWithContext";
|
||||||
import { useCluster } from "providers/cluster";
|
import { useCluster } from "providers/cluster";
|
||||||
import { programLabel } from "utils/tx";
|
import { programLabel } from "utils/tx";
|
||||||
|
import { HexData } from "components/common/HexData";
|
||||||
|
|
||||||
export function InstructionsSection({ message }: { message: Message }) {
|
export function InstructionsSection({ message }: { message: Message }) {
|
||||||
return (
|
return (
|
||||||
|
@ -30,19 +31,6 @@ function InstructionCard({
|
||||||
const programId = message.accountKeys[ix.programIdIndex];
|
const programId = message.accountKeys[ix.programIdIndex];
|
||||||
const programName = programLabel(programId.toBase58(), cluster) || "Unknown";
|
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 (
|
return (
|
||||||
<div className="card" id={`instruction-index-${index + 1}`} key={index}>
|
<div className="card" id={`instruction-index-${index + 1}`} key={index}>
|
||||||
<div className={`card-header${!expanded ? " border-bottom-none" : ""}`}>
|
<div className={`card-header${!expanded ? " border-bottom-none" : ""}`}>
|
||||||
|
@ -104,9 +92,7 @@ function InstructionCard({
|
||||||
Instruction Data <span className="text-muted">(Hex)</span>
|
Instruction Data <span className="text-muted">(Hex)</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-lg-right">
|
<td className="text-lg-right">
|
||||||
<pre className="d-inline-block text-left mb-0 data-wrap">
|
<HexData raw={bs58.decode(ix.data)} />
|
||||||
{data}
|
|
||||||
</pre>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</TableCardBody>
|
</TableCardBody>
|
||||||
|
|
|
@ -350,7 +350,7 @@ div.inner-cards {
|
||||||
|
|
||||||
pre.data-wrap,
|
pre.data-wrap,
|
||||||
pre.json-wrap {
|
pre.json-wrap {
|
||||||
max-width: 23rem;
|
max-width: 22rem;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
white-space: -moz-pre-wrap;
|
white-space: -moz-pre-wrap;
|
||||||
white-space: -pre-wrap;
|
white-space: -pre-wrap;
|
||||||
|
|
Loading…
Reference in New Issue