Add titles for token lending instructions (#15217)
* feat: add lending instruction names * chore: capitalize words
This commit is contained in:
parent
948819dfa8
commit
a0ba59a1ea
|
@ -10,6 +10,7 @@
|
|||
|
||||
# production
|
||||
/build
|
||||
/wasm/target
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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) =>
|
||||
|
|
|
@ -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
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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];
|
||||
}
|
|
@ -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} />;
|
||||
}
|
||||
|
|
|
@ -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] ||
|
||||
|
|
Loading…
Reference in New Issue