A Dynamic Web3 RPC Handler for UbiquityDAO

The premise is simple: You have a list of RPCs and you want to always use the one with the lowest latency while excluding bad eggs from future use. This is a common problem in the blockchain space, where RPCs can be unreliable and slow. I built a package to solve this problem for UbiquityDAO as part of one of their bounties.


Precurser

It seems recently that most of my bounties have been centered around the payment portal for Ubiquity.

  • Page performance (10x improvement)
  • Syncing ERC Permits across the eco-system
  • Bug Squashing (a rudimentary manual blacklist for rpcs created to prevent a flickering issue when any failed)
  • Dynamic RPC Handling

The blacklist was a poor approach to a problem that needed resolved in a much cleaner and more effective way. As molecula stated, it would be senseless to have to make a new commit/pr each time you needed to update that RPC blacklist manually, it just wasn't scalable.

And from this my biggest bounty yet was born.

The Bounty

The initial spec of the bounty was small and required that bad RPCs be dropped dynamically, it was simple enough and priced at about $200 I think. I was happy to take it on as it was a simple problem to solve and I was confident I could do it.

My approach was based off pavlovcik's code, that would ping the RPCs and return the lowest latency one, it stored these latencies in localStorage and always returned the quickest. I took this and built a package around it, adding a few extra features such as a timeout, an rpc cache, a blacklist and made it ESM and CJS compatible.

The bounty grew in scope which I only realized after I opened the PR against the portal repo, the initial PR being just a working version within the UI codebase. The bounty was updated to include a package that would be published to NPM and be ESM and CJS compatible, this took the bounty from $200 to $1200, a significant increase in scope.

The Package

As per the updated spec, the package was to be fit for both ESM and CJS, which was new to me having to make a package that was compatible with both. I had to do quite a bit of research to get it right, but I got there in the end.

The package takes a list of RPCs from chainlist that are injected at build time. In this way the package is always up to date with the latest RPCs and doesn't require any manual updating.

A great aspect of the package is that it only uses RPCs that are known by chainlist to track no data, so it's crypto-maxi friendly.

As the intent is to have the quickest RPC, making use of a request timeout was a no-brainer. I set the default timeout to 500ms, as with the quantity of RPCs that are being pinged, it's not worth waiting any longer than that.

The package also has a cache, in a browser environment the package leverages local storage to store the latencies of the RPCs, in a node environment it uses the class object. This is to prevent bad RPCs from being called more than once, making the package more efficient.

The Learnings

This bounty has taught me a lot, I'll highlight the most prominent learnings I've taken from it.

  • ESM and CJS compatibility
  • Build time injection
  • Setting up a package for publishing

Credits

I want to give a shoutout to UbiquityDAO for giving me the opportunity to contribute in their eco-system. In particular, I want to thank @pavlovcik who's the point of contact for most reviews and issues and for being helpful, patient and accomodating throughout every bounty as well as for pushing the code that my package was based on.

I also want to give @molecula451 a shoutout for being the heavy handed reviewer, I thrive on that shit, you can't improve much without being told where/how beyond a certain point when you are self-taught/self-assessing for the most-part so I appreciate and welcome it from all the reviewers on the team.


Conclusion

I'm happy that I was able to solve this bounty for UbiquityDAO, while at this time the PR is still open, I'm confident that it will be merged soon. I'm also happy to have built a package that will be published to NPM. Now, while it won't be published under my name, it's still a great feeling to have contributed to the open-source community in this way.

Thanks again to the UbiquityDAO team for the opportunity, I look forward to smashing out more bounties this year.