explorer: Update instruction details cards to handle parsed instructions for system, stake, and bpf-loader (#13247)
* update instruction cards to support system, stake, and bpf-loader parsed instructions
This commit is contained in:
parent
db9ddc7e5b
commit
413dfb01d5
|
@ -0,0 +1,117 @@
|
|||
import React from "react";
|
||||
import {
|
||||
SignatureResult,
|
||||
ParsedInstruction,
|
||||
ParsedTransaction,
|
||||
BPF_LOADER_PROGRAM_ID,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { coerce } from "superstruct";
|
||||
import { ParsedInfo } from "validators";
|
||||
import { IX_STRUCTS } from "./types";
|
||||
import { reportError } from "utils/sentry";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
type DetailsProps = {
|
||||
tx: ParsedTransaction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
};
|
||||
|
||||
export function BpfLoaderDetailsCard(props: DetailsProps) {
|
||||
try {
|
||||
const parsed = coerce(props.ix.parsed, ParsedInfo);
|
||||
const info = coerce(parsed.info, IX_STRUCTS[parsed.type]);
|
||||
|
||||
switch (parsed.type) {
|
||||
case "write":
|
||||
return <BpfLoaderWriteDetailsCard info={info} {...props} />;
|
||||
case "finalize":
|
||||
return <BpfLoaderFinalizeDetailsCard info={info} {...props} />;
|
||||
default:
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
} catch (error) {
|
||||
reportError(error, {
|
||||
signature: props.tx.signatures[0],
|
||||
});
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
type Props = {
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
};
|
||||
|
||||
export function BpfLoaderWriteDetailsCard(props: Props) {
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
ix={ix}
|
||||
index={index}
|
||||
result={result}
|
||||
title="BPF Loader 2: Write"
|
||||
>
|
||||
<tr>
|
||||
<td>Program</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={BPF_LOADER_PROGRAM_ID} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Account</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
Bytes <span className="text-muted">(base 64)</span>
|
||||
</td>
|
||||
<td className="text-lg-right">
|
||||
<code className="d-inline-block">{info.bytes}</code>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Offset</td>
|
||||
<td className="text-lg-right">{info.offset}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
}
|
||||
|
||||
export function BpfLoaderFinalizeDetailsCard(props: Props) {
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
ix={ix}
|
||||
index={index}
|
||||
result={result}
|
||||
title="BPF Loader 2: Finalize"
|
||||
>
|
||||
<tr>
|
||||
<td>Program</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={BPF_LOADER_PROGRAM_ID} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Account</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* eslint-disable @typescript-eslint/no-redeclare */
|
||||
|
||||
import { enums, number, pick, string, StructType } from "superstruct";
|
||||
import { Pubkey } from "validators/pubkey";
|
||||
|
||||
const Write = pick({
|
||||
account: Pubkey,
|
||||
bytes: string(),
|
||||
offset: number(),
|
||||
});
|
||||
|
||||
const Finalize = pick({
|
||||
account: Pubkey,
|
||||
});
|
||||
|
||||
export type BpfLoaderInstructionType = StructType<
|
||||
typeof BpfLoaderInstructionType
|
||||
>;
|
||||
export const BpfLoaderInstructionType = enums(["write", "finalize"]);
|
||||
|
||||
export const IX_STRUCTS: { [id: string]: any } = {
|
||||
write: Write,
|
||||
finalize: Finalize,
|
||||
};
|
|
@ -1,40 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function AuthorizeDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeAuthorize(ix);
|
||||
} catch (err) {
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
|
||||
let authorizationType;
|
||||
switch (params.stakeAuthorizationType.index) {
|
||||
case 0:
|
||||
authorizationType = "Staker";
|
||||
break;
|
||||
case 1:
|
||||
authorizationType = "Withdrawer";
|
||||
break;
|
||||
default:
|
||||
authorizationType = "Invalid";
|
||||
break;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -53,27 +32,27 @@ export function AuthorizeDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Old Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.authority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>New Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.newAuthorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.newAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Type</td>
|
||||
<td className="text-lg-right">{authorizationType}</td>
|
||||
<td className="text-lg-right">{info.authorityType}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function DeactivateDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeDeactivate(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,14 +32,14 @@ export function DeactivateDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function DelegateDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeDelegate(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,21 +32,21 @@ export function DelegateDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Delegated Vote Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.votePubkey} alignRight link />
|
||||
<Address pubkey={info.voteAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
SystemProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function InitializeDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeInitialize(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,45 +33,45 @@ export function InitializeDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Stake Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorized.staker} alignRight link />
|
||||
<Address pubkey={info.authorized.staker} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Withdraw Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorized.withdrawer} alignRight link />
|
||||
<Address pubkey={info.authorized.withdrawer} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{params.lockup.epoch > 0 && (
|
||||
{info.lockup.epoch > 0 && (
|
||||
<tr>
|
||||
<td>Lockup Expiry Epoch</td>
|
||||
<td className="text-lg-right">{params.lockup.epoch}</td>
|
||||
<td className="text-lg-right">{info.lockup.epoch}</td>
|
||||
</tr>
|
||||
)}
|
||||
|
||||
{params.lockup.unixTimestamp > 0 && (
|
||||
{info.lockup.unixTimestamp > 0 && (
|
||||
<tr>
|
||||
<td>Lockup Expiry Timestamp</td>
|
||||
<td className="text-lg-right">
|
||||
{new Date(params.lockup.unixTimestamp * 1000).toUTCString()}
|
||||
{new Date(info.lockup.unixTimestamp * 1000).toUTCString()}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
||||
{!params.lockup.custodian.equals(SystemProgram.programId) && (
|
||||
{!info.lockup.custodian.equals(SystemProgram.programId) && (
|
||||
<tr>
|
||||
<td>Lockup Custodian Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.lockup.custodian} alignRight link />
|
||||
<Address pubkey={info.lockup.custodian} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function SplitDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeSplit(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard ix={ix} index={index} result={result} title="Split Stake">
|
||||
|
@ -37,29 +28,27 @@ export function SplitDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>New Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.splitStakePubkey} alignRight link />
|
||||
<Address pubkey={info.newSplitAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Split Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(params.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import {
|
||||
StakeInstruction,
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
ParsedTransaction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
|
@ -12,36 +12,43 @@ import { AuthorizeDetailsCard } from "./AuthorizeDetailsCard";
|
|||
import { SplitDetailsCard } from "./SplitDetailsCard";
|
||||
import { WithdrawDetailsCard } from "./WithdrawDetailsCard";
|
||||
import { DeactivateDetailsCard } from "./DeactivateDetailsCard";
|
||||
import { ParsedInfo } from "validators";
|
||||
import { reportError } from "utils/sentry";
|
||||
import { coerce } from "superstruct";
|
||||
import { IX_STRUCTS } from "./types";
|
||||
|
||||
type DetailsProps = {
|
||||
ix: TransactionInstruction;
|
||||
tx: ParsedTransaction;
|
||||
ix: ParsedInstruction;
|
||||
result: SignatureResult;
|
||||
index: number;
|
||||
};
|
||||
|
||||
export function StakeDetailsCard(props: DetailsProps) {
|
||||
let stakeInstructionType;
|
||||
try {
|
||||
stakeInstructionType = StakeInstruction.decodeInstructionType(props.ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
const parsed = coerce(props.ix.parsed, ParsedInfo);
|
||||
const info = coerce(parsed.info, IX_STRUCTS[parsed.type]);
|
||||
|
||||
switch (parsed.type) {
|
||||
case "initialize":
|
||||
return <InitializeDetailsCard info={info} {...props} />;
|
||||
case "delegate":
|
||||
return <DelegateDetailsCard info={info} {...props} />;
|
||||
case "authorize":
|
||||
return <AuthorizeDetailsCard info={info} {...props} />;
|
||||
case "split":
|
||||
return <SplitDetailsCard info={info} {...props} />;
|
||||
case "withdraw":
|
||||
return <WithdrawDetailsCard info={info} {...props} />;
|
||||
case "deactivate":
|
||||
return <DeactivateDetailsCard info={info} {...props} />;
|
||||
default:
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
} catch (error) {
|
||||
reportError(error, {
|
||||
signature: props.tx.signatures[0],
|
||||
});
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
|
||||
switch (stakeInstructionType) {
|
||||
case "Initialize":
|
||||
return <InitializeDetailsCard {...props} />;
|
||||
case "Delegate":
|
||||
return <DelegateDetailsCard {...props} />;
|
||||
case "Authorize":
|
||||
return <AuthorizeDetailsCard {...props} />;
|
||||
case "Split":
|
||||
return <SplitDetailsCard {...props} />;
|
||||
case "Withdraw":
|
||||
return <WithdrawDetailsCard {...props} />;
|
||||
case "Deactivate":
|
||||
return <DeactivateDetailsCard {...props} />;
|
||||
default:
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
StakeInstruction,
|
||||
StakeProgram,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function WithdrawDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = StakeInstruction.decodeWithdraw(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,29 +33,27 @@ export function WithdrawDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Stake Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.stakePubkey} alignRight link />
|
||||
<Address pubkey={info.stakeAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.withdrawAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>To Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.toPubkey} alignRight link />
|
||||
<Address pubkey={info.destination} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Withdraw Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(params.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* eslint-disable @typescript-eslint/no-redeclare */
|
||||
|
||||
import { enums, number, pick, string, StructType } from "superstruct";
|
||||
import { Pubkey } from "validators/pubkey";
|
||||
|
||||
const Initialize = pick({
|
||||
stakeAccount: Pubkey,
|
||||
authorized: pick({
|
||||
staker: Pubkey,
|
||||
withdrawer: Pubkey,
|
||||
}),
|
||||
lockup: pick({
|
||||
epoch: number(),
|
||||
unixTimestamp: number(),
|
||||
custodian: Pubkey,
|
||||
}),
|
||||
});
|
||||
|
||||
const Delegate = pick({
|
||||
stakeAccount: Pubkey,
|
||||
voteAccount: Pubkey,
|
||||
stakeAuthority: Pubkey,
|
||||
});
|
||||
|
||||
const Authorize = pick({
|
||||
authorityType: string(),
|
||||
stakeAccount: Pubkey,
|
||||
authority: Pubkey,
|
||||
newAuthority: Pubkey,
|
||||
});
|
||||
|
||||
const Split = pick({
|
||||
stakeAccount: Pubkey,
|
||||
stakeAuthority: Pubkey,
|
||||
newSplitAccount: Pubkey,
|
||||
lamports: number(),
|
||||
});
|
||||
|
||||
const Withdraw = pick({
|
||||
stakeAccount: Pubkey,
|
||||
withdrawAuthority: Pubkey,
|
||||
destination: Pubkey,
|
||||
lamports: number(),
|
||||
});
|
||||
|
||||
const Deactivate = pick({
|
||||
stakeAccount: Pubkey,
|
||||
stakeAuthority: Pubkey,
|
||||
});
|
||||
|
||||
export type StakeInstructionType = StructType<typeof StakeInstructionType>;
|
||||
export const StakeInstructionType = enums([
|
||||
"initialize",
|
||||
"delegate",
|
||||
"authorize",
|
||||
"split",
|
||||
"withdraw",
|
||||
"deactivate",
|
||||
]);
|
||||
|
||||
export const IX_STRUCTS: { [id: string]: any } = {
|
||||
initialize: Initialize,
|
||||
delegate: Delegate,
|
||||
authorize: Authorize,
|
||||
split: Split,
|
||||
withdraw: Withdraw,
|
||||
deactivate: Deactivate,
|
||||
};
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function AllocateDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeAllocate(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,13 +32,13 @@ export function AllocateDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Account Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.accountPubkey} alignRight link />
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Allocated Space (Bytes)</td>
|
||||
<td className="text-lg-right">{params.space}</td>
|
||||
<td className="text-lg-right">{info.space}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { Copyable } from "components/common/Copyable";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function AllocateWithSeedDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeAllocateWithSeed(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,35 +33,35 @@ export function AllocateWithSeedDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Account Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.accountPubkey} alignRight link />
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Base Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.basePubkey} alignRight link />
|
||||
<Address pubkey={info.base} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Seed</td>
|
||||
<td className="text-lg-right">
|
||||
<Copyable right text={params.seed}>
|
||||
<code>{params.seed}</code>
|
||||
<Copyable right text={info.seed}>
|
||||
<code>{info.seed}</code>
|
||||
</Copyable>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Allocated Space (Bytes)</td>
|
||||
<td className="text-lg-right">{params.space}</td>
|
||||
<td className="text-lg-right">{info.space}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Assigned Owner</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.programId} alignRight link />
|
||||
<Address pubkey={info.owner} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function AssignDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeAssign(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,14 +32,14 @@ export function AssignDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Account Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.accountPubkey} alignRight link />
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Assigned Owner</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.programId} alignRight link />
|
||||
<Address pubkey={info.owner} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { Copyable } from "components/common/Copyable";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function AssignWithSeedDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeAssignWithSeed(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,22 +33,22 @@ export function AssignWithSeedDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Account Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.accountPubkey} alignRight link />
|
||||
<Address pubkey={info.account} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Base Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.basePubkey} alignRight link />
|
||||
<Address pubkey={info.base} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Seed</td>
|
||||
<td className="text-lg-right">
|
||||
<Copyable right text={params.seed}>
|
||||
<code>{params.seed}</code>
|
||||
<Copyable right text={info.seed}>
|
||||
<code>{info.seed}</code>
|
||||
</Copyable>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -65,7 +56,7 @@ export function AssignWithSeedDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Assigned Owner</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.programId} alignRight link />
|
||||
<Address pubkey={info.owner} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function CreateDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeCreateAccount(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,33 +33,31 @@ export function CreateDetailsCard(props: {
|
|||
<tr>
|
||||
<td>From Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.fromPubkey} alignRight link />
|
||||
<Address pubkey={info.source} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>New Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.newAccountPubkey} alignRight link />
|
||||
<Address pubkey={info.newAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Transfer Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(params.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Allocated Space (Bytes)</td>
|
||||
<td className="text-lg-right">{params.space}</td>
|
||||
<td className="text-lg-right">{info.space}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Assigned Owner</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.programId} alignRight link />
|
||||
<Address pubkey={info.owner} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { Copyable } from "components/common/Copyable";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function CreateWithSeedDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeCreateWithSeed(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -43,49 +34,47 @@ export function CreateWithSeedDetailsCard(props: {
|
|||
<tr>
|
||||
<td>From Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.fromPubkey} alignRight link />
|
||||
<Address pubkey={info.source} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>New Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.newAccountPubkey} alignRight link />
|
||||
<Address pubkey={info.newAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Base Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.basePubkey} alignRight link />
|
||||
<Address pubkey={info.base} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Seed</td>
|
||||
<td className="text-lg-right">
|
||||
<Copyable right text={params.seed}>
|
||||
<code>{params.seed}</code>
|
||||
<Copyable right text={info.seed}>
|
||||
<code>{info.seed}</code>
|
||||
</Copyable>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Transfer Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(params.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Allocated Space (Bytes)</td>
|
||||
<td className="text-lg-right">{params.space}</td>
|
||||
<td className="text-lg-right">{info.space}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Assigned Owner</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.programId} alignRight link />
|
||||
<Address pubkey={info.owner} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function NonceAdvanceDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeNonceAdvance(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,14 +32,14 @@ export function NonceAdvanceDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Nonce Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.noncePubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function NonceAuthorizeDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeNonceAuthorize(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,21 +32,21 @@ export function NonceAuthorizeDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Nonce Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.noncePubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Old Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>New Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.newAuthorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.newAuthorized} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function NonceInitializeDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeNonceInitialize(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -41,14 +32,14 @@ export function NonceInitializeDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Nonce Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.noncePubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function NonceWithdrawDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let params;
|
||||
try {
|
||||
params = SystemInstruction.decodeNonceWithdraw(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard
|
||||
|
@ -42,29 +33,27 @@ export function NonceWithdrawDetailsCard(props: {
|
|||
<tr>
|
||||
<td>Nonce Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.noncePubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAccount} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Authority Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.authorizedPubkey} alignRight link />
|
||||
<Address pubkey={info.nonceAuthority} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>To Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={params.toPubkey} alignRight link />
|
||||
<Address pubkey={info.destination} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Withdraw Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(params.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import {
|
||||
SystemInstruction,
|
||||
TransactionInstruction,
|
||||
SignatureResult,
|
||||
ParsedInstruction,
|
||||
ParsedTransaction,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
|
@ -17,46 +17,53 @@ import { NonceInitializeDetailsCard } from "./NonceInitializeDetailsCard";
|
|||
import { NonceAdvanceDetailsCard } from "./NonceAdvanceDetailsCard";
|
||||
import { NonceWithdrawDetailsCard } from "./NonceWithdrawDetailsCard";
|
||||
import { NonceAuthorizeDetailsCard } from "./NonceAuthorizeDetailsCard";
|
||||
import { ParsedInfo } from "validators";
|
||||
import { coerce } from "superstruct";
|
||||
import { reportError } from "utils/sentry";
|
||||
import { IX_STRUCTS } from "./types";
|
||||
|
||||
type DetailsProps = {
|
||||
ix: TransactionInstruction;
|
||||
tx: ParsedTransaction;
|
||||
ix: ParsedInstruction;
|
||||
result: SignatureResult;
|
||||
index: number;
|
||||
};
|
||||
|
||||
export function SystemDetailsCard(props: DetailsProps) {
|
||||
let systemInstructionType;
|
||||
try {
|
||||
systemInstructionType = SystemInstruction.decodeInstructionType(props.ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
const parsed = coerce(props.ix.parsed, ParsedInfo);
|
||||
const info = coerce(parsed.info, IX_STRUCTS[parsed.type]);
|
||||
|
||||
switch (parsed.type) {
|
||||
case "createAccount":
|
||||
return <CreateDetailsCard info={info} {...props} />;
|
||||
case "createAccountWithSeed":
|
||||
return <CreateWithSeedDetailsCard info={info} {...props} />;
|
||||
case "allocate":
|
||||
return <AllocateDetailsCard info={info} {...props} />;
|
||||
case "allocateWithSeed":
|
||||
return <AllocateWithSeedDetailsCard info={info} {...props} />;
|
||||
case "assign":
|
||||
return <AssignDetailsCard info={info} {...props} />;
|
||||
case "assignWithSeed":
|
||||
return <AssignWithSeedDetailsCard info={info} {...props} />;
|
||||
case "transfer":
|
||||
return <TransferDetailsCard info={info} {...props} />;
|
||||
case "advanceNonceAccount":
|
||||
return <NonceAdvanceDetailsCard info={info} {...props} />;
|
||||
case "withdrawNonceAccount":
|
||||
return <NonceWithdrawDetailsCard info={info} {...props} />;
|
||||
case "authorizeNonceAccount":
|
||||
return <NonceAuthorizeDetailsCard info={info} {...props} />;
|
||||
case "initializeNonceAccount":
|
||||
return <NonceInitializeDetailsCard info={info} {...props} />;
|
||||
default:
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
} catch (error) {
|
||||
reportError(error, {
|
||||
signature: props.tx.signatures[0],
|
||||
});
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
|
||||
switch (systemInstructionType) {
|
||||
case "Create":
|
||||
return <CreateDetailsCard {...props} />;
|
||||
case "CreateWithSeed":
|
||||
return <CreateWithSeedDetailsCard {...props} />;
|
||||
case "Allocate":
|
||||
return <AllocateDetailsCard {...props} />;
|
||||
case "AllocateWithSeed":
|
||||
return <AllocateWithSeedDetailsCard {...props} />;
|
||||
case "Assign":
|
||||
return <AssignDetailsCard {...props} />;
|
||||
case "AssignWithSeed":
|
||||
return <AssignWithSeedDetailsCard {...props} />;
|
||||
case "Transfer":
|
||||
return <TransferDetailsCard {...props} />;
|
||||
case "AdvanceNonceAccount":
|
||||
return <NonceAdvanceDetailsCard {...props} />;
|
||||
case "WithdrawNonceAccount":
|
||||
return <NonceWithdrawDetailsCard {...props} />;
|
||||
case "AuthorizeNonceAccount":
|
||||
return <NonceAuthorizeDetailsCard {...props} />;
|
||||
case "InitializeNonceAccount":
|
||||
return <NonceInitializeDetailsCard {...props} />;
|
||||
default:
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
import React from "react";
|
||||
import {
|
||||
TransactionInstruction,
|
||||
SystemProgram,
|
||||
SignatureResult,
|
||||
SystemInstruction,
|
||||
ParsedInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { InstructionCard } from "../InstructionCard";
|
||||
import { UnknownDetailsCard } from "../UnknownDetailsCard";
|
||||
import { Address } from "components/common/Address";
|
||||
|
||||
export function TransferDetailsCard(props: {
|
||||
ix: TransactionInstruction;
|
||||
ix: ParsedInstruction;
|
||||
index: number;
|
||||
result: SignatureResult;
|
||||
info: any;
|
||||
}) {
|
||||
const { ix, index, result } = props;
|
||||
|
||||
let transfer;
|
||||
try {
|
||||
transfer = SystemInstruction.decodeTransfer(ix);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return <UnknownDetailsCard {...props} />;
|
||||
}
|
||||
const { ix, index, result, info } = props;
|
||||
|
||||
return (
|
||||
<InstructionCard ix={ix} index={index} result={result} title="Transfer">
|
||||
|
@ -37,22 +28,20 @@ export function TransferDetailsCard(props: {
|
|||
<tr>
|
||||
<td>From Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={transfer.fromPubkey} alignRight link />
|
||||
<Address pubkey={info.source} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>To Address</td>
|
||||
<td className="text-lg-right">
|
||||
<Address pubkey={transfer.toPubkey} alignRight link />
|
||||
<Address pubkey={info.destination} alignRight link />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Transfer Amount (SOL)</td>
|
||||
<td className="text-lg-right">
|
||||
{lamportsToSolString(transfer.lamports)}
|
||||
</td>
|
||||
<td className="text-lg-right">{lamportsToSolString(info.lamports)}</td>
|
||||
</tr>
|
||||
</InstructionCard>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* eslint-disable @typescript-eslint/no-redeclare */
|
||||
|
||||
import { enums, number, pick, string, StructType } from "superstruct";
|
||||
import { Pubkey } from "validators/pubkey";
|
||||
|
||||
const CreateAccount = pick({
|
||||
source: Pubkey,
|
||||
newAccount: Pubkey,
|
||||
lamports: number(),
|
||||
space: number(),
|
||||
owner: Pubkey,
|
||||
});
|
||||
|
||||
const Assign = pick({
|
||||
account: Pubkey,
|
||||
owner: Pubkey,
|
||||
});
|
||||
|
||||
const Transfer = pick({
|
||||
source: Pubkey,
|
||||
destination: Pubkey,
|
||||
lamports: number(),
|
||||
});
|
||||
|
||||
const CreateAccountWithSeed = pick({
|
||||
source: Pubkey,
|
||||
newAccount: Pubkey,
|
||||
base: Pubkey,
|
||||
seed: string(),
|
||||
lamports: number(),
|
||||
space: number(),
|
||||
owner: Pubkey,
|
||||
});
|
||||
|
||||
const AdvanceNonceAccount = pick({
|
||||
nonceAccount: Pubkey,
|
||||
nonceAuthority: Pubkey,
|
||||
});
|
||||
|
||||
const WithdrawNonceAccount = pick({
|
||||
nonceAccount: Pubkey,
|
||||
destination: Pubkey,
|
||||
nonceAuthority: Pubkey,
|
||||
lamports: number(),
|
||||
});
|
||||
|
||||
const InitializeNonceAccount = pick({
|
||||
nonceAccount: Pubkey,
|
||||
nonceAuthority: Pubkey,
|
||||
});
|
||||
|
||||
const AuthorizeNonceAccount = pick({
|
||||
nonceAccount: Pubkey,
|
||||
nonceAuthority: Pubkey,
|
||||
newAuthorized: Pubkey,
|
||||
});
|
||||
|
||||
const Allocate = pick({
|
||||
account: Pubkey,
|
||||
space: number(),
|
||||
});
|
||||
|
||||
const AllocateWithSeed = pick({
|
||||
account: Pubkey,
|
||||
base: Pubkey,
|
||||
seed: string(),
|
||||
space: number(),
|
||||
owner: Pubkey,
|
||||
});
|
||||
|
||||
const AssignWithSeed = pick({
|
||||
account: Pubkey,
|
||||
base: Pubkey,
|
||||
seed: string(),
|
||||
owner: Pubkey,
|
||||
});
|
||||
|
||||
const TransferWithSeed = pick({
|
||||
source: Pubkey,
|
||||
sourceBase: Pubkey,
|
||||
destination: Pubkey,
|
||||
lamports: number(),
|
||||
sourceSeed: string(),
|
||||
sourceOwner: Pubkey,
|
||||
});
|
||||
|
||||
export type SystemInstructionType = StructType<typeof SystemInstructionType>;
|
||||
export const SystemInstructionType = enums([
|
||||
"createAccount",
|
||||
"createAccountWithSeed",
|
||||
"allocate",
|
||||
"allocateWithSeed",
|
||||
"assign",
|
||||
"assignWithSeed",
|
||||
"transfer",
|
||||
"advanceNonceAccount",
|
||||
"withdrawNonceAccount",
|
||||
"authorizeNonceAccount",
|
||||
"initializeNonceAccount",
|
||||
]);
|
||||
|
||||
export const IX_STRUCTS: { [id: string]: any } = {
|
||||
createAccount: CreateAccount,
|
||||
createAccountWithSeed: CreateAccountWithSeed,
|
||||
allocate: Allocate,
|
||||
allocateWithSeed: AllocateWithSeed,
|
||||
assign: Assign,
|
||||
assignWithSeed: AssignWithSeed,
|
||||
transfer: Transfer,
|
||||
advanceNonceAccount: AdvanceNonceAccount,
|
||||
withdrawNonceAccount: WithdrawNonceAccount,
|
||||
authorizeNonceAccount: AuthorizeNonceAccount,
|
||||
initializeNonceAccount: InitializeNonceAccount,
|
||||
transferWithSeed: TransferWithSeed, // TODO: Add support for transfer with seed
|
||||
};
|
|
@ -10,13 +10,13 @@ import { useCluster, ClusterStatus } from "providers/cluster";
|
|||
import {
|
||||
TransactionSignature,
|
||||
SystemProgram,
|
||||
StakeProgram,
|
||||
SystemInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { lamportsToSolString } from "utils";
|
||||
import { UnknownDetailsCard } from "components/instruction/UnknownDetailsCard";
|
||||
import { SystemDetailsCard } from "components/instruction/system/SystemDetailsCard";
|
||||
import { StakeDetailsCard } from "components/instruction/stake/StakeDetailsCard";
|
||||
import { BpfLoaderDetailsCard } from "components/instruction/bpf-loader/BpfLoaderDetailsCard";
|
||||
import { ErrorCard } from "components/common/ErrorCard";
|
||||
import { LoadingCard } from "components/common/LoadingCard";
|
||||
import { TableCardBody } from "components/common/TableCardBody";
|
||||
|
@ -405,23 +405,55 @@ function InstructionsSection({ signature }: SignatureProps) {
|
|||
const instructionDetails = transaction.message.instructions.map(
|
||||
(next, index) => {
|
||||
if ("parsed" in next) {
|
||||
if (next.program === "spl-token") {
|
||||
return (
|
||||
<TokenDetailsCard
|
||||
key={index}
|
||||
tx={transaction}
|
||||
ix={next}
|
||||
result={result}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
switch (next.program) {
|
||||
case "spl-token":
|
||||
return (
|
||||
<TokenDetailsCard
|
||||
key={index}
|
||||
tx={transaction}
|
||||
ix={next}
|
||||
result={result}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
case "bpf-loader":
|
||||
return (
|
||||
<BpfLoaderDetailsCard
|
||||
key={index}
|
||||
tx={transaction}
|
||||
ix={next}
|
||||
result={result}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
case "system":
|
||||
return (
|
||||
<SystemDetailsCard
|
||||
key={index}
|
||||
tx={transaction}
|
||||
ix={next}
|
||||
result={result}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
case "stake":
|
||||
return (
|
||||
<StakeDetailsCard
|
||||
key={index}
|
||||
tx={transaction}
|
||||
ix={next}
|
||||
result={result}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
const props = { ix: next, result, index };
|
||||
return <UnknownDetailsCard key={index} {...props} />;
|
||||
}
|
||||
|
||||
const props = { ix: next, result, index };
|
||||
return <UnknownDetailsCard key={index} {...props} />;
|
||||
}
|
||||
|
||||
const ix = intoTransactionInstruction(transaction, index);
|
||||
|
||||
if (!ix) {
|
||||
return (
|
||||
<ErrorCard
|
||||
|
@ -432,11 +464,8 @@ function InstructionsSection({ signature }: SignatureProps) {
|
|||
}
|
||||
|
||||
const props = { ix, result, index, signature };
|
||||
if (SystemProgram.programId.equals(ix.programId)) {
|
||||
return <SystemDetailsCard key={index} {...props} />;
|
||||
} else if (StakeProgram.programId.equals(ix.programId)) {
|
||||
return <StakeDetailsCard key={index} {...props} />;
|
||||
} else if (isSerumInstruction(ix)) {
|
||||
|
||||
if (isSerumInstruction(ix)) {
|
||||
return <SerumDetailsCard key={index} {...props} />;
|
||||
} else {
|
||||
return <UnknownDetailsCard key={index} {...props} />;
|
||||
|
|
Loading…
Reference in New Issue