Skip to content

External Call Template#1077

Merged
DZakh merged 6 commits into
mainfrom
nb/effect-template
Apr 2, 2026
Merged

External Call Template#1077
DZakh merged 6 commits into
mainfrom
nb/effect-template

Conversation

@nikbhintade

@nikbhintade nikbhintade commented Apr 2, 2026

Copy link
Copy Markdown
Member

A template for external calls was added to the CLI. Old PR: #826. All the suggestions from that PR are included in this PR.

Summary by CodeRabbit

  • New Features

    • Added a "Feature: External Calls" EVM project template with example handlers, schema for pool events, .env example, .gitignore, TypeScript config, and automatic inclusion of the Viem RPC dependency when that template is selected. Added interactive CLI option to choose this template.
  • Documentation

    • Added a detailed README for the External Calls template and updated CLI help to list the new template.
  • Tests

    • Added integration and unit tests and an e2e template entry exercising the new template.

@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 33e265b7-2ac2-4966-8289-bfe3504536cc

📥 Commits

Reviewing files that changed from the base of the PR and between 0812f8f and 6de6a87.

📒 Files selected for processing (1)
  • packages/cli/templates/static/external_calls_template/shared/README.md
✅ Files skipped from review due to trivial changes (1)
  • packages/cli/templates/static/external_calls_template/shared/README.md

📝 Walkthrough

Walkthrough

Adds an EVM init template variant FeatureExternalCalls, wires it into CLI prompts and template resolution, passes an extra viem dependency into template rendering for that flow, and introduces a TypeScript template demonstrating external RPC calls via an Effect (handlers, schema, config, tests, docs).

Changes

Cohort / File(s) Summary
CLI enums & prompts
packages/cli/src/cli_args/init_config.rs, packages/cli/src/cli_args/interactive_init/mod.rs
Added FeatureExternalCalls to EVM Template and interactive options; selection maps to the new init flow.
Template dir mapping
packages/cli/src/template_dirs.rs
Mapped evm::Template::FeatureExternalCalls"external_calls" directory.
Init executor & templating inputs
packages/cli/src/executor/init.rs, packages/cli/src/hbs_templating/init_templates.rs, packages/cli/templates/dynamic/init_templates/shared/package.json.hbs
Plumbed extra_dependencies into InitTemplates; FeatureExternalCalls adds ("viem", "^2.0.0"); package.json template renders extra_dependencies.
External Calls template — shared
packages/cli/templates/static/external_calls_template/shared/.env.example, .../.gitignore, .../README.md, .../schema.graphql
Added env example, gitignore, README documenting Effect-based external RPC usage, and GraphQL type UniswapV3Factory_PoolCreated.
External Calls template — TypeScript
packages/cli/templates/static/external_calls_template/typescript/config.yaml, .../src/handlers/UniswapV3Factory.ts, .../src/indexer.test.ts, .../tsconfig.json
Added TypeScript indexer with per-chain Viem clients, fetchTokenDetails effect, PoolCreated handler (decimals with fallbacks), unit/integration tests, and tsconfig.
E2E tests matrix
packages/e2e-tests/src/template-tests/templates.test.ts
Added evm-external-calls entry to parameterized template tests.
Docs
packages/cli/CommandLineHelp.md
Documented new template string feature-external-calls in CLI help.

Sequence Diagram(s)

sequenceDiagram
    participant Handler as Handler\n(UniswapV3Factory.PoolCreated)
    participant EffectAPI as Effect API\n(createEffect / context.effect)
    participant ViemClient as Viem Client(s)\n(per-chain)
    participant RPC as RPC Provider
    participant DB as Persistence

    Handler->>EffectAPI: context.effect("fetchTokenDetails",{token, chainId})
    EffectAPI->>ViemClient: select client by chainId -> readContract(decimals)
    ViemClient->>RPC: JSON-RPC request
    RPC-->>ViemClient: decimals (or error)
    ViemClient-->>EffectAPI: {decimal} (or fallback 18)
    EffectAPI-->>Handler: effect result {decimal}
    Handler->>DB: assemble entity and persist UniswapV3Factory_PoolCreated
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • JonoPrest
  • DZakh

Poem

🐰 I nibble code and chase a call,

Viem hops chain to chain and all.
Effects fetch decimals from afar,
Pools get logged, a shining star.
A carrot template — hop, hooray!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'External Call Template' directly and accurately describes the main change: adding a new external calls template to the CLI, matching the PR's primary objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nb/effect-template

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
packages/cli/templates/static/external_calls_template/shared/.gitignore (1)

1-18: Deduplicate repeated ignore patterns.

*.obj and *.annot are listed twice. Removing duplicates keeps the template cleaner without changing behavior.

Proposed cleanup
 *.exe
 *.obj
 *.out
 *.compile
 *.native
 *.byte
 *.cmo
 *.annot
 *.cmi
 *.cmx
 *.cmt
 *.cmti
 *.cma
 *.a
 *.cmxa
-*.obj
 *~
-*.annot
 *.cmj
 *.bak
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/templates/static/external_calls_template/shared/.gitignore`
around lines 1 - 18, The .gitignore template contains duplicate ignore patterns
(*.obj and *.annot); remove the repeated entries so each glob appears only once
(keep a single occurrence of *.obj and a single occurrence of *.annot),
preserving the existing order of the other entries and leaving all other
patterns unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/templates/static/external_calls_template/shared/.env.example`:
- Line 4: The .env.example currently ends with the ENVIO_ETHEREUM_MAINNET_RPC
entry without a trailing newline which triggers dotenv-linter; open the
.env.example containing the
ENVIO_ETHEREUM_MAINNET_RPC=<YOUR-ETHEREUM-MAINNET-RPC-URL> line and add a single
blank newline at EOF so the file ends with a trailing newline.

In
`@packages/cli/templates/static/external_calls_template/typescript/src/handlers/UniswapV3Factory.ts`:
- Around line 7-16: The module currently uses non-null assertions on
process.env.ENVIO_ETHEREUM_MAINNET_RPC and process.env.ENVIO_ARBITRUM_RPC when
building CHAIN_CLIENTS at module load (via createPublicClient + http), which can
instantiate clients with undefined URLs; change this to lazily or conditionally
create clients instead: either convert CHAIN_CLIENTS into a factory function
(e.g., getChainClients()) or make its values optional (Record<number,
ReturnType<typeof createPublicClient> | undefined>) and only call
http/createPublicClient when the corresponding env var exists, using optional
chaining or explicit checks for process.env.ENVIO_ETHEREUM_MAINNET_RPC and
process.env.ENVIO_ARBITRUM_RPC before calling http/createPublicClient to avoid
non-null assertions and preserve the runtime graceful fallback in the effect
handler.

---

Nitpick comments:
In `@packages/cli/templates/static/external_calls_template/shared/.gitignore`:
- Around line 1-18: The .gitignore template contains duplicate ignore patterns
(*.obj and *.annot); remove the repeated entries so each glob appears only once
(keep a single occurrence of *.obj and a single occurrence of *.annot),
preserving the existing order of the other entries and leaving all other
patterns unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7bd6f49d-65a3-482b-93a8-15ab9f712270

📥 Commits

Reviewing files that changed from the base of the PR and between c2bf0ea and 18e0278.

📒 Files selected for processing (14)
  • packages/cli/src/cli_args/init_config.rs
  • packages/cli/src/cli_args/interactive_init/mod.rs
  • packages/cli/src/executor/init.rs
  • packages/cli/src/hbs_templating/init_templates.rs
  • packages/cli/src/template_dirs.rs
  • packages/cli/templates/dynamic/init_templates/shared/package.json.hbs
  • packages/cli/templates/static/external_calls_template/shared/.env.example
  • packages/cli/templates/static/external_calls_template/shared/.gitignore
  • packages/cli/templates/static/external_calls_template/shared/README.md
  • packages/cli/templates/static/external_calls_template/shared/schema.graphql
  • packages/cli/templates/static/external_calls_template/typescript/config.yaml
  • packages/cli/templates/static/external_calls_template/typescript/src/handlers/UniswapV3Factory.ts
  • packages/cli/templates/static/external_calls_template/typescript/src/indexer.test.ts
  • packages/cli/templates/static/external_calls_template/typescript/tsconfig.json

Comment thread packages/cli/templates/static/external_calls_template/shared/.env.example Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/cli/templates/static/external_calls_template/typescript/src/indexer.test.ts (1)

102-102: Strengthen the ID test assertion to avoid false positives.

toBeDefined() is fairly loose for an identity-format test. Consider asserting the fetched entity id equals 1_${pool} (or matching the full expected object) so the test fails on subtle retrieval behavior changes.

Proposed test-tightening diff
-    expect(await indexer.UniswapV3Factory_PoolCreated.get(`1_${pool}`)).toBeDefined();
+    const entityId = `1_${pool}`;
+    await expect(indexer.UniswapV3Factory_PoolCreated.get(entityId)).resolves.toMatchObject({
+      id: entityId,
+      pool,
+      token0,
+      token1,
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/cli/templates/static/external_calls_template/typescript/src/indexer.test.ts`
at line 102, The test currently uses a loose assertion expect(await
indexer.UniswapV3Factory_PoolCreated.get(`1_${pool}`)).toBeDefined(); — change
it to assert the returned entity's id exactly equals the expected id (e.g.,
fetch via indexer.UniswapV3Factory_PoolCreated.get(`1_${pool}`) and
expect(entity.id).toBe(`1_${pool}`)) or assert full object equality against the
expected object to prevent false positives; target the
indexer.UniswapV3Factory_PoolCreated.get call and the pool variable when making
this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/cli/templates/static/external_calls_template/typescript/src/indexer.test.ts`:
- Line 102: The test currently uses a loose assertion expect(await
indexer.UniswapV3Factory_PoolCreated.get(`1_${pool}`)).toBeDefined(); — change
it to assert the returned entity's id exactly equals the expected id (e.g.,
fetch via indexer.UniswapV3Factory_PoolCreated.get(`1_${pool}`) and
expect(entity.id).toBe(`1_${pool}`)) or assert full object equality against the
expected object to prevent false positives; target the
indexer.UniswapV3Factory_PoolCreated.get call and the pool variable when making
this change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1bf6e39e-b10c-409e-a92f-c89fe4019c8f

📥 Commits

Reviewing files that changed from the base of the PR and between 3c81378 and 0812f8f.

📒 Files selected for processing (1)
  • packages/cli/templates/static/external_calls_template/typescript/src/indexer.test.ts

@nikbhintade nikbhintade requested a review from DZakh April 2, 2026 08:23
@nikbhintade nikbhintade self-assigned this Apr 2, 2026

@DZakh DZakh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Whoa, really nice. I didn't expect to see tests using Simulate, which has not even released. Really nice job!

@DZakh DZakh merged commit 89ef12d into main Apr 2, 2026
8 checks passed
@DZakh DZakh deleted the nb/effect-template branch April 2, 2026 08:46
@coderabbitai coderabbitai Bot mentioned this pull request Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants