explorer: Introduce flagged accounts provider (#15161)

This commit is contained in:
Josh 2021-02-08 12:54:36 -08:00 committed by GitHub
parent 9e39b815f7
commit 0da11af827
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 16 deletions

View File

@ -28,7 +28,7 @@ import { SlotHashesCard } from "components/account/SlotHashesCard";
import { StakeHistoryCard } from "components/account/StakeHistoryCard";
import { BlockhashesCard } from "components/account/BlockhashesCard";
import { ConfigAccountSection } from "components/account/ConfigAccountSection";
import { isScamAccount } from "scamRegistry";
import { useFlaggedAccounts } from "providers/accounts/flagged-accounts";
const TABS_LOOKUP: { [id: string]: Tab } = {
"spl-token:mint": {
@ -130,7 +130,7 @@ function DetailsSections({ pubkey, tab }: { pubkey: PublicKey; tab?: string }) {
const info = useAccountInfo(address);
const { status } = useCluster();
const location = useLocation();
const isScam = isScamAccount(address);
const { flaggedAccounts } = useFlaggedAccounts();
// Fetch account on load
React.useEffect(() => {
@ -159,7 +159,7 @@ function DetailsSections({ pubkey, tab }: { pubkey: PublicKey; tab?: string }) {
return (
<>
{isScam && (
{flaggedAccounts.has(address) && (
<div className="alert alert-danger alert-scam" role="alert">
Warning! This account has been flagged as a scam account. Please be
cautious sending SOL to this account.

View File

@ -0,0 +1,46 @@
import React from "react";
const initialState = new Map();
const FlaggedContext = React.createContext<Map<string, boolean>>(initialState);
type ProviderProps = { children: React.ReactNode };
export function FlaggedAccountsProvider({ children }: ProviderProps) {
const [flaggedAccounts, setFlaggedAccounts] = React.useState<
Map<string, boolean>
>(initialState);
React.useEffect(() => {
window
.fetch(
"https://solana-labs.github.io/solana-flagged-accounts/flagged.txt"
)
.then((res) => {
return res.text();
})
.then((body: string) => {
const flaggedAccounts = new Map<string, boolean>();
body
.split("\n")
.forEach((account) => flaggedAccounts.set(account, true));
setFlaggedAccounts(flaggedAccounts);
});
}, []);
return (
<FlaggedContext.Provider value={flaggedAccounts}>
{children}
</FlaggedContext.Provider>
);
}
export function useFlaggedAccounts() {
const flaggedAccounts = React.useContext(FlaggedContext);
if (!flaggedAccounts) {
throw new Error(
`useFlaggedAccounts must be used within a AccountsProvider`
);
}
return { flaggedAccounts };
}

View File

@ -18,6 +18,7 @@ import { VoteAccount } from "validators/accounts/vote";
import { NonceAccount } from "validators/accounts/nonce";
import { SysvarAccount } from "validators/accounts/sysvar";
import { ConfigAccount } from "validators/accounts/config";
import { FlaggedAccountsProvider } from "./flagged-accounts";
export { useAccountHistory } from "./history";
export type StakeProgramData = {
@ -92,7 +93,9 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
<StateContext.Provider value={state}>
<DispatchContext.Provider value={dispatch}>
<TokensProvider>
<HistoryProvider>{children}</HistoryProvider>
<HistoryProvider>
<FlaggedAccountsProvider>{children}</FlaggedAccountsProvider>
</HistoryProvider>
</TokensProvider>
</DispatchContext.Provider>
</StateContext.Provider>

View File

@ -1,12 +0,0 @@
const scamAddresses = toHash(["GACpXND1SSfTSQMmqGuFvGwXB3jGEYBDRGNzmLfTYwSP"]);
export function isScamAccount(address: string) {
return address in scamAddresses;
}
function toHash(addresses: string[]) {
return addresses.reduce((prev: { [addr: string]: boolean }, addr) => {
prev[addr] = true;
return prev;
}, {});
}