Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Hydra Gateway
REST API and WebSocket gateway for the hydra-amm universal AMM engine.
Hydra Gateway exposes every AMM pool type supported by hydra-amm through a JSON REST API and a real-time WebSocket feed. All AMM mathematics are delegated to hydra-amm — this service is a thin coordination and persistence layer.
Supported Pool Types
| Pool Type | Description | REST Endpoint |
|---|---|---|
| Constant Product | Uniswap V2 style (x · y = k) | POST /api/v1/pools |
| CLMM | Concentrated Liquidity (Uniswap V3 style) | POST /api/v1/pools |
| Hybrid / StableSwap | Curve-style with amplification | POST /api/v1/pools |
| Weighted | Balancer-style multi-token pools | POST /api/v1/pools |
| Dynamic / PMM | DODO-style oracle-driven pricing | POST /api/v1/pools |
| Order Book | Phoenix-style CLOB + AMM hybrid | POST /api/v1/pools |
Architecture
┌─────────────────────────────────────────────────┐
│ Clients (HTTP, WebSocket) │
├─────────────────────────────────────────────────┤
│ Layer 5: REST Handlers (api/) │
│ Axum routes · DTOs · OpenAPI (Swagger UI) │
├─────────────────────────────────────────────────┤
│ Layer 4: WebSocket Handler (ws/) │
│ Subscriptions · Real-time event streaming │
├─────────────────────────────────────────────────┤
│ Layer 3: PoolService (service/) │
│ Orchestration · Event emission │
├─────────────────────────────────────────────────┤
│ Layer 2: Domain (domain/) │
│ PoolRegistry · EventBus · PoolId · PoolEntry │
├─────────────────────────────────────────────────┤
│ Layer 1: hydra-amm Engine │
│ PoolBox enum dispatch · SwapPool · LiquidityPool│
├─────────────────────────────────────────────────┤
│ Layer 0: Persistence (persistence/) │
│ PostgreSQL · Events log · Pool snapshots │
└─────────────────────────────────────────────────┘
Key design decisions:
- Per-pool
RwLock: Fine-grained concurrency — no global mutex. - Enum dispatch:
PoolBoxfromhydra-amm— zero vtable overhead. - String-encoded amounts: All
u128values serialized as JSON strings to prevent precision loss. - EventBus:
tokio::broadcastchannel (configurable capacity) for real-time event streaming. - OpenAPI documentation: Full Swagger UI at
/swagger-ui.
API Endpoints
System
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/config/pool-types |
List supported pool types |
Pools
| Method | Path | Description |
|---|---|---|
POST |
/api/v1/pools |
Create a new pool |
GET |
/api/v1/pools |
List pools (paginated) |
GET |
/api/v1/pools/{id} |
Get pool details |
DELETE |
/api/v1/pools/{id} |
Delete a pool |
Swaps
| Method | Path | Description |
|---|---|---|
POST |
/api/v1/pools/{id}/swap |
Execute a swap |
POST |
/api/v1/pools/{id}/quote |
Get swap quote (read-only) |
Liquidity
| Method | Path | Description |
|---|---|---|
POST |
/api/v1/pools/{id}/liquidity/add |
Add liquidity |
POST |
/api/v1/pools/{id}/liquidity/remove |
Remove liquidity |
WebSocket
| Path | Description |
|---|---|
/ws |
Real-time event streaming (subscribe to pool events) |
Documentation
| Path | Description |
|---|---|
/swagger-ui |
Interactive Swagger UI |
/api-docs/openapi.json |
OpenAPI 3.0 specification |
Quick Start
Using Docker Compose
The fastest way to get started:
This starts PostgreSQL and the gateway. The API is available at http://localhost:3000.
From Source
# 1. Clone the repository
# 2. Start PostgreSQL (requires Docker)
&& &&
# 3. Copy environment file
# 4. Run the gateway
Create a Pool
Execute a Swap
Configuration
All settings are loaded from environment variables (or .env file). See .env.example for the full list.
| Variable | Default | Description |
|---|---|---|
LISTEN_ADDR |
0.0.0.0:3000 |
Server bind address |
DATABASE_URL |
postgres://hydra:hydra@localhost:5432/hydra_gateway |
PostgreSQL connection string |
DATABASE_MAX_CONNECTIONS |
10 |
Max DB pool connections |
DATABASE_MIN_CONNECTIONS |
2 |
Min idle DB connections |
DATABASE_CONNECT_TIMEOUT_SECS |
5 |
DB connection timeout (seconds) |
PERSISTENCE_ENABLED |
true |
Enable/disable persistence layer |
PERSISTENCE_SNAPSHOT_INTERVAL_SECS |
60 |
Pool snapshot interval (seconds) |
PERSISTENCE_EVENT_LOG_ENABLED |
true |
Enable event logging |
PERSISTENCE_CLEANUP_AFTER_DAYS |
30 |
Auto-delete snapshots older than N days |
EVENT_BUS_CAPACITY |
10000 |
EventBus broadcast channel capacity |
RUST_LOG |
info |
Log level (tracing format) |
Module Structure
hydra_gateway/
├── api/
│ ├── dto/ — Request/response DTOs (all amounts as strings)
│ ├── handlers/ — REST endpoint handlers (system, pool, swap, liquidity)
│ └── mod.rs — Router composition + OpenAPI (ApiDoc)
├── app_state.rs — Shared application state (PoolService + EventBus)
├── config.rs — Environment-based configuration
├── domain/
│ ├── pool_id.rs — Type-safe UUID v4 pool identifier
│ ├── pool_entry.rs — Pool metadata wrapper around PoolBox
│ ├── pool_event.rs — Domain event enum
│ ├── event_bus.rs — tokio::broadcast event bus
│ └── pool_registry.rs — HashMap<PoolId, RwLock<PoolEntry>>
├── error.rs — GatewayError → HTTP status code mapping
├── persistence/ — PostgreSQL persistence (events + snapshots)
├── service/
│ └── pool_service.rs — Orchestration layer
└── ws/ — WebSocket handler + subscription manager
Docker
Build the Image
Run with Docker Compose
Services:
- postgres: PostgreSQL 17 on port
5432 - hydra-gateway: API on port
3000
Safety and Correctness
unsafecode is denied — enforced at the compiler level- No
.unwrap()/.expect()/panic!— denied via Clippy lints - Per-pool
RwLock— no global mutex, no deadlocks - Overflow checks enabled in both debug and release profiles
- Strict Clippy with
-D warnings
Development
Prerequisites
- Rust 1.93+ (edition 2024, see
rust-toolchain.toml) - Docker and Docker Compose (for PostgreSQL)
- Make
Common Commands
# Build
# Test
# Quality
# Documentation
# Docker
# Coverage
# Packaging & Publishing
Pre-Push Checklist
Always run before pushing:
This executes: cargo fix → cargo fmt → cargo clippy → cargo test → cargo doc
Release
Releases are triggered by pushing a semver git tag:
# 1. Update version in Cargo.toml
# 2. Create and push a tag
The release workflow will automatically:
- Validate — format, clippy, tests, docs
- Publish crate to crates.io
- Build & push Docker image to GitHub Container Registry (
ghcr.io) - Create GitHub Release with auto-generated changelog
Docker images are available at:
ghcr.io/joaquinbejar/hydra-gateway:<version>
ghcr.io/joaquinbejar/hydra-gateway:latest
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository and create a feature branch
- Read the documentation in
.internalDoc/ - Write tests for all new public functions
- Run
make pre-pushbefore submitting - Create a PR with a clear description
Code Standards
- All comments and documentation in English
///doc comments on every public item#[must_use]on all pure functions- No panics in production code
- Newtypes for all domain concepts
License
This project is licensed under the MIT License — see the LICENSE file for details.
Contact
- Author: Joaquin Bejar Garcia
- Email: jb@taunais.com
- Telegram: @joaquin_bejar
- Repository: github.com/joaquinbejar/hydra-gateway