- {fair !== undefined
+ {fair !== undefined && toTokenInfo && fromTokenInfo
? `1 ${toTokenInfo.symbol} = ${fair.toFixed(
fromMintInfo?.decimals
)} ${fromTokenInfo.symbol}`
@@ -103,13 +101,9 @@ function InfoButton() {
function InfoDetails() {
const { fromMint, toMint } = useSwapContext();
const { swapClient } = useDexContext();
- const tokenList = useTokenList();
- const fromMintTicker = tokenList
- .filter((t) => t.address === fromMint.toString())
- .map((t) => t.symbol)[0];
- const toMintTicker = tokenList
- .filter((t) => t.address === toMint.toString())
- .map((t) => t.symbol)[0];
+ const tokenMap = useTokenMap();
+ const fromMintTicker = tokenMap.get(fromMint.toString())?.symbol;
+ const toMintTicker = tokenMap.get(toMint.toString())?.symbol;
const addresses = [
{ ticker: fromMintTicker, mint: fromMint },
{ ticker: toMintTicker, mint: toMint },
diff --git a/src/swap/components/Settings.tsx b/src/swap/components/Settings.tsx
index df273d4..3591347 100644
--- a/src/swap/components/Settings.tsx
+++ b/src/swap/components/Settings.tsx
@@ -32,7 +32,7 @@ import { SettingsOutlined as Settings, Close } from "@material-ui/icons";
import PopupState, { bindTrigger, bindPopover } from "material-ui-popup-state";
import { useSwapContext, useSwapFair } from "./context/Swap";
import { useMarket, useOpenOrders, useDexContext } from "./context/Dex";
-import { useTokenList } from "./context/TokenList";
+import { useTokenMap } from "./context/TokenList";
import { useMint } from "./context/Mint";
import { useOwnedTokenAccount } from "./context/Token";
@@ -298,17 +298,17 @@ function OpenOrdersRow({
const [ooAccount, setOoAccount] = useState(openOrders[0]);
const { swapClient } = useDexContext();
const marketClient = useMarket(market);
- const tokenList = useTokenList();
+ const tokenMap = useTokenMap();
const base = useMint(marketClient?.baseMintAddress);
const quote = useMint(marketClient?.quoteMintAddress);
const baseWallet = useOwnedTokenAccount(marketClient?.baseMintAddress);
const quoteWallet = useOwnedTokenAccount(marketClient?.quoteMintAddress);
- const baseTicker = tokenList
- .filter((t) => t.address === marketClient?.baseMintAddress.toString())
- .map((t) => t.symbol)[0];
- const quoteTicker = tokenList
- .filter((t) => t.address === marketClient?.quoteMintAddress.toString())
- .map((t) => t.symbol)[0];
+ const baseTicker = marketClient
+ ? tokenMap.get(marketClient?.baseMintAddress.toString())?.symbol
+ : "-";
+ const quoteTicker = marketClient
+ ? tokenMap.get(marketClient?.quoteMintAddress.toString())?.symbol
+ : "-";
const marketName =
baseTicker && quoteTicker
? `${baseTicker} / ${quoteTicker}`
diff --git a/src/swap/components/Swap.tsx b/src/swap/components/Swap.tsx
index 1aa00b3..c4f37a2 100644
--- a/src/swap/components/Swap.tsx
+++ b/src/swap/components/Swap.tsx
@@ -21,7 +21,7 @@ import {
useMarket,
} from "./context/Dex";
import { MintContextProvider, useMint } from "./context/Mint";
-import { TokenListContextProvider, useTokenList } from "./context/TokenList";
+import { TokenListContextProvider, useTokenMap } from "./context/TokenList";
import { TokenContextProvider, useOwnedTokenAccount } from "./context/Token";
import TokenDialog from "./TokenDialog";
import { SettingsButton } from "./Settings";
@@ -228,8 +228,8 @@ function TokenButton({
}
export function TokenIcon({ mint, style }: { mint: PublicKey; style: any }) {
- const tokenList = useTokenList();
- let tokenInfo = tokenList.filter((t) => t.address === mint.toString())[0];
+ const tokenMap = useTokenMap();
+ let tokenInfo = tokenMap.get(mint.toString());
return (
- {tokenInfo.logoURI ? (
-
+ {tokenInfo?.logoURI ? (
+
) : (
)}
@@ -248,10 +248,10 @@ export function TokenIcon({ mint, style }: { mint: PublicKey; style: any }) {
}
function TokenName({ mint }: { mint: PublicKey }) {
- const tokenList = useTokenList();
- let tokenInfo = tokenList.filter((t) => t.address === mint.toString())[0];
+ const tokenMap = useTokenMap();
+ let tokenInfo = tokenMap.get(mint.toString());
return (
-
{tokenInfo.symbol}
+
{tokenInfo?.symbol}
);
}
diff --git a/src/swap/components/TokenDialog.tsx b/src/swap/components/TokenDialog.tsx
index 64cfdf4..3b71c82 100644
--- a/src/swap/components/TokenDialog.tsx
+++ b/src/swap/components/TokenDialog.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useState, useMemo } from "react";
import { PublicKey } from "@solana/web3.js";
import {
makeStyles,
@@ -12,7 +12,7 @@ import {
} from "@material-ui/core";
import { TokenIcon } from "./Swap";
import { useDexContext } from "./context/Dex";
-import { useTokenList } from "./context/TokenList";
+import { useTokenMap } from "./context/TokenList";
import { USDC_MINT, USDT_MINT } from "../utils/pubkeys";
const useStyles = makeStyles(() => ({
@@ -39,6 +39,9 @@ export default function TokenDialog({
const [tokenFilter, setTokenFilter] = useState("");
const styles = useStyles();
const { swapClient } = useDexContext();
+ const tokens = useMemo(() => {
+ return swapClient.tokens().concat([USDC_MINT, USDT_MINT]);
+ }, [swapClient]);
return (
- {swapClient
- .tokens()
- .concat([USDC_MINT, USDT_MINT])
- .map((mint) => (
- {
- setMint(mint);
- onClose();
- }}
- />
- ))}
+ {tokens.map((mint) => (
+ {
+ setMint(mint);
+ onClose();
+ }}
+ />
+ ))}
@@ -101,13 +101,15 @@ function TokenListItem({
}
function TokenName({ mint }: { mint: PublicKey }) {
- const tokenList = useTokenList();
- let tokenInfo = tokenList.filter((t) => t.address === mint.toString())[0];
+ const tokenMap = useTokenMap();
+ let tokenInfo = tokenMap.get(mint.toString());
return (
- {tokenInfo.symbol}
+
+ {tokenInfo?.symbol}
+
- {tokenInfo.name}
+ {tokenInfo?.name}
);
diff --git a/src/swap/components/context/Dex.tsx b/src/swap/components/context/Dex.tsx
index e7f59c0..f8179e7 100644
--- a/src/swap/components/context/Dex.tsx
+++ b/src/swap/components/context/Dex.tsx
@@ -9,7 +9,7 @@ import {
} from "@project-serum/serum";
import { PublicKey } from "@solana/web3.js";
import { DEX_PID } from "../../utils/pubkeys";
-import { useTokenList } from "./TokenList";
+import { useTokenMap } from "./TokenList";
type DexContext = {
// Maps market address to open orders accounts.
@@ -196,14 +196,14 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
}
export function useMarketName(market: PublicKey): string {
- const tokenList = useTokenList();
+ const tokenMap = useTokenMap();
const marketClient = useMarket(market);
- const baseTicker = tokenList
- .filter((t) => t.address === marketClient?.baseMintAddress.toString())
- .map((t) => t.symbol)[0];
- const quoteTicker = tokenList
- .filter((t) => t.address === marketClient?.quoteMintAddress.toString())
- .map((t) => t.symbol)[0];
+ const baseTicker = marketClient
+ ? tokenMap.get(marketClient?.baseMintAddress.toString())?.symbol
+ : "-";
+ const quoteTicker = marketClient
+ ? tokenMap.get(marketClient?.quoteMintAddress.toString())?.symbol
+ : "-";
const name = `${baseTicker} / ${quoteTicker}`;
return name;
}
diff --git a/src/swap/components/context/TokenList.tsx b/src/swap/components/context/TokenList.tsx
index 073a9b6..e5d2cfd 100644
--- a/src/swap/components/context/TokenList.tsx
+++ b/src/swap/components/context/TokenList.tsx
@@ -1,24 +1,36 @@
-import React, { useContext } from "react";
-import { TokenListContainer, TokenInfo } from "@solana/spl-token-registry";
+import React, { useContext, useMemo } from "react";
+import { TokenInfo } from "@solana/spl-token-registry";
+type TokenListContext = {
+ tokenMap: Map
;
+};
const _TokenListContext = React.createContext(null);
export function TokenListContextProvider(props: any) {
+ const tokenList = useMemo(() => props.tokenList.getList(), [props.tokenList]);
+ const tokenMap = useMemo(() => {
+ const tokenMap = new Map();
+ tokenList.forEach((t: TokenInfo) => {
+ tokenMap.set(t.address, t);
+ });
+ return tokenMap;
+ }, [tokenList]);
return (
- <_TokenListContext.Provider value={{ tokenList: props.tokenList }}>
+ <_TokenListContext.Provider value={{ tokenMap }}>
{props.children}
);
}
-type TokenListContext = {
- tokenList: TokenListContainer;
-};
-
-export function useTokenList(): TokenInfo[] {
+function useTokenListContext(): TokenListContext {
const ctx = useContext(_TokenListContext);
if (ctx === null) {
throw new Error("Context not available");
}
- return ctx.tokenList.getList();
+ return ctx;
+}
+
+export function useTokenMap(): Map {
+ const { tokenMap } = useTokenListContext();
+ return tokenMap;
}