chore: added subgraph migration mdc file to cursor rules - #725
Conversation
WalkthroughAdds a new mandatory documentation file Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Developer
participant Doc as Migration Doc
participant Legacy as TheGraph Subgraph
participant Env as Envio HyperIndex
participant Eff as Effect API
rect #f8f9fa
Dev->>Doc: Read migration lifecycle & patterns
Dev->>Legacy: Inspect schema, handlers, helpers
end
rect #eef8f2
Dev->>Env: Refactor schema (IDs prefixed by event.chainId)
Dev->>Eff: Replace .bind calls with Effect API calls
Dev->>Env: Register dynamic contracts via factory events
end
rect #fff4e6
Env->>Dev: Runtime/QA feedback (codegen, tsc, tests)
Dev->>Env: Iterate fixes and final verification
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (8)
.cursor/rules/subgraph-migration.mdc (8)
86-86: Typo: trailing “s” after bold text.Remove the stray “s” in “Common Runtime Errors to Watch For:**s”.
-**Common Runtime Errors to Watch For:**s +**Common Runtime Errors to Watch For:**
1112-1134: Add timeout to external fetch example.Demonstrate cancelation to avoid hung handlers.
- const something = await fetch( - `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}` - ); - return something.json(); + const ctrl = new AbortController(); + const t = setTimeout(() => ctrl.abort(), 10_000); + const res = await fetch( + `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}`, + { signal: ctrl.signal } + ); + clearTimeout(t); + return res.json();
1007-1012: BigDecimal constructor inputs: prefer string literals for precision and consistency.Using numeric literals is easy to mimic incorrectly elsewhere.
-export const ZERO_BD = new BigDecimal(0); -export const ONE_BD = new BigDecimal(1); +export const ZERO_BD = new BigDecimal('0'); +export const ONE_BD = new BigDecimal('1');-export const ZERO_BD = new BigDecimal(0); -export const ONE_BD = new BigDecimal(1); +export const ZERO_BD = new BigDecimal('0'); +export const ONE_BD = new BigDecimal('1');Also applies to: 1036-1043
1029-1031: Clarify BigDecimal import vs dependency guidance.Doc currently says to install bignumber.js, but also to import BigDecimal from "generated". Tighten to one canonical approach to avoid confusion.
-# Install bignumber.js for BigDecimal support -pnpm add bignumber.js +# BigDecimal is re-exported from "generated". Install bignumber.js only if you use it directly elsewhere. +pnpm add bignumber.js-// ✅ CORRECT - Import from generated types (which re-exports BigNumber) +// ✅ CORRECT - Import from generated types (re-exported BigNumber) import { BigDecimal } from 'generated';Add a note: “Do not import BigDecimal from 'bignumber.js' in app code.”
Also applies to: 1539-1544
355-375: Show unordered_multichain_mode in the YAML example.You mention it later; include it in the primary snippet to reduce misconfig.
-contracts: +unordered_multichain_mode: true +contracts:
57-62: Clarify “whitelist commands” phrasing.This reads like a security prompt; suggest clearer instruction for local/CI.
-Prompt the user to whitelist the following commands: +Ensure these commands are permitted in your local/CI environment:
246-248: Formatting: missing closing backtick for inline code.Close the
@derivedFrominline code span.-**Envio requires explicit relationship definitions** via `@derivedFrom +**Envio requires explicit relationship definitions** via `@derivedFrom`
114-132: Add a note that handlers using transaction.hash require field_selection.To prevent copy–paste errors, annotate the first handler and entity patterns with a reminder about config.yaml field_selection for transaction fields.
// TODO: Implement business logic from subgraph // Reference: original-subgraph/src/contract.ts + // Note: if you use event.transaction.hash, add field_selection.transaction_fields: [hash] in config.yaml.transactionHash: event.transaction.hash, + // Note: requires field_selection.transaction_fields: [hash] in config.yamlAlso applies to: 944-955
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.cursor/rules/subgraph-migration.mdc(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-11T08:49:57.399Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/test_codegen/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:49:57.399Z
Learning: Applies to scenarios/test_codegen/**/*.ts : Always cast timestamps from events to BigInt (e.g., BigInt(event.block.timestamp))
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:47:04.346Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/fuel_test/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:47:04.346Z
Learning: Applies to scenarios/fuel_test/**/*.ts : Always cast timestamps from events to BigInt, e.g., `BigInt(event.block.timestamp)`; never use raw timestamps
Applied to files:
.cursor/rules/subgraph-migration.mdc
🔇 Additional comments (2)
.cursor/rules/subgraph-migration.mdc (2)
1-6: Solid addition; strong structure and actionable guidance.This MDC will help reduce migration churn and standardize patterns across PRs. No blocking issues with adding the file.
239-243: Confirm getWhere selector semantics (single vs multi).Examples assign the result of
context.Mint.getWhere.transaction_id.eq(...)to a single entity. IfgetWherecan return multiple rows, the example should use a plural or.first()helper to avoid confusion.Do your generated contexts return a single row for
getWhere.<field>.eq()or an array/iterator? If array, I can update the snippets to use.first()or adjust variable naming.Also applies to: 1765-1768
| ...entity, | ||
| field: newValue, | ||
| updatedAt: BigInt(Date.now()), | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use block timestamp, not Date.now(), for updatedAt.
Mixing wall-clock millis with on-chain seconds creates inconsistent units.
- updatedAt: BigInt(Date.now()),
+ updatedAt: BigInt(event.block.timestamp),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| }; | |
| updatedAt: BigInt(event.block.timestamp), | |
| }; |
🤖 Prompt for AI Agents
In .cursor/rules/subgraph-migration.mdc around line 973, the code sets updatedAt
using Date.now(), which mixes millisecond wall-clock time with on-chain seconds;
replace Date.now() with the block.timestamp value (or convert consistently) so
updatedAt uses the on-chain block timestamp (seconds) and adjust any downstream
expectations (or multiply/divide as needed) to keep all timestamps in the same
unit.
| const publicClient = createPublicClient({ | ||
| chain: { | ||
| id: 6342, // MegaETH Testnet - adjust for your network | ||
| name: 'MegaETH Testnet', | ||
| network: 'megaeth-testnet', | ||
| nativeCurrency: { | ||
| decimals: 18, | ||
| name: 'MegaETH', | ||
| symbol: 'METH', | ||
| }, | ||
| rpcUrls: { | ||
| default: { | ||
| http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'], | ||
| }, | ||
| public: { | ||
| http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'], | ||
| }, | ||
| }, | ||
| }, | ||
| transport: http(process.env.RPC_URL), | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid hardcoded chain config in Effect; make it chain-agnostic.
Baking “MegaETH Testnet” and a fixed chain id into docs will be copy–pasted and later break multichain setups.
-const publicClient = createPublicClient({
- chain: {
- id: 6342, // MegaETH Testnet - adjust for your network
- name: 'MegaETH Testnet',
- network: 'megaeth-testnet',
- nativeCurrency: { decimals: 18, name: 'MegaETH', symbol: 'METH' },
- rpcUrls: {
- default: { http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'] },
- public: { http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'] },
- },
- },
- transport: http(process.env.RPC_URL),
-});
+const publicClient = createPublicClient({
+ // Prefer environment-configured RPC; provide one per chain via env or config.
+ transport: http(process.env.RPC_URL!),
+});Add a note: pass chain-specific RPC via env per network or keep a registry keyed by event.chainId.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const publicClient = createPublicClient({ | |
| chain: { | |
| id: 6342, // MegaETH Testnet - adjust for your network | |
| name: 'MegaETH Testnet', | |
| network: 'megaeth-testnet', | |
| nativeCurrency: { | |
| decimals: 18, | |
| name: 'MegaETH', | |
| symbol: 'METH', | |
| }, | |
| rpcUrls: { | |
| default: { | |
| http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'], | |
| }, | |
| public: { | |
| http: [process.env.RPC_URL || 'https://rpc.ankr.com/megaeth_testnet'], | |
| }, | |
| }, | |
| }, | |
| transport: http(process.env.RPC_URL), | |
| }); | |
| const publicClient = createPublicClient({ | |
| // Prefer environment-configured RPC; provide one per chain via env or config. | |
| transport: http(process.env.RPC_URL!), | |
| }); |
🤖 Prompt for AI Agents
.cursor/rules/subgraph-migration.mdc around lines 1199 to 1219: the snippet
hardcodes a specific chain (MegaETH Testnet) and RPC URL which breaks multichain
usage; replace the fixed config with a chain-agnostic approach by reading chain
parameters (chainId, name, network, nativeCurrency, rpc URL) from environment
variables or from a registry keyed by chainId (e.g.,
process.env.RPC_URL_<CHAIN_ID> or a lookup map), pass the resolved values into
createPublicClient at runtime, and include a sensible fallback or explicit error
when no RPC for the requested chain is found.
|
Wow, this is huge 🔥 Do you want it just to be kept in the repository, or automatically added to the user's project on initialization? |
|
@DZakh shot! That's a good question. Maybe for now we can just keep it in the repo to have a solid version of it somewhere. |
|
Although I'm open to suggestions, don't see any harm in adding in on initialisation I suppose. |
|
Let's start with simply storing it in the repo. I don't know the cons to include it on init, just a little bit worried of the file size 😅 Could you take a look at the Coderabbit comments and whether they make sense. Let me know if everything is good and I'll aprove the PR. Also, it would be nice to share the file in the doc section https://docs.envio.dev/docs/HyperIndex/migration-guide |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
.cursor/rules/subgraph-migration.mdc (3)
945-960: Nice: ID template + field_selection reminder colocated.This example already uses hyphens and reminds about field_selection for transaction.hash. Good consistency with the rule; keep it.
973-981: Use on-chain block timestamp, not Date.now(), for updatedAt.Mixing wall-clock ms with on-chain seconds leads to inconsistent units; also aligns with the team learning to always cast event timestamps to BigInt.
- updatedAt: BigInt(Date.now()), + updatedAt: BigInt(event.block.timestamp),
1205-1228: Avoid hardcoded chain config in viem client; make it chain-agnostic.Hardcoding a specific testnet and RPC will be copy–pasted and break multichain setups. Prefer transport-only and resolve RPC per chainId via env or a registry.
-const publicClient = createPublicClient({ - chain: { - id: 6342, // MegaETH Testnet - adjust for your network - name: 'MegaETH Testnet', - network: 'megaeth-testnet', - nativeCurrency: { - decimals: 18, - name: 'MegaETH', - symbol: 'METH', - }, - rpcUrls: { - default: { - http: [process.env.RPC_URL], - }, - public: { - http: [process.env.RPC_URL], - }, - }, - }, - transport: http(process.env.RPC_URL), -}); +const publicClient = createPublicClient({ + // Provide chain-specific RPC via env (e.g., RPC_URL_<CHAIN_ID>) or a registry map. + transport: http(process.env.RPC_URL!), +});Add a short note below showing a simple resolver, e.g.,
const rpc = process.env[\RPC_URL_${event.chainId}`]`.
🧹 Nitpick comments (3)
.cursor/rules/subgraph-migration.mdc (3)
118-121: Standardize ID delimiter to hyphen to match multichain rule.Use hyphens consistently (you use underscores here but hyphens elsewhere and in the rules above). Also add a near-by reminder about field_selection for transaction.hash.
- id: `${event.chainId}_${event.block.number}_${event.logIndex}`, + id: `${event.chainId}-${event.block.number}-${event.logIndex}`, + // Note: transaction.hash requires field_selection in config.yaml
86-86: Fix typo in section heading.-**Common Runtime Errors to Watch For:**s +**Common Runtime Errors to Watch For:**
1035-1037: Clarify BigDecimal dependency guidance to avoid confusion.You later instruct to import BigDecimal from "generated" (not from bignumber.js). Make the install note conditional.
-# Install bignumber.js for BigDecimal support -pnpm add bignumber.js +# BigDecimal is re-exported from "generated". +# Only install bignumber.js if codegen/runtime complains about a missing peer dep. +# pnpm add bignumber.js
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.cursor/rules/subgraph-migration.mdc(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-08-11T08:42:57.311Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:42:57.311Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Always cast timestamps to BigInt (e.g., `BigInt(event.block.timestamp)`) and never use raw timestamps
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:49:57.399Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/test_codegen/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:49:57.399Z
Learning: Applies to scenarios/test_codegen/**/*.ts : Always cast timestamps from events to BigInt (e.g., BigInt(event.block.timestamp))
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:47:04.346Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/fuel_test/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:47:04.346Z
Learning: Applies to scenarios/fuel_test/**/*.ts : Always cast timestamps from events to BigInt, e.g., `BigInt(event.block.timestamp)`; never use raw timestamps
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:47:04.346Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/fuel_test/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:47:04.346Z
Learning: Applies to scenarios/fuel_test/**/*.ts : With preload enabled (handlers run twice), all external calls (e.g., fetch) MUST be implemented via the Envio Effect API (experimental_createEffect and context.effect)
Applied to files:
.cursor/rules/subgraph-migration.mdc
🔇 Additional comments (4)
.cursor/rules/subgraph-migration.mdc (4)
1309-1324: Schema/type alignment for decimals fields.You cast
decimalsto BigInt in the example entity. Many schemas model ERC20 decimals as Int (number). Ensure the example mirrors the schema guidance below (“Int! → number”).If schema uses
Int!, change:- decimals: BigInt(tokenMetadata.decimals), + decimals: tokenMetadata.decimals,
1118-1160: Good Effect API guidance with preload.Clear pattern: define effect with schema, consume via
context.effect, and!context.isPreloadnote. Solid baseline.
399-399: Keepunordered_multichain_mode: true—the flag name is confirmed as correct per Envio docs.
239-243: Confirm handler-time query API name (getWherevswhere)
After runningpnpm codegen, inspect your generated entity definitions (e.g. ingenerated/src/db/…) to see whether the finder method iswhere,getWhere, or named differently, and update the examples to match. Also applies to lines 1768–1776.
| // Define an effect. It can have any name you want. | ||
| export const getSomething = experimental_createEffect( | ||
| { | ||
| // The name for debugging purposes | ||
| name: "getSomething", | ||
| // The input schema for the effect | ||
| input: { | ||
| address: S.string, | ||
| blockNumber: S.number, | ||
| }, | ||
| output: S.union([S.string, null]), | ||
| }, | ||
| async ({ input, context }) => { | ||
| // Fetch or other external calls MUST always be done in an effect. | ||
| const something = await fetch( | ||
| `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}` | ||
| ); | ||
| return something.json(); | ||
| } |
There was a problem hiding this comment.
Effect output schema mismatch with returned JSON.
You declare output: S.union([S.string, null]) but return something.json() (object). Align schema and add an await.
- output: S.union([S.string, null]),
+ // Return shape is unknown JSON; tighten if you define a schema.
+ output: S.unknown(),
},
async ({ input, context }) => {
- const something = await fetch(
+ const res = await fetch(
`https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}`
);
- return something.json();
+ return await res.json();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Define an effect. It can have any name you want. | |
| export const getSomething = experimental_createEffect( | |
| { | |
| // The name for debugging purposes | |
| name: "getSomething", | |
| // The input schema for the effect | |
| input: { | |
| address: S.string, | |
| blockNumber: S.number, | |
| }, | |
| output: S.union([S.string, null]), | |
| }, | |
| async ({ input, context }) => { | |
| // Fetch or other external calls MUST always be done in an effect. | |
| const something = await fetch( | |
| `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}` | |
| ); | |
| return something.json(); | |
| } | |
| // Define an effect. It can have any name you want. | |
| export const getSomething = experimental_createEffect( | |
| { | |
| // The name for debugging purposes | |
| name: "getSomething", | |
| // The input schema for the effect | |
| input: { | |
| address: S.string, | |
| blockNumber: S.number, | |
| }, | |
| // Return shape is unknown JSON; tighten if you define a schema. | |
| output: S.unknown(), | |
| }, | |
| async ({ input, context }) => { | |
| // Fetch or other external calls MUST always be done in an effect. | |
| const res = await fetch( | |
| `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}` | |
| ); | |
| return await res.json(); | |
| } | |
| ); |
🤖 Prompt for AI Agents
In .cursor/rules/subgraph-migration.mdc around lines 1121 to 1139, the effect
declares output: S.union([S.string, null]) but returns something.json() (an
object) and also omits awaiting the JSON parse; update the output schema to
match the actual JSON shape returned (or change the returned value to a
string/null) and add await before something.json() so the effect returns the
parsed result rather than a Promise; ensure the schema precisely reflects the
object's properties (or map the JSON to a string/null) and adjust types
accordingly.
5c289a0 to
4ef643b
Compare
|
@DZakh Sweet shot. I checked it over and should be good now (made some small changes), it's mainly just random examples it's picking up rather than the actual steps or migration points so shouldn't be an issue. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
.cursor/rules/subgraph-migration.mdc (5)
118-121: Unify ID delimiter: use hyphens, not underscoresEarlier guidance and later examples use hyphens. Align this snippet.
- id: `${event.chainId}_${event.block.number}_${event.logIndex}`, + id: `${event.chainId}-${event.block.number}-${event.logIndex}`,
1205-1228: Avoid hardcoded chain config in viem clientHardcoding “MegaETH Testnet” and IDs harms multichain setups; prefer env-driven transport and resolve per-chain externally.
-const publicClient = createPublicClient({ - chain: { - id: 6342, // MegaETH Testnet - adjust for your network - name: 'MegaETH Testnet', - network: 'megaeth-testnet', - nativeCurrency: { - decimals: 18, - name: 'MegaETH', - symbol: 'METH', - }, - rpcUrls: { - default: { http: [process.env.RPC_URL] }, - public: { http: [process.env.RPC_URL] }, - }, - }, - transport: http(process.env.RPC_URL), -}); +const publicClient = createPublicClient({ + // Resolve RPC per chain via env/registry. Example: RPC_URL_1, RPC_URL_10, etc. + transport: http(process.env.RPC_URL!), +});Add a short note: “Resolve the correct RPC from a map keyed by event.chainId; throw if missing.”
973-980: Use on-chain timestamp for updatedAtAvoid
Date.now()to keep units and source consistent with on-chain data.- updatedAt: BigInt(Date.now()), + updatedAt: BigInt(event.block.timestamp),
1121-1140: Effect output schema mismatch and missing await on JSONSchema declares string/null but returns parsed JSON object; also missing
awaitonjson().- output: S.union([S.string, null]), + // Return shape is JSON; tighten if you know the structure. + output: S.unknown(), }, async ({ input, context }) => { - const something = await fetch( + const res = await fetch( `https://api.example.com/something?address=${input.address}&blockNumber=${input.blockNumber}` ); - return something.json(); + return await res.json(); }
1373-1415: Prefix entity IDs (and foreign keys) with event.chainIdExamples here omit the chain prefix, breaking multichain integrity and relationships.
- let token = await context.Token.get(event.params.token); + let token = await context.Token.get(`${event.chainId}-${event.params.token}`); if (!token) { token = { - id: event.params.token, + id: `${event.chainId}-${event.params.token}`, name: tokenMetadata.name, symbol: tokenMetadata.symbol, decimals: BigInt(tokenMetadata.decimals), totalSupply: BigInt(tokenMetadata.totalSupply), rate: ZERO_BD, - dataFeedId: event.params.token, + dataFeedId: event.params.token, updatedAt: BigInt(event.block.timestamp), blockNumber: BigInt(event.block.number), blockTimestamp: BigInt(event.block.timestamp), transactionHash: event.transaction.hash, - address: event.params.token, + address: event.params.token, }; context.Token.set(token); } @@ - const contract: ContractDataEntity = { - id: event.params.contract, + const contract: ContractDataEntity = { + id: `${event.chainId}-${event.params.contract}`, name: contractMetadata.name, symbol: contractMetadata.symbol, decimals: BigInt(contractMetadata.decimals), manager: event.params.poolManager, timestamp: BigInt(event.block.timestamp), lastUpdate: BigInt(event.block.timestamp), fee: ZERO_BI, depositApy: ZERO_BI, convertToAssetsMultiplier, totalDepositsVolume: ZERO_BI, totalWithdrawalsVolume: ZERO_BI, totalAssets: ZERO_BI, totalShares: ZERO_BI, - token_id: event.params.token, - contractFactory_id: ONE_BI.toString(), + token_id: `${event.chainId}-${event.params.token}`, + contractFactory_id: `${event.chainId}-${ONE_BI.toString()}`, };Also update any preceding
.get(...)usage forContractFactoryto use the same prefixed ID.
🧹 Nitpick comments (5)
.cursor/rules/subgraph-migration.mdc (5)
31-31: Standardize Bundle ID example to use event.chainIdUse
${event.chainId}-1for consistency with the multichain rule above.- - **Use chain-specific Bundle IDs**: `${chainId}-1` for accurate pricing per network + - **Use chain-specific Bundle IDs**: `${event.chainId}-1` for accurate pricing per network
1034-1038: Clarify BigDecimal source; avoid unnecessary dependencyDoc suggests installing
bignumber.jsbut examples importBigDecimalfromgenerated. Remove the install step or explain when it’s needed.-# Install bignumber.js for BigDecimal support -pnpm add bignumber.js +# BigDecimal is re-exported from "generated"; no extra install needed in typical setups. +# Install bignumber.js only if your environment requires direct usage.
1547-1552: Align import guidance for BigDecimalRecommend importing from
generatedand discourage directbignumber.jsimports to match codegen types.-// ❌ WRONG - Direct import from bignumber.js -import { BigDecimal } from 'bignumber.js'; +// ✅ Preferred - Import from generated types (re-exported) +import { BigDecimal } from 'generated';
1737-1739: Chain ID availability in async exampleIf
chainIdis not in scope, prefer${event.chainId}-1or passchainIdexplicitly to the function to avoid implicit globals.-export async function updateTokenDayData() { - const bundle = await context.Bundle.get(`${chainId}-1`); +export async function updateTokenDayData(event: any) { + const bundle = await context.Bundle.get(`${event.chainId}-1`);
1-13: Mirror this MDC in docs + consider init-time inclusionPer reviewer feedback, add this file to docs at docs.envio.dev and consider auto-including it on project init (with an option to skip) to maximize visibility.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.cursor/rules/subgraph-migration.mdc(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-08-11T08:42:57.311Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: codegenerator/cli/templates/static/shared/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:42:57.311Z
Learning: Applies to codegenerator/cli/templates/static/shared/**/*.ts : Always cast timestamps to BigInt (e.g., `BigInt(event.block.timestamp)`) and never use raw timestamps
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:49:57.399Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/test_codegen/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:49:57.399Z
Learning: Applies to scenarios/test_codegen/**/*.ts : Always cast timestamps from events to BigInt (e.g., BigInt(event.block.timestamp))
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:47:04.346Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/fuel_test/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:47:04.346Z
Learning: Applies to scenarios/fuel_test/**/*.ts : Always cast timestamps from events to BigInt, e.g., `BigInt(event.block.timestamp)`; never use raw timestamps
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:49:57.399Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/test_codegen/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:49:57.399Z
Learning: Applies to scenarios/test_codegen/**/*.ts : For any external call (e.g., fetch), wrap it in an Effect via experimental_createEffect and consume via context.effect
Applied to files:
.cursor/rules/subgraph-migration.mdc
📚 Learning: 2025-08-11T08:47:04.346Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: scenarios/fuel_test/.cursor/rules/hyperindex.mdc:0-0
Timestamp: 2025-08-11T08:47:04.346Z
Learning: Applies to scenarios/fuel_test/**/*.ts : With preload enabled (handlers run twice), all external calls (e.g., fetch) MUST be implemented via the Envio Effect API (experimental_createEffect and context.effect)
Applied to files:
.cursor/rules/subgraph-migration.mdc
| - [ ] **Check that events are being processed** (if you have test data) | ||
| - [ ] **Only proceed to the next step** after confirming the indexer runs without errors | ||
|
|
||
| **Common Runtime Errors to Watch For:**s |
There was a problem hiding this comment.
Fix typo in heading
Remove stray “s”.
-**Common Runtime Errors to Watch For:**s
+**Common Runtime Errors to Watch For:**📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| **Common Runtime Errors to Watch For:**s | |
| **Common Runtime Errors to Watch For:** |
🤖 Prompt for AI Agents
In .cursor/rules/subgraph-migration.mdc around line 86, the heading "Common
Runtime Errors to Watch For:**s" contains a stray trailing "s"; remove the extra
"s" so the heading reads "Common Runtime Errors to Watch For:" and ensure
surrounding punctuation/formatting (bold markers) remains correct.
chore: added subgraph migration mdc file to cursor rules
Summary by CodeRabbit