Skip to content

shipmesh/eventmesh-engine

Repository files navigation

Eventmesh

Solana-native, real-time event subscription service for autonomous agents.

Eventmesh is the eyes and ears for on-chain agents. Describe what you want to react to in plain English — "any swap over 10k SOL on Orca SOL/USDC", "SOL price drops below 80 USDC on Raydium", "Jupiter TVL drops 5%", "any Polymarket Solana market crosses 60 cents" — and Eventmesh streams matching events straight into your agent over WebSocket, webhook, or stdin.

npx eventmeshcc subscribe "any trade over 10k SOL on SOL/USDC" --webhook https://agent.app/hook

Built for the Solana agent stack: native DEX streaming via Helius, prediction-market signals, on-chain DeFi metrics, and a long tail of market data — all funnelled through one typed event bus your agent can subscribe to in a single line.


What it does

  1. Connectors stream from Solana's data plane and adjacent markets (Helius WebSocket for DEX trades, Polymarket / Kalshi for prediction markets, DefiLlama for protocol TVL, plus weather and sports). Every source is normalized into a single CanonicalEvent shape.
  2. The compiler turns each agent's natural-language intent into a structured rule — a vector embedding plus optional MongoDB-style condition filters ({ effectivePrice: { $lte: 80 } }, { baseAmount: { $gte: 10000 } }).
  3. The matcher runs every incoming event against every active subscription, combining cosine similarity over embeddings with the structured filters — so an intent can be both semantic ("SOL price crash") and precise ("effectivePrice < 80 USDC").
  4. The delivery engine fans matches out to agents via WebSocket (live) or HTTP webhook (signed, retried, batched).

Everything is one Bun process plus Postgres and Redis. Self-host it next to your agent, run it locally, or point your agent at a shared instance.

Why Solana agents

  • Sub-second on-chain visibility. The sol-defi connector subscribes to Helius's Enhanced WebSocket and parses Orca Whirlpool + Raydium (AMM v4 + CLMM) swaps, liquidity adds and removes in real time — token-pair-aware, automatically discovering pools.
  • Natural-language intents over structured data. Agents don't need to learn a DSL or babysit pollers. Say "big SOL/USDC sells" and the compiler emits a rule against type, side, baseAmount, effectivePrice, etc.
  • One event bus, many sources. Subscribe to a Solana DEX swap, a Polymarket odds shift, and a DefiLlama TVL drawdown from the same agent loop with the same CLI.
  • Local-first AI. Set IS_LOCAL=true and the intent compiler + embeddings run on-device via QVAC + llama.cpp — no external LLM calls, agent prompts stay on the host.
  • Built for autonomy. Webhook signing, retry, dedupe, and per-subscription delivery limits mean an agent can fire off thousands of subscriptions and trust the bus to behave.

Use cases

  • Solana trading and MEV agents reacting to swaps, liquidity events, and price thresholds on Orca / Raydium.
  • Agents that combine on-chain signals with prediction-market or off-chain data (e.g., hedge a Polymarket position against a Solana DEX move).
  • Notification and ops bots: TVL drawdowns on a tracked protocol, large-wallet activity, market resolution.
  • A backend for any product that wants "tell me when X happens on Solana" semantics without writing per-source pollers.

Architecture

                          ┌──────────────────────────────────────────┐
   external sources       │              Eventmesh server            │
   ──────────────────     │                                          │
   Helius Enhanced WS ──▶ │  Connectors ──▶ Event Queue (BullMQ)     │
   (Orca + Raydium)       │       │              │                   │
   Polymarket WS      ──▶ │       │              ▼                   │       Solana agents
   Kalshi REST        ──▶ │       │         Processor                │  ───▶ (WebSocket / CLI)
   DefiLlama API      ──▶ │       │         (matcher,                │
   ESPN scores        ──▶ │       │          embeddings,             │       Webhooks
   Weather API        ──▶ │       │          conditions)             │  ───▶ (signed, retried,
                          │       │              │                   │        batched)
                          │       └─▶ Postgres ◀─┤                   │
                          │          (subs,      ▼                   │
                          │           events,   Delivery Queue       │
                          │           pgvector)  + Batchers          │
                          └──────────────────────────────────────────┘
                                 │                   │
                                 ▼                   ▼
                             Postgres              Redis
                           (pgvector)            (BullMQ)

Key pieces (in server/src/):

Path Role
connectors/ Pluggable source adapters — each exports a ConnectorDefinition (id, prompt, normalizer, validator, runner).
domains/subscriptions/compiler.ts Compiles natural-language intent → embedding + condition rules (OpenRouter or on-device QVAC llama.cpp).
engine/matcher.ts Evaluates an event against a subscription (cosine similarity + MongoDB-style operators with $or support).
engine/processor.ts Per-event pipeline: matcher → delivery batcher.
engine/delivery.ts Webhook signing, retry, dedupe; WebSocket fan-out.
queue/ BullMQ event + delivery queues and workers.
db/schema/ Drizzle tables: users, accounts, subscriptions, deliveries, connectors, webhook registrations.
ws/ WebSocket upgrade handler and per-connection auth.
domains/ Hono REST domains: auth, subscriptions, account, connectors.

Connectors

Default (no extra config)

These ship registered out of the box and run with no per-connector keys:

  • defillama — Protocol TVL. Tracks TVL across DefiLlama-indexed protocols. Solana-native protocols (Jupiter, Marinade, Kamino, Jito, Orca, Raydium, Drift…) are first-class — point an agent at a protocol slug and react to TVL deltas, dominance shifts, or chain-level totals.
  • polymarket — Polymarket prediction markets. Streams price/odds updates and resolutions over Polymarket's WebSocket. Useful for agents that hedge or arbitrage between on-chain positions and event-outcome markets.
  • kalshi — Kalshi event contracts. Polled REST, normalized into the same canonical event shape so an agent can subscribe to crypto, macro, and sports contracts uniformly.
  • Sports — ESPN-backed connectors for basketball, football (NFL), baseball, hockey, soccer, tennis. Score changes, status transitions, game-end.
  • weather — current conditions via public weather APIs.

Available with extra config

Reference connectors live under server/src/connectors/examples/. They aren't registered by default — copy the folder out (or add it to connectors/index.ts) and provide the listed env var:

Connector Env var What it does
sol-defi HELIUS_API_KEY Solana DEX streaming via Helius — live swaps, liquidity adds/removes on Orca Whirlpool and Raydium (AMM v4 + CLMM), token-pair-aware with automatic pool discovery.
alchemy ALCHEMY_AUTH_TOKEN EVM + Solana on-chain webhooks via Alchemy (address activity, NFT activity).
coindesk CRYPTOCOMPARE_API_KEY Crypto price polling via CryptoCompare.
news NEWSAPI_API_KEY Top headlines via thenewsapi.com (polled every 5 min).
cryptoprices Public crypto price polling (no key).

Adding a connector

Drop a folder under server/src/connectors/<name>/ with connector.ts, prompt.ts, normalizer.ts, validator.ts, then register it in connectors/index.ts. The sol-defi example under connectors/examples/sol-defi/ is a good reference for streaming connectors with structured filters; server/AGENTS.md has the full contract.

Stack

  • Runtime: Bun
  • API: Hono (REST + WebSocket, OpenAPI/Swagger at /docs)
  • DB: PostgreSQL with pgvector, via Drizzle ORM
  • Queues: Redis + BullMQ
  • AI: OpenRouter for embeddings + intent compilation, or fully local via QVAC (llama.cpp) when IS_LOCAL=true
  • Monorepo: Turbo, three workspaces — server/, shared/ (DTOs), cli/ (eventmeshcc)
  • Lint/format: Biome (tabs, double quotes)

Run it

Option 1 — Docker (recommended)

git clone https://github.com/shipmesh/eventmesh-engine.git
cd eventmesh
cp .env.example .env
# Edit .env: at minimum set POSTGRES_PASSWORD, OPENROUTER_API_KEY (or IS_LOCAL=true)
docker compose up --build

This brings up Postgres (with pgvector), Redis, and the API on http://localhost:3000. Open http://localhost:3000/docs for the OpenAPI explorer and http://localhost:3000/health for a liveness check.

Option 2 — Local Bun

bun install                      # installs + builds shared/server via postinstall
docker compose up db redis -d    # just the infra
cp .env.example .env             # set DATABASE_URL, REDIS_URL, OPENROUTER_API_KEY
bun run dev                      # runs server (and any active workspaces)

Tests

bun run test:docker   # spins up an ephemeral Postgres on :5433 (tmpfs), runs all tests, tears down

Tests are integration tests — they hit real routes via app.request() against a real DB and (where applicable) real third-party APIs. Pass API keys through env vars; mocks are a last resort.

Environment

Required to boot

Var Purpose
DATABASE_URL Postgres connection string (must have the pgvector extension available).
REDIS_URL Redis for BullMQ event + delivery queues.
OPENROUTER_API_KEY Intent compilation + embeddings — unless IS_LOCAL=true.

Both DATABASE_URL and REDIS_URL have sensible localhost defaults, so a docker compose up flow only needs OPENROUTER_API_KEY (or IS_LOCAL=true) and POSTGRES_PASSWORD.

Optional

Var Default Purpose
IS_LOCAL false Run completions + embeddings on-device via QVAC + llama.cpp. No OpenRouter calls, no data leaves the host.
NODE_ENV development
PORT 3000
LOG_LEVEL info fatal / error / warn / info / debug / trace
PUBLIC_URL Public base URL (used for outbound webhook signing).
COMPILER_ROUTER_MODEL openai/gpt-oss-20b Compiler router model (OpenRouter slug).
COMPILER_SPECIALIST_MODEL openai/gpt-oss-20b Compiler specialist model (OpenRouter slug).
FUZZY_MATCH_MIN_SCORE 0.4 Minimum fuzzy match score (0..1) for entity resolution.

Optional — per connector

Only set these if you enable the matching connector (see Connectors):

Var Connector
HELIUS_API_KEY sol-defi (example)
ALCHEMY_AUTH_TOKEN alchemy (example)
CRYPTOCOMPARE_API_KEY coindesk (example)
NEWSAPI_API_KEY news (example)

See .env.example for the full list with defaults.


Using it

CLI

npx eventmeshcc login                                                          # auth via the running server
npx eventmeshcc connectors                                                     # list available sources
npx eventmeshcc subscribe "any swap over 10k SOL on SOL/USDC" --active         # Solana DEX
npx eventmeshcc subscribe "Jupiter TVL drops more than 5% in an hour" --active # DefiLlama
npx eventmeshcc list                                                           # your subscriptions
npx eventmeshcc listen <id>                                                    # tail matches over WebSocket
npx eventmeshcc subscribe "SOL drops below 80 USDC" --webhook https://...      # webhook delivery

By default the CLI talks to http://localhost:3000; override with --server or EVENTMESH_SERVER_URL.

REST

curl -X POST http://localhost:3000/api/subscriptions \
  -H "Authorization: Bearer $EVENTMESH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"intent":"any trade over 10k SOL on SOL/USDC","sensitivity":"balanced","isActive":true}'

Full schema at http://localhost:3000/docs.

Webhooks

Webhook deliveries are batched, retried with backoff, and signed. Register a webhook URL on a subscription (or per-account in domains/webhooks/) and verify the signature on your side. URLs are validated against loopback / private / metadata addresses before being accepted.


Repository layout

.
├── server/         # Hono backend — connectors, engine, queues, REST + WS
├── shared/         # DTOs and types shared across workspaces
├── cli/            # eventmeshcc — npm CLI + thin WebSocket layer
├── scripts/        # test runner (Dockerized Postgres)
├── docker-compose.yml         # local stack
├── docker-compose.test.yml    # ephemeral test DB
├── Dockerfile
├── turbo.json
├── biome.json
└── .env.example

Workspace dependency order is shared ← server ← cli. Turbo handles build ordering; the postinstall hook prebuilds shared and server so types are available immediately after bun install.

Contributing

Issues and PRs are welcome. Before submitting:

bun run format        # Biome
bun run type-check
bun run test:docker

If you're adding a connector, follow the checklist in server/AGENTS.md and include tests that exercise the real upstream API.

License

Elastic License 2.0 — source-available.

You can:

  • Run Eventmesh in production, including for commercial purposes.
  • Modify it, embed it inside your own product, and redistribute the source.
  • Self-host it for your team, your customers, or your agents.

You cannot:

  • Offer Eventmesh to third parties as a hosted or managed service that exposes a substantial set of its features (i.e. no reselling Eventmesh-as-a-service).
  • Remove or obscure the licensor's notices.

If you want to host Eventmesh as a paid service for others, reach out for a commercial license.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages