Skip to content

blockzenith/eagle-eye

Repository files navigation

eagle-eye

Onchain trading terminal — Solana + Base swaps and prediction markets (Polymarket, Kalshi, Limitless), surfaced through a green-phosphor terminal UI. Microservice architecture: Rust where latency matters (chain ingest, market tracker), NestJS where developer ergonomics matter (gateway, auth, signals), Next.js for the client.

Architecture

            ┌──────────────────────────┐
            │  Next.js  :3000          │   green-phosphor terminal UI
            └────────────┬─────────────┘
                         │ HTTP / WS
                  ┌──────▼─────────┐
                  │  nginx :80     │
                  └──────┬─────────┘
                /api/*   │   /ws
                  ┌──────▼──────────────────────┐
                  │  NestJS gateway :4000       │  REST + WS, SIWE/JWT, NATS client
                  └──┬───────────┬───────────┬──┘
                     │           │           │
        ┌────────────▼─┐  ┌──────▼─────┐    │
        │ users :NATS  │  │ signals    │    │  NATS subjects:
        │              │  │ :NATS      │    │   evm.heartbeat
        └──────────────┘  └────────────┘    │   sol.heartbeat
                                            │   pm.market.upsert
                            NATS  ──────────┤
                                            │
            ┌───────────────────┬───────────┴────────────┐
            │                   │                        │
   ┌────────▼─────────┐ ┌──────▼─────────────┐ ┌────────▼─────────┐
   │ svc-evm-indexer  │ │ svc-solana-indexer │ │ svc-pm-tracker   │
   │ Rust + Alloy     │ │ Rust + solana-     │ │ Rust + reqwest   │
   │  Base RPC/WS     │ │ client/RPC         │ │  Polymarket+     │
   │                  │ │                    │ │  Kalshi+Limitless│
   └──────────┬───────┘ └────────┬───────────┘ └────────┬─────────┘
              │                  │                      │
              └──────────────────┼──────────────────────┘
                                 ▼
              ┌────────────────────────────────────────┐
              │ TimescaleDB :5432  Redis :6379  NATS   │
              │ (timescale/pg16)   (7.4)        :4222  │
              └────────────────────────────────────────┘

Tech stack

  • Rust: 1.90.0, tokio, axum, sqlx (postgres + timescaledb + bigdecimal + chrono), alloy, solana-client, async-nats.
  • Node: 22.11.0 (LTS), pnpm 9, NestJS 10. @nestjs/microservices (NATS), @nestjs/websockets (Socket.IO), siwe + JWT.
  • Frontend: Next.js 15 App Router, React 19, Tailwind 3.4, socket.io-client, SWR, Zustand.
  • Infra: TimescaleDB 2.17.2-pg16, Redis 7.4-alpine, NATS 2.10-alpine, nginx 1.27-alpine. All pinned, never latest.

Quick start

git clone https://github.com/blockzenith/eagle-eye.git
cd eagle-eye
git checkout dev
cp .env.example .env
make up            # docker compose up --build -d
make logs          # tail until healthy
open http://localhost

Once everything is up:

URL Purpose
http://localhost/ terminal UI dashboard
http://localhost/markets live polymarket feed
http://localhost/api/v1/health gateway health
http://localhost/api/v1/markets?venue=polymarket&limit=5 sample REST query
ws://localhost/ws socket.io WebSocket
http://localhost:8222/varz NATS monitoring

The first Polymarket fetch tick lands ~60s after pm-tracker boots; expect the /markets page to populate within ~90s. Watch upserts arrive over WebSocket: rows flash on each update.

Repo layout

eagle-eye/
├── services-rs/           # Rust workspace
│   └── crates/{core, svc-evm-indexer, svc-solana-indexer, svc-pm-tracker}
├── services-ts/           # NestJS pnpm workspace
│   ├── apps/{gateway, users, signals}
│   └── packages/contracts # shared DTOs + NATS subject constants
├── apps-web/eagle-eye-web # Next.js 15 terminal UI
├── infra/
│   ├── nginx/nginx.conf
│   └── postgres/init/     # bind-mounted to /docker-entrypoint-initdb.d
├── docker-compose.yml         # dev stack (build locally)
├── docker-compose.prod.yml    # prod overlay (pull from registry)
├── Makefile                   # `make up | down | logs | fmt | lint | test`
└── .github/workflows/{ci,images}.yml   # self-hosted runner: [self-hosted, linux, x64, eagle-eye]

Branching

  • dev — active development. All work lands here first.
  • stage — receives fast-forward merges from dev once a version is confirmed.
  • main — receives fast-forward merges from stage. Tagged releases live here.
# after dev is verified for v0.x.y
git checkout stage  && git merge --ff-only dev   && git push
git checkout main   && git merge --ff-only stage && git push
git tag -a v0.x.y -m "v0.x.y" && git push --tags

Image tagging

Deterministic, never latest. Every image is tagged <registry>/eagle-eye-<service>:<VERSION>-<GIT_SHA> where:

  • VERSION defaults to git describe --tags --always --dirty
  • GIT_SHA defaults to git rev-parse --short HEAD
  • REGISTRY defaults to ghcr.io/blockzenith

Override at build time:

VERSION=0.2.0 GIT_SHA=$(git rev-parse --short HEAD) make build

CI / runners

CI runs on a self-hosted runner registered against this repo (labels self-hosted, linux, x64, eagle-eye). The runner installation lives at /opt/actions-runner-eagle-eye, runs as the gha-runner user, and is managed by systemd:

sudo systemctl status actions.runner.blockzenith-eagle-eye.eagle-eye-host.service

The runner has access to the host Docker daemon (member of docker group) so the images.yml workflow can build and push images.

What's wired vs stubbed

See docs/feature-matrix.md for the per-chain and per-venue map (indexer → gateway → UI) — the table makes the "Solana, Base, Polymarket, Kalshi, Limitless" headline concrete.

What's stubbed in v0.1

  • Real EVM/Solana swap decoding — indexers heartbeat block heights and slots; per-DEX log decoding is a follow-up.
  • Kalshi + Limitless market fetchers — function stubs in svc-pm-tracker/src/{kalshi,limitless}.rs. Polymarket is live.
  • SIWE signature verification — gateway accepts signatures as opaque strings; production must call new SiweMessage(...).verify(...) with domain + nonce checks.
  • Wallet / token detail pages — routes exist, no data flows yet.
  • Telegram / KOL signals ingestion, trade execution, multi-arch images — all deferred.

License

MIT — see LICENSE.

About

onchain trading terminal — solana + base swaps and prediction markets, surfaced through a green-phosphor terminal UI

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors