Schema Reference (schema.graphql)
Entity Rules
- Every type is an entity — no
@entitydecorator (unlike TheGraph) - Must have an
idfield first —ID!(recommended), orString!,Int!,BigInt! - Names: 1-63 chars, alphanumeric + underscore, no reserved words
- Relationship fields use the entity type directly:
collection: NftCollection!— never add_idin the schema field name - The
_idsuffix only appears in TypeScript handlers (added by codegen): schema fieldcollection→ handler fieldcollection_id, typed as the referenced entity's id
Scalar Types
| Schema Type | TypeScript Type | Notes |
|---|---|---|
ID! |
string |
Recommended entity id; String!/Int!/BigInt! also allowed as id |
String! |
string |
|
Int! |
number |
|
Float! |
number |
|
Boolean! |
boolean |
|
BigInt! |
bigint |
Use @config(precision: N) for custom precision |
BigDecimal! |
BigDecimal |
Use @config(precision: N, scale: M) |
Bytes! |
string or Uint8Array |
Depends on bytes_type in config.yaml: hex (the EVM/Fuel default) gives a hex-encoded string, uint8array gives a Uint8Array stored as raw bytes. SVM is always Uint8Array |
Timestamp! |
Date |
|
Json! |
any |
Enums
enum Status {
Active
Inactive
Paused
}
type Pool {
id: ID!
status: Status!
allowedStatuses: [Status!]! # enum arrays supported
}
@derivedFrom
Virtual reverse-lookup — cannot access in handlers, only in API queries:
type Pool {
id: ID!
swaps: [Swap!]! @derivedFrom(field: "pool")
}
type Swap {
id: ID!
pool: Pool! # entity reference — field name matches @derivedFrom "field" arg
}
Critical rules:
- The
fieldargument must match the schema field name on the child entity — which is the entity reference name ("pool"), not"pool_id" - In TypeScript handlers, set this relationship using the
_idsuffix:pool_id: poolEntity.id— codegen transformspool: Pool!→pool_idin the TypeScript type - Never write
pool_id: String!in the schema when using@derivedFrom(field: "pool"). The schema field must bepool: Pool!; the_idis a codegen artifact for handlers only
@index
Single-field index for faster queries:
type Transfer {
id: ID!
from: String! @index
to: String! @index
timestamp: BigInt! @index
}
Composite index with optional DESC direction:
type Trade @index(fields: ["poolId", ["date", "DESC"]]) {
id: ID!
poolId: String!
date: BigInt!
volume: BigDecimal!
}
- Fields default to ASC; use
["field", "DESC"]for descending - IDs and
@derivedFromfields are automatically indexed - Any non-derived field is queryable via
context.Entity.getWhere(). Indexes are never created up front:@indexfields are built together when the backfill finishes, before the indexer reports ready, and any field — marked or not — is indexed on the spot if agetWhereneeds it earlier, pausing indexing while it builds
@config
Customize precision for numeric types:
type Token {
id: ID!
totalSupply: BigInt! @config(precision: 100)
price: BigDecimal! @config(precision: 30, scale: 15)
}
BigIntdefault precision: 76 digitsBigDecimaldefault: precision 76, scale 32
Array Rules
- Supported:
[Type!]!— non-nullable elements, non-nullable array - Not supported:
[Type]!(nullable elements), nested arrays,[Boolean!]!,[Timestamp!]! - Entity arrays require
@derivedFrom— bare[Swap!]!without it causes a codegen error
Example
enum PoolType {
UniswapV2
UniswapV3
}
type Token {
id: ID!
symbol: String!
}
type Pool @index(fields: ["token0", "token1"]) {
id: ID!
poolType: PoolType!
token0: Token! # entity reference — handler uses token0_id
token1: Token! # entity reference — handler uses token1_id
reserve0: BigInt!
reserve1: BigInt!
totalValueLocked: BigDecimal! @config(precision: 30, scale: 15)
swaps: [Swap!]! @derivedFrom(field: "pool") # "pool" matches Swap.pool field name
}
type Swap {
id: ID!
pool: Pool! @index # entity reference — handler uses pool_id; @derivedFrom field arg = "pool"
sender: String! @index
amount0In: BigInt!
amount1In: BigInt!
timestamp: BigInt! @index
}
Schema vs handler field names (entity refs to ID!-keyed entities):
| Schema field | Schema type | TypeScript handler field |
|---|---|---|
pool |
Pool! |
pool_id: string |
token0 |
Token! |
token0_id: string |
collection |
NftCollection! |
collection_id: string |
Codegen appends _id to entity reference fields (never add it in the schema), typed as the referenced entity's id.
If something is unclear, use the
envio-docsskill to search and read the latest documentation.