Add programs and sysvars to explorer search suggestions (#11467)

This commit is contained in:
Justin Starry 2020-08-08 20:01:26 +08:00 committed by GitHub
parent 40656911a6
commit 3d97b04815
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 44 deletions

View File

@ -3,6 +3,7 @@ import bs58 from "bs58";
import { useHistory, useLocation } from "react-router-dom";
import Select, { InputActionMeta, ActionMeta, ValueType } from "react-select";
import StateManager from "react-select";
import { PROGRAM_IDS, SYSVAR_IDS } from "utils/tx";
export function SearchBar() {
const [search, setSearch] = React.useState("");
@ -10,10 +11,7 @@ export function SearchBar() {
const history = useHistory();
const location = useLocation();
const onChange = (
{ value: pathname }: ValueType<any>,
meta: ActionMeta<any>
) => {
const onChange = ({ pathname }: ValueType<any>, meta: ActionMeta<any>) => {
if (meta.action === "select-option") {
history.push({ ...location, pathname });
setSearch("");
@ -24,38 +22,6 @@ export function SearchBar() {
if (action === "input-change") setSearch(value);
};
const options = ((searchValue: string) => {
try {
const decoded = bs58.decode(searchValue);
if (decoded.length === 32) {
return [
{
label: "Account",
options: [
{
label: searchValue,
value: "/address/" + searchValue,
},
],
},
];
} else if (decoded.length === 64) {
return [
{
label: "Transaction",
options: [
{
label: searchValue,
value: "/tx/" + searchValue,
},
],
},
];
}
} catch (err) {}
return [];
})(search);
const resetValue = "" as any;
return (
<div className="container my-4">
@ -63,7 +29,7 @@ export function SearchBar() {
<div className="col">
<Select
ref={(ref) => (selectRef.current = ref)}
options={options}
options={buildOptions(search)}
noOptionsMessage={() => "No Results"}
placeholder="Search by address or signature"
value={resetValue}
@ -81,6 +47,89 @@ export function SearchBar() {
);
}
const SEARCHABLE_PROGRAMS = ["Config", "Stake", "System", "Vote", "Token"];
function buildProgramOptions(search: string) {
const matchedPrograms = Object.entries(PROGRAM_IDS).filter(([, name]) => {
return (
SEARCHABLE_PROGRAMS.includes(name) &&
name.toLowerCase().includes(search.toLowerCase())
);
});
if (matchedPrograms.length > 0) {
return {
label: "Programs",
options: matchedPrograms.map(([id, name]) => ({
label: name,
value: name,
pathname: "/address/" + id,
})),
};
}
}
function buildSysvarOptions(search: string) {
const matchedSysvars = Object.entries(SYSVAR_IDS).filter(([, name]) => {
return name.toLowerCase().includes(search.toLowerCase());
});
if (matchedSysvars.length > 0) {
return {
label: "Sysvars",
options: matchedSysvars.map(([id, name]) => ({
label: name,
value: name,
pathname: "/address/" + id,
})),
};
}
}
function buildOptions(search: string) {
if (search.length === 0) return [];
const options = [];
const programOptions = buildProgramOptions(search);
if (programOptions) {
options.push(programOptions);
}
const sysvarOptions = buildSysvarOptions(search);
if (sysvarOptions) {
options.push(sysvarOptions);
}
try {
const decoded = bs58.decode(search);
if (decoded.length === 32) {
options.push({
label: "Account",
options: [
{
label: search,
value: search,
pathname: "/address/" + search,
},
],
});
} else if (decoded.length === 64) {
options.push({
label: "Transaction",
options: [
{
label: search,
value: search,
pathname: "/tx/" + search,
},
],
});
}
} catch (err) {}
return options;
}
function DropdownIndicator() {
return (
<div className="search-indicator">

View File

@ -64,7 +64,7 @@ function OverviewCard({
<tr>
<td>Address</td>
<td className="text-lg-right">
<Address pubkey={account.pubkey} alignRight />
<Address pubkey={account.pubkey} alignRight raw />
</td>
</tr>
<tr>

View File

@ -18,7 +18,7 @@ export function UnknownAccountCard({ account }: { account: Account }) {
<tr>
<td>Address</td>
<td className="text-lg-right">
<Address pubkey={account.pubkey} alignRight />
<Address pubkey={account.pubkey} alignRight raw />
</td>
</tr>
<tr>

View File

@ -10,9 +10,10 @@ type Props = {
pubkey: PublicKey | Pubkey;
alignRight?: boolean;
link?: boolean;
raw?: boolean;
};
export function Address({ pubkey, alignRight, link }: Props) {
export function Address({ pubkey, alignRight, link, raw }: Props) {
const [state, setState] = useState<CopyState>("copy");
const address = pubkey.toBase58();
@ -36,9 +37,11 @@ export function Address({ pubkey, alignRight, link }: Props) {
<span className="text-monospace">
{link ? (
<Link className="" to={clusterPath(`/address/${address}`)}>
{displayAddress(address)}
{raw ? address : displayAddress(address)}
<span className="fe fe-external-link ml-2"></span>
</Link>
) : raw ? (
address
) : (
displayAddress(address)
)}

View File

@ -32,6 +32,14 @@ code, pre {
box-shadow: $card-box-shadow !important;
.search-bar__option {
background-color: $gray-700-dark !important;
cursor: pointer;
&.search-bar__option--is-focused {
background-color: transparent !important;
}
&:hover {
background-color: $gray-700-dark !important;
}
}
}

View File

@ -155,6 +155,7 @@ h4.slot-pill {
color: hsl(0,0%,60%);
display: flex;
padding: 8px 10px;
padding-left: 14px;
transition: color 150ms;
box-sizing: border-box;
cursor: pointer;
@ -166,6 +167,7 @@ h4.slot-pill {
.search-bar__control {
border-radius: $border-radius !important;
padding: 4px;
}
.search-bar__menu {

View File

@ -13,7 +13,7 @@ import {
Transaction,
} from "@solana/web3.js";
const PROGRAM_IDS = {
export const PROGRAM_IDS = {
Budget1111111111111111111111111111111111111: "Budget",
Config1111111111111111111111111111111111111: "Config",
Exchange11111111111111111111111111111111111: "Exchange",
@ -31,8 +31,11 @@ const LOADER_IDS = {
[BpfLoader.programId.toBase58()]: "BPF Loader",
};
const SYSVAR_IDS = {
const SYSVAR_ID: { [key: string]: string } = {
Sysvar1111111111111111111111111111111111111: "SYSVAR",
};
export const SYSVAR_IDS = {
[SYSVAR_CLOCK_PUBKEY.toBase58()]: "SYSVAR_CLOCK",
SysvarEpochSchedu1e111111111111111111111111: "SYSVAR_EPOCH_SCHEDULE",
SysvarFees111111111111111111111111111111111: "SYSVAR_FEES",
@ -49,6 +52,7 @@ export function displayAddress(address: string): string {
PROGRAM_IDS[address] ||
LOADER_IDS[address] ||
SYSVAR_IDS[address] ||
SYSVAR_ID[address] ||
address
);
}