Skip to content

Latest commit

 

History

History
64 lines (50 loc) · 2.38 KB

README.md

File metadata and controls

64 lines (50 loc) · 2.38 KB

Simple ERC-20 Indexer

This is an skeleton app that uses the Alchemy SDK rigged to Alchemy's Enhanced APIs in order to display all of an address's ERC-20 token balances.

Set Up

  1. Install dependencies by running npm install
  2. Start application by running npm run dev

Challenge

Fork this repo and build out more features! This is minimalistic on purpose.

We purposefully built this app to be minimalistic so that you can get some software development practice in fixing our bugs! 🪲

Here are a few challenge suggestions:

  1. Add Wallet integration so that any user that connects their wallet can check their ERC-20 token balance
  2. There is no indication of a request in progress... that's bad UX! Do you think you can add some sort of indication of loading?
  3. Add some styling! 🎨
  4. The token balances can sometimes be a little long and break the outline of the page... can you fix that? 🔧
  5. There is no error-checking for wrongly formed requests, or really any error checking of any kind... can you add some in?
  6. The images and grid display could look better... anything you can do about that?
  7. There are ways to make this app faster... can you implement some of them? How can the query be made even quicker?
  8. Can you add ENS support for inputs?
  9. Completely open-ended!! Use this as the base for your next hackathon project, dream company or personal expedition :)

Solution

Apart from basic challenge, I implemented a concurrent batching pattern through an async generator to prevent the 429: Too many request error. For simplicity, here I fixed the request rate to 10 per time.

Here is the code snippet of the generator:

async function* consumeTokens(tokensAddresses = []) {
  let sliceIndex = 0;
  let sliceSize = 10;
  const alchemy = await getAlchemy();
  while (sliceIndex < tokensAddresses.length) {
    const tokens = tokensAddresses.slice(sliceIndex, sliceIndex + sliceSize);
    const promises = tokens.map(
      address =>
        new Promise(resolve => {
          alchemy.core.getTokenMetadata(address).then(data => {
            resolve({ ...data, address });
          });
        })
    );
    const results = await Promise.all(promises);
    sliceIndex += sliceSize;
    yield results;
  }
}

Here is how I consumed:

const dataObjects = [];
for await (let info of consumeTokens(addresses)) {
  dataObjects.push(...info);
}