Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
321 changes: 321 additions & 0 deletions docs/HyperIndex/Guides/query-conversion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
---
id: query-conversion
title: Query Conversion Guide
sidebar_label: Query Conversion
slug: /query-conversion
description: Learn how to convert queries from TheGraph's custom GraphQL syntax to Envio's standard GraphQL syntax.
---

# Query Conversion

Envio uses standard GraphQL query language, while TheGraph uses a custom GraphQL syntax. While the queries are very similar, there are some important differences to be aware of when migrating.

This guide covers all the differences between TheGraph's query syntax and Envio's query syntax, with examples for each conversion rule.

## Converter Tool

We've built a [query converter tool](https://github.com/enviodev/subgraph-to-hyperindex-query-converter) that automatically converts TheGraph queries to Envio's GraphQL syntax. You can:

- **Convert and execute**: Provide your Envio GraphQL endpoint and a query written in TheGraph syntax. The tool will convert it, execute it against your endpoint, and return the results
- **Convert only**: Use the tool to convert queries and view the converted output without executing them

**Repository**: [subgraph-to-hyperindex-query-converter](https://github.com/enviodev/subgraph-to-hyperindex-query-converter)

### Dedicated Tier: Hosted Converter Endpoint

For users on our dedicated tier, we can host the query converter as a proxy endpoint for your hosted indexer. This allows you to continue using TheGraph query syntax without making any changes to your existing queries or client code. Simply point your applications to the converter endpoint, which will automatically translate TheGraph queries to Envio's syntax and forward them to your indexer.

:::warning Beta Status
This converter tool is still very much in beta. We're actively working on it and discovering new query conversions that need to be handled.

**If you encounter any conversion failures or incorrect conversions, please [file a GitHub issue](https://github.com/enviodev/subgraph-to-hyperindex-query-converter/issues) in the repository so we can address it.**
:::

---

### 1. Entity Name Conversion

**Rule**: TheGraph uses pluralized entity names (e.g., `pools`, `factories`, `tokens`), while Envio uses the entity name exactly as defined in your schema (singular, PascalCase).

**Example**:

```graphql
# TheGraph
query {
pools { id }
factories { id }
tokens { id }
}

# Envio
query {
Pool { id }
Factory { id }
Token { id }
}
```

Single entity queries use `EntityName_by_pk` (by primary key) in Envio. Alternatively, you could use a `where` clause with the primary key field:

```graphql
# TheGraph
query {
pool(id: "0x123") { value }
}

# Envio
query {
Pool_by_pk(id: "0x123") { value }
}
```

Or using a `where` clause:

```graphql
# Envio
query {
Pool(where: {id: {_eq: "0x123"}}) { value }
}
```

### 2. Pagination Parameters

#### First → Limit

**Rule**: Use `limit` instead of `first`.

**Example**:

```graphql
# TheGraph
query {
pools(first: 10) { id }
}

# Envio
query {
Pool(limit: 10) { id }
}
```

#### Skip → Offset

**Rule**: Use `offset` instead of `skip`.

**Example**:

```graphql
# TheGraph
query {
pools(skip: 20) { id }
}

# Envio
query {
Pool(offset: 20) { id }
}
```

### 3. Ordering Parameters

#### OrderBy and OrderDirection → Order_by

**Rule**: Combine `orderBy` and `orderDirection` into a single `order_by: {field: direction}` clause.

**Example**:

```graphql
# TheGraph
query {
pools(orderBy: name, orderDirection: desc) { id name }
# Use orderDirection: asc for ascending order
}

# Envio
query {
Pool(order_by: {name: desc}) { id name }
# Use asc for ascending order, e.g., order_by: {name: asc}
}
```

### 4. Filter Operators

#### Equality Filter

**Rule**: Use `where: {field: {_eq: value}}` format for simple equality filters.

**Example**:

```graphql
# TheGraph
query {
pools(name: "test") { id name }
}

# Envio
query {
Pool(where: {name: {_eq: "test"}}) { id name }
}
```

#### Comparison Filters

**Rule**: Use Hasura filter operators for comparison filters. Replace `_not` with `_neq`, `_not_in` with `_nin`, and keep `_gt`, `_gte`, `_lt`, `_lte`, `_in` as-is, wrapping them in `where: {field: {_operator: value}}`.

**Examples**:

```graphql
# TheGraph
query {
pools(id_not: "0x123") { id }
pools(amount_gt: 100) { id amount }
pools(amount_gte: 100) { id amount }
pools(timestamp_lt: 1650000000) { id timestamp }
pools(timestamp_lte: 1650000000) { id timestamp }
pools(id_in: ["1", "2", "3"]) { id name }
pools(id_not_in: ["1", "2", "3"]) { id name }
}

# Envio
query {
Pool(where: {id: {_neq: "0x123"}}) { id }
Pool(where: {amount: {_gt: 100}}) { id amount }
Pool(where: {amount: {_gte: 100}}) { id amount }
Pool(where: {timestamp: {_lt: 1650000000}}) { id timestamp }
Pool(where: {timestamp: {_lte: 1650000000}}) { id timestamp }
Pool(where: {id: {_in: ["1", "2", "3"]}}) { id name }
Pool(where: {id: {_nin: ["1", "2", "3"]}}) { id name }
}
```

#### String Filters

**Rule**: Use `_ilike` with `%` wildcards for string filters. Replace `_contains` with `_ilike: "%text%"`, `_starts_with` with `_ilike: "text%"`, and `_ends_with` with `_ilike: "%text"`. The `%` symbol represents any text at that position in the pattern.

**Examples**:

```graphql
# TheGraph
query {
pools(name_contains: "test") { id name }
pools(name_not_contains: "test") { id name }
pools(symbol_starts_with: "ABC") { id symbol }
pools(symbol_ends_with: "XYZ") { id symbol }
pools(name_not_starts_with: "A") { id name }
pools(name_not_ends_with: "x") { id name }
pools(name_contains_nocase: "test") { id name }
pools(name_starts_with_nocase: "test") { id name }
pools(name_ends_with_nocase: "test") { id name }
}

# Envio
query {
Pool(where: {name: {_ilike: "%test%"}}) { id name }
Pool(where: {_not: {name: {_ilike: "%test%"}}}) { id name }
Pool(where: {symbol: {_ilike: "ABC%"}}) { id symbol }
Pool(where: {symbol: {_ilike: "%XYZ"}}) { id symbol }
Pool(where: {_not: {name: {_ilike: "A%"}}}) { id name }
Pool(where: {_not: {name: {_ilike: "%x"}}}) { id name }
Pool(where: {name: {_ilike: "%test%"}}) { id name }
Pool(where: {name: {_ilike: "test%"}}) { id name }
Pool(where: {name: {_ilike: "%test"}}) { id name }
}
```

### 5. Variable Type Conversions

#### ID → String

**Rule**: Use `String` and `String!` instead of `ID` and `ID!` for variable types.

**Example**:

```graphql
# TheGraph
query getPoolValue($id: ID!) {
pool(id: $id) { value }
}

# Envio
query getPoolValue($id: String!) {
Pool_by_pk(id: $id) { value }
}
```

#### Bytes → String

**Rule**: Use `String` and `String!` instead of `Bytes` and `Bytes!` for variable types.

**Example**:

```graphql
# TheGraph
query getTokens($id: Bytes) {
tokens(where: { id: $id }) { id timestamp }
}

# Envio
query getTokens($id: String) {
Token(where: {id: {_eq: $id}}) { id timestamp }
}
```

#### BigInt → numeric

**Rule**: Use `numeric` and `numeric!` instead of `BigInt` and `BigInt!` for variable types.

**Example**:

```graphql
# TheGraph
query GetTokens($amount: BigInt) {
tokens(where: { amount: $amount }) { id amount }
}

# Envio
query GetTokens($amount: numeric) {
Token(where: {amount: {_eq: $amount}}) { id amount }
}
```

#### BigDecimal → numeric

**Rule**: Use `numeric` and `numeric!` instead of `BigDecimal` and `BigDecimal!` for variable types.

**Example**:

```graphql
# TheGraph
query GetValue($value: BigDecimal!) {
pools(where: { value: $value }) { id }
}

# Envio
query GetValue($value: numeric!) {
Pool(where: {value: {_eq: $value}}) { id }
}
```

---

## Summary Table

| Category | TheGraph | Envio | Example |
|----------|-----------|-------|---------|
| **Entity Names** | Plural camelCase | Singular PascalCase (as-is from schema) | `pools` → `Pool` |
| **Pagination** | `first`, `skip` | `limit`, `offset` | `first: 10, skip: 20` → `limit: 10, offset: 20` |
| **Ordering** | `orderBy`, `orderDirection` | `order_by: {field: direction}` | `orderBy: name, orderDirection: desc` → `order_by: {name: desc}` |
| **Equality Filter** | `field: value` | `field: {_eq: value}` | `name: "test"` → `name: {_eq: "test"}` |
| **Comparison Filters** | `field_gt`, `field_gte`, etc. | `field: {_gt: value}`, etc. | `amount_gt: 100` → `amount: {_gt: 100}` |
| **String Filters** | `_contains`, `_starts_with`, etc. | `_ilike` with `%` wildcards | `name_contains: "test"` → `name: {_ilike: "%test%"}` |
| **Variable Types** | `ID`, `Bytes`, `BigInt`, `BigDecimal` | `String`, `numeric` | `$id: ID!` → `$id: String!` |

---

## Getting Help

If you encounter any issues with query conversion or have questions:

- **Converter Issues**: File a [GitHub issue](https://github.com/enviodev/subgraph-to-hyperindex-query-converter/issues) for the converter tool
- **General Questions**: Join our [Discord community](https://discord.gg/envio) for support

2 changes: 1 addition & 1 deletion docs/HyperIndex/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ HyperIndex is a powerful tool that can be used to index any contract. There are
- Use the `field_selection` option to add additional fields to your index. Doc here: [field selection](../HyperIndex/configuration-file#field-selection)
- Use the `unordered_multichain_mode` option to enable unordered multichain mode, this is the most common need for multichain indexing. However comes with tradeoffs worth understanding. Doc here: [unordered multichain mode](../HyperIndex/configuration-file#unordered-multichain-mode)
- Use wildcard indexing to index by event signatures rather than by contract address.
- HyperIndex uses the standard graphql query language, where as the subgraph uses a custom query language. You can read about the slight nuances [here](https://docs.sablier.com/api/caveats). (We are working on a basic tool to help with backwards compatibility, please check in with us on discord for it's current status).
- Query Conversion: HyperIndex uses the standard GraphQL query language, whereas TheGraph uses a custom GraphQL syntax. While queries are very similar, there are important differences when querying your indexed data. See the [Query Conversion Guide](../HyperIndex/query-conversion) for detailed conversion rules and examples.
- Loaders are a powerful feature to optimize historical sync performance. You can read more about them [here](../HyperIndex/loaders).
- HyperIndex is very flexible and can be used to index offchain data too or send messages to a queue etc for fetching external data, you can further optimise the fetching by using the [effects api](/docs/HyperIndex/effect-api)

Expand Down
63 changes: 63 additions & 0 deletions docs/HyperIndex/supported-networks/hoodi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
id: hoodi
title: Hoodi
sidebar_label: Hoodi
slug: /hoodi
---

# Hoodi

## Indexing Hoodi Data with Envio

| **Field** | **Value** |
|-------------------------------|----------------------------------------------------------------------------------------------------|
| **Hoodi Chain ID** | 560048 |
| **HyperSync URL Endpoint** | [https://hoodi.hypersync.xyz](https://hoodi.hypersync.xyz) or [https://560048.hypersync.xyz](https://560048.hypersync.xyz) |
| **HyperRPC URL Endpoint** | [https://hoodi.rpc.hypersync.xyz](https://hoodi.rpc.hypersync.xyz) or [https://560048.rpc.hypersync.xyz](https://560048.rpc.hypersync.xyz) |

---

### Tier

TESTNET 🎒

### Overview

Envio is a modular hyper-performant data indexing solution for Hoodi, enabling applications and developers to efficiently index and aggregate real-time and historical blockchain data. Envio offers three primary solutions for indexing and accessing large amounts of data: [HyperIndex](/docs/HyperIndex/overview) (a customizable indexing framework), [HyperSync](/docs/HyperSync/overview) (a real-time indexed data layer), and [HyperRPC](/docs/HyperRPC/overview-hyperrpc) (extremely fast read-only RPC).

HyperSync accelerates the synchronization of historical data on Hoodi, enabling what usually takes hours to sync millions of events to be completed in under a minute—up to 1000x faster than traditional RPC methods.

Designed to optimize the user experience, Envio offers automatic code generation, flexible language support, multi-chain data aggregation, and a reliable, cost-effective hosted service.

To get started, see our documentation or follow our quickstart [guide](/docs/HyperIndex/contract-import).

---

### Defining Network Configurations

```yaml
name: IndexerName # Specify indexer name
description: Indexer Description # Include indexer description
networks:
- id: 560048 # Hoodi
start_block: START_BLOCK_NUMBER # Specify the starting block
contracts:
- name: ContractName
address:
- "0xYourContractAddress1"
- "0xYourContractAddress2"
handler: ./src/EventHandlers.ts
events:
- event: Event # Specify event
- event: Event
```

With these steps completed, your application will be set to efficiently index Hoodi data using Envio’s blockchain indexer.

For more information on how to set up your config, define a schema, and write event handlers, refer to the guides section in our [documentation](/docs/HyperIndex/configuration-file).

### Support

Can’t find what you’re looking for or need support? Reach out to us on [Discord](https://discord.com/invite/Q9qt8gZ2fX); we’re always happy to help!

---
Loading