Add titles for token lending instructions (#15217)

* feat: add lending instruction names

* chore: capitalize words
This commit is contained in:
B 2021-02-09 19:50:34 -06:00 committed by GitHub
parent 948819dfa8
commit a0ba59a1ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 154 additions and 30 deletions

1
explorer/.gitignore vendored
View File

@ -10,6 +10,7 @@
# production
/build
/wasm/target
# misc
.DS_Store

View File

@ -5,10 +5,10 @@ import Select, { InputActionMeta, ActionMeta, ValueType } from "react-select";
import StateManager from "react-select";
import {
LOADER_IDS,
PROGRAM_IDS,
PROGRAM_NAME_BY_ID,
SYSVAR_IDS,
ProgramName,
LoaderName,
SEARCHABLE_PROGRAMS,
} from "utils/tx";
import { TokenRegistry } from "tokenRegistry";
import { Cluster, useCluster } from "providers/cluster";
@ -64,18 +64,8 @@ export function SearchBar() {
);
}
const SEARCHABLE_PROGRAMS: ProgramName[] = [
"Break Solana Program",
"Config Program",
"Stake Program",
"System Program",
"Vote Program",
"SPL Token Program",
"Memo Program",
];
function buildProgramOptions(search: string) {
const matchedPrograms = Object.entries(PROGRAM_IDS).filter(
const matchedPrograms = Object.entries(PROGRAM_NAME_BY_ID).filter(
([address, name]) => {
return (
SEARCHABLE_PROGRAMS.includes(name) &&

View File

@ -37,6 +37,10 @@ import {
isTokenSwapInstruction,
parseTokenSwapInstructionTitle,
} from "components/instruction/token-swap/types";
import {
isTokenLendingInstruction,
parseTokenLendingInstructionTitle,
} from "components/instruction/token-lending/types";
import {
isSerumInstruction,
parseSerumInstructionTitle,
@ -489,6 +493,16 @@ const TokenTransactionRow = React.memo(
reportError(error, { signature: tx.signature });
return undefined;
}
} else if (
transactionInstruction &&
isTokenLendingInstruction(transactionInstruction)
) {
try {
name = parseTokenLendingInstructionTitle(transactionInstruction);
} catch (error) {
reportError(error, { signature: tx.signature });
return undefined;
}
} else {
if (
ix.accounts.findIndex((account) =>

View File

@ -0,0 +1,46 @@
import React from "react";
import { TransactionInstruction, SignatureResult } from "@solana/web3.js";
import { InstructionCard } from "./InstructionCard";
import { useCluster } from "providers/cluster";
import { reportError } from "utils/sentry";
import { parseTokenLendingInstructionTitle } from "./token-lending/types";
export function TokenLendingDetailsCard({
ix,
index,
result,
signature,
innerCards,
childIndex,
}: {
ix: TransactionInstruction;
index: number;
result: SignatureResult;
signature: string;
innerCards?: JSX.Element[];
childIndex?: number;
}) {
const { url } = useCluster();
let title;
try {
title = parseTokenLendingInstructionTitle(ix);
} catch (error) {
reportError(error, {
url: url,
signature: signature,
});
}
return (
<InstructionCard
ix={ix}
index={index}
result={result}
title={`Token Lending: ${title || "Unknown"}`}
innerCards={innerCards}
childIndex={childIndex}
defaultRaw
/>
);
}

View File

@ -0,0 +1,35 @@
import { TransactionInstruction } from "@solana/web3.js";
export const PROGRAM_IDS: string[] = [
"LendZqTs7gn5CTSJU1jWKhKuVpjJGom45nnwPb2AMTi", // mainnet / testnet / devnet
];
const INSTRUCTION_LOOKUP: { [key: number]: string } = {
0: "Initialize Lending Market",
1: "Initialize Reserve",
2: "Initialize Obligation",
3: "Reserve Deposit",
4: "Reserve Withdraw",
5: "Borrow",
6: "Repay Loan",
7: "Liquidate Loan",
8: "Accrue Interest",
};
export function isTokenLendingInstruction(
instruction: TransactionInstruction
): boolean {
return PROGRAM_IDS.includes(instruction.programId.toBase58());
}
export function parseTokenLendingInstructionTitle(
instruction: TransactionInstruction
): string {
const code = instruction.data[0];
if (!(code in INSTRUCTION_LOOKUP)) {
throw new Error(`Unrecognized Token Swap instruction code: ${code}`);
}
return INSTRUCTION_LOOKUP[code];
}

View File

@ -37,7 +37,9 @@ import { FetchStatus } from "providers/cache";
import { SerumDetailsCard } from "components/instruction/SerumDetailsCard";
import { Slot } from "components/common/Slot";
import { isTokenSwapInstruction } from "components/instruction/token-swap/types";
import { isTokenLendingInstruction } from "components/instruction/token-lending/types";
import { TokenSwapDetailsCard } from "components/instruction/TokenSwapDetailsCard";
import { TokenLendingDetailsCard } from "components/instruction/TokenLendingDetailsCard";
import { isSerumInstruction } from "components/instruction/serum/types";
import { MemoDetailsCard } from "components/instruction/MemoDetailsCard";
import { BigNumber } from "bignumber.js";
@ -613,6 +615,8 @@ function renderInstructionCard({
return <SerumDetailsCard key={key} {...props} />;
} else if (isTokenSwapInstruction(transactionIx)) {
return <TokenSwapDetailsCard key={key} {...props} />;
} else if (isTokenLendingInstruction(transactionIx)) {
return <TokenLendingDetailsCard key={key} {...props} />;
} else {
return <UnknownDetailsCard key={key} {...props} />;
}

View File

@ -19,23 +19,57 @@ import { TokenRegistry } from "tokenRegistry";
import { Cluster } from "providers/cluster";
import { SerumMarketRegistry } from "serumMarketRegistry";
export type ProgramName = typeof PROGRAM_IDS[keyof typeof PROGRAM_IDS];
export type ProgramName = typeof PROGRAM_NAME_BY_ID[keyof typeof PROGRAM_NAME_BY_ID];
export const PROGRAM_IDS = {
BrEAK7zGZ6dM71zUDACDqJnekihmwF15noTddWTsknjC: "Break Solana Program",
Budget1111111111111111111111111111111111111: "Budget Program",
Config1111111111111111111111111111111111111: "Config Program",
Exchange11111111111111111111111111111111111: "Exchange Program",
[StakeProgram.programId.toBase58()]: "Stake Program",
Storage111111111111111111111111111111111111: "Storage Program",
[SystemProgram.programId.toBase58()]: "System Program",
Vest111111111111111111111111111111111111111: "Vest Program",
[VOTE_PROGRAM_ID.toBase58()]: "Vote Program",
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA: "SPL Token Program",
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL:
"SPL Associated Token Account Program",
Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo: "Memo Program",
SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8: "Token Swap Program",
export enum PROGRAM_NAMES {
BREAK_SOLANA = "Break Solana Program",
BUDGET = "Budget Program",
CONFIG = "Config Program",
EXCHANGE = "Exchange Program",
STAKE = "Stake Program",
STORAGE = "Storage Program",
SYSTEM = "System Program",
VEST = "Vest Program",
VOTE = "Vote Program",
SPL_TOKEN = "SPL Token Program",
ASSOCIATED_TOKEN = "SPL Associated Token Program",
MEMO = "Memo Program",
SWAP = "Swap Program",
LENDING = "Lending Program",
}
export const SEARCHABLE_PROGRAMS: ProgramName[] = [
PROGRAM_NAMES.BREAK_SOLANA,
PROGRAM_NAMES.BUDGET,
PROGRAM_NAMES.CONFIG,
PROGRAM_NAMES.EXCHANGE,
PROGRAM_NAMES.STAKE,
PROGRAM_NAMES.STORAGE,
PROGRAM_NAMES.SYSTEM,
PROGRAM_NAMES.VEST,
PROGRAM_NAMES.VOTE,
PROGRAM_NAMES.SPL_TOKEN,
PROGRAM_NAMES.ASSOCIATED_TOKEN,
PROGRAM_NAMES.MEMO,
PROGRAM_NAMES.SWAP,
PROGRAM_NAMES.LENDING,
];
export const PROGRAM_NAME_BY_ID = {
BrEAK7zGZ6dM71zUDACDqJnekihmwF15noTddWTsknjC: PROGRAM_NAMES.BREAK_SOLANA,
Budget1111111111111111111111111111111111111: PROGRAM_NAMES.BUDGET,
Config1111111111111111111111111111111111111: PROGRAM_NAMES.CONFIG,
Exchange11111111111111111111111111111111111: PROGRAM_NAMES.EXCHANGE,
[StakeProgram.programId.toBase58()]: PROGRAM_NAMES.STAKE,
Storage111111111111111111111111111111111111: PROGRAM_NAMES.STORAGE,
[SystemProgram.programId.toBase58()]: PROGRAM_NAMES.SYSTEM,
Vest111111111111111111111111111111111111111: PROGRAM_NAMES.VEST,
[VOTE_PROGRAM_ID.toBase58()]: PROGRAM_NAMES.VOTE,
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA: PROGRAM_NAMES.SPL_TOKEN,
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL: PROGRAM_NAMES.ASSOCIATED_TOKEN,
Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo: PROGRAM_NAMES.MEMO,
SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8: PROGRAM_NAMES.SWAP,
LendZqTs7gn5CTSJU1jWKhKuVpjJGom45nnwPb2AMTi: PROGRAM_NAMES.LENDING,
} as const;
export type LoaderName = typeof LOADER_IDS[keyof typeof LOADER_IDS];
@ -67,7 +101,7 @@ export function addressLabel(
cluster: Cluster
): string | undefined {
return (
PROGRAM_IDS[address] ||
PROGRAM_NAME_BY_ID[address] ||
LOADER_IDS[address] ||
SYSVAR_IDS[address] ||
SYSVAR_ID[address] ||