Real-time arbitrage engine for Iranian cryptocurrency exchanges.
Three independently buildable projects in one repository: an async Rust
engine that streams live prices from exchange WebSockets into Kafka and a
real-time WS feed, a CLI (sc) to control it, and a Dioxus web UI to watch
it.
Each exchange adapter parses its own WebSocket stream into a common Price
type. Every tick is published to Kafka (for downstream arbitrage detection)
and broadcast over WebSocket to connected clients at the same time. The CLI
and UI both talk to the same REST control plane to start/stop/list tickers.
See ARCHITECTURE.md for the full data-flow diagram.
stream-coin/
├── engine/ # the server — actix-web, exchange adapters, Kafka, Redis, WS feed
├── cli/ # `sc` — controls the engine over REST, zero dependency on engine
└── ui/ # Dioxus SPA — shared core + a web launcher, consumes the WS feed
| Exchange | Status |
|---|---|
| Tabdeal | ✅ |
New exchanges are added by implementing one trait (ExchangeAdapter) —
nothing else in the engine changes.
Infra (Redis, Kafka, Flink, Kafka UI):
cp .env.example .env # fill in passwords
docker compose up -dEngine:
just run # cargo run --bin stream-coinCLI:
just sc ticker start --exchange tabdeal --pair USDT/IRT
just sc ticker listUI (dev server with hot reload):
just ui-devThis project uses just as its task runner.
just check # fmt + clippy -D warnings + unit tests + integration tests + clean-room docker build
just test # unit tests only
just sc --helpThe ui/ workspace has its own test/lint targets: cd ui && just ui-test /
ui-lint.
Tagged pushes (vX.Y.Z) trigger a CI pipeline that builds and publishes,
independently: the engine (stream-coin, tar/deb/rpm/msi/AppImage + Docker
image), the CLI (sc, tar/deb/rpm), and the web UI (static bundle) — see
Releases.
Outstanding standardization work is tracked in ROADMAP.md.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) just checkbefore opening a PR- Open a Pull Request
GPL-3.0 — see LICENSE.