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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion codegenerator/cli/CommandLineHelp.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ Initialize Evm indexer from an example template

* `-t`, `--template <TEMPLATE>` — Name of the template to be used in initialization

Possible values: `greeter`, `erc20`
Possible values: `greeter`, `erc20`, `topic-filtering`, `wildcard-indexing`, `on-block-handler`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify all new templates are documented.

The PR description mentions adding 6 new templates, but only 5 are listed here. The AI summary references templates like effects-api, factory-indexer, and multichain-indexer that don't appear in this help text. Please confirm:

  1. Are all new templates included in the documentation?
  2. Are greeter and erc20 pre-existing templates or new additions?

🏁 Script executed:

#!/bin/bash
# Find all template directories to verify what templates exist
fd -t d . codegenerator/cli/templates/static/ -d 1 --exec basename

Length of output: 235


I need to view the complete CommandLineHelp.md file to understand the full context and what should be documented.


---

🏁 Script executed:

```shell
#!/bin/bash
# View the CommandLineHelp.md file to see complete context
cat codegenerator/cli/CommandLineHelp.md

Length of output: 10277


Update the EVM template documentation to include all available templates.

The filesystem contains more templates than currently documented:

EVM templates in codebase:

  • Documented: greeter, erc20, topic-filtering, wildcard-indexing, on-block-handler
  • Not documented: factory-indexer, multichain-indexer, effects-api, blank

Fuel templates in codebase:

  • Documented: greeter
  • Not documented: greeteronfuel

Update line 145 (envio init template section) and the Fuel template section to include all available templates, or confirm that undocumented templates are intentionally excluded.

🤖 Prompt for AI Agents
In codegenerator/cli/CommandLineHelp.md around line 145, the list of possible
templates is incomplete: add the missing EVM templates (factory-indexer,
multichain-indexer, effects-api, blank) to the `envio init template` section and
update the Fuel templates section to include `greeteronfuel` (or explicitly note
any intentionally excluded templates); edit the documented lists so they match
the filesystem names exactly and keep ordering/format consistent with existing
entries.




Expand Down
14 changes: 14 additions & 0 deletions codegenerator/cli/src/cli_args/init_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,22 @@ pub mod evm {

#[derive(Clone, Debug, ValueEnum, Serialize, Deserialize, EnumIter, EnumString, Display)]
pub enum Template {
#[strum(serialize = "Greeter")]
Greeter,
#[strum(serialize = "ERC20")]
Erc20,
#[strum(serialize = "Feature: Topic Filtering")]
TopicFiltering,
#[strum(serialize = "Feature: Wildcard Indexing")]
WildcardIndexing,
#[strum(serialize = "Feature: onBlock Handler")]
OnBlockHandler,
#[strum(serialize = "Feature: Effects API")]
EffectsAPI,
#[strum(serialize = "Feature: Factory Indexer")]
FactoryIndexer,
#[strum(serialize = "Feature: Multichain Indexer")]
MultichainIndexer,
Comment on lines +35 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[strum(serialize = "Feature: Topic Filtering")]
TopicFiltering,
#[strum(serialize = "Feature: Wildcard Indexing")]
WildcardIndexing,
#[strum(serialize = "Feature: onBlock Handler")]
OnBlockHandler,
#[strum(serialize = "Feature: Effects API")]
EffectsAPI,
#[strum(serialize = "Feature: Factory Indexer")]
FactoryIndexer,
#[strum(serialize = "Feature: Multichain Indexer")]
MultichainIndexer,
#[strum(serialize = "Feature: Topic Filtering")]
TopicFiltering,
#[strum(serialize = "Feature: Wildcard Indexing")]
WildcardIndexing,
#[strum(serialize = "Feature: Block Handler")]
OnBlockHandler,
#[strum(serialize = "Feature: External Calls")]
EffectsAPI,
#[strum(serialize = "Feature: Factory Contract")]
FactoryIndexer,
#[strum(serialize = "Feature: Multichain Indexer")]
MultichainIndexer,

}

///A an object that holds all the values a user can select during
Expand Down
14 changes: 11 additions & 3 deletions codegenerator/cli/src/cli_args/interactive_init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::{
clap_definitions::{self, InitArgs, ProjectPaths},
init_config::{InitConfig, Language},
};
use crate::template_dirs::Template;
use crate::{
clap_definitions::InitFlow,
constants::project_paths::DEFAULT_PROJECT_ROOT_PATH,
Expand All @@ -30,7 +31,10 @@ enum EcosystemOption {
Fuel,
}

async fn prompt_ecosystem(cli_init_flow: Option<InitFlow>) -> Result<Ecosystem> {
async fn prompt_ecosystem(
cli_init_flow: Option<InitFlow>,
selected_language: Language,
) -> Result<Ecosystem> {
let init_flow = match cli_init_flow {
Some(v) => v,
None => {
Expand Down Expand Up @@ -72,7 +76,11 @@ async fn prompt_ecosystem(cli_init_flow: Option<InitFlow>) -> Result<Ecosystem>
let chosen_template = match args.template {
Some(template) => template,
None => {
let options = evm::Template::iter().collect();
// ✅ Filter templates based on selected language
let options: Vec<_> = evm::Template::iter()
.filter(|t| t.supported_languages().contains(&selected_language))
.collect();

prompt_template(options)?
}
};
Expand Down Expand Up @@ -155,7 +163,7 @@ pub async fn prompt_missing_init_args(
}
};

let ecosystem = prompt_ecosystem(init_args.init_commands)
let ecosystem = prompt_ecosystem(init_args.init_commands, language.clone())
.await
.context("Failed getting template")?;

Expand Down
109 changes: 90 additions & 19 deletions codegenerator/cli/src/template_dirs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,46 @@ use std::{

pub trait Template: Display {
fn to_dir_name(&self) -> String;

fn supported_languages(&self) -> Vec<Language>;
}

impl Template for evm::Template {
fn to_dir_name(&self) -> String {
match self {
evm::Template::Greeter => "greeter",
evm::Template::Erc20 => "erc20",
evm::Template::TopicFiltering => "topic_filtering",
evm::Template::WildcardIndexing => "wildcard_indexing",
evm::Template::OnBlockHandler => "onblock_handler",
evm::Template::EffectsAPI => "effects_api",
evm::Template::FactoryIndexer => "factory_indexer",
evm::Template::MultichainIndexer => "multichain_indexer",
}
.to_string()
}

fn supported_languages(&self) -> Vec<Language> {
match self {
// Example mappings — adjust based on what your actual templates support
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove the placeholder comment.

The comment suggests this is example code needing adjustment. Please remove it as the mappings appear to be the actual implementation.

-            // Example mappings — adjust based on what your actual templates support
📝 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.

Suggested change
// Example mappings — adjust based on what your actual templates support
🤖 Prompt for AI Agents
In codegenerator/cli/src/template_dirs.rs around line 31, remove the placeholder
comment line "// Example mappings — adjust based on what your actual templates
support" from the file since the mappings below are the real implementation;
simply delete that comment so the file contains only relevant code/comments and
re-run formatting if needed.

evm::Template::Greeter => vec![
Language::JavaScript,
Language::TypeScript,
Language::ReScript,
],
evm::Template::Erc20 => vec![
Language::JavaScript,
Language::TypeScript,
Language::ReScript,
],
evm::Template::TopicFiltering => vec![Language::TypeScript],
evm::Template::WildcardIndexing => vec![Language::TypeScript],
evm::Template::OnBlockHandler => vec![Language::TypeScript],
evm::Template::EffectsAPI => vec![Language::TypeScript],
evm::Template::FactoryIndexer => vec![Language::TypeScript],
evm::Template::MultichainIndexer => vec![Language::TypeScript],
}
}
}

impl Template for fuel::Template {
Expand All @@ -29,6 +59,16 @@ impl Template for fuel::Template {
}
.to_string()
}

fn supported_languages(&self) -> Vec<Language> {
match self {
fuel::Template::Greeter => vec![
Language::JavaScript,
Language::TypeScript,
Language::ReScript,
],
}
}
}

static TEMPLATES_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/templates");
Expand Down Expand Up @@ -432,58 +472,89 @@ mod test {
fn all_init_templates_exist() {
let template_dirs = TemplateDirs::new();

// EVM templates
for template in evm::Template::iter() {
for lang in Language::iter() {
for lang in template.supported_languages() {
template_dirs
.get_template_lang_dir(&template, &lang)
.expect("static lang");
.expect(&format!(
"Expected static language dir for EVM template {:?} and language {:?}",
template, lang
));
}
template_dirs
.get_template_shared_dir(&template)
.expect("static templte shared");
.expect(&format!(
"Expected shared static dir for EVM template {:?}",
template
));
}

// FUEL templates
for template in fuel::Template::iter() {
for lang in Language::iter() {
for lang in template.supported_languages() {
template_dirs
.get_template_lang_dir(&template, &lang)
.expect("static lang");
.expect(&format!(
"Expected static language dir for FUEL template {:?} and language {:?}",
template, lang
));
}
template_dirs
.get_template_shared_dir(&template)
.expect("static templte shared");
.expect(&format!(
"Expected shared static dir for FUEL template {:?}",
template
));
}

// Shared dynamic init template
template_dirs
.get_init_template_dynamic_shared()
.expect("dynami shared init template");
.expect("Expected dynamic shared init template dir to exist");
}

#[test]
fn all_init_templates_extract_succesfully() {
let template_dirs = TemplateDirs::new();
let temp_dir =
TempDir::new("init_extract_lang_test").expect("Failed creating tempdir init template");
let temp_dir = TempDir::new("init_extract_lang_test")
.expect("Failed creating tempdir for init template");

// EVM templates
for template in evm::Template::iter() {
for lang in Language::iter() {
for lang in template.supported_languages() {
template_dirs
.get_and_extract_template(&template, &lang, &(PathBuf::from(temp_dir.path())))
.expect("static lang");
.get_and_extract_template(&template, &lang, &PathBuf::from(temp_dir.path()))
.expect(&format!(
"Failed extracting EVM template {:?} for language {:?}",
template, lang
));
}
}

// FUEL templates
for template in fuel::Template::iter() {
for lang in Language::iter() {
for lang in template.supported_languages() {
template_dirs
.get_and_extract_template(&template, &lang, &(PathBuf::from(temp_dir.path())))
.expect("static lang");
.get_and_extract_template(&template, &lang, &PathBuf::from(temp_dir.path()))
.expect(&format!(
"Failed extracting FUEL template {:?} for language {:?}",
template, lang
));
}
}
let temp_dir =
TempDir::new("init_extract_blank_lang_test").expect("Failed creating tempdir blank");

// Blank template extraction
let blank_temp_dir = TempDir::new("init_extract_blank_lang_test")
.expect("Failed creating tempdir for blank template");

for lang in Language::iter() {
template_dirs
.get_and_extract_blank_template(&lang, &temp_dir.path().into())
.expect("static blank");
.get_and_extract_blank_template(&lang, &PathBuf::from(blank_temp_dir.path()))
.expect(&format!(
"Failed extracting blank template for language {:?}",
lang
));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# To create or update a token visit https://envio.dev/app/api-tokens
ENVIO_API_TOKEN="<YOUR-API-TOKEN>"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove quotes around the placeholder value in .env.example.

The double-quoted placeholder value violates dotenv conventions. If users copy this line without modification, the token value will include the literal quotes, causing authentication failures. Placeholder values in .env.example should be unquoted.

- ENVIO_API_TOKEN="<YOUR-API-TOKEN>"
+ ENVIO_API_TOKEN=<YOUR-API-TOKEN>
🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 2-2: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)

🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/effects_api_template/shared/.env.example
around line 2, the placeholder ENVIO_API_TOKEN is wrapped in double quotes which
can cause users to copy the quotes into their actual .env and break
authentication; remove the surrounding quotes so the placeholder is unquoted
(ENVIO_API_TOKEN=<YOUR-API-TOKEN>) and ensure any accompanying documentation
notes the token should be pasted without quotes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
*.exe
*.obj
*.out
*.compile
*.native
*.byte
*.cmo
*.annot
*.cmi
*.cmx
*.cmt
*.cmti
*.cma
*.a
*.cmxa
*.obj
*~
*.annot
*.cmj
*.bak
lib/*
*.mlast
*.mliast
.vscode
.merlin
.bsb.lock
node_modules/
build/
benchmarks/
artifacts
cache
*.res.js
*.res.mjs
generated
.env
Comment on lines +1 to +35
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove duplicate ignore patterns.

The file contains duplicate patterns that should be consolidated:

  • *.obj appears on lines 2 and 16
  • *.annot appears on lines 8 and 18

Apply this diff to remove duplicates:

 *.exe
 *.obj
 *.out
 *.compile
 *.native
 *.byte
 *.cmo
 *.annot
 *.cmi
 *.cmx
 *.cmt
 *.cmti
 *.cma
 *.a
 *.cmxa
-*.obj
 *~
-*.annot
 *.cmj
 *.bak
📝 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.

Suggested change
*.exe
*.obj
*.out
*.compile
*.native
*.byte
*.cmo
*.annot
*.cmi
*.cmx
*.cmt
*.cmti
*.cma
*.a
*.cmxa
*.obj
*~
*.annot
*.cmj
*.bak
lib/*
*.mlast
*.mliast
.vscode
.merlin
.bsb.lock
node_modules/
build/
benchmarks/
artifacts
cache
*.res.js
*.res.mjs
generated
.env
*.exe
*.obj
*.out
*.compile
*.native
*.byte
*.cmo
*.annot
*.cmi
*.cmx
*.cmt
*.cmti
*.cma
*.a
*.cmxa
*~
*.cmj
*.bak
lib/*
*.mlast
*.mliast
.vscode
.merlin
.bsb.lock
node_modules/
build/
benchmarks/
artifacts
cache
*.res.js
*.res.mjs
generated
.env
🤖 Prompt for AI Agents
In codegenerator/cli/templates/static/effects_api_template/shared/.gitignore
around lines 1 to 35, there are duplicate ignore patterns (*.obj on lines 2 and
16, and *.annot on lines 8 and 18); remove the duplicated entries so each
pattern appears only once (keep a single instance of *.obj and a single instance
of *.annot), preserving the rest of the ordering and content.

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Effects API

_Please refer to the [documentation website](https://docs.envio.dev) for a thorough guide on all [Envio](https://envio.dev) indexer features_

With HyperIndex, the Effects API allows you to perform external calls from your handlers.
These calls run in parallel with your handler logic, so they don’t block execution.

You can learn more about the Effects API in the documentation: [https://docs.envio.dev/docs/HyperIndex/effect-api](https://docs.envio.dev/docs/HyperIndex/effect-api)

The following example extends the **factory pattern** example to fetch the **decimal of a token** using an RPC call via **Viem**.

## Create Effect

To create an effect in your handler, use the `experimental_createEffect` function from the `envio` package.
This function takes **two arguments**: effect options and a handler function.

Effect options:

* `name`: used for debugging and logging
* `input`: the input type of the effect
* `output`: the output type of the effect
* `cache`: whether to cache the effect result in the database

## Using Effect

To use the effect, use `context.effect` from your handlers, loaders, or other effects:

```ts
CONTRACT.EVENT.handler(async ({ event, context }) => {
const effectOutput = await context.effect(YOUR_EFFECT, EFFECT_INPUTS);
});
```

## `getTokenDetails` Effect

The following effect fetches the **decimal of a token** using an RPC call:

```ts
const client = createPublicClient({
chain: mainnet,
transport: http(process.env.ETHEREUM_MAINNET_RPC!),
});

const ERC20_ABI = parseAbi(["function decimals() view returns (uint8)"]);

const fetchTokenDetails = experimental_createEffect(
{
name: "fetchTokenDetails",
input: {
token: S.string,
},
output: {
decimal: S.number,
},
},
async ({ input }) => {
const decimals = await client.readContract({
address: input.token as `0x${string}`,
abi: ERC20_ABI,
functionName: "decimals",
});

console.log(`Token decimals: ${decimals}`);
return { decimal: decimals };
}
);
```

## Prerequisites

Before running the indexer locally, make sure you have the following installed:

- **[Node.js 18+](https://nodejs.org/en/download/)**
- **[pnpm](https://pnpm.io/installation)**
- **[Docker Desktop](https://www.docker.com/products/docker-desktop/)**

## Running the Indexer

Add your Envio API key to the .env file, then start the indexer:

```bash
pnpm dev
```

If you make changes to `config.yaml` or `schema.graphql`, regenerate the type files:

```bash
pnpm codegen
```

## GraphQL Playground

While indexer is running, visit the Envio Console([https://envio.dev/console](https://envio.dev/console)) to open the GraphQL Playground and query your indexed data.
Loading
Loading