Trying to get nftMetadata() for the last 100 nfts in a wallet, but running into rate limits

I made priceData await for getNftMetaData().then()

It works as in no Axios Errors, but it’s waiting for each request now and it takes almost a minute to get all data. Is this normal?

      const priceData = await getNftMetaData(
        transfer.token_address,
        transfer.token_id
      )
        .then((nftData) => {
          console.log({
            name: nftData.name,
            price: transfer.value,
          });
          return {
            name: nftData.name,
            price: transfer.value,
          };
        })
        .catch((error) => {
          console.log(error);
          return error;
        });
      console.log(priceData);

To be honest, I don’t know where and how to add the settimeout(), I tried in all places.

usually you can use an equivalent of sleep function where you can specify a number of milliseconds, you will have to use it with await.

1 minute seems too much, how many request you are making?

1 Like

Maximum page size is 100 for getWalletNftTransfers, so 100 requests to getNftMetaData

you could also try to show the results almost realtime when you get the info and not to wait until all the requests finished for all 100 of them

1 Like

If I result = await getNftMetadata.then() it still takes about 1 second for each request. 20 NFTs to show, 20 seconds to load

If I process the result inside then from getNftMetadata().then without awaiting for a return I get axios errors as it’s not finishing the request before doing another one. Did I understand ok here?

It would be ok if I could take this second choice and stick a delay somehow in there. Sorry I’m such a nub.

This one outputs stuff like { name: ‘AxiosError’, price: ‘800000000000000000’ }

        getNftMetaData(transfer.token_address, transfer.token_id)
        .then((nftData) => {
          console.log({
            name: nftData.name,
            price: transfer.value,
          });
        })
        .catch((error) => {
          console.log(error);
        });

This works but it takes ~1 second for each result to get to console

        const priceData = await getNftMetaData(
        transfer.token_address,
        transfer.token_id
      )
        .then((nftData) => {
          console.log({
            name: nftData.name,
            price: transfer.value,
          });
          return {
            name: nftData.name,
            price: transfer.value,
          };
        })
        .catch((error) => {
          console.log(error);
          return error;
        });
      console.log(priceData);```


***edited, it was the other way around

there are ways to improve it, you could make a number of requests concurrently in every second so that you don’t hit the rate limit, you can also increase the account limit of compute units in the future if needed and you will be able to make more requests in a second in that case

I don’t know the code that you should use

1 Like

I’m in hell since yesterday.

I give up and I’ll use rapidapi for these nft queries, it gets all the data in just one easy query there, so much easier. I had that working great, just wanted to use Moralis instead.

Thanks a lot @cryptokid, much appreciated.

function getIt() {
    return new Promise((resolve, reject) => {

      let someArray = [];

      const interval = setInterval(async () => {

        if (intervalIterator > 9) {
          clearInterval(interval);
          resolve(someArray);
        }

        const transfer = onlyTrasnfersWithValue[intervalIterator];
        
        getNftMetaData(transfer.token_address, transfer.token_id).then(
          (result) => {
            someArray.push({
              ...result,
              price: onlyTrasnfersWithValue[intervalIterator].value,
            });
          }
        );

        intervalIterator += 1;
      }, 260);
    });
  }

  getIt().then((result) => {
    console.log("got ", result.length," results");
    res.send(result);
  });

Whenever setInterval is less than 260ms errors start popping up.

Basically I need to upgrade to lower that number?

You can upgrade if you want to lower that number. You don’t have to necessarily do it now.

A free plan has a limit of 25 compute units per second, a pro plan of 60 compute units per second.

What you have now for testing may be an edge case and for wallets that have few nfts it will work with one query.

You could also use caching if you query data for same token id multiple times.

I tried lowering the number of max iterations to simulate a smaller wallet.

It has errors as long as that interval is less than 260, so it will behave the same for any wallet with three or more nfts.

I think it’s normal for an app to show a list of a few nfts, with their last price stuck somewhere near the name and picture, I think I’m missing something obvious.

how many wallets do you plan to track?

Just two now while testing, to have options. But what I would like is to be able to search for any wallet, with a few already listed to be selected maybe.

I wanted to see this info for myself, and started making an app for it while learning React and Moralis.

I managed to make it pretty easily using an api from rapidapi, a few months ago, with just one api call for each address.

It should be just as easy with Moralis, I must be missing something and it’s frustrating. Basically, any NFT has transfers, and some accompanying data about those transactions. On the other hand, any wallet with nfts has transactions for those nfts, and those nfts have accompanying metadata.

We don’t have an api endpoint that returns this data now directly in one request.