From 186b3424534a1a361216576ca26d6f16895d2dae Mon Sep 17 00:00:00 2001 From: Justin Starry Date: Sat, 13 Mar 2021 13:31:52 +0800 Subject: [PATCH] explorer: Update superstruct (#15835) --- explorer/package-lock.json | 5 +- explorer/package.json | 2 +- .../account/TokenAccountSection.tsx | 8 +- .../components/account/TokenHistoryCard.tsx | 6 +- .../bpf-loader/BpfLoaderDetailsCard.tsx | 8 +- .../instruction/bpf-loader/types.ts | 20 +- .../BpfUpgradeableLoaderDetailsCard.tsx | 6 +- .../bpf-upgradeable-loader/types.ts | 72 +++---- .../src/components/instruction/serum/types.ts | 54 ++--- .../instruction/stake/StakeDetailsCard.tsx | 18 +- .../src/components/instruction/stake/types.ts | 84 ++++---- .../instruction/system/SystemDetailsCard.tsx | 28 +-- .../components/instruction/system/types.ts | 120 ++++++----- .../instruction/token/TokenDetailsCard.tsx | 10 +- .../src/components/instruction/token/types.ts | 200 +++++++++--------- .../instruction/vote/VoteDetailsCard.tsx | 6 +- .../src/components/instruction/vote/types.ts | 90 ++++---- explorer/src/providers/accounts/index.tsx | 26 +-- explorer/src/providers/accounts/tokens.tsx | 4 +- explorer/src/providers/mints/largest.tsx | 12 +- explorer/src/validators/accounts/config.ts | 33 ++- explorer/src/validators/accounts/nonce.ts | 18 +- explorer/src/validators/accounts/stake.ts | 44 ++-- explorer/src/validators/accounts/sysvar.ts | 101 ++++----- explorer/src/validators/accounts/token.ts | 42 ++-- .../accounts/upgradeable-program.ts | 24 +-- explorer/src/validators/accounts/vote.ts | 43 ++-- explorer/src/validators/bignum.ts | 5 +- explorer/src/validators/index.ts | 6 +- explorer/src/validators/pubkey.ts | 12 +- 30 files changed, 544 insertions(+), 563 deletions(-) diff --git a/explorer/package-lock.json b/explorer/package-lock.json index d2fff8ae2b..029f0b69e8 100644 --- a/explorer/package-lock.json +++ b/explorer/package-lock.json @@ -17746,8 +17746,9 @@ "integrity": "sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA==" }, "superstruct": { - "version": "github:solana-labs/superstruct#3425dfd28967286ac9d1c78ce7b3c07c5781caee", - "from": "github:solana-labs/superstruct" + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" }, "supports-color": { "version": "5.5.0", diff --git a/explorer/package.json b/explorer/package.json index 5c78cebab7..4df3cfc70f 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -41,7 +41,7 @@ "react-router-dom": "^5.2.0", "react-scripts": "^4.0.3", "react-select": "^4.2.1", - "superstruct": "github:solana-labs/superstruct", + "superstruct": "^0.14.2", "typescript": "^4.2.3" }, "scripts": { diff --git a/explorer/src/components/account/TokenAccountSection.tsx b/explorer/src/components/account/TokenAccountSection.tsx index b634930f56..943dfef2eb 100644 --- a/explorer/src/components/account/TokenAccountSection.tsx +++ b/explorer/src/components/account/TokenAccountSection.tsx @@ -6,7 +6,7 @@ import { TokenAccountInfo, MultisigAccountInfo, } from "validators/accounts/token"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { TableCardBody } from "components/common/TableCardBody"; import { Address } from "components/common/Address"; import { UnknownAccountCard } from "./UnknownAccountCard"; @@ -27,15 +27,15 @@ export function TokenAccountSection({ try { switch (tokenAccount.type) { case "mint": { - const info = coerce(tokenAccount.info, MintAccountInfo); + const info = create(tokenAccount.info, MintAccountInfo); return ; } case "account": { - const info = coerce(tokenAccount.info, TokenAccountInfo); + const info = create(tokenAccount.info, TokenAccountInfo); return ; } case "multisig": { - const info = coerce(tokenAccount.info, MultisigAccountInfo); + const info = create(tokenAccount.info, MultisigAccountInfo); return ; } } diff --git a/explorer/src/components/account/TokenHistoryCard.tsx b/explorer/src/components/account/TokenHistoryCard.tsx index 4ab20e8823..681686a621 100644 --- a/explorer/src/components/account/TokenHistoryCard.tsx +++ b/explorer/src/components/account/TokenHistoryCard.tsx @@ -25,7 +25,7 @@ import { useFetchTransactionDetails, useTransactionDetailsCache, } from "providers/transactions/details"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { ParsedInfo } from "validators"; import { TokenInstructionType, @@ -366,9 +366,9 @@ function instructionTypeName( tx: ConfirmedSignatureInfo ): string { try { - const parsed = coerce(ix.parsed, ParsedInfo); + const parsed = create(ix.parsed, ParsedInfo); const { type: rawType } = parsed; - const type = coerce(rawType, TokenInstructionType); + const type = create(rawType, TokenInstructionType); return IX_TITLES[type]; } catch (err) { reportError(err, { signature: tx.signature }); diff --git a/explorer/src/components/instruction/bpf-loader/BpfLoaderDetailsCard.tsx b/explorer/src/components/instruction/bpf-loader/BpfLoaderDetailsCard.tsx index 2303eed6fa..fe140b367b 100644 --- a/explorer/src/components/instruction/bpf-loader/BpfLoaderDetailsCard.tsx +++ b/explorer/src/components/instruction/bpf-loader/BpfLoaderDetailsCard.tsx @@ -6,7 +6,7 @@ import { BPF_LOADER_PROGRAM_ID, } from "@solana/web3.js"; import { InstructionCard } from "../InstructionCard"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { ParsedInfo } from "validators"; import { WriteInfo, FinalizeInfo } from "./types"; import { reportError } from "utils/sentry"; @@ -25,15 +25,15 @@ type DetailsProps = { export function BpfLoaderDetailsCard(props: DetailsProps) { try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); switch (parsed.type) { case "write": { - const info = coerce(parsed.info, WriteInfo); + const info = create(parsed.info, WriteInfo); return ; } case "finalize": { - const info = coerce(parsed.info, FinalizeInfo); + const info = create(parsed.info, FinalizeInfo); return ; } default: diff --git a/explorer/src/components/instruction/bpf-loader/types.ts b/explorer/src/components/instruction/bpf-loader/types.ts index 19b406f936..1879f57466 100644 --- a/explorer/src/components/instruction/bpf-loader/types.ts +++ b/explorer/src/components/instruction/bpf-loader/types.ts @@ -1,21 +1,19 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { enums, number, pick, string, StructType } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { enums, number, type, string, Infer } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type WriteInfo = StructType; -export const WriteInfo = pick({ - account: Pubkey, +export type WriteInfo = Infer; +export const WriteInfo = type({ + account: PublicKeyFromString, bytes: string(), offset: number(), }); -export type FinalizeInfo = StructType; -export const FinalizeInfo = pick({ - account: Pubkey, +export type FinalizeInfo = Infer; +export const FinalizeInfo = type({ + account: PublicKeyFromString, }); -export type BpfLoaderInstructionType = StructType< - typeof BpfLoaderInstructionType ->; +export type BpfLoaderInstructionType = Infer; export const BpfLoaderInstructionType = enums(["write", "finalize"]); diff --git a/explorer/src/components/instruction/bpf-upgradeable-loader/BpfUpgradeableLoaderDetailsCard.tsx b/explorer/src/components/instruction/bpf-upgradeable-loader/BpfUpgradeableLoaderDetailsCard.tsx index 07695f243e..5c3ca288ef 100644 --- a/explorer/src/components/instruction/bpf-upgradeable-loader/BpfUpgradeableLoaderDetailsCard.tsx +++ b/explorer/src/components/instruction/bpf-upgradeable-loader/BpfUpgradeableLoaderDetailsCard.tsx @@ -6,7 +6,7 @@ import { PublicKey, } from "@solana/web3.js"; import { Address } from "components/common/Address"; -import { coerce, Struct } from "superstruct"; +import { create, Struct } from "superstruct"; import { camelToTitleCase } from "utils"; import { reportError } from "utils/sentry"; import { ParsedInfo } from "validators"; @@ -31,7 +31,7 @@ type DetailsProps = { export function BpfUpgradeableLoaderDetailsCard(props: DetailsProps) { try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); switch (parsed.type) { case "write": { return renderDetails(props, parsed, WriteInfo); @@ -72,7 +72,7 @@ function renderDetails( parsed: ParsedInfo, struct: Struct ) { - const info = coerce(parsed.info, struct); + const info = create(parsed.info, struct); const attributes: JSX.Element[] = []; for (let [key, value] of Object.entries(info)) { diff --git a/explorer/src/components/instruction/bpf-upgradeable-loader/types.ts b/explorer/src/components/instruction/bpf-upgradeable-loader/types.ts index 7f206dbc6f..51c780686a 100644 --- a/explorer/src/components/instruction/bpf-upgradeable-loader/types.ts +++ b/explorer/src/components/instruction/bpf-upgradeable-loader/types.ts @@ -1,56 +1,54 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { enums, nullable, number, pick, string, StructType } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { enums, nullable, number, type, string, Infer } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type WriteInfo = StructType; -export const WriteInfo = pick({ - account: Pubkey, - authority: Pubkey, +export type WriteInfo = Infer; +export const WriteInfo = type({ + account: PublicKeyFromString, + authority: PublicKeyFromString, bytes: string(), offset: number(), }); -export type InitializeBufferInfo = StructType; -export const InitializeBufferInfo = pick({ - account: Pubkey, - authority: Pubkey, +export type InitializeBufferInfo = Infer; +export const InitializeBufferInfo = type({ + account: PublicKeyFromString, + authority: PublicKeyFromString, }); -export type UpgradeInfo = StructType; -export const UpgradeInfo = pick({ - programDataAccount: Pubkey, - programAccount: Pubkey, - bufferAccount: Pubkey, - spillAccount: Pubkey, - authority: Pubkey, - rentSysvar: Pubkey, - clockSysvar: Pubkey, +export type UpgradeInfo = Infer; +export const UpgradeInfo = type({ + programDataAccount: PublicKeyFromString, + programAccount: PublicKeyFromString, + bufferAccount: PublicKeyFromString, + spillAccount: PublicKeyFromString, + authority: PublicKeyFromString, + rentSysvar: PublicKeyFromString, + clockSysvar: PublicKeyFromString, }); -export type SetAuthorityInfo = StructType; -export const SetAuthorityInfo = pick({ - account: Pubkey, - authority: Pubkey, - newAuthority: nullable(Pubkey), +export type SetAuthorityInfo = Infer; +export const SetAuthorityInfo = type({ + account: PublicKeyFromString, + authority: PublicKeyFromString, + newAuthority: nullable(PublicKeyFromString), }); -export type DeployWithMaxDataLenInfo = StructType< - typeof DeployWithMaxDataLenInfo ->; -export const DeployWithMaxDataLenInfo = pick({ - programDataAccount: Pubkey, - programAccount: Pubkey, - payerAccount: Pubkey, - bufferAccount: Pubkey, - authority: Pubkey, - rentSysvar: Pubkey, - clockSysvar: Pubkey, - systemProgram: Pubkey, +export type DeployWithMaxDataLenInfo = Infer; +export const DeployWithMaxDataLenInfo = type({ + programDataAccount: PublicKeyFromString, + programAccount: PublicKeyFromString, + payerAccount: PublicKeyFromString, + bufferAccount: PublicKeyFromString, + authority: PublicKeyFromString, + rentSysvar: PublicKeyFromString, + clockSysvar: PublicKeyFromString, + systemProgram: PublicKeyFromString, maxDataLen: number(), }); -export type UpgradeableBpfLoaderInstructionType = StructType< +export type UpgradeableBpfLoaderInstructionType = Infer< typeof UpgradeableBpfLoaderInstructionType >; export const UpgradeableBpfLoaderInstructionType = enums([ diff --git a/explorer/src/components/instruction/serum/types.ts b/explorer/src/components/instruction/serum/types.ts index 37723fc9a9..6232c9b6e5 100644 --- a/explorer/src/components/instruction/serum/types.ts +++ b/explorer/src/components/instruction/serum/types.ts @@ -3,9 +3,9 @@ import { decodeInstruction, MARKETS } from "@project-serum/serum"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import { coerce, enums, number, optional, pick, StructType } from "superstruct"; -import { BigNumValue } from "validators/bignum"; -import { Pubkey } from "validators/pubkey"; +import { enums, number, optional, type, Infer, create } from "superstruct"; +import { BigNumFromString } from "validators/bignum"; +import { PublicKeyFromString } from "validators/pubkey"; const SERUM_PROGRAM_IDS = [ "4ckmDgGdxQoPDLUkDT3vHgSAkzA3QRdNq5ywwY4sUSJn", @@ -14,10 +14,10 @@ const SERUM_PROGRAM_IDS = [ export const SERUM_DECODED_MAX = 6; -export type Side = StructType; +export type Side = Infer; export const Side = enums(["buy", "sell"]); -export type OrderType = StructType; +export type OrderType = Infer; export const OrderType = enums(["limit", "ioc", "postOnly"]); export type InitializeMarket = { @@ -38,18 +38,18 @@ export type InitializeMarket = { programId: PublicKey; }; -export const InitializeMarketDecode = pick({ - baseLotSize: BigNumValue, - quoteLotSize: BigNumValue, +export const InitializeMarketDecode = type({ + baseLotSize: BigNumFromString, + quoteLotSize: BigNumFromString, feeRateBps: number(), - quoteDustThreshold: BigNumValue, - vaultSignerNonce: BigNumValue, + quoteDustThreshold: BigNumFromString, + vaultSignerNonce: BigNumFromString, }); export function decodeInitializeMarket( ix: TransactionInstruction ): InitializeMarket { - const decoded = coerce( + const decoded = create( decodeInstruction(ix.data).initializeMarket, InitializeMarketDecode ); @@ -92,17 +92,17 @@ export type NewOrder = { clientId: BN; }; -export const NewOrderDecode = pick({ +export const NewOrderDecode = type({ side: Side, - limitPrice: BigNumValue, - maxQuantity: BigNumValue, + limitPrice: BigNumFromString, + maxQuantity: BigNumFromString, orderType: OrderType, - clientId: BigNumValue, - feeDiscountPubkey: optional(Pubkey), + clientId: BigNumFromString, + feeDiscountPubkey: optional(PublicKeyFromString), }); 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 = { market: ix.keys[0].pubkey, @@ -139,12 +139,12 @@ export type MatchOrders = { programId: PublicKey; }; -export const MatchOrdersDecode = pick({ +export const MatchOrdersDecode = type({ limit: number(), }); export function decodeMatchOrders(ix: TransactionInstruction): MatchOrders { - const decoded = coerce( + const decoded = create( decodeInstruction(ix.data).matchOrders, MatchOrdersDecode ); @@ -172,12 +172,12 @@ export type ConsumeEvents = { programId: PublicKey; }; -export const ConsumeEventsDecode = pick({ +export const ConsumeEventsDecode = type({ limit: number(), }); export function decodeConsumeEvents(ix: TransactionInstruction): ConsumeEvents { - const decoded = coerce( + const decoded = create( decodeInstruction(ix.data).consumeEvents, ConsumeEventsDecode ); @@ -204,14 +204,14 @@ export type CancelOrder = { programId: PublicKey; }; -export const CancelOrderDecode = pick({ +export const CancelOrderDecode = type({ side: Side, - orderId: BigNumValue, + orderId: BigNumFromString, openOrdersSlot: number(), }); export function decodeCancelOrder(ix: TransactionInstruction): CancelOrder { - const decoded = coerce( + const decoded = create( decodeInstruction(ix.data).cancelOrder, CancelOrderDecode ); @@ -239,14 +239,14 @@ export type CancelOrderByClientId = { programId: PublicKey; }; -export const CancelOrderByClientIdDecode = pick({ - clientId: BigNumValue, +export const CancelOrderByClientIdDecode = type({ + clientId: BigNumFromString, }); export function decodeCancelOrderByClientId( ix: TransactionInstruction ): CancelOrderByClientId { - const decoded = coerce( + const decoded = create( decodeInstruction(ix.data).cancelOrderByClientId, CancelOrderByClientIdDecode ); diff --git a/explorer/src/components/instruction/stake/StakeDetailsCard.tsx b/explorer/src/components/instruction/stake/StakeDetailsCard.tsx index a46a70b713..b49fef4097 100644 --- a/explorer/src/components/instruction/stake/StakeDetailsCard.tsx +++ b/explorer/src/components/instruction/stake/StakeDetailsCard.tsx @@ -14,7 +14,7 @@ import { WithdrawDetailsCard } from "./WithdrawDetailsCard"; import { DeactivateDetailsCard } from "./DeactivateDetailsCard"; import { ParsedInfo } from "validators"; import { reportError } from "utils/sentry"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { AuthorizeInfo, DeactivateInfo, @@ -37,35 +37,35 @@ type DetailsProps = { export function StakeDetailsCard(props: DetailsProps) { try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); switch (parsed.type) { case "initialize": { - const info = coerce(parsed.info, InitializeInfo); + const info = create(parsed.info, InitializeInfo); return ; } case "delegate": { - const info = coerce(parsed.info, DelegateInfo); + const info = create(parsed.info, DelegateInfo); return ; } case "authorize": { - const info = coerce(parsed.info, AuthorizeInfo); + const info = create(parsed.info, AuthorizeInfo); return ; } case "split": { - const info = coerce(parsed.info, SplitInfo); + const info = create(parsed.info, SplitInfo); return ; } case "withdraw": { - const info = coerce(parsed.info, WithdrawInfo); + const info = create(parsed.info, WithdrawInfo); return ; } case "deactivate": { - const info = coerce(parsed.info, DeactivateInfo); + const info = create(parsed.info, DeactivateInfo); return ; } case "merge": { - const info = coerce(parsed.info, MergeInfo); + const info = create(parsed.info, MergeInfo); return ; } default: diff --git a/explorer/src/components/instruction/stake/types.ts b/explorer/src/components/instruction/stake/types.ts index ced4c02f91..7ea4977885 100644 --- a/explorer/src/components/instruction/stake/types.ts +++ b/explorer/src/components/instruction/stake/types.ts @@ -1,69 +1,69 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { enums, number, pick, string, StructType } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { enums, number, type, string, Infer } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type InitializeInfo = StructType; -export const InitializeInfo = pick({ - stakeAccount: Pubkey, - authorized: pick({ - staker: Pubkey, - withdrawer: Pubkey, +export type InitializeInfo = Infer; +export const InitializeInfo = type({ + stakeAccount: PublicKeyFromString, + authorized: type({ + staker: PublicKeyFromString, + withdrawer: PublicKeyFromString, }), - lockup: pick({ + lockup: type({ unixTimestamp: number(), epoch: number(), - custodian: Pubkey, + custodian: PublicKeyFromString, }), }); -export type DelegateInfo = StructType; -export const DelegateInfo = pick({ - stakeAccount: Pubkey, - voteAccount: Pubkey, - stakeAuthority: Pubkey, +export type DelegateInfo = Infer; +export const DelegateInfo = type({ + stakeAccount: PublicKeyFromString, + voteAccount: PublicKeyFromString, + stakeAuthority: PublicKeyFromString, }); -export type AuthorizeInfo = StructType; -export const AuthorizeInfo = pick({ +export type AuthorizeInfo = Infer; +export const AuthorizeInfo = type({ authorityType: string(), - stakeAccount: Pubkey, - authority: Pubkey, - newAuthority: Pubkey, + stakeAccount: PublicKeyFromString, + authority: PublicKeyFromString, + newAuthority: PublicKeyFromString, }); -export type SplitInfo = StructType; -export const SplitInfo = pick({ - stakeAccount: Pubkey, - stakeAuthority: Pubkey, - newSplitAccount: Pubkey, +export type SplitInfo = Infer; +export const SplitInfo = type({ + stakeAccount: PublicKeyFromString, + stakeAuthority: PublicKeyFromString, + newSplitAccount: PublicKeyFromString, lamports: number(), }); -export type WithdrawInfo = StructType; -export const WithdrawInfo = pick({ - stakeAccount: Pubkey, - withdrawAuthority: Pubkey, - destination: Pubkey, +export type WithdrawInfo = Infer; +export const WithdrawInfo = type({ + stakeAccount: PublicKeyFromString, + withdrawAuthority: PublicKeyFromString, + destination: PublicKeyFromString, lamports: number(), }); -export type DeactivateInfo = StructType; -export const DeactivateInfo = pick({ - stakeAccount: Pubkey, - stakeAuthority: Pubkey, +export type DeactivateInfo = Infer; +export const DeactivateInfo = type({ + stakeAccount: PublicKeyFromString, + stakeAuthority: PublicKeyFromString, }); -export type MergeInfo = StructType; -export const MergeInfo = pick({ - source: Pubkey, - destination: Pubkey, - stakeAuthority: Pubkey, - stakeHistorySysvar: Pubkey, - clockSysvar: Pubkey, +export type MergeInfo = Infer; +export const MergeInfo = type({ + source: PublicKeyFromString, + destination: PublicKeyFromString, + stakeAuthority: PublicKeyFromString, + stakeHistorySysvar: PublicKeyFromString, + clockSysvar: PublicKeyFromString, }); -export type StakeInstructionType = StructType; +export type StakeInstructionType = Infer; export const StakeInstructionType = enums([ "initialize", "delegate", diff --git a/explorer/src/components/instruction/system/SystemDetailsCard.tsx b/explorer/src/components/instruction/system/SystemDetailsCard.tsx index 12b0d1a3bc..aa508159e3 100644 --- a/explorer/src/components/instruction/system/SystemDetailsCard.tsx +++ b/explorer/src/components/instruction/system/SystemDetailsCard.tsx @@ -19,7 +19,7 @@ import { NonceWithdrawDetailsCard } from "./NonceWithdrawDetailsCard"; import { NonceAuthorizeDetailsCard } from "./NonceAuthorizeDetailsCard"; import { TransferWithSeedDetailsCard } from "./TransferWithSeedDetailsCard"; import { ParsedInfo } from "validators"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { reportError } from "utils/sentry"; import { CreateAccountInfo, @@ -47,54 +47,54 @@ type DetailsProps = { export function SystemDetailsCard(props: DetailsProps) { try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); switch (parsed.type) { case "createAccount": { - const info = coerce(parsed.info, CreateAccountInfo); + const info = create(parsed.info, CreateAccountInfo); return ; } case "createAccountWithSeed": { - const info = coerce(parsed.info, CreateAccountWithSeedInfo); + const info = create(parsed.info, CreateAccountWithSeedInfo); return ; } case "allocate": { - const info = coerce(parsed.info, AllocateInfo); + const info = create(parsed.info, AllocateInfo); return ; } case "allocateWithSeed": { - const info = coerce(parsed.info, AllocateWithSeedInfo); + const info = create(parsed.info, AllocateWithSeedInfo); return ; } case "assign": { - const info = coerce(parsed.info, AssignInfo); + const info = create(parsed.info, AssignInfo); return ; } case "assignWithSeed": { - const info = coerce(parsed.info, AssignWithSeedInfo); + const info = create(parsed.info, AssignWithSeedInfo); return ; } case "transfer": { - const info = coerce(parsed.info, TransferInfo); + const info = create(parsed.info, TransferInfo); return ; } case "advanceNonce": { - const info = coerce(parsed.info, AdvanceNonceInfo); + const info = create(parsed.info, AdvanceNonceInfo); return ; } case "withdrawNonce": { - const info = coerce(parsed.info, WithdrawNonceInfo); + const info = create(parsed.info, WithdrawNonceInfo); return ; } case "authorizeNonce": { - const info = coerce(parsed.info, AuthorizeNonceInfo); + const info = create(parsed.info, AuthorizeNonceInfo); return ; } case "initializeNonce": { - const info = coerce(parsed.info, InitializeNonceInfo); + const info = create(parsed.info, InitializeNonceInfo); return ; } case "transferWithSeed": { - const info = coerce(parsed.info, TransferWithSeedInfo); + const info = create(parsed.info, TransferWithSeedInfo); return ; } default: diff --git a/explorer/src/components/instruction/system/types.ts b/explorer/src/components/instruction/system/types.ts index ee34f5a31e..e503630351 100644 --- a/explorer/src/components/instruction/system/types.ts +++ b/explorer/src/components/instruction/system/types.ts @@ -1,104 +1,102 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { enums, number, pick, string, StructType } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { enums, number, type, string, Infer } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type CreateAccountInfo = StructType; -export const CreateAccountInfo = pick({ - source: Pubkey, - newAccount: Pubkey, +export type CreateAccountInfo = Infer; +export const CreateAccountInfo = type({ + source: PublicKeyFromString, + newAccount: PublicKeyFromString, lamports: number(), space: number(), - owner: Pubkey, + owner: PublicKeyFromString, }); -export type AssignInfo = StructType; -export const AssignInfo = pick({ - account: Pubkey, - owner: Pubkey, +export type AssignInfo = Infer; +export const AssignInfo = type({ + account: PublicKeyFromString, + owner: PublicKeyFromString, }); -export type TransferInfo = StructType; -export const TransferInfo = pick({ - source: Pubkey, - destination: Pubkey, +export type TransferInfo = Infer; +export const TransferInfo = type({ + source: PublicKeyFromString, + destination: PublicKeyFromString, lamports: number(), }); -export type CreateAccountWithSeedInfo = StructType< - typeof CreateAccountWithSeedInfo ->; -export const CreateAccountWithSeedInfo = pick({ - source: Pubkey, - newAccount: Pubkey, - base: Pubkey, +export type CreateAccountWithSeedInfo = Infer; +export const CreateAccountWithSeedInfo = type({ + source: PublicKeyFromString, + newAccount: PublicKeyFromString, + base: PublicKeyFromString, seed: string(), lamports: number(), space: number(), - owner: Pubkey, + owner: PublicKeyFromString, }); -export type AdvanceNonceInfo = StructType; -export const AdvanceNonceInfo = pick({ - nonceAccount: Pubkey, - nonceAuthority: Pubkey, +export type AdvanceNonceInfo = Infer; +export const AdvanceNonceInfo = type({ + nonceAccount: PublicKeyFromString, + nonceAuthority: PublicKeyFromString, }); -export type WithdrawNonceInfo = StructType; -export const WithdrawNonceInfo = pick({ - nonceAccount: Pubkey, - destination: Pubkey, - nonceAuthority: Pubkey, +export type WithdrawNonceInfo = Infer; +export const WithdrawNonceInfo = type({ + nonceAccount: PublicKeyFromString, + destination: PublicKeyFromString, + nonceAuthority: PublicKeyFromString, lamports: number(), }); -export type InitializeNonceInfo = StructType; -export const InitializeNonceInfo = pick({ - nonceAccount: Pubkey, - nonceAuthority: Pubkey, +export type InitializeNonceInfo = Infer; +export const InitializeNonceInfo = type({ + nonceAccount: PublicKeyFromString, + nonceAuthority: PublicKeyFromString, }); -export type AuthorizeNonceInfo = StructType; -export const AuthorizeNonceInfo = pick({ - nonceAccount: Pubkey, - nonceAuthority: Pubkey, - newAuthorized: Pubkey, +export type AuthorizeNonceInfo = Infer; +export const AuthorizeNonceInfo = type({ + nonceAccount: PublicKeyFromString, + nonceAuthority: PublicKeyFromString, + newAuthorized: PublicKeyFromString, }); -export type AllocateInfo = StructType; -export const AllocateInfo = pick({ - account: Pubkey, +export type AllocateInfo = Infer; +export const AllocateInfo = type({ + account: PublicKeyFromString, space: number(), }); -export type AllocateWithSeedInfo = StructType; -export const AllocateWithSeedInfo = pick({ - account: Pubkey, - base: Pubkey, +export type AllocateWithSeedInfo = Infer; +export const AllocateWithSeedInfo = type({ + account: PublicKeyFromString, + base: PublicKeyFromString, seed: string(), space: number(), - owner: Pubkey, + owner: PublicKeyFromString, }); -export type AssignWithSeedInfo = StructType; -export const AssignWithSeedInfo = pick({ - account: Pubkey, - base: Pubkey, +export type AssignWithSeedInfo = Infer; +export const AssignWithSeedInfo = type({ + account: PublicKeyFromString, + base: PublicKeyFromString, seed: string(), - owner: Pubkey, + owner: PublicKeyFromString, }); -export type TransferWithSeedInfo = StructType; -export const TransferWithSeedInfo = pick({ - source: Pubkey, - sourceBase: Pubkey, - destination: Pubkey, +export type TransferWithSeedInfo = Infer; +export const TransferWithSeedInfo = type({ + source: PublicKeyFromString, + sourceBase: PublicKeyFromString, + destination: PublicKeyFromString, lamports: number(), sourceSeed: string(), - sourceOwner: Pubkey, + sourceOwner: PublicKeyFromString, }); -export type SystemInstructionType = StructType; +export type SystemInstructionType = Infer; export const SystemInstructionType = enums([ "createAccount", "createAccountWithSeed", diff --git a/explorer/src/components/instruction/token/TokenDetailsCard.tsx b/explorer/src/components/instruction/token/TokenDetailsCard.tsx index 2fb2575afb..2fba9491f2 100644 --- a/explorer/src/components/instruction/token/TokenDetailsCard.tsx +++ b/explorer/src/components/instruction/token/TokenDetailsCard.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { SignatureResult, ParsedTransaction, @@ -37,12 +37,12 @@ type DetailsProps = { export function TokenDetailsCard(props: DetailsProps) { try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); const { type: rawType, info } = parsed; - const type = coerce(rawType, TokenInstructionType); + const type = create(rawType, TokenInstructionType); const title = `Token: ${IX_TITLES[type]}`; - const coerced = coerce(info, IX_STRUCTS[type] as any); - return ; + const created = create(info, IX_STRUCTS[type] as any); + return ; } catch (err) { reportError(err, { signature: props.tx.signatures[0], diff --git a/explorer/src/components/instruction/token/types.ts b/explorer/src/components/instruction/token/types.ts index e76fee9c4d..9b0851fd2a 100644 --- a/explorer/src/components/instruction/token/types.ts +++ b/explorer/src/components/instruction/token/types.ts @@ -2,8 +2,8 @@ import { enums, - pick, - StructType, + type, + Infer, number, string, optional, @@ -11,60 +11,60 @@ import { nullable, union, } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { PublicKeyFromString } from "validators/pubkey"; -export type TokenAmountUi = StructType; -export const TokenAmountUi = pick({ +export type TokenAmountUi = Infer; +export const TokenAmountUi = type({ amount: string(), decimals: number(), uiAmountString: string(), }); -const InitializeMint = pick({ - mint: Pubkey, +const InitializeMint = type({ + mint: PublicKeyFromString, decimals: number(), - mintAuthority: Pubkey, - rentSysvar: Pubkey, - freezeAuthority: optional(Pubkey), + mintAuthority: PublicKeyFromString, + rentSysvar: PublicKeyFromString, + freezeAuthority: optional(PublicKeyFromString), }); -const InitializeAccount = pick({ - account: Pubkey, - mint: Pubkey, - owner: Pubkey, - rentSysvar: Pubkey, +const InitializeAccount = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, + owner: PublicKeyFromString, + rentSysvar: PublicKeyFromString, }); -const InitializeMultisig = pick({ - multisig: Pubkey, - rentSysvar: Pubkey, - signers: array(Pubkey), +const InitializeMultisig = type({ + multisig: PublicKeyFromString, + rentSysvar: PublicKeyFromString, + signers: array(PublicKeyFromString), m: number(), }); -const Transfer = pick({ - source: Pubkey, - destination: Pubkey, +const Transfer = type({ + source: PublicKeyFromString, + destination: PublicKeyFromString, amount: union([string(), number()]), - authority: optional(Pubkey), - multisigAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), + authority: optional(PublicKeyFromString), + multisigAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const Approve = pick({ - source: Pubkey, - delegate: Pubkey, +const Approve = type({ + source: PublicKeyFromString, + delegate: PublicKeyFromString, amount: union([string(), number()]), - owner: optional(Pubkey), - multisigOwner: optional(Pubkey), - signers: optional(array(Pubkey)), + owner: optional(PublicKeyFromString), + multisigOwner: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const Revoke = pick({ - source: Pubkey, - owner: optional(Pubkey), - multisigOwner: optional(Pubkey), - signers: optional(array(Pubkey)), +const Revoke = type({ + source: PublicKeyFromString, + owner: optional(PublicKeyFromString), + multisigOwner: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); const AuthorityType = enums([ @@ -74,97 +74,97 @@ const AuthorityType = enums([ "closeAccount", ]); -const SetAuthority = pick({ - mint: optional(Pubkey), - account: optional(Pubkey), +const SetAuthority = type({ + mint: optional(PublicKeyFromString), + account: optional(PublicKeyFromString), authorityType: AuthorityType, - newAuthority: nullable(Pubkey), - authority: optional(Pubkey), - multisigAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), + newAuthority: nullable(PublicKeyFromString), + authority: optional(PublicKeyFromString), + multisigAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const MintTo = pick({ - mint: Pubkey, - account: Pubkey, +const MintTo = type({ + mint: PublicKeyFromString, + account: PublicKeyFromString, amount: union([string(), number()]), - mintAuthority: optional(Pubkey), - multisigMintAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), + mintAuthority: optional(PublicKeyFromString), + multisigMintAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const Burn = pick({ - account: Pubkey, - mint: Pubkey, +const Burn = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, amount: union([string(), number()]), - authority: optional(Pubkey), - multisigAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), + authority: optional(PublicKeyFromString), + multisigAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const CloseAccount = pick({ - account: Pubkey, - destination: Pubkey, - owner: optional(Pubkey), - multisigOwner: optional(Pubkey), - signers: optional(array(Pubkey)), +const CloseAccount = type({ + account: PublicKeyFromString, + destination: PublicKeyFromString, + owner: optional(PublicKeyFromString), + multisigOwner: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const FreezeAccount = pick({ - account: Pubkey, - mint: Pubkey, - freezeAuthority: optional(Pubkey), - multisigFreezeAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), +const FreezeAccount = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, + freezeAuthority: optional(PublicKeyFromString), + multisigFreezeAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const ThawAccount = pick({ - account: Pubkey, - mint: Pubkey, - freezeAuthority: optional(Pubkey), - multisigFreezeAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), +const ThawAccount = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, + freezeAuthority: optional(PublicKeyFromString), + multisigFreezeAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), }); -const TransferChecked = pick({ - source: Pubkey, - mint: Pubkey, - destination: Pubkey, - authority: optional(Pubkey), - multisigAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), +const TransferChecked = type({ + source: PublicKeyFromString, + mint: PublicKeyFromString, + destination: PublicKeyFromString, + authority: optional(PublicKeyFromString), + multisigAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), tokenAmount: TokenAmountUi, }); -const ApproveChecked = pick({ - source: Pubkey, - mint: Pubkey, - delegate: Pubkey, - owner: optional(Pubkey), - multisigOwner: optional(Pubkey), - signers: optional(array(Pubkey)), +const ApproveChecked = type({ + source: PublicKeyFromString, + mint: PublicKeyFromString, + delegate: PublicKeyFromString, + owner: optional(PublicKeyFromString), + multisigOwner: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), tokenAmount: TokenAmountUi, }); -const MintToChecked = pick({ - account: Pubkey, - mint: Pubkey, - mintAuthority: optional(Pubkey), - multisigMintAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), +const MintToChecked = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, + mintAuthority: optional(PublicKeyFromString), + multisigMintAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), tokenAmount: TokenAmountUi, }); -const BurnChecked = pick({ - account: Pubkey, - mint: Pubkey, - authority: optional(Pubkey), - multisigAuthority: optional(Pubkey), - signers: optional(array(Pubkey)), +const BurnChecked = type({ + account: PublicKeyFromString, + mint: PublicKeyFromString, + authority: optional(PublicKeyFromString), + multisigAuthority: optional(PublicKeyFromString), + signers: optional(array(PublicKeyFromString)), tokenAmount: TokenAmountUi, }); -export type TokenInstructionType = StructType; +export type TokenInstructionType = Infer; export const TokenInstructionType = enums([ "initializeMint", "initializeAccount", diff --git a/explorer/src/components/instruction/vote/VoteDetailsCard.tsx b/explorer/src/components/instruction/vote/VoteDetailsCard.tsx index c4bdf2d8e0..41c149df70 100644 --- a/explorer/src/components/instruction/vote/VoteDetailsCard.tsx +++ b/explorer/src/components/instruction/vote/VoteDetailsCard.tsx @@ -1,6 +1,6 @@ import React from "react"; import { PublicKey } from "@solana/web3.js"; -import { coerce, Struct } from "superstruct"; +import { create, Struct } from "superstruct"; import { ParsedInfo } from "validators"; import { UpdateCommissionInfo, @@ -23,7 +23,7 @@ export function VoteDetailsCard(props: InstructionDetailsProps) { const { url } = useCluster(); try { - const parsed = coerce(props.ix.parsed, ParsedInfo); + const parsed = create(props.ix.parsed, ParsedInfo); switch (parsed.type) { case "vote": @@ -61,7 +61,7 @@ function renderDetails( parsed: ParsedInfo, struct: Struct ) { - const info = coerce(parsed.info, struct); + const info = create(parsed.info, struct); const attributes: JSX.Element[] = []; for (let [key, value] of Object.entries(info)) { diff --git a/explorer/src/components/instruction/vote/types.ts b/explorer/src/components/instruction/vote/types.ts index d31669db70..01da2b6456 100644 --- a/explorer/src/components/instruction/vote/types.ts +++ b/explorer/src/components/instruction/vote/types.ts @@ -5,74 +5,74 @@ import { nullable, number, optional, - pick, + type, string, - StructType, + Infer, } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { PublicKeyFromString } from "validators/pubkey"; -export type InitializeInfo = StructType; -export const InitializeInfo = pick({ - voteAccount: Pubkey, - rentSysvar: Pubkey, - clockSysvar: Pubkey, - node: Pubkey, - authorizedVoter: Pubkey, - authorizedWithdrawer: Pubkey, +export type InitializeInfo = Infer; +export const InitializeInfo = type({ + voteAccount: PublicKeyFromString, + rentSysvar: PublicKeyFromString, + clockSysvar: PublicKeyFromString, + node: PublicKeyFromString, + authorizedVoter: PublicKeyFromString, + authorizedWithdrawer: PublicKeyFromString, commission: number(), }); -export type AuthorizeInfo = StructType; -export const AuthorizeInfo = pick({ - voteAccount: Pubkey, - clockSysvar: Pubkey, - authority: Pubkey, - newAuthority: Pubkey, +export type AuthorizeInfo = Infer; +export const AuthorizeInfo = type({ + voteAccount: PublicKeyFromString, + clockSysvar: PublicKeyFromString, + authority: PublicKeyFromString, + newAuthority: PublicKeyFromString, authorityType: number(), }); -export type VoteInfo = StructType; -export const VoteInfo = pick({ - clockSysvar: Pubkey, - slotHashesSysvar: Pubkey, - voteAccount: Pubkey, - voteAuthority: Pubkey, - vote: pick({ +export type VoteInfo = Infer; +export const VoteInfo = type({ + clockSysvar: PublicKeyFromString, + slotHashesSysvar: PublicKeyFromString, + voteAccount: PublicKeyFromString, + voteAuthority: PublicKeyFromString, + vote: type({ hash: string(), slots: array(number()), timestamp: optional(nullable(number())), }), }); -export type WithdrawInfo = StructType; -export const WithdrawInfo = pick({ - voteAccount: Pubkey, - destination: Pubkey, - withdrawAuthority: Pubkey, +export type WithdrawInfo = Infer; +export const WithdrawInfo = type({ + voteAccount: PublicKeyFromString, + destination: PublicKeyFromString, + withdrawAuthority: PublicKeyFromString, lamports: number(), }); -export type UpdateValidatorInfo = StructType; -export const UpdateValidatorInfo = pick({ - voteAccount: Pubkey, - newValidatorIdentity: Pubkey, - withdrawAuthority: Pubkey, +export type UpdateValidatorInfo = Infer; +export const UpdateValidatorInfo = type({ + voteAccount: PublicKeyFromString, + newValidatorIdentity: PublicKeyFromString, + withdrawAuthority: PublicKeyFromString, }); -export type UpdateCommissionInfo = StructType; -export const UpdateCommissionInfo = pick({ - voteAccount: Pubkey, - withdrawAuthority: Pubkey, +export type UpdateCommissionInfo = Infer; +export const UpdateCommissionInfo = type({ + voteAccount: PublicKeyFromString, + withdrawAuthority: PublicKeyFromString, commission: number(), }); -export type VoteSwitchInfo = StructType; -export const VoteSwitchInfo = pick({ - voteAccount: Pubkey, - slotHashesSysvar: Pubkey, - clockSysvar: Pubkey, - voteAuthority: Pubkey, - vote: pick({ +export type VoteSwitchInfo = Infer; +export const VoteSwitchInfo = type({ + voteAccount: PublicKeyFromString, + slotHashesSysvar: PublicKeyFromString, + clockSysvar: PublicKeyFromString, + voteAuthority: PublicKeyFromString, + vote: type({ hash: string(), slots: array(number()), timestamp: number(), diff --git a/explorer/src/providers/accounts/index.tsx b/explorer/src/providers/accounts/index.tsx index b3112faf9a..648a76c0a1 100644 --- a/explorer/src/providers/accounts/index.tsx +++ b/explorer/src/providers/accounts/index.tsx @@ -3,7 +3,7 @@ import { PublicKey, Connection, StakeActivationData } from "@solana/web3.js"; import { useCluster, Cluster } from "../cluster"; import { HistoryProvider } from "./history"; import { TokensProvider } from "./tokens"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { ParsedInfo } from "validators"; import { StakeAccount } from "validators/accounts/stake"; import { @@ -151,7 +151,7 @@ async function fetchAccountInfo( let data: ProgramData | undefined; if ("parsed" in result.data) { try { - const info = coerce(result.data.parsed, ParsedInfo); + const info = create(result.data.parsed, ParsedInfo); switch (result.data.program) { case "bpf-upgradeable-loader": { let programAccount: ProgramAccountInfo; @@ -161,7 +161,7 @@ async function fetchAccountInfo( break; } - const parsed = coerce(info, ProgramAccount); + const parsed = create(info, ProgramAccount); programAccount = parsed.info; const result = ( await connection.getParsedAccountInfo(parsed.info.programData) @@ -171,8 +171,8 @@ async function fetchAccountInfo( "parsed" in result.data && result.data.program === "bpf-upgradeable-loader" ) { - const info = coerce(result.data.parsed, ParsedInfo); - programData = coerce(info, ProgramDataAccount).info; + const info = create(result.data.parsed, ParsedInfo); + programData = create(info, ProgramDataAccount).info; } else { throw new Error( `invalid program data account for program: ${pubkey.toBase58()}` @@ -188,7 +188,7 @@ async function fetchAccountInfo( break; } case "stake": { - const parsed = coerce(info, StakeAccount); + const parsed = create(info, StakeAccount); const isDelegated = parsed.type === "delegated"; const activation = isDelegated ? await connection.getStakeActivation(pubkey) @@ -204,32 +204,32 @@ async function fetchAccountInfo( case "vote": data = { program: result.data.program, - parsed: coerce(info, VoteAccount), + parsed: create(info, VoteAccount), }; break; case "nonce": data = { program: result.data.program, - parsed: coerce(info, NonceAccount), + parsed: create(info, NonceAccount), }; break; case "sysvar": data = { program: result.data.program, - parsed: coerce(info, SysvarAccount), + parsed: create(info, SysvarAccount), }; break; case "config": data = { program: result.data.program, - parsed: coerce(info, ConfigAccount), + parsed: create(info, ConfigAccount), }; break; case "spl-token": data = { program: result.data.program, - parsed: coerce(info, TokenAccount), + parsed: create(info, TokenAccount), }; break; default: @@ -298,7 +298,7 @@ export function useMintAccountInfo( return; } - return coerce(data.parsed.info, MintAccountInfo); + return create(data.parsed.info, MintAccountInfo); } catch (err) { reportError(err, { address }); } @@ -318,7 +318,7 @@ export function useTokenAccountInfo( return; } - return coerce(data.parsed.info, TokenAccountInfo); + return create(data.parsed.info, TokenAccountInfo); } catch (err) { reportError(err, { address }); } diff --git a/explorer/src/providers/accounts/tokens.tsx b/explorer/src/providers/accounts/tokens.tsx index d25b87ebfe..2c07252eb1 100644 --- a/explorer/src/providers/accounts/tokens.tsx +++ b/explorer/src/providers/accounts/tokens.tsx @@ -4,7 +4,7 @@ import * as Cache from "providers/cache"; import { ActionType, FetchStatus } from "providers/cache"; import { TokenAccountInfo } from "validators/accounts/token"; import { useCluster, Cluster } from "../cluster"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { reportError } from "utils/sentry"; export type TokenInfoWithPubkey = { @@ -68,7 +68,7 @@ async function fetchAccountTokens( data = { tokens: value.map((accountInfo) => { const parsedInfo = accountInfo.account.data.parsed.info; - const info = coerce(parsedInfo, TokenAccountInfo); + const info = create(parsedInfo, TokenAccountInfo); return { info, pubkey: accountInfo.pubkey }; }), }; diff --git a/explorer/src/providers/mints/largest.tsx b/explorer/src/providers/mints/largest.tsx index 2ef8f875cc..11ef7ffe5c 100644 --- a/explorer/src/providers/mints/largest.tsx +++ b/explorer/src/providers/mints/largest.tsx @@ -10,7 +10,7 @@ import { } from "@solana/web3.js"; import { TokenAccountInfo, TokenAccount } from "validators/accounts/token"; import { ParsedInfo } from "validators"; -import { coerce } from "superstruct"; +import { create } from "superstruct"; import { reportError } from "utils/sentry"; type LargestAccounts = { @@ -81,7 +81,7 @@ async function fetchLargestAccounts( ) ).value; if (accountInfo && "parsed" in accountInfo.data) { - const info = coerceParsedAccountInfo(accountInfo.data); + const info = createParsedAccountInfo(accountInfo.data); return { ...account, owner: info.owner, @@ -144,13 +144,13 @@ export function useTokenLargestTokens( return context.entries[address]; } -function coerceParsedAccountInfo( +function createParsedAccountInfo( parsedData: ParsedAccountData ): TokenAccountInfo { try { - const data = coerce(parsedData.parsed, ParsedInfo); - const parsed = coerce(data, TokenAccount); - return coerce(parsed.info, TokenAccountInfo); + const data = create(parsedData.parsed, ParsedInfo); + const parsed = create(data, TokenAccount); + return create(parsed.info, TokenAccountInfo); } catch (error) { throw error; } diff --git a/explorer/src/validators/accounts/config.ts b/explorer/src/validators/accounts/config.ts index 80691f8b76..14f0fea8d9 100644 --- a/explorer/src/validators/accounts/config.ts +++ b/explorer/src/validators/accounts/config.ts @@ -1,11 +1,10 @@ /* eslint-disable @typescript-eslint/no-redeclare */ import { - StructType, - pick, + Infer, array, boolean, - object, + type, number, string, record, @@ -13,44 +12,40 @@ import { literal, } from "superstruct"; -export type StakeConfigInfo = StructType; -export const StakeConfigInfo = pick({ +export type StakeConfigInfo = Infer; +export const StakeConfigInfo = type({ warmupCooldownRate: number(), slashPenalty: number(), }); -export type ConfigKey = StructType; -export const ConfigKey = pick({ +export type ConfigKey = Infer; +export const ConfigKey = type({ pubkey: string(), signer: boolean(), }); -export type ValidatorInfoConfigData = StructType< - typeof ValidatorInfoConfigData ->; +export type ValidatorInfoConfigData = Infer; export const ValidatorInfoConfigData = record(string(), string()); -export type ValidatorInfoConfigInfo = StructType< - typeof ValidatorInfoConfigInfo ->; -export const ValidatorInfoConfigInfo = pick({ +export type ValidatorInfoConfigInfo = Infer; +export const ValidatorInfoConfigInfo = type({ keys: array(ConfigKey), configData: ValidatorInfoConfigData, }); -export type ValidatorInfoAccount = StructType; -export const ValidatorInfoAccount = object({ +export type ValidatorInfoAccount = Infer; +export const ValidatorInfoAccount = type({ type: literal("validatorInfo"), info: ValidatorInfoConfigInfo, }); -export type StakeConfigInfoAccount = StructType; -export const StakeConfigInfoAccount = object({ +export type StakeConfigInfoAccount = Infer; +export const StakeConfigInfoAccount = type({ type: literal("stakeConfig"), info: StakeConfigInfo, }); -export type ConfigAccount = StructType; +export type ConfigAccount = Infer; export const ConfigAccount = union([ StakeConfigInfoAccount, ValidatorInfoAccount, diff --git a/explorer/src/validators/accounts/nonce.ts b/explorer/src/validators/accounts/nonce.ts index e47464dfff..4220f06430 100644 --- a/explorer/src/validators/accounts/nonce.ts +++ b/explorer/src/validators/accounts/nonce.ts @@ -1,22 +1,22 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { StructType, object, string, enums, pick } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { Infer, string, enums, type } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type NonceAccountType = StructType; +export type NonceAccountType = Infer; export const NonceAccountType = enums(["uninitialized", "initialized"]); -export type NonceAccountInfo = StructType; -export const NonceAccountInfo = pick({ - authority: Pubkey, +export type NonceAccountInfo = Infer; +export const NonceAccountInfo = type({ + authority: PublicKeyFromString, blockhash: string(), - feeCalculator: pick({ + feeCalculator: type({ lamportsPerSignature: string(), }), }); -export type NonceAccount = StructType; -export const NonceAccount = object({ +export type NonceAccount = Infer; +export const NonceAccount = type({ type: NonceAccountType, info: NonceAccountInfo, }); diff --git a/explorer/src/validators/accounts/stake.ts b/explorer/src/validators/accounts/stake.ts index 4fc7f5c487..e431026083 100644 --- a/explorer/src/validators/accounts/stake.ts +++ b/explorer/src/validators/accounts/stake.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { object, StructType, number, nullable, enums } from "superstruct"; -import { Pubkey } from "validators/pubkey"; -import { BigNum } from "validators/bignum"; +import { Infer, number, nullable, enums, type } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; +import { BigNumFromString } from "validators/bignum"; -export type StakeAccountType = StructType; +export type StakeAccountType = Infer; export const StakeAccountType = enums([ "uninitialized", "initialized", @@ -12,30 +12,30 @@ export const StakeAccountType = enums([ "rewardsPool", ]); -export type StakeMeta = StructType; -export const StakeMeta = object({ - rentExemptReserve: BigNum, - authorized: object({ - staker: Pubkey, - withdrawer: Pubkey, +export type StakeMeta = Infer; +export const StakeMeta = type({ + rentExemptReserve: BigNumFromString, + authorized: type({ + staker: PublicKeyFromString, + withdrawer: PublicKeyFromString, }), - lockup: object({ + lockup: type({ unixTimestamp: number(), epoch: number(), - custodian: Pubkey, + custodian: PublicKeyFromString, }), }); -export type StakeAccountInfo = StructType; -export const StakeAccountInfo = object({ +export type StakeAccountInfo = Infer; +export const StakeAccountInfo = type({ meta: StakeMeta, stake: nullable( - object({ - delegation: object({ - voter: Pubkey, - stake: BigNum, - activationEpoch: BigNum, - deactivationEpoch: BigNum, + type({ + delegation: type({ + voter: PublicKeyFromString, + stake: BigNumFromString, + activationEpoch: BigNumFromString, + deactivationEpoch: BigNumFromString, warmupCooldownRate: number(), }), creditsObserved: number(), @@ -43,8 +43,8 @@ export const StakeAccountInfo = object({ ), }); -export type StakeAccount = StructType; -export const StakeAccount = object({ +export type StakeAccount = Infer; +export const StakeAccount = type({ type: StakeAccountType, info: StakeAccountInfo, }); diff --git a/explorer/src/validators/accounts/sysvar.ts b/explorer/src/validators/accounts/sysvar.ts index 30655694df..9612ff4bc5 100644 --- a/explorer/src/validators/accounts/sysvar.ts +++ b/explorer/src/validators/accounts/sysvar.ts @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/no-redeclare */ import { - StructType, + Infer, enums, array, number, - object, + type, boolean, string, - pick, literal, union, } from "superstruct"; -export type SysvarAccountType = StructType; +export type SysvarAccountType = Infer; export const SysvarAccountType = enums([ "clock", "epochSchedule", @@ -26,22 +25,22 @@ export const SysvarAccountType = enums([ "stakeHistory", ]); -export type ClockAccountInfo = StructType; -export const ClockAccountInfo = pick({ +export type ClockAccountInfo = Infer; +export const ClockAccountInfo = type({ slot: number(), epoch: number(), leaderScheduleEpoch: number(), unixTimestamp: number(), }); -export type SysvarClockAccount = StructType; -export const SysvarClockAccount = object({ +export type SysvarClockAccount = Infer; +export const SysvarClockAccount = type({ type: literal("clock"), info: ClockAccountInfo, }); -export type EpochScheduleInfo = StructType; -export const EpochScheduleInfo = pick({ +export type EpochScheduleInfo = Infer; +export const EpochScheduleInfo = type({ slotsPerEpoch: number(), leaderScheduleSlotOffset: number(), warmup: boolean(), @@ -49,126 +48,120 @@ export const EpochScheduleInfo = pick({ firstNormalSlot: number(), }); -export type SysvarEpochScheduleAccount = StructType< +export type SysvarEpochScheduleAccount = Infer< typeof SysvarEpochScheduleAccount >; -export const SysvarEpochScheduleAccount = object({ +export const SysvarEpochScheduleAccount = type({ type: literal("epochSchedule"), info: EpochScheduleInfo, }); -export type FeesInfo = StructType; -export const FeesInfo = pick({ - feeCalculator: pick({ +export type FeesInfo = Infer; +export const FeesInfo = type({ + feeCalculator: type({ lamportsPerSignature: string(), }), }); -export type SysvarFeesAccount = StructType; -export const SysvarFeesAccount = object({ +export type SysvarFeesAccount = Infer; +export const SysvarFeesAccount = type({ type: literal("fees"), info: FeesInfo, }); -export type RecentBlockhashesEntry = StructType; -export const RecentBlockhashesEntry = pick({ +export type RecentBlockhashesEntry = Infer; +export const RecentBlockhashesEntry = type({ blockhash: string(), - feeCalculator: pick({ + feeCalculator: type({ lamportsPerSignature: string(), }), }); -export type RecentBlockhashesInfo = StructType; +export type RecentBlockhashesInfo = Infer; export const RecentBlockhashesInfo = array(RecentBlockhashesEntry); -export type SysvarRecentBlockhashesAccount = StructType< +export type SysvarRecentBlockhashesAccount = Infer< typeof SysvarRecentBlockhashesAccount >; -export const SysvarRecentBlockhashesAccount = object({ +export const SysvarRecentBlockhashesAccount = type({ type: literal("recentBlockhashes"), info: RecentBlockhashesInfo, }); -export type RentInfo = StructType; -export const RentInfo = pick({ +export type RentInfo = Infer; +export const RentInfo = type({ lamportsPerByteYear: string(), exemptionThreshold: number(), burnPercent: number(), }); -export type SysvarRentAccount = StructType; -export const SysvarRentAccount = object({ +export type SysvarRentAccount = Infer; +export const SysvarRentAccount = type({ type: literal("rent"), info: RentInfo, }); -export type RewardsInfo = StructType; -export const RewardsInfo = pick({ +export type RewardsInfo = Infer; +export const RewardsInfo = type({ validatorPointValue: number(), }); -export type SysvarRewardsAccount = StructType; -export const SysvarRewardsAccount = object({ +export type SysvarRewardsAccount = Infer; +export const SysvarRewardsAccount = type({ type: literal("rewards"), info: RewardsInfo, }); -export type SlotHashEntry = StructType; -export const SlotHashEntry = pick({ +export type SlotHashEntry = Infer; +export const SlotHashEntry = type({ slot: number(), hash: string(), }); -export type SlotHashesInfo = StructType; +export type SlotHashesInfo = Infer; export const SlotHashesInfo = array(SlotHashEntry); -export type SysvarSlotHashesAccount = StructType< - typeof SysvarSlotHashesAccount ->; -export const SysvarSlotHashesAccount = object({ +export type SysvarSlotHashesAccount = Infer; +export const SysvarSlotHashesAccount = type({ type: literal("slotHashes"), info: SlotHashesInfo, }); -export type SlotHistoryInfo = StructType; -export const SlotHistoryInfo = pick({ +export type SlotHistoryInfo = Infer; +export const SlotHistoryInfo = type({ nextSlot: number(), bits: string(), }); -export type SysvarSlotHistoryAccount = StructType< - typeof SysvarSlotHistoryAccount ->; -export const SysvarSlotHistoryAccount = object({ +export type SysvarSlotHistoryAccount = Infer; +export const SysvarSlotHistoryAccount = type({ type: literal("slotHistory"), info: SlotHistoryInfo, }); -export type StakeHistoryEntryItem = StructType; -export const StakeHistoryEntryItem = pick({ +export type StakeHistoryEntryItem = Infer; +export const StakeHistoryEntryItem = type({ effective: number(), activating: number(), deactivating: number(), }); -export type StakeHistoryEntry = StructType; -export const StakeHistoryEntry = pick({ +export type StakeHistoryEntry = Infer; +export const StakeHistoryEntry = type({ epoch: number(), stakeHistory: StakeHistoryEntryItem, }); -export type StakeHistoryInfo = StructType; +export type StakeHistoryInfo = Infer; export const StakeHistoryInfo = array(StakeHistoryEntry); -export type SysvarStakeHistoryAccount = StructType< - typeof SysvarStakeHistoryAccount ->; -export const SysvarStakeHistoryAccount = object({ +export type SysvarStakeHistoryAccount = Infer; +export const SysvarStakeHistoryAccount = type({ type: literal("stakeHistory"), info: StakeHistoryInfo, }); -export type SysvarAccount = StructType; +export type SysvarAccount = Infer; export const SysvarAccount = union([ SysvarClockAccount, SysvarEpochScheduleAccount, diff --git a/explorer/src/validators/accounts/token.ts b/explorer/src/validators/accounts/token.ts index a53f69672d..441d95e37b 100644 --- a/explorer/src/validators/accounts/token.ts +++ b/explorer/src/validators/accounts/token.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-redeclare */ import { - StructType, + Infer, number, optional, enums, @@ -9,55 +9,55 @@ import { boolean, string, array, - pick, + type, nullable, } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { PublicKeyFromString } from "validators/pubkey"; -export type TokenAccountType = StructType; +export type TokenAccountType = Infer; export const TokenAccountType = enums(["mint", "account", "multisig"]); -export type TokenAccountState = StructType; +export type TokenAccountState = Infer; const AccountState = enums(["initialized", "uninitialized", "frozen"]); -const TokenAmount = pick({ +const TokenAmount = type({ decimals: number(), uiAmountString: string(), amount: string(), }); -export type TokenAccountInfo = StructType; -export const TokenAccountInfo = pick({ - mint: Pubkey, - owner: Pubkey, +export type TokenAccountInfo = Infer; +export const TokenAccountInfo = type({ + mint: PublicKeyFromString, + owner: PublicKeyFromString, tokenAmount: TokenAmount, - delegate: optional(Pubkey), + delegate: optional(PublicKeyFromString), state: AccountState, isNative: boolean(), rentExemptReserve: optional(TokenAmount), delegatedAmount: optional(TokenAmount), - closeAuthority: optional(Pubkey), + closeAuthority: optional(PublicKeyFromString), }); -export type MintAccountInfo = StructType; -export const MintAccountInfo = pick({ - mintAuthority: nullable(Pubkey), +export type MintAccountInfo = Infer; +export const MintAccountInfo = type({ + mintAuthority: nullable(PublicKeyFromString), supply: string(), decimals: number(), isInitialized: boolean(), - freezeAuthority: nullable(Pubkey), + freezeAuthority: nullable(PublicKeyFromString), }); -export type MultisigAccountInfo = StructType; -export const MultisigAccountInfo = pick({ +export type MultisigAccountInfo = Infer; +export const MultisigAccountInfo = type({ numRequiredSigners: number(), numValidSigners: number(), isInitialized: boolean(), - signers: array(Pubkey), + signers: array(PublicKeyFromString), }); -export type TokenAccount = StructType; -export const TokenAccount = pick({ +export type TokenAccount = Infer; +export const TokenAccount = type({ type: TokenAccountType, info: any(), }); diff --git a/explorer/src/validators/accounts/upgradeable-program.ts b/explorer/src/validators/accounts/upgradeable-program.ts index 44f349182a..b9596984b7 100644 --- a/explorer/src/validators/accounts/upgradeable-program.ts +++ b/explorer/src/validators/accounts/upgradeable-program.ts @@ -1,28 +1,28 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { StructType, pick, number, nullable, literal } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { type, number, literal, nullable, Infer } from "superstruct"; +import { PublicKeyFromString } from "validators/pubkey"; -export type ProgramAccountInfo = StructType; -export const ProgramAccountInfo = pick({ - programData: Pubkey, +export type ProgramAccountInfo = Infer; +export const ProgramAccountInfo = type({ + programData: PublicKeyFromString, }); -export type ProgramAccount = StructType; -export const ProgramAccount = pick({ +export type ProgramAccount = Infer; +export const ProgramAccount = type({ type: literal("program"), info: ProgramAccountInfo, }); -export type ProgramDataAccountInfo = StructType; -export const ProgramDataAccountInfo = pick({ - authority: nullable(Pubkey), +export type ProgramDataAccountInfo = Infer; +export const ProgramDataAccountInfo = type({ + authority: nullable(PublicKeyFromString), // don't care about data yet slot: number(), }); -export type ProgramDataAccount = StructType; -export const ProgramDataAccount = pick({ +export type ProgramDataAccount = Infer; +export const ProgramDataAccount = type({ type: literal("programData"), info: ProgramDataAccountInfo, }); diff --git a/explorer/src/validators/accounts/vote.ts b/explorer/src/validators/accounts/vote.ts index 68292bac42..ca33fed0e6 100644 --- a/explorer/src/validators/accounts/vote.ts +++ b/explorer/src/validators/accounts/vote.ts @@ -1,64 +1,63 @@ /* eslint-disable @typescript-eslint/no-redeclare */ import { - StructType, + Infer, enums, - pick, number, array, - object, + type, nullable, string, } from "superstruct"; -import { Pubkey } from "validators/pubkey"; +import { PublicKeyFromString } from "validators/pubkey"; -export type VoteAccountType = StructType; +export type VoteAccountType = Infer; export const VoteAccountType = enums(["vote"]); -export type AuthorizedVoter = StructType; -export const AuthorizedVoter = pick({ - authorizedVoter: Pubkey, +export type AuthorizedVoter = Infer; +export const AuthorizedVoter = type({ + authorizedVoter: PublicKeyFromString, epoch: number(), }); -export type PriorVoter = StructType; -export const PriorVoter = pick({ - authorizedPubkey: Pubkey, +export type PriorVoter = Infer; +export const PriorVoter = type({ + authorizedPubkey: PublicKeyFromString, epochOfLastAuthorizedSwitch: number(), targetEpoch: number(), }); -export type EpochCredits = StructType; -export const EpochCredits = pick({ +export type EpochCredits = Infer; +export const EpochCredits = type({ epoch: number(), credits: string(), previousCredits: string(), }); -export type Vote = StructType; -export const Vote = object({ +export type Vote = Infer; +export const Vote = type({ slot: number(), confirmationCount: number(), }); -export type VoteAccountInfo = StructType; -export const VoteAccountInfo = pick({ +export type VoteAccountInfo = Infer; +export const VoteAccountInfo = type({ authorizedVoters: array(AuthorizedVoter), - authorizedWithdrawer: Pubkey, + authorizedWithdrawer: PublicKeyFromString, commission: number(), epochCredits: array(EpochCredits), - lastTimestamp: object({ + lastTimestamp: type({ slot: number(), timestamp: number(), }), - nodePubkey: Pubkey, + nodePubkey: PublicKeyFromString, priorVoters: array(PriorVoter), rootSlot: nullable(number()), votes: array(Vote), }); -export type VoteAccount = StructType; -export const VoteAccount = pick({ +export type VoteAccount = Infer; +export const VoteAccount = type({ type: VoteAccountType, info: VoteAccountInfo, }); diff --git a/explorer/src/validators/bignum.ts b/explorer/src/validators/bignum.ts index b7ce9a4e77..3203803ba0 100644 --- a/explorer/src/validators/bignum.ts +++ b/explorer/src/validators/bignum.ts @@ -1,8 +1,7 @@ -import { coercion, struct, Struct } from "superstruct"; +import { coerce, instance, string } from "superstruct"; import BN from "bn.js"; -export const BigNumValue = struct("BigNum", (value) => value instanceof BN); -export const BigNum: Struct = coercion(BigNumValue, (value) => { +export const BigNumFromString = coerce(instance(BN), string(), (value) => { if (typeof value === "string") return new BN(value, 10); throw new Error("invalid big num"); }); diff --git a/explorer/src/validators/index.ts b/explorer/src/validators/index.ts index 659ae01d84..d47c7e01c7 100644 --- a/explorer/src/validators/index.ts +++ b/explorer/src/validators/index.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-redeclare */ -import { object, any, StructType, string } from "superstruct"; +import { type, any, Infer, string } from "superstruct"; -export type ParsedInfo = StructType; -export const ParsedInfo = object({ +export type ParsedInfo = Infer; +export const ParsedInfo = type({ type: string(), info: any(), }); diff --git a/explorer/src/validators/pubkey.ts b/explorer/src/validators/pubkey.ts index b4a19fee32..1b270a2e1d 100644 --- a/explorer/src/validators/pubkey.ts +++ b/explorer/src/validators/pubkey.ts @@ -1,8 +1,8 @@ -import { coercion, struct, Struct } from "superstruct"; +import { coerce, instance, string } from "superstruct"; import { PublicKey } from "@solana/web3.js"; -const PubkeyValue = struct("Pubkey", (value) => value instanceof PublicKey); -export const Pubkey: Struct = coercion(PubkeyValue, (value) => { - if (typeof value === "string") return new PublicKey(value); - throw new Error("invalid pubkey"); -}); +export const PublicKeyFromString = coerce( + instance(PublicKey), + string(), + (value) => new PublicKey(value) +);