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
- Repository
- github.com/pwnholic/sadewa
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
| Decision | Alternative | Why |
|---|---|---|
| Interfaces per exchange, one shared model | An exchange-specific API | Callers should not branch on the venue |
| Circuit breaker around each venue | Retry until it works | A venue that is down should stop consuming the caller’s budget |
| Rate limiting inside the client | Caller-side pacing | The limit belongs to the venue, not to the call site |
| Key rotation without restart | Restart on rotation | A 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.