Blog/Eterna Execution Engine
Project Guide

Building Eterna

An Order Execution Engine for Solana DEXs

6 min read
Eterna - High-Performance Solana DEX Execution Engine

The Task

The goal was to build an order execution engine for Solana DEXs that processes market orders with real on-chain execution (not simulated). The system needed to handle DEX routing between Raydium and Meteora, provide real-time status updates via WebSocket, and process concurrent orders using a queue system.

Key Requirements:

  • Execute actual swaps on Solana Devnet using Raydium and Meteora SDKs
  • Compare prices from both DEXs and route to the better one
  • Handle 100 orders/minute with 10 concurrent workers
  • Implement retry logic (max 3 attempts with exponential backoff)
  • Stream order status updates (pending → routing → building → submitted → confirmed/failed)
  • User authentication and order history

Implementation

Eterna is built with Next.js 15 as a full-stack application. Orders are submitted via REST API, added to a BullMQ queue backed by Redis, and processed by worker threads that interact with Raydium and Meteora SDKs. All transactions are executed on Solana Devnet and can be verified on Solana Explorer.

What I Built:

  • REST API endpoints for order submission and history
  • BullMQ worker that fetches quotes from both DEXs in parallel
  • DEX router that compares prices and selects the optimal DEX
  • Transaction builder for Raydium and Meteora swaps
  • Socket.IO server for broadcasting status updates
  • PostgreSQL database with Drizzle ORM for persistence
  • JWT authentication for user sessions

Real On-Chain Execution

Executes actual swaps on Solana Devnet using @raydium-io/raydium-sdk-v2 and @meteora-ag/dynamic-amm-sdk. Each transaction gets a signature that can be verified on Solana Explorer.

BullMQ Queue System

Orders are processed asynchronously by workers (max 10 concurrent). Failed transactions retry up to 3 times with exponential backoff (2s, 4s, 8s delays). Queue persists in Redis.

DEX Price Comparison

Worker fetches quotes from Raydium and Meteora simultaneously. Compares output amounts and routes the order to whichever DEX gives more tokens. Routing choice is logged to database.

Real-Time Status Updates

Socket.IO broadcasts order status changes as they happen: pending, routing, building, submitted, confirmed, or failed. Client receives updates with <100ms latency.

How It Works

1

Pending → Queue Entry

Order submitted via POST /api/orders/execute. System generates orderId, saves to PostgreSQL, pushes job to BullMQ queue, and returns WebSocket URL. Status: pending.

2

Routing → Price Discovery

Worker fetches quotes from both Raydium and Meteora in parallel. Compares output amounts, selects best DEX, logs routing decision. Status update streamed via Socket.IO. Status: routing.

3

Building → Transaction Creation

Worker creates swap instruction for chosen DEX, handles wrapped SOL if needed, adds 1% slippage protection, and builds the complete transaction. Status: building.

4

Submitted → On-Chain Execution

Transaction sent to Solana Devnet RPC. Worker gets transaction signature immediately and broadcasts it to client. User can track on Solana Explorer in real-time. Status: submitted.

5

Confirmed/Failed → Settlement

Worker waits for finalization. On success: extracts execution price, updates DB with txHash, emits 'confirmed'. On failure after 3 retries: saves error, emits 'failed'.

Technical Architecture

Full-Stack

Next.js 15 + TypeScript

Database

PostgreSQL (Drizzle ORM)

Queue & Cache

Redis + BullMQ

Blockchain

Solana Web3.js + DEX SDKs

Built With Modern Technologies

Next.js 15
TypeScript
PostgreSQL
Drizzle ORM
Redis + BullMQ
Socket.IO
@solana/web3.js
Raydium SDK v2
Meteora SDK
JWT Auth

System Architecture

HTTP + WebSocket Pattern

REST endpoint for order submission returns immediately with orderId. Client establishes WebSocket connection for status streaming. Decouples submission from execution—no blocking, no timeouts.

Distributed Queue with BullMQ

Redis-backed job queue handles concurrent processing (10 workers). Each order is a job with automatic retries (max 3 attempts, exponential backoff: 2s, 4s, 8s). Queue persistence survives crashes.

Parallel Quote Fetching

Worker initializes both Raydium and Meteora SDKs concurrently. Fetches quotes in parallel (200ms each). Compares output amounts and selects DEX with higher return. Routing decision logged to PostgreSQL.

Real Devnet Execution

No mocks, no simulations. Worker builds actual swap transactions using SDK methods, signs with server keypair, submits to Solana Devnet RPC, and confirms on-chain. Every txHash is verifiable on Solana Explorer.

Database Schema (Drizzle ORM)

Users table with JWT auth. Orders table tracks full lifecycle: orderId, userId, tokens, amounts, status, selectedDex, txHash, error. Type-safe queries with Drizzle prevent SQL injection and runtime errors.

Status Streaming via Socket.IO

Worker emits events to Socket.IO server after each status change. Server broadcasts to clients subscribed to that orderId. Sub-100ms latency ensures users see status updates in real-time.

Technical Challenges

  • Integrating Raydium SDK v2 and Meteora SDK - different APIs, different pool structures
  • Handling wrapped SOL for native token swaps (required extra transaction steps)
  • Managing concurrent order processing without hitting RPC rate limits
  • Implementing exponential backoff retry logic that doesn't retry forever
  • Coordinating WebSocket updates between worker threads and API server
  • Database schema design for tracking order lifecycle and routing decisions

Check Out the Code

The full source code, documentation, and deployment guide are available on GitHub. Includes API documentation, database schema, and example transactions on Solana Explorer.

What I Learned

This project taught me a lot about building systems that deal with external services (blockchain RPCs, DEX SDKs) that can fail or be slow. Key takeaways:

  • Queue-based processing decouples API from heavy blockchain operations
  • Parallel quote fetching saves time but requires careful error handling
  • WebSocket + REST pattern works well for async workflows
  • Exponential backoff prevents hammering RPC nodes during failures
  • Type-safe ORMs (Drizzle) catch bugs at compile time
  • Status tracking in DB is crucial for debugging failed orders

The code is on GitHub with full documentation, API examples, and deployment instructions. All transactions are verifiable on Solana Explorer (Devnet).