Hystorical token balances

Hi all,

I am trying to build a graph that shows my token balances over time.
Any advice in how to do that?
Are there built in functions we can use?

Thank you

https://docs.moralis.io/moralis-server/web3-sdk/account#gettokenbalances

it looks like it has to_block parameter

Hi @cryptokid,

Should I implement it as a Cloud functions? I hit rate limit when running from the browser.
I am also looking at the Covalent plugin.
What would you use?

Thx

how do you hit the rate limit? what rate limit do you hit (asking because there are two options)

I don’t have experience with Covalent plugin, I would use web3api

Let’s say I get one representative block per day.
I then get token balances for that block.
I hit rate limit as soon as I ask for more than 10 days.

Find below the code I am using.

let dates = Array(Number(50)).fill().map((e, i) => moment().subtract(i, "d").format("YYYY-MM-DD")).reverse();
const balances = await Promise.all(dates.map(async(e, i) => native.getDateToBlock({chain: chainId, date: e})))
                          .then((result) => {
                            const balance = Promise.all(result.map(async(e, i) => {
                              const  tokenBalan = account.getTokenBalances({ chain: chainId, address: walletAddress, to_block: e.block });
                              (await tokenBalan).map((t) => {
                                t.block = e.block
                                t.date = moment(e.date).format("YYYY-MM-DD")
                                return t;
                              })
                              return tokenBalan;
                              }
                            ));
                            return balance;
                            }
                          )

ok, I guess that you shouldn’t do all those 10 requests in parallel, try to add some delay between requests, like 1 second, or 0.3 seconds

also, after you get the info for a particular day, you could save it in db so that you don’t ask the API again next time

Which error you get about rate limit exactly?

@cryptokid, yes that’s one solution I am exploring. Not easy to do technically, the following is the route I am taking.
Any advice?

	const blocks = [];
    const result           = result => blocks.push(result);
    function getBlockByDate(date) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          native.getDateToBlock({chain: chainId, date: date}).then(result);
          resolve();
        }, 1000);
      });
    }
    
    //run sequentially with delay
    dates.reduce( (p, date) => {
      console.log(`Loop! ${moment().format('hh:mm:ss')}`);
      return p.then(() => {
        return getBlockByDate(date);
      });
    }, Promise.resolve());

@ivan, find below screenshot of the error:

I would do a simple for or forEach

i think you are doing too many requests each second - try to spread them out maybe add 100-200 ms delays

@cryptokid and @ivan

Any code snippet I can start from?

Really appreciated gents.

Thx

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

array1 = ['a', 'b', 'c'];
for(i=0; i <= array1.length; i = i + 1){
   await sleep(1000);
   console.log(array1[i]);
}