Explorer: use explicit types for instruction info (#13257)

This commit is contained in:
Justin Starry 2020-10-29 23:46:36 +08:00 committed by GitHub
parent 0d233370e8
commit 636ae12621
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 168 additions and 96 deletions

View File

@ -8,7 +8,7 @@ import {
import { InstructionCard } from "../InstructionCard";
import { coerce } from "superstruct";
import { ParsedInfo } from "validators";
import { IX_STRUCTS } from "./types";
import { WriteInfo, FinalizeInfo } from "./types";
import { reportError } from "utils/sentry";
import { UnknownDetailsCard } from "../UnknownDetailsCard";
import { Address } from "components/common/Address";
@ -24,13 +24,16 @@ type DetailsProps = {
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":
case "write": {
const info = coerce(parsed.info, WriteInfo);
return <BpfLoaderWriteDetailsCard info={info} {...props} />;
case "finalize":
}
case "finalize": {
const info = coerce(parsed.info, FinalizeInfo);
return <BpfLoaderFinalizeDetailsCard info={info} {...props} />;
}
default:
return <UnknownDetailsCard {...props} />;
}
@ -42,14 +45,14 @@ export function BpfLoaderDetailsCard(props: DetailsProps) {
}
}
type Props = {
type Props<T> = {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: T;
};
export function BpfLoaderWriteDetailsCard(props: Props) {
export function BpfLoaderWriteDetailsCard(props: Props<WriteInfo>) {
const { ix, index, result, info } = props;
const bytes = wrap(info.bytes, 50);
return (
@ -90,7 +93,7 @@ export function BpfLoaderWriteDetailsCard(props: Props) {
);
}
export function BpfLoaderFinalizeDetailsCard(props: Props) {
export function BpfLoaderFinalizeDetailsCard(props: Props<FinalizeInfo>) {
const { ix, index, result, info } = props;
return (

View File

@ -3,13 +3,15 @@
import { enums, number, pick, string, StructType } from "superstruct";
import { Pubkey } from "validators/pubkey";
const Write = pick({
export type WriteInfo = StructType<typeof WriteInfo>;
export const WriteInfo = pick({
account: Pubkey,
bytes: string(),
offset: number(),
});
const Finalize = pick({
export type FinalizeInfo = StructType<typeof FinalizeInfo>;
export const FinalizeInfo = pick({
account: Pubkey,
});
@ -17,8 +19,3 @@ export type BpfLoaderInstructionType = StructType<
typeof BpfLoaderInstructionType
>;
export const BpfLoaderInstructionType = enums(["write", "finalize"]);
export const IX_STRUCTS: { [id: string]: any } = {
write: Write,
finalize: Finalize,
};

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { AuthorizeInfo } from "./types";
export function AuthorizeDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AuthorizeInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { DeactivateInfo } from "./types";
export function DeactivateDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: DeactivateInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { DelegateInfo } from "./types";
export function DelegateDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: DelegateInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { InitializeInfo } from "./types";
export function InitializeDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: InitializeInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { SplitInfo } from "./types";
export function SplitDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: SplitInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -15,7 +15,14 @@ import { DeactivateDetailsCard } from "./DeactivateDetailsCard";
import { ParsedInfo } from "validators";
import { reportError } from "utils/sentry";
import { coerce } from "superstruct";
import { IX_STRUCTS } from "./types";
import {
AuthorizeInfo,
DeactivateInfo,
DelegateInfo,
InitializeInfo,
SplitInfo,
WithdrawInfo,
} from "./types";
type DetailsProps = {
tx: ParsedTransaction;
@ -27,21 +34,32 @@ type DetailsProps = {
export function StakeDetailsCard(props: DetailsProps) {
try {
const parsed = coerce(props.ix.parsed, ParsedInfo);
const info = coerce(parsed.info, IX_STRUCTS[parsed.type]);
switch (parsed.type) {
case "initialize":
case "initialize": {
const info = coerce(parsed.info, InitializeInfo);
return <InitializeDetailsCard info={info} {...props} />;
case "delegate":
}
case "delegate": {
const info = coerce(parsed.info, DelegateInfo);
return <DelegateDetailsCard info={info} {...props} />;
case "authorize":
}
case "authorize": {
const info = coerce(parsed.info, AuthorizeInfo);
return <AuthorizeDetailsCard info={info} {...props} />;
case "split":
}
case "split": {
const info = coerce(parsed.info, SplitInfo);
return <SplitDetailsCard info={info} {...props} />;
case "withdraw":
}
case "withdraw": {
const info = coerce(parsed.info, WithdrawInfo);
return <WithdrawDetailsCard info={info} {...props} />;
case "deactivate":
}
case "deactivate": {
const info = coerce(parsed.info, DeactivateInfo);
return <DeactivateDetailsCard info={info} {...props} />;
}
default:
return <UnknownDetailsCard {...props} />;
}

View File

@ -7,12 +7,13 @@ import {
import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { WithdrawInfo } from "./types";
export function WithdrawDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: WithdrawInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -3,7 +3,8 @@
import { enums, number, pick, string, StructType } from "superstruct";
import { Pubkey } from "validators/pubkey";
const Initialize = pick({
export type InitializeInfo = StructType<typeof InitializeInfo>;
export const InitializeInfo = pick({
stakeAccount: Pubkey,
authorized: pick({
staker: Pubkey,
@ -16,34 +17,39 @@ const Initialize = pick({
}),
});
const Delegate = pick({
export type DelegateInfo = StructType<typeof DelegateInfo>;
export const DelegateInfo = pick({
stakeAccount: Pubkey,
voteAccount: Pubkey,
stakeAuthority: Pubkey,
});
const Authorize = pick({
export type AuthorizeInfo = StructType<typeof AuthorizeInfo>;
export const AuthorizeInfo = pick({
authorityType: string(),
stakeAccount: Pubkey,
authority: Pubkey,
newAuthority: Pubkey,
});
const Split = pick({
export type SplitInfo = StructType<typeof SplitInfo>;
export const SplitInfo = pick({
stakeAccount: Pubkey,
stakeAuthority: Pubkey,
newSplitAccount: Pubkey,
lamports: number(),
});
const Withdraw = pick({
export type WithdrawInfo = StructType<typeof WithdrawInfo>;
export const WithdrawInfo = pick({
stakeAccount: Pubkey,
withdrawAuthority: Pubkey,
destination: Pubkey,
lamports: number(),
});
const Deactivate = pick({
export type DeactivateInfo = StructType<typeof DeactivateInfo>;
export const DeactivateInfo = pick({
stakeAccount: Pubkey,
stakeAuthority: Pubkey,
});
@ -57,12 +63,3 @@ export const StakeInstructionType = enums([
"withdraw",
"deactivate",
]);
export const IX_STRUCTS: { [id: string]: any } = {
initialize: Initialize,
delegate: Delegate,
authorize: Authorize,
split: Split,
withdraw: Withdraw,
deactivate: Deactivate,
};

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { AllocateInfo } from "./types";
export function AllocateDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AllocateInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
import { InstructionCard } from "../InstructionCard";
import { Copyable } from "components/common/Copyable";
import { Address } from "components/common/Address";
import { AllocateWithSeedInfo } from "./types";
export function AllocateWithSeedDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AllocateWithSeedInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { AssignInfo } from "./types";
export function AssignDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AssignInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
import { InstructionCard } from "../InstructionCard";
import { Copyable } from "components/common/Copyable";
import { Address } from "components/common/Address";
import { AssignWithSeedInfo } from "./types";
export function AssignWithSeedDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AssignWithSeedInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { CreateAccountInfo } from "./types";
export function CreateDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: CreateAccountInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -8,12 +8,13 @@ import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Copyable } from "components/common/Copyable";
import { Address } from "components/common/Address";
import { CreateAccountWithSeedInfo } from "./types";
export function CreateWithSeedDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: CreateAccountWithSeedInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { AdvanceNonceAccountInfo } from "./types";
export function NonceAdvanceDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AdvanceNonceAccountInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { AuthorizeNonceAccountInfo } from "./types";
export function NonceAuthorizeDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: AuthorizeNonceAccountInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -6,12 +6,13 @@ import {
} from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { InitializeNonceAccountInfo } from "./types";
export function NonceInitializeDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: InitializeNonceAccountInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -7,12 +7,13 @@ import {
import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { WithdrawNonceAccountInfo } from "./types";
export function NonceWithdrawDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: WithdrawNonceAccountInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -20,7 +20,19 @@ import { NonceAuthorizeDetailsCard } from "./NonceAuthorizeDetailsCard";
import { ParsedInfo } from "validators";
import { coerce } from "superstruct";
import { reportError } from "utils/sentry";
import { IX_STRUCTS } from "./types";
import {
CreateAccountInfo,
CreateAccountWithSeedInfo,
AllocateInfo,
AllocateWithSeedInfo,
AssignInfo,
AssignWithSeedInfo,
TransferInfo,
AdvanceNonceAccountInfo,
AuthorizeNonceAccountInfo,
InitializeNonceAccountInfo,
WithdrawNonceAccountInfo,
} from "./types";
type DetailsProps = {
tx: ParsedTransaction;
@ -32,31 +44,51 @@ type DetailsProps = {
export function SystemDetailsCard(props: DetailsProps) {
try {
const parsed = coerce(props.ix.parsed, ParsedInfo);
const info = coerce(parsed.info, IX_STRUCTS[parsed.type]);
switch (parsed.type) {
case "createAccount":
case "createAccount": {
const info = coerce(parsed.info, CreateAccountInfo);
return <CreateDetailsCard info={info} {...props} />;
case "createAccountWithSeed":
}
case "createAccountWithSeed": {
const info = coerce(parsed.info, CreateAccountWithSeedInfo);
return <CreateWithSeedDetailsCard info={info} {...props} />;
case "allocate":
}
case "allocate": {
const info = coerce(parsed.info, AllocateInfo);
return <AllocateDetailsCard info={info} {...props} />;
case "allocateWithSeed":
}
case "allocateWithSeed": {
const info = coerce(parsed.info, AllocateWithSeedInfo);
return <AllocateWithSeedDetailsCard info={info} {...props} />;
case "assign":
}
case "assign": {
const info = coerce(parsed.info, AssignInfo);
return <AssignDetailsCard info={info} {...props} />;
case "assignWithSeed":
}
case "assignWithSeed": {
const info = coerce(parsed.info, AssignWithSeedInfo);
return <AssignWithSeedDetailsCard info={info} {...props} />;
case "transfer":
}
case "transfer": {
const info = coerce(parsed.info, TransferInfo);
return <TransferDetailsCard info={info} {...props} />;
case "advanceNonceAccount":
}
case "advanceNonceAccount": {
const info = coerce(parsed.info, AdvanceNonceAccountInfo);
return <NonceAdvanceDetailsCard info={info} {...props} />;
case "withdrawNonceAccount":
}
case "withdrawNonceAccount": {
const info = coerce(parsed.info, WithdrawNonceAccountInfo);
return <NonceWithdrawDetailsCard info={info} {...props} />;
case "authorizeNonceAccount":
}
case "authorizeNonceAccount": {
const info = coerce(parsed.info, AuthorizeNonceAccountInfo);
return <NonceAuthorizeDetailsCard info={info} {...props} />;
case "initializeNonceAccount":
}
case "initializeNonceAccount": {
const info = coerce(parsed.info, InitializeNonceAccountInfo);
return <NonceInitializeDetailsCard info={info} {...props} />;
}
default:
return <UnknownDetailsCard {...props} />;
}

View File

@ -7,12 +7,13 @@ import {
import { lamportsToSolString } from "utils";
import { InstructionCard } from "../InstructionCard";
import { Address } from "components/common/Address";
import { TransferInfo } from "./types";
export function TransferDetailsCard(props: {
ix: ParsedInstruction;
index: number;
result: SignatureResult;
info: any;
info: TransferInfo;
}) {
const { ix, index, result, info } = props;

View File

@ -3,7 +3,8 @@
import { enums, number, pick, string, StructType } from "superstruct";
import { Pubkey } from "validators/pubkey";
const CreateAccount = pick({
export type CreateAccountInfo = StructType<typeof CreateAccountInfo>;
export const CreateAccountInfo = pick({
source: Pubkey,
newAccount: Pubkey,
lamports: number(),
@ -11,18 +12,23 @@ const CreateAccount = pick({
owner: Pubkey,
});
const Assign = pick({
export type AssignInfo = StructType<typeof AssignInfo>;
export const AssignInfo = pick({
account: Pubkey,
owner: Pubkey,
});
const Transfer = pick({
export type TransferInfo = StructType<typeof TransferInfo>;
export const TransferInfo = pick({
source: Pubkey,
destination: Pubkey,
lamports: number(),
});
const CreateAccountWithSeed = pick({
export type CreateAccountWithSeedInfo = StructType<
typeof CreateAccountWithSeedInfo
>;
export const CreateAccountWithSeedInfo = pick({
source: Pubkey,
newAccount: Pubkey,
base: Pubkey,
@ -32,35 +38,49 @@ const CreateAccountWithSeed = pick({
owner: Pubkey,
});
const AdvanceNonceAccount = pick({
export type AdvanceNonceAccountInfo = StructType<
typeof AdvanceNonceAccountInfo
>;
export const AdvanceNonceAccountInfo = pick({
nonceAccount: Pubkey,
nonceAuthority: Pubkey,
});
const WithdrawNonceAccount = pick({
export type WithdrawNonceAccountInfo = StructType<
typeof WithdrawNonceAccountInfo
>;
export const WithdrawNonceAccountInfo = pick({
nonceAccount: Pubkey,
destination: Pubkey,
nonceAuthority: Pubkey,
lamports: number(),
});
const InitializeNonceAccount = pick({
export type InitializeNonceAccountInfo = StructType<
typeof InitializeNonceAccountInfo
>;
export const InitializeNonceAccountInfo = pick({
nonceAccount: Pubkey,
nonceAuthority: Pubkey,
});
const AuthorizeNonceAccount = pick({
export type AuthorizeNonceAccountInfo = StructType<
typeof AuthorizeNonceAccountInfo
>;
export const AuthorizeNonceAccountInfo = pick({
nonceAccount: Pubkey,
nonceAuthority: Pubkey,
newAuthorized: Pubkey,
});
const Allocate = pick({
export type AllocateInfo = StructType<typeof AllocateInfo>;
export const AllocateInfo = pick({
account: Pubkey,
space: number(),
});
const AllocateWithSeed = pick({
export type AllocateWithSeedInfo = StructType<typeof AllocateWithSeedInfo>;
export const AllocateWithSeedInfo = pick({
account: Pubkey,
base: Pubkey,
seed: string(),
@ -68,14 +88,16 @@ const AllocateWithSeed = pick({
owner: Pubkey,
});
const AssignWithSeed = pick({
export type AssignWithSeedInfo = StructType<typeof AssignWithSeedInfo>;
export const AssignWithSeedInfo = pick({
account: Pubkey,
base: Pubkey,
seed: string(),
owner: Pubkey,
});
const TransferWithSeed = pick({
export type TransferWithSeedInfo = StructType<typeof TransferWithSeedInfo>;
export const TransferWithSeedInfo = pick({
source: Pubkey,
sourceBase: Pubkey,
destination: Pubkey,
@ -97,19 +119,5 @@ export const SystemInstructionType = enums([
"withdrawNonceAccount",
"authorizeNonceAccount",
"initializeNonceAccount",
// "transferWithSeed", TODO: Add support for transfer with seed
]);
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
};