Remove MintContextProvider

This commit is contained in:
armaniferrante 2021-05-17 17:21:25 -07:00
parent 5db9a61b35
commit 395d7c70be
No known key found for this signature in database
GPG Key ID: 58BEF301E91F7828
6 changed files with 66 additions and 90 deletions

View File

@ -10,7 +10,7 @@ import PopupState, { bindTrigger, bindPopover } from "material-ui-popup-state";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { useTokenMap } from "../context/TokenList"; import { useTokenMap } from "../context/TokenList";
import { useSwapContext, useSwapFair } from "../context/Swap"; import { useSwapContext, useSwapFair } from "../context/Swap";
import { useMint } from "../context/Mint"; import { useMint } from "../context/Token";
import { useRoute, useMarketName, useFair } from "../context/Dex"; import { useRoute, useMarketName, useFair } from "../context/Dex";
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({

View File

@ -24,8 +24,7 @@ import {
import { Close } from "@material-ui/icons"; import { Close } from "@material-ui/icons";
import { useMarket, useOpenOrders, useDexContext } from "../context/Dex"; import { useMarket, useOpenOrders, useDexContext } from "../context/Dex";
import { useTokenMap } from "../context/TokenList"; import { useTokenMap } from "../context/TokenList";
import { useMint } from "../context/Mint"; import { useMint, useOwnedTokenAccount } from "../context/Token";
import { useOwnedTokenAccount } from "../context/Token";
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
table: {}, table: {},

View File

@ -17,9 +17,8 @@ import {
useRouteVerbose, useRouteVerbose,
useMarket, useMarket,
} from "../context/Dex"; } from "../context/Dex";
import { useMint } from "../context/Mint";
import { useTokenMap } from "../context/TokenList"; import { useTokenMap } from "../context/TokenList";
import { useOwnedTokenAccount } from "../context/Token"; import { useMint, useOwnedTokenAccount } from "../context/Token";
import { useCanSwap } from "../context/Swap"; import { useCanSwap } from "../context/Swap";
import TokenDialog from "./TokenDialog"; import TokenDialog from "./TokenDialog";
import { SettingsButton } from "./Settings"; import { SettingsButton } from "./Settings";

View File

@ -1,64 +0,0 @@
import React, { useContext, useState } from "react";
import { useAsync } from "react-async-hook";
import { Provider } from "@project-serum/anchor";
import { PublicKey, Account } from "@solana/web3.js";
import { MintInfo, Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
const _MintContext = React.createContext<null | MintContext>(null);
type MintContext = {
mintCache: Map<string, MintInfo>;
setMintCache: (m: Map<string, MintInfo>) => void;
provider: Provider;
};
export function MintContextProvider(props: any) {
const provider = props.provider;
const [mintCache, setMintCache] = useState(new Map<string, MintInfo>());
return (
<_MintContext.Provider
value={{
mintCache,
setMintCache,
provider,
}}
>
{props.children}
</_MintContext.Provider>
);
}
export function useMint(mint?: PublicKey): MintInfo | undefined | null {
const ctx = useContext(_MintContext);
if (ctx === null) {
throw new Error("Mint context not found");
}
// Lazy load the mint account if needeed.
const asyncMintInfo = useAsync(async () => {
if (!mint) {
return undefined;
}
if (ctx.mintCache.get(mint.toString())) {
return ctx.mintCache.get(mint.toString());
}
const mintClient = new Token(
ctx.provider.connection,
mint,
TOKEN_PROGRAM_ID,
new Account()
);
const mintInfo = await mintClient.getMintInfo();
let cache = new Map(ctx.mintCache);
cache.set(mint.toString(), mintInfo);
ctx.setMintCache(cache);
return mintInfo;
}, [ctx.provider.connection, mint]);
if (asyncMintInfo.result) {
return asyncMintInfo.result;
}
return undefined;
}

View File

@ -1,9 +1,17 @@
import React, { useContext, useState, useEffect } from "react"; import React, { useContext, useState, useEffect } from "react";
import { PublicKey } from "@solana/web3.js"; import { useAsync } from "react-async-hook";
import { AccountInfo as TokenAccount } from "@solana/spl-token"; import { Provider } from "@project-serum/anchor";
import { PublicKey, Account } from "@solana/web3.js";
import {
MintInfo,
AccountInfo as TokenAccount,
Token,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import { getOwnedTokenAccounts } from "../utils/tokens"; import { getOwnedTokenAccounts } from "../utils/tokens";
export type TokenContext = { export type TokenContext = {
provider: Provider;
ownedTokenAccounts: ownedTokenAccounts:
| { publicKey: PublicKey; account: TokenAccount }[] | { publicKey: PublicKey; account: TokenAccount }[]
| undefined; | undefined;
@ -29,6 +37,7 @@ export function TokenContextProvider(props: any) {
<_TokenContext.Provider <_TokenContext.Provider
value={{ value={{
ownedTokenAccounts, ownedTokenAccounts,
provider,
}} }}
> >
{props.children} {props.children}
@ -36,15 +45,20 @@ export function TokenContextProvider(props: any) {
); );
} }
function useTokenContext() {
const ctx = useContext(_TokenContext);
if (ctx === null) {
throw new Error("Context not available");
}
return ctx;
}
// Null => none exists. // Null => none exists.
// Undefined => loading. // Undefined => loading.
export function useOwnedTokenAccount( export function useOwnedTokenAccount(
mint?: PublicKey mint?: PublicKey
): { publicKey: PublicKey; account: TokenAccount } | null | undefined { ): { publicKey: PublicKey; account: TokenAccount } | null | undefined {
const ctx = useContext(_TokenContext); const ctx = useTokenContext();
if (ctx === null) {
throw new Error("Context not available");
}
if (mint === undefined) { if (mint === undefined) {
return mint; return mint;
} }
@ -69,3 +83,34 @@ export function useOwnedTokenAccount(
); );
return tokenAccounts[0]; return tokenAccounts[0];
} }
// Cache storing all previously fetched mint infos.
const _MINT_CACHE = new Map<string, MintInfo>();
export function useMint(mint?: PublicKey): MintInfo | undefined | null {
const { provider } = useTokenContext();
// Lazy load the mint account if needeed.
const asyncMintInfo = useAsync(async () => {
if (!mint) {
return undefined;
}
if (_MINT_CACHE.get(mint.toString())) {
return _MINT_CACHE.get(mint.toString());
}
const mintClient = new Token(
provider.connection,
mint,
TOKEN_PROGRAM_ID,
new Account()
);
const mintInfo = await mintClient.getMintInfo();
_MINT_CACHE.set(mint.toString(), mintInfo);
return mintInfo;
}, [provider.connection, mint]);
if (asyncMintInfo.result) {
return asyncMintInfo.result;
}
return undefined;
}

View File

@ -4,7 +4,6 @@ import { Provider } from "@project-serum/anchor";
import { Swap as SwapClient } from "@project-serum/swap"; import { Swap as SwapClient } from "@project-serum/swap";
import { SwapContextProvider } from "./context/Swap"; import { SwapContextProvider } from "./context/Swap";
import { DexContextProvider } from "./context/Dex"; import { DexContextProvider } from "./context/Dex";
import { MintContextProvider } from "./context/Mint";
import { TokenListContextProvider } from "./context/TokenList"; import { TokenListContextProvider } from "./context/TokenList";
import { TokenContextProvider } from "./context/Token"; import { TokenContextProvider } from "./context/Token";
import SwapCard from "./components/Swap"; import SwapCard from "./components/Swap";
@ -31,20 +30,18 @@ export default function Swap({
const swapClient = new SwapClient(provider, tokenList); const swapClient = new SwapClient(provider, tokenList);
return ( return (
<TokenListContextProvider tokenList={tokenList}> <TokenListContextProvider tokenList={tokenList}>
<MintContextProvider provider={provider}> <TokenContextProvider provider={provider}>
<TokenContextProvider provider={provider}> <DexContextProvider swapClient={swapClient}>
<DexContextProvider swapClient={swapClient}> <SwapContextProvider
<SwapContextProvider fromMint={fromMint}
fromMint={fromMint} toMint={toMint}
toMint={toMint} fromAmount={fromAmount}
fromAmount={fromAmount} toAmount={toAmount}
toAmount={toAmount} >
> <SwapCard style={style} />
<SwapCard style={style} /> </SwapContextProvider>
</SwapContextProvider> </DexContextProvider>
</DexContextProvider> </TokenContextProvider>
</TokenContextProvider>
</MintContextProvider>
</TokenListContextProvider> </TokenListContextProvider>
); );
} }