explorer: Update superstruct (#15835)

This commit is contained in:
Justin Starry
2021-03-13 13:31:52 +08:00
committed by GitHub
parent 5b2da19c93
commit 186b342453
30 changed files with 544 additions and 563 deletions

View File

@ -17746,8 +17746,9 @@
"integrity": "sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA==" "integrity": "sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA=="
}, },
"superstruct": { "superstruct": {
"version": "github:solana-labs/superstruct#3425dfd28967286ac9d1c78ce7b3c07c5781caee", "version": "0.14.2",
"from": "github:solana-labs/superstruct" "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz",
"integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ=="
}, },
"supports-color": { "supports-color": {
"version": "5.5.0", "version": "5.5.0",

View File

@ -41,7 +41,7 @@
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3", "react-scripts": "^4.0.3",
"react-select": "^4.2.1", "react-select": "^4.2.1",
"superstruct": "github:solana-labs/superstruct", "superstruct": "^0.14.2",
"typescript": "^4.2.3" "typescript": "^4.2.3"
}, },
"scripts": { "scripts": {

View File

@ -6,7 +6,7 @@ import {
TokenAccountInfo, TokenAccountInfo,
MultisigAccountInfo, MultisigAccountInfo,
} from "validators/accounts/token"; } from "validators/accounts/token";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { TableCardBody } from "components/common/TableCardBody"; import { TableCardBody } from "components/common/TableCardBody";
import { Address } from "components/common/Address"; import { Address } from "components/common/Address";
import { UnknownAccountCard } from "./UnknownAccountCard"; import { UnknownAccountCard } from "./UnknownAccountCard";
@ -27,15 +27,15 @@ export function TokenAccountSection({
try { try {
switch (tokenAccount.type) { switch (tokenAccount.type) {
case "mint": { case "mint": {
const info = coerce(tokenAccount.info, MintAccountInfo); const info = create(tokenAccount.info, MintAccountInfo);
return <MintAccountCard account={account} info={info} />; return <MintAccountCard account={account} info={info} />;
} }
case "account": { case "account": {
const info = coerce(tokenAccount.info, TokenAccountInfo); const info = create(tokenAccount.info, TokenAccountInfo);
return <TokenAccountCard account={account} info={info} />; return <TokenAccountCard account={account} info={info} />;
} }
case "multisig": { case "multisig": {
const info = coerce(tokenAccount.info, MultisigAccountInfo); const info = create(tokenAccount.info, MultisigAccountInfo);
return <MultisigAccountCard account={account} info={info} />; return <MultisigAccountCard account={account} info={info} />;
} }
} }

View File

@ -25,7 +25,7 @@ import {
useFetchTransactionDetails, useFetchTransactionDetails,
useTransactionDetailsCache, useTransactionDetailsCache,
} from "providers/transactions/details"; } from "providers/transactions/details";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { import {
TokenInstructionType, TokenInstructionType,
@ -366,9 +366,9 @@ function instructionTypeName(
tx: ConfirmedSignatureInfo tx: ConfirmedSignatureInfo
): string { ): string {
try { try {
const parsed = coerce(ix.parsed, ParsedInfo); const parsed = create(ix.parsed, ParsedInfo);
const { type: rawType } = parsed; const { type: rawType } = parsed;
const type = coerce(rawType, TokenInstructionType); const type = create(rawType, TokenInstructionType);
return IX_TITLES[type]; return IX_TITLES[type];
} catch (err) { } catch (err) {
reportError(err, { signature: tx.signature }); reportError(err, { signature: tx.signature });

View File

@ -6,7 +6,7 @@ import {
BPF_LOADER_PROGRAM_ID, BPF_LOADER_PROGRAM_ID,
} from "@solana/web3.js"; } from "@solana/web3.js";
import { InstructionCard } from "../InstructionCard"; import { InstructionCard } from "../InstructionCard";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { WriteInfo, FinalizeInfo } from "./types"; import { WriteInfo, FinalizeInfo } from "./types";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
@ -25,15 +25,15 @@ type DetailsProps = {
export function BpfLoaderDetailsCard(props: DetailsProps) { export function BpfLoaderDetailsCard(props: DetailsProps) {
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
switch (parsed.type) { switch (parsed.type) {
case "write": { case "write": {
const info = coerce(parsed.info, WriteInfo); const info = create(parsed.info, WriteInfo);
return <BpfLoaderWriteDetailsCard info={info} {...props} />; return <BpfLoaderWriteDetailsCard info={info} {...props} />;
} }
case "finalize": { case "finalize": {
const info = coerce(parsed.info, FinalizeInfo); const info = create(parsed.info, FinalizeInfo);
return <BpfLoaderFinalizeDetailsCard info={info} {...props} />; return <BpfLoaderFinalizeDetailsCard info={info} {...props} />;
} }
default: default:

View File

@ -1,21 +1,19 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { enums, number, pick, string, StructType } from "superstruct"; import { enums, number, type, string, Infer } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type WriteInfo = StructType<typeof WriteInfo>; export type WriteInfo = Infer<typeof WriteInfo>;
export const WriteInfo = pick({ export const WriteInfo = type({
account: Pubkey, account: PublicKeyFromString,
bytes: string(), bytes: string(),
offset: number(), offset: number(),
}); });
export type FinalizeInfo = StructType<typeof FinalizeInfo>; export type FinalizeInfo = Infer<typeof FinalizeInfo>;
export const FinalizeInfo = pick({ export const FinalizeInfo = type({
account: Pubkey, account: PublicKeyFromString,
}); });
export type BpfLoaderInstructionType = StructType< export type BpfLoaderInstructionType = Infer<typeof BpfLoaderInstructionType>;
typeof BpfLoaderInstructionType
>;
export const BpfLoaderInstructionType = enums(["write", "finalize"]); export const BpfLoaderInstructionType = enums(["write", "finalize"]);

View File

@ -6,7 +6,7 @@ import {
PublicKey, PublicKey,
} from "@solana/web3.js"; } from "@solana/web3.js";
import { Address } from "components/common/Address"; import { Address } from "components/common/Address";
import { coerce, Struct } from "superstruct"; import { create, Struct } from "superstruct";
import { camelToTitleCase } from "utils"; import { camelToTitleCase } from "utils";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
@ -31,7 +31,7 @@ type DetailsProps = {
export function BpfUpgradeableLoaderDetailsCard(props: DetailsProps) { export function BpfUpgradeableLoaderDetailsCard(props: DetailsProps) {
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
switch (parsed.type) { switch (parsed.type) {
case "write": { case "write": {
return renderDetails<WriteInfo>(props, parsed, WriteInfo); return renderDetails<WriteInfo>(props, parsed, WriteInfo);
@ -72,7 +72,7 @@ function renderDetails<T>(
parsed: ParsedInfo, parsed: ParsedInfo,
struct: Struct<T> struct: Struct<T>
) { ) {
const info = coerce(parsed.info, struct); const info = create(parsed.info, struct);
const attributes: JSX.Element[] = []; const attributes: JSX.Element[] = [];
for (let [key, value] of Object.entries(info)) { for (let [key, value] of Object.entries(info)) {

View File

@ -1,56 +1,54 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { enums, nullable, number, pick, string, StructType } from "superstruct"; import { enums, nullable, number, type, string, Infer } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type WriteInfo = StructType<typeof WriteInfo>; export type WriteInfo = Infer<typeof WriteInfo>;
export const WriteInfo = pick({ export const WriteInfo = type({
account: Pubkey, account: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
bytes: string(), bytes: string(),
offset: number(), offset: number(),
}); });
export type InitializeBufferInfo = StructType<typeof InitializeBufferInfo>; export type InitializeBufferInfo = Infer<typeof InitializeBufferInfo>;
export const InitializeBufferInfo = pick({ export const InitializeBufferInfo = type({
account: Pubkey, account: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
}); });
export type UpgradeInfo = StructType<typeof UpgradeInfo>; export type UpgradeInfo = Infer<typeof UpgradeInfo>;
export const UpgradeInfo = pick({ export const UpgradeInfo = type({
programDataAccount: Pubkey, programDataAccount: PublicKeyFromString,
programAccount: Pubkey, programAccount: PublicKeyFromString,
bufferAccount: Pubkey, bufferAccount: PublicKeyFromString,
spillAccount: Pubkey, spillAccount: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
rentSysvar: Pubkey, rentSysvar: PublicKeyFromString,
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
}); });
export type SetAuthorityInfo = StructType<typeof SetAuthorityInfo>; export type SetAuthorityInfo = Infer<typeof SetAuthorityInfo>;
export const SetAuthorityInfo = pick({ export const SetAuthorityInfo = type({
account: Pubkey, account: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
newAuthority: nullable(Pubkey), newAuthority: nullable(PublicKeyFromString),
}); });
export type DeployWithMaxDataLenInfo = StructType< export type DeployWithMaxDataLenInfo = Infer<typeof DeployWithMaxDataLenInfo>;
typeof DeployWithMaxDataLenInfo export const DeployWithMaxDataLenInfo = type({
>; programDataAccount: PublicKeyFromString,
export const DeployWithMaxDataLenInfo = pick({ programAccount: PublicKeyFromString,
programDataAccount: Pubkey, payerAccount: PublicKeyFromString,
programAccount: Pubkey, bufferAccount: PublicKeyFromString,
payerAccount: Pubkey, authority: PublicKeyFromString,
bufferAccount: Pubkey, rentSysvar: PublicKeyFromString,
authority: Pubkey, clockSysvar: PublicKeyFromString,
rentSysvar: Pubkey, systemProgram: PublicKeyFromString,
clockSysvar: Pubkey,
systemProgram: Pubkey,
maxDataLen: number(), maxDataLen: number(),
}); });
export type UpgradeableBpfLoaderInstructionType = StructType< export type UpgradeableBpfLoaderInstructionType = Infer<
typeof UpgradeableBpfLoaderInstructionType typeof UpgradeableBpfLoaderInstructionType
>; >;
export const UpgradeableBpfLoaderInstructionType = enums([ export const UpgradeableBpfLoaderInstructionType = enums([

View File

@ -3,9 +3,9 @@
import { decodeInstruction, MARKETS } from "@project-serum/serum"; import { decodeInstruction, MARKETS } from "@project-serum/serum";
import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import BN from "bn.js"; import BN from "bn.js";
import { coerce, enums, number, optional, pick, StructType } from "superstruct"; import { enums, number, optional, type, Infer, create } from "superstruct";
import { BigNumValue } from "validators/bignum"; import { BigNumFromString } from "validators/bignum";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
const SERUM_PROGRAM_IDS = [ const SERUM_PROGRAM_IDS = [
"4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn", "4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn",
@ -14,10 +14,10 @@ const SERUM_PROGRAM_IDS = [
export const SERUM_DECODED_MAX = 6; export const SERUM_DECODED_MAX = 6;
export type Side = StructType<typeof Side>; export type Side = Infer<typeof Side>;
export const Side = enums(["buy", "sell"]); export const Side = enums(["buy", "sell"]);
export type OrderType = StructType<typeof OrderType>; export type OrderType = Infer<typeof OrderType>;
export const OrderType = enums(["limit", "ioc", "postOnly"]); export const OrderType = enums(["limit", "ioc", "postOnly"]);
export type InitializeMarket = { export type InitializeMarket = {
@ -38,18 +38,18 @@ export type InitializeMarket = {
programId: PublicKey; programId: PublicKey;
}; };
export const InitializeMarketDecode = pick({ export const InitializeMarketDecode = type({
baseLotSize: BigNumValue, baseLotSize: BigNumFromString,
quoteLotSize: BigNumValue, quoteLotSize: BigNumFromString,
feeRateBps: number(), feeRateBps: number(),
quoteDustThreshold: BigNumValue, quoteDustThreshold: BigNumFromString,
vaultSignerNonce: BigNumValue, vaultSignerNonce: BigNumFromString,
}); });
export function decodeInitializeMarket( export function decodeInitializeMarket(
ix: TransactionInstruction ix: TransactionInstruction
): InitializeMarket { ): InitializeMarket {
const decoded = coerce( const decoded = create(
decodeInstruction(ix.data).initializeMarket, decodeInstruction(ix.data).initializeMarket,
InitializeMarketDecode InitializeMarketDecode
); );
@ -92,17 +92,17 @@ export type NewOrder = {
clientId: BN; clientId: BN;
}; };
export const NewOrderDecode = pick({ export const NewOrderDecode = type({
side: Side, side: Side,
limitPrice: BigNumValue, limitPrice: BigNumFromString,
maxQuantity: BigNumValue, maxQuantity: BigNumFromString,
orderType: OrderType, orderType: OrderType,
clientId: BigNumValue, clientId: BigNumFromString,
feeDiscountPubkey: optional(Pubkey), feeDiscountPubkey: optional(PublicKeyFromString),
}); });
export function decodeNewOrder(ix: TransactionInstruction): NewOrder { export function decodeNewOrder(ix: TransactionInstruction): NewOrder {
const decoded = coerce(decodeInstruction(ix.data).newOrder, NewOrderDecode); const decoded = create(decodeInstruction(ix.data).newOrder, NewOrderDecode);
let newOrder: NewOrder = { let newOrder: NewOrder = {
market: ix.keys[0].pubkey, market: ix.keys[0].pubkey,
@ -139,12 +139,12 @@ export type MatchOrders = {
programId: PublicKey; programId: PublicKey;
}; };
export const MatchOrdersDecode = pick({ export const MatchOrdersDecode = type({
limit: number(), limit: number(),
}); });
export function decodeMatchOrders(ix: TransactionInstruction): MatchOrders { export function decodeMatchOrders(ix: TransactionInstruction): MatchOrders {
const decoded = coerce( const decoded = create(
decodeInstruction(ix.data).matchOrders, decodeInstruction(ix.data).matchOrders,
MatchOrdersDecode MatchOrdersDecode
); );
@ -172,12 +172,12 @@ export type ConsumeEvents = {
programId: PublicKey; programId: PublicKey;
}; };
export const ConsumeEventsDecode = pick({ export const ConsumeEventsDecode = type({
limit: number(), limit: number(),
}); });
export function decodeConsumeEvents(ix: TransactionInstruction): ConsumeEvents { export function decodeConsumeEvents(ix: TransactionInstruction): ConsumeEvents {
const decoded = coerce( const decoded = create(
decodeInstruction(ix.data).consumeEvents, decodeInstruction(ix.data).consumeEvents,
ConsumeEventsDecode ConsumeEventsDecode
); );
@ -204,14 +204,14 @@ export type CancelOrder = {
programId: PublicKey; programId: PublicKey;
}; };
export const CancelOrderDecode = pick({ export const CancelOrderDecode = type({
side: Side, side: Side,
orderId: BigNumValue, orderId: BigNumFromString,
openOrdersSlot: number(), openOrdersSlot: number(),
}); });
export function decodeCancelOrder(ix: TransactionInstruction): CancelOrder { export function decodeCancelOrder(ix: TransactionInstruction): CancelOrder {
const decoded = coerce( const decoded = create(
decodeInstruction(ix.data).cancelOrder, decodeInstruction(ix.data).cancelOrder,
CancelOrderDecode CancelOrderDecode
); );
@ -239,14 +239,14 @@ export type CancelOrderByClientId = {
programId: PublicKey; programId: PublicKey;
}; };
export const CancelOrderByClientIdDecode = pick({ export const CancelOrderByClientIdDecode = type({
clientId: BigNumValue, clientId: BigNumFromString,
}); });
export function decodeCancelOrderByClientId( export function decodeCancelOrderByClientId(
ix: TransactionInstruction ix: TransactionInstruction
): CancelOrderByClientId { ): CancelOrderByClientId {
const decoded = coerce( const decoded = create(
decodeInstruction(ix.data).cancelOrderByClientId, decodeInstruction(ix.data).cancelOrderByClientId,
CancelOrderByClientIdDecode CancelOrderByClientIdDecode
); );

View File

@ -14,7 +14,7 @@ import { WithdrawDetailsCard } from "./WithdrawDetailsCard";
import { DeactivateDetailsCard } from "./DeactivateDetailsCard"; import { DeactivateDetailsCard } from "./DeactivateDetailsCard";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { import {
AuthorizeInfo, AuthorizeInfo,
DeactivateInfo, DeactivateInfo,
@ -37,35 +37,35 @@ type DetailsProps = {
export function StakeDetailsCard(props: DetailsProps) { export function StakeDetailsCard(props: DetailsProps) {
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
switch (parsed.type) { switch (parsed.type) {
case "initialize": { case "initialize": {
const info = coerce(parsed.info, InitializeInfo); const info = create(parsed.info, InitializeInfo);
return <InitializeDetailsCard info={info} {...props} />; return <InitializeDetailsCard info={info} {...props} />;
} }
case "delegate": { case "delegate": {
const info = coerce(parsed.info, DelegateInfo); const info = create(parsed.info, DelegateInfo);
return <DelegateDetailsCard info={info} {...props} />; return <DelegateDetailsCard info={info} {...props} />;
} }
case "authorize": { case "authorize": {
const info = coerce(parsed.info, AuthorizeInfo); const info = create(parsed.info, AuthorizeInfo);
return <AuthorizeDetailsCard info={info} {...props} />; return <AuthorizeDetailsCard info={info} {...props} />;
} }
case "split": { case "split": {
const info = coerce(parsed.info, SplitInfo); const info = create(parsed.info, SplitInfo);
return <SplitDetailsCard info={info} {...props} />; return <SplitDetailsCard info={info} {...props} />;
} }
case "withdraw": { case "withdraw": {
const info = coerce(parsed.info, WithdrawInfo); const info = create(parsed.info, WithdrawInfo);
return <WithdrawDetailsCard info={info} {...props} />; return <WithdrawDetailsCard info={info} {...props} />;
} }
case "deactivate": { case "deactivate": {
const info = coerce(parsed.info, DeactivateInfo); const info = create(parsed.info, DeactivateInfo);
return <DeactivateDetailsCard info={info} {...props} />; return <DeactivateDetailsCard info={info} {...props} />;
} }
case "merge": { case "merge": {
const info = coerce(parsed.info, MergeInfo); const info = create(parsed.info, MergeInfo);
return <MergeDetailsCard info={info} {...props} />; return <MergeDetailsCard info={info} {...props} />;
} }
default: default:

View File

@ -1,69 +1,69 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { enums, number, pick, string, StructType } from "superstruct"; import { enums, number, type, string, Infer } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type InitializeInfo = StructType<typeof InitializeInfo>; export type InitializeInfo = Infer<typeof InitializeInfo>;
export const InitializeInfo = pick({ export const InitializeInfo = type({
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
authorized: pick({ authorized: type({
staker: Pubkey, staker: PublicKeyFromString,
withdrawer: Pubkey, withdrawer: PublicKeyFromString,
}), }),
lockup: pick({ lockup: type({
unixTimestamp: number(), unixTimestamp: number(),
epoch: number(), epoch: number(),
custodian: Pubkey, custodian: PublicKeyFromString,
}), }),
}); });
export type DelegateInfo = StructType<typeof DelegateInfo>; export type DelegateInfo = Infer<typeof DelegateInfo>;
export const DelegateInfo = pick({ export const DelegateInfo = type({
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
stakeAuthority: Pubkey, stakeAuthority: PublicKeyFromString,
}); });
export type AuthorizeInfo = StructType<typeof AuthorizeInfo>; export type AuthorizeInfo = Infer<typeof AuthorizeInfo>;
export const AuthorizeInfo = pick({ export const AuthorizeInfo = type({
authorityType: string(), authorityType: string(),
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
newAuthority: Pubkey, newAuthority: PublicKeyFromString,
}); });
export type SplitInfo = StructType<typeof SplitInfo>; export type SplitInfo = Infer<typeof SplitInfo>;
export const SplitInfo = pick({ export const SplitInfo = type({
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
stakeAuthority: Pubkey, stakeAuthority: PublicKeyFromString,
newSplitAccount: Pubkey, newSplitAccount: PublicKeyFromString,
lamports: number(), lamports: number(),
}); });
export type WithdrawInfo = StructType<typeof WithdrawInfo>; export type WithdrawInfo = Infer<typeof WithdrawInfo>;
export const WithdrawInfo = pick({ export const WithdrawInfo = type({
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
withdrawAuthority: Pubkey, withdrawAuthority: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
lamports: number(), lamports: number(),
}); });
export type DeactivateInfo = StructType<typeof DeactivateInfo>; export type DeactivateInfo = Infer<typeof DeactivateInfo>;
export const DeactivateInfo = pick({ export const DeactivateInfo = type({
stakeAccount: Pubkey, stakeAccount: PublicKeyFromString,
stakeAuthority: Pubkey, stakeAuthority: PublicKeyFromString,
}); });
export type MergeInfo = StructType<typeof MergeInfo>; export type MergeInfo = Infer<typeof MergeInfo>;
export const MergeInfo = pick({ export const MergeInfo = type({
source: Pubkey, source: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
stakeAuthority: Pubkey, stakeAuthority: PublicKeyFromString,
stakeHistorySysvar: Pubkey, stakeHistorySysvar: PublicKeyFromString,
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
}); });
export type StakeInstructionType = StructType<typeof StakeInstructionType>; export type StakeInstructionType = Infer<typeof StakeInstructionType>;
export const StakeInstructionType = enums([ export const StakeInstructionType = enums([
"initialize", "initialize",
"delegate", "delegate",

View File

@ -19,7 +19,7 @@ import { NonceWithdrawDetailsCard } from "./NonceWithdrawDetailsCard";
import { NonceAuthorizeDetailsCard } from "./NonceAuthorizeDetailsCard"; import { NonceAuthorizeDetailsCard } from "./NonceAuthorizeDetailsCard";
import { TransferWithSeedDetailsCard } from "./TransferWithSeedDetailsCard"; import { TransferWithSeedDetailsCard } from "./TransferWithSeedDetailsCard";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
import { import {
CreateAccountInfo, CreateAccountInfo,
@ -47,54 +47,54 @@ type DetailsProps = {
export function SystemDetailsCard(props: DetailsProps) { export function SystemDetailsCard(props: DetailsProps) {
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
switch (parsed.type) { switch (parsed.type) {
case "createAccount": { case "createAccount": {
const info = coerce(parsed.info, CreateAccountInfo); const info = create(parsed.info, CreateAccountInfo);
return <CreateDetailsCard info={info} {...props} />; return <CreateDetailsCard info={info} {...props} />;
} }
case "createAccountWithSeed": { case "createAccountWithSeed": {
const info = coerce(parsed.info, CreateAccountWithSeedInfo); const info = create(parsed.info, CreateAccountWithSeedInfo);
return <CreateWithSeedDetailsCard info={info} {...props} />; return <CreateWithSeedDetailsCard info={info} {...props} />;
} }
case "allocate": { case "allocate": {
const info = coerce(parsed.info, AllocateInfo); const info = create(parsed.info, AllocateInfo);
return <AllocateDetailsCard info={info} {...props} />; return <AllocateDetailsCard info={info} {...props} />;
} }
case "allocateWithSeed": { case "allocateWithSeed": {
const info = coerce(parsed.info, AllocateWithSeedInfo); const info = create(parsed.info, AllocateWithSeedInfo);
return <AllocateWithSeedDetailsCard info={info} {...props} />; return <AllocateWithSeedDetailsCard info={info} {...props} />;
} }
case "assign": { case "assign": {
const info = coerce(parsed.info, AssignInfo); const info = create(parsed.info, AssignInfo);
return <AssignDetailsCard info={info} {...props} />; return <AssignDetailsCard info={info} {...props} />;
} }
case "assignWithSeed": { case "assignWithSeed": {
const info = coerce(parsed.info, AssignWithSeedInfo); const info = create(parsed.info, AssignWithSeedInfo);
return <AssignWithSeedDetailsCard info={info} {...props} />; return <AssignWithSeedDetailsCard info={info} {...props} />;
} }
case "transfer": { case "transfer": {
const info = coerce(parsed.info, TransferInfo); const info = create(parsed.info, TransferInfo);
return <TransferDetailsCard info={info} {...props} />; return <TransferDetailsCard info={info} {...props} />;
} }
case "advanceNonce": { case "advanceNonce": {
const info = coerce(parsed.info, AdvanceNonceInfo); const info = create(parsed.info, AdvanceNonceInfo);
return <NonceAdvanceDetailsCard info={info} {...props} />; return <NonceAdvanceDetailsCard info={info} {...props} />;
} }
case "withdrawNonce": { case "withdrawNonce": {
const info = coerce(parsed.info, WithdrawNonceInfo); const info = create(parsed.info, WithdrawNonceInfo);
return <NonceWithdrawDetailsCard info={info} {...props} />; return <NonceWithdrawDetailsCard info={info} {...props} />;
} }
case "authorizeNonce": { case "authorizeNonce": {
const info = coerce(parsed.info, AuthorizeNonceInfo); const info = create(parsed.info, AuthorizeNonceInfo);
return <NonceAuthorizeDetailsCard info={info} {...props} />; return <NonceAuthorizeDetailsCard info={info} {...props} />;
} }
case "initializeNonce": { case "initializeNonce": {
const info = coerce(parsed.info, InitializeNonceInfo); const info = create(parsed.info, InitializeNonceInfo);
return <NonceInitializeDetailsCard info={info} {...props} />; return <NonceInitializeDetailsCard info={info} {...props} />;
} }
case "transferWithSeed": { case "transferWithSeed": {
const info = coerce(parsed.info, TransferWithSeedInfo); const info = create(parsed.info, TransferWithSeedInfo);
return <TransferWithSeedDetailsCard info={info} {...props} />; return <TransferWithSeedDetailsCard info={info} {...props} />;
} }
default: default:

View File

@ -1,104 +1,102 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { enums, number, pick, string, StructType } from "superstruct"; import { enums, number, type, string, Infer } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type CreateAccountInfo = StructType<typeof CreateAccountInfo>; export type CreateAccountInfo = Infer<typeof CreateAccountInfo>;
export const CreateAccountInfo = pick({ export const CreateAccountInfo = type({
source: Pubkey, source: PublicKeyFromString,
newAccount: Pubkey, newAccount: PublicKeyFromString,
lamports: number(), lamports: number(),
space: number(), space: number(),
owner: Pubkey, owner: PublicKeyFromString,
}); });
export type AssignInfo = StructType<typeof AssignInfo>; export type AssignInfo = Infer<typeof AssignInfo>;
export const AssignInfo = pick({ export const AssignInfo = type({
account: Pubkey, account: PublicKeyFromString,
owner: Pubkey, owner: PublicKeyFromString,
}); });
export type TransferInfo = StructType<typeof TransferInfo>; export type TransferInfo = Infer<typeof TransferInfo>;
export const TransferInfo = pick({ export const TransferInfo = type({
source: Pubkey, source: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
lamports: number(), lamports: number(),
}); });
export type CreateAccountWithSeedInfo = StructType< export type CreateAccountWithSeedInfo = Infer<typeof CreateAccountWithSeedInfo>;
typeof CreateAccountWithSeedInfo export const CreateAccountWithSeedInfo = type({
>; source: PublicKeyFromString,
export const CreateAccountWithSeedInfo = pick({ newAccount: PublicKeyFromString,
source: Pubkey, base: PublicKeyFromString,
newAccount: Pubkey,
base: Pubkey,
seed: string(), seed: string(),
lamports: number(), lamports: number(),
space: number(), space: number(),
owner: Pubkey, owner: PublicKeyFromString,
}); });
export type AdvanceNonceInfo = StructType<typeof AdvanceNonceInfo>; export type AdvanceNonceInfo = Infer<typeof AdvanceNonceInfo>;
export const AdvanceNonceInfo = pick({ export const AdvanceNonceInfo = type({
nonceAccount: Pubkey, nonceAccount: PublicKeyFromString,
nonceAuthority: Pubkey, nonceAuthority: PublicKeyFromString,
}); });
export type WithdrawNonceInfo = StructType<typeof WithdrawNonceInfo>; export type WithdrawNonceInfo = Infer<typeof WithdrawNonceInfo>;
export const WithdrawNonceInfo = pick({ export const WithdrawNonceInfo = type({
nonceAccount: Pubkey, nonceAccount: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
nonceAuthority: Pubkey, nonceAuthority: PublicKeyFromString,
lamports: number(), lamports: number(),
}); });
export type InitializeNonceInfo = StructType<typeof InitializeNonceInfo>; export type InitializeNonceInfo = Infer<typeof InitializeNonceInfo>;
export const InitializeNonceInfo = pick({ export const InitializeNonceInfo = type({
nonceAccount: Pubkey, nonceAccount: PublicKeyFromString,
nonceAuthority: Pubkey, nonceAuthority: PublicKeyFromString,
}); });
export type AuthorizeNonceInfo = StructType<typeof AuthorizeNonceInfo>; export type AuthorizeNonceInfo = Infer<typeof AuthorizeNonceInfo>;
export const AuthorizeNonceInfo = pick({ export const AuthorizeNonceInfo = type({
nonceAccount: Pubkey, nonceAccount: PublicKeyFromString,
nonceAuthority: Pubkey, nonceAuthority: PublicKeyFromString,
newAuthorized: Pubkey, newAuthorized: PublicKeyFromString,
}); });
export type AllocateInfo = StructType<typeof AllocateInfo>; export type AllocateInfo = Infer<typeof AllocateInfo>;
export const AllocateInfo = pick({ export const AllocateInfo = type({
account: Pubkey, account: PublicKeyFromString,
space: number(), space: number(),
}); });
export type AllocateWithSeedInfo = StructType<typeof AllocateWithSeedInfo>; export type AllocateWithSeedInfo = Infer<typeof AllocateWithSeedInfo>;
export const AllocateWithSeedInfo = pick({ export const AllocateWithSeedInfo = type({
account: Pubkey, account: PublicKeyFromString,
base: Pubkey, base: PublicKeyFromString,
seed: string(), seed: string(),
space: number(), space: number(),
owner: Pubkey, owner: PublicKeyFromString,
}); });
export type AssignWithSeedInfo = StructType<typeof AssignWithSeedInfo>; export type AssignWithSeedInfo = Infer<typeof AssignWithSeedInfo>;
export const AssignWithSeedInfo = pick({ export const AssignWithSeedInfo = type({
account: Pubkey, account: PublicKeyFromString,
base: Pubkey, base: PublicKeyFromString,
seed: string(), seed: string(),
owner: Pubkey, owner: PublicKeyFromString,
}); });
export type TransferWithSeedInfo = StructType<typeof TransferWithSeedInfo>; export type TransferWithSeedInfo = Infer<typeof TransferWithSeedInfo>;
export const TransferWithSeedInfo = pick({ export const TransferWithSeedInfo = type({
source: Pubkey, source: PublicKeyFromString,
sourceBase: Pubkey, sourceBase: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
lamports: number(), lamports: number(),
sourceSeed: string(), sourceSeed: string(),
sourceOwner: Pubkey, sourceOwner: PublicKeyFromString,
}); });
export type SystemInstructionType = StructType<typeof SystemInstructionType>; export type SystemInstructionType = Infer<typeof SystemInstructionType>;
export const SystemInstructionType = enums([ export const SystemInstructionType = enums([
"createAccount", "createAccount",
"createAccountWithSeed", "createAccountWithSeed",

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { import {
SignatureResult, SignatureResult,
ParsedTransaction, ParsedTransaction,
@ -37,12 +37,12 @@ type DetailsProps = {
export function TokenDetailsCard(props: DetailsProps) { export function TokenDetailsCard(props: DetailsProps) {
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
const { type: rawType, info } = parsed; const { type: rawType, info } = parsed;
const type = coerce(rawType, TokenInstructionType); const type = create(rawType, TokenInstructionType);
const title = `Token: ${IX_TITLES[type]}`; const title = `Token: ${IX_TITLES[type]}`;
const coerced = coerce(info, IX_STRUCTS[type] as any); const created = create(info, IX_STRUCTS[type] as any);
return <TokenInstruction title={title} info={coerced} {...props} />; return <TokenInstruction title={title} info={created} {...props} />;
} catch (err) { } catch (err) {
reportError(err, { reportError(err, {
signature: props.tx.signatures[0], signature: props.tx.signatures[0],

View File

@ -2,8 +2,8 @@
import { import {
enums, enums,
pick, type,
StructType, Infer,
number, number,
string, string,
optional, optional,
@ -11,60 +11,60 @@ import {
nullable, nullable,
union, union,
} from "superstruct"; } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type TokenAmountUi = StructType<typeof TokenAmountUi>; export type TokenAmountUi = Infer<typeof TokenAmountUi>;
export const TokenAmountUi = pick({ export const TokenAmountUi = type({
amount: string(), amount: string(),
decimals: number(), decimals: number(),
uiAmountString: string(), uiAmountString: string(),
}); });
const InitializeMint = pick({ const InitializeMint = type({
mint: Pubkey, mint: PublicKeyFromString,
decimals: number(), decimals: number(),
mintAuthority: Pubkey, mintAuthority: PublicKeyFromString,
rentSysvar: Pubkey, rentSysvar: PublicKeyFromString,
freezeAuthority: optional(Pubkey), freezeAuthority: optional(PublicKeyFromString),
}); });
const InitializeAccount = pick({ const InitializeAccount = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
owner: Pubkey, owner: PublicKeyFromString,
rentSysvar: Pubkey, rentSysvar: PublicKeyFromString,
}); });
const InitializeMultisig = pick({ const InitializeMultisig = type({
multisig: Pubkey, multisig: PublicKeyFromString,
rentSysvar: Pubkey, rentSysvar: PublicKeyFromString,
signers: array(Pubkey), signers: array(PublicKeyFromString),
m: number(), m: number(),
}); });
const Transfer = pick({ const Transfer = type({
source: Pubkey, source: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
amount: union([string(), number()]), amount: union([string(), number()]),
authority: optional(Pubkey), authority: optional(PublicKeyFromString),
multisigAuthority: optional(Pubkey), multisigAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const Approve = pick({ const Approve = type({
source: Pubkey, source: PublicKeyFromString,
delegate: Pubkey, delegate: PublicKeyFromString,
amount: union([string(), number()]), amount: union([string(), number()]),
owner: optional(Pubkey), owner: optional(PublicKeyFromString),
multisigOwner: optional(Pubkey), multisigOwner: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const Revoke = pick({ const Revoke = type({
source: Pubkey, source: PublicKeyFromString,
owner: optional(Pubkey), owner: optional(PublicKeyFromString),
multisigOwner: optional(Pubkey), multisigOwner: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const AuthorityType = enums([ const AuthorityType = enums([
@ -74,97 +74,97 @@ const AuthorityType = enums([
"closeAccount", "closeAccount",
]); ]);
const SetAuthority = pick({ const SetAuthority = type({
mint: optional(Pubkey), mint: optional(PublicKeyFromString),
account: optional(Pubkey), account: optional(PublicKeyFromString),
authorityType: AuthorityType, authorityType: AuthorityType,
newAuthority: nullable(Pubkey), newAuthority: nullable(PublicKeyFromString),
authority: optional(Pubkey), authority: optional(PublicKeyFromString),
multisigAuthority: optional(Pubkey), multisigAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const MintTo = pick({ const MintTo = type({
mint: Pubkey, mint: PublicKeyFromString,
account: Pubkey, account: PublicKeyFromString,
amount: union([string(), number()]), amount: union([string(), number()]),
mintAuthority: optional(Pubkey), mintAuthority: optional(PublicKeyFromString),
multisigMintAuthority: optional(Pubkey), multisigMintAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const Burn = pick({ const Burn = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
amount: union([string(), number()]), amount: union([string(), number()]),
authority: optional(Pubkey), authority: optional(PublicKeyFromString),
multisigAuthority: optional(Pubkey), multisigAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const CloseAccount = pick({ const CloseAccount = type({
account: Pubkey, account: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
owner: optional(Pubkey), owner: optional(PublicKeyFromString),
multisigOwner: optional(Pubkey), multisigOwner: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const FreezeAccount = pick({ const FreezeAccount = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
freezeAuthority: optional(Pubkey), freezeAuthority: optional(PublicKeyFromString),
multisigFreezeAuthority: optional(Pubkey), multisigFreezeAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const ThawAccount = pick({ const ThawAccount = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
freezeAuthority: optional(Pubkey), freezeAuthority: optional(PublicKeyFromString),
multisigFreezeAuthority: optional(Pubkey), multisigFreezeAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
}); });
const TransferChecked = pick({ const TransferChecked = type({
source: Pubkey, source: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
authority: optional(Pubkey), authority: optional(PublicKeyFromString),
multisigAuthority: optional(Pubkey), multisigAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
tokenAmount: TokenAmountUi, tokenAmount: TokenAmountUi,
}); });
const ApproveChecked = pick({ const ApproveChecked = type({
source: Pubkey, source: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
delegate: Pubkey, delegate: PublicKeyFromString,
owner: optional(Pubkey), owner: optional(PublicKeyFromString),
multisigOwner: optional(Pubkey), multisigOwner: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
tokenAmount: TokenAmountUi, tokenAmount: TokenAmountUi,
}); });
const MintToChecked = pick({ const MintToChecked = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
mintAuthority: optional(Pubkey), mintAuthority: optional(PublicKeyFromString),
multisigMintAuthority: optional(Pubkey), multisigMintAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
tokenAmount: TokenAmountUi, tokenAmount: TokenAmountUi,
}); });
const BurnChecked = pick({ const BurnChecked = type({
account: Pubkey, account: PublicKeyFromString,
mint: Pubkey, mint: PublicKeyFromString,
authority: optional(Pubkey), authority: optional(PublicKeyFromString),
multisigAuthority: optional(Pubkey), multisigAuthority: optional(PublicKeyFromString),
signers: optional(array(Pubkey)), signers: optional(array(PublicKeyFromString)),
tokenAmount: TokenAmountUi, tokenAmount: TokenAmountUi,
}); });
export type TokenInstructionType = StructType<typeof TokenInstructionType>; export type TokenInstructionType = Infer<typeof TokenInstructionType>;
export const TokenInstructionType = enums([ export const TokenInstructionType = enums([
"initializeMint", "initializeMint",
"initializeAccount", "initializeAccount",

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { coerce, Struct } from "superstruct"; import { create, Struct } from "superstruct";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { import {
UpdateCommissionInfo, UpdateCommissionInfo,
@ -23,7 +23,7 @@ export function VoteDetailsCard(props: InstructionDetailsProps) {
const { url } = useCluster(); const { url } = useCluster();
try { try {
const parsed = coerce(props.ix.parsed, ParsedInfo); const parsed = create(props.ix.parsed, ParsedInfo);
switch (parsed.type) { switch (parsed.type) {
case "vote": case "vote":
@ -61,7 +61,7 @@ function renderDetails<T>(
parsed: ParsedInfo, parsed: ParsedInfo,
struct: Struct<T> struct: Struct<T>
) { ) {
const info = coerce(parsed.info, struct); const info = create(parsed.info, struct);
const attributes: JSX.Element[] = []; const attributes: JSX.Element[] = [];
for (let [key, value] of Object.entries(info)) { for (let [key, value] of Object.entries(info)) {

View File

@ -5,74 +5,74 @@ import {
nullable, nullable,
number, number,
optional, optional,
pick, type,
string, string,
StructType, Infer,
} from "superstruct"; } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type InitializeInfo = StructType<typeof InitializeInfo>; export type InitializeInfo = Infer<typeof InitializeInfo>;
export const InitializeInfo = pick({ export const InitializeInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
rentSysvar: Pubkey, rentSysvar: PublicKeyFromString,
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
node: Pubkey, node: PublicKeyFromString,
authorizedVoter: Pubkey, authorizedVoter: PublicKeyFromString,
authorizedWithdrawer: Pubkey, authorizedWithdrawer: PublicKeyFromString,
commission: number(), commission: number(),
}); });
export type AuthorizeInfo = StructType<typeof AuthorizeInfo>; export type AuthorizeInfo = Infer<typeof AuthorizeInfo>;
export const AuthorizeInfo = pick({ export const AuthorizeInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
authority: Pubkey, authority: PublicKeyFromString,
newAuthority: Pubkey, newAuthority: PublicKeyFromString,
authorityType: number(), authorityType: number(),
}); });
export type VoteInfo = StructType<typeof VoteInfo>; export type VoteInfo = Infer<typeof VoteInfo>;
export const VoteInfo = pick({ export const VoteInfo = type({
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
slotHashesSysvar: Pubkey, slotHashesSysvar: PublicKeyFromString,
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
voteAuthority: Pubkey, voteAuthority: PublicKeyFromString,
vote: pick({ vote: type({
hash: string(), hash: string(),
slots: array(number()), slots: array(number()),
timestamp: optional(nullable(number())), timestamp: optional(nullable(number())),
}), }),
}); });
export type WithdrawInfo = StructType<typeof WithdrawInfo>; export type WithdrawInfo = Infer<typeof WithdrawInfo>;
export const WithdrawInfo = pick({ export const WithdrawInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
destination: Pubkey, destination: PublicKeyFromString,
withdrawAuthority: Pubkey, withdrawAuthority: PublicKeyFromString,
lamports: number(), lamports: number(),
}); });
export type UpdateValidatorInfo = StructType<typeof UpdateValidatorInfo>; export type UpdateValidatorInfo = Infer<typeof UpdateValidatorInfo>;
export const UpdateValidatorInfo = pick({ export const UpdateValidatorInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
newValidatorIdentity: Pubkey, newValidatorIdentity: PublicKeyFromString,
withdrawAuthority: Pubkey, withdrawAuthority: PublicKeyFromString,
}); });
export type UpdateCommissionInfo = StructType<typeof UpdateCommissionInfo>; export type UpdateCommissionInfo = Infer<typeof UpdateCommissionInfo>;
export const UpdateCommissionInfo = pick({ export const UpdateCommissionInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
withdrawAuthority: Pubkey, withdrawAuthority: PublicKeyFromString,
commission: number(), commission: number(),
}); });
export type VoteSwitchInfo = StructType<typeof VoteSwitchInfo>; export type VoteSwitchInfo = Infer<typeof VoteSwitchInfo>;
export const VoteSwitchInfo = pick({ export const VoteSwitchInfo = type({
voteAccount: Pubkey, voteAccount: PublicKeyFromString,
slotHashesSysvar: Pubkey, slotHashesSysvar: PublicKeyFromString,
clockSysvar: Pubkey, clockSysvar: PublicKeyFromString,
voteAuthority: Pubkey, voteAuthority: PublicKeyFromString,
vote: pick({ vote: type({
hash: string(), hash: string(),
slots: array(number()), slots: array(number()),
timestamp: number(), timestamp: number(),

View File

@ -3,7 +3,7 @@ import { PublicKey, Connection, StakeActivationData } from "@solana/web3.js";
import { useCluster, Cluster } from "../cluster"; import { useCluster, Cluster } from "../cluster";
import { HistoryProvider } from "./history"; import { HistoryProvider } from "./history";
import { TokensProvider } from "./tokens"; import { TokensProvider } from "./tokens";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { StakeAccount } from "validators/accounts/stake"; import { StakeAccount } from "validators/accounts/stake";
import { import {
@ -151,7 +151,7 @@ async function fetchAccountInfo(
let data: ProgramData | undefined; let data: ProgramData | undefined;
if ("parsed" in result.data) { if ("parsed" in result.data) {
try { try {
const info = coerce(result.data.parsed, ParsedInfo); const info = create(result.data.parsed, ParsedInfo);
switch (result.data.program) { switch (result.data.program) {
case "bpf-upgradeable-loader": { case "bpf-upgradeable-loader": {
let programAccount: ProgramAccountInfo; let programAccount: ProgramAccountInfo;
@ -161,7 +161,7 @@ async function fetchAccountInfo(
break; break;
} }
const parsed = coerce(info, ProgramAccount); const parsed = create(info, ProgramAccount);
programAccount = parsed.info; programAccount = parsed.info;
const result = ( const result = (
await connection.getParsedAccountInfo(parsed.info.programData) await connection.getParsedAccountInfo(parsed.info.programData)
@ -171,8 +171,8 @@ async function fetchAccountInfo(
"parsed" in result.data && "parsed" in result.data &&
result.data.program === "bpf-upgradeable-loader" result.data.program === "bpf-upgradeable-loader"
) { ) {
const info = coerce(result.data.parsed, ParsedInfo); const info = create(result.data.parsed, ParsedInfo);
programData = coerce(info, ProgramDataAccount).info; programData = create(info, ProgramDataAccount).info;
} else { } else {
throw new Error( throw new Error(
`invalid program data account for program: ${pubkey.toBase58()}` `invalid program data account for program: ${pubkey.toBase58()}`
@ -188,7 +188,7 @@ async function fetchAccountInfo(
break; break;
} }
case "stake": { case "stake": {
const parsed = coerce(info, StakeAccount); const parsed = create(info, StakeAccount);
const isDelegated = parsed.type === "delegated"; const isDelegated = parsed.type === "delegated";
const activation = isDelegated const activation = isDelegated
? await connection.getStakeActivation(pubkey) ? await connection.getStakeActivation(pubkey)
@ -204,32 +204,32 @@ async function fetchAccountInfo(
case "vote": case "vote":
data = { data = {
program: result.data.program, program: result.data.program,
parsed: coerce(info, VoteAccount), parsed: create(info, VoteAccount),
}; };
break; break;
case "nonce": case "nonce":
data = { data = {
program: result.data.program, program: result.data.program,
parsed: coerce(info, NonceAccount), parsed: create(info, NonceAccount),
}; };
break; break;
case "sysvar": case "sysvar":
data = { data = {
program: result.data.program, program: result.data.program,
parsed: coerce(info, SysvarAccount), parsed: create(info, SysvarAccount),
}; };
break; break;
case "config": case "config":
data = { data = {
program: result.data.program, program: result.data.program,
parsed: coerce(info, ConfigAccount), parsed: create(info, ConfigAccount),
}; };
break; break;
case "spl-token": case "spl-token":
data = { data = {
program: result.data.program, program: result.data.program,
parsed: coerce(info, TokenAccount), parsed: create(info, TokenAccount),
}; };
break; break;
default: default:
@ -298,7 +298,7 @@ export function useMintAccountInfo(
return; return;
} }
return coerce(data.parsed.info, MintAccountInfo); return create(data.parsed.info, MintAccountInfo);
} catch (err) { } catch (err) {
reportError(err, { address }); reportError(err, { address });
} }
@ -318,7 +318,7 @@ export function useTokenAccountInfo(
return; return;
} }
return coerce(data.parsed.info, TokenAccountInfo); return create(data.parsed.info, TokenAccountInfo);
} catch (err) { } catch (err) {
reportError(err, { address }); reportError(err, { address });
} }

View File

@ -4,7 +4,7 @@ import * as Cache from "providers/cache";
import { ActionType, FetchStatus } from "providers/cache"; import { ActionType, FetchStatus } from "providers/cache";
import { TokenAccountInfo } from "validators/accounts/token"; import { TokenAccountInfo } from "validators/accounts/token";
import { useCluster, Cluster } from "../cluster"; import { useCluster, Cluster } from "../cluster";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
export type TokenInfoWithPubkey = { export type TokenInfoWithPubkey = {
@ -68,7 +68,7 @@ async function fetchAccountTokens(
data = { data = {
tokens: value.map((accountInfo) => { tokens: value.map((accountInfo) => {
const parsedInfo = accountInfo.account.data.parsed.info; const parsedInfo = accountInfo.account.data.parsed.info;
const info = coerce(parsedInfo, TokenAccountInfo); const info = create(parsedInfo, TokenAccountInfo);
return { info, pubkey: accountInfo.pubkey }; return { info, pubkey: accountInfo.pubkey };
}), }),
}; };

View File

@ -10,7 +10,7 @@ import {
} from "@solana/web3.js"; } from "@solana/web3.js";
import { TokenAccountInfo, TokenAccount } from "validators/accounts/token"; import { TokenAccountInfo, TokenAccount } from "validators/accounts/token";
import { ParsedInfo } from "validators"; import { ParsedInfo } from "validators";
import { coerce } from "superstruct"; import { create } from "superstruct";
import { reportError } from "utils/sentry"; import { reportError } from "utils/sentry";
type LargestAccounts = { type LargestAccounts = {
@ -81,7 +81,7 @@ async function fetchLargestAccounts(
) )
).value; ).value;
if (accountInfo && "parsed" in accountInfo.data) { if (accountInfo && "parsed" in accountInfo.data) {
const info = coerceParsedAccountInfo(accountInfo.data); const info = createParsedAccountInfo(accountInfo.data);
return { return {
...account, ...account,
owner: info.owner, owner: info.owner,
@ -144,13 +144,13 @@ export function useTokenLargestTokens(
return context.entries[address]; return context.entries[address];
} }
function coerceParsedAccountInfo( function createParsedAccountInfo(
parsedData: ParsedAccountData parsedData: ParsedAccountData
): TokenAccountInfo { ): TokenAccountInfo {
try { try {
const data = coerce(parsedData.parsed, ParsedInfo); const data = create(parsedData.parsed, ParsedInfo);
const parsed = coerce(data, TokenAccount); const parsed = create(data, TokenAccount);
return coerce(parsed.info, TokenAccountInfo); return create(parsed.info, TokenAccountInfo);
} catch (error) { } catch (error) {
throw error; throw error;
} }

View File

@ -1,11 +1,10 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { import {
StructType, Infer,
pick,
array, array,
boolean, boolean,
object, type,
number, number,
string, string,
record, record,
@ -13,44 +12,40 @@ import {
literal, literal,
} from "superstruct"; } from "superstruct";
export type StakeConfigInfo = StructType<typeof StakeConfigInfo>; export type StakeConfigInfo = Infer<typeof StakeConfigInfo>;
export const StakeConfigInfo = pick({ export const StakeConfigInfo = type({
warmupCooldownRate: number(), warmupCooldownRate: number(),
slashPenalty: number(), slashPenalty: number(),
}); });
export type ConfigKey = StructType<typeof ConfigKey>; export type ConfigKey = Infer<typeof ConfigKey>;
export const ConfigKey = pick({ export const ConfigKey = type({
pubkey: string(), pubkey: string(),
signer: boolean(), signer: boolean(),
}); });
export type ValidatorInfoConfigData = StructType< export type ValidatorInfoConfigData = Infer<typeof ValidatorInfoConfigData>;
typeof ValidatorInfoConfigData
>;
export const ValidatorInfoConfigData = record(string(), string()); export const ValidatorInfoConfigData = record(string(), string());
export type ValidatorInfoConfigInfo = StructType< export type ValidatorInfoConfigInfo = Infer<typeof ValidatorInfoConfigInfo>;
typeof ValidatorInfoConfigInfo export const ValidatorInfoConfigInfo = type({
>;
export const ValidatorInfoConfigInfo = pick({
keys: array(ConfigKey), keys: array(ConfigKey),
configData: ValidatorInfoConfigData, configData: ValidatorInfoConfigData,
}); });
export type ValidatorInfoAccount = StructType<typeof ValidatorInfoAccount>; export type ValidatorInfoAccount = Infer<typeof ValidatorInfoAccount>;
export const ValidatorInfoAccount = object({ export const ValidatorInfoAccount = type({
type: literal("validatorInfo"), type: literal("validatorInfo"),
info: ValidatorInfoConfigInfo, info: ValidatorInfoConfigInfo,
}); });
export type StakeConfigInfoAccount = StructType<typeof StakeConfigInfoAccount>; export type StakeConfigInfoAccount = Infer<typeof StakeConfigInfoAccount>;
export const StakeConfigInfoAccount = object({ export const StakeConfigInfoAccount = type({
type: literal("stakeConfig"), type: literal("stakeConfig"),
info: StakeConfigInfo, info: StakeConfigInfo,
}); });
export type ConfigAccount = StructType<typeof ConfigAccount>; export type ConfigAccount = Infer<typeof ConfigAccount>;
export const ConfigAccount = union([ export const ConfigAccount = union([
StakeConfigInfoAccount, StakeConfigInfoAccount,
ValidatorInfoAccount, ValidatorInfoAccount,

View File

@ -1,22 +1,22 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { StructType, object, string, enums, pick } from "superstruct"; import { Infer, string, enums, type } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type NonceAccountType = StructType<typeof NonceAccountType>; export type NonceAccountType = Infer<typeof NonceAccountType>;
export const NonceAccountType = enums(["uninitialized", "initialized"]); export const NonceAccountType = enums(["uninitialized", "initialized"]);
export type NonceAccountInfo = StructType<typeof NonceAccountInfo>; export type NonceAccountInfo = Infer<typeof NonceAccountInfo>;
export const NonceAccountInfo = pick({ export const NonceAccountInfo = type({
authority: Pubkey, authority: PublicKeyFromString,
blockhash: string(), blockhash: string(),
feeCalculator: pick({ feeCalculator: type({
lamportsPerSignature: string(), lamportsPerSignature: string(),
}), }),
}); });
export type NonceAccount = StructType<typeof NonceAccount>; export type NonceAccount = Infer<typeof NonceAccount>;
export const NonceAccount = object({ export const NonceAccount = type({
type: NonceAccountType, type: NonceAccountType,
info: NonceAccountInfo, info: NonceAccountInfo,
}); });

View File

@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { object, StructType, number, nullable, enums } from "superstruct"; import { Infer, number, nullable, enums, type } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
import { BigNum } from "validators/bignum"; import { BigNumFromString } from "validators/bignum";
export type StakeAccountType = StructType<typeof StakeAccountType>; export type StakeAccountType = Infer<typeof StakeAccountType>;
export const StakeAccountType = enums([ export const StakeAccountType = enums([
"uninitialized", "uninitialized",
"initialized", "initialized",
@ -12,30 +12,30 @@ export const StakeAccountType = enums([
"rewardsPool", "rewardsPool",
]); ]);
export type StakeMeta = StructType<typeof StakeMeta>; export type StakeMeta = Infer<typeof StakeMeta>;
export const StakeMeta = object({ export const StakeMeta = type({
rentExemptReserve: BigNum, rentExemptReserve: BigNumFromString,
authorized: object({ authorized: type({
staker: Pubkey, staker: PublicKeyFromString,
withdrawer: Pubkey, withdrawer: PublicKeyFromString,
}), }),
lockup: object({ lockup: type({
unixTimestamp: number(), unixTimestamp: number(),
epoch: number(), epoch: number(),
custodian: Pubkey, custodian: PublicKeyFromString,
}), }),
}); });
export type StakeAccountInfo = StructType<typeof StakeAccountInfo>; export type StakeAccountInfo = Infer<typeof StakeAccountInfo>;
export const StakeAccountInfo = object({ export const StakeAccountInfo = type({
meta: StakeMeta, meta: StakeMeta,
stake: nullable( stake: nullable(
object({ type({
delegation: object({ delegation: type({
voter: Pubkey, voter: PublicKeyFromString,
stake: BigNum, stake: BigNumFromString,
activationEpoch: BigNum, activationEpoch: BigNumFromString,
deactivationEpoch: BigNum, deactivationEpoch: BigNumFromString,
warmupCooldownRate: number(), warmupCooldownRate: number(),
}), }),
creditsObserved: number(), creditsObserved: number(),
@ -43,8 +43,8 @@ export const StakeAccountInfo = object({
), ),
}); });
export type StakeAccount = StructType<typeof StakeAccount>; export type StakeAccount = Infer<typeof StakeAccount>;
export const StakeAccount = object({ export const StakeAccount = type({
type: StakeAccountType, type: StakeAccountType,
info: StakeAccountInfo, info: StakeAccountInfo,
}); });

View File

@ -1,19 +1,18 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { import {
StructType, Infer,
enums, enums,
array, array,
number, number,
object, type,
boolean, boolean,
string, string,
pick,
literal, literal,
union, union,
} from "superstruct"; } from "superstruct";
export type SysvarAccountType = StructType<typeof SysvarAccountType>; export type SysvarAccountType = Infer<typeof SysvarAccountType>;
export const SysvarAccountType = enums([ export const SysvarAccountType = enums([
"clock", "clock",
"epochSchedule", "epochSchedule",
@ -26,22 +25,22 @@ export const SysvarAccountType = enums([
"stakeHistory", "stakeHistory",
]); ]);
export type ClockAccountInfo = StructType<typeof ClockAccountInfo>; export type ClockAccountInfo = Infer<typeof ClockAccountInfo>;
export const ClockAccountInfo = pick({ export const ClockAccountInfo = type({
slot: number(), slot: number(),
epoch: number(), epoch: number(),
leaderScheduleEpoch: number(), leaderScheduleEpoch: number(),
unixTimestamp: number(), unixTimestamp: number(),
}); });
export type SysvarClockAccount = StructType<typeof SysvarClockAccount>; export type SysvarClockAccount = Infer<typeof SysvarClockAccount>;
export const SysvarClockAccount = object({ export const SysvarClockAccount = type({
type: literal("clock"), type: literal("clock"),
info: ClockAccountInfo, info: ClockAccountInfo,
}); });
export type EpochScheduleInfo = StructType<typeof EpochScheduleInfo>; export type EpochScheduleInfo = Infer<typeof EpochScheduleInfo>;
export const EpochScheduleInfo = pick({ export const EpochScheduleInfo = type({
slotsPerEpoch: number(), slotsPerEpoch: number(),
leaderScheduleSlotOffset: number(), leaderScheduleSlotOffset: number(),
warmup: boolean(), warmup: boolean(),
@ -49,126 +48,120 @@ export const EpochScheduleInfo = pick({
firstNormalSlot: number(), firstNormalSlot: number(),
}); });
export type SysvarEpochScheduleAccount = StructType< export type SysvarEpochScheduleAccount = Infer<
typeof SysvarEpochScheduleAccount typeof SysvarEpochScheduleAccount
>; >;
export const SysvarEpochScheduleAccount = object({ export const SysvarEpochScheduleAccount = type({
type: literal("epochSchedule"), type: literal("epochSchedule"),
info: EpochScheduleInfo, info: EpochScheduleInfo,
}); });
export type FeesInfo = StructType<typeof FeesInfo>; export type FeesInfo = Infer<typeof FeesInfo>;
export const FeesInfo = pick({ export const FeesInfo = type({
feeCalculator: pick({ feeCalculator: type({
lamportsPerSignature: string(), lamportsPerSignature: string(),
}), }),
}); });
export type SysvarFeesAccount = StructType<typeof SysvarFeesAccount>; export type SysvarFeesAccount = Infer<typeof SysvarFeesAccount>;
export const SysvarFeesAccount = object({ export const SysvarFeesAccount = type({
type: literal("fees"), type: literal("fees"),
info: FeesInfo, info: FeesInfo,
}); });
export type RecentBlockhashesEntry = StructType<typeof RecentBlockhashesEntry>; export type RecentBlockhashesEntry = Infer<typeof RecentBlockhashesEntry>;
export const RecentBlockhashesEntry = pick({ export const RecentBlockhashesEntry = type({
blockhash: string(), blockhash: string(),
feeCalculator: pick({ feeCalculator: type({
lamportsPerSignature: string(), lamportsPerSignature: string(),
}), }),
}); });
export type RecentBlockhashesInfo = StructType<typeof RecentBlockhashesInfo>; export type RecentBlockhashesInfo = Infer<typeof RecentBlockhashesInfo>;
export const RecentBlockhashesInfo = array(RecentBlockhashesEntry); export const RecentBlockhashesInfo = array(RecentBlockhashesEntry);
export type SysvarRecentBlockhashesAccount = StructType< export type SysvarRecentBlockhashesAccount = Infer<
typeof SysvarRecentBlockhashesAccount typeof SysvarRecentBlockhashesAccount
>; >;
export const SysvarRecentBlockhashesAccount = object({ export const SysvarRecentBlockhashesAccount = type({
type: literal("recentBlockhashes"), type: literal("recentBlockhashes"),
info: RecentBlockhashesInfo, info: RecentBlockhashesInfo,
}); });
export type RentInfo = StructType<typeof RentInfo>; export type RentInfo = Infer<typeof RentInfo>;
export const RentInfo = pick({ export const RentInfo = type({
lamportsPerByteYear: string(), lamportsPerByteYear: string(),
exemptionThreshold: number(), exemptionThreshold: number(),
burnPercent: number(), burnPercent: number(),
}); });
export type SysvarRentAccount = StructType<typeof SysvarRentAccount>; export type SysvarRentAccount = Infer<typeof SysvarRentAccount>;
export const SysvarRentAccount = object({ export const SysvarRentAccount = type({
type: literal("rent"), type: literal("rent"),
info: RentInfo, info: RentInfo,
}); });
export type RewardsInfo = StructType<typeof RewardsInfo>; export type RewardsInfo = Infer<typeof RewardsInfo>;
export const RewardsInfo = pick({ export const RewardsInfo = type({
validatorPointValue: number(), validatorPointValue: number(),
}); });
export type SysvarRewardsAccount = StructType<typeof SysvarRewardsAccount>; export type SysvarRewardsAccount = Infer<typeof SysvarRewardsAccount>;
export const SysvarRewardsAccount = object({ export const SysvarRewardsAccount = type({
type: literal("rewards"), type: literal("rewards"),
info: RewardsInfo, info: RewardsInfo,
}); });
export type SlotHashEntry = StructType<typeof SlotHashEntry>; export type SlotHashEntry = Infer<typeof SlotHashEntry>;
export const SlotHashEntry = pick({ export const SlotHashEntry = type({
slot: number(), slot: number(),
hash: string(), hash: string(),
}); });
export type SlotHashesInfo = StructType<typeof SlotHashesInfo>; export type SlotHashesInfo = Infer<typeof SlotHashesInfo>;
export const SlotHashesInfo = array(SlotHashEntry); export const SlotHashesInfo = array(SlotHashEntry);
export type SysvarSlotHashesAccount = StructType< export type SysvarSlotHashesAccount = Infer<typeof SysvarSlotHashesAccount>;
typeof SysvarSlotHashesAccount export const SysvarSlotHashesAccount = type({
>;
export const SysvarSlotHashesAccount = object({
type: literal("slotHashes"), type: literal("slotHashes"),
info: SlotHashesInfo, info: SlotHashesInfo,
}); });
export type SlotHistoryInfo = StructType<typeof SlotHistoryInfo>; export type SlotHistoryInfo = Infer<typeof SlotHistoryInfo>;
export const SlotHistoryInfo = pick({ export const SlotHistoryInfo = type({
nextSlot: number(), nextSlot: number(),
bits: string(), bits: string(),
}); });
export type SysvarSlotHistoryAccount = StructType< export type SysvarSlotHistoryAccount = Infer<typeof SysvarSlotHistoryAccount>;
typeof SysvarSlotHistoryAccount export const SysvarSlotHistoryAccount = type({
>;
export const SysvarSlotHistoryAccount = object({
type: literal("slotHistory"), type: literal("slotHistory"),
info: SlotHistoryInfo, info: SlotHistoryInfo,
}); });
export type StakeHistoryEntryItem = StructType<typeof StakeHistoryEntryItem>; export type StakeHistoryEntryItem = Infer<typeof StakeHistoryEntryItem>;
export const StakeHistoryEntryItem = pick({ export const StakeHistoryEntryItem = type({
effective: number(), effective: number(),
activating: number(), activating: number(),
deactivating: number(), deactivating: number(),
}); });
export type StakeHistoryEntry = StructType<typeof StakeHistoryEntry>; export type StakeHistoryEntry = Infer<typeof StakeHistoryEntry>;
export const StakeHistoryEntry = pick({ export const StakeHistoryEntry = type({
epoch: number(), epoch: number(),
stakeHistory: StakeHistoryEntryItem, stakeHistory: StakeHistoryEntryItem,
}); });
export type StakeHistoryInfo = StructType<typeof StakeHistoryInfo>; export type StakeHistoryInfo = Infer<typeof StakeHistoryInfo>;
export const StakeHistoryInfo = array(StakeHistoryEntry); export const StakeHistoryInfo = array(StakeHistoryEntry);
export type SysvarStakeHistoryAccount = StructType< export type SysvarStakeHistoryAccount = Infer<typeof SysvarStakeHistoryAccount>;
typeof SysvarStakeHistoryAccount export const SysvarStakeHistoryAccount = type({
>;
export const SysvarStakeHistoryAccount = object({
type: literal("stakeHistory"), type: literal("stakeHistory"),
info: StakeHistoryInfo, info: StakeHistoryInfo,
}); });
export type SysvarAccount = StructType<typeof SysvarAccount>; export type SysvarAccount = Infer<typeof SysvarAccount>;
export const SysvarAccount = union([ export const SysvarAccount = union([
SysvarClockAccount, SysvarClockAccount,
SysvarEpochScheduleAccount, SysvarEpochScheduleAccount,

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { import {
StructType, Infer,
number, number,
optional, optional,
enums, enums,
@ -9,55 +9,55 @@ import {
boolean, boolean,
string, string,
array, array,
pick, type,
nullable, nullable,
} from "superstruct"; } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type TokenAccountType = StructType<typeof TokenAccountType>; export type TokenAccountType = Infer<typeof TokenAccountType>;
export const TokenAccountType = enums(["mint", "account", "multisig"]); export const TokenAccountType = enums(["mint", "account", "multisig"]);
export type TokenAccountState = StructType<typeof AccountState>; export type TokenAccountState = Infer<typeof AccountState>;
const AccountState = enums(["initialized", "uninitialized", "frozen"]); const AccountState = enums(["initialized", "uninitialized", "frozen"]);
const TokenAmount = pick({ const TokenAmount = type({
decimals: number(), decimals: number(),
uiAmountString: string(), uiAmountString: string(),
amount: string(), amount: string(),
}); });
export type TokenAccountInfo = StructType<typeof TokenAccountInfo>; export type TokenAccountInfo = Infer<typeof TokenAccountInfo>;
export const TokenAccountInfo = pick({ export const TokenAccountInfo = type({
mint: Pubkey, mint: PublicKeyFromString,
owner: Pubkey, owner: PublicKeyFromString,
tokenAmount: TokenAmount, tokenAmount: TokenAmount,
delegate: optional(Pubkey), delegate: optional(PublicKeyFromString),
state: AccountState, state: AccountState,
isNative: boolean(), isNative: boolean(),
rentExemptReserve: optional(TokenAmount), rentExemptReserve: optional(TokenAmount),
delegatedAmount: optional(TokenAmount), delegatedAmount: optional(TokenAmount),
closeAuthority: optional(Pubkey), closeAuthority: optional(PublicKeyFromString),
}); });
export type MintAccountInfo = StructType<typeof MintAccountInfo>; export type MintAccountInfo = Infer<typeof MintAccountInfo>;
export const MintAccountInfo = pick({ export const MintAccountInfo = type({
mintAuthority: nullable(Pubkey), mintAuthority: nullable(PublicKeyFromString),
supply: string(), supply: string(),
decimals: number(), decimals: number(),
isInitialized: boolean(), isInitialized: boolean(),
freezeAuthority: nullable(Pubkey), freezeAuthority: nullable(PublicKeyFromString),
}); });
export type MultisigAccountInfo = StructType<typeof MultisigAccountInfo>; export type MultisigAccountInfo = Infer<typeof MultisigAccountInfo>;
export const MultisigAccountInfo = pick({ export const MultisigAccountInfo = type({
numRequiredSigners: number(), numRequiredSigners: number(),
numValidSigners: number(), numValidSigners: number(),
isInitialized: boolean(), isInitialized: boolean(),
signers: array(Pubkey), signers: array(PublicKeyFromString),
}); });
export type TokenAccount = StructType<typeof TokenAccount>; export type TokenAccount = Infer<typeof TokenAccount>;
export const TokenAccount = pick({ export const TokenAccount = type({
type: TokenAccountType, type: TokenAccountType,
info: any(), info: any(),
}); });

View File

@ -1,28 +1,28 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { StructType, pick, number, nullable, literal } from "superstruct"; import { type, number, literal, nullable, Infer } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type ProgramAccountInfo = StructType<typeof ProgramAccountInfo>; export type ProgramAccountInfo = Infer<typeof ProgramAccountInfo>;
export const ProgramAccountInfo = pick({ export const ProgramAccountInfo = type({
programData: Pubkey, programData: PublicKeyFromString,
}); });
export type ProgramAccount = StructType<typeof ProgramDataAccount>; export type ProgramAccount = Infer<typeof ProgramDataAccount>;
export const ProgramAccount = pick({ export const ProgramAccount = type({
type: literal("program"), type: literal("program"),
info: ProgramAccountInfo, info: ProgramAccountInfo,
}); });
export type ProgramDataAccountInfo = StructType<typeof ProgramDataAccountInfo>; export type ProgramDataAccountInfo = Infer<typeof ProgramDataAccountInfo>;
export const ProgramDataAccountInfo = pick({ export const ProgramDataAccountInfo = type({
authority: nullable(Pubkey), authority: nullable(PublicKeyFromString),
// don't care about data yet // don't care about data yet
slot: number(), slot: number(),
}); });
export type ProgramDataAccount = StructType<typeof ProgramDataAccount>; export type ProgramDataAccount = Infer<typeof ProgramDataAccount>;
export const ProgramDataAccount = pick({ export const ProgramDataAccount = type({
type: literal("programData"), type: literal("programData"),
info: ProgramDataAccountInfo, info: ProgramDataAccountInfo,
}); });

View File

@ -1,64 +1,63 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { import {
StructType, Infer,
enums, enums,
pick,
number, number,
array, array,
object, type,
nullable, nullable,
string, string,
} from "superstruct"; } from "superstruct";
import { Pubkey } from "validators/pubkey"; import { PublicKeyFromString } from "validators/pubkey";
export type VoteAccountType = StructType<typeof VoteAccountType>; export type VoteAccountType = Infer<typeof VoteAccountType>;
export const VoteAccountType = enums(["vote"]); export const VoteAccountType = enums(["vote"]);
export type AuthorizedVoter = StructType<typeof AuthorizedVoter>; export type AuthorizedVoter = Infer<typeof AuthorizedVoter>;
export const AuthorizedVoter = pick({ export const AuthorizedVoter = type({
authorizedVoter: Pubkey, authorizedVoter: PublicKeyFromString,
epoch: number(), epoch: number(),
}); });
export type PriorVoter = StructType<typeof PriorVoter>; export type PriorVoter = Infer<typeof PriorVoter>;
export const PriorVoter = pick({ export const PriorVoter = type({
authorizedPubkey: Pubkey, authorizedPubkey: PublicKeyFromString,
epochOfLastAuthorizedSwitch: number(), epochOfLastAuthorizedSwitch: number(),
targetEpoch: number(), targetEpoch: number(),
}); });
export type EpochCredits = StructType<typeof EpochCredits>; export type EpochCredits = Infer<typeof EpochCredits>;
export const EpochCredits = pick({ export const EpochCredits = type({
epoch: number(), epoch: number(),
credits: string(), credits: string(),
previousCredits: string(), previousCredits: string(),
}); });
export type Vote = StructType<typeof Vote>; export type Vote = Infer<typeof Vote>;
export const Vote = object({ export const Vote = type({
slot: number(), slot: number(),
confirmationCount: number(), confirmationCount: number(),
}); });
export type VoteAccountInfo = StructType<typeof VoteAccountInfo>; export type VoteAccountInfo = Infer<typeof VoteAccountInfo>;
export const VoteAccountInfo = pick({ export const VoteAccountInfo = type({
authorizedVoters: array(AuthorizedVoter), authorizedVoters: array(AuthorizedVoter),
authorizedWithdrawer: Pubkey, authorizedWithdrawer: PublicKeyFromString,
commission: number(), commission: number(),
epochCredits: array(EpochCredits), epochCredits: array(EpochCredits),
lastTimestamp: object({ lastTimestamp: type({
slot: number(), slot: number(),
timestamp: number(), timestamp: number(),
}), }),
nodePubkey: Pubkey, nodePubkey: PublicKeyFromString,
priorVoters: array(PriorVoter), priorVoters: array(PriorVoter),
rootSlot: nullable(number()), rootSlot: nullable(number()),
votes: array(Vote), votes: array(Vote),
}); });
export type VoteAccount = StructType<typeof VoteAccount>; export type VoteAccount = Infer<typeof VoteAccount>;
export const VoteAccount = pick({ export const VoteAccount = type({
type: VoteAccountType, type: VoteAccountType,
info: VoteAccountInfo, info: VoteAccountInfo,
}); });

View File

@ -1,8 +1,7 @@
import { coercion, struct, Struct } from "superstruct"; import { coerce, instance, string } from "superstruct";
import BN from "bn.js"; import BN from "bn.js";
export const BigNumValue = struct("BigNum", (value) => value instanceof BN); export const BigNumFromString = coerce(instance(BN), string(), (value) => {
export const BigNum: Struct<BN, any> = coercion(BigNumValue, (value) => {
if (typeof value === "string") return new BN(value, 10); if (typeof value === "string") return new BN(value, 10);
throw new Error("invalid big num"); throw new Error("invalid big num");
}); });

View File

@ -1,9 +1,9 @@
/* eslint-disable @typescript-eslint/no-redeclare */ /* eslint-disable @typescript-eslint/no-redeclare */
import { object, any, StructType, string } from "superstruct"; import { type, any, Infer, string } from "superstruct";
export type ParsedInfo = StructType<typeof ParsedInfo>; export type ParsedInfo = Infer<typeof ParsedInfo>;
export const ParsedInfo = object({ export const ParsedInfo = type({
type: string(), type: string(),
info: any(), info: any(),
}); });

View File

@ -1,8 +1,8 @@
import { coercion, struct, Struct } from "superstruct"; import { coerce, instance, string } from "superstruct";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
const PubkeyValue = struct("Pubkey", (value) => value instanceof PublicKey); export const PublicKeyFromString = coerce(
export const Pubkey: Struct<PublicKey, any> = coercion(PubkeyValue, (value) => { instance(PublicKey),
if (typeof value === "string") return new PublicKey(value); string(),
throw new Error("invalid pubkey"); (value) => new PublicKey(value)
}); );