- 
                Notifications
    You must be signed in to change notification settings 
- Fork 28
Make an option to make addresses lower case #736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| WalkthroughAdds opt-in EVM address-format support (checksum|lowercase): new Address.Evm lowercase helpers, config surface ( Changes
 Sequence Diagram(s)sequenceDiagram
  autonumber
  participant User as User config.yaml
  participant CLI as CLI Parser (Rust)
  participant Gen as Codegen Templates
  participant App as Generated App
  participant NS as NetworkSources.evm
  participant HS as HyperSyncSource
  participant RPC as RpcSource
  participant Eth as Ethers/Viem
  User->>CLI: sets evm.address_format, event_decoder
  CLI->>Gen: produce SystemConfig with lowercase_addresses & should_use_hypersync_client_decoder
  Gen->>App: emit Config.make(~lowercaseAddresses, ~shouldUseHypersyncClientDecoder)
  App->>NS: evm(~lowercaseAddresses, ~shouldUseHypersyncClientDecoder, ...)
  alt shouldUseHypersyncClientDecoder = true
    NS->>HS: make({ lowercaseAddresses, ... })
    HS->>Eth: HyperSyncClient.make(~enableChecksumAddresses = !lowercase)
  else
    NS->>RPC: make({ lowercaseAddresses, shouldUseHypersyncClientDecoder=false, ... })
    RPC->>Eth: JsonRpcProvider.makeGetTransactionFields(~lowercaseAddresses)
  end
  Note over App,Eth: Address.Evm.fromStringLowercaseOrThrow / fromStringOrThrow used where applicable
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
 Possibly related PRs
 Suggested reviewers
 Poem
 Pre-merge checks and finishing touches✅ Passed checks (3 passed)
 ✨ 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. 🧪 Early access (Sonnet 4.5): enabledWe are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience. Note: 
 Comment  | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️  Outside diff range comments (1)
codegenerator/cli/npm/envio/src/Address.res (1)
39-48: Critical: infinite recursion due to name shadowing of fromStringOrThrowThe local let fromStringOrThrow calls itself, not the external viem binding. This will recurse until stack overflow.
Apply this diff to disambiguate the external and fix the call site:
- @module("viem") - external fromStringOrThrow: string => t = "getAddress" + @module("viem") + external viemGetAddress: string => t = "getAddress" ... - let fromStringOrThrow = string => { + let fromStringOrThrow = string => { try { - fromStringOrThrow(string) + viemGetAddress(string) } catch { | _ => Js.Exn.raiseError( `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`, ) } }
🧹 Nitpick comments (4)
codegenerator/cli/npm/envio/src/Address.res (1)
14-18: Input validation source — consider regex to decouple from viem (optional)isAddress is fine; if you want to avoid the viem dep here, a fast anchored regex would suffice given hex-only input.
- @module("viem") @private - external isAddress: string => bool = "isAddress" + // Optional: replace viem dep with a strict, anchored regex + let isAddress = (s: string) => + Js.Re.test_(%re("/^0x[a-fA-F0-9]{40}$/"), s)codegenerator/cli/src/config_parsing/human_config.rs (1)
212-216: Consider future-proofing the config shape.If you anticipate more address formatting modes later, consider an enum like
address_format: "checksummed" | "lowercase"or grouping under asubgraph_compatibilitysection (as discussed in the PR). Current boolean is fine if this is the only mode you’ll support.codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res (2)
175-192: Deduplicate client construction.Compute
enableChecksumAddresses = !lowercaseAddressesonce and callHyperSyncClient.makeonce.- let client = - if lowercaseAddresses { - HyperSyncClient.make( - ~url=endpointUrl, - ~apiToken, - ~maxNumRetries=Env.hyperSyncClientMaxRetries, - ~httpReqTimeoutMillis=Env.hyperSyncClientTimeoutMillis, - ~enableChecksumAddresses=false, - ) - } else { - HyperSyncClient.make( - ~url=endpointUrl, - ~apiToken, - ~maxNumRetries=Env.hyperSyncClientMaxRetries, - ~httpReqTimeoutMillis=Env.hyperSyncClientTimeoutMillis, - ~enableChecksumAddresses=true, - ) - } + let enableChecksumAddresses = !lowercaseAddresses + let client = HyperSyncClient.make( + ~url=endpointUrl, + ~apiToken, + ~maxNumRetries=Env.hyperSyncClientMaxRetries, + ~httpReqTimeoutMillis=Env.hyperSyncClientTimeoutMillis, + ~enableChecksumAddresses, + )
205-209: Mirror decoder toggle via same boolean.Use the computed
enableChecksumAddressesto drive decoder setup for clarity.- if lowercaseAddresses { - decoder.disableChecksummedAddresses() - } else { - decoder.enableChecksummedAddresses() - } + if enableChecksumAddresses { + decoder.enableChecksummedAddresses() + } else { + decoder.disableChecksummedAddresses() + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
- scenarios/test_codegen/pnpm-lock.yamlis excluded by- !**/pnpm-lock.yaml
📒 Files selected for processing (13)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res(1 hunks)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(5 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(3 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs(2 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/UserContext.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(2 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res(4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/npm/envio/src/Address.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/npm/envio/src/Address.res
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src
Files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
{codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs}
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (5)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- codegenerator/cli/src/config_parsing/human_config.rs
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/npm/envio/src/Address.res
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/npm/envio/src/Address.res
📚 Learning: 2025-09-01T14:12:02.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-09-01T14:12:02.500Z
Learning: Applies to {codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs} : When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Applied to files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/src/config_parsing/system_config.rs
🔇 Additional comments (18)
codegenerator/cli/npm/envio/src/Address.res (2)
20-30: Lowercasing constructor with validation — LGTMValidates first, returns canonical lowercase. Clear error message.
32-34: Helper passthrough — LGTMKeeps the API ergonomic alongside the non-lowercasing variant.
codegenerator/cli/templates/static/codegen/src/UserContext.res (1)
292-297: Respect lowercaseAddresses when validating user-provided contract addresses — good; ensure consistency across pipelineThis matches the config and prevents mixed-case drift at registration. Please verify Hypersync/decoder paths also use lowercase when this flag is on (they appear to).
codegenerator/cli/src/config_parsing/graph_migration/mod.rs (1)
288-289: Initialize new field with None — LGTMNeutral default keeps migrations non-opinionated; system layer can unwrap_or(false).
codegenerator/cli/src/cli_args/init_config.rs (1)
174-175: Expose lowercase_addresses on HumanConfig (EVM) — LGTMKeeps init flow backward-compatible while enabling the new option.
codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res (1)
16-17: Thread lowercaseAddresses into HyperSyncSource — LGTM; validate call sitesSignature change is localized to templates and forwarded correctly. Ensure all template emitters pass this arg.
Also applies to: 34-35
codegenerator/cli/templates/static/codegen/src/Config.res (1)
131-132: Add top-level lowercaseAddresses with default false — LGTMPublic surface and constructor default look right; field is included in returned record.
Also applies to: 142-143, 177-178
codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs (1)
30-31: Expose lowercaseAddresses in generated YAML — LGTM; confirm scopeTemplate maps lowercase_addresses -> lowercaseAddresses per chain entry. Confirm the intent is global (same for all chains) vs per-chain overrides.
Also applies to: 65-66
codegenerator/cli/src/config_parsing/human_config.rs (1)
212-216: Add optionallowercase_addressesto EVM HumanConfig — LGTM; regenerate npm schema
- Wiring confirmed: codegenerator/cli/src/config_parsing/system_config.rs defines
pub lowercase_addresses: booland maps from human config withevm_config.lowercase_addresses.unwrap_or(false)(default=false).- Generated schema not verifiable: repo search failed because the
npmdirectory / npm/envio/evm.schema.json was not present. Regenerate and commit the updated evm.schema.json and run the schema-equality tests.codegenerator/cli/src/hbs_templating/codegen_templates.rs (2)
1282-1283: Exposelowercase_addresseson ProjectTemplate — LGTM.Field added to the serialization surface so templates can consume it. No concerns.
1389-1390: Propagate from SystemConfig — LGTM.Correctly sources
cfg.lowercase_addressesfor templates.codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res (1)
147-156: PlumbinglowercaseAddressesthrough options/make — LGTM.Type and arg added consistently; aligns with generator changes.
Also applies to: 157-167
codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs (1)
78-79: Config.make already supports ~lowercaseAddresses (default=false) — no action requiredConfirmed: codegenerator/cli/templates/static/codegen/src/Config.res defines
lowercaseAddresses: booland~lowercaseAddresses=false; the dynamic template passes~lowercaseAddresses={{lowercase_addresses}}(codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs:78).codegenerator/cli/src/config_parsing/system_config.rs (5)
417-418: SystemConfig gains lowercase_addressesField addition is straightforward and scoped; no trait bounds impacted. LGTM.
725-726: EVM default wiring
lowercase_addresses: evm_config.lowercase_addresses.unwrap_or(false)correctly preserves backward compatibility. LGTM.
863-864: Fuel path explicitly disables lowercasingExplicit
falsekeeps behavior unchanged for Fuel. LGTM.
2091-2092: Tests: include new optional fieldAdding
lowercase_addresses: Nonein test configs is correct to exercise defaults. LGTM.
2138-2139: Tests: include new optional field (second case)Same here; maintains parity across fixtures. LGTM.
        
          
                codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
              
                Outdated
          
            Show resolved
            Hide resolved
        
      There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 🔥
|  | ||
| // NOTE: We could use a regex for this instead, not sure if it is faster/slower than viem's 'isAddress' function | ||
| // `/^0x[a-fA-F0-9]{40}$/` | ||
| @module("viem") @private | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| @module("viem") @private | |
| @module("viem") | 
@Private doesn't exist in ReScript
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, funny. I actually added that. It wasn't from AI. I had a vague memory of something like this but you're right it might be from ReasonML 🤔
We need to find a way to make sure this doesn't make Viem a required dependency for the users. I don't fully understand the solution that is used for the other function (fromStringOrThrow) but I assume I need to do the same here 🤔 - I thought making it private would maybe help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, it was this that I rememberred 😅 https://rescript-lang.org/docs/manual/v11.0.0/let-binding#private-let-bindings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do let fromStringOrThrow = fromStringOrThrow below the line. This way it will be exported for ReScript users, but won't require to install viem
| #[schemars( | ||
| description = "If true, Ethereum addresses are kept lowercase (no checksum) across the indexer (default: false)" | ||
| )] | ||
| pub lowercase_addresses: Option<bool>, | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote for address_format: checksum | lowercase field
| if lowercaseAddresses { | ||
| HyperSyncClient.make( | ||
| ~url=endpointUrl, | ||
| ~apiToken, | ||
| ~maxNumRetries=Env.hyperSyncClientMaxRetries, | ||
| ~httpReqTimeoutMillis=Env.hyperSyncClientTimeoutMillis, | ||
| ~enableChecksumAddresses=false, | ||
| ) | ||
| } else { | ||
| HyperSyncClient.make( | ||
| ~url=endpointUrl, | ||
| ~apiToken, | ||
| ~maxNumRetries=Env.hyperSyncClientMaxRetries, | ||
| ~httpReqTimeoutMillis=Env.hyperSyncClientTimeoutMillis, | ||
| ~enableChecksumAddresses=true, | ||
| ) | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to ~enableChecksumAddresses=!lowercaseAddresses
| | decoder => | ||
| decoder.enableChecksummedAddresses() | ||
| if lowercaseAddresses { | ||
| decoder.disableChecksummedAddresses() | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I didn't know that we have the option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think it is the default, but doesn't hurt to explicitly set it :)
| Let's also update init templates to use lowercase by default | 
a61383e    to
    e552611      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
codegenerator/cli/npm/envio/src/Address.res (1)
37-38: Avoid re-validating an already-typed Address.t.
fromAddressLowercaseOrThrowconvertst -> string -> tbut re-runs validation. Sinceaddress: tis already valid, you can lowercase and wrap directly.- let fromAddressLowercaseOrThrow = address => - address->toString->fromStringLowercaseOrThrow + // No need to re-validate a value already typed as Address.t. + let fromAddressLowercaseOrThrow = address => + address->toString->Js.String2.toLowerCase->unsafeFromString
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- codegenerator/cli/templates/static/codegen/src/eventFetching/hypersync/HyperSyncSource.res
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- codegenerator/cli/npm/envio/src/Address.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- codegenerator/cli/npm/envio/src/Address.res
🧠 Learnings (3)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
| 
 Could you explain this more, is this just for being more similar to subgraphs? | 
| Yes, I think it's good to be more similar to SubGraph, as well as Ponder. It should also be a little bit more performant | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
scenarios/test_codegen/test/AddressLowercase_test.res (2)
10-12: Optional: strengthen the failure assertion.Also assert the error type or message (regex) to avoid false positives from unrelated exceptions.
Example:
Assert.throws( () => Address.Evm.fromStringLowercaseOrThrow("invalid-address")->ignore, /* match by message or custom predicate */ )
3-19: Consider a dict-key normalization test.Add a test proving that using lowercase addresses as map keys enables case-insensitive retrieval, aligning with our “lowercase keys + compare with toLowerCase” guidance.
Example:
it("dict lookups work with lowercased keys", () => { let d = Js.Dict.empty() Js.Dict.set(d, "0xabc0000000000000000000000000000000000000", "ok") let k = "0xAbC0000000000000000000000000000000000000" ->Address.Evm.fromStringLowercaseOrThrow Assert.strictEqual(Js.Dict.get(d, k)->Belt.Option.getExn, "ok") })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
- scenarios/test_codegen/rescript.json(1 hunks)
- scenarios/test_codegen/test/AddressLowercase_test.res(1 hunks)
- scenarios/test_codegen/test/Config_test.res(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- scenarios/test_codegen/rescript.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- scenarios/test_codegen/test/Config_test.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- scenarios/test_codegen/test/Config_test.res
🧠 Learnings (4)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- scenarios/test_codegen/test/Config_test.res
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- scenarios/test_codegen/test/Config_test.res
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- scenarios/test_codegen/test/Config_test.res
🔇 Additional comments (4)
scenarios/test_codegen/test/Config_test.res (2)
12-12: Good addition: default lowercaseAddresses flag captured in expected config.Matches the new config surface and keeps backward-compat defaults explicit.
24-24: Add a companion test for thetruepath (lowercaseAddresses: true).Existing test sets lowercaseAddresses: false in scenarios/test_codegen/test/Config_test.res — add a mirror test that sets lowercaseAddresses: true and asserts the generated config normalizes addresses to lowercase.
scenarios/test_codegen/test/AddressLowercase_test.res (2)
4-8: LGTM: Valid address lowercasing is correctly asserted.Covers EIP-55 mixed case -> canonical lowercase round-trip via
toString.
14-18: LGTM: Idempotence of lowercase normalization.Confirms
fromAddressLowercaseOrThrowpreserves lowercase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
codegenerator/cli/src/config_parsing/human_config.rs (2)
212-217: New field looks good; decide on explicit default vs. implied default.Docs say “default: checksum” but the type is
Option<AddressFormat>. If you want an actual default at deserialization/schema level (and to omit it from YAML when defaulted), consider making the field non-optional with serde+schemars defaults; otherwise tweak the description to “unset = checksum”.Possible refactor (optional, ripple across callers expected):
- #[serde(skip_serializing_if = "Option::is_none")] - #[schemars( - description = "Address format for Ethereum addresses: 'checksum' or 'lowercase' (default: checksum)" - )] - pub address_format: Option<AddressFormat>, + #[serde( + default = "default_address_format", + skip_serializing_if = "is_default_address_format" + )] + #[schemars( + description = "Address format for Ethereum addresses: 'checksum' or 'lowercase' (default: checksum)" + )] + pub address_format: AddressFormat,Add within the same module:
fn default_address_format() -> AddressFormat { AddressFormat::Checksum } fn is_default_address_format(fmt: &AddressFormat) -> bool { matches!(fmt, AddressFormat::Checksum) }
219-224: Make AddressFormat trivially copyable (and Eq).Tiny ergonomics win and avoids unnecessary clones in downstream code.
- #[derive(Debug, Serialize, Deserialize, PartialEq, Clone, JsonSchema)] + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Copy, Clone, JsonSchema)] #[serde(rename_all = "lowercase")] pub enum AddressFormat { Checksum, Lowercase, }codegenerator/cli/src/config_parsing/graph_migration/mod.rs (1)
288-289: Consider defaulting migrated configs to lowercase format to align with ecosystem and internal guidance.Subgraphs and similar tools often use lowercase addresses; we’ve also standardized on lowercase comparisons in configs previously. Setting this to lowercase by default improves consistency and avoids mixed-casing pitfalls.
- preload_handlers: Some(true), - address_format: None, + preload_handlers: Some(true), + address_format: Some(AddressFormat::Lowercase),Add import near existing human_config imports:
use crate::config_parsing::human_config::evm::AddressFormat;Please verify end-to-end that a migrated subgraph with checksummed addresses still matches correctly when
address_format: lowercaseis set (the pipeline should normalize accordingly). If you prefer to preserve source casing, keepNonehere but ensure templates/init paths default to lowercase elsewhere per PR discussion.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- codegenerator/cli/src/cli_args/init_config.rs
- codegenerator/cli/src/config_parsing/system_config.rs
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
| 
 I just saw that the  What would be more performant is to just do a regex to check that it is lowercase and fail if it is not lowercase 🤔 But maybe a bit abrasive to our users to get a runtime error like that. | 
| Tested a few versions, it is definitely better not to use regex, and only very very marginally faster on the function that only allows lower-case (but of course has the big downsides).  | 
6ed09d8    to
    1dfea0b      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (8)
codegenerator/cli/templates/static/greeter_template/rescript/config.yaml (1)
33-35: Wording + EOF newline
- Recommend softening the perf claim to reflect the marginal/conditional nature.
- Add trailing newline to satisfy YAMLlint.
Apply:
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: consider lowercasing the example addresses above to match this setting and prior casing consistency learnings.
codegenerator/cli/templates/static/greeter_template/javascript/config.yaml (1)
33-35: Wording + EOF newlineSame as the Rescript greeter: soften perf claim and add trailing newline.
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: lowercase the two example contract addresses to align with address_format.
codegenerator/cli/templates/static/greeter_template/typescript/config.yaml (1)
33-35: Wording + EOF newlineAdjust the comment and fix the missing newline at EOF.
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: lowercase the example addresses for consistency with the configured format.
codegenerator/cli/templates/static/erc20_template/typescript/config.yaml (1)
22-24: Wording + EOF newlineTweak the perf phrasing and add a trailing newline.
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: lowercase the UNI token address above to match the configured format.
codegenerator/cli/templates/static/erc20_template/javascript/config.yaml (1)
22-24: Wording + EOF newlineSame adjustments as other EVM templates.
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: lowercase the UNI token address above to align with the configured format.
codegenerator/cli/templates/static/erc20_template/rescript/config.yaml (1)
22-24: Wording + EOF newlineAdjust perf phrasing and add a trailing newline.
-# using lowercase addresses is slightly faster +# lowercase may be marginally faster in some setups; also improves Subgraph/Ponder compatibility address_format: lowercase +Optional: lowercase the UNI token address above for consistency with the configured format.
codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml (1)
21-21: Add newline at EOF.YAMLlint flags missing terminal newline.
-address_format: lowercase +address_format: lowercase +scenarios/test_codegen/test/AddressLowercase_test.res (1)
3-19: Tests cover the critical paths for lowercase helpers. LGTM.Covers valid mixed-case input, invalid input, and Address->lowercase roundtrip.
Consider adding one more case for a checksummed input that differs only by checksum (e.g., mixed casing) to ensure normalization is always lowercase.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
- scenarios/test_codegen/pnpm-lock.yamlis excluded by- !**/pnpm-lock.yaml
📒 Files selected for processing (25)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res(4 hunks)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(5 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(3 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs(2 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/UserContext.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(2 hunks)
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml(1 hunks)
- scenarios/test_codegen/rescript.json(1 hunks)
- scenarios/test_codegen/test/AddressLowercase_test.res(1 hunks)
- scenarios/test_codegen/test/Config_test.res(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- scenarios/test_codegen/rescript.json
🚧 Files skipped from review as they are similar to previous changes (11)
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs
- codegenerator/cli/src/cli_args/init_config.rs
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
🧠 Learnings (9)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to config.yaml : Enable preload_handlers: true when using Effect API for external calls
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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/**/config.yaml : Enable preload optimizations by adding preload_handlers: true in config.yaml
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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/**/config.yaml : Enable preload optimizations by adding `preload_handlers: true` in config.yaml
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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/**/config.yaml : Add `preload_handlers: true` to config.yaml to enable preload optimisations
Applied to files:
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
🪛 YAMLlint (1.37.1)
codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
🔇 Additional comments (6)
codegenerator/cli/src/config_parsing/human_config.rs (2)
219-224: AddressFormat enum is appropriately modeled.Serde lowercasing aligns with YAML values 'checksum' | 'lowercase'.
212-217: Approve — address_format field OK; schema test couldn't be run locallyPublic address_format: optional with sensible default (checksum); serde + schemars attrs and docs look correct.
Attempted to run:
cargo test -p codegenerator -- test_evm_config_schema -- --nocapture— failed with: "rustup could not choose a version of cargo to run, because one wasn't specified explicitly, and no default is configured." Runrustup default stableif needed and re-run the test locally to confirm evm.schema.json matches the Rust schema.codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res (1)
157-158: Approve: lowercaseAddresses threaded correctlyThreading lowercaseAddresses and negating into ~enableChecksumAddresses is correct; decoder toggle matches intent. Verified HyperSyncSource.make callsite passes ~lowercaseAddresses (codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res:25) and HyperSyncClient.make accepts enableChecksumAddresses (codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res:9,456-460).
codegenerator/cli/src/config_parsing/system_config.rs (3)
417-418: SystemConfig.new field lowercase_addresses added—OK.Placement is fine; no serialization concerns here.
725-729: Correctly derive lowercase_addresses from EVM address_format.Defaulting to checksum when None is consistent with docs.
866-867: Fuel default lowercase_addresses = false is sensible.Fuel path remains unaffected by EVM-only option.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove EVM-only address_format from Fuel template (breaks schema).
Fuel HumanConfig denies unknown fields and doesn’t define address_format. Keeping this here will make generated Fuel projects fail to parse config.yaml. Also, the comment mentions Ethereum in a Fuel template.
Apply:
-# Address format for Ethereum addresses: 'checksum' or 'lowercase'
-# using lowercase addresses is slightly faster
-address_format: lowercase📝 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.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | |
| # using lowercase addresses is slightly faster | |
| address_format: lowercase | 
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
🤖 Prompt for AI Agents
In
codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
around lines 19 to 21, remove the EVM-specific "address_format: lowercase" line
and its Ethereum-specific comment because Fuel HumanConfig rejects unknown
fields; also replace or remove the comment referencing Ethereum so the template
contains only Fuel-relevant config entries and valid comments.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fuel template: incorrect “Ethereum addresses” wording and potential schema issue
Same concern as the Fuel TypeScript template: misleading wording and possible schema rejection.
Choose one:
A) Remove:
-# Address format for Ethereum addresses: 'checksum' or 'lowercase'
-# using lowercase addresses is slightly faster
-address_format: lowercaseB) Keep with clear EVM-only note and add newline:
-# Address format for Ethereum addresses: 'checksum' or 'lowercase'
-# using lowercase addresses is slightly faster
+# EVM-only: address format ('checksum' or 'lowercase'). Ignored for Fuel.
 address_format: lowercase
+📝 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.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | |
| # using lowercase addresses is slightly faster | |
| address_format: lowercase | |
| # EVM-only: address format ('checksum' or 'lowercase'). Ignored for Fuel. | |
| address_format: lowercase | |
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
🤖 Prompt for AI Agents
In
codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
around lines 19–21, the comment incorrectly says "Ethereum addresses" and may
cause schema confusion; update the comment to refer to "EVM addresses" (or
remove the line if you prefer option A), and if keeping it, add a clear EVM-only
note and a trailing newline after the comment, and ensure the documented values
('checksum' or 'lowercase') match the config schema enum so the YAML won't be
rejected.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fuel template mentions “Ethereum addresses” and may introduce a schema mismatch
- The comment explicitly references Ethereum addresses in a Fuel template; this is misleading.
- Verify whether fuel.schema.json accepts address_format. If not, this will fail validation.
Two options:
A) Remove the setting from Fuel templates (safest):
-# Address format for Ethereum addresses: 'checksum' or 'lowercase'
-# using lowercase addresses is slightly faster
-address_format: lowercaseB) If the schema supports it and it’s intentionally a no-op, clarify and keep, plus newline:
-# Address format for Ethereum addresses: 'checksum' or 'lowercase'
-# using lowercase addresses is slightly faster
+# EVM-only: address format ('checksum' or 'lowercase'). Ignored for Fuel.
 address_format: lowercase
+📝 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.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | |
| # using lowercase addresses is slightly faster | |
| address_format: lowercase | 
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | |
| # using lowercase addresses is slightly faster | |
| address_format: lowercase | |
| # EVM-only: address format ('checksum' or 'lowercase'). Ignored for Fuel. | |
| address_format: lowercase | |
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
🤖 Prompt for AI Agents
In
codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
around lines 19 to 21, the inline comment references "Ethereum addresses" and
the file defines address_format: lowercase which may not be valid for Fuel
templates; confirm whether fuel.schema.json actually accepts address_format and
if not remove the entire address_format line (and its Ethereum-specific comment)
from the Fuel template; if the schema does accept it and the field is
intentionally a no-op, change the comment to mention Fuel-specific address
behavior (not Ethereum), keep the setting, and add a trailing newline to the
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
codegenerator/cli/npm/envio/evm.schema.json (3)
2-3: Add $id for resolvable schema identity (better editor UX).Including a stable $id helps YAML LS and tooling cache/resolve this schema reliably.
Apply this diff (adjust URL to your final CDN/npm URL on release):
{ - "$schema": "https://json-schema.org/draft/2020-12/schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.envio.dev/evm.schema.json",
668-674: Clarify enum semantics for AddressFormat.Make intent explicit (EIP‑55 vs plain lowercase) to avoid ambiguity in consumers.
Apply this diff:
"AddressFormat": { "type": "string", + "description": "Address formatting mode: 'checksum' (EIP-55 validation/normalization) or 'lowercase' (all-hex lowercase without checksum validation).", "enum": [ "checksum", "lowercase" ] }
117-126: Add schema default and examples for address_format (non-behavioral)Add an advisory default and examples to improve editor/docs UX; this does not change runtime behavior (templates already set explicit values).
Apply this diff:
"address_format": { "description": "Address format for Ethereum addresses: 'checksum' or 'lowercase' (default: checksum)", + "default": "checksum", + "examples": ["checksum", "lowercase"], "anyOf": [ { "$ref": "#/$defs/AddressFormat" }, { "type": "null" } ] }Optional: to restrict use to EVM-only configs, consider a root-level conditional (Draft 2020-12) requiring ecosystem === "evm" when address_format is present.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
- codegenerator/cli/npm/envio/evm.schema.json(2 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(5 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(8 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
- codegenerator/cli/src/config_parsing/system_config.rs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
📚 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/**/config.yaml : Add YAML schema validation header to config.yaml: `# yaml-language-server: $schema=./node_modules/envio/evm.schema.json`
Applied to files:
- codegenerator/cli/npm/envio/evm.schema.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 🎉
But I just thought of viem decoder and RPC data source. I'm not 100% but do you know whether we need to do something with them. Feel free to merge if you think it's fine.
| 
 Worth testing, I assumed it would lower case them, before being saved still, but worth testing it. Will try that on Monday | 
2b200cd    to
    de879da      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (5)
codegenerator/cli/src/commands.rs (4)
339-339: Set HTTP client timeouts to avoid hanging polls.Requests can hang indefinitely under network issues.
Apply:
- let client = reqwest::Client::new(); + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(15)) + .build() + .context("Failed to build HTTP client")?;
338-343: Normalize base URL to avoid double slashes.ENVIO_API_URL ending with “/” yields //api/... paths.
Apply:
- let base = get_api_base_url(); + let base = get_api_base_url().trim_end_matches('/').to_string();
365-372: Avoid 4s initial delay before first poll.You sleep 2s pre-loop and again at loop start. Remove one.
Apply:
- // Give the UI a brief warm-up before first poll - sleep(Duration::from_secs(2)).await; - let mut consecutive_not_found = 0u32; - for _ in 0..max_attempts { - sleep(poll_interval).await; + for _ in 0..max_attempts { + sleep(poll_interval).await;Alternative: keep the pre-loop 2s sleep and move the in-loop sleep to the end of the loop body.
393-411: Fail fast on completed-without-token and on unauthorized.Prevent silent loops when completed=true but token is missing; also handle 401/403 explicitly.
Apply:
if resp.status().is_success() { let status: CliAuthStatus = match resp.json().await { Ok(s) => s, Err(_) => continue, }; if let Some(err) = status.error { if !err.is_empty() { return Err(anyhow!("authentication error: {}", err)); } } if status.completed { if let Some(token) = status.token { println!("{}", token); return Ok(()); + } else { + return Err(anyhow!("authentication completed but token missing")); } } + } else if resp.status() == StatusCode::UNAUTHORIZED || resp.status() == StatusCode::FORBIDDEN { + return Err(anyhow!("authentication unauthorized; please retry login")); }codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res (1)
456-460: Naming inconsistency: “Checksum” vs “Checksummed”.Decoder uses enableChecksummedAddresses/disableChecksummedAddresses; your config uses enableChecksumAddresses.
Align naming to reduce confusion (even if not forwarded to the client), e.g., rename to enableChecksummedAddresses across your wrappers/config.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
- scenarios/test_codegen/pnpm-lock.yamlis excluded by- !**/pnpm-lock.yaml
📒 Files selected for processing (30)
- codegenerator/cli/CommandLineHelp.md(1 hunks)
- codegenerator/cli/npm/envio/evm.schema.json(2 hunks)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res(4 hunks)
- codegenerator/cli/src/cli_args/clap_definitions.rs(1 hunks)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/commands.rs(1 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(5 hunks)
- codegenerator/cli/src/executor/mod.rs(1 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(8 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs(2 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/UserContext.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(2 hunks)
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml(1 hunks)
- scenarios/test_codegen/rescript.json(1 hunks)
- scenarios/test_codegen/test/AddressLowercase_test.res(1 hunks)
- scenarios/test_codegen/test/Config_test.res(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- scenarios/test_codegen/rescript.json
- codegenerator/cli/CommandLineHelp.md
🚧 Files skipped from review as they are similar to previous changes (13)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/src/config_parsing/human_config.rs
- codegenerator/cli/src/cli_args/init_config.rs
- scenarios/test_codegen/test/AddressLowercase_test.res
🧰 Additional context used
📓 Path-based instructions (4)
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src
Files:
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
{codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs}
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (11)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
📚 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/**/config.yaml : Add YAML schema validation header to config.yaml: `# yaml-language-server: $schema=./node_modules/envio/evm.schema.json`
Applied to files:
- codegenerator/cli/npm/envio/evm.schema.json
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to config.yaml : Enable preload_handlers: true when using Effect API for external calls
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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/**/config.yaml : Enable preload optimizations by adding preload_handlers: true in config.yaml
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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/**/config.yaml : Enable preload optimizations by adding `preload_handlers: true` in config.yaml
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 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/**/config.yaml : Add `preload_handlers: true` to config.yaml to enable preload optimisations
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
🧬 Code graph analysis (2)
codegenerator/cli/src/executor/mod.rs (1)
codegenerator/cli/src/commands.rs (1)
run_auth(337-415)
codegenerator/cli/src/commands.rs (1)
codegenerator/cli/src/config_parsing/system_config.rs (4)
var(67-102)
new(60-65)
new(1186-1199)
new(1481-1486)
🪛 GitHub Actions: Build & Test Scenario
codegenerator/cli/src/cli_args/clap_definitions.rs
[error] 403-403: Test 'check_cli_help_md_is_up_to_date' failed. Please run 'make update-generated-docs' to update the generated CLI documentation.
🔇 Additional comments (12)
codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml (1)
19-21: Remove the EVM-onlyaddress_formatblock from the Fuel template.Fuel configs are validated against
fuel.schema.json, which does not accept the EVM-onlyaddress_formatfield. Leaving this in place breaks schema validation for anyone bootstrapping the Fuel greeter template, and the accompanying comment is misleading. Please drop the block (or gate it behind the EVM templates only).-# Address format for Ethereum addresses: 'checksum' or 'lowercase' -# using lowercase addresses is slightly faster -address_format: lowercasescenarios/test_codegen/test/Config_test.res (1)
12-12: Lowercase flag expectation captured correctlyThe generated config now surfaces the flag, and defaulting to
falsehere aligns with the existing mixed-case address fixture. Looks good.codegenerator/cli/templates/static/codegen/src/UserContext.res (1)
290-296: Correctly respects lowercaseAddresses when validating user-supplied addresses.Switching between checksum and lowercase validators based on config is correct.
codegenerator/cli/src/executor/mod.rs (1)
119-123: Auth command wiring looks correct.Executes async flow and adds helpful error context.
codegenerator/cli/npm/envio/evm.schema.json (1)
116-127: Schema surface for address_format added cleanly.Top-level address_format with AddressFormat enum ("checksum" | "lowercase") integrates without breaking required sets.
Also applies to: 668-674
codegenerator/cli/src/hbs_templating/codegen_templates.rs (3)
1123-1128: Propagates ~lowercaseAddresses into generated NetworkSources.evm.Correctly emits boolean based on cfg.lowercase_addresses.
1283-1284: Template data includes lowercase_addresses and maps from SystemConfig.Keeps flag available to all templates and tests.
Also applies to: 1404-1405
1526-1527: Updated test expectations for sources_code to include ~lowercaseAddresses=false.Ensures stability after adding the new labeled arg.
Also applies to: 1581-1582, 1588-1589, 1621-1622, 1651-1653, 1662-1663
codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs (1)
38-43: Correct Handlebars scoping and config propagation for lowercase addresses.
- Uses ../../../lowercase_addresses under is_evm_ecosystem scope (correct).
- Threads ~lowercaseAddresses into Config.make.
Also applies to: 79-80
codegenerator/cli/src/cli_args/clap_definitions.rs (1)
69-71: Remove doc update suggestion; docs are current
CommandLineHelp.md already includes “*auth— Authenticate with envio hosted services and print a JWT”, so no update is needed.Likely an incorrect or invalid review comment.
codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res (1)
16-17: Threading lowercaseAddresses through EVM sources looks good — all NetworkSources.evm call sites include ~lowercaseAddresses
Verified repository-wide; no remaining calls missing the new arg.codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res (1)
451-461: Constructor option likely ignored by @envio-dev/hypersync-client.Passing enableChecksumAddresses is probably a no-op; this option isn’t documented/supported.
If the client doesn’t honor this field, drop it from the object you pass and handle casing via the Decoder or upstream normalization.
Minimal change:
let make = ( ~url, ~apiToken, ~httpReqTimeoutMillis, ~maxNumRetries, ~enableChecksumAddresses=true, ) => make({ url, - enableChecksumAddresses, bearerToken: apiToken, httpReqTimeoutMillis, maxNumRetries, })Optionally keep the parameter for API symmetry, but don’t forward it until the client supports it.
Would you like me to also update cfg to remove the field and thread the behavior via Decoder.enableChecksummedAddresses/disableChecksummedAddresses where Decoder is constructed?
| external fromStringLowercaseOrThrow: string => bool = "isAddress" | ||
|  | ||
| // Reassign since the function might be used in the handler code | ||
| // and we don't want to have a "viem" import there. It's needed to keep "viem" a dependency | ||
| // of generated code instead of adding it to the indexer project dependencies. | ||
| // Also, we want a custom error message, which is searchable in our codebase. | ||
| // Validate that the string is a proper address but return a lowercased value | ||
| let fromStringLowercaseOrThrow = string => { | ||
| if (fromStringLowercaseOrThrow(string)) { | ||
| unsafeFromString(string->Js.String2.toLowerCase) | ||
| } else { | ||
| Js.Exn.raiseError( | ||
| `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`, | ||
| ) | ||
| } | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix infinite recursion by aliasing externals before wrapper definitions.
Both wrappers call identically named bindings and will recurse forever at runtime. Alias viem externals (getAddress/isAddress) under different names and call those inside wrappers.
Apply:
 module Evm = {
-  @module("viem")
-  external fromStringOrThrow: string => t = "getAddress"
+  @module("viem")
+  external viemGetAddress: string => t = "getAddress"
@@
-  // NOTE: the function is named to be overshadowed by the one below, so that we don't have to import viem in the handler code
-  @module("viem")
-  external fromStringLowercaseOrThrow: string => bool = "isAddress" 
+  // viem helpers (keep dependency in this package, not user handlers)
+  @module("viem")
+  external viemIsAddress: string => bool = "isAddress"
@@
-  let fromStringLowercaseOrThrow = string => {
-    if (fromStringLowercaseOrThrow(string)) {
+  let fromStringLowercaseOrThrow = string => {
+    if (viemIsAddress(string)) {
       unsafeFromString(string->Js.String2.toLowerCase)
     } else {
       Js.Exn.raiseError(
         `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`,
       )
     }
   }
@@
   let fromStringOrThrow = string => {
     try {
-      fromStringOrThrow(string)
+      viemGetAddress(string)
     } catch {
     | _ =>
       Js.Exn.raiseError(
         `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`,
       )
     }
   }Also applies to: 40-49
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/Address.res around lines 16 to 31 (and
similarly lines 40 to 49), the wrapper functions are shadowing the externals and
causing infinite recursion; alias the imported viem externals before defining
wrappers (e.g., define isAddressExternal/getAddressExternal or similar names
that reference the original externals) and then implement the wrapper functions
to call those aliased externals, preserving the custom error messages and
lowercasing behavior.
        
          
                codegenerator/cli/src/commands.rs
              
                Outdated
          
        
      | let extra_grace_attempts = 15; // ~30s grace | ||
| let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts; | ||
|  | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix integer type mismatch in max_attempts calculation (compile error).
Adding i32 (extra_grace_attempts) to u64 causes a type error.
Apply one of the following diffs:
-        let extra_grace_attempts = 15; // ~30s grace
-        let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts;
+        let extra_grace_attempts: u64 = 15; // ~30s grace
+        let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts;or
-        let extra_grace_attempts = 15; // ~30s grace
-        let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts;
+        let extra_grace_attempts = 15; // ~30s grace
+        let max_attempts = (session.expires_in.max(0) as u64) / 2 + (extra_grace_attempts as u64);📝 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.
| let extra_grace_attempts = 15; // ~30s grace | |
| let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts; | |
| let extra_grace_attempts: u64 = 15; // ~30s grace | |
| let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts; | 
| let extra_grace_attempts = 15; // ~30s grace | |
| let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts; | |
| let extra_grace_attempts = 15; // ~30s grace | |
| let max_attempts = (session.expires_in.max(0) as u64) / 2 | |
| (extra_grace_attempts as u64); | 
🤖 Prompt for AI Agents
In codegenerator/cli/src/commands.rs around lines 362 to 364, the expression
adds extra_grace_attempts (i32) to a u64 result causing a type mismatch; fix by
making both operands the same unsigned type — either declare
extra_grace_attempts as u64 (e.g. let extra_grace_attempts: u64 = 15;) or cast
it when used (e.g. ... / 2 + extra_grace_attempts as u64); ensure the cast or
changed declaration yields the intended value and that parentheses are used
correctly around the division before the addition.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address format flag conflicts with template address casing
Same issue here: address_format: lowercase mandates lowercase addresses, but the sample contract entry remains checksummed (Line 9). This leaves the generated config in an invalid state. Please align the sample address casing with the flag or keep the flag at checksum.
-# using lowercase addresses is slightly faster
-address_format: lowercase
+# using lowercase addresses is slightly faster
+address_format: checksum🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/erc20_template/rescript/config.yaml around
lines 22-24 (and note the sample contract address at line 9), the config sets
address_format: lowercase while the example address remains checksummed; make
them consistent by either changing address_format to checksum or converting the
sample contract address on line 9 to a lowercase address (and update any other
example addresses in the file to match), ensuring the address_format value and
example addresses use the same casing.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address format flag conflicts with template address casing
address_format: lowercase requires every configured address to already be lowercase. The template still ships the ERC20 address in its original mixed-case checksum form (Line 9), so a freshly generated project will fail validation/parsing under the new flag. Either keep the sample in checksum mode or lowercase the address to match the flag.
-# using lowercase addresses is slightly faster
-address_format: lowercase
+# using lowercase addresses is slightly faster
+address_format: checksum🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
around lines 22-24, the address_format is set to "lowercase" but the template's
sample ERC20 address (line 9) is still in checksum mixed-case form; make these
consistent by either changing address_format to "checksum" or converting the
sample ERC20 address on line 9 to lowercase so the sample complies with the
lowercase requirement; update only one of those places to keep format consistent
across the template.
| # Address format for Ethereum addresses: 'checksum' or 'lowercase' | ||
| # using lowercase addresses is slightly faster | ||
| address_format: lowercase | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lowercase format flag requires the example addresses to be lowercase as well
Setting address_format: lowercase means the config loader will now expect the contract addresses in this file to already be lowercase. The two sample addresses above remain in checksum case, so a freshly generated project will hit validation errors. Please lowercase the example addresses to keep the template runnable.
-        address: 0x9D02A17dE4E68545d3a58D3a20BbBE0399E05c9c
+        address: 0x9d02a17de4e68545d3a58d3a20bbbe0399e05c9c
...
-        address: 0xdEe21B97AB77a16B4b236F952e586cf8408CF32A
+        address: 0xdee21b97ab77a16b4b236f952e586cf8408cf32a🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
around lines 33 to 35, the config sets address_format: lowercase but the example
contract addresses earlier in the file are still in checksum case; update those
sample addresses to be fully lowercase (replace the two example Ethereum
addresses above this setting with their lowercase equivalents) so the config
loader validation won't fail for freshly generated projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️  Outside diff range comments (3)
codegenerator/cli/src/config_parsing/entity_parsing.rs (1)
277-286: Duplicate enum detection is broken (always passes).You pre-fill the set, so inserts never detect dups. This lets duplicate enum values slip through.
Apply:
- let mut value_set: HashSet<String> = self.values.clone().into_iter().collect(); - - let duplicate_values = self - .values - .clone() - .into_iter() - .filter(|value| value_set.insert(value.clone())) - .collect::<Vec<_>>(); + let mut value_set: HashSet<String> = HashSet::new(); + let duplicate_values = self + .values + .clone() + .into_iter() + .filter(|value| !value_set.insert(value.clone())) + .collect::<Vec<_>>();Consider adding a test that asserts an error when enum values repeat.
codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res (1)
188-207: Decoder instantiated on every call; cache it in the refgetHscDecoder() never stores the decoder into hscDecoder, so each call re-creates it. Cache once and reuse; also keeps your enable/disableChecksummedAddresses choice stable.
Apply this diff:
let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None) let getHscDecoder = () => { switch hscDecoder.contents { | Some(decoder) => decoder | None => switch HyperSyncClient.Decoder.fromSignatures(allEventSignatures) { | exception exn => exn->ErrorHandling.mkLogAndRaise( ~msg="Failed to instantiate a decoder from hypersync client, please double check your ABI or try using 'event_decoder: viem' config option", ) | decoder => if lowercaseAddresses { decoder.disableChecksummedAddresses() } else { decoder.enableChecksummedAddresses() } - decoder + hscDecoder := Some(decoder); + decoder } } }codegenerator/cli/npm/envio/src/sources/RpcSource.res (1)
755-836: Viem path ignores lowercaseAddresses for routing and srcAddressWhen lowercaseAddresses=true, eventRouter lookups and emitted srcAddress should use the lowercased form, same as the HyperSync path, otherwise matching can fail.
Apply this diff:
- await logs - ->Belt.Array.keepMap(log => { + logs + ->Belt.Array.keepMap(log => { let topic0 = log.topics->Js.Array2.unsafe_get(0) + let routedAddress = + if lowercaseAddresses { + log.address->Address.Evm.fromAddressLowercaseOrThrow + } else { + log.address + } switch eventRouter->EventRouter.get( ~tag=EventRouter.getEvmEventId( ~sighash=topic0->EvmTypes.Hex.toString, ~topicCount=log.topics->Array.length, ), ~indexingContracts, - ~contractAddress=log.address, + ~contractAddress=routedAddress, ~blockNumber=log.blockNumber, ) { ... Internal.Event({ eventConfig: (eventConfig :> Internal.eventConfig), timestamp: block.timestamp, blockNumber: block.number, chain, logIndex: log.logIndex, event: { chainId: chain->ChainMap.Chain.toChainId, params: decodedEvent.args, transaction, // Unreliably expect that the Ethers block fields match the types in HyperIndex // I assume this is wrong in some cases, so we need to fix it in the future block: block->( Utils.magic: Ethers.JsonRpcProvider.block => Internal.eventBlock ), - srcAddress: log.address, + srcAddress: routedAddress, logIndex: log.logIndex, }->Internal.fromGenericEvent, })
🧹 Nitpick comments (17)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (6)
1125-1134: Don’t hardcode shouldUseHypersyncClientDecoder; wire it from cfg and simplify bool formattingUse the config flag instead of
trueand pass booleans directly rather than constructing"true"/"false"strings.- "NetworkSources.evm(~chain, ~contracts=[{contracts_code}], \ - ~hyperSync={hyper_sync_code}, \ - ~allEventSignatures=[{all_event_signatures}]->Belt.Array.concatMany, \ - ~shouldUseHypersyncClientDecoder=true, ~rpcs=[{rpcs}], \ - ~lowercaseAddresses={})", - if config.lowercase_addresses { - "true" - } else { - "false" - } + "NetworkSources.evm(~chain, ~contracts=[{contracts_code}], \ + ~hyperSync={hyper_sync_code}, \ + ~allEventSignatures=[{all_event_signatures}]->Belt.Array.concatMany, \ + ~shouldUseHypersyncClientDecoder={}, ~rpcs=[{rpcs}], \ + ~lowercaseAddresses={})", + config.should_use_hypersync_client_decoder, + config.lowercase_addresses
1107-1121: JSON‑escape RPC URLs to avoid broken generated code on unusual charactersInterpolating
rpc.urlinside quotes risks breaking the generated Rescript if the URL ever contains quotes or backslashes. Emit a JSON string literal instead.- let rpcs = rpcs - .iter() - .map(|rpc| { - format!( - "{{url: \"{}\", sourceFor: {}, syncConfig: {}}}", - rpc.url, - match rpc.source_for { - For::Sync => "Sync", - For::Fallback => "Fallback", - }, - rpc_to_sync_config_options(rpc) - ) - }) + let rpcs = rpcs + .iter() + .map(|rpc| { + let url_json = serde_json::to_string(&rpc.url) + .expect("url should serialize to JSON"); + let source_for = match rpc.source_for { + For::Sync => "Sync", + For::Fallback => "Fallback", + }; + format!( + "{{url: {url_json}, sourceFor: {source_for}, syncConfig: {}}}", + rpc_to_sync_config_options(rpc) + ) + })
1535-1536: Add a positive test for lowercaseAddresses=trueTests cover the default
false. Add one config fixture withaddress_format: lowercase(or equivalent) and assert the generated sources string contains~lowercaseAddresses=true. This guards the new path and prevents regressions.Based on learnings
Would you like me to draft the test and a minimal YAML fixture?
Also applies to: 1590-1592, 1597-1599, 1630-1632, 1660-1661, 1671-1672
1023-1025: Unusedis_client_decoderargument — align with the new flag or remove
is_client_decoder: _suggests the param is ignored. Either:
- thread it to control
shouldUseHypersyncClientDecoder, or- remove/deprecate it across config to avoid drift.
Confirm intended source of truth for client decoder (old param vs new
cfg.should_use_hypersync_client_decoder) to avoid confusion.
965-965: Remove commented field or add a TODO with rationale
// event_decoder: Option<String>,is leftover noise in a serialized struct. Either delete or add a short TODO explaining why it’s intentionally kept commented.
870-872: Fuel ABI transpile string — consider path escapingLooks fine. If there’s any chance of backticks in paths, consider escaping or switching to JSON string emission for safety (low priority).
codegenerator/cli/src/config_parsing/entity_parsing.rs (1)
269-276: Typo in method name: valididate → validate.Minor polish; keeps API clear.
Apply:
- pub fn new(name: String, values: Vec<String>) -> anyhow::Result<Self> { - Self { name, values }.valididate() - } + pub fn new(name: String, values: Vec<String>) -> anyhow::Result<Self> { + Self { name, values }.validate() + } @@ - fn valididate(self) -> anyhow::Result<Self> { + fn validate(self) -> anyhow::Result<Self> { self.check_duplicate_values()?.check_valid_postgres_name() }codegenerator/cli/src/commands.rs (1)
337-418: Set an HTTP client timeout to avoid indefinite hangs.Add a sane timeout on the reqwest Client; network hiccups can stall polls.
Example:
- let client = reqwest::Client::new(); + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(15)) + .build() + .context("failed to build HTTP client")?;codegenerator/cli/templates/static/codegen/src/Config.res (2)
117-118: Document the new public config surface.Add a brief doc comment explaining what is lowered (addresses in DB? event router filters? outputs?) and the incompatibility with viem.
130-144: Micro-nit: unnecessary loop.The forEach over chains doesn’t use chain; a single if around the block is enough.
- chains->Array.forEach(chain => { - if ( - lowercaseAddresses && - !shouldUseHypersyncClientDecoder - ) { - Js.Exn.raiseError( - "lowercase addresses is not supported when event_decoder is 'viem'. Please set event_decoder to 'hypersync-client' or change address_format to 'checksum'.", - ) - } - }) + if (lowercaseAddresses && !shouldUseHypersyncClientDecoder) { + Js.Exn.raiseError( + "lowercase addresses is not supported when event_decoder is 'viem'. Please set event_decoder to 'hypersync-client' or change address_format to 'checksum'.", + ) + }scenarios/test_codegen/test/Integration_ts_helpers.res (1)
53-56: Thread from config to avoid drift.Instead of hardcoding, consider passing lowercaseAddresses/decoder from the top‑level Config to mirror real setups and reduce test maintenance.
scenarios/test_codegen/test/E2EEthNode_test.res (1)
64-67: Add a variant with lowercaseAddresses=true.Include one E2E that sets lowercaseAddresses=true and asserts stored/emitted addresses are lowercase to exercise the new path.
scenarios/test_codegen/test/RpcSource_test.res (1)
172-177: Cover lowercase address formatting.Add a companion test with
~lowercaseAddresses=trueand assertfrom/toare lowercased. This ensures the builder and downstream schema honor the flag.scenarios/test_codegen/test/__mocks__/MockConfig.res (1)
64-67: Confirm mock addresses align withlowercaseAddressessettingTests currently set
lowercaseAddresses: falseand use checksummed addresses in mocks—no change needed now. If you enablelowercaseAddresses: truelater, update any static mock addresses to lowercase (e.g. viaAddress.Evm.fromAddressLowercaseOrThrow) to ensure deterministic matching.codegenerator/cli/npm/envio/src/sources/RpcSource.res (3)
45-54: In-place miner lowercasing OK; consider parity for any alias fieldsMutation is fine for perf. If any providers alias miner as author, consider normalizing that too in the same branch (low priority).
664-676: Drop superfluous await on plain arraysawait logs is a no-op here; remove for clarity.
Also applies to: 755-756
538-539: Typo: “endipoint” → “endpoint”Minor logging string fix.
- "suggestedFix": "This likely means the RPC url you are using is not responding correctly. Please try another RPC endipoint.", + "suggestedFix": "This likely means the RPC url you are using is not responding correctly. Please try another RPC endpoint.",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
- codegenerator/cli/npm/envio/src/bindings/Ethers.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res(4 hunks)
- codegenerator/cli/npm/envio/src/sources/RpcSource.res(8 hunks)
- codegenerator/cli/src/commands.rs(1 hunks)
- codegenerator/cli/src/config_parsing/entity_parsing.rs(3 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(3 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(7 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(15 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/Env.res(0 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(3 hunks)
- scenarios/test_codegen/config.yaml(1 hunks)
- scenarios/test_codegen/test/E2EEthNode_test.res(2 hunks)
- scenarios/test_codegen/test/Integration_ts_helpers.res(1 hunks)
- scenarios/test_codegen/test/RpcSource_test.res(3 hunks)
- scenarios/test_codegen/test/__mocks__/MockConfig.res(1 hunks)
💤 Files with no reviewable changes (1)
- codegenerator/cli/templates/static/codegen/src/Env.res
🚧 Files skipped from review as they are similar to previous changes (2)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/src/config_parsing/human_config.rs
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- scenarios/test_codegen/test/Integration_ts_helpers.res
- scenarios/test_codegen/test/RpcSource_test.res
- scenarios/test_codegen/test/__mocks__/MockConfig.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- scenarios/test_codegen/test/E2EEthNode_test.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- scenarios/test_codegen/test/Integration_ts_helpers.res
- scenarios/test_codegen/test/RpcSource_test.res
- scenarios/test_codegen/test/__mocks__/MockConfig.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- scenarios/test_codegen/test/E2EEthNode_test.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
scenarios/test_codegen/**/config.yaml
📄 CodeRabbit inference engine (scenarios/test_codegen/.cursor/rules/hyperindex.mdc)
scenarios/test_codegen/**/config.yaml: After changing config.yaml, run: pnpm codegen
Enable preload optimizations by adding preload_handlers: true in config.yaml
If using transaction-level data (e.g., event.transaction.hash), declare it under field_selection.transaction_fields in config.yaml
Annotate config.yaml with the YAML schema directive: # yaml-language-server: $schema=./node_modules/envio/evm.schema.json
Files:
- scenarios/test_codegen/config.yaml
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src
Files:
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
{codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs}
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (11)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
📚 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/**/config.yaml : If using transaction-level data (e.g., event.transaction.hash), declare it under field_selection.transaction_fields in config.yaml
Applied to files:
- scenarios/test_codegen/config.yaml
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to src/**/*.ts : For multichain support, prefix all entity IDs with event.chainId (e.g., `${event.chainId}-${originalId}`), never hardcode chainId=1, pass chainId into helpers, and use chain-specific Bundle IDs like `${chainId}-1`
Applied to files:
- scenarios/test_codegen/test/__mocks__/MockConfig.res
- codegenerator/cli/templates/static/codegen/src/Config.res
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/src/config_parsing/system_config.rs
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/src/config_parsing/system_config.rs
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- codegenerator/cli/src/config_parsing/system_config.rs
📚 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/**/*.graphql : Use `entity_id` fields for relationships instead of entity arrays in the schema
Applied to files:
- codegenerator/cli/src/config_parsing/entity_parsing.rs
📚 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/**/schema.graphql : Do not add the entity decorator to GraphQL schema types
Applied to files:
- codegenerator/cli/src/config_parsing/entity_parsing.rs
📚 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/**/*.graphql : In GraphQL schema, use `entity_id` fields (e.g., `token_id: String!`) for relationships instead of direct object references
Applied to files:
- codegenerator/cli/src/config_parsing/entity_parsing.rs
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to schema.graphql : Migrate schema from TheGraph to Envio: remove entity decorators, change Bytes! to String!, keep ID! as ID!, and preserve all business entities
Applied to files:
- codegenerator/cli/src/config_parsing/entity_parsing.rs
🧬 Code graph analysis (1)
codegenerator/cli/src/config_parsing/system_config.rs (1)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (1)
network(973-979)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
🔇 Additional comments (18)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (4)
365-372: Event filters Rescript types — LGTMThe new
eventFiltersArgs/eventFiltersDefinitionscaffolding reads clean and keeps types precise.
588-600: Event filter parsing glue — LGTMThe generated call to
LogSelection.parseEventFiltersOrThrowwith normalized topic filters looks correct.
621-635: HyperSync decoder mapping — LGTMIndex/body mapping into event params is consistent with indexed/non‑indexed ordering.
Please ensure tests cover at least one event with mixed indexed/non‑indexed params.
1290-1292: Verify template wiring and explicit lowercase conversions
lowercase_addressesis passed throughRegisterHandlers.res.hbsandConfigYAML.res.hbsand consumed inConfig.res,UserContext.res, andNetworkSources.res—but noaddress.toLowerCase()calls were found; ensure your generated code applies.toLowerCase()when the flag is true.
should_use_hypersync_client_decoderis correctly threaded throughRegisterHandlers.res.hbs,Config.res, andNetworkSources.res.codegenerator/cli/src/config_parsing/entity_parsing.rs (2)
193-203: Lifetimes in TypeDef are fine.Return type now borrows from self; this avoids clones and is sound here.
1472-1475: Test helper lifetime tweaks look good.Also applies to: 1491-1495
codegenerator/cli/src/config_parsing/system_config.rs (2)
1032-1049: Good, clear error on conflicting HyperSync vs RPC for sync.
726-735: Verify template threading for new flags
Config flags flow correctly throughcodegen_templates.rsinto both static and dynamic codegen templates (e.g.Config.res,UserContext.res,NetworkSources.res,ConfigYAML.res.hbs,RegisterHandlers.res.hbs), but I didn’t findlowercaseAddressesorshouldUseHypersyncClientDecoderinEnv.res, nor could I locate aRpcSource.resor anyHyperSync*template. Please manually confirm that both flags are exposed in all required templates and source files.codegenerator/cli/npm/envio/src/bindings/Ethers.res (2)
150-186: Lowercasing from/to/contractAddress is correct and minimal.
150-186: Normalizelog.addressacross all log‐decoding paths whenlowercaseAddresses = true.
Currently, only the Hypersync client decoder branch inRpcSource.reslowercaseslog.addressfor routing (theroutedAddressvariable). Everywhere else—convertEthersLogToHyperSyncEvent(usingaddress: log.address),makeEventBatchQueueItem(srcAddress: log.address), and non‐client flows (~contractAddress=log.address)—the rawlog.addressis used, leading to inconsistent casing and potential mismatches. Update these spots to apply lowercase normalization (e.g. viaAddress.Evm.fromAddressLowercaseOrThroworJs.String2.toLowerCase) wheneverlowercaseAddressesis enabled.⛔ Skipped due to learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matchingLearnt 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistencycodegenerator/cli/src/commands.rs (1)
365-367: Fix integer type mismatch in max_attempts (compile error).Use a u64 literal or cast:
- let extra_grace_attempts = 15; // ~30s grace + let extra_grace_attempts: u64 = 15; // ~30s grace let max_attempts = (session.expires_in.max(0) as u64) / 2 + extra_grace_attempts;codegenerator/cli/templates/static/codegen/src/Config.res (1)
186-187: Ensure consumers actually honor the flag.Double‑check that Address.Evm parsing/formatting, DB layer, and selection config consistently lower-case when this flag is true (match keys and comparisons with toLowerCase()). I can help add an E2E asserting DB/handler outputs are lowercase.
Based on learnings
scenarios/test_codegen/test/RpcSource_test.res (2)
33-36: LGTM on surface expansion.Good to surface the new options explicitly in RpcSource.make tests.
50-53: Running scripts to locate and inspectConfig.makeandRpcSource.makedefinitions.codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res (2)
157-158: Threading lowercaseAddresses into options and make() looks correctPlumbing the new flag through options and into make() is consistent and straightforward.
Sanity-check that all callers of HyperSyncSource.make pass the new lowercaseAddresses arg (templates and NetworkSources).
Also applies to: 171-172
180-186: Correct polarity: enableChecksumAddresses = !lowercaseAddressesGood inversion; aligns client response format to the chosen address casing.
codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs (2)
37-43: Scope for lowercase_addresses is now correctUsing ../../../lowercase_addresses under the current each nesting fixes the prior overshoot and ensures EVM addresses are parsed with the intended helper.
72-81: New Config.make args are properly exposedlowercaseAddresses and shouldUseHypersyncClientDecoder are passed through; matches downstream expectations.
Regenerate a sample project to confirm these flags appear in the generated Config.make signature and compile cleanly.
| @send | ||
| external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction" | ||
|  | ||
| let makeGetTransactionFields = (~getTransactionByHash) => | ||
| async (log: log): promise<unknown> => { | ||
| let transaction = await getTransactionByHash(log.transactionHash) | ||
| // Mutating should be fine, since the transaction isn't used anywhere else outside the function | ||
| let fields: {..} = transaction->Obj.magic | ||
|  | ||
| // Make it compatible with HyperSync transaction fields | ||
| fields["transactionIndex"] = log.transactionIndex | ||
| fields["input"] = fields["data"] | ||
|  | ||
| fields->Obj.magic | ||
| let makeGetTransactionFields = (~getTransactionByHash, ~lowercaseAddresses: bool) => async ( | ||
| log: log, | ||
| ): promise<unknown> => { | ||
| let transaction = await getTransactionByHash(log.transactionHash) | ||
| // Mutating should be fine, since the transaction isn't used anywhere else outside the function | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle nullable getTransaction results (ethers may return null).
Provider.getTransaction can return null; current type/signature assumes non-null and may crash.
Apply:
-  @send
-  external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction"
+  @send
+  external getTransaction: (t, ~transactionHash: string) => promise<Js.nullable<transaction>> = "getTransaction"
@@
-  let makeGetTransactionFields = (~getTransactionByHash, ~lowercaseAddresses: bool) => async (
+  let makeGetTransactionFields = (~getTransactionByHash, ~lowercaseAddresses: bool) => async (
     log: log,
   ): promise<unknown> => {
-    let transaction = await getTransactionByHash(log.transactionHash)
+    let transaction = await getTransactionByHash(log.transactionHash)
+    let transaction =
+      switch transaction {
+      | Js.Nullable.Value(tx) => tx
+      | Js.Nullable.Null
+      | Js.Nullable.Undefined =>
+        Js.Exn.raiseError("getTransaction returned null for " ++ log.transactionHash)
+      }Also applies to: 150-156
| let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None) | ||
| let getHscDecoder = () => { | ||
| switch hscDecoder.contents { | ||
| | Some(decoder) => decoder | ||
| | None => { | ||
| let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures) | ||
| decoder | ||
| } | ||
| } | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cache the HyperSync decoder and set address mode like HyperSyncSource
getHscDecoder() creates a new decoder every time and doesn’t set address casing behavior. Mirror HyperSyncSource: cache once and toggle checksummed vs lowercase to keep decoded address fields consistent.
Apply this diff:
 let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None)
 let getHscDecoder = () => {
   switch hscDecoder.contents {
   | Some(decoder) => decoder
-  | None => {
-      let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures)
-      decoder
-    }
+  | None => {
+      let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures)
+      // Align decoded address handling with lowercaseAddresses
+      if lowercaseAddresses {
+        decoder.disableChecksummedAddresses()
+      } else {
+        decoder.enableChecksummedAddresses()
+      };
+      hscDecoder := Some(decoder);
+      decoder
+    }
   }
 }🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/sources/RpcSource.res around lines 575-584,
getHscDecoder currently constructs a new decoder on every call and never updates
hscDecoder.contents or the decoder's address-casing behavior; change it to
create the decoder only once (store it into hscDecoder.contents when None) and
set its address mode to mirror HyperSyncSource (toggle between Checksummed and
Lowercase as used elsewhere — e.g., set decoder.addressMode =
HyperSyncClient.Decoder.AddressMode.Checksummed when checksummed addresses are
expected, otherwise .Lowercase) so decoded address fields remain consistent.
| await logs | ||
| ->Array.zip(parsedEvents) | ||
| ->Array.keepMap((( | ||
| log: Ethers.log, | ||
| maybeDecodedEvent: Js.Nullable.t<HyperSyncClient.Decoder.decodedEvent>, | ||
| )) => { | ||
| let topic0 = log.topics[0]->Option.getWithDefault("0x0"->EvmTypes.Hex.fromStringUnsafe) | ||
| let routedAddress = if lowercaseAddresses { | ||
| log.address->Address.Evm.fromAddressLowercaseOrThrow | ||
| } else { | ||
| log.address | ||
| } | ||
|  | ||
| switch eventRouter->EventRouter.get( | ||
| ~tag=EventRouter.getEvmEventId( | ||
| ~sighash=topic0->EvmTypes.Hex.toString, | ||
| ~topicCount=log.topics->Array.length, | ||
| ), | ||
| ~indexingContracts, | ||
| ~contractAddress=routedAddress, | ||
| ~blockNumber=log.blockNumber, | ||
| ) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: topic0 extraction uses Option on non-option; also normalize routedAddress here
log.topics is an array; indexing doesn’t return option. Use Js.Array2.unsafe_get(0) like the Viem branch, and keep routedAddress normalization.
Apply this diff:
-      await logs
-      ->Array.zip(parsedEvents)
+      logs
+      ->Array.zip(parsedEvents)
       ->Array.keepMap(((
         log: Ethers.log,
         maybeDecodedEvent: Js.Nullable.t<HyperSyncClient.Decoder.decodedEvent>,
       )) => {
-        let topic0 = log.topics[0]->Option.getWithDefault("0x0"->EvmTypes.Hex.fromStringUnsafe)
+        let topic0 = log.topics->Js.Array2.unsafe_get(0)
         let routedAddress = if lowercaseAddresses {
           log.address->Address.Evm.fromAddressLowercaseOrThrow
         } else {
           log.address
         }Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/sources/RpcSource.res around lines 678 to
699, the code incorrectly treats log.topics[0] as an Option and uses
Option.getWithDefault; replace that with Js.Array2.unsafe_get(0) (as in the Viem
branch) to directly extract the first topic, and keep/ensure the routedAddress
normalization logic (using Address.Evm.fromAddressLowercaseOrThrow when
lowercaseAddresses is true) so the EventRouter.get call uses the normalized
address and the correct topic0 string and topicCount.
| - event: EmptyFiltersArray(address indexed from) | ||
| - event: "WildcardHandlerWithLoader()" | ||
| - event: "FilterTestEvent(address indexed addr)" | ||
| event_decoder: "hypersync-client" # default | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Add preload_handlers and regenerate code.
Good with event_decoder default. Also enable preload optimizations and rerun codegen.
Apply:
 name: test_codegen
 description: Gravatar for Ethereum
 rollback_on_reorg: true
 save_full_history: false
+preload_handlers: trueThen run:
As per coding guidelines.
🏁 Script executed:
pnpm codegenLength of output: 124
🏁 Script executed:
#!/bin/bash
find . -maxdepth 4 -type f -name package.jsonLength of output: 203
🏁 Script executed:
#!/bin/bash
sed -n '1,200p' scenarios/test_codegen/package.jsonLength of output: 2120
Enable preload optimizations in test_codegen
Add preload_handlers: true to scenarios/test_codegen/config.yaml and regenerate the generated code:
 name: test_codegen
 description: Gravatar for Ethereum
 rollback_on_reorg: true
 save_full_history: false
+preload_handlers: trueThen run from the package directory:
cd scenarios/test_codegen
pnpm codegen🤖 Prompt for AI Agents
In scenarios/test_codegen/config.yaml at line 24, the config is missing the
preload_handlers optimization; add the line preload_handlers: true to that file,
save, then regenerate the generated code by running pnpm codegen from the
scenarios/test_codegen package directory (cd scenarios/test_codegen && pnpm
codegen) so the codegen output includes the preload handler optimizations.
2a2afc8    to
    8ed9ee5      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️  Outside diff range comments (1)
codegenerator/cli/npm/envio/src/sources/RpcSource.res (1)
753-837: Add address normalization to the Viem decoding branch.The Viem decoding path (lines 755-836) doesn't normalize
log.addressbased onlowercaseAddresses, unlike the HyperSync path. This creates inconsistent address casing across decoding strategies.Apply this diff to normalize addresses in the Viem branch:
await logs ->Belt.Array.keepMap(log => { let topic0 = log.topics->Js.Array2.unsafe_get(0) + let routedAddress = if lowercaseAddresses { + log.address->Address.Evm.fromAddressLowercaseOrThrow + } else { + log.address + } switch eventRouter->EventRouter.get( ~tag=EventRouter.getEvmEventId( ~sighash=topic0->EvmTypes.Hex.toString, ~topicCount=log.topics->Array.length, ), ~indexingContracts, - ~contractAddress=log.address, + ~contractAddress=routedAddress, ~blockNumber=log.blockNumber, ) {And update the event construction at line 827:
- srcAddress: log.address, + srcAddress: routedAddress,
♻️ Duplicate comments (7)
codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml (1)
19-21: Misleading "Ethereum addresses" comment in Fuel template.This is a duplicate concern: the past review already flagged that the comment references "Ethereum addresses" in a Fuel template where the ecosystem is
fuel(line 3), not EVM. Fuel uses 32-byte ContractIds, not 20-byte Ethereum addresses, making the comment confusing.As suggested in the previous review, either:
- Option A: Remove these lines if
address_formatdoesn't apply to Fuel templates- Option B: Clarify the comment as "EVM-only" and add a trailing newline
Based on learnings
codegenerator/cli/templates/static/erc20_template/typescript/config.yaml (1)
22-24: Address format flag conflicts with template address casing.The
address_format: lowercasesetting requires addresses to be lowercase, but the sample ERC20 address on line 9 (0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984) is in mixed-case checksum format. Either changeaddress_formattochecksumor lowercase the sample address to maintain consistency.scenarios/test_codegen/test/E2EEthNode_test.res (1)
13-13: Revertit_onlytoitbefore merging.Using
it_onlydisables all other tests in the suite, which will break CI coverage.Apply this diff:
- Async.it_only("Complete E2E", async () => { + Async.it("Complete E2E", async () => {codegenerator/cli/templates/static/codegen/src/Config.res (1)
133-143: Validation doesn't check per-source decoder overrides.This validation iterates over chains but only checks the global
shouldUseHypersyncClientDecoderparameter. Individual sources (e.g.,RpcSource) can override the decoder setting, so a configuration can pass this check yet still violate the constraint at the source level.Consider adding the same validation inside
RpcSource.makeand other source constructors to catch misconfigurations when per-source overrides are used.Run this script to locate source constructors that accept decoder options:
#!/bin/bash # Description: Find source constructors that may need validation # Search for RpcSource.make and similar patterns ast-grep --pattern $'let make = ($$$) => { $$$ }' # Search for shouldUseHypersyncClientDecoder usage in source files rg -n "shouldUseHypersyncClientDecoder" --type=rescript -C3codegenerator/cli/npm/envio/src/bindings/Ethers.res (1)
147-148: Address the nullable getTransaction return type.This concern was raised in a previous review and remains unresolved. Ethers.js
getTransactioncan returnnullfor non-existent transactions, but the current binding assumes a non-null result and will crash at runtime.Apply this fix:
- @send - external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction" + @send + external getTransaction: (t, ~transactionHash: string) => promise<Js.nullable<transaction>> = "getTransaction"Then update
makeGetTransactionFieldsat line 153:let makeGetTransactionFields = (~getTransactionByHash, ~lowercaseAddresses: bool) => async ( log: log, ): promise<unknown> => { - let transaction = await getTransactionByHash(log.transactionHash) + let txResult = await getTransactionByHash(log.transactionHash) + let transaction = switch txResult { + | Js.Nullable.Value(tx) => tx + | Js.Nullable.Null | Js.Nullable.Undefined => + Js.Exn.raiseError("Transaction not found: " ++ log.transactionHash) + }codegenerator/cli/npm/envio/src/sources/RpcSource.res (2)
678-699: Fix topic0 extraction; routedAddress normalization is correct.Line 684 incorrectly treats
log.topics[0]as an option. Sincelog.topicsis an array, indexing returns the element directly.Apply this diff to fix the extraction:
- let topic0 = log.topics[0]->Option.getWithDefault("0x0"->EvmTypes.Hex.fromStringUnsafe) + let topic0 = log.topics->Js.Array2.unsafe_get(0)The
routedAddressnormalization at lines 685-689 is correctly implemented.
575-584: Cache decoder and set address casing mode.
getHscDecoderdoesn't cache the decoder or set its address mode. This creates a new decoder on every call and fails to align withlowercaseAddresses.Apply this diff to cache and configure the decoder:
let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None) let getHscDecoder = () => { switch hscDecoder.contents { | Some(decoder) => decoder | None => { let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures) - decoder + if lowercaseAddresses { + decoder.disableChecksummedAddresses() + } else { + decoder.enableChecksummedAddresses() + } + hscDecoder := Some(decoder) + decoder } } }
🧹 Nitpick comments (1)
scenarios/test_codegen/test/AddressLowercase_test.res (1)
1-19: Good baseline test coverage for address lowercase helpers.The tests correctly validate:
- Lowercasing of checksummed addresses
- Error handling for invalid addresses
- Normalization via
fromAddressLowercaseOrThrowConsider adding tests for additional edge cases:
- All-uppercase addresses:
"0xABCDEF123456..."- Already-lowercase addresses (idempotency)
- Invalid checksum but valid format:
"0x2c169DFe5fBbA12957Bdd0Ba47d9CEDbFE260CA7"(mixed case with wrong checksum)- Missing
0xprefix handlingThese would provide more comprehensive coverage of the address validation and normalization logic.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
- scenarios/test_codegen/pnpm-lock.yamlis excluded by- !**/pnpm-lock.yaml
📒 Files selected for processing (35)
- codegenerator/cli/npm/envio/evm.schema.json(2 hunks)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/npm/envio/src/bindings/Ethers.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res(4 hunks)
- codegenerator/cli/npm/envio/src/sources/RpcSource.res(8 hunks)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/entity_parsing.rs(3 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(3 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(7 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(15 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs(2 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/Env.res(0 hunks)
- codegenerator/cli/templates/static/codegen/src/UserContext.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(3 hunks)
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml(1 hunks)
- scenarios/test_codegen/config.yaml(1 hunks)
- scenarios/test_codegen/rescript.json(1 hunks)
- scenarios/test_codegen/test/AddressLowercase_test.res(1 hunks)
- scenarios/test_codegen/test/Config_test.res(1 hunks)
- scenarios/test_codegen/test/E2EEthNode_test.res(2 hunks)
- scenarios/test_codegen/test/Integration_ts_helpers.res(1 hunks)
- scenarios/test_codegen/test/RpcSource_test.res(3 hunks)
- scenarios/test_codegen/test/__mocks__/MockConfig.res(1 hunks)
💤 Files with no reviewable changes (1)
- codegenerator/cli/templates/static/codegen/src/Env.res
🚧 Files skipped from review as they are similar to previous changes (17)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- scenarios/test_codegen/test/mocks/MockConfig.res
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- scenarios/test_codegen/rescript.json
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- scenarios/test_codegen/test/RpcSource_test.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/src/config_parsing/system_config.rs
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- scenarios/test_codegen/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- scenarios/test_codegen/test/E2EEthNode_test.res
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- scenarios/test_codegen/test/Integration_ts_helpers.res
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/templates/static/codegen/src/Config.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- scenarios/test_codegen/test/E2EEthNode_test.res
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- scenarios/test_codegen/test/Integration_ts_helpers.res
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/Address.res
- codegenerator/cli/templates/static/codegen/src/Config.res
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src
Files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/templates/static/codegen/src/Config.res
{codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs}
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (7)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
- codegenerator/cli/templates/static/codegen/src/Config.res
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to config.yaml : Enable preload_handlers: true when using Effect API for external calls
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- scenarios/test_codegen/test/AddressLowercase_test.res
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
🔇 Additional comments (24)
codegenerator/cli/src/config_parsing/entity_parsing.rs (1)
36-39: LGTM: Lifetime annotation refinements improve type safety.The lifetime annotations have been updated consistently across
TypeDef,try_get_type_def, and test helpers. Using the anonymous lifetime'_is idiomatic and allows the compiler to infer lifetimes from context without changing behavior.Also applies to: 193-203, 472-475, 1491-1495
codegenerator/cli/templates/static/codegen/src/UserContext.res (1)
288-299: LGTM: Address validation correctly respects the lowercase configuration.The conditional logic properly validates addresses according to the
lowercaseAddressesconfig flag, usingfromAddressLowercaseOrThrowwhen enabled andfromAddressOrThrowotherwise. The EVM-specific scoping is appropriate, and the comment accurately describes the behavior.Based on learnings
scenarios/test_codegen/test/Config_test.res (1)
12-12: LGTM: Test correctly includes the new configuration field.The addition of
lowercaseAddresses: falseto the expected config aligns with the new address formatting feature and its default value.scenarios/test_codegen/test/Integration_ts_helpers.res (1)
53-55: LGTM: RpcSource configuration correctly includes new fields.The three new fields (
allEventSignatures,shouldUseHypersyncClientDecoder,lowercaseAddresses) are properly initialized with sensible defaults for the test scenario. The inline comments clearly document their purpose.codegenerator/cli/src/cli_args/init_config.rs (1)
174-174: LGTM! Appropriate initialization for new field.Setting
address_format: Noneduring contract import initialization is correct and consistent with other optional fields in theHumanConfigstruct.scenarios/test_codegen/test/E2EEthNode_test.res (1)
64-66: LGTM! Appropriate test configuration for new fields.The new fields are correctly initialized:
allEventSignatures: []provides required initialization
shouldUseHypersyncClientDecoder: falseexplicitly selects VIEM decoder (as noted in comment)
lowercaseAddresses: falseis a safe default for this E2E testcodegenerator/cli/templates/static/codegen/src/Config.res (3)
117-117: LGTM! New field added to config type.The
lowercaseAddressesboolean field is appropriately added to the config type.
130-131: LGTM! Reasonable parameter defaults.The default values are appropriate:
lowercaseAddresses=falsemaintains backward compatibility
shouldUseHypersyncClientDecoder=truealigns with existing behavior
186-186: LGTM! Field correctly propagated to config.The
lowercaseAddressesfield is properly included in the returned configuration object.codegenerator/cli/npm/envio/evm.schema.json (2)
117-127: LGTM! Address format configuration looks good.The schema correctly introduces the new
address_formatfield as an optional configuration with proper enum constraints. The description clearly communicates the default behavior (checksum) to users.
668-674: AddressFormat enum definition is correct.The enum properly defines the two supported variants with lowercase serialization. This aligns with the configuration surface introduced in the Rust config parsing.
codegenerator/cli/npm/envio/src/bindings/Ethers.res (1)
150-185: Lowercasing logic is correct, but verify the performance concern.The implementation correctly handles nullable fields when lowercasing addresses. However, the inline comment (lines 161-163) notes this may be wasteful when these fields aren't selected in user config.
According to the PR comments, microbenchmarks showed minimal performance difference between implementations. However, to confirm this isn't a concern in practice, consider:
- Are the selected transaction fields available at this call site to enable conditional lowercasing?
- Would the added complexity of conditional field processing be worth any performance gain?
Based on the PR discussion showing only ~85ms difference between lowercase and checksummed inputs (885ms vs 930ms), the current approach seems acceptable unless profiling reveals this as a bottleneck.
codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res (1)
9-57: LGTM! Proper propagation of address format configuration.The
lowercaseAddressesparameter is correctly threaded through to both HyperSync and RPC sources. The cleanup ofshouldUseHypersyncClientDecoderhandling (passing directly rather than unwrapping inline) improves readability.codegenerator/cli/src/config_parsing/human_config.rs (2)
215-226: LGTM! AddressFormat configuration is well-defined.The Rust configuration correctly introduces:
AddressFormatenum with appropriate variants- Optional
address_formatfield onHumanConfig- Proper serde attributes for lowercase serialization
- Schema generation support via
JsonSchemaderiveThis aligns with the schema changes and follows the naming suggested in prior review feedback.
87-90: Minor improvement to description clarity.The updated description for
start_blockis clearer and more accurate.codegenerator/cli/npm/envio/src/Address.res (2)
14-31: LGTM! Consistent overshadowing pattern for lowercase address validation.The external binding and wrapper follow the established pattern: the external
isAddressis called within the wrapper (line 24) before being shadowed by theletdefinition, avoiding a viem dependency in handler code while providing validation and lowercasing.
33-34: LGTM! Convenience wrapper consistent with existing pattern.The wrapper correctly composes
toStringwithfromStringLowercaseOrThrow, matching the pattern used byfromAddressOrThrowat line 51.codegenerator/cli/npm/envio/src/sources/RpcSource.res (3)
19-54: Address lowercasing in getKnownBlockWithBackoff is acceptable for RPC sync.The in-place mutation of
result.minerusingObj.magicis pragmatic for the RPC sync path. The comment at lines 47-50 acknowledges the potential waste when the miner field isn't selected in the user's config.
459-483: LGTM! Configuration fields properly threaded through RpcSource.The new
allEventSignatures,shouldUseHypersyncClientDecoder, andlowercaseAddressesfields are correctly added to the options type and destructured in themakefunction signature.
518-543: LGTM! blockLoader correctly threads lowercaseAddresses.The
blockLoaderinitialization properly passes~lowercaseAddressestogetKnownBlockWithBackoffat line 526, ensuring consistent address casing behavior.codegenerator/cli/src/hbs_templating/codegen_templates.rs (4)
1290-1291: LGTM! New configuration flags properly added to ProjectTemplate.The
lowercase_addressesandshould_use_hypersync_client_decoderfields are correctly typed and initialized from config at lines 1412-1413.
1123-1135: LGTM! NetworkSources.evm correctly emits lowercaseAddresses flag.The conditional at lines 1130-1134 correctly interpolates
"true"or"false"into the~lowercaseAddresses={}placeholder based onconfig.lowercase_addresses.
1535-1671: LGTM! Test expectations correctly updated for new flag.All test cases (lines 1535, 1590, 1597, 1630, 1660, 1671) now expect
~lowercaseAddresses=falsein the generatedNetworkSources.evmstrings, consistent with the default configuration.
1022-1026: LGTM! Ignoring is_client_decoder in pattern match is acceptable.The pattern at line 1024 correctly ignores
is_client_decoderusing_, as this field isn't needed for this specific emission logic. The field is properly utilized elsewhere in the template generation.
8ed9ee5    to
    a001786      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (8)
codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml (1)
19-21: Remove EVM-specific address_format from Fuel template.This configuration is misleading and potentially broken. The
address_formatoption is designed for EVM chains (as discussed in the PR objectives), but this is a Fuel template. Fuel uses a different address format (typically bech32m), not EVM checksummed or lowercase hex addresses.Apply this diff to remove the configuration:
preload_handlers: true -# Address format for Ethereum addresses: 'checksum' or 'lowercase' -# using lowercase addresses is slightly faster -address_format: lowercaseIf the schema permits this field for Fuel configs (which would be a schema design issue), you should still remove it to avoid user confusion.
codegenerator/cli/templates/static/greeter_template/typescript/config.yaml (1)
33-35: Example addresses must be lowercased to match the configured format.The
address_format: lowercasesetting has been added, but the example contract addresses at lines 19 and 24 remain in checksum format. This inconsistency will cause validation errors when users generate a project from this template.This issue was previously flagged and remains unresolved. Please update the example addresses to lowercase:
- address: 0x9D02A17dE4E68545d3a58D3a20BbBE0399E05c9c + address: 0x9d02a17de4e68545d3a58d3a20bbbe0399e05c9cand
- address: 0xdEe21B97AB77a16B4b236F952e586cf8408CF32A + address: 0xdee21b97ab77a16b4b236f952e586cf8408cf32ascenarios/test_codegen/config.yaml (1)
1-6: Consider adding preload optimization.Per coding guidelines, consider adding
preload_handlers: trueto enable preload optimizations. This would be placed after Line 5 as a new top-level config field.Apply this diff if desired:
name: test_codegen description: Gravatar for Ethereum rollback_on_reorg: true save_full_history: false +preload_handlers: trueAs per coding guidelines.
codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res (1)
451-464: Verify constructor option 'enableChecksumAddresses' exists.The wrapper forwards
enableChecksumAddressesto the@envio-dev/hypersync-clientconstructor (Line 460), but per past review, there's no evidence this option exists in the client library. If the option doesn't exist, it will be silently ignored and the checksummed-address behavior won't be controlled.The web search did not find documentation for the
enableChecksumAddressesconstructor option. Let me search the GitHub source code directly:#!/bin/bash # Search the hypersync-client-node repository for enableChecksumAddresses or related config rg -n "enableChecksum" --type ts --type jscodegenerator/cli/templates/static/erc20_template/typescript/config.yaml (1)
22-24: Address format flag conflicts with template address casing.The
address_format: lowercaseflag requires all configured addresses to be lowercase, but the sample ERC20 address on Line 9 remains in checksum (mixed-case) format. Either changeaddress_formatback tochecksumor lowercase the address on Line 9 to match the flag.codegenerator/cli/npm/envio/src/bindings/Ethers.res (1)
147-148: Handle nullable getTransaction results.
Provider.getTransactioncan returnnullwhen a transaction is not found. The current type signature assumes non-null and may cause runtime errors. Update the external to returnpromise<Js.nullable<transaction>>and handle the null case inmakeGetTransactionFields.Apply this diff:
@send -external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction" +external getTransaction: (t, ~transactionHash: string) => promise<Js.nullable<transaction>> = "getTransaction"Then add null handling in
makeGetTransactionFieldsafter Line 153:let transaction = await getTransactionByHash(log.transactionHash) +let transaction = switch transaction { +| Js.Nullable.Value(tx) => tx +| Js.Nullable.Null | Js.Nullable.Undefined => + Js.Exn.raiseError("getTransaction returned null for " ++ log.transactionHash) +}codegenerator/cli/npm/envio/src/sources/RpcSource.res (2)
575-584: Critical: decoder never cached and address mode not set.The
getHscDecodercreates a new decoder on every call but never stores it in thehscDecoderref. Additionally, it doesn't configure address casing behavior based onlowercaseAddresses.Apply this diff to cache the decoder and set address mode:
let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None) let getHscDecoder = () => { switch hscDecoder.contents { | Some(decoder) => decoder | None => { let decoder = HyperSyncClient.Decoder.fromSignatures(allEventSignatures) + if lowercaseAddresses { + decoder.disableChecksummedAddresses() + } else { + decoder.enableChecksummedAddresses() + } + hscDecoder := Some(decoder) decoder } } }Based on past review comments.
678-699: Critical: topic0 extraction incorrectly uses Option; also ensure routedAddress normalization.Line 684 treats
log.topics[0]as returning anOption, but array indexing doesn't return option types. UseJs.Array2.unsafe_get(0)to extract the first topic (as done in the Viem branch at line 757).Apply this diff:
- await logs + logs ->Array.zip(parsedEvents) ->Array.keepMap((( log: Ethers.log, maybeDecodedEvent: Js.Nullable.t<HyperSyncClient.Decoder.decodedEvent>, )) => { - let topic0 = log.topics[0]->Option.getWithDefault("0x0"->EvmTypes.Hex.fromStringUnsafe) + let topic0 = log.topics->Js.Array2.unsafe_get(0) let routedAddress = if lowercaseAddresses { log.address->Address.Evm.fromAddressLowercaseOrThrow } else { log.address }Based on past review comments.
🧹 Nitpick comments (3)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (2)
964-964: Remove or clarify commented field.The commented
event_decoderfield adds no value without context. Either remove it if it's not needed, or add a TODO comment explaining why it's reserved for future use.- // event_decoder: Option<String>,
1024-1024: Remove or wire through theis_client_decoderflagIn
codegenerator/cli/src/hbs_templating/codegen_templates.rsat line 1024 theis_client_decoderfield is destructured but ignored, and~shouldUseHypersyncClientDecoder=trueis hard-coded at line 1128. Either dropis_client_decoderfrom theDataSource::Evmenum if it’s obsolete, or pass its value into the template instead.codegenerator/cli/templates/static/codegen/src/Config.res (1)
137-146: Validation loop is unnecessary.The validation checks global parameters
lowercaseAddressesandshouldUseHypersyncClientDecoder, but iterates overchainswithout using the loop variable. This repeats the same check once per chain. Since both flags are function-level parameters, validate once before iterating.Apply this diff:
+ // Validate that lowercase addresses is not used with viem decoder + if ( + lowercaseAddresses && + !shouldUseHypersyncClientDecoder + ) { + Js.Exn.raiseError( + "lowercase addresses is not supported when event_decoder is 'viem'. Please set event_decoder to 'hypersync-client' or change address_format to 'checksum'.", + ) + } + - // Validate that lowercase addresses is not used with viem decoder - chains->Array.forEach(chain => { - if ( - lowercaseAddresses && - !shouldUseHypersyncClientDecoder - ) { - Js.Exn.raiseError( - "lowercase addresses is not supported when event_decoder is 'viem'. Please set event_decoder to 'hypersync-client' or change address_format to 'checksum'.", - ) - } - }) -
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
- scenarios/test_codegen/pnpm-lock.yamlis excluded by- !**/pnpm-lock.yaml
📒 Files selected for processing (35)
- codegenerator/cli/npm/envio/evm.schema.json(2 hunks)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
- codegenerator/cli/npm/envio/src/bindings/Ethers.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res(1 hunks)
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res(4 hunks)
- codegenerator/cli/npm/envio/src/sources/RpcSource.res(8 hunks)
- codegenerator/cli/src/cli_args/init_config.rs(1 hunks)
- codegenerator/cli/src/config_parsing/entity_parsing.rs(3 hunks)
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs(1 hunks)
- codegenerator/cli/src/config_parsing/human_config.rs(3 hunks)
- codegenerator/cli/src/config_parsing/system_config.rs(7 hunks)
- codegenerator/cli/src/hbs_templating/codegen_templates.rs(15 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs(2 hunks)
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs(2 hunks)
- codegenerator/cli/templates/static/codegen/src/Config.res(3 hunks)
- codegenerator/cli/templates/static/codegen/src/Env.res(0 hunks)
- codegenerator/cli/templates/static/codegen/src/UserContext.res(1 hunks)
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res(3 hunks)
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml(1 hunks)
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml(1 hunks)
- scenarios/test_codegen/config.yaml(1 hunks)
- scenarios/test_codegen/rescript.json(1 hunks)
- scenarios/test_codegen/test/AddressLowercase_test.res(1 hunks)
- scenarios/test_codegen/test/Config_test.res(1 hunks)
- scenarios/test_codegen/test/E2EEthNode_test.res(2 hunks)
- scenarios/test_codegen/test/Integration_ts_helpers.res(1 hunks)
- scenarios/test_codegen/test/RpcSource_test.res(3 hunks)
- scenarios/test_codegen/test/__mocks__/MockConfig.res(1 hunks)
💤 Files with no reviewable changes (1)
- codegenerator/cli/templates/static/codegen/src/Env.res
✅ Files skipped from review due to trivial changes (1)
- scenarios/test_codegen/rescript.json
🚧 Files skipped from review as they are similar to previous changes (17)
- scenarios/test_codegen/test/E2EEthNode_test.res
- codegenerator/cli/templates/static/erc20_template/rescript/config.yaml
- codegenerator/cli/templates/static/erc20_template/javascript/config.yaml
- scenarios/test_codegen/test/mocks/MockConfig.res
- codegenerator/cli/templates/dynamic/codegen/src/ConfigYAML.res.hbs
- scenarios/test_codegen/test/Integration_ts_helpers.res
- codegenerator/cli/src/cli_args/init_config.rs
- codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
- codegenerator/cli/templates/static/codegen/src/UserContext.res
- codegenerator/cli/npm/envio/evm.schema.json
- codegenerator/cli/templates/static/codegen/src/eventFetching/NetworkSources.res
- codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
- codegenerator/cli/templates/static/greeter_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/javascript/config.yaml
- codegenerator/cli/src/config_parsing/graph_migration/mod.rs
- codegenerator/cli/templates/static/greeteronfuel_template/javascript/config.yaml
- scenarios/test_codegen/test/AddressLowercase_test.res
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- scenarios/test_codegen/test/RpcSource_test.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/Address.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res
- scenarios/test_codegen/test/RpcSource_test.res
- codegenerator/cli/templates/static/codegen/src/Config.res
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/npm/envio/src/sources/HyperSyncClient.res
- codegenerator/cli/npm/envio/src/sources/RpcSource.res
- codegenerator/cli/npm/envio/src/Address.res
codegenerator/cli/templates/{static,dynamic}/codegen/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Edit template versions under codegenerator/cli/templates/static/codegen/src or codegenerator/cli/templates/dynamic/codegen/src instead of editing generated/src
Files:
- codegenerator/cli/templates/static/codegen/src/Config.res
scenarios/test_codegen/**/config.yaml
📄 CodeRabbit inference engine (scenarios/test_codegen/.cursor/rules/hyperindex.mdc)
scenarios/test_codegen/**/config.yaml: After changing config.yaml, run: pnpm codegen
Enable preload optimizations by adding preload_handlers: true in config.yaml
If using transaction-level data (e.g., event.transaction.hash), declare it under field_selection.transaction_fields in config.yaml
Annotate config.yaml with the YAML schema directive: # yaml-language-server: $schema=./node_modules/envio/evm.schema.json
Files:
- scenarios/test_codegen/config.yaml
{codegenerator/cli/src/human_config.rs,codegenerator/cli/src/system_config.rs,codegenerator/cli/src/hbs_templating/codegen_templates.rs}
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
When tracking how a value reaches templates, follow human_config.rs → system_config.rs → hbs_templating/codegen_templates.rs
Files:
- codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (9)
📓 Common learnings
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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/templates/static/codegen/src/Config.res
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/npm/envio/src/bindings/Ethers.res
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
- codegenerator/cli/npm/envio/src/Address.res
📚 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 : When matching addresses in configuration objects within code, ensure keys are lowercase and compare using address.toLowerCase()
Applied to files:
- scenarios/test_codegen/test/Config_test.res
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
📚 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/**/config.yaml : In config.yaml addresses, use lowercase hex strings for consistency
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
📚 Learning: 2025-09-04T14:42:53.500Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/subgraph-migration.mdc:0-0
Timestamp: 2025-09-04T14:42:53.500Z
Learning: Applies to config.yaml : Enable preload_handlers: true when using Effect API for external calls
Applied to files:
- codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
- codegenerator/cli/templates/static/greeteronfuel_template/rescript/config.yaml
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
📚 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/**/config.yaml : Enable preload optimizations by adding preload_handlers: true in config.yaml
Applied to files:
- scenarios/test_codegen/config.yaml
📚 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/**/config.yaml : Add `preload_handlers: true` to config.yaml to enable preload optimisations
Applied to files:
- scenarios/test_codegen/config.yaml
📚 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 : For address-based config maps in TypeScript, use lowercase keys and compare using `address.toLowerCase()` for consistent matching
Applied to files:
- codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
🔇 Additional comments (28)
codegenerator/cli/src/config_parsing/entity_parsing.rs (3)
193-193: LGTM: Correct lifetime annotation.The anonymous lifetime
<'_>properly ties the returnedTypeDefreference to the&selfborrow, ensuring the borrow checker knows the reference is valid only while the Schema exists.
472-472: LGTM: Correct lifetime annotation for test helper.The lifetime annotation
<'_>correctly reflects that the returnedDocumentborrows from the inputschema: &strparameter, which is required byparse_schema.
1491-1495: Lifetime annotation is correct for clonedObjectType
Cloning theObjectType<'_, String>yields ownedStringfields with no borrow fromschema_str; the signature’s lifetime parameter is required by the type definition. No changes needed.codegenerator/cli/src/hbs_templating/codegen_templates.rs (4)
1125-1135: LGTM - lowercaseAddresses threaded correctly.The conditional logic correctly threads
config.lowercase_addressesinto the generatedNetworkSources.evmcall, emitting the appropriate boolean literal.
1290-1291: LGTM - new fields added to ProjectTemplate.The new boolean fields
lowercase_addressesandshould_use_hypersync_client_decoderare appropriately typed and follow Rust conventions.
1412-1413: LGTM - fields correctly initialized from SystemConfig.The fields are correctly mapped from
cfg.lowercase_addressesandcfg.should_use_hypersync_client_decoder, completing the flow from human_config → system_config → codegen_templates as per coding guidelines.
1535-1535: LGTM - test expectations updated correctly.All test cases now correctly expect
~lowercaseAddresses=falsein the generatedNetworkSources.evmstrings, matching the default configuration behavior.Also applies to: 1590-1590, 1597-1597, 1630-1630, 1660-1660, 1671-1671
scenarios/test_codegen/config.yaml (1)
24-24: LGTM! Event decoder default set correctly.The addition of
event_decoder: "hypersync-client"as a top-level default aligns with the PR's goal to enable configurable address formatting and decoder behavior.codegenerator/cli/npm/envio/src/bindings/Ethers.res (1)
150-185: LGTM! Lowercase address support added correctly.The
~lowercaseAddresses: boolparameter is correctly threaded throughmakeGetTransactionFieldsand the conditional lowercasing logic forfrom,to, andcontractAddressfields is properly implemented usingJs.Nullablepattern matching.codegenerator/cli/npm/envio/src/Address.res (1)
14-34: LGTM! Lowercase address validation added correctly.The new
fromStringLowercaseOrThrowbinding and wrapper leverage viem'sisAddressfor validation and return a lowercased address. The intentional overshadowing pattern (documented in comments) is correctly applied: the external is invoked before being shadowed by the wrapper, avoiding viem imports in handler code. The companionfromAddressLowercaseOrThrowhelper completes the API surface.scenarios/test_codegen/test/Config_test.res (1)
12-12: LGTM!Test expectation correctly updated to include the new
lowercaseAddressesfield with the default value.codegenerator/cli/templates/static/codegen/src/Config.res (2)
118-118: LGTM!The
lowercaseAddressesfield is correctly added to theConfig.ttype.
190-190: LGTM!The
lowercaseAddressesfield is correctly included in the returned config record.scenarios/test_codegen/test/RpcSource_test.res (3)
33-35: LGTM!RpcSource.make correctly updated with the new required fields and appropriate test values.
50-52: LGTM!Test configuration is appropriate, with
shouldUseHypersyncClientDecoder: truepaired with event signatures.
176-176: LGTM!The
lowercaseAddressesparameter correctly propagates to the Ethers provider bindings.codegenerator/cli/npm/envio/src/sources/HyperSyncSource.res (4)
157-157: LGTM!The
lowercaseAddressesfield is correctly added to theoptionstype.
171-171: LGTM!Parameter destructuring is correct.
185-185: LGTM!The boolean inversion
!lowercaseAddressescorrectly maps toenableChecksumAddresses.
199-203: LGTM!The conditional decoder configuration correctly applies checksum settings based on
lowercaseAddresses.codegenerator/cli/src/config_parsing/human_config.rs (2)
215-218: LGTM!The
address_formatfield is correctly added with appropriate attributes and clear documentation.
221-226: LGTM!The
AddressFormatenum is correctly defined with appropriate derives and serialization attributes.codegenerator/cli/npm/envio/src/sources/RpcSource.res (2)
459-483: LGTM: options type and make signature correctly expanded.The new fields
allEventSignatures,shouldUseHypersyncClientDecoder, andlowercaseAddressesare properly added to theoptionstype and correctly destructured in themakefunction signature.
753-837: Normalize addresses in Viem decoding branch under lowercaseAddresses
The Viem path (RpcSource.res:765) passes rawlog.addresstoeventRouter.getinstead of applyingAddress.Evm.fromAddressLowercaseOrThrowwhenlowercaseAddressesis true, unlike the HyperSync branch (RpcSource.res:685–689). Apply the same conditional normalization or confirm that this divergence is intentional.codegenerator/cli/src/config_parsing/system_config.rs (4)
417-418: LGTM: new config fields properly declared.The two new boolean fields
lowercase_addressesandshould_use_hypersync_client_decoderare clearly named and appropriately typed for propagating address format and decoder preferences through the system.
726-735: LGTM: derivation logic correctly implements opt-in lowercase addresses and decoder selection.The derivation correctly defaults to checksummed addresses (lowercase_addresses = false when address_format is None) and HyperSync client decoder (true when event_decoder is None), aligning with the PR's opt-in design for lowercase addresses.
873-874: LGTM: Fuel defaults and error message formatting appropriate.Fuel ecosystem correctly defaults to no lowercase address conversion (line 873) and HyperSync decoder (line 874). Error message reformatting at lines 1032-1049 improves readability without changing logic.
Also applies to: 1032-1049
2110-2110: LGTM: test configs correctly updated with address_format field.Tests properly include
address_format: Noneto use default checksummed behavior, addressing the compile error flagged in past review comments.Based on past review comments.
Also applies to: 2157-2157
| | result => | ||
| if lowercaseAddresses { | ||
| // NOTE: this is wasteful if these fields are not selected in the users config. | ||
| // There might be a better way to do this based on the block schema. | ||
| // However this is not extremely expensive and good enough for now (only on rpc sync also). | ||
| // The in place mutation is cheapest. | ||
| (result->Obj.magic)["miner"] = result.miner->Address.Evm.fromAddressLowercaseOrThrow | ||
| } | ||
| result | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify: in-place mutation may affect cached blocks and happens on every fetch.
The miner address is mutated in-place on every successful block fetch (not just after backoff). Since blockLoader is a LazyLoader (line 518), the mutated block may be cached and shared across multiple call sites. This could cause unexpected behavior if the same block is accessed elsewhere expecting checksummed addresses.
Consider returning a transformed copy instead of mutating in-place, or ensure the loader never caches when lowercaseAddresses is enabled.
Run this script to check if the blockLoader cache could be accessed from multiple locations:
🏁 Script executed:
#!/bin/bash
# Check for other usages of blockLoader that might expect unmutated blocks
rg -nC3 'blockLoader->LazyLoader\.get' --type=resLength of output: 27
Let's rerun the search without the --type filter:
🏁 Script executed:
#!/bin/bash
rg -nC3 'blockLoader' -g '**/*.res'
rg -nC3 'LazyLoader' -g '**/*.res'
rg -nC3 'getKnownBlockWithBackoff' -g '**/*.res'Length of output: 9687
🏁 Script executed:
#!/bin/bash
sed -n '1,100p' codegenerator/cli/npm/envio/src/sources/RpcSource.resLength of output: 3708
🏁 Script executed:
#!/bin/bash
# Find LazyLoader implementation
fd LazyLoader.resLength of output: 46
🏁 Script executed:
#!/bin/bash
sed -n '1,200p' codegenerator/cli/npm/envio/src/LazyLoader.resLength of output: 4422
🏁 Script executed:
#!/bin/bash
sed -n '400,650p' codegenerator/cli/npm/envio/src/sources/RpcSource.resLength of output: 8842
Return a new block object instead of mutating the cached record
The in-place mutation in getKnownBlockWithBackoff (RpcSource.res) writes the lower-cased miner into the shared LazyLoader cache, so every later fetch of the same block sees a mutated address even if checksummed values are required. Clone result before altering—e.g.:
let block =
  if lowercaseAddresses {
    {...result, miner: Address.Evm.fromAddressLowercaseOrThrow(result.miner)}
  } else {
    result
  }
block—or disable caching when lowercaseAddresses is true.
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/sources/RpcSource.res around lines 45-53, the
function mutates the cached `result` by assigning a lower-cased `miner` into the
shared LazyLoader cache; instead clone `result` before altering so the cache is
not mutated — construct and return a new block object where `miner` is replaced
with Address.Evm.fromAddressLowercaseOrThrow(result.miner) when
`lowercaseAddresses` is true (otherwise return the original `result`), and
remove the in-place Obj.magic mutation; alternatively, if cloning is
undesirable, disable caching/avoid returning cached records when
`lowercaseAddresses` is true.
Co-authored-by: Dmitry Zakharov <dzakh.dev@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
codegenerator/cli/npm/envio/src/Address.res (1)
14-31: Consider renaming the external to match viem's API for clarity.The external
fromStringLowercaseOrThrowat line 16 binds to viem'sisAddress(returnsbool) but is shadowed by theletbinding at line 23 (returnst). While the overshadowing pattern is intentional to avoid viem imports in handler code, the name mismatch between the external and the viem function creates confusion:
- Line 12's external
fromStringOrThrowclearly maps togetAddress- Line 16's external
fromStringLowercaseOrThrowmaps toisAddress(inconsistent)Consider renaming the external to
isAddressto match viem's API, making the code more maintainable:- // NOTE: the function is named to be overshadowed by the one below, so that we don't have to import viem in the handler code @module("viem") - external fromStringLowercaseOrThrow: string => bool = "isAddress" + external isAddress: string => bool = "isAddress" // Reassign since the function might be used in the handler code // and we don't want to have a "viem" import there. It's needed to keep "viem" a dependency // of generated code instead of adding it to the indexer project dependencies. // Also, we want a custom error message, which is searchable in our codebase. // Validate that the string is a proper address but return a lowercased value let fromStringLowercaseOrThrow = string => { - if (fromStringLowercaseOrThrow(string)) { + if (isAddress(string)) { unsafeFromString(string->Js.String2.toLowerCase) } else { Js.Exn.raiseError( `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`, ) } }This change eliminates the shadowing of
fromStringLowercaseOrThrowwhile preserving the pattern used forfromStringOrThrowand maintaining the goal of avoiding viem imports in handlers.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- codegenerator/cli/npm/envio/src/Address.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- codegenerator/cli/npm/envio/src/Address.res
🧠 Learnings (2)
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
🔇 Additional comments (3)
codegenerator/cli/npm/envio/src/Address.res (3)
33-34: LGTM!The
fromAddressLowercaseOrThrowimplementation correctly converts an address to its lowercase string representation.
40-49: LGTM! Overshadowing pattern is correct.The
fromStringOrThrowwrapper correctly calls the external binding at line 12 before being shadowed. This pattern avoids viem imports in handler code while providing custom error messages, as confirmed in previous discussions.
51-51: LGTM!The
fromAddressOrThrowimplementation correctly validates an address by converting to string and callingfromStringOrThrow.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
codegenerator/cli/npm/envio/src/Address.res (2)
14-16: Rename the external binding to avoid confusion.The external
fromStringLowercaseOrThrowbinds to viem'sisAddress(which returnsbool), but the name suggests it returns an address. This is confusing because the wrapper function below (lines 23-31) shadows this name and does return an address.Consider using a clearer intermediate name like
viemIsAddressorisAddressExternalfor the external binding, then call that alias in the wrapper. This makes the code more maintainable and reduces confusion for future readers.Apply this diff:
- // NOTE: the function is named to be overshadowed by the one below, so that we don't have to import viem in the handler code @module("viem") - external fromStringLowercaseOrThrow: string => bool = "isAddress" + external viemIsAddress: string => bool = "isAddress"Then update the wrapper to call the alias:
let fromStringLowercaseOrThrow = string => { - if fromStringLowercaseOrThrow(string) { + if viemIsAddress(string) { unsafeFromString(string->Js.String2.toLowerCase) } else {
33-34: Function name is misleading—it doesn't throw.
fromAddressLowercaseOrThrowdoesn't validate or throw errors; it simply lowercases an already-valid address. The name suggests validation behavior similar tofromAddressOrThrow(line 51), but this function only transforms the casing.Consider renaming to
toLowercaseorasLowercaseto clarify that it's a pure transformation without validation.Apply this diff:
- let fromAddressLowercaseOrThrow = address => + let toLowercase = address => address->toString->Js.String2.toLowerCase->(Utils.magic: string => t)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
- codegenerator/cli/npm/envio/src/Address.res(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{res,resi}
📄 CodeRabbit inference engine (.cursor/rules/rescript.mdc)
**/*.{res,resi}: Never use[| item |]to create an array. Use[ item ]instead.
Must always use=for setting value to a field. Use:=only for ref values created usingreffunction.
ReScript has record types which require a type definition before hand. You can access record fields by dot likefoo.myField.
It's also possible to define an inline object, it'll have quoted fields in this case.
Use records when working with structured data, and objects to conveniently pass payload data between functions.
Never use %raw to access object fields if you know the type.
Files:
- codegenerator/cli/npm/envio/src/Address.res
**/*.res
📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)
Prefer reading ReScript .res modules directly; compiled .js artifacts can be ignored
Files:
- codegenerator/cli/npm/envio/src/Address.res
🧠 Learnings (2)
📚 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 : Ensure address matching uses consistent casing: use lowercase keys in config objects and compare against `address.toLowerCase()`
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
📚 Learning: 2025-07-22T07:15:55.433Z
Learnt from: CR
PR: enviodev/hyperindex#0
File: .cursor/rules/rescript.mdc:0-0
Timestamp: 2025-07-22T07:15:55.433Z
Learning: Never suggest ReasonML syntax.
Applied to files:
- codegenerator/cli/npm/envio/src/Address.res
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build_and_test
| let fromStringLowercaseOrThrow = string => { | ||
| if fromStringLowercaseOrThrow(string) { | ||
| unsafeFromString(string->Js.String2.toLowerCase) | ||
| } else { | ||
| Js.Exn.raiseError( | ||
| `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`, | ||
| ) | ||
| } | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify viem's isAddress accepts both checksummed and lowercase inputs.
The wrapper validates using isAddress then lowercases the result. Ensure viem's isAddress accepts both checksummed (e.g., 0xAbC...) and lowercase (e.g., 0xabc...) addresses, so users can pass either format.
Based on the PR discussion, this validation path may be more expensive than a simple regex but provides better UX by accepting mixed-case inputs.
🌐 Web query:
Does viem's isAddress function accept both checksummed and lowercase Ethereum addresses?
💡 Result:
Short answer: Yes — but with options.
Details: isAddress(address, { strict?: boolean }) defaults to strict: true, which enforces EIP‑55 checksums. An all-lowercase address will be considered valid only if you call isAddress(..., { strict: false }). [1]
Sources:
- viem isAddress docs. [1]
Use non-strict validation to accept lowercase addresses
In codegenerator/cli/npm/envio/src/Address.res, update the isAddress call to pass { strict: false }, for example:
let fromStringLowercaseOrThrow = string => {
  if isAddress(string, { strict: false }) {
    unsafeFromString(string->Js.String2.toLowerCase)
  } else {
    Js.Exn.raiseError(
      `Address "${string}" is invalid. Expected a 20-byte hex string starting with 0x.`,
    )
  }
}This ensures both EIP-55 checksummed and all-lowercase addresses are accepted.
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/Address.res around lines 23 to 31, the
validation currently rejects valid lowercase Ethereum addresses; update the
boolean check to call isAddress(string, { strict: false }) so the validator
accepts both EIP-55 checksummed and all-lowercase addresses, then keep the
existing unsafeFromString(string->Js.String2.toLowerCase) and error raise logic
unchanged.
TODO:
Summary by CodeRabbit
New Features
Configuration
Validation
Tests