Tools and tech by @royphilip_, built for developers who ship.

Hero image for Building a Financial-Grade Etherscan SDK in 48 Hours

Published on

Building a Financial-Grade Etherscan SDK in 48 Hours

At aixCB Capital, our investment models depend on investigative blockchain data. Precision isn’t a nicety. It’s the difference between correct analytics and silent financial drift.

So when I reviewed the ecosystem of existing Etherscan TypeScript libraries, I found a problem: none of them were built for real-world, financial-grade reliability. Many relied on deprecated V1 endpoints. Many silently swallowed API failures. Most used JavaScript number for token balances. A guaranteed way to corrupt 18-decimal assets.

I couldn’t risk our data pipeline on any of it.

So I spent the next 48 hours rebuilding everything from scratch.

What began as a weekend task became an unexpectedly deep audit of what “production-grade” really means.

Starting with Raw Chaos

Etherscan’s documentation is a maze of legacy quirks, evolving schemas, and inconsistent response formats. A common industry response is code generation: ingest the docs and spit out thousands of autogenerated TypeScript files.

That would have been “easy,” but also wrong.

Documentation often lags behind reality. The types lie. The examples lie. And generated clients inherit those lies.

So I made a contrarian call: Write the schemas by hand.

Not for masochism, but because manually defining Zod models forces you to confront reality. It revealed mismatches, undocumented fields, inconsistent shapes, and several schema drifts that would have silently corrupted downstream analytics.

This was the first moment the project crossed from “SDK” into “infrastructure.”

Defining What “Production-Grade” Actually Means

Before writing code, I reduced the requirements to three non-negotiables:

Zero Precision Loss

Crypto values exceed MAX_SAFE_INTEGER.

Using JavaScript numbers for balances is malpractice.

Therefore, every numeric value entering the SDK is transformed into native BigInt at the transport layer, before userland code ever touches it.

Trust Nothing

TypeScript interfaces are compile-time fiction.

If the API changes, the compiler will happily let you deploy a time bomb.

With Zod, every response is validated the moment it arrives. If something drifts, it fails loudly. Right where the bug originates.

Self-Regulated Safety

Etherscan enforces strict rate limits.

A naive loop will trip a 429, crash a pipeline, or burn through your key quota.

The SDK includes a built-in leaky bucket limiter tuned to Etherscan’s constraints. It handles local process limiting, preventing accidental bursts within individual worker processes. For distributed systems (Kubernetes, serverless fleets), you’ll want upstream rate limiting (like Redis) since the SDK’s limiter is in-memory.

These principles became the design spine of the entire project.

The V2 Architecture Insight

The breakthrough moment came from fully embracing the V2 API.

In V1, you needed a massive router mapping 50+ networks:

  • api-sepolia.etherscan.io
  • api.polygonscan.com
  • api-optimistic.etherscan.io

V2 deletes all of that.

There is one endpoint: api.etherscan.io/v2/api?chainid=...

This single change eliminated an entire layer of complexity. No more routers. No more per-chain classes. No more branching logic.

Support for new networks becomes trivial. Just pass the chain ID.

The SDK becomes inherently future-proof.

This realization cut the codebase by roughly 30% with zero loss in capability.

Solving the Hard Problems (The Ones SDKs Avoid)

BigInt at the Transport Layer

A 1-wei precision loss propagates across every analytics layer.

I built custom Zod transformers that convert raw string values to BigInt instantly:

schema.coerce.bigint()

No precision loss. Ever.

Runtime Validation: Ending the TypeScript Lie

Here’s the painful truth:

interface Response { balance: string }

This is a lie.

You’re hoping Etherscan returns this shape.

With Zod, hope is replaced with certainty. If the schema shifts (field renamed, type changed, or removed), you get an immediate, actionable error at the network boundary.

This alone prevented multiple silent data corruptions during development.

Rate Limiting That Survived Production

Early versions of the leaky bucket limiter failed under CI timing variations.

We hit edge cases with concurrent bursts, clock drift, and chained promise queues.

It took several iterations. Audits, refinements, stress tests. Before it became stable across all environments.

This process reinforced a truth: Good rate limiters aren’t built. They’re tuned.

Capability Guards

Not all chains support all endpoints.

Beacon Chain methods on Polygon should fail early, not return JSON noise.

Capability Guards ensure misuse is caught instantly with clear errors.

The Development Journey (The Honest Version)

The project went through real phases:

  • Foundation & Testing: building the testing harnesses
  • Audit Feedback: discovering unexpected schema drift and response irregularities
  • CI Hardening: making the rate limiter behave identically everywhere
  • API Alignment: correcting dozens of mismatches between docs and reality
  • Iteration Cycles: refining schemas, parameters, chain handling
  • Documentation Maturity: adding PRO examples, guard behavior, advanced usage
  • Platform Evolution: Bun transition, coverage tracking, performance profiling
  • Release Polish: trimming surface area, tightening interfaces

It wasn’t instant. It wasn’t clean. It was real engineering.

The Simplicity Paradox

Late in the process, someone asked:

“Why is this so small compared to other SDKs?”

Because size is not a virtue.

Correctness is.

The SDK is small because:

  1. V2 unified the architecture
  2. Zod is both the type system and the documentation
  3. BigInt eliminates entire layers of “safe math” libraries
  4. Modern Node removes polyfills and legacy codepaths

It looks simple only because the complexity was handled properly.

Production Ready

etherscan-v2-sdk is now deployed internally and open-source:

  • Financial Precision: Transport-level BigInt
  • Runtime Safety: Zod validation on every response
  • Rate Limiting: Leaky bucket, CI-stable, production-tested
  • 40+ Chains: Chain ID, not routers
  • Coverage: 88%+ with mainnet integration tests
  • Production Proven: Actively powering aixCB’s data infrastructure

It doesn’t try to do everything.

It tries to do the right things. Safely, predictably, and with absolute precision.

View on GitHubView on NPM