Skip to content

Commit

Permalink
replace useInterval with useQuery - not perfect, but not spamming the…
Browse files Browse the repository at this point in the history
… rpic endpoint either - for #207

Signed-off-by: Sven Dowideit <[email protected]>
  • Loading branch information
SvenDowideit committed Jul 14, 2022
1 parent bf388df commit 19bdfb7
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 96 deletions.
5 changes: 3 additions & 2 deletions src/renderer/components/MintInfoView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export function MintInfoView(props: { mintKey: string }) {

const { loadStatus, account: mintInfo /* , error */ } = useParsedAccount(
net,
mintKey
mintKey,
{}
);

// ("idle" or "error" or "loading" or "success").
Expand All @@ -80,7 +81,7 @@ export function MintInfoView(props: { mintKey: string }) {
);
}

logger.info('mintInfo:', JSON.stringify(mintInfo));
// logger.info('mintInfo:', JSON.stringify(mintInfo));
const hasAuthority =
mintInfo.accountInfo.data?.parsed.info.mintAuthority ===
fromKey.publicKey?.toString();
Expand Down
9 changes: 5 additions & 4 deletions src/renderer/components/tokens/MetaplexMintMetaDataView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ export function MetaplexMintMetaDataView(props: { mintKey: string }) {
} = useQuery<metaplex.programs.metadata.Metadata | undefined, Error>(
['token-mint-meta', { net, pubKey }],
// TODO: need to be able to say "we errored, don't keep looking" - there doesn't need to be metadata...
queryTokenMetadata
);
logger.silly(
`queryTokenMetadata(${pubKey}): ${loadStatus} - error: ${error}`
queryTokenMetadata,
{}
);
// logger.silly(
// `queryTokenMetadata(${pubKey}): ${loadStatus} - error: ${error}`
// );

// ("idle" or "error" or "loading" or "success").
if (loadStatus === 'loading') {
Expand Down
100 changes: 66 additions & 34 deletions src/renderer/components/tokens/MetaplexTokenData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import * as metaplex from '@metaplex/js';
import * as sol from '@solana/web3.js';

import { getTokenMetadata } from '../../data/accounts/getAccount';
import { useQuery } from 'react-query';
import {
getTokenMetadata,
queryTokenMetadata,
} from '../../data/accounts/getAccount';
import { useAppSelector, useInterval } from '../../hooks';

import {
Expand All @@ -25,42 +29,70 @@ function DataPopover(props: { mintPubKey: sol.PublicKey | undefined }) {
const { connection } = useConnection();
const { net, status } = useAppSelector(selectValidatorNetworkState);

const [name, setName] = useState<string>('Workbench token');
const [symbol, setSymbol] = useState<string>('WORKBENCH');
const [uri, setUri] = useState<string>(
'https://github.com/workbenchapp/solana-workbench/'
);
const [sellerFeeBasisPoints, setSellerFeeBasisPoints] = useState<number>(10);
const [metaData, setMetaData] =
useState<metaplex.programs.metadata.Metadata>();
// const [metaData, setMetaData] =
// useState<metaplex.programs.metadata.Metadata>();

useInterval(() => {
// I don't think i can useEffect, as we need to keep polling until the metadata exists
if (status !== NetStatus.Running) {
return;
}
if (metaData && metaData.data.mint !== mintPubKey?.toString()) {
setMetaData(undefined);
// useInterval(() => {
// // I don't think i can useEffect, as we need to keep polling until the metadata exists
// if (status !== NetStatus.Running) {
// return;
// }
// if (metaData && metaData.data?.mint !== mintPubKey?.toString()) {
// setMetaData(undefined);

return;
}
if (metaData) {
return;
}
if (mintPubKey) {
getTokenMetadata(net, mintPubKey.toString())
.then((md) => {
setMetaData(md);
// TODO: no, this is wrong, only want this to happen once... (and then refresh onchange)
setName(md.data.data.name);
setSymbol(md.data.data.symbol);
setUri(md.data.data.uri);
setSellerFeeBasisPoints(md.data.data.sellerFeeBasisPoints);
return md;
})
.catch(logger.info);
// return;
// }
// if (metaData) {
// return;
// }
// if (mintPubKey) {
// getTokenMetadata(net, mintPubKey.toString())
// .then((md) => {
// setMetaData(md);
// // TODO: no, this is wrong, only want this to happen once... (and then refresh onchange)
// setName(md.data.data.name);
// setSymbol(md.data.data.symbol);
// setUri(md.data.data.uri);
// setSellerFeeBasisPoints(md.data.data.sellerFeeBasisPoints);
// return md;
// })
// .catch(logger.info);
// }
// }, 666);
const pubKey = mintPubKey.toString();
const {
status: loadStatus,
error,
data: metaData,
} = useQuery<metaplex.programs.metadata.Metadata | undefined, Error>(
['token-mint-meta', { net, pubKey }],
// TODO: need to be able to say "we errored, don't keep looking" - there doesn't need to be metadata...
queryTokenMetadata,
{
// enabled: false,
}
}, 666);
);
// logger.silly(
// `queryTokenMetadata(${pubKey}): ${loadStatus} - error: ${error}`
// );

const [name, setName] = useState<string>(
metaData?.data?.data.name || 'Workbench token'
);
const [symbol, setSymbol] = useState<string>(
metaData?.data?.data.symbol || 'WORKBENCH'
);
const [uri, setUri] = useState<string>(
metaData?.data?.data.uri ||
'https://github.com/workbenchapp/solana-workbench/'
);
const [sellerFeeBasisPoints, setSellerFeeBasisPoints] = useState<number>(
metaData?.data?.data.sellerFeeBasisPoints || 10
);

if (loadStatus !== 'success' && loadStatus !== 'error') {
return <b>loading</b>;
}

async function createOurMintMetadata() {
// Create a new token
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/components/tokens/TokensListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export function TokensListView(props: { pubKey: string | undefined }) {
['parsed-token-account', { net, pubKey }],
queryTokenAccounts
);
logger.silly(
`queryTokenAccounts(${pubKey}): ${loadStatus} - error: ${error}`
);
// logger.silly(
// `queryTokenAccounts(${pubKey}): ${loadStatus} - error: ${error}`
// );

// ("idle" or "error" or "loading" or "success").
if (loadStatus !== 'success') {
Expand Down
89 changes: 36 additions & 53 deletions src/renderer/data/accounts/getAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,8 @@ export async function getParsedAccount(
const solConn = new sol.Connection(netToURL(net));
const key = new sol.PublicKey(pubKey);

// TODO: SVENSVENSVEN - this is the crux of tokens stuff...
const solAccount = await solConn.getParsedAccountInfo(key);

logger.info('SSSS getParsedAccount', pubKey);

const response: AccountInfo = {
accountId: key,
accountInfo: solAccount.value,
Expand Down Expand Up @@ -83,21 +80,26 @@ export async function queryParsedAccount(params: ParsedAccountParams) {

return accountInfo;
}
export function useParsedAccount(net: Net, pubKey: string | undefined) {
export function useParsedAccount(
net: Net,
pubKey: string | undefined,
queryOption
) {
const {
status: loadStatus,
error,
data: accountData,
} = useQuery<sol.AccountInfo<sol.ParsedAccountData>, Error>(
['parsed-account', { net, pubKey }],
queryParsedAccount
queryParsedAccount,
queryOption || {}
);
const account = accountData;
logger.silly(
`queryParsedAccount(${pubKey}): ${loadStatus} - error: ${error}: ${JSON.stringify(
account
)}`
);
// logger.silly(
// `queryParsedAccount(${pubKey}): ${loadStatus} - error: ${error}: ${JSON.stringify(
// account
// )}`
// );
return { loadStatus, account, error };
}
/// ///////////////////////////////////////////////////////////////////
Expand All @@ -106,12 +108,14 @@ export function useParsedAccount(net: Net, pubKey: string | undefined) {
// if you absoluetly need to current latest, don't use this function :)
// it is written to avoid RPC requests if at all possible, and is used in conjunction with the programChanges subscriptions
export function getAccount(net: Net, pubKey: string): AccountInfo | undefined {
// logger.silly('getAccountInfo ', pubKey);

const cachedResponse = cache.get(`${net}_${pubKey}`);
if (cachedResponse) {
return cachedResponse;
}

logger.silly('getAccountInfo cache miss', pubKey, pubKey.toString());
// logger.silly('getAccountInfo cache miss', pubKey, pubKey.toString());

const response: AccountInfo = {
accountId: new sol.PublicKey(pubKey),
Expand Down Expand Up @@ -139,30 +143,10 @@ export type TokenAccountArray = Array<{
account: sol.AccountInfo<sol.ParsedAccountData>;
}>;

const tokenAccountCache = new LRUCache<
string,
sol.RpcResponseAndContext<TokenAccountArray>
>({
maxSize: 500,
entryExpirationTimeInMS: 60000,
});

export function forceRequestTokenAccount(net: Net, pubKey: string) {
cache.delete(`${net}_${pubKey}_getTokenAccounts`);
}

export async function getTokenAccounts(
net: Net,
pubKey: string
): Promise<sol.RpcResponseAndContext<TokenAccountArray>> {
// logger.silly('getTokenAccounts', { pubKey });
const cachedResponse = tokenAccountCache.peek(
`${net}_${pubKey}_getTokenAccounts`
);
if (cachedResponse) {
return cachedResponse;
}

const solConn = new sol.Connection(netToURL(net));
const key = new sol.PublicKey(pubKey);
const filter: sol.TokenAccountsFilter = {
Expand All @@ -173,9 +157,6 @@ export async function getTokenAccounts(
filter
);

logger.silly('getTokenAccounts cache miss', pubKey, tokenAccounts);

tokenAccountCache.set(`${net}_${pubKey}_getTokenAccounts`, tokenAccounts);
return tokenAccounts;
}
// react-query support
Expand All @@ -202,18 +183,20 @@ export async function getTokenMetadata(
tokenPublicKey: string
): Promise<metaplex.programs.metadata.Metadata> {
const conn = new metaplex.Connection(netToURL(net), 'finalized');
// try {
const meta = await metaplex.programs.metadata.Metadata.findByMint(
conn,
tokenPublicKey
);
// logger.info('GETOKENMETA!: ', JSON.stringify(meta));

// const meta = metaplex.programs.metadata.Metadata.load(conn, tokenPublicKey);
return meta;
// } catch (e) {
// logger.error('metadata load', e);
// }
try {
// TODO: this console.logs "metadata load Error: Unable to find account: HKCjVqNU35H3zsXAVetgo743qCDMu7ssGnET1yvN4RSJ"
const meta = await metaplex.programs.metadata.Metadata.findByMint(
conn,
tokenPublicKey
);

// const meta = metaplex.programs.metadata.Metadata.load(conn, tokenPublicKey);
return meta;
} catch (e) {
logger.error('metadata load', e);
}
const fake: metaplex.programs.metadata.Metadata = {};
return fake;
}
// react-query support
// TODO: if i understood right, re-querying will make a non-blocking request, so caould be used to update on action?
Expand All @@ -225,16 +208,16 @@ export async function queryTokenMetadata(
): metaplex.programs.metadata.Metadata | undefined {
const [, { net, pubKey }] = params.queryKey;

// logger.info(`OKENMETA!: ${pubKey}`);

const meta = await getTokenMetadata(net, pubKey);
try {
const meta = await getTokenMetadata(net, pubKey);
return meta;
} catch (e) {
logger.warn(e);
}
// if (!meta) {
// throw Error(`tokenmetadata for ${pubKey} Not found`);
// }

// logger.info('OKENMETA!: ', JSON.stringify(meta));

return meta;
return undefined;
}
/// ///////////////////////////////////////////////////////////////////

Expand Down
2 changes: 2 additions & 0 deletions src/renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const queryClient = new QueryClient({
queries: {
// retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),
retry: false,
staleTime: 10000, // milliSeconds
cacheTime: 60000, // milliSeconds
},
},
});
Expand Down

0 comments on commit 19bdfb7

Please sign in to comment.