Skip to content

Commit

Permalink
Use UTL API directly for address token info (#298)
Browse files Browse the repository at this point in the history
The problem here was not with our request coalescer, the
`getMultipleAccounts` requests are coming from the UTL SDK. Specifically
on the transaction page where we use `<Address pubkey={pubkey} ...
fetchTokenLabelInfo`. We do this on addresses that may be, but probably
are not, token mints, ie every address in a transaction.

Previously this check came from the baked in legacy token list. When the
token list was removed it was moved to the UTL SDK. The UTL SDK first
calls the UTL API to see if the address has known token info. If it does
not then it makes an on-chain call using `getMultipleAccounts` to fetch
the token info from the Metaplex metadata program if it exists.

I don't think this fallback is appropriate for our use case of
`fetchTokenLabelInfo` on addresses. Most addresses displayed are not
tokens, and we display many addresses simultaneously. This is leading to
many unnecessary `getMultipleAccounts` calls, and rate limiting.

Instead for this use case, we should only use the UTL API. This may mean
that brand new tokens can be displayed in eg the token details page, but
won't be correctly labelled in addresses. But this is a better tradeoff
than making an on-chain request for every address that we render that
may be a token.

Note that we already use the same public API for search
(https://github.com/solana-labs/explorer/blob/master/app/utils/token-search.ts),
where the SDK also can't provide an on-chain fallback.
  • Loading branch information
mcintyre94 authored Sep 26, 2023
1 parent 15a5268 commit 3e5b2a7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
4 changes: 2 additions & 2 deletions app/components/common/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';
import { useState } from 'react';
import useAsyncEffect from 'use-async-effect';

import { getTokenInfo } from '@/app/utils/token-info';
import { getTokenInfoWithoutOnChainFallback } from '@/app/utils/token-info';

import { Copyable } from './Copyable';

Expand Down Expand Up @@ -125,7 +125,7 @@ const useTokenInfo = (fetchTokenLabelInfo: boolean | undefined, pubkey: string)
if (!fetchTokenLabelInfo) return;
if (!info) {
try {
const token = await getTokenInfo(new PublicKey(pubkey), cluster, url);
const token = await getTokenInfoWithoutOnChainFallback(new PublicKey(pubkey), cluster);
if (isMounted()) {
setInfo(token);
}
Expand Down
36 changes: 33 additions & 3 deletions app/utils/token-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,36 @@ export async function getTokenInfo(
return token;
}

type UtlApiResponse = {
content: Token[]
}

export async function getTokenInfoWithoutOnChainFallback(
address: PublicKey,
cluster: Cluster
): Promise<Token | undefined> {
const chainId = getChainId(cluster);
if (!chainId) return undefined;

// Request token info directly from UTL API
// We don't use the SDK here because we don't want it to fallback to an on-chain request
const response = await fetch(`https://token-list-api.solana.cloud/v1/mints?chainId=${chainId}`, {
body: JSON.stringify({ addresses: [address.toBase58()] }),
headers: {
"Content-Type": "application/json",
},
method: 'POST',
})

if (response.status >= 400) {
console.error(`Error calling UTL API for address ${address} on chain ID ${chainId}. Status ${response.status}`);
return undefined
}

const fetchedData = await response.json() as UtlApiResponse;
return fetchedData.content[0];
}

async function getFullLegacyTokenInfoUsingCdn(
address: PublicKey,
chainId: ChainId
Expand Down Expand Up @@ -111,9 +141,9 @@ export async function getFullTokenInfo(
if (!sdkTokenInfo) {
return legacyCdnTokenInfo
? {
...legacyCdnTokenInfo,
verified: true,
}
...legacyCdnTokenInfo,
verified: true,
}
: undefined;
}

Expand Down

1 comment on commit 3e5b2a7

@vercel
Copy link

@vercel vercel bot commented on 3e5b2a7 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

explorer – ./

explorer-git-master-solana-labs.vercel.app
explorer.solana.com
explorer-solana-labs.vercel.app

Please sign in to comment.