Explorer: update to new spl-token-registry standard (#15765)
* feat: update tokenlist * feat: bump spl-token-registry version to 0.2.0
This commit is contained in:
parent
2204898ded
commit
5bde399499
6
explorer/package-lock.json
generated
6
explorer/package-lock.json
generated
@ -2599,9 +2599,9 @@
|
||||
}
|
||||
},
|
||||
"@solana/spl-token-registry": {
|
||||
"version": "0.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@solana/spl-token-registry/-/spl-token-registry-0.1.9.tgz",
|
||||
"integrity": "sha512-cXjNg3MQVC+LWoFOMYSNRZrnJLCjOXEioIJPBX2V8Ft9v4f4THV/lim6JLddKGXZC2wr5NTOaI2zLYRbtpXW0w==",
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@solana/spl-token-registry/-/spl-token-registry-0.2.0.tgz",
|
||||
"integrity": "sha512-DC1gQDthODgCa0Nd5sPuoGpgEG3xdxQRoggfFFLQpwX689zILabvmVj6v6hF8bN8fGEpADZK1Fp8pwD427jkUQ==",
|
||||
"requires": {
|
||||
"cross-fetch": "^3.0.6"
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
"@project-serum/serum": "^0.13.25",
|
||||
"@react-hook/debounce": "^3.0.0",
|
||||
"@sentry/react": "^6.2.0",
|
||||
"@solana/spl-token-registry": "^0.1.9",
|
||||
"@solana/spl-token-registry": "^0.2.0",
|
||||
"@solana/web3.js": "^0.94.2",
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
} from "utils/tx";
|
||||
import { Cluster, useCluster } from "providers/cluster";
|
||||
import { useTokenRegistry } from "providers/mints/token-registry";
|
||||
import { KnownTokenMap } from "@solana/spl-token-registry";
|
||||
import { TokenInfoMap } from "@solana/spl-token-registry";
|
||||
|
||||
export function SearchBar() {
|
||||
const [search, setSearch] = React.useState("");
|
||||
@ -143,14 +143,14 @@ function buildSysvarOptions(search: string) {
|
||||
function buildTokenOptions(
|
||||
search: string,
|
||||
cluster: Cluster,
|
||||
tokenRegistry: KnownTokenMap
|
||||
tokenRegistry: TokenInfoMap
|
||||
) {
|
||||
const matchedTokens = Array.from(tokenRegistry.entries()).filter(
|
||||
([address, details]) => {
|
||||
const searchLower = search.toLowerCase();
|
||||
return (
|
||||
details.tokenName.toLowerCase().includes(searchLower) ||
|
||||
details.tokenSymbol.toLowerCase().includes(searchLower) ||
|
||||
details.name.toLowerCase().includes(searchLower) ||
|
||||
details.symbol.toLowerCase().includes(searchLower) ||
|
||||
address.includes(search)
|
||||
);
|
||||
}
|
||||
@ -160,8 +160,8 @@ function buildTokenOptions(
|
||||
return {
|
||||
label: "Tokens",
|
||||
options: matchedTokens.map(([id, details]) => ({
|
||||
label: details.tokenName,
|
||||
value: [details.tokenName, details.tokenSymbol, id],
|
||||
label: details.name,
|
||||
value: [details.name, details.symbol, id],
|
||||
pathname: "/address/" + id,
|
||||
})),
|
||||
};
|
||||
@ -171,7 +171,7 @@ function buildTokenOptions(
|
||||
function buildOptions(
|
||||
rawSearch: string,
|
||||
cluster: Cluster,
|
||||
tokenRegistry: KnownTokenMap
|
||||
tokenRegistry: TokenInfoMap
|
||||
) {
|
||||
const search = rawSearch.trim();
|
||||
if (search.length === 0) return [];
|
||||
|
@ -92,7 +92,7 @@ function HoldingsDetailTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
const detailsList: React.ReactNode[] = [];
|
||||
const { tokenRegistry } = useTokenRegistry();
|
||||
const showLogos = tokens.some(
|
||||
(t) => tokenRegistry.get(t.info.mint.toBase58())?.icon !== undefined
|
||||
(t) => tokenRegistry.get(t.info.mint.toBase58())?.logoURI !== undefined
|
||||
);
|
||||
tokens.forEach((tokenAccount) => {
|
||||
const address = tokenAccount.pubkey.toBase58();
|
||||
@ -102,9 +102,9 @@ function HoldingsDetailTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
<tr key={address}>
|
||||
{showLogos && (
|
||||
<td className="w-1 p-0 text-center">
|
||||
{tokenDetails?.icon && (
|
||||
{tokenDetails?.logoURI && (
|
||||
<img
|
||||
src={tokenDetails.icon}
|
||||
src={tokenDetails.logoURI}
|
||||
alt="token icon"
|
||||
className="token-icon rounded-circle border border-4 border-gray-dark"
|
||||
/>
|
||||
@ -119,7 +119,7 @@ function HoldingsDetailTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
</td>
|
||||
<td>
|
||||
{tokenAccount.info.tokenAmount.uiAmountString}{" "}
|
||||
{tokenDetails && tokenDetails.tokenSymbol}
|
||||
{tokenDetails && tokenDetails.symbol}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
@ -161,7 +161,7 @@ function HoldingsSummaryTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
|
||||
const detailsList: React.ReactNode[] = [];
|
||||
const showLogos = tokens.some(
|
||||
(t) => tokenRegistry.get(t.info.mint.toBase58())?.icon !== undefined
|
||||
(t) => tokenRegistry.get(t.info.mint.toBase58())?.logoURI !== undefined
|
||||
);
|
||||
mappedTokens.forEach((totalByMint, mintAddress) => {
|
||||
const tokenDetails = tokenRegistry.get(mintAddress);
|
||||
@ -169,9 +169,9 @@ function HoldingsSummaryTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
<tr key={mintAddress}>
|
||||
{showLogos && (
|
||||
<td className="w-1 p-0 text-center">
|
||||
{tokenDetails?.icon && (
|
||||
{tokenDetails?.logoURI && (
|
||||
<img
|
||||
src={tokenDetails.icon}
|
||||
src={tokenDetails.logoURI}
|
||||
alt="token icon"
|
||||
className="token-icon rounded-circle border border-4 border-gray-dark"
|
||||
/>
|
||||
@ -182,7 +182,7 @@ function HoldingsSummaryTable({ tokens }: { tokens: TokenInfoWithPubkey[] }) {
|
||||
<Address pubkey={new PublicKey(mintAddress)} link />
|
||||
</td>
|
||||
<td>
|
||||
{totalByMint} {tokenDetails && tokenDetails.tokenSymbol}
|
||||
{totalByMint} {tokenDetails && tokenDetails.symbol}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
@ -89,16 +89,16 @@ function MintAccountCard({
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
{tokenInfo?.website && (
|
||||
{tokenInfo?.extensions?.website && (
|
||||
<tr>
|
||||
<td>Website</td>
|
||||
<td className="text-lg-right">
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href={tokenInfo.website}
|
||||
href={tokenInfo.extensions.website}
|
||||
>
|
||||
{tokenInfo.website}
|
||||
{tokenInfo.extensions.website}
|
||||
<span className="fe fe-external-link ml-2"></span>
|
||||
</a>
|
||||
</td>
|
||||
@ -160,7 +160,7 @@ function TokenAccountCard({
|
||||
);
|
||||
} else {
|
||||
balance = <>{info.tokenAmount.uiAmountString}</>;
|
||||
unit = tokenRegistry.get(info.mint.toBase58())?.tokenSymbol || "tokens";
|
||||
unit = tokenRegistry.get(info.mint.toBase58())?.symbol || "tokens";
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -50,7 +50,7 @@ import { useCluster, Cluster } from "providers/cluster";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Location } from "history";
|
||||
import { useQuery } from "utils/url";
|
||||
import { KnownTokenMap } from "@solana/spl-token-registry";
|
||||
import { TokenInfoMap } from "@solana/spl-token-registry";
|
||||
import { useTokenRegistry } from "providers/mints/token-registry";
|
||||
|
||||
const TRUNCATE_TOKEN_LENGTH = 10;
|
||||
@ -608,7 +608,7 @@ function InstructionDetails({
|
||||
function formatTokenName(
|
||||
pubkey: string,
|
||||
cluster: Cluster,
|
||||
tokenRegistry: KnownTokenMap
|
||||
tokenRegistry: TokenInfoMap
|
||||
): string {
|
||||
let display = displayAddress(pubkey, cluster, tokenRegistry);
|
||||
|
||||
|
@ -24,7 +24,7 @@ export function TokenLargestAccountsCard({ pubkey }: { pubkey: PublicKey }) {
|
||||
fetchLargestAccounts,
|
||||
]);
|
||||
const { tokenRegistry } = useTokenRegistry();
|
||||
const unit = tokenRegistry.get(mintAddress)?.tokenSymbol;
|
||||
const unit = tokenRegistry.get(mintAddress)?.symbol;
|
||||
const unitLabel = unit ? `(${unit})` : "";
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -118,7 +118,7 @@ function TokenInstruction(props: InfoProps) {
|
||||
const tokenDetails = tokenRegistry.get(mintAddress);
|
||||
|
||||
if (tokenDetails) {
|
||||
tokenSymbol = tokenDetails.tokenSymbol;
|
||||
tokenSymbol = tokenDetails.symbol;
|
||||
}
|
||||
|
||||
attributes.push(
|
||||
|
@ -50,7 +50,7 @@ export function TokenBalancesCard({ signature }: SignatureProps) {
|
||||
|
||||
const accountRows = rows.map(({ account, delta, balance, mint }) => {
|
||||
const key = account.toBase58() + mint;
|
||||
const units = tokenRegistry.get(mint)?.tokenSymbol || "tokens";
|
||||
const units = tokenRegistry.get(mint)?.symbol || "tokens";
|
||||
|
||||
return (
|
||||
<tr key={key}>
|
||||
|
@ -97,11 +97,11 @@ export function AccountHeader({ address }: { address: string }) {
|
||||
if (tokenDetails) {
|
||||
return (
|
||||
<div className="row align-items-end">
|
||||
{tokenDetails.icon && (
|
||||
{tokenDetails.logoURI && (
|
||||
<div className="col-auto">
|
||||
<div className="avatar avatar-lg header-avatar-top">
|
||||
<img
|
||||
src={tokenDetails.icon}
|
||||
src={tokenDetails.logoURI}
|
||||
alt="token logo"
|
||||
className="avatar-img rounded-circle border border-4 border-body"
|
||||
/>
|
||||
@ -111,7 +111,7 @@ export function AccountHeader({ address }: { address: string }) {
|
||||
|
||||
<div className="col mb-3 ml-n3 ml-md-n2">
|
||||
<h6 className="header-pretitle">Token</h6>
|
||||
<h2 className="header-title">{tokenDetails.tokenName}</h2>
|
||||
<h2 className="header-title">{tokenDetails.name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,34 +1,35 @@
|
||||
import React from "react";
|
||||
import {
|
||||
TokenListProvider,
|
||||
KnownToken,
|
||||
KnownTokenMap,
|
||||
TokenInfoMap,
|
||||
TokenInfo,
|
||||
TokenListContainer,
|
||||
} from "@solana/spl-token-registry";
|
||||
import { clusterSlug, useCluster } from "providers/cluster";
|
||||
|
||||
const TokenRegistryContext = React.createContext<KnownTokenMap>(new Map());
|
||||
const TokenRegistryContext = React.createContext<TokenInfoMap>(new Map());
|
||||
|
||||
type ProviderProps = { children: React.ReactNode };
|
||||
|
||||
export function TokenRegistryProvider({ children }: ProviderProps) {
|
||||
const [tokenRegistry, setTokenRegistry] = React.useState<KnownTokenMap>(
|
||||
const [tokenRegistry, setTokenRegistry] = React.useState<TokenInfoMap>(
|
||||
new Map()
|
||||
);
|
||||
const { cluster } = useCluster();
|
||||
|
||||
React.useEffect(() => {
|
||||
new TokenListProvider()
|
||||
.resolve(clusterSlug(cluster))
|
||||
.then((tokens: KnownToken[]) => {
|
||||
setTokenRegistry(
|
||||
tokens.reduce((map: KnownTokenMap, item: KnownToken) => {
|
||||
if (item.tokenName && item.tokenSymbol) {
|
||||
map.set(item.mintAddress, item);
|
||||
}
|
||||
return map;
|
||||
}, new Map())
|
||||
);
|
||||
});
|
||||
new TokenListProvider().resolve().then((tokens: TokenListContainer) => {
|
||||
const tokenList = tokens
|
||||
.filterByClusterSlug(clusterSlug(cluster))
|
||||
.getList();
|
||||
|
||||
setTokenRegistry(
|
||||
tokenList.reduce((map: TokenInfoMap, item: TokenInfo) => {
|
||||
map.set(item.address, item);
|
||||
return map;
|
||||
}, new Map())
|
||||
);
|
||||
});
|
||||
}, [cluster]);
|
||||
|
||||
return (
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
} from "@solana/web3.js";
|
||||
import { Cluster } from "providers/cluster";
|
||||
import { SerumMarketRegistry } from "serumMarketRegistry";
|
||||
import { KnownTokenMap } from "@solana/spl-token-registry";
|
||||
import { TokenInfoMap } from "@solana/spl-token-registry";
|
||||
|
||||
export type ProgramName = typeof PROGRAM_NAME_BY_ID[keyof typeof PROGRAM_NAME_BY_ID];
|
||||
|
||||
@ -109,14 +109,14 @@ export const SYSVAR_IDS = {
|
||||
export function addressLabel(
|
||||
address: string,
|
||||
cluster: Cluster,
|
||||
tokenRegistry?: KnownTokenMap
|
||||
tokenRegistry?: TokenInfoMap
|
||||
): string | undefined {
|
||||
return (
|
||||
PROGRAM_NAME_BY_ID[address] ||
|
||||
LOADER_IDS[address] ||
|
||||
SYSVAR_IDS[address] ||
|
||||
SYSVAR_ID[address] ||
|
||||
tokenRegistry?.get(address)?.tokenName ||
|
||||
tokenRegistry?.get(address)?.name ||
|
||||
SerumMarketRegistry.get(address, cluster)
|
||||
);
|
||||
}
|
||||
@ -124,7 +124,7 @@ export function addressLabel(
|
||||
export function displayAddress(
|
||||
address: string,
|
||||
cluster: Cluster,
|
||||
tokenRegistry: KnownTokenMap
|
||||
tokenRegistry: TokenInfoMap
|
||||
): string {
|
||||
return addressLabel(address, cluster, tokenRegistry) || address;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user