Sadewa

A type-safe Go library for integrating multiple trading exchanges, covering order models, streaming, rate limiting, circuit breaking and reconnection.

Role
Author
Status
Active
Stack
Go

Overview

Sadewa is a Go library for integrating more than one trading exchange behind a single interface: order, balance, trade and order book models, streaming over WebSocket, rate limiting, circuit breaking, caching, reconnection, key rotation, and dependency injection.

It is the project I point at when asked whether I can design a library rather than an application, because the reliability work is the point rather than a detail.

Problem

Every exchange integration starts the same way - a client, a signing helper and a loop that reads a socket - and ends the same way, with the failure handling copy-pasted from the previous one. The interesting problems are not the HTTP calls. They are what happens when the socket drops mid-order, when the exchange starts rate-limiting, or when a credential has to be rotated without restarting a process.

Constraints

  • A public library. Every exported type is a compatibility promise, so the surface has to stay small enough to keep.
  • No hidden global state. Clients must be constructible independently, which is what makes dependency injection a requirement rather than a style choice.
  • Fail visibly. A dropped stream has to be distinguishable from a quiet market.

Technical decisions

DecisionAlternativeWhy
Interfaces per exchange, one shared modelAn exchange-specific APICallers should not branch on the venue
Circuit breaker around each venueRetry until it worksA venue that is down should stop consuming the caller’s budget
Rate limiting inside the clientCaller-side pacingThe limit belongs to the venue, not to the call site
Key rotation without restartRestart on rotationA credential change should not be an outage

Tradeoffs

Abstracting several venues behind one model means the shared model is the intersection of what they support; venue-specific behaviour has to be reachable without leaking into the general interface. Streaming, reconnection and caching also add moving parts to a library whose callers may not want all of them, which is why they are separately constructible.

Results

The repository documents this functionality and passes its own checks. I am not quoting latency or throughput figures, because I have not measured them under conditions worth quoting.

Lessons learned

Reconnection is part of the data model, not an error handler. Deciding where a resumed stream re-enters the caller’s state is a design question, and answering it late means rewriting the stream handling.

Search this site