Im trying to figure out the best way to automatically update balances in front end upon receiving and sending tokens. Ive tried creating an instance of a token in my react app, then creating an event listener and filter to listen to "Transfer" events going to and from my contract address, then it would run a function that updates the contract token balance and my wallet balance after spending gas on the transfer (my wallets ether balance is displayed in my UI). This way works when a user sends the token to the contract, but it doesn't keep track of how much each user sends. To keep track, I create an instance of the token in my contract, I added a transfer function which calls the transfer function of the token, it adds the balance to the addressToBalance mapping, and then emits an event. I tried listening for this event, but the problem is, I believe it emits the event before the token is actually transferred, is that right? so the event listener is triggered before the the token is transferred. Is there an "industry standard" way of doing this? My guess is listening to transfer events of the token contract is the most reliable, but you you have to be careful with filters an un subscribing, otherwise it gets triggered a thousand times. Any tips are appreciated!
it will be very taxing, on your browser resources, to list all balances of all holders and update them at the same time.
your bet is to show some balances and listen to the transfer event with a filtered topic based on each wallet address you are trying to update. if an event is fired for one wallet, you can call the token and get the new balance of that wallet. you should also do some sorting of events as you can easily have 2 transfers or more in the same block to the same address which would result in multiple useless balanceOf requests.
You have 2 options:
1- Use on-chain reads every x seconds, but batch all on-chain read requests using Maker's Multicall contract, or through a JS lib that abstracts Multicall like @pooltogether/etherplex. It's better to batch read calls to stay below your Infura or Alchemy API limits.
2- Leverage the power of The Graph protocol for on-chain data caching and indexing. The UI would basically use the Apollo GraphQL client to fetch data from your deployed subgraph by pooling every x seconds (Apollo supports polling).
you need to add
emit ... after transfer.