Subgraph Migration
This skill should be used when the user asks to "migrate from subgraph", "convert subgraph to hyperindex", "migrate from thegraph", "port subgraph", "convert subgraph handlers", "migrate assemblyscript to typescript", or mentions TheGraph, subgraph migration, subgraph.yaml conversion, or converting from TheGraph to Envio. For core HyperIndex development patterns, refer to the hyperindex-development skill.
What this skill does
# Subgraph to HyperIndex Migration
Migrate from TheGraph subgraphs to Envio HyperIndex. HyperIndex delivers up to 100x faster indexing with a developer-friendly TypeScript API.
## Migration Overview
Three major steps:
1. `subgraph.yaml` → `config.yaml`
2. Schema migration (near copy-paste)
3. Event handler migration (AssemblyScript → TypeScript)
## Step 1: Config Migration
### subgraph.yaml → config.yaml
**TheGraph:**
```yaml
specVersion: 0.0.4
dataSources:
- kind: ethereum/contract
name: Factory
network: mainnet
source:
address: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f"
startBlock: 10000835
abi: Factory
mapping:
eventHandlers:
- event: PairCreated(indexed address,indexed address,address,uint256)
handler: handlePairCreated
templates:
- name: Pair
source:
abi: Pair
```
**HyperIndex:**
```yaml
name: my-indexer
networks:
- id: 1
start_block: 10000835
contracts:
- name: Factory
address: 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
handler: src/factory.ts
events:
- event: PairCreated(address indexed token0, address indexed token1, address pair, uint256)
- name: Pair
handler: src/pair.ts # No address - dynamic
events:
- event: Swap(...)
```
**Key differences:**
- Remove `dataSources`, `templates`, `mapping` nesting
- Use `networks` → `contracts` structure
- Event signatures include parameter names
- Dynamic contracts have no address field
## Step 2: Schema Migration
### Remove @entity decorator
```graphql
# TheGraph
type Token @entity {
id: ID!
symbol: String!
}
# HyperIndex
type Token {
id: ID!
symbol: String!
}
```
### Convert Bytes to String
```graphql
# TheGraph
address: Bytes!
# HyperIndex
address: String!
```
### Entity Relationships
```graphql
# TheGraph
type Transfer @entity {
token: Token!
}
# HyperIndex - use _id suffix
type Transfer {
token_id: String!
}
```
### Entity Arrays MUST have @derivedFrom
```graphql
# TheGraph (sometimes implicit)
type Token @entity {
transfers: [Transfer!]!
}
# HyperIndex - REQUIRED explicit @derivedFrom
type Token {
transfers: [Transfer!]! @derivedFrom(field: "token")
}
type Transfer {
token_id: String! # The field referenced by @derivedFrom
}
```
**Critical:** Arrays without `@derivedFrom` cause codegen error EE211.
## Step 3: Handler Migration
### Basic Pattern
**TheGraph (AssemblyScript):**
```typescript
export function handleTransfer(event: TransferEvent): void {
let entity = new Transfer(event.transaction.hash.toHexString());
entity.from = event.params.from;
entity.to = event.params.to;
entity.amount = event.params.value;
entity.save();
}
```
**HyperIndex (TypeScript):**
```typescript
import { MyContract } from "generated";
MyContract.Transfer.handler(async ({ event, context }) => {
const entity = {
id: `${event.chainId}-${event.transaction.hash}-${event.logIndex}`,
from: event.params.from,
to: event.params.to,
amount: event.params.value,
blockNumber: BigInt(event.block.number),
};
context.Transfer.set(entity);
});
```
### Entity Loading
**TheGraph:**
```typescript
let token = Token.load(id);
if (token == null) {
token = new Token(id);
}
```
**HyperIndex:**
```typescript
let token = await context.Token.get(id);
if (!token) {
token = { id, name: "Unknown", /* ... */ };
}
```
### Entity Updates
**TheGraph:**
```typescript
token.totalSupply = newSupply;
token.save();
```
**HyperIndex (use spread - entities are immutable):**
```typescript
context.Token.set({
...token,
totalSupply: newSupply,
});
```
### Dynamic Contract Registration
**TheGraph:**
```typescript
import { Pair as PairTemplate } from "../generated/templates";
PairTemplate.create(event.params.pair);
```
**HyperIndex:**
```typescript
// Register BEFORE handler
Factory.PairCreated.contractRegister(({ event, context }) => {
context.addPair(event.params.pair);
});
Factory.PairCreated.handler(async ({ event, context }) => {
// Handle event...
});
```
### Contract State (RPC Calls)
**TheGraph:**
```typescript
let contract = ERC20.bind(address);
let name = contract.name();
```
**HyperIndex (use Effect API):**
```typescript
import { createEffect, S } from "envio";
export const getTokenName = createEffect({
name: "getTokenName",
input: S.string,
output: S.string,
cache: true,
}, async ({ input: address }) => {
// Use viem for RPC calls
const name = await client.readContract({
address: address as `0x${string}`,
abi: ERC20_ABI,
functionName: "name",
});
return name;
});
// In handler
const name = await context.effect(getTokenName, address);
```
## Common Migration Issues
### Missing async/await
```typescript
// WRONG - returns {} instead of entity
const token = context.Token.get(id);
// CORRECT
const token = await context.Token.get(id);
```
### Field Selection for Transaction Data
```yaml
# Add to config.yaml for event.transaction.hash access
events:
- event: Transfer(...)
field_selection:
transaction_fields:
- hash
```
### Multichain ID Prefixes
```typescript
// Always prefix with chainId for multichain
const id = `${event.chainId}-${originalId}`;
```
### BigDecimal Precision
Maintain precision from original subgraph:
```typescript
import { BigDecimal } from "generated";
const ZERO_BD = new BigDecimal(0);
const ONE_BD = new BigDecimal(1);
// Don't simplify to JavaScript numbers
```
## Migration Checklist
- [ ] Convert subgraph.yaml to config.yaml
- [ ] Remove @entity decorators from schema
- [ ] Change Bytes! to String!
- [ ] Use _id suffix for relationships
- [ ] Add @derivedFrom to all entity arrays
- [ ] Add async to all handlers
- [ ] Add await to all context.Entity.get() calls
- [ ] Use spread operator for entity updates
- [ ] Replace Template.create() with contractRegister
- [ ] Add field_selection for transaction data
- [ ] Prefix IDs with chainId for multichain
- [ ] Convert contract bindings to Effect API
## Additional Resources
### Reference Files
For detailed migration patterns:
- **`references/migration-patterns.md`** - Complete pattern reference
- **`references/common-mistakes.md`** - Pitfalls and solutions
### External Resources
- Full docs: https://docs.envio.dev/docs/HyperIndex-LLM/hyperindex-complete
- Migration guide: https://docs.envio.dev/docs/migration-guide
- Example indexers:
- Uniswap v4: https://github.com/enviodev/uniswap-v4-indexer
- Safe: https://github.com/enviodev/safe-analysis-indexer
Related in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".