A standalone Rust service that converts The Graph subgraph GraphQL queries to Envio HyperIndex / Hasura GraphQL format and forwards them to a HyperIndex endpoint. Responses are converted back to The Graph subgraph format, making it a transparent proxy that lets existing frontends and clients read from HyperIndex without code changes.
Note: This tool is under active development and is currently in a proof-of-concept stage. It is not yet ready for production use. It will likely work for most common subgraph query patterns but may not cover all edge cases.
When migrating from a subgraph to HyperIndex, existing frontends use The Graph's GraphQL query syntax (e.g. streams(first: 2, orderBy: timestamp)) which is different from HyperIndex's Hasura-based syntax (e.g. Stream(limit: 2, order_by: {timestamp: asc})). This converter acts as a middleware proxy so you can point your existing frontend at it without rewriting all your queries.
See the HyperIndex query conversion guide for a manual reference on the differences.
Teams migrating from The Graph to HyperIndex who want to keep their existing frontend queries working during the transition, without rewriting all GraphQL calls upfront. Point your frontend at this proxy, migrate your indexer to HyperIndex, and update your queries at your own pace.
- Query conversion: Converts subgraph GraphQL syntax to HyperIndex / Hasura format
- Response conversion: Converts responses back to subgraph format
- HTTP proxy: Forwards converted queries to your HyperIndex endpoint
- Chain-specific endpoint: Automatically adds
chainIdfilters via/chainId/{chain_id} - Debug endpoint: Inspect converted queries without forwarding (
/debug) - Prometheus metrics: Request latency, error rates, conversion timing
- Filter mapping: Translates all common subgraph filter operators (
_gt,_in,_contains, etc.) to Hasura equivalents
| Endpoint | Description |
|---|---|
POST / |
Convert and forward to HyperIndex (no chain filter) |
POST /chainId/{id} |
Convert and forward, auto-adds chainId filter |
POST /debug |
Return converted query without forwarding |
GET /metrics |
Prometheus metrics |
- Rust (latest stable)
git clone <repository-url>
cd subgraph-to-hyperindex-query-converter
cp .env.example .env
# Set HYPERINDEX_URL in .env
cargo runService starts on http://localhost:3000.
# Required
HYPERINDEX_URL=https://indexer.hyperindex.xyz/your-deployment/v1/graphql
# Optional
PORT=3000
HTTP_TIMEOUT_SECS=30docker build -t subgraph-converter .
docker run -p 3000:3000 --env-file .env subgraph-converterSubgraph input:
query {
streams(first: 2, skip: 10) {
category
cliff
chainId
}
}HyperIndex output (at /):
query {
Stream(limit: 2, offset: 10) {
category
cliff
chainId
}
}HyperIndex output (at /chainId/1):
query {
Stream(limit: 2, offset: 10, where: { chainId: { _eq: "1" } }) {
category
cliff
chainId
}
}| Subgraph Filter | Hasura Equivalent |
|---|---|
field: val |
field: { _eq: val } |
field_not: val |
field: { _neq: val } |
field_gt: val |
field: { _gt: val } |
field_gte: val |
field: { _gte: val } |
field_lt: val |
field: { _lt: val } |
field_lte: val |
field: { _lte: val } |
field_in: [...] |
field: { _in: [...] } |
field_not_in: [...] |
field: { _nin: [...] } |
field_contains: val |
field: { _ilike: "%val%" } |
field_starts_with: val |
field: { _ilike: "val%" } |
field_ends_with: val |
field: { _ilike: "%val" } |
See the full filter table and known limitations in the source code.
- Uses string parsing rather than a full GraphQL parser
orderByandorderDirectionwith variables are not supported (Hasura limitation)- Block/time-travel queries are not supported
_metaqueries only return latest block number- Default limit should not exceed 1000 unless HyperIndex is configured for higher limits
MIT