<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Envio Blog</title>
        <link>https://docs.envio.dev/blog</link>
        <description>Envio Blog</description>
        <lastBuildDate>Thu, 14 May 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Why AI Agents Acting Onchain Need an Indexer]]></title>
            <link>https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer</link>
            <guid>https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer</guid>
            <pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[AI agents that act onchain need reorg-safe, queryable data they can act on. HyperIndex delivers it. Real MCP server, real Claude skills, 400k events in 20 seconds.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/ai-agents-acting-onchain-indexer.png" alt="Why AI Agents Acting Onchain Need an Indexer" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. It is the right data layer for AI agents acting onchain because it ships reorg-safe data, structured GraphQL output, an MCP server that exposes the docs to any agent, and a <code>.claude/skills/</code> directory that auto-discovers for Cursor, Claude Code, and Codex.</li>
<li>The published <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic demo</a> documents an end-to-end flow where an agent scaffolded, configured, pushed to GitHub, and deployed a wstETH indexer on Monad Mainnet from a single prompt. 400,000 events indexed in approximately 20 seconds.</li>
<li>The Envio docs MCP server exposes two tools (<code>docs_search</code> and <code>docs_fetch</code>) over Streamable HTTP at <code>https://docs.envio.dev/mcp</code>. Configured into Claude Code, Cursor, or VS Code with one command.</li>
<li>HyperIndex projects scaffold a <code>.claude/skills/</code> directory pre-populated with 14 skills covering config, schema, handler syntax, factory patterns, filters, multichain, performance, traces, transactions, wildcard, blocks, external calls (the Effect API), testing, and subgraph migration.</li>
</ul></div></div>
<p>The agentic-onchain conversation in 2026 has settled into two camps. One says agents need a reconciled SQL warehouse to make sense of raw blockchain data. The other says agents need a programmable indexer that lets them act, not just analyse. Both are right about the diagnosis. Raw RPC is unworkable for an agent. The disagreement is about what replaces it.</p>
<p>This blog is the case for indexers, not warehouses. A SQL warehouse lets an agent ask questions. An indexing framework lets an agent build, deploy, and own new data pipelines mid-session. The first is a query tool, the second is infrastructure. Agents acting onchain need the second. HyperIndex ships it today.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-raw-blockchain-data-breaks-agents">Why Raw Blockchain Data Breaks Agents<a class="hash-link" aria-label="Direct link to Why Raw Blockchain Data Breaks Agents" title="Direct link to Why Raw Blockchain Data Breaks Agents" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#why-raw-blockchain-data-breaks-agents">​</a></h2>
<p>An agent reading from RPC directly hits four problems within minutes.</p>
<p><strong>1. Reorgs.</strong> A recent block can be reorged. An agent that wrote a record based on an unfinalized block has to either lag the chain head (and miss real-time signals) or roll its own rollback logic (and get it wrong on the next edge case). Neither is acceptable for an agent running in a production environment.</p>
<p><strong>2. Schema.</strong> RPC returns logs and transactions. It does not return entities, relationships, or aggregations. The agent has to assemble the schema in memory on every query. Cross-contract state, factory pattern instances, and anything time-windowed have to be rebuilt from scratch.</p>
<p><strong>3. Throughput.</strong> An agent that wants to know the last 1,000 trades on a market has to issue 1,000 <code>eth_getLogs</code> calls or hand-tune a paginated request. A historical sweep across a year of activity can take hours to query from RPC.</p>
<p><strong>4. Multichain.</strong> Most agents that matter operate across at least two chains. Each chain is a separate RPC, separate quirks, separate rate limits. The application code that joins those RPCs is exactly the indexing code an indexer would write for you.</p>
<p>The standard response to "raw RPC is unworkable for agents" is to put a SQL warehouse in front of it. That works for read-only analytical queries. It does not work for an agent that needs to spin up a new product on top of the data within a session.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-hyperindex-provides-instead">What HyperIndex Provides Instead<a class="hash-link" aria-label="Direct link to What HyperIndex Provides Instead" title="Direct link to What HyperIndex Provides Instead" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#what-hyperindex-provides-instead">​</a></h2>
<p>HyperIndex addresses all four problems by being a blockchain indexing framework rather than a query layer.</p>
<ul>
<li><strong>Reorg safety at the framework level.</strong> Entity state history, automatic rollback, no reorg logic required in handlers. Learn more in <a href="https://docs.envio.dev/blog/indexing-and-reorgs" target="_blank" rel="noopener noreferrer">Indexing and Reorgs</a>.</li>
<li><strong>Structured GraphQL output.</strong> Entities, relationships, aggregations, time-windowed views, all queryable from one endpoint. Agents read GraphQL, not raw logs.</li>
<li><strong>HyperSync historical throughput.</strong> Up to 2,000x faster than RPC. The Polymarket reference indexer synced its first 4,000,000,000 events in 6 days and has indexed over 6,500,000,000 to date.</li>
<li><strong>Multichain in one config.</strong> <!-- -->87+<!-- --> have native HyperSync coverage, any EVM chain accessible via standard RPC, all in a single <code>config.yaml</code>.</li>
</ul>
<p>That is the read side. The act side is what makes HyperIndex an agent's infrastructure, not just an agent's data layer.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-three-things-that-make-it-programmable-for-agents">The Three Things That Make It Programmable for Agents<a class="hash-link" aria-label="Direct link to The Three Things That Make It Programmable for Agents" title="Direct link to The Three Things That Make It Programmable for Agents" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#the-three-things-that-make-it-programmable-for-agents">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-the-envio-docs-mcp-server">1. The Envio Docs MCP Server<a class="hash-link" aria-label="Direct link to 1. The Envio Docs MCP Server" title="Direct link to 1. The Envio Docs MCP Server" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#1-the-envio-docs-mcp-server">​</a></h3>
<p>The <a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">docs MCP server</a> exposes the entire Envio docs site as two MCP tools:</p>
<ul>
<li><code>docs_search</code> for semantic search across the docs</li>
<li><code>docs_fetch</code> to retrieve a docs page by ID</li>
</ul>
<p>Endpoint: <code>https://docs.envio.dev/mcp</code>. Transport: Streamable HTTP.</p>
<p>Setup is one command for Claude Code:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">claude mcp </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--transport</span><span class="token plain"> http envio-docs https://docs.envio.dev/mcp</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Cursor and VS Code use the JSON config form on the same page. Once added, every agent session in that workspace grounds its answers about HyperIndex in the live docs rather than stale training data.</p>
<p>This matters because agents writing indexer code typically hallucinate APIs that do not exist. The MCP server gives the agent a fresh source of truth on every request, so it cites real HyperIndex syntax instead of guessing.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-auto-discovered-skills-in-claudeskills">2. Auto-Discovered Skills in <code>.claude/skills/</code><a class="hash-link" aria-label="Direct link to 2-auto-discovered-skills-in-claudeskills" title="Direct link to 2-auto-discovered-skills-in-claudeskills" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#2-auto-discovered-skills-in-claudeskills">​</a></h3>
<p>When a HyperIndex project is initialised, it scaffolds a <code>.claude/skills/</code> directory pre-populated with skill definitions. Cursor, Claude Code, and Codex all auto-discover skills from this directory at session start. The descriptions load up front, full skill content loads on demand. Confirmed in the public Polymarket reference repo's <code>CLAUDE.md</code>:</p>
<blockquote>
<p>Skills in <code>.claude/skills/</code> are auto-discovered — descriptions load at startup, full content on demand.</p>
</blockquote>
<p>HyperIndex projects scaffolded with v3 rc ship 14 skill definitions:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">.claude/skills/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-blocks/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-configuration/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-external-calls/   # Effect API for fetch / RPC / async I/O</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-factory/          # Dynamic contract registration</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-filters/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-handlers/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-multichain/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-performance/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-schema/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-testing/          # Vitest patterns for handler tests</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-traces/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-transactions/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer-wildcard/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  migrate-from-subgraph/    # AssemblyScript-to-TypeScript conversion</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The canonical skill set lives at <a href="https://github.com/enviodev/hyperindex/tree/main/packages/cli/templates/static/shared/.claude/skills" target="_blank" rel="noopener noreferrer">github.com/enviodev/hyperindex/tree/main/packages/cli/templates/static/shared/.claude/skills</a> and ships into every new HyperIndex project.</p>
<p>These skills encode the patterns that make a HyperIndex project work. A developer running Claude Code, Cursor, or Codex in a HyperIndex project does not need to teach the agent what HyperIndex is. The skills do that, scoped to the actual conventions the framework expects.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-the-envio-cloud-cli">3. The envio-cloud CLI<a class="hash-link" aria-label="Direct link to 3. The envio-cloud CLI" title="Direct link to 3. The envio-cloud CLI" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#3-the-envio-cloud-cli">​</a></h3>
<p>The <code>envio-cloud</code> CLI is the GitHub-native deploy surface for HyperIndex indexers running on Envio Cloud. The three core agent-facing commands are:</p>
<ul>
<li><code>envio-cloud login</code> to authenticate via GitHub</li>
<li><code>envio-cloud indexer add</code> to register a new indexer</li>
<li><code>envio-cloud deployment status</code> to check sync state</li>
</ul>
<p>Every command supports <code>-o json</code> for parseable output. Install with <code>npm install -g envio-cloud</code>.</p>
<p>The full <a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">CLI reference</a> is in the docs.</p>
<p>The deploy model is GitHub-native. An agent commits the indexer code to a GitHub repo, pushes to the <code>envio</code> branch (the default deploy branch), and registers the indexer with <code>envio-cloud indexer add</code>. The Envio GitHub App handles deployments from there. No deploy button, no dashboard step.</p>
<p>The published agentic demo did exactly that for a wstETH indexer on Monad Mainnet. 400,000 events indexed in approximately 20 seconds. The agent reads the contract, scaffolds the project from the ERC20 template, configures <code>config.yaml</code> for Monad, runs codegen and a type check, pushes to GitHub, and registers the indexer. End to end, no human in the loop after the first prompt. <a href="https://www.loom.com/share/09cdac43b18f4143ad78b18c8c8a492b" target="_blank" rel="noopener noreferrer">Loom walkthrough</a>. <a href="https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35" target="_blank" rel="noopener noreferrer">Live deployment</a>.</p>
<p>That is the <em>act</em> in "programmable infrastructure for agents that need to act, not just query."</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="a-concrete-example-the-published-wsteth-on-monad-demo">A Concrete Example: The Published wstETH-on-Monad Demo<a class="hash-link" aria-label="Direct link to A Concrete Example: The Published wstETH-on-Monad Demo" title="Direct link to A Concrete Example: The Published wstETH-on-Monad Demo" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#a-concrete-example-the-published-wsteth-on-monad-demo">​</a></h2>
<p>The <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic indexing blog</a> documents the full end-to-end flow an agent ran from scaffold to live deployment. This is not a hypothetical. The <a href="https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35" target="_blank" rel="noopener noreferrer">live deployment</a> and the <a href="https://www.loom.com/share/09cdac43b18f4143ad78b18c8c8a492b" target="_blank" rel="noopener noreferrer">Loom walkthrough</a> are both public.</p>
<p>The commands the agent ran (from the published blog):</p>
<p><strong>Step 1: Scaffold from the ERC20 template</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio@3.0.0-rc.0 init template </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-t</span><span class="token plain"> erc20 </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-l</span><span class="token plain"> typescript </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-d</span><span class="token plain"> ./my-indexer --api-token </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The <code>--api-token ""</code> makes the init non-interactive. No token is needed at scaffold time; auth is handled at deploy.</p>
<p><strong>Step 2: Configure for the target chain</strong></p>
<p>The agent edits <code>config.yaml</code> to target the wstETH contract on Monad Mainnet. From the published blog: chain ID 143, contract <code>0x10Aeaf63194db8d453d4D85a06E5eFE1dd0b5417</code>, <code>start_block: 0</code>.</p>
<p>Then runs codegen and a type check:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> codegen</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> tsc </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--noEmit</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>Step 3: Push to GitHub on the deploy branch</strong></p>
<p>Envio Cloud deploys from the <code>envio</code> branch by default:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">gh repo create wsteth-monad-indexer-demo </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--public</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> init </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">.</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> commit </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-m</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"init"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-u</span><span class="token plain"> origin main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> checkout </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-b</span><span class="token plain"> envio </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-u</span><span class="token plain"> origin envio</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>Step 4: Connect the Envio GitHub App to the repo</strong></p>
<p>A one-time install at <a href="https://github.com/apps/envio-deployments/installations/select_target" target="_blank" rel="noopener noreferrer">github.com/apps/envio-deployments</a>. The app handles the actual deployment when commits land on the <code>envio</code> branch.</p>
<p><strong>Step 5: Register and deploy</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud login</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud indexer </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--name</span><span class="token plain"> wsteth-monad-indexer-demo </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--repo</span><span class="token plain"> wsteth-monad-indexer-demo </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--description</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"wstETH ERC20 indexer on Monad"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--branch</span><span class="token plain"> envio </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --skip-repo-check </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--yes</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><strong>Step 6: Verify</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud indexer get wsteth-monad-indexer-demo </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">org</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud deployment status wsteth-monad-indexer-demo </span><span class="token operator">&lt;</span><span class="token plain">commit-hash</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">org</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Once synced, the indexer is at <code>https://envio.dev/app/{org}/{indexer-name}/{commit-hash}</code>.</p>
<p><strong>Result: 400,000 events indexed in ~20 seconds.</strong></p>
<p>Every command above is taken directly from the published blog. Every flag exists. The flow is what this whole blog is arguing for, an agent that scaffolds, configures, deploys, and verifies an indexer end to end, with no human stepping in. The <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference indexer</a> is the production-scale reference for what this stack produces at full scale. The wstETH demo is the documented one-prompt run.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-this-beats-a-sql-warehouse-for-agentic-workflows">Why This Beats a SQL Warehouse for Agentic Workflows<a class="hash-link" aria-label="Direct link to Why This Beats a SQL Warehouse for Agentic Workflows" title="Direct link to Why This Beats a SQL Warehouse for Agentic Workflows" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#why-this-beats-a-sql-warehouse-for-agentic-workflows">​</a></h2>
<p>A SQL warehouse fronted by an LLM is excellent for analysts. The agent reads a question, writes SQL, returns a number. The agent does not change the warehouse, does not deploy new ingestion, does not branch the schema.</p>
<p>An agent acting onchain needs the opposite. It needs to:</p>
<ul>
<li>Add a new contract to its data ingestion mid-session</li>
<li>Branch the schema to add a new entity type for a workflow it is exploring</li>
<li>Spin up a brand-new indexer for an opportunity it just discovered</li>
<li>Deploy to a hosted runtime and stream results back</li>
</ul>
<p>HyperIndex gives the agent that ability. The indexer is a project the agent owns, not a warehouse it queries. The same agent can have ten indexers running at any time, each tracking a different market. None of that is possible if the only interface is read-only SQL.</p>
<p>For analysts: SQL warehouses are the right tool. For agents acting on the data: an indexing framework is the right tool. Both can coexist. The case here is for the agent side, which is the side under-served by the current SQL-warehouse-plus-LLM consensus.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#get-started">​</a></h2>
<ul>
<li><a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">HyperIndex Quickstart with AI</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">Envio docs MCP server</a></li>
<li><a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">Agentic indexing case (400k events, 20s)</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">envio-cloud CLI reference</a></li>
<li><a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket production reference</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-do-ai-agents-acting-onchain-need-an-indexer-at-all">Why do AI agents acting onchain need an indexer at all?<a class="hash-link" aria-label="Direct link to Why do AI agents acting onchain need an indexer at all?" title="Direct link to Why do AI agents acting onchain need an indexer at all?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#why-do-ai-agents-acting-onchain-need-an-indexer-at-all">​</a></h3>
<p>Raw RPC has four problems for an agent: reorgs, no schema, low throughput, and per-chain quirks at multichain scale. An indexer addresses all four. HyperIndex addresses them at the framework level, with reorg-safe storage, structured GraphQL output, HyperSync throughput, and a single multichain config.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-envio-docs-mcp-server">What is the Envio docs MCP server?<a class="hash-link" aria-label="Direct link to What is the Envio docs MCP server?" title="Direct link to What is the Envio docs MCP server?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#what-is-the-envio-docs-mcp-server">​</a></h3>
<p>A Model Context Protocol server at <code>https://docs.envio.dev/mcp</code> that exposes the Envio docs as two tools, <code>docs_search</code> and <code>docs_fetch</code>. Configured into Claude Code, Cursor, or VS Code with one setup command. Announcement blog: <a href="https://docs.envio.dev/blog/envio-docs-mcp-server" target="_blank" rel="noopener noreferrer">Introducing the Envio Docs MCP Server</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-skills-ship-with-hyperindex">What skills ship with HyperIndex?<a class="hash-link" aria-label="Direct link to What skills ship with HyperIndex?" title="Direct link to What skills ship with HyperIndex?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#what-skills-ship-with-hyperindex">​</a></h3>
<p>HyperIndex projects scaffold a <code>.claude/skills/</code> directory that auto-discovers for Cursor, Claude Code, and Codex. The canonical templates ship 14 skill definitions covering <code>indexer-configuration</code>, <code>indexer-schema</code>, <code>indexer-handlers</code>, <code>indexer-factory</code> (dynamic contracts), <code>indexer-external-calls</code> (Effect API), <code>indexer-multichain</code>, <code>indexer-performance</code>, <code>indexer-blocks</code>, <code>indexer-transactions</code>, <code>indexer-traces</code>, <code>indexer-filters</code>, <code>indexer-wildcard</code>, <code>indexer-testing</code>, and <code>migrate-from-subgraph</code>. The full list lives at <a href="https://github.com/enviodev/hyperindex/tree/main/packages/cli/templates/static/shared/.claude/skills" target="_blank" rel="noopener noreferrer">the canonical skills directory</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-fast-can-an-ai-agent-deploy-a-hyperindex-indexer">How fast can an AI agent deploy a HyperIndex indexer?<a class="hash-link" aria-label="Direct link to How fast can an AI agent deploy a HyperIndex indexer?" title="Direct link to How fast can an AI agent deploy a HyperIndex indexer?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#how-fast-can-an-ai-agent-deploy-a-hyperindex-indexer">​</a></h3>
<p>The <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic indexing blog</a> documents a single-prompt flow that scaffolds, deploys, and runs an indexer covering 400,000 events on Monad in roughly 20 seconds.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-the-envio-cloud-cli-support-agent-driven-deploys">Does the envio-cloud CLI support agent-driven deploys?<a class="hash-link" aria-label="Direct link to Does the envio-cloud CLI support agent-driven deploys?" title="Direct link to Does the envio-cloud CLI support agent-driven deploys?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#does-the-envio-cloud-cli-support-agent-driven-deploys">​</a></h3>
<p>Yes. The CLI surface includes <code>envio-cloud login</code>, <code>envio-cloud indexer add</code>, <code>envio-cloud deployment status</code>, <code>envio-cloud deployment metrics</code>, <code>envio-cloud deployment promote</code>, with <code>-o json</code> on any command for parseable output. Deployments are GitHub-native: an agent commits to the <code>envio</code> branch and the registered indexer deploys automatically.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-hyperindex-differ-from-a-sql-warehouse-for-agents">How does HyperIndex differ from a SQL warehouse for agents?<a class="hash-link" aria-label="Direct link to How does HyperIndex differ from a SQL warehouse for agents?" title="Direct link to How does HyperIndex differ from a SQL warehouse for agents?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#how-does-hyperindex-differ-from-a-sql-warehouse-for-agents">​</a></h3>
<p>A SQL warehouse is a read-only query layer. HyperIndex is a programmable indexer the agent can own, branch, and deploy. Both have a place. SQL warehouses suit analytical workflows. Indexers suit agents that need to act, not just query.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-chains-does-hyperindex-support-for-ai-agents">What chains does HyperIndex support for AI agents?<a class="hash-link" aria-label="Direct link to What chains does HyperIndex support for AI agents?" title="Direct link to What chains does HyperIndex support for AI agents?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#what-chains-does-hyperindex-support-for-ai-agents">​</a></h3>
<p>Any EVM chain. <!-- -->87+<!-- --> have native HyperSync coverage for maximum speed. Any EVM chain without native HyperSync is accessible via standard RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-hyperindex-handle-reorgs-for-agents">How does HyperIndex handle reorgs for agents?<a class="hash-link" aria-label="Direct link to How does HyperIndex handle reorgs for agents?" title="Direct link to How does HyperIndex handle reorgs for agents?" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#how-does-hyperindex-handle-reorgs-for-agents">​</a></h3>
<p>At the framework level. Entity state history is persisted for unfinalized blocks. The framework rolls back automatically on reorg. No handler code is required.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/ai-agents-acting-onchain-indexer#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[Build an AI-Powered App with HyperIndex and Claude]]></title>
            <link>https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude</link>
            <guid>https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude</guid>
            <pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[End-to-end tutorial: scaffold, deploy, and run a multichain HyperIndex indexer with Claude. Real config, real handlers, real CLI, real GraphQL.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/ai-onchain-app-hyperindex-claude.png" alt="Build an AI-Powered App with HyperIndex and Claude" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. With Claude Code pointed at a HyperIndex project, the agent has the docs (via the docs MCP server) and the patterns (via the auto-discovered <code>.claude/skills/</code> directory shipped with every v3 rc project) to scaffold, code, deploy, and run an indexer end to end.</li>
<li>The CLI surface is <code>pnpx envio init</code> for scaffold, <code>TUI_OFF=true pnpm dev</code> for local, and the GitHub-native <code>envio-cloud indexer add</code> flow for hosted deployments. Every command is scriptable and agent-friendly.</li>
<li>The Polymarket reference at <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a> is the public production example. 8 subgraphs replaced with 1; the first 4,000,000,000 events synced in 6 days, over 6,500,000,000 indexed to date.</li>
<li>Anything in this blog is reproducible today against the current HyperIndex release tracked at <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">github.com/enviodev/hyperindex/releases</a>.</li>
</ul></div></div>
<p>This is a practical, end-to-end walkthrough of building a HyperIndex indexer with Claude as a pair programmer. Every command is from the published Envio docs. Every code shape is taken directly from the public Polymarket reference indexer. The aim is to show the shortest reliable path from a blank project to a deployed multichain indexer that an engineer (or an agent) can actually run today.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-youre-building">What You're Building<a class="hash-link" aria-label="Direct link to What You're Building" title="Direct link to What You're Building" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#what-youre-building">​</a></h2>
<p>A multichain HyperIndex indexer that tracks ERC20 transfers across two chains (Ethereum and Base) and exposes the data through a GraphQL endpoint. Two contracts, one schema, one config, deployed to <a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">Envio Cloud</a> and queryable in roughly 30 minutes if you are reading along, or roughly 5 minutes if Claude is driving.</p>
<p>The structure of the project will be three files plus generated TypeScript:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">my-erc20-indexer/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  config.yaml          # Networks, contracts, events</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  schema.graphql       # Entity model</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  src/EventHandlers.ts # The handler logic</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Source for the three-file structure: <a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperIndex/quickstart-with-ai</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-0-wire-up-claude">Step 0: Wire Up Claude<a class="hash-link" aria-label="Direct link to Step 0: Wire Up Claude" title="Direct link to Step 0: Wire Up Claude" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-0-wire-up-claude">​</a></h2>
<p>Once. Then never again. The Envio <a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">docs MCP server</a> exposes the live docs to any MCP-capable agent. From the docs MCP server reference, the setup commands are:</p>
<p>For Claude Code:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">claude mcp </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--transport</span><span class="token plain"> http envio-docs https://docs.envio.dev/mcp</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>For Cursor or VS Code, drop this into the MCP config:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"mcpServers"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"envio-docs"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"url"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://docs.envio.dev/mcp"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"transport"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"http"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>After this, Claude has two tools available in any session: <code>docs_search</code> (semantic search) and <code>docs_fetch</code> (retrieve a page). The agent uses these instead of guessing at API surface from training data.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-1-scaffold-the-project">Step 1: Scaffold the Project<a class="hash-link" aria-label="Direct link to Step 1: Scaffold the Project" title="Direct link to Step 1: Scaffold the Project" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-1-scaffold-the-project">​</a></h2>
<p>Use the template flow to scaffold an ERC20 indexer in one non-interactive command.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio@3.0.0-rc.0 init template </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-t</span><span class="token plain"> erc20 </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-l</span><span class="token plain"> typescript </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-d</span><span class="token plain"> ./my-indexer --api-token </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This pulls the current HyperIndex v3 release candidate, which ships with the V3 testing framework, the built-in <code>.claude/skills/</code> directory, and the current CLI flags. The current release is tracked at <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">github.com/enviodev/hyperindex/releases</a>.</p>
<p>The <code>--api-token ""</code> flag tells the init to run non-interactively, with no prompt for an Etherscan-style API token. If an agent is driving, every interactive prompt is a failure mode.</p>
<p>The init produces the three files plus a <code>package.json</code>, <code>tsconfig.json</code>, an <code>AGENTS.md</code> and <code>CLAUDE.md</code> documenting the conventions, and an auto-discovered <code>.claude/skills/</code> directory. Every project scaffolded with v3 rc ships these skills out of the box, encoding the indexing patterns Claude needs to write idiomatic HyperIndex code without improvising.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-2-make-it-multichain">Step 2: Make It Multichain<a class="hash-link" aria-label="Direct link to Step 2: Make It Multichain" title="Direct link to Step 2: Make It Multichain" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-2-make-it-multichain">​</a></h2>
<p>The init scaffolds for one chain. Adding a second is a config edit, not a fresh project. Open <code>config.yaml</code> and add a second chain entry. The shape mirrors the public <a href="https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml" target="_blank" rel="noopener noreferrer">Polymarket config</a>. HyperIndex uses two-tier declaration. Top-level <code>contracts:</code> for global event signatures, then a <code>chains:</code> array for per-chain addresses and start blocks.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># Pattern from: https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># yaml-language-server: $schema=./node_modules/envio/evm.schema.json</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> erc20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">multichain</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> USDC</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Transfer(address indexed from, address indexed to, uint256 value)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">field_selection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">transaction_fields</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> hash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> from</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> to</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">chains</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">17000000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> USDC</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">8453</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">2000000</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> USDC</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Three things to call out:</p>
<ul>
<li><code>chains:</code> is the keyword, not <code>networks:</code>. Per the AGENTS.md generated into every HyperIndex project: "Uses chains (not networks)." If your editor or an AI agent suggests <code>networks:</code>, the schema validation will fail.</li>
<li>The <code>handler:</code> field is optional. Handlers auto-register from <code>src/handlers/</code>. Same AGENTS.md.</li>
<li><code>field_selection</code> controls which transaction fields HyperSync ships down. Asking for fewer fields is faster and uses less memory.</li>
</ul>
<p>For the current set of supported config options including per-contract <code>start_block</code> and environment variable interpolation, the full <a href="https://docs.envio.dev/docs/HyperIndex/configuration-file" target="_blank" rel="noopener noreferrer">configuration reference</a> lives in the docs.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-3-the-schema">Step 3: The Schema<a class="hash-link" aria-label="Direct link to Step 3: The Schema" title="Direct link to Step 3: The Schema" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-3-the-schema">​</a></h2>
<p>Edit <code>schema.graphql</code> to model entities the application will query. The shape uses a <code>chainId</code>-first pattern (per-chain entities plus aggregated entities) for clean cross-chain queries:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># Pattern from: https://github.com/enviodev/polymarket-indexer/blob/main/schema.graphql</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">Transfer</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token attr-name" style="color:rgb(241, 250, 140)">fields</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"from"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"timestamp"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"DESC"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token attr-name" style="color:rgb(241, 250, 140)">fields</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"to"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"timestamp"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"DESC"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token class-name">BigInt</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">chainId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">blockNumber</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">AccountBalance</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">chainId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">balance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token class-name">BigInt</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">lastUpdated</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">AggregateBalance</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function" style="color:rgb(80, 250, 123)">@index</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">totalAcrossChains</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token class-name">BigInt</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token attr-name" style="color:rgb(241, 250, 140)">lastUpdated</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Two HyperIndex-specific things worth noting in this schema:</p>
<ul>
<li>No <code>@entity</code> decorator. From the project's <code>AGENTS.md</code>: "Unlike TheGraph, schema types have no decorators." Subgraphs put <code>@entity</code> on every type. HyperIndex does not.</li>
<li><code>@index</code> is composable. The <a href="https://github.com/enviodev/polymarket-indexer/blob/main/schema.graphql" target="_blank" rel="noopener noreferrer">Polymarket schema</a> uses both per-field <code>@index</code> and per-type composite indexes like <code>@index(fields: ["from", ["timestamp", "DESC"]])</code> to drive the queries the application needs.</li>
</ul>
<p><code>Transfer</code> carries every transfer event with <code>chainId</code> first-class. <code>AccountBalance</code> is per-chain. <code>AggregateBalance</code> is the cross-chain rollup. The same indexer writes to all three.</p>
<p>After editing the schema, run <code>pnpm codegen</code> to regenerate the typed bindings. The project's <code>AGENTS.md</code> is explicit that codegen is required after any schema or config change. Types go stale otherwise.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-4-the-handler">Step 4: The Handler<a class="hash-link" aria-label="Direct link to Step 4: The Handler" title="Direct link to Step 4: The Handler" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-4-the-handler">​</a></h2>
<p>In v3 rc, types come from the <code>envio</code> package directly. The handler imports <code>indexer</code> plus any entity types it needs, then registers handlers as <code>indexer.onEvent({ contract: "CONTRACT_NAME", event: "EVENT_NAME" }, handler)</code>.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  indexer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">Transfer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">AccountBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"envio"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">onEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> contract</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"USDC"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> event</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Transfer"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> transferId </span><span class="token operator">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">chainId</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">block</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">number</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">logIndex</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> transfer</span><span class="token operator">:</span><span class="token plain"> Transfer </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      id</span><span class="token operator">:</span><span class="token plain"> transferId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      from</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      to</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      value</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      chainId</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">chainId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      blockNumber</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      timestamp</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Transfer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">transfer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> fromKey </span><span class="token operator">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">chainId</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">params</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">from</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> toKey </span><span class="token operator">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">chainId</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">params</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">to</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> fromBal</span><span class="token operator">:</span><span class="token plain"> AccountBalance </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AccountBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">fromKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      id</span><span class="token operator">:</span><span class="token plain"> fromKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      account</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      chainId</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">chainId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      balance</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AccountBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token operator">...</span><span class="token plain">fromBal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      balance</span><span class="token operator">:</span><span class="token plain"> fromBal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">balance </span><span class="token operator">-</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> toBal</span><span class="token operator">:</span><span class="token plain"> AccountBalance </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AccountBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">toKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      id</span><span class="token operator">:</span><span class="token plain"> toKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      account</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      chainId</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">chainId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      balance</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AccountBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token operator">...</span><span class="token plain">toBal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      balance</span><span class="token operator">:</span><span class="token plain"> toBal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">balance </span><span class="token operator">+</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> fromAgg</span><span class="token operator">:</span><span class="token plain"> AggregateBalance </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      id</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      account</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      totalAcrossChains</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token operator">...</span><span class="token plain">fromAgg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      totalAcrossChains</span><span class="token operator">:</span><span class="token plain"> fromAgg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">totalAcrossChains </span><span class="token operator">-</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> toAgg</span><span class="token operator">:</span><span class="token plain"> AggregateBalance </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      id</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      account</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      totalAcrossChains</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token operator">...</span><span class="token plain">toAgg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      totalAcrossChains</span><span class="token operator">:</span><span class="token plain"> toAgg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">totalAcrossChains </span><span class="token operator">+</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      lastUpdated</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Three project-enforced conventions visible in this snippet, all spelled out in the <code>AGENTS.md</code> generated into every HyperIndex project:</p>
<ul>
<li><strong>Spread operator for updates.</strong> Entities returned by <code>context.Entity.get()</code> are read-only. Always spread: <code>context.Entity.set({ ...existing, field: newValue })</code>. Direct mutation throws.</li>
<li><strong>Composite IDs for cross-chain uniqueness.</strong> <code>${event.chainId}_${event.block.number}_${event.logIndex}</code> is the Polymarket pattern. Without <code>chainId</code> in the ID, two chains writing the same <code>(block, logIndex)</code> collide.</li>
<li><strong>Effect API for any external call.</strong> If the handler needs to fetch Gamma metadata, call an RPC, or hit any other async I/O, use <code>createEffect</code> plus <code>context.effect()</code>. Never call external services directly. The Polymarket <code>TokenRegistered</code> handler shows the pattern with <code>context.effect(getMarketMetadata, token0Str)</code>.</li>
</ul>
<p>This is the structure an agent with the <code>indexer-handlers</code> and <code>indexer-external-calls</code> skills produces when asked to "write the Transfer handler that updates per-chain and aggregate balances." The skills encode these conventions so the agent does not improvise them wrongly.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-5-run-it-locally">Step 5: Run It Locally<a class="hash-link" aria-label="Direct link to Step 5: Run It Locally" title="Direct link to Step 5: Run It Locally" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-5-run-it-locally">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> codegen          </span><span class="token comment" style="color:rgb(98, 114, 164)"># regenerate types from schema + config</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> tsc </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--noEmit</span><span class="token plain">     </span><span class="token comment" style="color:rgb(98, 114, 164)"># type-check without emitting</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">TUI_OFF</span><span class="token operator">=</span><span class="token plain">true </span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> dev </span><span class="token comment" style="color:rgb(98, 114, 164)"># run indexer (TUI_OFF gives AI-friendly stdout)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Source for these exact commands: <a href="https://github.com/enviodev/polymarket-indexer/blob/main/AGENTS.md" target="_blank" rel="noopener noreferrer">polymarket-indexer/AGENTS.md</a>.</p>
<p>The local dev environment spins up a Postgres and a Hasura GraphQL instance. The indexer starts pulling events from both chains via HyperSync. Sync rates of 25,000 events per second on historical backfill are standard. The <a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" target="_blank" rel="noopener noreferrer">Polymarket case study</a> documents 4,000,000,000 events synced in 6 days on Polygon; the indexer has since indexed over 6,500,000,000 in total.</p>
<p>The Hasura GraphQL endpoint is available locally. Once the indexer is at chain head, queries like:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">query</span><span class="token plain"> </span><span class="token definition-query function" style="color:rgb(80, 250, 123)">AggregateBalanceForAccount</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property-query">AggregateBalance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token attr-name" style="color:rgb(241, 250, 140)">where</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token attr-name" style="color:rgb(241, 250, 140)">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token attr-name" style="color:rgb(241, 250, 140)">_eq</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xabc..."</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">account</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">totalAcrossChains</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">lastUpdated</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>return live data.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-6-deploy-to-envio-cloud">Step 6: Deploy to Envio Cloud<a class="hash-link" aria-label="Direct link to Step 6: Deploy to Envio Cloud" title="Direct link to Step 6: Deploy to Envio Cloud" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-6-deploy-to-envio-cloud">​</a></h2>
<p>Envio Cloud uses a GitHub-native deploy model. An agent commits the indexer to a GitHub repo, pushes to the <code>envio</code> branch (the default deploy branch), and registers the indexer with <code>envio-cloud indexer add</code>. The Envio GitHub App handles deployments from there. No deploy button, no dashboard step.</p>
<p>Install the CLI and authenticate:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">npm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-g</span><span class="token plain"> envio-cloud</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">envio-cloud login</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Push the project to GitHub on the <code>envio</code> branch:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">gh repo create my-erc20-indexer </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--public</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> init </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">.</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> commit </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-m</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"init"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-u</span><span class="token plain"> origin main</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> checkout </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-b</span><span class="token plain"> envio </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-u</span><span class="token plain"> origin envio</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Connect the Envio GitHub App to the repo (one-time install at <a href="https://github.com/apps/envio-deployments/installations/select_target" target="_blank" rel="noopener noreferrer">github.com/apps/envio-deployments</a>), then register the indexer:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">envio-cloud indexer </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--name</span><span class="token plain"> my-erc20-indexer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--repo</span><span class="token plain"> my-erc20-indexer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--description</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Multichain ERC20 indexer"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--branch</span><span class="token plain"> envio </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --skip-repo-check </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--yes</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The verified CLI surface (from the <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic indexing blog</a>) includes:</p>
<ul>
<li><code>envio-cloud login</code> authenticates via GitHub</li>
<li><code>envio-cloud indexer add</code> registers a new indexer pointing at a GitHub repo and branch</li>
<li><code>envio-cloud indexer get</code> fetches indexer details</li>
<li><code>envio-cloud deployment status</code> returns the current sync state of a deployment</li>
<li><code>envio-cloud deployment metrics</code> returns runtime metrics</li>
<li><code>envio-cloud deployment promote</code> promotes a deployment to production</li>
<li><code>-o json</code> on any command for parseable output</li>
</ul>
<p>Track sync progress with <code>envio-cloud deployment status</code> and <code>envio-cloud deployment metrics</code>. Full reference at <a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperIndex/envio-cloud-cli</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="step-7-test-it">Step 7: Test It<a class="hash-link" aria-label="Direct link to Step 7: Test It" title="Direct link to Step 7: Test It" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#step-7-test-it">​</a></h2>
<p><code>pnpm test</code> runs the project's Vitest suite. In v3 rc, tests import <code>createTestIndexer</code> and <code>TestHelpers</code> from the <code>envio</code> package directly, so tests use the same types as handlers. The <code>indexer-testing</code> skill in <code>.claude/skills/</code> encodes the current API surface (mock event factories, test indexer setup, assertion patterns) and the <a href="https://docs.envio.dev/docs/HyperIndex/testing" target="_blank" rel="noopener noreferrer">testing reference docs</a> cover it end to end.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-the-stack-looks-like-end-to-end">What the Stack Looks Like End to End<a class="hash-link" aria-label="Direct link to What the Stack Looks Like End to End" title="Direct link to What the Stack Looks Like End to End" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#what-the-stack-looks-like-end-to-end">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[Claude Code or Cursor]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         | (reads docs via MCP server, applies built-in Claude skills)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[HyperIndex Project (config.yaml + schema.graphql + handlers)]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         | (pnpm dev locally, or push to GitHub envio branch)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[HyperIndex Runtime + HyperSync]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         | (live indexes EVM chains natively, any EVM via RPC)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[Postgres + Hasura GraphQL endpoint]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         | (queried by application, dashboard, agent, or downstream service)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">         v</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[Your AI-Powered Onchain App]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Each layer is a piece you have full control over. None of them require black-box assumptions about how an indexer behaves under reorgs, source outages, or scale. The <a href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex" target="_blank" rel="noopener noreferrer">reliability blog</a> covers what HyperIndex provides at the framework level.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#get-started">​</a></h2>
<ul>
<li><a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">HyperIndex Quickstart with AI</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">Envio docs MCP server</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">envio-cloud CLI reference</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/configuration-file" target="_blank" rel="noopener noreferrer">config.yaml reference</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/testing" target="_blank" rel="noopener noreferrer">Testing docs (V3 framework)</a></li>
<li><a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket production reference</a></li>
<li><a href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude" target="_blank" rel="noopener noreferrer">Companion: AI-assisted subgraph migration</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-does-an-ai-powered-onchain-app-stack-look-like">What does an AI-powered onchain app stack look like?<a class="hash-link" aria-label="Direct link to What does an AI-powered onchain app stack look like?" title="Direct link to What does an AI-powered onchain app stack look like?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#what-does-an-ai-powered-onchain-app-stack-look-like">​</a></h3>
<p>The stack is: Claude Code (or another MCP-aware editor) as the development surface, a HyperIndex project with an auto-discovered <code>.claude/skills/</code> directory shipped by v3 rc, the HyperIndex runtime with HyperSync as the data engine, Postgres plus Hasura for GraphQL, and the application or agent on top. Every layer is real and shipping today.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-deploy-a-hyperindex-indexer-programmatically">How do I deploy a HyperIndex indexer programmatically?<a class="hash-link" aria-label="Direct link to How do I deploy a HyperIndex indexer programmatically?" title="Direct link to How do I deploy a HyperIndex indexer programmatically?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#how-do-i-deploy-a-hyperindex-indexer-programmatically">​</a></h3>
<p>Install the envio-cloud CLI with <code>npm install -g envio-cloud</code> and authenticate with <code>envio-cloud login</code>. Push the indexer code to a GitHub repo on the <code>envio</code> branch, connect the Envio GitHub App to the repo, then register with <code>envio-cloud indexer add</code>. Track sync state with <code>envio-cloud deployment status</code> and <code>envio-cloud deployment metrics</code>. Every command supports <code>-o json</code> for parseable output. Full reference at <a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperIndex/envio-cloud-cli</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-add-a-chain-to-a-hyperindex-indexer-without-redeploying">Can I add a chain to a HyperIndex indexer without redeploying?<a class="hash-link" aria-label="Direct link to Can I add a chain to a HyperIndex indexer without redeploying?" title="Direct link to Can I add a chain to a HyperIndex indexer without redeploying?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#can-i-add-a-chain-to-a-hyperindex-indexer-without-redeploying">​</a></h3>
<p>Adding a chain requires a config change and a redeploy because the indexer needs to start a new HyperSync stream. The redeploy itself is one CLI command. Adding a contract on an existing chain that uses the factory pattern can be done dynamically without a redeploy. See the <code>indexer-factory</code> skill in the project.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-hyperindex-compare-to-subgraphs-for-an-ai-workflow">How does HyperIndex compare to subgraphs for an AI workflow?<a class="hash-link" aria-label="Direct link to How does HyperIndex compare to subgraphs for an AI workflow?" title="Direct link to How does HyperIndex compare to subgraphs for an AI workflow?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#how-does-hyperindex-compare-to-subgraphs-for-an-ai-workflow">​</a></h3>
<p>Subgraphs use AssemblyScript handlers, single-chain config per subgraph, and matchstick for testing. HyperIndex uses TypeScript handlers, multichain config in one file, and Vitest for testing. The TypeScript surface is what makes Claude's involvement straightforward. The migration story is covered in <a href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude" target="_blank" rel="noopener noreferrer">AI-assisted subgraph migration</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-are-the-built-in-hyperindex-skills">What are the built-in HyperIndex skills?<a class="hash-link" aria-label="Direct link to What are the built-in HyperIndex skills?" title="Direct link to What are the built-in HyperIndex skills?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#what-are-the-built-in-hyperindex-skills">​</a></h3>
<p>HyperIndex projects scaffolded with v3 rc ship a <code>.claude/skills/</code> directory pre-populated with 14 skills covering the core indexing patterns: <code>indexer-configuration</code>, <code>indexer-schema</code>, <code>indexer-handlers</code>, <code>indexer-factory</code>, <code>indexer-multichain</code>, <code>indexer-external-calls</code>, <code>indexer-performance</code>, <code>indexer-testing</code>, <code>indexer-blocks</code>, <code>indexer-filters</code>, <code>indexer-traces</code>, <code>indexer-transactions</code>, <code>indexer-wildcard</code>, and <code>migrate-from-subgraph</code>. Claude Code auto-discovers them at session start.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-hyperindex-faster-than-other-indexers-in-benchmarks">Is HyperIndex faster than other indexers in benchmarks?<a class="hash-link" aria-label="Direct link to Is HyperIndex faster than other indexers in benchmarks?" title="Direct link to Is HyperIndex faster than other indexers in benchmarks?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#is-hyperindex-faster-than-other-indexers-in-benchmarks">​</a></h3>
<p>In Sentio's independent Uniswap V2 Factory benchmark, HyperIndex completed in 8 seconds, 142x faster than The Graph and 15x faster than the nearest competitor.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-chains-are-supported">What chains are supported?<a class="hash-link" aria-label="Direct link to What chains are supported?" title="Direct link to What chains are supported?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#what-chains-are-supported">​</a></h3>
<p>Any EVM chain. <!-- -->87+<!-- --> have native HyperSync coverage for maximum speed. Any EVM chain without native HyperSync is accessible via standard RPC. The current chain count is published on <a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">envio.dev</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="where-can-i-see-a-public-production-reference">Where can I see a public production reference?<a class="hash-link" aria-label="Direct link to Where can I see a public production reference?" title="Direct link to Where can I see a public production reference?" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#where-can-i-see-a-public-production-reference">​</a></h3>
<p>The <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference indexer</a>. Synced its first 4,000,000,000 events from block 3,764,531 in 6 days, replacing 8 separate subgraphs, and has indexed over 6,500,000,000 to date. Live at <a href="https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad" target="_blank" rel="noopener noreferrer">envio.dev/app/moose-code/polymarket-indexer/7cad3ad</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/ai-onchain-app-hyperindex-claude#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[AI-Assisted Subgraph Migration to HyperIndex with Claude]]></title>
            <link>https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude</link>
            <guid>https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude</guid>
            <pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Migrate a subgraph from The Graph to Envio HyperIndex with Claude doing the AssemblyScript-to-TypeScript rewrite. Real config, real handlers, real repo.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/ai-subgraph-migration-hyperindex-claude.png" alt="AI-Assisted Subgraph Migration to HyperIndex with Claude" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. It accepts subgraph YAML and ABIs as input, scaffolds a HyperIndex project, and ships a TypeScript handler skeleton that AssemblyScript handler logic can be ported into.</li>
<li>Claude (running with the Envio docs MCP server and the auto-discovered <code>.claude/skills/</code> directory, including the dedicated <code>migrate-from-subgraph</code> skill) handles the AssemblyScript-to-TypeScript rewrite end to end. Skills auto-discover for Cursor, Claude Code, and Codex.</li>
<li>The Polymarket reference indexer is the public production-scale example: 8 subgraphs' worth of logic consolidated into one TypeScript indexer that synced its first 4,000,000,000 events in 6 days on Polygon and has indexed over 6,500,000,000 to date.</li>
</ul></div></div>
<p>The hardest part of migrating off The Graph to HyperIndex has always been the AssemblyScript rewrite. Subgraphs run handler code in WebAssembly, which means handlers are written in AssemblyScript, a stricter subset of TypeScript with its own constraints, its own tooling, and its own foot-guns. Teams who otherwise live in TypeScript every day end up maintaining one codebase in a language they touch only when their indexer breaks.</p>
<p>The HyperIndex reference indexer for Polymarket demonstrates the consolidation pattern at scale, 8 subgraphs' worth of logic rewritten as a single TypeScript indexer. The full reference is public on <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">GitHub</a> and is documented in our <a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" target="_blank" rel="noopener noreferrer">Polymarket case study</a>.</p>
<p>This blog is about how you can leverage Claude (or any coding agent) to migrate your subgraphs to HyperIndex. The agent does the AssemblyScript-to-TypeScript rewrite; a developer reviews the diff, runs the tests, and ships the indexer.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-hyperindex-is-and-why-the-migration-story-changed">What HyperIndex Is and Why the Migration Story Changed<a class="hash-link" aria-label="Direct link to What HyperIndex Is and Why the Migration Story Changed" title="Direct link to What HyperIndex Is and Why the Migration Story Changed" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#what-hyperindex-is-and-why-the-migration-story-changed">​</a></h2>
<p>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. HyperIndex handlers are written in regular TypeScript. Unlike AssemblyScript, which restricts which npm packages handlers can use, HyperIndex lets you bring in any npm package you want. Since handlers are TypeScript, there is no WebAssembly compilation step and no AssemblyScript-specific syntax to learn, you write handlers in the language you already use every day.</p>
<p>Two things changed in the last six months that turned subgraph migration into a tractable AI-assisted workflow:</p>
<ol>
<li>The <a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">HyperIndex docs MCP server</a> went live, exposing the entire docs site as two tools (<code>docs_search</code> and <code>docs_fetch</code>) over Streamable HTTP at <code>https://docs.envio.dev/mcp</code>. Any IDE or assistant that speaks MCP, including Claude Code, Cursor, Codex, and VS Code, can now ground answers about HyperIndex in the live docs rather than stale training data.</li>
<li>HyperIndex projects ship a <code>.claude/skills/</code> directory that auto-discovers for Cursor, Claude Code, and Codex. The Polymarket reference repo's directory currently ships 14 skills, including a dedicated <code>migrate-from-subgraph</code> skill purpose-built for this workflow, plus <code>indexer-configuration</code>, <code>indexer-schema</code>, <code>indexer-handlers</code>, <code>indexer-factory</code> (dynamic contracts), <code>indexer-external-calls</code> (the Effect API), <code>indexer-multichain</code>, <code>indexer-performance</code>, <code>indexer-testing</code>, <code>indexer-blocks</code>, <code>indexer-filters</code>, <code>indexer-traces</code>, <code>indexer-transactions</code>, and <code>indexer-wildcard</code>. The full list lives at <a href="https://github.com/enviodev/hyperindex/tree/main/packages/cli/templates/static/shared/.claude/skills" target="_blank" rel="noopener noreferrer">the canonical skills directory</a>.</li>
</ol>
<p>Combined, these mean a developer can hand the agent a subgraph repo and a working HyperIndex project shell and ask for a migration. The agent has live docs, a project-resident migration skill, and its own validation tooling.</p>
<p>The <a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" target="_blank" rel="noopener noreferrer">Polymarket case study</a> is the production reference for what the end state looks like. The rest of this post walks the AI-assisted version of that same migration on a smaller surface area, anchored to real artifacts in the Polymarket repo.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-four-files-claude-needs-to-see">The Four Files Claude Needs to See<a class="hash-link" aria-label="Direct link to The Four Files Claude Needs to See" title="Direct link to The Four Files Claude Needs to See" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#the-four-files-claude-needs-to-see">​</a></h2>
<p>Every subgraph has the same four primary inputs. Claude reads them in this order.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">my-subgraph/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  subgraph.yaml          # contracts, networks, event handlers, start blocks</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  schema.graphql         # entity types and relations</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  src/mappings/*.ts      # AssemblyScript handler logic (despite the .ts extension)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  abis/*.json            # contract ABIs the handlers parse logs against</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>subgraph.yaml</code> carries the network, the contract addresses, the start blocks, and the event-to-handler mapping. <code>schema.graphql</code> carries the entity model. The mappings carry the actual logic. The ABIs carry the signatures for the events mappings parse.</p>
<p>HyperIndex needs the same four kinds of input, restructured. The Polymarket reference shows the target shape. From <a href="https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml" target="_blank" rel="noopener noreferrer">the canonical config.yaml</a> (selected events shown for brevity):</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># Source: https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># yaml-language-server: $schema=./node_modules/envio/evm.schema.json</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> polymarket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">indexer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Unified Polymarket HyperIndex</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Exchange</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">abi_file_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./abis/Exchange.json</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrderFilled(bytes32 indexed orderHash, address indexed maker, address indexed taker, uint256 makerAssetId, uint256 takerAssetId, uint256 makerAmountFilled, uint256 takerAmountFilled, uint256 fee)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrdersMatched(...)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"TokenRegistered(...)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConditionalTokens</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">abi_file_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./abis/ConditionalTokens.json</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PositionSplit(...)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PositionsMerge(...)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PayoutRedemption(...)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">field_selection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">transaction_fields</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> hash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> from</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> to</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">chains</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">137</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)"># Polygon</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">3764531</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Exchange</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xC5d563A36AE78145C45a50134d48A1215220f80a"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">33605403</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConditionalTokens</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">4023686</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Three small differences from subgraph YAML to know up front: HyperIndex uses <code>chains:</code> (not <code>networks:</code>), declares contracts once at the top level with addresses supplied per-chain, and auto-registers handlers from <code>src/handlers/&lt;ContractName&gt;.ts</code> (subgraphs require explicit handler-to-event mapping).</p>
<p>This single file replaces what would otherwise be eight separate <code>subgraph.yaml</code> files. Every shared event (<code>PositionSplit</code>, <code>PositionsMerge</code>, <code>PayoutRedemption</code>) is declared once and routed to a single TypeScript handler that updates every relevant entity in one pass. That architectural detail, "handler merging," is the structural win of the consolidation pattern.</p>
<p><code>schema.graphql</code> carries across with two specific rewrites. Subgraph schemas decorate every type with <code>@entity</code>. HyperIndex schemas have no decorators, per the AGENTS.md: "Unlike TheGraph, schema types have no decorators." Subgraph relations like <code>@derivedFrom</code> are kept; ID conventions stay; the type body is otherwise identical. The built-in <code>indexer-schema</code> skill knows the diffs and applies them.</p>
<p>Handlers are where the migration work happens. The Polymarket reference repo's <a href="https://github.com/enviodev/polymarket-indexer/blob/main/src/handlers/Exchange.ts" target="_blank" rel="noopener noreferrer"><code>Exchange.ts</code></a> shows the canonical TypeScript shape and the conventions the <code>migrate-from-subgraph</code> skill applies (simplified for the post, helper functions inlined):</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// Source: https://github.com/enviodev/polymarket-indexer/blob/main/src/handlers/Exchange.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> Exchange</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">Orderbook</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"generated"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  parseOrderFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  updateUserPositionWithBuy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  updateUserPositionWithSell</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"../utils/pnl.js"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">COLLATERAL_SCALE</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"../utils/constants.js"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> scaleBigInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ZERO_BD</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"../utils/fpmm.js"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> getMarketMetadata </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"../effects/marketMetadata.js"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRADE_TYPE_BUY</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Buy"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRADE_TYPE_SELL</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Sell"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Exchange</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">OrderFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">handler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> side </span><span class="token operator">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">makerAssetId </span><span class="token operator">===</span><span class="token plain"> </span><span class="token number">0n</span><span class="token plain"> </span><span class="token operator">?</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRADE_TYPE_BUY</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRADE_TYPE_SELL</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> tokenId </span><span class="token operator">=</span><span class="token plain"> side </span><span class="token operator">===</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRADE_TYPE_BUY</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">?</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">takerAssetId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toString</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">makerAssetId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toString</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1. Persist the OrderFilled event (chainId in ID prevents cross-chain collisions)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">OrderFilledEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    id</span><span class="token operator">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">chainId</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">block</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">number</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">logIndex</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    transactionHash</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">transaction</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">hash</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    timestamp</span><span class="token operator">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">BigInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">timestamp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    orderHash</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">orderHash</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    maker</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">maker</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    taker</span><span class="token operator">:</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">taker</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// ... rest of the event</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// 2. Read-then-write Orderbook (spread mandatory, returned entities are read-only)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> orderbook </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Orderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tokenId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">??</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">defaultOrderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tokenId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Orderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">set</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">...</span><span class="token plain">orderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    tradesQuantity</span><span class="token operator">:</span><span class="token plain"> orderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">tradesQuantity </span><span class="token operator">+</span><span class="token plain"> </span><span class="token number">1n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    collateralVolume</span><span class="token operator">:</span><span class="token plain"> orderbook</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">collateralVolume </span><span class="token operator">+</span><span class="token plain"> size</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// 3. PnL update. Handler merged with what was previously a separate pnl subgraph</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> order </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">parseOrderFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">params</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">side </span><span class="token operator">===</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"BUY"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">updateUserPositionWithBuy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">positionId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> price</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">baseAmount</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">updateUserPositionWithSell</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">account</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">positionId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> price</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> order</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">baseAmount</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The same handler file also processes <code>OrdersMatched</code> and <code>TokenRegistered</code>. The <code>TokenRegistered</code> handler fetches Polymarket Gamma API metadata via the Effect API:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// Same source file, TokenRegistered handler</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> metadata </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">effect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">getMarketMetadata</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> token0Str</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>createEffect</code> plus <code>context.effect()</code> is the documented pattern for any external call (fetch, RPC, async I/O). From the project's <code>AGENTS.md</code>: "All <code>fetch</code>, RPC, or other async I/O must use <code>createEffect</code> + <code>context.effect()</code>. Never call external services directly in handlers."</p>
<p>The comparable AssemblyScript handler on The Graph would be split across three subgraph repos, each parsing the same OrderFilled log independently, each writing to its own subgraph database, with cross-domain joins happening at query time. Handler merging is the architectural reason the Polymarket reference consolidates 8 subgraphs into 1. It is also the thing that makes AssemblyScript handlers straightforward for an agent to translate: the event parsing is mechanical, the entity writes are explicit, and the conventions are documented in the project-resident skills.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-the-ai-assisted-migration-workflow-runs">How the AI-Assisted Migration Workflow Runs<a class="hash-link" aria-label="Direct link to How the AI-Assisted Migration Workflow Runs" title="Direct link to How the AI-Assisted Migration Workflow Runs" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#how-the-ai-assisted-migration-workflow-runs">​</a></h2>
<p>The flow assumes a developer with Claude Code or Cursor installed, the Envio docs MCP server configured, and the HyperIndex CLI on their machine. From the <a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">HyperIndex Quickstart with AI</a> the MCP setup is one command for Claude Code:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">claude mcp </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--transport</span><span class="token plain"> http envio-docs https://docs.envio.dev/mcp</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Cursor or VS Code uses the JSON config form on the same page. Once added, every Claude session in that workspace can query the live docs.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-1-scaffold-a-hyperindex-project-from-a-template">Step 1: Scaffold a HyperIndex project from a template<a class="hash-link" aria-label="Direct link to Step 1: Scaffold a HyperIndex project from a template" title="Direct link to Step 1: Scaffold a HyperIndex project from a template" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#step-1-scaffold-a-hyperindex-project-from-a-template">​</a></h3>
<p>Scaffold a fresh HyperIndex project using the template flow. Pass <code>--api-token ""</code> so the init runs non-interactively when an agent is driving:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio@3.0.0-rc.0 init template </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-t</span><span class="token plain"> erc20 </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-l</span><span class="token plain"> typescript </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-d</span><span class="token plain"> ./my-indexer --api-token </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This produces a working HyperIndex project shell with <code>config.yaml</code>, <code>schema.graphql</code>, handler stubs, an <code>AGENTS.md</code>, and the auto-discovered <code>.claude/skills/</code> directory (including the <code>migrate-from-subgraph</code> skill). The current release is tracked at <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">github.com/enviodev/hyperindex/releases</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-2-hand-claude-the-assemblyscript-mappings">Step 2: Hand Claude the AssemblyScript mappings<a class="hash-link" aria-label="Direct link to Step 2: Hand Claude the AssemblyScript mappings" title="Direct link to Step 2: Hand Claude the AssemblyScript mappings" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#step-2-hand-claude-the-assemblyscript-mappings">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">You: I just initialised a HyperIndex project and the /XYZ folder has my subgraph</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">could you help me migrate that to my HyperIndex project. The generated</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">config.yaml and schema.graphql are in place. The original AssemblyScript</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mappings are in ../old-subgraph/src/mappings/. Use the migrate-from-subgraph</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">skill to translate them into TypeScript handlers under src/handlers/. Apply the</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">project conventions in AGENTS.md: spread operator for entity updates, Effect</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">API for any external calls, entity_id fields for relationships. Flag anything</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">that uses nested entity loads or AssemblyScript-specific helpers so I can</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">review.</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Claude opens the migration skill, walks the mapping files in dependency order, and produces TypeScript handlers under <code>src/handlers/</code>. Every entity load and write is explicit. Every BigInt operation uses native JavaScript <code>BigInt</code> rather than the AssemblyScript <code>BigInt</code> class. Imports come from the auto-generated types, not from <code>@graphprotocol/graph-ts</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-3-run-the-indexer-locally-and-compare">Step 3: Run the indexer locally and compare<a class="hash-link" aria-label="Direct link to Step 3: Run the indexer locally and compare" title="Direct link to Step 3: Run the indexer locally and compare" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#step-3-run-the-indexer-locally-and-compare">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> dev</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The indexer comes up against a local Postgres and a Hasura GraphQL endpoint. The deployed subgraph endpoint and the local HyperIndex endpoint can be queried side by side for any entity at any block height. Claude knows how to write the comparison queries because the <code>indexer-testing</code> skill ships in the project.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-4-ship-to-envio-cloud">Step 4: Ship to Envio Cloud<a class="hash-link" aria-label="Direct link to Step 4: Ship to Envio Cloud" title="Direct link to Step 4: Ship to Envio Cloud" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#step-4-ship-to-envio-cloud">​</a></h3>
<p>Envio Cloud uses a GitHub-native deploy model. Push the indexer to a GitHub repo on the <code>envio</code> branch, connect the Envio GitHub App, and register the indexer with <code>envio-cloud indexer add</code>. The full flow from the <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic indexing blog</a>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">npm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-g</span><span class="token plain"> envio-cloud</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">envio-cloud login</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># push the migrated indexer to the envio branch</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> checkout </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-b</span><span class="token plain"> envio </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-u</span><span class="token plain"> origin envio</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># install the Envio GitHub App on the repo</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># https://github.com/apps/envio-deployments/installations/select_target</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># register the indexer</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">envio-cloud indexer </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--name</span><span class="token plain"> my-migrated-indexer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--repo</span><span class="token plain"> my-migrated-indexer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--description</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Subgraph migrated to HyperIndex"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--branch</span><span class="token plain"> envio </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --skip-repo-check </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--yes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># track sync state</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">envio-cloud deployment status my-migrated-indexer </span><span class="token operator">&lt;</span><span class="token plain">commit-hash</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">org</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Every command supports <code>-o json</code> for parseable output. The Polymarket reference indexer is live at <a href="https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad" target="_blank" rel="noopener noreferrer">envio.dev/app/moose-code/polymarket-indexer/7cad3ad</a>. Full CLI reference at <a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperIndex/envio-cloud-cli</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-the-ai-catches-and-what-it-doesnt">What the AI Catches and What It Doesn't<a class="hash-link" aria-label="Direct link to What the AI Catches and What It Doesn't" title="Direct link to What the AI Catches and What It Doesn't" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#what-the-ai-catches-and-what-it-doesnt">​</a></h2>
<p>After running this workflow on smaller subgraphs internally, here is the honest split.</p>
<p>Claude is reliably good at:</p>
<ul>
<li>Translating event parsing and entity writes (the bulk of any handler)</li>
<li>Replacing AssemblyScript <code>BigInt</code> with native JS <code>BigInt</code></li>
<li>Replacing <code>@graphprotocol/graph-ts</code> imports with the HyperIndex generated types</li>
<li>Stripping the <code>@entity</code> decorator from every schema type (HyperIndex schemas have no decorators per AGENTS.md)</li>
<li>Applying the spread operator pattern on entity updates (mandatory in HyperIndex, returned entities are read-only)</li>
<li>Wrapping any external call from a mapping in <code>createEffect</code> plus <code>context.effect()</code> (the Effect API)</li>
<li>Generating the matching test cases against the Vitest framework HyperIndex ships with</li>
</ul>
<p>Claude needs human review on:</p>
<ul>
<li><strong>Cross-handler shared state.</strong> Subgraphs sometimes encode shared state in entity IDs in ways that look fine until two handlers race at the same block. Handler merging in HyperIndex usually fixes this, but the migration is the moment to redesign it consciously.</li>
</ul>
<p>A migration that runs all four steps with Claude driving and a developer reviewing typically turns a multi-week AssemblyScript rewrite into a one or two day exercise. The Polymarket reference is the upper bound: 8 subgraphs' worth of logic, 50+ entities, four years of handler history. Smaller subgraphs are correspondingly faster.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-migrate-at-all-the-numbers">Why Migrate at All: The Numbers<a class="hash-link" aria-label="Direct link to Why Migrate at All: The Numbers" title="Direct link to Why Migrate at All: The Numbers" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#why-migrate-at-all-the-numbers">​</a></h2>
<p>The reason teams move off The Graph is performance and developer experience. From the public benchmarks:</p>
<table><thead><tr><th>Indexer</th><th>Time (Sentio Uniswap V2 Factory benchmark)</th><th>vs HyperIndex</th></tr></thead><tbody><tr><td>Envio HyperIndex</td><td>8 seconds</td><td>baseline</td></tr><tr><td>Subsquid (SQD)</td><td>2 minutes</td><td>15x slower</td></tr><tr><td>The Graph</td><td>19 minutes</td><td>142x slower</td></tr><tr><td>Ponder</td><td>21 minutes</td><td>157x slower</td></tr></tbody></table>
<p>Full benchmark comparison at <a href="https://docs.envio.dev/docs/HyperIndex/benchmarks" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperIndex/benchmarks</a>.</p>
<p>Polymarket's full historical sync, 4,000,000,000 events on Polygon, completed in 6 days, and the indexer has since indexed over 6,500,000,000 events in total. The same workload on a single subgraph in the Polymarket setup would have been measured in months and would still leave eight separate APIs to query.</p>
<p>Speed is one half of the story. Developer experience is the other. TypeScript handlers, native npm package use, generated types, real test runners, multichain configuration in a single file, dynamic contract registration without redeployment. Once a team has been on HyperIndex for a sprint, the subgraph workflow stops feeling like a viable alternative.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-long-does-an-ai-assisted-subgraph-migration-to-hyperindex-take">How long does an AI-assisted subgraph migration to HyperIndex take?<a class="hash-link" aria-label="Direct link to How long does an AI-assisted subgraph migration to HyperIndex take?" title="Direct link to How long does an AI-assisted subgraph migration to HyperIndex take?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#how-long-does-an-ai-assisted-subgraph-migration-to-hyperindex-take">​</a></h3>
<p>For a single-domain subgraph with one or two contracts, the AI-assisted workflow with Claude typically runs in a few hours. For a complex multi-domain setup at the scale of the Polymarket reference (8 subgraphs' worth of logic, 50+ entities, four years of handler history), the migration with Claude assistance runs in days, not weeks. The bulk of the time is human review, not generation.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-hyperindex-support-every-subgraph-schema-directive">Does HyperIndex support every subgraph schema directive?<a class="hash-link" aria-label="Direct link to Does HyperIndex support every subgraph schema directive?" title="Direct link to Does HyperIndex support every subgraph schema directive?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#does-hyperindex-support-every-subgraph-schema-directive">​</a></h3>
<p>Most directives carry across. <code>@derivedFrom</code> and ID-based relations have direct HyperIndex equivalents. The biggest difference is decorators: HyperIndex schemas have no <code>@entity</code> decorator at all. Per the project's <code>AGENTS.md</code>: "Unlike TheGraph, schema types have no decorators." The <code>indexer-schema</code> skill knows the translations and the <code>migrate-from-subgraph</code> skill applies them. Anything without a direct equivalent gets flagged for manual handling.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-migrate-an-alchemy-subgraph-the-same-way">Can I migrate an Alchemy subgraph the same way?<a class="hash-link" aria-label="Direct link to Can I migrate an Alchemy subgraph the same way?" title="Direct link to Can I migrate an Alchemy subgraph the same way?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#can-i-migrate-an-alchemy-subgraph-the-same-way">​</a></h3>
<p>Yes. Alchemy Subgraphs are technically subgraphs, and the same AI-assisted migration flow described in this blog applies, scaffold a HyperIndex project from a template, hand Claude the AssemblyScript mappings, validate locally, and ship.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-if-my-subgraph-uses-dynamic-contracts-factory-pattern">What if my subgraph uses dynamic contracts (factory pattern)?<a class="hash-link" aria-label="Direct link to What if my subgraph uses dynamic contracts (factory pattern)?" title="Direct link to What if my subgraph uses dynamic contracts (factory pattern)?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#what-if-my-subgraph-uses-dynamic-contracts-factory-pattern">​</a></h3>
<p>HyperIndex supports dynamic contract registration as a first-class feature. Polymarket uses it for FPMM pools created by <code>FPMMFactory</code>. The <code>indexer-factory</code> skill in <code>.claude/skills/</code> handles the translation. See the Polymarket reference handler at <a href="https://github.com/enviodev/polymarket-indexer/blob/main/src/handlers/FPMMFactory.ts" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer/blob/main/src/handlers/FPMMFactory.ts</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-validate-that-the-migrated-indexer-matches-the-original-subgraph">How do I validate that the migrated indexer matches the original subgraph?<a class="hash-link" aria-label="Direct link to How do I validate that the migrated indexer matches the original subgraph?" title="Direct link to How do I validate that the migrated indexer matches the original subgraph?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#how-do-i-validate-that-the-migrated-indexer-matches-the-original-subgraph">​</a></h3>
<p>Run both endpoints side by side and query the same entity at the same block. The <code>indexer-testing</code> skill in <code>.claude/skills/</code> generates the comparison queries. For production migrations, Envio also provides a CLI validation tool that diffs entity state across both endpoints over a block range. The <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference repo</a> is the public production example to compare your migrated output against.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-the-ai-workflow-work-without-claude">Does the AI workflow work without Claude?<a class="hash-link" aria-label="Direct link to Does the AI workflow work without Claude?" title="Direct link to Does the AI workflow work without Claude?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#does-the-ai-workflow-work-without-claude">​</a></h3>
<p>Yes. Skills in <code>.claude/skills/</code> auto-discover for Cursor, Claude Code, and Codex per the project's <code>CLAUDE.md</code>. The docs MCP server is MCP-standard so any MCP-capable agent works. The setup commands on the <a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">Quickstart with AI</a> page cover Claude Code, Cursor, and VS Code explicitly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-does-hyperindex-do-that-subgraphs-do-not">What does HyperIndex do that subgraphs do not?<a class="hash-link" aria-label="Direct link to What does HyperIndex do that subgraphs do not?" title="Direct link to What does HyperIndex do that subgraphs do not?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#what-does-hyperindex-do-that-subgraphs-do-not">​</a></h3>
<p>Single multichain config (subgraphs are single-chain). Native TypeScript handlers (subgraphs require AssemblyScript). 142x faster sync on the Sentio Uniswap V2 Factory benchmark. Framework-level reorg handling with no handler logic required. Self-hostable or deployed to Envio Cloud with a GitHub-native flow (<code>envio-cloud indexer add</code> against an <code>envio</code> branch).</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="where-is-the-production-reference-for-a-large-subgraph-migration">Where is the production reference for a large subgraph migration?<a class="hash-link" aria-label="Direct link to Where is the production reference for a large subgraph migration?" title="Direct link to Where is the production reference for a large subgraph migration?" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#where-is-the-production-reference-for-a-large-subgraph-migration">​</a></h3>
<p>The <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket HyperIndex reference indexer</a>. 8 subgraphs' worth of logic consolidated into one indexer, with the first 4,000,000,000 events synced in 6 days and over 6,500,000,000 indexed to date. The full repo is public on GitHub and the case study can be found in <a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" target="_blank" rel="noopener noreferrer">our blog</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#get-started">​</a></h2>
<p>Migration starts with two things: an existing subgraph (deployed or local) and a Claude Code or Cursor session pointed at a fresh HyperIndex project.</p>
<ul>
<li><a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">HyperIndex Quickstart with AI</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">HyperIndex docs MCP server</a></li>
<li><a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference indexer</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/migration-guide" target="_blank" rel="noopener noreferrer">Migration guide (manual reference)</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-cli" target="_blank" rel="noopener noreferrer">Envio Cloud CLI</a></li>
</ul>
<p>For larger migrations, the Envio team supports the planning and review pass directly. Reach out via Discord or Telegram.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/ai-subgraph-migration-hyperindex-claude#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[Production Indexer Reliability with HyperIndex]]></title>
            <link>https://docs.envio.dev/blog/production-indexer-reliability-hyperindex</link>
            <guid>https://docs.envio.dev/blog/production-indexer-reliability-hyperindex</guid>
            <pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Production indexer reliability with HyperIndex: framework reorg rollback, restart-resistant operation, HyperSync data validation, multi data-source recovery, stable Prometheus metrics.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/production-indexer-reliability-hyperindex.png" alt="Production Indexer Reliability with HyperIndex" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. Production reliability lives at the framework level, not bolted on per indexer.</li>
<li>Reorg handling is built in. Entity state history is tracked for every unfinalized block; the framework rolls back automatically when a chain re-orgs. No handler code required.</li>
<li>The indexer is restart-resistant. State (including dynamically registered contracts) is persisted to the database and restored on reboot. If a handler fails, the framework restarts automatically without data loss, the indexer resumes from the last committed block.</li>
<li>HyperSync, Envio's default data engine, ships a robust set of data validation features that RPC does not: block parent hash verification, fork detection, automatic re-sync. The indexer can trust that no events are silently missed, in contrast to raw RPC which only serves whatever the upstream node currently considers canonical.</li>
<li>Multi data-source recovery falls back to a secondary source on primary outage and attempts to recover to the primary 60 seconds later. The indexer stays alive through upstream RPC and HyperSync failures.</li>
<li>Polymarket's HyperIndex reference indexer synced 4,000,000,000 events in 6 days on Polygon. Public at <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a>.</li>
</ul></div></div>
<p>A production indexer fails in three ways. The chain reorgs and the indexer either misses the rollback or hand-rolls bespoke logic that breaks at the next edge case. The data source goes down and the indexer either stalls silently or fails over and never comes back to primary. The indexer hits a counter ceiling, a memory leak in a long-running handler, or another silent failure, and the operator finds out from a downstream outage instead of an alert.</p>
<p>HyperIndex is Envio's multichain blockchain indexing framework for EVM chains. Reliability lives at the framework level so that any indexer built on it inherits the behaviour without writing operational code. Four guarantees compound to keep an indexer production-correct: framework-level reorg handling, restart-resistant operation, HyperSync data validation, and multi data-source recovery. Observability through Prometheus layers on top.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-these-four-reliability-pillars-reinforce-each-other">Why These Four Reliability Pillars Reinforce Each Other<a class="hash-link" aria-label="Direct link to Why These Four Reliability Pillars Reinforce Each Other" title="Direct link to Why These Four Reliability Pillars Reinforce Each Other" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#why-these-four-reliability-pillars-reinforce-each-other">​</a></h2>
<p>Reorg handling guarantees your indexer doesn't carry corrupt state forward when a chain rolls back. Restart-resistant operation means a failed indexer process doesn't leak that corruption into a stuck or amnesiac state. HyperSync validation means the data feeding both is the canonical chain, not a stale or partial fork. Multi-source recovery keeps the whole stack live when upstream sources fail. Each pillar protects the rest.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="reorg-handling-at-the-framework-level">Reorg Handling at the Framework Level<a class="hash-link" aria-label="Direct link to Reorg Handling at the Framework Level" title="Direct link to Reorg Handling at the Framework Level" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#reorg-handling-at-the-framework-level">​</a></h2>
<p>The reorg architecture is the deepest piece of work HyperIndex's reliability story rests on. To understand why "framework-level" matters, it helps to be precise about what a reorg actually does to an indexer.</p>
<p>A reorg is a chain rolling back to a previous point in time. A recent block (or several) is no longer canonical, and the new canonical chain has different events at those heights. The implications for an indexer split along a single axis, stateless versus stateful.</p>
<p>Stateless indexers only create entities. On a reorg, the fix is mechanical. Delete the entities written from orphaned blocks, re-ingest from the canonical chain, move on. Stateless indexing parallelises well and is fast.</p>
<p>Stateful indexers also update and delete entities based on previous state. An order book's running volume, an account's balance, a market's open interest, all of these aggregate prior state into current state. On a reorg, you cannot just delete and replay. You have to revert previous operations to the entity state at the pre-reorg point, then replay forward against the canonical chain. Doing that correctly requires tracking the history of every change to every entity for the entire unfinalized window.</p>
<p>HyperIndex's framework keeps that entity history for you.</p>
<blockquote>
<p>"Envio HyperIndex tracks entity state history for all unfinalized blocks. When a reorg is detected, it rolls back entity state to the correct point and reprocesses events from the canonical chain. This happens automatically and does not require any custom rollback logic in your event handlers."</p>
<p>Denham Preen, Envio Co-founder</p>
</blockquote>
<p>Learn more in our <a href="https://docs.envio.dev/blog/indexing-and-reorgs" target="_blank" rel="noopener noreferrer">Indexing and Reorgs</a> blog.</p>
<p>Three architectural details worth knowing about that mechanism:</p>
<ol>
<li>
<p><strong>History is per-entity, not per-block.</strong> The framework persists the prior state of each entity each time a handler writes to it within the unfinalized window. On a reorg, the rollback walks the per-entity history backwards to the pre-reorg state, applies it, and reprocesses forward. This is what lets time-travel queries work against unfinalized blocks.</p>
</li>
<li>
<p><strong>History is pruned automatically.</strong> Once a block is finalised, its entries in the entity history are no longer needed. The framework prunes them. The unfinalized window is the only window that ever carries history overhead, which keeps the storage cost bounded regardless of total chain length.</p>
</li>
<li>
<p><strong>Multichain reorg handling is harder than single-chain, and the framework does it.</strong> When a single entity's state is updated by events from multiple chains, a reorg on chain A may force the framework to also reprocess events on chain B that were applied after the reorg point but depended on the rolled-back state. The reorg blog calls this out explicitly. Hand-rolling correct multichain reorg logic is the kind of thing you do not want any application engineer to have to write.</p>
</li>
</ol>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="reorgs-in-the-wild">Reorgs in the Wild<a class="hash-link" aria-label="Direct link to Reorgs in the Wild" title="Direct link to Reorgs in the Wild" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#reorgs-in-the-wild">​</a></h3>
<p>These are not theoretical edge cases. From the same reorg blog:</p>
<ul>
<li><strong>Polygon</strong> has frequent and sometimes deep reorgs. The forum has documented a single <a href="https://forum.polygon.technology/t/157-block-reorg-at-block-height-39599624/11388" target="_blank" rel="noopener noreferrer">157-block reorg at block height 39,599,624</a>. Polymarket runs on Polygon. Polymarket's reference indexer at <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a> has stayed correct through every Polygon reorg, including the deep ones, because the framework does the work.</li>
<li><strong>Ethereum mainnet</strong> sees roughly 1% of blocks affected by reorgs. Assuming a 50/50 chance of a transaction landing in the orphaned versus canonical fork, that's about 1 in 200 transactions ending up in a reorged block. An indexer that does not roll back state is silently wrong for ~0.5% of the transactions it ingests.</li>
<li><strong>Base and OP-stack chains</strong> are largely reorg-resistant due to single-slot finality, with <a href="https://optimistic.etherscan.io/blocks_forked" target="_blank" rel="noopener noreferrer">documented exceptions</a>.</li>
</ul>
<p>Why this matters operationally:</p>
<ul>
<li><strong>No bespoke per-handler logic.</strong> The most common subgraph reliability bug is a handler that does not handle a reorg correctly because the dev forgot to. With HyperIndex that bug class does not exist.</li>
<li><strong>No "wait for N confirmations" delay.</strong> Some indexers paper over reorgs by lagging behind the chain head by N blocks. HyperIndex stays at chain head and rolls back if needed.</li>
<li><strong>Entity state history is queryable.</strong> Time-travel queries against the unfinalized window work because the history is persisted, not discarded.</li>
<li><strong>Multichain stays correct.</strong> A multichain indexer with one chain reorging does not corrupt the cross-chain aggregates. The framework rolls back the dependent state on every other chain too.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="multi-data-source-recovery">Multi Data-Source Recovery<a class="hash-link" aria-label="Direct link to Multi Data-Source Recovery" title="Direct link to Multi Data-Source Recovery" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#multi-data-source-recovery">​</a></h2>
<p>HyperIndex's multi data-source recovery is documented in the <a href="https://docs.envio.dev/blog" target="_blank" rel="noopener noreferrer">dev update archive</a> and tracked in the <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">GitHub releases</a>.</p>
<p>The feature has three concrete pieces.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-smarter-source-selection">1. Smarter source selection<a class="hash-link" aria-label="Direct link to 1. Smarter source selection" title="Direct link to 1. Smarter source selection" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#1-smarter-source-selection">​</a></h3>
<p>Indexers configured with multiple data sources (a primary plus one or more fallbacks) route requests using selection logic that weights source health. A flapping fallback does not win the rotation purely because it answered fastest.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-automatic-failover-within-seconds">2. Automatic failover within seconds<a class="hash-link" aria-label="Direct link to 2. Automatic failover within seconds" title="Direct link to 2. Automatic failover within seconds" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#2-automatic-failover-within-seconds">​</a></h3>
<p>When the primary source goes down, the indexer fails over to a fallback within seconds. When the primary comes back, <a href="https://docs.envio.dev/docs/HyperIndex/whats-new-in-v3#improved-multiple-data-sources-support" target="_blank" rel="noopener noreferrer">HyperIndex attempts to recover to it 60 seconds later</a>. The indexer does not need to be restarted to return to its preferred source.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-live-mode-enforcement">3. Live mode enforcement<a class="hash-link" aria-label="Direct link to 3. Live mode enforcement" title="Direct link to 3. Live mode enforcement" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#3-live-mode-enforcement">​</a></h3>
<p>Live mode means the indexer is at chain head and processing new blocks as they arrive. HyperIndex enforces live mode strictly: if the indexer's effective progress is stalling on a degraded source, metrics surface it. Operators see the degradation before downstream consumers do.</p>
<p>This pillar is the one operators feel daily. Most indexer outages in 2025 were not chain outages. They were data-source outages that the indexer did not handle gracefully. Multi data-source recovery removes the operator pager from that loop.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="resumes-cleanly-across-restarts">Resumes Cleanly Across Restarts<a class="hash-link" aria-label="Direct link to Resumes Cleanly Across Restarts" title="Direct link to Resumes Cleanly Across Restarts" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#resumes-cleanly-across-restarts">​</a></h2>
<p>A production indexer runs for months. The host will restart. Configs will change. The reliability question isn't whether restarts happen, it's what state the indexer is in when they do.</p>
<p>HyperIndex persists indexer state across restarts. On reboot, state is restored from the database, including dynamically registered contracts. The indexer resumes from the last committed block, not from chain head and not from genesis. Application code does not have to track checkpoints or persist offsets, the framework handles it.</p>
<p>Handler-side failures are caught at the framework level too. If a handler throws an unhandled exception, the indexer restarts automatically without data loss. Application code does not have to wrap handlers in try/catch, implement custom retry logic, or rebuild offsets after a crash. The framework does this for you.</p>
<p>The dev environment also preserves data by default. <code>envio dev</code> no longer wipes the database on incompatible config or schema changes; the explicit opt-in is <code>envio dev -r</code>. For some config changes (RPC configuration is the first to land), the indexer can continue indexing through the change without erroring out at all.</p>
<p>This complements the reorg story. Reorg handling protects against chain-side rollbacks; restart persistence protects against indexer-side restarts. Together they cover the failure surface a production indexer actually faces.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hypersync-data-validation">HyperSync Data Validation<a class="hash-link" aria-label="Direct link to HyperSync Data Validation" title="Direct link to HyperSync Data Validation" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#hypersync-data-validation">​</a></h2>
<p>The data feeding the indexer matters as much as the indexer itself. A reorg-aware framework with restart safety is still only as correct as the events that arrive at the handler.</p>
<p>HyperIndex pulls historical data through HyperSync, Envio's data engine. HyperSync ships a robust set of validation features that raw RPC does not, block parent hash verification, fork detection, automatic re-sync on detected forks. The validation runs at ingestion, not in your handler. The framework's confidence is that no events are silently missed by the data layer.</p>
<p>Raw RPC does not give the same guarantee. A standard RPC endpoint will serve whatever the upstream node currently considers canonical, and a slow rotation between forks (or a single RPC sitting on an orphaned tip) can quietly hand stale events to a downstream indexer. With HyperSync as the data layer, that class of silent corruption is removed before any handler sees it.</p>
<p>For application teams: events that reach your handler are canonical-chain events. For AI agents acting on indexer state: the data they reason over is validated upstream, not a best-effort RPC read.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-data-validity-matters-for-ai">Why Data Validity Matters for AI<a class="hash-link" aria-label="Direct link to Why Data Validity Matters for AI" title="Direct link to Why Data Validity Matters for AI" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#why-data-validity-matters-for-ai">​</a></h3>
<p>When an agent acts on indexer data, the agent is only as correct as the data it queries. A missing or stale event in a derivative pricing agent, a position tracker, or a governance bot is not a logging error, it's a financial event. The premise of the AI-onchain stack is that the data layer underneath gives the agent verified, canonical state.</p>
<p>HyperIndex's framework-level guarantees (reorg-aware, restart-persistent, parent-hash-validated upstream) are what let an agent treat indexer output as a stable source of truth rather than a feed to second-guess. The <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">companion blog on agentic blockchain indexing</a> covers the agent-side story end to end.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="observability-through-prometheus">Observability Through Prometheus<a class="hash-link" aria-label="Direct link to Observability Through Prometheus" title="Direct link to Observability Through Prometheus" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#observability-through-prometheus">​</a></h2>
<p>HyperIndex exposes a standard Prometheus <code>/metrics</code> endpoint with three properties operators rely on.</p>
<ul>
<li><strong>Semver-stable contract.</strong> Metric names and labels do not change between minor versions. Grafana dashboards built against this endpoint do not need to be rebuilt every release.</li>
<li><strong>Time units in seconds.</strong> Every duration metric is in seconds, matching Prometheus convention. Histograms use second-based buckets.</li>
<li><strong>Benchmark data points in the standard endpoint.</strong> The data points historically surfaced under a separate benchmark mode are part of the standard <code>/metrics</code> output. Continuous benchmarking against a production deployment does not require a separate run mode.</li>
</ul>
<p>For self-hosted deployments, the endpoint plugs into existing Prometheus infrastructure. For Envio Cloud deployments, alerts are exposed through the standard alert channels (Discord, Slack, Telegram, and Email).</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-this-looks-like-in-a-real-configuration">What This Looks Like in a Real Configuration<a class="hash-link" aria-label="Direct link to What This Looks Like in a Real Configuration" title="Direct link to What This Looks Like in a Real Configuration" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#what-this-looks-like-in-a-real-configuration">​</a></h2>
<p>The Polymarket reference indexer's <code>config.yaml</code> is the public production example. The structural pieces below are drawn from <a href="https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml" target="_blank" rel="noopener noreferrer">the canonical file</a> (selected events shown for brevity):</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># Source: https://github.com/enviodev/polymarket-indexer/blob/main/config.yaml</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># yaml-language-server: $schema=./node_modules/envio/evm.schema.json</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> polymarket</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">indexer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Unified Polymarket HyperIndex</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Phase 1A: Fee Module</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> FeeModule</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">abi_file_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./abis/FeeModule.json</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"FeeRefunded(bytes32 indexed orderHash, address indexed to, uint256 id, uint256 refund, uint256 indexed feeCharged)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Phase 2B: Orderbook</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Exchange</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">abi_file_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./abis/Exchange.json</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrderFilled(bytes32 indexed orderHash, address indexed maker, address indexed taker, uint256 makerAssetId, uint256 takerAssetId, uint256 makerAmountFilled, uint256 takerAmountFilled, uint256 fee)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrdersMatched(bytes32 indexed takerOrderHash, address indexed takerOrderMaker, uint256 makerAssetId, uint256 takerAssetId, uint256 makerAmountFilled, uint256 takerAmountFilled)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Phase 3: Open Interest + Activity</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConditionalTokens</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">abi_file_path</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./abis/ConditionalTokens.json</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PositionSplit(address indexed stakeholder, address collateralToken, bytes32 indexed parentCollectionId, bytes32 indexed conditionId, uint256[] partition, uint256 amount)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PositionsMerge(address indexed stakeholder, address collateralToken, bytes32 indexed parentCollectionId, bytes32 indexed conditionId, uint256[] partition, uint256 amount)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"PayoutRedemption(address indexed redeemer, address indexed collateralToken, bytes32 indexed parentCollectionId, bytes32 conditionId, uint256[] indexSets, uint256 payout)"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">field_selection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">transaction_fields</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> hash</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> from</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> to</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">chains</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">137</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)"># Polygon</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">3764531</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token key atrule">contracts</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> FeeModule</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xE3f18aCc55091e2c48d883fc8C8413319d4Ab7b0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xB768891e3130F6dF18214Ac804d4DB76c2C37730"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">75253526</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Exchange</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0xC5d563A36AE78145C45a50134d48A1215220f80a"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">33605403</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ConditionalTokens</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token key atrule">start_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">4023686</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Three details worth pointing at in this config:</p>
<ol>
<li><strong>Two-tier declaration.</strong> The top-level <code>contracts:</code> block declares the contract name, ABI, and event signatures globally. The <code>chains:</code> block (per chain ID) supplies addresses and per-contract <code>start_block</code> overrides. This is how the same contract definition gets reused across multiple deployed addresses (Exchange has two production addresses, FeeModule has two) without duplicating the event signatures.</li>
<li><strong><code>field_selection</code></strong> controls which transaction fields HyperSync ships down to the handler. Polymarket asks for <code>hash</code>, <code>from</code>, and <code>to</code> only. Smaller per-event payload, faster sync, lower memory pressure. Available on every config.</li>
<li><strong>No reorg block.</strong> There is no <code>rollback_on_reorg</code> flag set in the config because rollback is the framework default. The handlers in <code>src/</code> do not contain reorg logic. They write entities, the framework manages history, the database stays consistent.</li>
</ol>
<p>The full file declares 9 V1 contracts (FeeModule, UmaSportsOracle, RelayHub, SafeProxyFactory, USDC, Exchange, ConditionalTokens, NegRiskAdapter, FPMMFactory) plus a dynamic FixedProductMarketMaker registered at runtime, and 5 V2 contracts (CTFExchangeV2, PolyUSD, Rewards, CtfCollateralAdapter, NegRiskCtfCollateralAdapter), all routed through merged handlers in a single multichain-capable config. For a true multichain deployment, the same <code>chains:</code> array gets additional entries (e.g., <code>id: 8453</code> for Base) with their own contracts block.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-reliability-beats-speed-when-you-are-picking-an-indexer">Why Reliability Beats Speed When You Are Picking an Indexer<a class="hash-link" aria-label="Direct link to Why Reliability Beats Speed When You Are Picking an Indexer" title="Direct link to Why Reliability Beats Speed When You Are Picking an Indexer" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#why-reliability-beats-speed-when-you-are-picking-an-indexer">​</a></h2>
<p>Speed is the easier comparison and the one most blog posts lead with. Sentio's independent Uniswap V2 Factory benchmark put HyperIndex at 8 seconds, 142x faster than The Graph and 15x faster than the nearest competitor. Polymarket synced 4 billion events in 6 days. Our <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">agentic indexing blog</a> covers a 400,000-event Monad indexer in roughly 20 seconds.</p>
<p>Reliability is the one that decides whether an indexer stays running for years. The four pillars above (framework reorg handling, restart-resistant operation, HyperSync data validation, and multi data-source recovery) are what separate a production indexer from a benchmark.</p>
<p>Three operational consequences for teams choosing HyperIndex over alternatives:</p>
<ul>
<li><strong>One on-call surface, not three.</strong> The framework handles reorgs, source failover, restart recovery, and observability. The on-call person reads the Prometheus dashboard and the Envio Cloud alerts. They do not also have to maintain custom reorg or checkpoint code.</li>
<li><strong>Source diversity without operator overhead.</strong> Adding a fallback source is a config change. Multi data-source recovery does the runtime work. The operator does not author retry policies.</li>
<li><strong>Time-travel queries on unfinalized state.</strong> Because entity state history is persisted, the indexer can answer "what was this entity at block N" even when N is in the unfinalized window. Most subgraphs cannot.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#get-started">​</a></h2>
<ul>
<li><a href="https://docs.envio.dev/docs/HyperIndex/whats-new-in-v3" target="_blank" rel="noopener noreferrer">What's new in v3</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/getting-started" target="_blank" rel="noopener noreferrer">HyperIndex quickstart</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">Quickstart with AI</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/benchmarks" target="_blank" rel="noopener noreferrer">Benchmarks</a></li>
<li><a href="https://docs.envio.dev/blog/indexing-and-reorgs" target="_blank" rel="noopener noreferrer">Reorg handling reference</a></li>
<li><a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference indexer</a></li>
<li><a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">Envio Cloud (alerts, hosted reliability)</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-envio-hyperindex-handle-blockchain-reorgs">How does Envio HyperIndex handle blockchain reorgs?<a class="hash-link" aria-label="Direct link to How does Envio HyperIndex handle blockchain reorgs?" title="Direct link to How does Envio HyperIndex handle blockchain reorgs?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#how-does-envio-hyperindex-handle-blockchain-reorgs">​</a></h3>
<p>HyperIndex tracks entity state history for every unfinalized block at the framework level. When a reorg occurs, the framework walks the per-entity history backwards to the pre-reorg state, applies it, then reprocesses forward against the canonical chain. History is pruned automatically once a block is finalised. No handler code is required.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-hypersync-guarantee-canonical-chain-data">How does HyperSync guarantee canonical chain data?<a class="hash-link" aria-label="Direct link to How does HyperSync guarantee canonical chain data?" title="Direct link to How does HyperSync guarantee canonical chain data?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#how-does-hypersync-guarantee-canonical-chain-data">​</a></h3>
<p>HyperSync ships a robust set of validation features that raw RPC does not, block parent hash verification, fork detection, automatic re-sync on detected forks. The indexer can trust that no events are silently missed by the data layer. The validation runs at ingestion, not in your handler. Raw RPC endpoints serve whatever the upstream node currently considers canonical, which is why a standard RPC-fed indexer can silently ingest stale or orphaned data from a slow-rotating provider.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-often-do-reorgs-actually-happen">How often do reorgs actually happen?<a class="hash-link" aria-label="Direct link to How often do reorgs actually happen?" title="Direct link to How often do reorgs actually happen?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#how-often-do-reorgs-actually-happen">​</a></h3>
<p>On Ethereum mainnet, roughly 1% of blocks undergo reorgs, meaning approximately 1 in 200 transactions ends up in a reorged block. Polygon experiences deeper reorgs more frequently and has documented a single 157-block reorg at block height 39,599,624. Base and OP-stack chains are largely reorg-resistant due to single-slot finality, with documented exceptions.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-multi-data-source-recovery-in-hyperindex">What is multi data-source recovery in HyperIndex?<a class="hash-link" aria-label="Direct link to What is multi data-source recovery in HyperIndex?" title="Direct link to What is multi data-source recovery in HyperIndex?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#what-is-multi-data-source-recovery-in-hyperindex">​</a></h3>
<p>Multi data-source recovery automatically routes between configured data sources. On primary outage, the indexer fails over to a fallback within seconds. When the primary returns, the indexer attempts to recover to it 60 seconds later, no restart required. Selection logic weights source health, not just first-response. Live mode enforcement surfaces through metrics when forward progress slows on a degraded source.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-happens-to-the-indexer-when-the-process-restarts-or-a-handler-fails">What happens to the indexer when the process restarts or a handler fails?<a class="hash-link" aria-label="Direct link to What happens to the indexer when the process restarts or a handler fails?" title="Direct link to What happens to the indexer when the process restarts or a handler fails?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#what-happens-to-the-indexer-when-the-process-restarts-or-a-handler-fails">​</a></h3>
<p>HyperIndex is restart-resistant. State persists to the database; on restart, the indexer restores state (including dynamically registered contracts) and resumes from the last committed block. If a handler fails mid-execution, the framework restarts automatically without data loss. Application code does not have to track checkpoints, persist offsets, or wrap handlers in retry logic.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-the-hyperindex-prometheus-metrics-endpoint-production-ready">Is the HyperIndex Prometheus metrics endpoint production-ready?<a class="hash-link" aria-label="Direct link to Is the HyperIndex Prometheus metrics endpoint production-ready?" title="Direct link to Is the HyperIndex Prometheus metrics endpoint production-ready?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#is-the-hyperindex-prometheus-metrics-endpoint-production-ready">​</a></h3>
<p>Yes. The <code>/metrics</code> endpoint follows semver, uses second-based time units, and exposes the benchmark data points historically surfaced under a separate run mode as part of the standard endpoint.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="where-can-i-see-the-production-scale-hyperindex-reference">Where can I see the production-scale HyperIndex reference?<a class="hash-link" aria-label="Direct link to Where can I see the production-scale HyperIndex reference?" title="Direct link to Where can I see the production-scale HyperIndex reference?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#where-can-i-see-the-production-scale-hyperindex-reference">​</a></h3>
<p>The <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">Polymarket reference indexer</a>. It synced 4,000,000,000 events from block 3,764,531 on Polygon Mainnet in 6 days, replacing 8 separate subgraphs.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-alert-channels-does-envio-cloud-support">What alert channels does Envio Cloud support?<a class="hash-link" aria-label="Direct link to What alert channels does Envio Cloud support?" title="Direct link to What alert channels does Envio Cloud support?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#what-alert-channels-does-envio-cloud-support">​</a></h3>
<p>Envio Cloud alerts route through the platform's alert channels documented in the <a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">hosted service docs</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-hyperindex-stay-at-chain-head-or-lag-for-safety">Does HyperIndex stay at chain head or lag for safety?<a class="hash-link" aria-label="Direct link to Does HyperIndex stay at chain head or lag for safety?" title="Direct link to Does HyperIndex stay at chain head or lag for safety?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#does-hyperindex-stay-at-chain-head-or-lag-for-safety">​</a></h3>
<p>HyperIndex stays at chain head. Reorgs are handled by rollback, not by lag. There is no "wait N confirmations" mode required for correctness.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-hyperindex-faster-than-the-graph-in-production">Is HyperIndex faster than The Graph in production?<a class="hash-link" aria-label="Direct link to Is HyperIndex faster than The Graph in production?" title="Direct link to Is HyperIndex faster than The Graph in production?" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#is-hyperindex-faster-than-the-graph-in-production">​</a></h3>
<p>Yes. In the Sentio Uniswap V2 Factory benchmark, HyperIndex completed in 8 seconds. The Graph took 19 minutes on the same workload, 142x slower. Subsquid, the nearest competitor, was 15x slower. Full results on the benchmarks page linked in Get Started.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/production-indexer-reliability-hyperindex#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Privacy in Public: A Case Study on Privacy Pools]]></title>
            <link>https://docs.envio.dev/blog/privacy-in-public-case-study</link>
            <guid>https://docs.envio.dev/blog/privacy-in-public-case-study</guid>
            <pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[What an Envio HyperIndex multichain indexer plus a thin Uniswap V4 price feed reveal about Privacy Pools (21 pools, 4 chains, ~5,200 deposits, $5.78M TVL): a working privacy primitive whose on-chain footprint shows the cryptographic floor holding.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/privacy-pools-case-study.png" alt="Privacy in Public: A Case Study on Privacy Pools" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Privacy Pools is live on <strong>4 chains (Ethereum, Optimism, BSC, Arbitrum) across 21 pools</strong>, with ~$5.78M of TVL, ~5,180 lifetime deposits, ~5,630 withdrawals, and a healthy mainnet ETH pool of <strong>2,320 distinct depositors</strong> behind a strong anonymity set.</li>
<li>The protocol's ZK proof hides which deposit funded which withdrawal cryptographically. Public-data signals an outside observer could attempt to read are heuristic only, and the protocol's design (open ragequit, free decoy construction, relayer flow) makes those heuristics impossible to verify from on-chain data alone.</li>
<li>Indexed end-to-end with one Envio HyperIndex v3 indexer, ClickHouse storage, and a thin Uniswap V4 price feed on BSC. Full multichain sync to head: ~30 seconds.</li>
<li>Full open-source code, queries, and BI report generator at <a href="https://github.com/enviodev/privacy-pools" target="_blank" rel="noopener noreferrer">github.com/enviodev/privacy-pools</a>.</li>
</ul></div></div>
<p><a href="https://privacypools.com/" target="_blank" rel="noopener noreferrer">Privacy Pools</a> is one of the more ambitious privacy primitives shipped on Ethereum and its L2s. The protocol, <a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364" target="_blank" rel="noopener noreferrer">co-authored by Vitalik Buterin and others</a>, pairs a zero-knowledge proof of pool membership with an off-chain compliance vetting layer (the <strong>Association Set Provider</strong>, ASP). The result is a privacy mechanism that gives users cryptographic unlinkability between their deposit and their withdrawal, while still letting an off-chain layer say "we don't think this commitment came from a sanctioned address". Both halves matter, and both halves are working.</p>
<p>This post walks through a fully indexed snapshot of every deposit, withdrawal, ragequit, ASP root update, and relayer fee across all 21 live pools on every chain Privacy Pools runs on (14 on Ethereum, 2 on Optimism, 2 on BSC, 3 on Arbitrum). The headline takeaways are positive: the ZK proof is sound, the relayed-withdrawal path that preserves privacy gets used by 91% of withdrawers, and the largest pool has a genuinely diverse depositor base. The smaller, newer pools are doing what newer pools do: building toward those numbers.</p>
<p>The interesting analytical question, then, is what an outside observer with the public on-chain data can or can't say about who linked to whom. The answer is a clean "very little, and never with certainty". This is by design, and the data shows the design holding.</p>
<p>The full stack (indexer, analytics queries, BI report generator) is open-source at <a href="https://github.com/enviodev/privacy-pools" target="_blank" rel="noopener noreferrer">github.com/enviodev/privacy-pools</a> under MIT license.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-privacy-pools">What is Privacy Pools<a class="hash-link" aria-label="Direct link to What is Privacy Pools" title="Direct link to What is Privacy Pools" href="https://docs.envio.dev/blog/privacy-in-public-case-study#what-is-privacy-pools">​</a></h2>
<p>Three on-chain entities matter for indexing:</p>
<ul>
<li><strong>The Entrypoint</strong>: the singleton each pool registers under. Routes deposits and relays withdrawals.</li>
<li><strong>PrivacyPool</strong>: one contract per asset (ETH, USDC, USDT, fxUSD, BOLD, and so on). Emits <code>Deposited</code>, <code>Withdrawn</code>, <code>Ragequit</code>, <code>LeafInserted</code>, <code>PoolDied</code>.</li>
<li><strong>Association Set Provider (ASP)</strong>: off-chain vetting. On-chain footprint is the <code>RootUpdated</code> events from the Entrypoint, each carrying a Merkle root and an IPFS pointer to the approved set.</li>
</ul>
<p>The deposit/withdraw flow produces a commitment in a per-pool Merkle tree on deposit, and on withdrawal proves "I own <em>some</em> commitment in this pool, and that commitment is in the <strong>Association Set</strong> approved by the ASP", without revealing which commitment. <code>Ragequit</code> is the escape hatch: a depositor whose commitment has been excluded from a recent ASP root pulls their position out without the ZK-protected withdrawal flow.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-dataset">The Dataset<a class="hash-link" aria-label="Direct link to The Dataset" title="Direct link to The Dataset" href="https://docs.envio.dev/blog/privacy-in-public-case-study#the-dataset">​</a></h2>
<p>The indexer covers every Entrypoint and every PrivacyPool live across the four supported chains. Headline state at the time of writing (block heights are real-time):</p>
<table><thead><tr><th>chain</th><th>pools</th><th>deposits</th><th>withdrawals</th><th>ragequits</th><th>leaves</th></tr></thead><tbody><tr><td>Ethereum</td><td>14</td><td>4,731</td><td>5,138</td><td>322</td><td>9,883</td></tr><tr><td>Optimism</td><td>2</td><td>124</td><td>128</td><td>37</td><td>254</td></tr><tr><td>BSC</td><td>2</td><td>60</td><td>20</td><td>45</td><td>82</td></tr><tr><td>Arbitrum</td><td>3</td><td>265</td><td>344</td><td>36</td><td>612</td></tr><tr><td><strong>Total</strong></td><td><strong>21</strong></td><td><strong>5,180</strong></td><td><strong>5,630</strong></td><td><strong>440</strong></td><td><strong>10,831</strong></td></tr></tbody></table>
<p>USD TVL across all chains: <strong>~$5.78M</strong>. Largest pools:</p>
<table><thead><tr><th>pool</th><th>TVL (USD)</th></tr></thead><tbody><tr><td>Ethereum USDT</td><td>$2.40M</td></tr><tr><td>Ethereum ETH</td><td>$1.75M</td></tr><tr><td>Ethereum USDC</td><td>$1.46M</td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-mainnet-eth-pool-a-working-anonymity-set">The mainnet ETH pool: a working anonymity set<a class="hash-link" aria-label="Direct link to The mainnet ETH pool: a working anonymity set" title="Direct link to The mainnet ETH pool: a working anonymity set" href="https://docs.envio.dev/blog/privacy-in-public-case-study#the-mainnet-eth-pool-a-working-anonymity-set">​</a></h2>
<p>The Ethereum ETH pool is the protocol's flagship deployment, and its numbers tell a clear story:</p>
<ul>
<li><strong>2,320 distinct depositors</strong> (the next-largest cohort is 253 on Ethereum USDC).</li>
<li><strong>7,889 leaves</strong> in the Merkle tree, more than every other pool combined.</li>
<li><strong>Herfindahl-Hirschman Index of 132</strong> on depositor-value share, far below the 2,500 threshold considered "highly concentrated". The top depositor controls 8.0% of value, the top five 17.4%, the top ten 24.7%. There is no dominant wallet.</li>
</ul>
<p>Together those numbers describe a pool with real anonymity. A withdrawal from this pool has thousands of plausible commitments behind it, and no single dominant depositor for an analyst to single out.</p>
<p>The smaller pools (BNB on BSC, yUSND on Arbitrum, BOLD on Ethereum, and the rest of the long tail) are at much earlier points in the same curve. With anywhere from 1 to ~250 leaves, the long tail is in early-cohort phase. Concentration is high there because the pools are young, not because the protocol is broken.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="anonymity-set-growth">Anonymity-set growth<a class="hash-link" aria-label="Direct link to Anonymity-set growth" title="Direct link to Anonymity-set growth" href="https://docs.envio.dev/blog/privacy-in-public-case-study#anonymity-set-growth">​</a></h2>
<p>Each commitment lives as a leaf in the per-pool Merkle tree. Both deposits and the ZK-replacement leaves emitted on withdrawal contribute, so the leaf count keeps climbing as the pool gets used.</p>
<img src="https://docs.envio.dev/blog-assets/privacy-pools-anonymity-growth.png" alt="Anonymity-set growth (leaves) per pool over time" width="100%">
<p>The Ethereum ETH pool dominates by volume, but every active pool shows steady growth. There is no sign of pool abandonment.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="activity-patterns">Activity patterns<a class="hash-link" aria-label="Direct link to Activity patterns" title="Direct link to Activity patterns" href="https://docs.envio.dev/blog/privacy-in-public-case-study#activity-patterns">​</a></h2>
<p>Aggregating deposits and withdrawals by hour-of-day and day-of-week (UTC) reveals a global usage pattern: activity is roughly continuous, with a mild ramp through European and US business hours and a softer Asia-Pacific tail. Privacy Pools is being used as a steady utility, not as an event-driven product.</p>
<img src="https://docs.envio.dev/blog-assets/privacy-pools-hourly-heatmap.png" alt="Activity heatmap by day-of-week and hour-of-day" width="100%">
<p>The lack of strong timezone clustering is itself a privacy positive: a sharply timezone-skewed user base would be an inadvertent fingerprint. This data shows a globally distributed user set.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="relayed-withdrawal-share">Relayed-withdrawal share<a class="hash-link" aria-label="Direct link to Relayed-withdrawal share" title="Direct link to Relayed-withdrawal share" href="https://docs.envio.dev/blog/privacy-in-public-case-study#relayed-withdrawal-share">​</a></h2>
<p>Withdrawals can be self-submitted (the recipient submits their own proof, paying gas with their own address) or relayed (a relayer submits on the recipient's behalf, taking a fee). Self-submitted withdrawals link the recipient address to the gas-paying address; relayed withdrawals don't.</p>
<p>Across all chains:</p>
<ul>
<li><strong>5,148</strong> withdrawals were relayed.</li>
<li><strong>482</strong> were self-submitted (~8.6%).</li>
</ul>
<p><strong>91.4%</strong> of withdrawals took the privacy-preserving relayed path. That's a strong positive signal: users understand the privacy model and use it.</p>
<p>The relayer market on Ethereum is currently concentrated, with one relayer (<code>0xec15c200…</code>) processing ~77.7% of relayed flow and <code>0x855b4a60…</code> taking 19.9%. The relayer doesn't see the deposit side, so they can't break the ZK link, but the concentration is worth watching as the relayer ecosystem matures. New relayers entering the market would distribute that observability and is a natural maturation step for the protocol.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="linkability-the-public-data-heuristic-and-why-it-can-never-be-proof">Linkability: the public-data heuristic, and why it can never be proof<a class="hash-link" aria-label="Direct link to Linkability: the public-data heuristic, and why it can never be proof" title="Direct link to Linkability: the public-data heuristic, and why it can never be proof" href="https://docs.envio.dev/blog/privacy-in-public-case-study#linkability-the-public-data-heuristic-and-why-it-can-never-be-proof">​</a></h2>
<p>Take every (deposit, withdrawal) pair in the same pool with the same on-chain value, and a time gap of 60 seconds to 2 hours. Treat the withdrawal as <em>possibly linkable</em> to that deposit by an external observer.</p>
<p>This is a heuristic. There is no proof the same actor controls both addresses, only that the visible flow is consistent with that.</p>
<table><thead><tr><th>pool</th><th>candidate pairs</th><th>total withdrawals</th><th>linkable share</th><th>median gap</th></tr></thead><tbody><tr><td>Ethereum USDC</td><td>50</td><td>862</td><td>5.6%</td><td>61 min</td></tr><tr><td>Ethereum USDT</td><td>7</td><td>170</td><td>3.5%</td><td>57 min</td></tr><tr><td>Ethereum ETH</td><td>882</td><td>3,916</td><td>~10.9%</td><td>39 min</td></tr><tr><td>Arbitrum USDC</td><td>26</td><td>150</td><td>16.0%</td><td>57 min</td></tr><tr><td>Arbitrum ETH</td><td>28</td><td>168</td><td>15.5%</td><td>47 min</td></tr><tr><td>Optimism ETH</td><td>13</td><td>60</td><td>15.0%</td><td>61 min</td></tr><tr><td>BSC USDT</td><td>3</td><td>8</td><td>37.5%</td><td>25 min</td></tr><tr><td>Ethereum USDS</td><td>3</td><td>8</td><td>37.5%</td><td>4 min</td></tr></tbody></table>
<p>About one in ten Ethereum ETH withdrawals fits this shape. On the smaller pools, the share is higher because there are fewer deposits to lose oneself in. These are upper bounds on what a naive heuristic can flag, and they are not proofs. The next section shows why.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="decoy-withdrawals-how-the-protocol-absorbs-the-heuristic">Decoy withdrawals: how the protocol absorbs the heuristic<a class="hash-link" aria-label="Direct link to Decoy withdrawals: how the protocol absorbs the heuristic" title="Direct link to Decoy withdrawals: how the protocol absorbs the heuristic" href="https://docs.envio.dev/blog/privacy-in-public-case-study#decoy-withdrawals-how-the-protocol-absorbs-the-heuristic">​</a></h2>
<p>The same-amount heuristic has a known counter, and it is a feature of the privacy model rather than a workaround.</p>
<p>An existing depositor whose funds have been in the pool for weeks or months sees a fresh deposit hit the contract. They withdraw an equivalent amount within the heuristic's time window, to a fresh address that has nothing to do with the new depositor. An outside observer running the same-amount analysis links the new deposit to that withdrawal address.</p>
<p>From outside, the pair looks like "Alice deposited and Alice (the withdrawal recipient) withdrew shortly after". Inside, Alice and the withdrawal recipient have nothing to do with each other. The withdrawer's funds predate Alice entirely.</p>
<p>Querying for deposits followed within 30 minutes by a same-amount withdrawal where the depositor and the withdrawal recipient are different addresses:</p>
<ul>
<li><strong>393</strong> decoy-candidate pairs across the dataset.</li>
<li><strong>163</strong> distinct depositors had a same-amount withdrawal land within 30 minutes from a different address.</li>
<li><strong>160</strong> distinct withdrawal addresses received those decoy-shaped withdrawals.</li>
</ul>
<p>These are candidates, not proven decoys. Every pair could be one of three things, all indistinguishable from public data:</p>
<ol>
<li>The depositor really is the same actor, just routing the receipt through a different address.</li>
<li>Two unrelated parties happen to transact for the same round amount within minutes (more likely on busy pools and round denominations).</li>
<li>An existing depositor deliberately constructs the match to spoof the heuristic.</li>
</ol>
<p>Because option (3) is cheap (one extra withdrawal proof) and option (2) is plausible on common amounts, the linkable-share table above is a <em>plausibility upper bound</em>, not a recall figure. An actor who knows the heuristic exists can deliberately produce false matches, and an actor who is genuinely the same person across both addresses will also show up in the same table. This is the verifiability ceiling that the protocol's design relies on, and it does the load-bearing work of converting the cryptographic guarantee into practical anonymity. Plausible deniability is real precisely because it can never be ruled out from public data.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="ragequit-the-safety-valve-doing-its-job">Ragequit: the safety valve doing its job<a class="hash-link" aria-label="Direct link to Ragequit: the safety valve doing its job" title="Direct link to Ragequit: the safety valve doing its job" href="https://docs.envio.dev/blog/privacy-in-public-case-study#ragequit-the-safety-valve-doing-its-job">​</a></h2>
<p>Ragequit is the escape hatch. When the ASP excludes a commitment from the latest approved root, the depositor still gets their funds back, just through a path that reveals which commitment they originally made.</p>
<p>The mainnet ETH baseline is <strong>6.0% ragequit-by-count, 9.2% by value</strong>. The smaller pools have higher rates:</p>
<img src="https://docs.envio.dev/blog-assets/privacy-pools-ragequit-rate.png" alt="Ragequit rate by pool" width="100%">
<table><thead><tr><th>pool</th><th>ragequit % (count)</th><th>ragequit % (value)</th></tr></thead><tbody><tr><td>BSC BNB</td><td>78.3%</td><td>97.1%</td></tr><tr><td>Arbitrum yUSND</td><td>48.5%</td><td>90.7%</td></tr><tr><td>BSC USDT</td><td>72.9%</td><td>78.6%</td></tr><tr><td>Ethereum USDS</td><td>62.5%</td><td>58.7%</td></tr><tr><td>Ethereum sUSDS</td><td>54.5%</td><td>35.7%</td></tr><tr><td>Ethereum fxUSD</td><td>15.8%</td><td>33.2%</td></tr><tr><td>Ethereum wstETH</td><td>23.5%</td><td>24.0%</td></tr><tr><td>Ethereum ETH</td><td>6.0%</td><td>9.2%</td></tr></tbody></table>
<p>Three pools (BSC BNB, Arbitrum yUSND, BSC USDT) have seen most of their deposit value exit through the ragequit path rather than ordinary withdrawals. Depositors did not lose funds, they got their money back. What was lost on those specific commitments was the cryptographic privacy property, because ragequit reveals which commitment exited.</p>
<p>This is the ASP doing what it is designed to do: rejecting commitments after the fact when the off-chain compliance check changes its mind, and giving users a way out that doesn't trap their funds. The fact that the escape hatch is being exercised on the edges (small, young pools) is the system's compliance layer working as advertised, and it doesn't affect the privacy of any other depositor. For the mainnet ETH pool, where the bulk of activity sits, the ragequit rate is low and stable.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="where-the-public-data-layer-helps">Where the public-data layer helps<a class="hash-link" aria-label="Direct link to Where the public-data layer helps" title="Direct link to Where the public-data layer helps" href="https://docs.envio.dev/blog/privacy-in-public-case-study#where-the-public-data-layer-helps">​</a></h2>
<p>A privacy protocol's job is to provide cryptographic guarantees that an external observer can't link who deposited what to who withdrew. Privacy Pools does that: the ZK proof is sound, the verifiers are deployed, the on-chain mechanism works.</p>
<p>What the on-chain trail also does is record every deposit value, every withdrawal value, every relayer address, every recipient, and every timestamp. From that an indexed dataset gives you:</p>
<ul>
<li>A linkable-share number per pool (5-37% across the indexed pools), constrained by the verifiability ceiling above.</li>
<li>A concentration index per pool that tells you how mature the anonymity set is.</li>
<li>A ragequit-rate signal that confirms the ASP layer is active and that the safety valve is functioning.</li>
<li>A relayed-share number showing 91% of withdrawers using the privacy-preserving path.</li>
<li>A decoy-candidate count that quantifies how much credibility the plausible-deniability layer has on each pool.</li>
</ul>
<p>None of these break the protocol. None of these are verifiable. All of them are useful operational metadata that anyone, including the ASP, the protocol team, and end users, can use to track the protocol's health.</p>
<p>The point of indexing the protocol publicly is precisely that this kind of monitoring should be open. The same dataset that enables the heuristics also exposes the limits of those heuristics, and lets honest actors and the protocol team work on the things that actually matter (anonymity-set growth on the long-tail pools, relayer-market diversification, ASP responsiveness) without anyone needing privileged access.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-this-isnt">What this isn't<a class="hash-link" aria-label="Direct link to What this isn't" title="Direct link to What this isn't" href="https://docs.envio.dev/blog/privacy-in-public-case-study#what-this-isnt">​</a></h2>
<p>A few things this analysis explicitly does <em>not</em> show:</p>
<ul>
<li><strong>It does not break the ZK proof.</strong> Every linkability claim above is heuristic. A withdrawal that matches a deposit by amount and timing is consistent with the same actor controlling both addresses, but it is not proof.</li>
<li><strong>The decoy-candidate count is not a fraud detector.</strong> Many of the 393 decoy-shaped pairs will be coincidence on common round amounts, and some will be the same actor using a fresh address. The count is a ceiling on intentional decoys, not a measurement of them.</li>
<li><strong>High-ragequit pools aren't broken.</strong> Ragequit firing is the system working as designed when the ASP excludes a commitment.</li>
<li><strong>The fee figures are operator drains, not gross protocol revenue.</strong> The Entrypoint emits post-fee deposit values, so we can only observe the cashflow at the <code>FeesWithdrawn</code> step.</li>
</ul>
<p>Any heuristic an analyst can run, a depositor can game. Anyone can construct decoy patterns at low cost. Anyone can split deposits across rounds, jitter timing, and rotate recipient addresses. Public-data heuristics are a probability surface, not a truth function. Privacy Pools is built for exactly that constraint.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-this-was-indexed">How this was indexed<a class="hash-link" aria-label="Direct link to How this was indexed" title="Direct link to How this was indexed" href="https://docs.envio.dev/blog/privacy-in-public-case-study#how-this-was-indexed">​</a></h2>
<p>The full stack is one Envio HyperIndex v3 indexer running locally with dual Postgres + ClickHouse storage:</p>
<ul>
<li><strong>One config</strong>, four chains: Ethereum (1), Optimism (10), BSC (56), Arbitrum (42161). Same <code>Entrypoint</code> and <code>PrivacyPool</code> ABIs reused across all four. The L2s share a deterministic <code>0x44192215…</code> Entrypoint via CreateX, while mainnet has the original <code>0x6818809E…</code>.</li>
<li><strong>One handler set</strong> writes 9 entity types: <code>Pool</code>, <code>Deposit</code>, <code>Withdrawal</code>, <code>Ragequit</code>, <code>MerkleLeaf</code>, <code>AssociationSetRoot</code>, <code>Account</code>, <code>FeeWithdrawal</code>, plus a derived <code>LatestPrice</code>/<code>TokenPrice</code> pair from a thin Uniswap V4 price feed on BSC. All chain-scoped IDs (<code>{chainId}_{address}</code>) so the L2 ETH-pool address collision (<code>0x4626…918ff</code> is the ETH pool on Optimism, BSC, <em>and</em> Arbitrum) doesn't fold rows together.</li>
<li><strong>Multichain sync to head: ~30 seconds.</strong> HyperSync handles 4 chains in parallel; the only non-trivial cost is the V4 price feed, which we keep cheap by starting near BSC's head and filtering Swap events to ~70 hardcoded pricing-pool IDs (see <a href="https://developers.uniswap.org/contracts/v4/deployments" target="_blank" rel="noopener noreferrer">Uniswap V4 deployments</a>). No Initialize handler, no historical V4 backfill, just current prices.</li>
<li><strong>Analytics on ClickHouse.</strong> A Python <code>analytics/</code> package runs the headline queries through <code>clickhouse-connect</code>, charts them with matplotlib, and assembles a markdown BI report that renders to PDF via <code>reportlab</code>. The full report regenerates in a couple of seconds against the live ClickHouse.</li>
</ul>
<p>The schema and the SQL queries are designed for this kind of question. Adding a new heuristic, say "deposits whose precommitment hash has a leading-zero prefix", is an <code>.sql</code> file, not a re-index.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="reproducing-this">Reproducing this<a class="hash-link" aria-label="Direct link to Reproducing this" title="Direct link to Reproducing this" href="https://docs.envio.dev/blog/privacy-in-public-case-study#reproducing-this">​</a></h2>
<p>The full stack lives at <a href="https://github.com/enviodev/privacy-pools" target="_blank" rel="noopener noreferrer"><strong>github.com/enviodev/privacy-pools</strong></a> under MIT license. One HyperIndex v3 indexer plus a Python analytics package that ships the BI report generator and every saved query.</p>
<ul>
<li><code>config.yaml</code>, <code>schema.graphql</code>, <code>src/EventHandlers.ts</code>, <code>src/v4Pricing.ts</code>, <code>src/v4PoolMeta.ts</code>: the indexer.</li>
<li><code>analytics/queries/{health,anonymity,risk,asp,relayers,fees,activity,pricing}/*.sql</code>: every metric in this post.</li>
<li><code>analytics/scripts/generate_bi_report.py</code>: assembles the report markdown plus 6 charts.</li>
<li><code>analytics/scripts/render_pdf.py</code>: markdown to PDF, including image embedding.</li>
</ul>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> clone https://github.com/enviodev/privacy-pools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> privacy-pools</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">cp</span><span class="token plain"> .env.example .env  </span><span class="token comment" style="color:rgb(98, 114, 164)"># add your free ENVIO_API_TOKEN from envio.dev</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> envio start</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># in another shell</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> analytics</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">cp</span><span class="token plain"> .env.example .env</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">uv </span><span class="token function" style="color:rgb(80, 250, 123)">sync</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">uv run python scripts/generate_bi_report.py</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Multichain sync completes in well under a minute. The BI report regenerates against live ClickHouse in seconds.</p>
<p>If you want to extend the analysis (chain-cross transitive linkability, ASP root vs deposit timing, relayer-collusion graphs, or anything else), every entity carries <code>chainId</code> and <code>blockNumber</code>, and the schema is documented end-to-end in <code>analytics/CLAUDE.md</code>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build with Envio<a class="hash-link" aria-label="Direct link to Build with Envio" title="Direct link to Build with Envio" href="https://docs.envio.dev/blog/privacy-in-public-case-study#build-with-envio">​</a></h2>
<p>Envio HyperIndex is independently benchmarked as the fastest EVM blockchain indexer available. The Privacy Pools indexer is one example of what's possible when multichain coverage and an analytics-grade columnar store are first-class features. If you're building onchain (DeFi, prediction markets, gaming, or something nobody has thought of yet), the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a> are the starting point.</p>
<ul>
<li>Repo: <a href="https://github.com/enviodev/privacy-pools" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/privacy-pools</a></li>
<li>Docs: <a href="https://docs.envio.dev/" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/</a></li>
<li>Discord: <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">https://discord.gg/envio</a></li>
<li>Telegram: <a href="https://t.me/+kAIGElzPjApiMjI0" target="_blank" rel="noopener noreferrer">https://t.me/+kAIGElzPjApiMjI0</a></li>
<li>X: <a href="https://x.com/envio_indexer" target="_blank" rel="noopener noreferrer">https://x.com/envio_indexer</a></li>
</ul>]]></content:encoded>
            <category>case-studies</category>
        </item>
        <item>
            <title><![CDATA[How Revert Finance Fixed 2 Years of Unsynced PancakeSwap V3 Data with Envio]]></title>
            <link>https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex</link>
            <guid>https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex</guid>
            <pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Revert Finance's PancakeSwap V3 subgraph on The Graph had been stuck at 70% sync on BNB Smart Chain for over 2 years. Envio HyperIndex synced it to 100% in 10 days, processing 1.7 billion events.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/revert-hyperindex-case-study.png" alt="How Revert Finance Fixed 2 Years of Unsynced PancakeSwap V3 Data with Envio" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Revert Finance's PancakeSwap V3 subgraph on The Graph had been stuck at 70% sync on BNB Smart Chain for over 2 years.</li>
<li>Envio HyperIndex synced 1,711,569,200 events to 100% in 10 days, solving a problem that had gone unresolved for over 2 years.</li>
<li>HyperSync eliminates the RPC bottleneck that causes other indexing frameworks to stall on high-throughput chains, like BNB Smart Chain, while HyperIndex's batch processing and caching ensure the indexer keeps up with the throughput.</li>
</ul></div></div>
<p>Revert Finance builds analytics and management tools for AMM liquidity providers across protocols including PancakeSwap, Uniswap, and others. Accurate, real-time onchain data is the foundation of everything they build.</p>
<p>They run several indexers using Envio, spanning multiple chains and contracts. This case study covers one of them: a PancakeSwap V3 indexer on BNB Smart Chain. Their previous subgraph had been stuck at 70% sync for over 2 years, unable to reach the chain's head.</p>
<img src="https://docs.envio.dev/blog-assets/revert-hyperindex-case-study-1.png" alt="PancakeSwap V3 subgraph on The Graph stuck at 70% sync on BNB Smart Chain" width="100%">
<p>The subgraph instance can be viewed here: <a href="https://thegraph.com/explorer/subgraphs/Hv1GncLY5docZoGtXjo4kwbTvxm3MAhVZqBZE4sUT9eZ?view=Query&amp;chain=bsc" target="_blank" rel="noopener noreferrer">https://thegraph.com/explorer/subgraphs/Hv1GncLY5docZoGtXjo4kwbTvxm3MAhVZqBZE4sUT9eZ?view=Query&amp;chain=bsc</a></p>
<p>Envio built a HyperIndex indexer for PancakeSwap V3 on BNB Smart Chain. It synced 1,711,569,200 events to 100% in 10 days.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem-revert-finance-needed-to-solve">The Problem Revert Finance Needed to Solve<a class="hash-link" aria-label="Direct link to The Problem Revert Finance Needed to Solve" title="Direct link to The Problem Revert Finance Needed to Solve" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#the-problem-revert-finance-needed-to-solve">​</a></h2>
<p>Revert Finance requires real-time PancakeSwap V3 position and liquidity data to power its analytics and tooling for liquidity providers. A public subgraph on The Graph's decentralized network had been stuck at 70% sync on BNB Smart Chain for over 2 years, unable to reach chain head.</p>
<p>BNB Smart Chain's high throughput has presented well-documented challenges for RPC-based indexing, with teams reporting sync issues going back to 2021. The volume of events per block outpaces what standard indexing infrastructure can sustain, causing subgraphs to fall progressively further behind until they stall entirely.</p>
<p>A subgraph stuck at 70% sync for over 2 years is effectively unusable.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-solution-envio-hyperindex-on-bnb-smart-chain">The Solution: Envio HyperIndex on BNB Smart Chain<a class="hash-link" aria-label="Direct link to The Solution: Envio HyperIndex on BNB Smart Chain" title="Direct link to The Solution: Envio HyperIndex on BNB Smart Chain" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#the-solution-envio-hyperindex-on-bnb-smart-chain">​</a></h2>
<p>Envio HyperIndex is a real-time multichain blockchain indexing framework for any EVM chain. Developers write event handlers in TypeScript and deploy a single indexer covering multiple contracts and chains simultaneously. It uses HyperSync, Envio's proprietary data engine, which serves filtered event data in bulk directly from a purpose-built data lake, replacing having to poll RPC endpoints block by block. This removes the RPC bottleneck entirely, which is precisely what causes subgraph stalls on BNB Smart Chain.</p>
<p>HyperIndex is independently benchmarked as the fastest blockchain indexer available. In the Uniswap V2 Factory benchmark run by Sentio in May 2025, HyperIndex synced in 1 minute, 143x faster than The Graph and 15x faster than the nearest competitor. BNB Smart Chain is one of <!-- -->87+<!-- --> EVM chains with native HyperSync coverage.</p>
<p>For a full benchmark breakdown see the <a href="https://docs.envio.dev/docs/HyperIndex/benchmarks" target="_blank" rel="noopener noreferrer">complete blockchain indexer comparison</a>.</p>
<p>Envio built a HyperIndex indexer covering PancakeSwap V3 on BNB Smart Chain, tracking Factory, Pool, and NFPM (Non-Fungible Position Manager) contracts from block 26,956,207.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="contracts-indexed">Contracts Indexed<a class="hash-link" aria-label="Direct link to Contracts Indexed" title="Direct link to Contracts Indexed" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#contracts-indexed">​</a></h3>
<p>The indexer covers the full PancakeSwap V3 contract surface on BNB Smart Chain:</p>
<ul>
<li><strong>Factory</strong> (<code>0x0bfbcf9fa4f9c56b0f40a671ad40e0805a091865</code>): Pool creation and registry</li>
<li><strong>Pool</strong> (dynamic): All Pool events across all dynamically registered pool instances</li>
<li><strong>NFPM</strong> (<code>0x46a15b0b27311cedf172ab29e4f4766fbe7f4364</code>): NFT position management events</li>
</ul>
<p>Dynamic contract registration handles the Pool contracts. As new PancakeSwap V3 pools are created onchain by the Factory, the indexer registers them automatically without requiring a redeployment.</p>
<img src="https://docs.envio.dev/blog-assets/revert-hyperindex-case-study-2.png" alt="Revert Finance PancakeSwap V3 indexer running on Envio" width="100%">
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-results">The Results<a class="hash-link" aria-label="Direct link to The Results" title="Direct link to The Results" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#the-results">​</a></h2>
<table><thead><tr><th>Metric</th><th>Result</th></tr></thead><tbody><tr><td>Chain</td><td>BNB Smart Chain (chain ID 56)</td></tr><tr><td>Events processed</td><td>1,711,569,200</td></tr><tr><td>Historical sync time</td><td>10 days</td></tr><tr><td>Final sync status</td><td>100% at block 88,286,723</td></tr><tr><td>Start block</td><td>26,956,207</td></tr></tbody></table>
<p>Over 1.7 billion events, fully synced, on a chain where the equivalent subgraph had been stuck for over 2 years. The indexer is hosted on Envio Cloud, Envio's managed hosting platform.</p>
<img src="https://docs.envio.dev/blog-assets/revert-hyperindex-case-study-3.png" alt="Revert Finance PancakeSwap V3 indexer synced to 100% on BNB Smart Chain in 10 days" width="100%">
<div style="margin:2rem 0;padding:1.5rem 2rem;border-left:4px solid #f97316;background:rgba(249,115,22,0.06);border-radius:0 8px 8px 0"><p style="font-size:1.1rem;font-style:italic;margin-bottom:0.75rem">"We had a problem with our PancakeSwap V3 data on BNB for over two years. The subgraph just would not catch up, and we'd basically given up on it. Envio synced it in 10 days. Great team, great dev experience!"</p><p style="margin:0;font-weight:600">Mario Romero, Founder at Revert Finance</p></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-vs-the-graph-on-bnb-smart-chain">Envio vs The Graph on BNB Smart Chain<a class="hash-link" aria-label="Direct link to Envio vs The Graph on BNB Smart Chain" title="Direct link to Envio vs The Graph on BNB Smart Chain" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#envio-vs-the-graph-on-bnb-smart-chain">​</a></h2>
<table><thead><tr><th></th><th>The Graph (subgraph)</th><th>Envio HyperIndex</th></tr></thead><tbody><tr><td>BNB Smart Chain sync status</td><td>Stuck, unable to reach chain head for 2+ years</td><td>100% synced in 10 days</td></tr><tr><td>Language</td><td>AssemblyScript</td><td>TypeScript</td></tr><tr><td>Real-time data availability</td><td>No</td><td>Yes</td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-high-throughput-chains-need-hypersync">Why High-Throughput Chains Need HyperSync<a class="hash-link" aria-label="Direct link to Why High-Throughput Chains Need HyperSync" title="Direct link to Why High-Throughput Chains Need HyperSync" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#why-high-throughput-chains-need-hypersync">​</a></h2>
<p>BNB Smart Chain is not an edge case. Any high-throughput EVM chain, whether BNB Smart Chain, Polygon, or a high-activity L2, generates event volumes that stress RPC-based indexing. The pattern is the same: subgraph starts syncing, falls progressively further behind, eventually stalls.</p>
<p>HyperSync eliminates this failure mode by removing RPC polling from the historical sync path entirely. Event data is retrieved in bulk from Envio's data lake, meaning sync speed scales with data volume rather than being bottlenecked by RPC rate limits and polling intervals.</p>
<p>For protocols like Revert Finance that require accurate, real-time onchain data to power liquidity analytics, this is the difference between functional infrastructure and a permanently stale data source.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#get-started">​</a></h2>
<ul>
<li>Quickstart: <a href="https://docs.envio.dev/docs/HyperIndex/contract-import" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperIndex/contract-import</a></li>
<li>Envio docs: <a href="https://docs.envio.dev/" target="_blank" rel="noopener noreferrer">https://docs.envio.dev</a></li>
<li>Discord: <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">https://discord.gg/envio</a></li>
<li>Telegram: <a href="https://t.me/+kAIGElzPjApiMjI0" target="_blank" rel="noopener noreferrer">https://t.me/+kAIGElzPjApiMjI0</a></li>
<li>Follow us on X: <a href="https://x.com/envio_indexer" target="_blank" rel="noopener noreferrer">https://x.com/envio_indexer</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-revert-finance">What is Revert Finance?<a class="hash-link" aria-label="Direct link to What is Revert Finance?" title="Direct link to What is Revert Finance?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-revert-finance">​</a></h3>
<p>Revert Finance builds analytics and management tools for liquidity providers in AMM protocols. Its tooling covers position analytics, auto-compounding, and liquidity management across protocols including PancakeSwap, Uniswap, and others.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-pancakeswap-v3">What is PancakeSwap V3?<a class="hash-link" aria-label="Direct link to What is PancakeSwap V3?" title="Direct link to What is PancakeSwap V3?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-pancakeswap-v3">​</a></h3>
<p>PancakeSwap V3 is the concentrated liquidity version of PancakeSwap, the largest decentralized exchange on BNB Smart Chain. V3 introduces capital-efficient liquidity positions represented as NFTs, managed via the Non-Fungible Position Manager contract.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-a-blockchain-indexer">What is a blockchain indexer?<a class="hash-link" aria-label="Direct link to What is a blockchain indexer?" title="Direct link to What is a blockchain indexer?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-a-blockchain-indexer">​</a></h3>
<p>A blockchain indexer is a system that listens to onchain events and organises them into a structured, queryable database. Developers use blockchain indexers to build fast backends for DeFi protocols, analytics tools, and trading interfaces without querying slow RPC endpoints directly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hyperindex">What is HyperIndex?<a class="hash-link" aria-label="Direct link to What is HyperIndex?" title="Direct link to What is HyperIndex?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-hyperindex">​</a></h3>
<p>Envio HyperIndex is a real-time multichain blockchain indexing framework for EVM chains. Developers write event handlers in TypeScript and deploy a single indexer covering multiple contracts, chains, and domains. It uses HyperSync, Envio's proprietary data engine, to fetch filtered event data in bulk rather than polling RPC endpoints, enabling historical syncs at speeds not achievable through standard RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hypersync">What is HyperSync?<a class="hash-link" aria-label="Direct link to What is HyperSync?" title="Direct link to What is HyperSync?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-hypersync">​</a></h3>
<p>HyperSync is Envio's high-performance data engine. Instead of querying RPC endpoints block by block, HyperSync fetches and serves filtered event data in bulk from a purpose-built data lake, delivering up to 2,000x faster data access than traditional RPC. BNB Smart Chain is one of <!-- -->87+<!-- --> EVM chains with native HyperSync coverage. Any EVM chain can be indexed via standard RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-envio-cloud">What is Envio Cloud?<a class="hash-link" aria-label="Direct link to What is Envio Cloud?" title="Direct link to What is Envio Cloud?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-is-envio-cloud">​</a></h3>
<p>Envio Cloud is Envio's managed hosting platform for HyperIndex indexers. It handles infrastructure, scaling, and monitoring so teams can run production-ready indexers without managing operational overhead. Revert Finance's PancakeSwap V3 indexer runs on Envio Cloud.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-chains-does-envio-support">What chains does Envio support?<a class="hash-link" aria-label="Direct link to What chains does Envio support?" title="Direct link to What chains does Envio support?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#what-chains-does-envio-support">​</a></h3>
<p>Envio supports any EVM chain. <!-- -->87+<!-- --> EVM chains have native HyperSync coverage for maximum speed, including BNB Smart Chain, Polygon, Ethereum, Base, Arbitrum, Optimism, and more. Any EVM chain without native HyperSync support can be indexed via standard RPC. See the full list of supported chains at <a href="https://envio.dev/chains" target="_blank" rel="noopener noreferrer">envio.dev/chains</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-migrate-from-the-graph-to-hyperindex">How do I migrate from The Graph to HyperIndex?<a class="hash-link" aria-label="Direct link to How do I migrate from The Graph to HyperIndex?" title="Direct link to How do I migrate from The Graph to HyperIndex?" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#how-do-i-migrate-from-the-graph-to-hyperindex">​</a></h3>
<p>Because HyperIndex handlers are written in TypeScript and AssemblyScript is a subset of TypeScript, most handler logic can be carried across directly. Envio provides a full <a href="https://docs.envio.dev/docs/HyperIndex/migration-guide" target="_blank" rel="noopener noreferrer">migration guide</a>, a CLI validation tool to compare output between both endpoints, and white-glove migration support for teams moving from The Graph.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/revert-finance-pancakeswap-bnb-hyperindex#build-with-envio">​</a></h2>
<p>Envio is independently benchmarked as the fastest EVM blockchain indexer available. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, or come talk to us about your data needs.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://x.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+kAIGElzPjApiMjI0" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>case-studies</category>
        </item>
        <item>
            <title><![CDATA[What is HyperSync?]]></title>
            <link>https://docs.envio.dev/blog/what-is-hypersync</link>
            <guid>https://docs.envio.dev/blog/what-is-hypersync</guid>
            <pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[HyperSync is Envio's high-performance blockchain data layer, up to 2000x faster than RPC across dozens of supported chains. Learn what it is, how it works, and how to query it.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="Cover image for the What is HyperSync blog" src="https://docs.envio.dev/assets/images/what-is-hypersync-7a7de2b58c25bf12079cf2fc4bd4c175.png" width="1906" height="1115" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperSync is Envio's high-performance blockchain data-retrieval layer.</li>
<li>Up to 2000x faster than RPC for getting or fetching the logs, transactions, traces, and blocks across <!-- -->87+<!-- --> chains.</li>
<li>Primary data source for HyperIndex and the data layer behind products like <a href="https://chaindensity.xyz/" target="_blank" rel="noopener noreferrer">ChainDensity.xyz</a>, <a href="https://scope.sh/" target="_blank" rel="noopener noreferrer">Scope.sh</a>, LogTUI, and the Polymarket reference indexer (4 billion events in 6 days).</li>
<li>Client libraries available for TypeScript/Node.js, Python, Rust, and Go.</li>
</ul></div></div>
<p>Reading onchain data is one of the slowest, most expensive parts of building any Web3 product or service. Standard JSON-RPC endpoints work for one-off lookups, but break down the moment you need fast or filtered historical data, multichain coverage, or anything more than a handful of blocks at a time. HyperSync exists to fix that. This post covers what HyperSync is, why Envio built it, how it works, and how to use it in your own application.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem-with-rpc">The Problem with RPC<a class="hash-link" aria-label="Direct link to The Problem with RPC" title="Direct link to The Problem with RPC" href="https://docs.envio.dev/blog/what-is-hypersync#the-problem-with-rpc">​</a></h2>
<p>Reading onchain data over JSON-RPC is the default path most teams start with. It also breaks the moment your needs go beyond a single contract on a single chain.</p>
<p>Three things happen as soon as you scale:</p>
<ul>
<li><strong>Speed.</strong> Backfilling a year of events across an L2 takes hours or days because RPC was designed to serve one request at a time, not stream historical data in bulk.</li>
<li><strong>Query Flexibility.</strong> RPC limits you to small block windows, typically 100 to 1000 blocks per request depending on the provider, with strict rate limits and inconsistent behavior across providers. Anything more sophisticated, like fetching every <code>PoolCreated</code> event across an entire chain, still requires hundreds or thousands of separate calls and bespoke retry logic.</li>
<li><strong>Cost.</strong> Data-intensive workloads on premium RPC providers add up fast, and you are still rate-limited at the moment you most need throughput.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-hypersync-is">What HyperSync Is<a class="hash-link" aria-label="Direct link to What HyperSync Is" title="Direct link to What HyperSync Is" href="https://docs.envio.dev/blog/what-is-hypersync#what-hypersync-is">​</a></h2>
<p>HyperSync is a purpose-built data retrieval layer that gives developers direct access to blockchain data at speeds RPC cannot match. It is written in Rust, uses optimised binary encoding and parallel fetching, and exposes a query API that is both fast at serving requested data and flexible about how that data can be filtered and shaped.</p>
<p>Where RPC is a single endpoint serving one block of data at a time, HyperSync is a streaming query engine. You describe what you want once, in a single query object, and it streams back exactly that data across whatever block range you asked for.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="performance-verified">Performance, Verified<a class="hash-link" aria-label="Direct link to Performance, Verified" title="Direct link to Performance, Verified" href="https://docs.envio.dev/blog/what-is-hypersync#performance-verified">​</a></h2>
<p>The numbers below are pulled from the <a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync overview</a>.</p>
<table><thead><tr><th>Task</th><th>Traditional RPC</th><th>HyperSync</th><th>Improvement</th></tr></thead><tbody><tr><td>Scan Arbitrum for sparse log data</td><td>Hours to days</td><td>2 seconds</td><td>~2000x faster</td></tr><tr><td>Fetch all Uniswap v3 <code>PoolCreated</code> events on Ethereum</td><td>Hours</td><td>Seconds</td><td>~500x faster</td></tr></tbody></table>
<p>HyperSync is also the data layer powering HyperIndex, the fastest blockchain indexer available. Sentio's independent Uniswap V2 Factory benchmark (May 2025) measured HyperIndex completing the test in 1 minute, 143x faster than The Graph and 15x faster than the nearest competitor (Subsquid).</p>
<p>In production, that translates into projects like the Polymarket reference indexer, which synced 4 billion events in 6 days and replaced 8 separate subgraphs with a single HyperIndex deployment powered by HyperSync.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-hypersync-works">How HyperSync Works<a class="hash-link" aria-label="Direct link to How HyperSync Works" title="Direct link to How HyperSync Works" href="https://docs.envio.dev/blog/what-is-hypersync#how-hypersync-works">​</a></h2>
<p>There are four primitives you need to understand to use HyperSync.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-queries">1. Queries<a class="hash-link" aria-label="Direct link to 1. Queries" title="Direct link to 1. Queries" href="https://docs.envio.dev/blog/what-is-hypersync#1-queries">​</a></h3>
<p>A query is a single object that describes the data you want. It includes a block range, a set of filters, and a field selection. You hand it to a HyperSync client and it streams matching results back to you.</p>
<p>Here is a working query in TypeScript that streams every Uniswap v3 event from Ethereum mainnet, starting at genesis. This pattern is taken from the Polymarket trades tutorial and the API Tokens implementation guide.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@envio-dev/hypersync-client"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> keccak256</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> toHex </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"viem"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> event_signatures </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"PoolCreated(address,address,uint24,int24,address)"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"Burn(address,int24,int24,uint128,uint256,uint256)"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"Initialize(uint160,int24)"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"Mint(address,address,int24,int24,uint128,uint256,uint256)"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"Swap(address,address,int256,int256,uint160,uint128,int24)"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> topic0_list </span><span class="token operator">=</span><span class="token plain"> event_signatures</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">sig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">keccak256</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">toHex</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">sig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://eth.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> query</span><span class="token operator">:</span><span class="token plain"> Query </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fromBlock</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  logs</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> topics</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">topic0_list</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fieldSelection</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    log</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic3"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> stream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> res </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">recv</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res </span><span class="token operator">===</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data</span><span class="token operator">?.</span><span class="token plain">logs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">Got </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">res</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">data</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">logs</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">length</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)"> logs</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">nextBlock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">fromBlock </span><span class="token operator">=</span><span class="token plain"> res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">nextBlock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-filters">2. Filters<a class="hash-link" aria-label="Direct link to 2. Filters" title="Direct link to 2. Filters" href="https://docs.envio.dev/blog/what-is-hypersync#2-filters">​</a></h3>
<p>You can filter on logs, transactions, traces, and blocks, alone or in combination. Filters narrow down what HyperSync streams back, so you only pay for the data you actually need.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// TypeScript: every USDC Transfer in a given block range</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> logSelection </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  address</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  topics</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Trace filters give you access to execution traces and internal transactions, which is the only way to track native ETH transfers since they do not emit event logs. Traces are accessed via a separate trace-enabled endpoint, for example <code>https://eth-traces.hypersync.xyz</code>. The <a href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync">Native ETH Transfers tutorial</a> walks through that pattern end to end.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-field-selection">3. Field Selection<a class="hash-link" aria-label="Direct link to 3. Field Selection" title="Direct link to 3. Field Selection" href="https://docs.envio.dev/blog/what-is-hypersync#3-field-selection">​</a></h3>
<p>HyperSync lets you ask for only the fields you need. Smaller responses, less bandwidth, faster downstream processing.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> fieldSelection </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  block</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Number"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Timestamp"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  transaction</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Hash"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"From"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"To"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  log</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"Address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="4-output-modes">4. Output Modes<a class="hash-link" aria-label="Direct link to 4. Output Modes" title="Direct link to 4. Output Modes" href="https://docs.envio.dev/blog/what-is-hypersync#4-output-modes">​</a></h3>
<p>HyperSync gives you three ways to consume results:</p>
<ul>
<li><code>client.stream(query, config)</code> for direct in-memory processing.</li>
<li><code>client.collect_json(path, query, config)</code> for smaller datasets and debugging.</li>
<li><code>client.collect_parquet(path, query, config)</code> for analytical workloads on large datasets.</li>
</ul>
<p>Streaming is the right default for indexers and real-time applications. Parquet is the right default for ETL pipelines and data science work.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="switching-networks">Switching Networks<a class="hash-link" aria-label="Direct link to Switching Networks" title="Direct link to Switching Networks" href="https://docs.envio.dev/blog/what-is-hypersync#switching-networks">​</a></h2>
<p>Switching chains is a one-line change. The same client works against any of the <!-- -->87+<!-- --> supported networks by changing the URL.</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// Ethereum</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://eth.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Arbitrum</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://arbitrum.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Base</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://base.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The full list of network URLs is on the <a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" target="_blank" rel="noopener noreferrer">Supported Networks</a> page.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="try-hypersync-in-30-seconds">Try HyperSync in 30 Seconds<a class="hash-link" aria-label="Direct link to Try HyperSync in 30 Seconds" title="Direct link to Try HyperSync in 30 Seconds" href="https://docs.envio.dev/blog/what-is-hypersync#try-hypersync-in-30-seconds">​</a></h2>
<p>The fastest way to feel HyperSync is to install nothing.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx logtui aave arbitrum</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>That command launches LogTUI, a terminal-based blockchain event viewer built on HyperSync, and starts streaming Aave events on Arbitrum into your terminal in real time. LogTUI ships with presets for 20+ protocols including Uniswap, Chainlink, Aave, and ENS.</p>
<p>When you are ready for a real client, clone the hypersync-quickstart repo and run one of the included scripts.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">git</span><span class="token plain"> clone https://github.com/enviodev/hypersync-quickstart.git</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> hypersync-quickstart</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">pnpm</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">node</span><span class="token plain"> run-simple.js</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>You will need an API token. Set it as an environment variable.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token builtin class-name" style="color:rgb(189, 147, 249)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">ENVIO_API_TOKEN</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">"your-api-token-here"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Generate a token from <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">envio.dev/app/api-tokens</a> and read the <a href="https://docs.envio.dev/docs/HyperSync/api-tokens" target="_blank" rel="noopener noreferrer">API Tokens guide</a> for usage and security best practices.</p>
<p>If you are building a full indexer with schema management, event handlers, and a hosted GraphQL API, jump to the <a href="https://docs.envio.dev/docs/HyperIndex/contract-import" target="_blank" rel="noopener noreferrer">HyperIndex Quickstart</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="handling-large-backfills">Handling Large Backfills<a class="hash-link" aria-label="Direct link to Handling Large Backfills" title="Direct link to Handling Large Backfills" href="https://docs.envio.dev/blog/what-is-hypersync#handling-large-backfills">​</a></h2>
<p>A single HyperSync request has a 5-second processing window. For a fresh historical backfill across a high-volume chain, loop through block ranges by feeding the <code>nextBlock</code> from each response back into the next query.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">current_block </span><span class="token operator">=</span><span class="token plain"> start_block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">while</span><span class="token plain"> current_block </span><span class="token operator">&lt;</span><span class="token plain"> end_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from_block </span><span class="token operator">=</span><span class="token plain"> current_block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to_block </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">current_block </span><span class="token operator">+</span><span class="token plain"> </span><span class="token number">1_000_000</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> end_block</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">collect_parquet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    current_block </span><span class="token operator">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">end_block </span><span class="token operator">+</span><span class="token plain"> </span><span class="token number">1</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>For most use cases, the streaming client handles this automatically.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="use-cases">Use Cases<a class="hash-link" aria-label="Direct link to Use Cases" title="Direct link to Use Cases" href="https://docs.envio.dev/blog/what-is-hypersync#use-cases">​</a></h2>
<p>HyperSync makes a class of applications practical that traditional RPC cannot reasonably support.</p>
<ul>
<li><strong>Blockchain indexers</strong> that build high-performance data pipelines with minimal infrastructure.</li>
<li><strong>Data analytics</strong> that runs complex onchain analysis in seconds instead of days.</li>
<li><strong>Block explorers</strong> that serve responsive UIs with comprehensive historical access.</li>
<li><strong>Monitoring tools</strong> that track blockchain activity with near real-time updates.</li>
<li><strong>Cross-chain applications</strong> that pull unified data across multiple networks from a single query interface.</li>
<li><strong>ETL pipelines</strong> that extract onchain data into data warehouses fast.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-hypersync-powers">What HyperSync Powers<a class="hash-link" aria-label="Direct link to What HyperSync Powers" title="Direct link to What HyperSync Powers" href="https://docs.envio.dev/blog/what-is-hypersync#what-hypersync-powers">​</a></h2>
<p>HyperSync is the data engine underneath a growing set of tools and applications.</p>
<p><strong>HyperIndex</strong> is Envio's full indexing framework. It uses HyperSync as its primary data source, then layers on schema management, event handlers, multichain support, automatic reorg handling, and a hosted GraphQL API. HyperIndex is the fastest blockchain indexer available, 143x faster than The Graph and 15x faster than Subsquid on the Sentio Uniswap V2 Factory benchmark (May 2025).</p>
<p><strong><a href="https://chaindensity.xyz/" target="_blank" rel="noopener noreferrer">ChainDensity.xyz</a></strong> uses HyperSync to render transaction and event density across any address on any supported chain. It generates insights in seconds that would take hours over RPC.</p>
<p><strong><a href="https://scope.sh/" target="_blank" rel="noopener noreferrer">Scope.sh</a></strong> is an Account Abstraction-focused block explorer that uses HyperSync for ultra-fast historical data retrieval.</p>
<p><strong>LogTUI</strong> is the zero-install event viewer mentioned above. Try <code>pnpx logtui --help</code> for the full list of presets.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="when-to-use-hypersync-vs-hyperindex">When to Use HyperSync vs HyperIndex<a class="hash-link" aria-label="Direct link to When to Use HyperSync vs HyperIndex" title="Direct link to When to Use HyperSync vs HyperIndex" href="https://docs.envio.dev/blog/what-is-hypersync#when-to-use-hypersync-vs-hyperindex">​</a></h2>
<p>A common question. The short answer.</p>
<p>Use <strong>HyperSync</strong> directly when you want raw blockchain data at maximum speed and you are happy to manage your own pipeline, storage, and downstream API. Good fits include analytics scripts, ETL into a data warehouse, custom alert systems, and anything that needs the absolute thinnest layer between you and the data.</p>
<p>Use <strong>HyperIndex</strong> when you want a complete indexing framework with schema management, event handlers, GraphQL output, multichain support, automatic reorg handling, and managed hosting on Envio Cloud. Good fits include application backends, dashboards, and anything where you would otherwise reach for The Graph or Subsquid. HyperIndex is itself powered by HyperSync.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="common-patterns">Common Patterns<a class="hash-link" aria-label="Direct link to Common Patterns" title="Direct link to Common Patterns" href="https://docs.envio.dev/blog/what-is-hypersync#common-patterns">​</a></h2>
<p>Three patterns we see most often from teams adopting HyperSync.</p>
<p><strong>Pattern 1. Replace a slow RPC backfill.</strong> A team has an existing indexer that takes days to backfill from genesis. Swapping the RPC source for HyperSync brings that down to minutes. The Polymarket case study is the canonical example, with 4 billion events synced in 6 days.</p>
<p><strong>Pattern 2. Query across many chains in one place.</strong> A team builds a multichain dashboard and is tired of stitching together a dozen RPC providers. HyperSync exposes the same query interface for every supported chain, so the only thing that changes between Ethereum, Arbitrum, Base, and Optimism is the URL.</p>
<p><strong>Pattern 3. Build a niche analytics tool fast.</strong> ChainDensity, Scope, and LogTUI are all examples. HyperSync makes it cheap to ship the kind of tool that would otherwise need a dedicated data team.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="pricing-and-access">Pricing and Access<a class="hash-link" aria-label="Direct link to Pricing and Access" title="Direct link to Pricing and Access" href="https://docs.envio.dev/blog/what-is-hypersync#pricing-and-access">​</a></h2>
<p>HyperSync requires an API token. API tokens have been required since 3 November 2025. Generate a token at <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">envio.dev/app/api-tokens</a> and read the <a href="https://docs.envio.dev/docs/HyperSync/api-tokens" target="_blank" rel="noopener noreferrer">API Tokens documentation</a> for limits, usage tracking (requests and credits), and security best practices. Indexers deployed to Envio Cloud have special access to HyperSync and do not require a custom API token. For production tier options, see the <a href="https://envio.dev/pricing" target="_blank" rel="noopener noreferrer">Envio pricing page</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/what-is-hypersync#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-fast-is-hypersync-compared-to-rpc">How Fast Is HyperSync Compared to RPC?<a class="hash-link" aria-label="Direct link to How Fast Is HyperSync Compared to RPC?" title="Direct link to How Fast Is HyperSync Compared to RPC?" href="https://docs.envio.dev/blog/what-is-hypersync#how-fast-is-hypersync-compared-to-rpc">​</a></h3>
<p>HyperSync is up to 2000x faster than RPC for sparse log scans. Scanning Arbitrum for sparse log data takes 2 seconds with HyperSync, versus hours or days over RPC. Fetching every Uniswap v3 <code>PoolCreated</code> event on Ethereum is roughly 500x faster.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-chains-does-hypersync-support">What Chains Does HyperSync Support?<a class="hash-link" aria-label="Direct link to What Chains Does HyperSync Support?" title="Direct link to What Chains Does HyperSync Support?" href="https://docs.envio.dev/blog/what-is-hypersync#what-chains-does-hypersync-support">​</a></h3>
<p>HyperSync is natively available on <!-- -->87+<!-- --> chains, including Fuel, with new networks added regularly. The full list is on the <a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" target="_blank" rel="noopener noreferrer">Supported Networks</a> page.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-client-libraries-are-available">What Client Libraries Are Available?<a class="hash-link" aria-label="Direct link to What Client Libraries Are Available?" title="Direct link to What Client Libraries Are Available?" href="https://docs.envio.dev/blog/what-is-hypersync#what-client-libraries-are-available">​</a></h3>
<p>HyperSync ships official client libraries in Python, Rust, Node.js, and Go. There is also a curl interface for quick testing.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="do-i-need-an-api-token">Do I Need an API Token?<a class="hash-link" aria-label="Direct link to Do I Need an API Token?" title="Direct link to Do I Need an API Token?" href="https://docs.envio.dev/blog/what-is-hypersync#do-i-need-an-api-token">​</a></h3>
<p>Yes. API tokens have been required since 3 November 2025. Generate a token at <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">envio.dev/app/api-tokens</a> and pass it as <code>apiToken</code> in TypeScript or <code>bearer_token</code> in Python. Indexers deployed to Envio Cloud have special access and do not need a custom token.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-is-hypersync-different-from-hyperindex">How Is HyperSync Different from HyperIndex?<a class="hash-link" aria-label="Direct link to How Is HyperSync Different from HyperIndex?" title="Direct link to How Is HyperSync Different from HyperIndex?" href="https://docs.envio.dev/blog/what-is-hypersync#how-is-hypersync-different-from-hyperindex">​</a></h3>
<p>HyperSync is the raw data layer. HyperIndex is the full indexing framework built on top of it. Use HyperSync directly when you want maximum speed and full control of your pipeline. Use HyperIndex when you want schema management, event handlers, GraphQL APIs, automatic reorg handling, and managed hosting.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-use-hypersync-for-real-time-data">Can I Use HyperSync for Real-Time Data?<a class="hash-link" aria-label="Direct link to Can I Use HyperSync for Real-Time Data?" title="Direct link to Can I Use HyperSync for Real-Time Data?" href="https://docs.envio.dev/blog/what-is-hypersync#can-i-use-hypersync-for-real-time-data">​</a></h3>
<p>Yes. HyperSync streams data continuously and you can poll for new blocks at the head of the chain. The <a href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync">Polymarket trades tutorial</a> is a worked example of real-time streaming.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="are-traces-supported-on-every-chain">Are Traces Supported on Every Chain?<a class="hash-link" aria-label="Direct link to Are Traces Supported on Every Chain?" title="Direct link to Are Traces Supported on Every Chain?" href="https://docs.envio.dev/blog/what-is-hypersync#are-traces-supported-on-every-chain">​</a></h3>
<p>No. Trace filters are accessed via separate trace-enabled HyperSync endpoints, for example <code>https://eth-traces.hypersync.xyz</code> for Ethereum mainnet. See the <a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" target="_blank" rel="noopener noreferrer">Supported Networks</a> page for trace availability.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/what-is-hypersync#build-with-envio">​</a></h2>
<p>Envio HyperIndex is independently benchmarked as the fastest EVM blockchain indexer available (Sentio benchmark, May 2025). If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, or come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a></p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Envio Developer Update April 2026]]></title>
            <link>https://docs.envio.dev/blog/envio-developer-update-april-2026</link>
            <guid>https://docs.envio.dev/blog/envio-developer-update-april-2026</guid>
            <pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio's April 2026 developer update covering HyperIndex v3 alpha.21 with experimental ClickHouse Sink, the Envio Docs MCP Server, Quickstart with AI guide, Polymarket V2 indexer, Monad traces on HyperSync, Tempo support, and EthCC[9].]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026.png" alt="Cover Image Envio Developer Update April 2026" width="100%">
<p>April was a big step forward for AI-assisted indexing on Envio. We launched the Envio Docs MCP Server and a new Quickstart with AI guide for building or migrating indexers with Claude, Cursor, and other AI coding assistants. HyperIndex v3.0.0 alpha.21 ships with an experimental ClickHouse Sink, improved multiple data-sources support, and an updated testing framework with three ways to feed events. We also released the Polymarket V2 Indexer, which is now powering a new data-driven series breaking down the actual top-PnL traders on Polymarket. HyperSync added Monad trace support with full history from block 0, Envio went live on Tempo, and much more. The team was also at EthCC[9] in Cannes.</p>
<p>Let's dive in.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hyperindex-v300-alpha-alpha20--alpha21">HyperIndex v3.0.0 Alpha: alpha.20 &amp; alpha.21<a class="hash-link" aria-label="Direct link to HyperIndex v3.0.0 Alpha: alpha.20 &amp; alpha.21" title="Direct link to HyperIndex v3.0.0 Alpha: alpha.20 &amp; alpha.21" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#hyperindex-v300-alpha-alpha20--alpha21">​</a></h2>
<p>Continuing steady progress on V3 across indexing resilience, testing, analytics, and developer experience.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="improved-multiple-data-sources-support">Improved Multiple Data-Sources Support<a class="hash-link" aria-label="Direct link to Improved Multiple Data-Sources Support" title="Direct link to Improved Multiple Data-Sources Support" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#improved-multiple-data-sources-support">​</a></h3>
<p>HyperIndex now handles data source switching more intelligently.</p>
<p>After switching to a fallback source, HyperIndex automatically attempts to recover to the primary source 60 seconds later, rather than staying stuck on the fallback until it goes down or the indexer is restarted. The logic for choosing which source to use next has also been improved, alongside stricter enforcement of source usage configured for live mode.</p>
<p>The result: better indexing resilience, less vendor lock-in, and more predictable failover behaviour in production.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="testing-framework-highlights">Testing Framework Highlights<a class="hash-link" aria-label="Direct link to Testing Framework Highlights" title="Direct link to Testing Framework Highlights" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#testing-framework-highlights">​</a></h3>
<p>Our testing framework has matured with three ways to feed events, making it easier to write tests against the same indexer that runs in production. No database, no Docker, no manual mock wiring.</p>
<ul>
<li>Auto-exit: zero config, processes the first block with matching events</li>
<li>Explicit block range: deterministic CI snapshots</li>
<li>Simulate: typed synthetic events, no network needed</li>
</ul>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> describe</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> it </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"vitest"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> createTestIndexer </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"generated"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">describe</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"ERC20 indexer"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token function" style="color:rgb(80, 250, 123)">it</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"processes the first block with events"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">t</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> indexer </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">createTestIndexer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> indexer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> chains</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token number">1</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Auto-filled by Vitest on first run, just review and commit</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    t</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">expect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toMatchInlineSnapshot</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">      {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">        "changes": [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">          {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">            "Transfer": {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">              "sets": [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "blockNumber": 10861674,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "from": "0x0000000000000000000000000000000000000000",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "id": "1-10861674-23",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "to": "0x41653c7d61609D856f29355E404F310Ec4142Cfb",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "transactionHash": "0x4b37d2f343608457ca...",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                  "value": 1000000000000000000000000000n,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">                },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">              ],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">            },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">            "block": 10861674,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">            "chainId": 1,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">            "eventsProcessed": 1,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">          },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">        ],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">      }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token template-string string" style="color:rgb(255, 121, 198)">    </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="experimental-clickhouse-sink">Experimental ClickHouse Sink<a class="hash-link" aria-label="Direct link to Experimental ClickHouse Sink" title="Direct link to Experimental ClickHouse Sink" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#experimental-clickhouse-sink">​</a></h3>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-1.png" alt="Experimental ClickHouse Sink" width="100%">
<p>HyperIndex V3 Alpha introduces an experimental ClickHouse Sink. Postgres remains the primary database, with your entity data additionally replicated to ClickHouse for analytics workloads.</p>
<p>ClickHouse is a columnar database built for heavy analytical queries on datasets in the 100s of GBs or TBs, a natural fit for onchain data which can easily reach billions of events for a single token. If your indexer is powering a dashboard, leaderboard, historical chart, or any reporting layer on top of a large dataset, ClickHouse is the right tool for that read path.</p>
<p>Enable it on Envio Cloud by setting four environment variables:</p>
<ul>
<li><code>ENVIO_CLICKHOUSE_SINK_HOST</code></li>
<li><code>ENVIO_CLICKHOUSE_SINK_DATABASE</code></li>
<li><code>ENVIO_CLICKHOUSE_SINK_USERNAME</code></li>
<li><code>ENVIO_CLICKHOUSE_SINK_PASSWORD</code></li>
</ul>
<p>Currently supported on the Dedicated Plan only, and you need to bring your own ClickHouse instance. Managed ClickHouse is coming to Envio Cloud, fill out <a href="https://forms.gle/P19S7KXYfdHQM8J69" target="_blank" rel="noopener noreferrer">this form</a> to be one of the first users.</p>
<p>Read the full walkthrough here: <a href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3</a></p>
<p>See the full <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">release notes</a>.
Star us on <a href="https://github.com/enviodev/hyperindex" target="_blank" rel="noopener noreferrer">GitHub</a> ⭐</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-top-hundred-polymarket-traders">The Top Hundred Polymarket Traders<a class="hash-link" aria-label="Direct link to The Top Hundred Polymarket Traders" title="Direct link to The Top Hundred Polymarket Traders" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#the-top-hundred-polymarket-traders">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-2.png" alt="The Top Hundred Polymarket Traders" width="100%">
<p>We released the Polymarket V2 Indexer this month, a drop-in reference for teams wanting to collect all v2 market data. It covers the new v2 markets end-to-end, designed to scale alongside Polymarket's growth.</p>
<p>Check it out on GitHub: <a href="https://github.com/enviodev/polymarket-v2-indexer" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/polymarket-v2-indexer</a></p>
<p>Off the back of the release, we kicked off a data-driven series breaking down the actual top-PnL traders on Polymarket. 2.66 million wallets have traded on the platform, and the top 100 captured $853 million in profit between them. None of them are clicking buttons on a phone app between sips of beer.</p>
<p>Day 1 profiles "Bids On Everything", the wallet ranked #24 by realized PnL with roughly $24 million net profit across 2,698,796 fills, 44,954 simultaneous markets, and 289 active days. The strategy in one sentence: post buy orders on every outcome token of every binary market at every price level, then merge YES + NO pairs for one dollar whenever both fill.</p>
<p>It's a strong example of the kind of analysis you can run when you have full historical and real-time access to v2 market data. Stay tuned for more!</p>
<p>Read the full breakdown: <a href="https://x.com/jonjonclark/status/2049067586046816561?s=20" target="_blank" rel="noopener noreferrer">https://x.com/jonjonclark/status/2049067586046816561?s=20</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-docs-mcp-server">Envio Docs MCP Server<a class="hash-link" aria-label="Direct link to Envio Docs MCP Server" title="Direct link to Envio Docs MCP Server" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#envio-docs-mcp-server">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-3.png" alt="Envio Docs MCP Server" width="100%">
<p>Envio docs now speak AI. Plug your AI coding assistant (Claude Code, Cursor, Copilot, and more) straight into our docs with the new Envio Docs MCP Server.</p>
<ul>
<li>Always up-to-date</li>
<li>Instant accurate context</li>
<li>Easy setup</li>
</ul>
<p>The biggest shift in AI workflows isn't better prompts, it's better context, and that's exactly what the MCP Server solves. Your assistant pulls live documentation on demand instead of relying on stale training data.</p>
<p>Setup guide and more here: <a href="https://docs.envio.dev/blog/envio-docs-mcp-server" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/envio-docs-mcp-server</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="quickstart-with-ai">Quickstart with AI<a class="hash-link" aria-label="Direct link to Quickstart with AI" title="Direct link to Quickstart with AI" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#quickstart-with-ai">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-4.png" alt="Quickstart with AI" width="100%">
<p>Build or migrate an indexer end-to-end using Claude, Cursor, or any other AI coding assistant with our new Quickstart with AI guide.</p>
<p>What's included:</p>
<ul>
<li>Live docs via MCP</li>
<li>Non-interactive init</li>
<li>Built-in Claude skills</li>
<li>AI-assisted subgraph migration</li>
<li>Programmatic deploys via the envio-cloud CLI</li>
</ul>
<p>This pulls everything together into a single agentic workflow, from scaffolding to deployment, without touching a config file manually.</p>
<p>Get started here: <a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="concentrated-liquidity-on-uniswap-v4">Concentrated Liquidity on Uniswap v4<a class="hash-link" aria-label="Direct link to Concentrated Liquidity on Uniswap v4" title="Direct link to Concentrated Liquidity on Uniswap v4" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#concentrated-liquidity-on-uniswap-v4">​</a></h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/UZGtLVQGliE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>
<p>Envio was a Sapphire sponsor of EthCC[9], held at Palais des Festivals in Cannes from March 30 to April 2, 2026.</p>
<p>JonJon took to the Monroe Stage with his talk "From x<em>y=k to Ticks: Seeing Concentrated Liquidity on Uniswap v4 in Real Time", walking through the jump from x</em>y=k to ticks on Uniswap v4, with a real-time visual layer tracking active liquidity and pool behaviour across chains.</p>
<p>Big thanks to the EthCC team, sponsors, organisers, and volunteers for putting on such a great event. Had a great time connecting with some incredible teams and builders across the week, and a special thanks to everyone who swung by our booth.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="monad-traces-live-on-hypersync">Monad Traces Live on HyperSync<a class="hash-link" aria-label="Direct link to Monad Traces Live on HyperSync" title="Direct link to Monad Traces Live on HyperSync" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#monad-traces-live-on-hypersync">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-5.png" alt="Monad Traces Live on HyperSync" width="100%">
<p>Monad traces are live on HyperSync, with full history from block 0.</p>
<p>Stream all Monad trace data in minutes and export it to CSV using our new export tool. Ideal for teams running deep onchain analytics, MEV research, or custom pipelines on top of Monad's execution traces.</p>
<p>Export tool on GitHub: <a href="https://github.com/enviodev/export-monad-traces" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/export-monad-traces</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-is-live-on-tempo">Envio is Live on Tempo<a class="hash-link" aria-label="Direct link to Envio is Live on Tempo" title="Direct link to Envio is Live on Tempo" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#envio-is-live-on-tempo">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-6.gif" alt="Envio is Live on Tempo" width="100%">
<p>Envio is live on Tempo, the blockchain built for stablecoin payments at scale.</p>
<p>Index and query real-time payment data, build fully customisable data pipelines, and query millions of events up to 2000x faster than traditional RPC.</p>
<p>Easy, fast, and fully customisable.</p>
<p>Original post on X: <a href="https://x.com/i/status/2042577679380013222" target="_blank" rel="noopener noreferrer">https://x.com/i/status/2042577679380013222</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-track-native-eth-transfers-using-hypersync">How to Track Native ETH Transfers Using HyperSync<a class="hash-link" aria-label="Direct link to How to Track Native ETH Transfers Using HyperSync" title="Direct link to How to Track Native ETH Transfers Using HyperSync" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#how-to-track-native-eth-transfers-using-hypersync">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-7.png" alt="How to Track Native ETH Transfers Using HyperSync" width="100%">
<p>Tracking native ETH transfers onchain is trickier than ERC-20 transfers. There's no event log to index, so you have to parse traces, which is slow over standard RPC.</p>
<p>Our new tutorial walks through how to use HyperSync's native trace filtering to stream transfers by filtering on <code>call_type=call</code> with a value threshold. It includes a full working example using the Node.js client in a Bun project, streaming results until 10 transfers above 0.005 ETH are collected.</p>
<p>HyperSync trace support is currently available on Ethereum, Base, Arbitrum, Gnosis, and Monad.</p>
<p>Read the full tutorial: <a href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="current--upcoming-events--hackathons">Current &amp; Upcoming Events &amp; Hackathons<a class="hash-link" aria-label="Direct link to Current &amp; Upcoming Events &amp; Hackathons" title="Direct link to Current &amp; Upcoming Events &amp; Hackathons" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#current--upcoming-events--hackathons">​</a></h2>
<ul>
<li><a href="https://ethconf.com/" target="_blank" rel="noopener noreferrer">ETHConf - New York</a>: June 8th -&gt; 10th (sponsoring)</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="featured-developer-claude">Featured Developer: Claude<a class="hash-link" aria-label="Direct link to Featured Developer: Claude" title="Direct link to Featured Developer: Claude" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#featured-developer-claude">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-8.png" alt="Featured developer Claude" width="100%">
<p>This month's featured developer is Claude.</p>
<p>A shoutout to Anthropic's Claude, who has become a familiar name in the developer community and a strong collaborator for teams building with AI assistants. With the launch of the Envio Docs MCP Server and Quickstart with AI guide this month, we're excited to see how the community continues to build with AI alongside Envio.</p>
<p>More to come.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="playlist-of-the-month">Playlist of the Month<a class="hash-link" aria-label="Direct link to Playlist of the Month" title="Direct link to Playlist of the Month" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#playlist-of-the-month">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-april-2026-9.png" alt="Playlist of the month" width="100%">
<p>▶ <a href="https://open.spotify.com/playlist/240pHTCbwvf6kBMdfWGmw9?si=bb40d616e82a49f3" target="_blank" rel="noopener noreferrer">Open Spotify</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-developer-update-april-2026#build-with-envio">​</a></h2>
<p>Envio is a multichain EVM blockchain indexer for querying real-time and historical data. If you're working on a Web3 project and want a smoother development process, Envio's got your back(end). Check out our docs, join the community, and let's talk about your data needs.</p>
<p>Stay tuned for more monthly updates by subscribing to our newsletter, following us on X, or hopping into our Discord for more up-to-date information.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>product-updates</category>
        </item>
        <item>
            <title><![CDATA[Using ClickHouse Storage in HyperIndex V3]]></title>
            <link>https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3</link>
            <guid>https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3</guid>
            <pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[HyperIndex V3 Alpha adds experimental ClickHouse Storage. Postgres stays primary, entity data mirrors to ClickHouse for analytics workloads on billions of onchain events.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="Cover image for the ClickHouse Storage blog" src="https://docs.envio.dev/assets/images/clickhouse-storage-d2f888e3165b146a98f61864eb5705a7.png" width="1906" height="1115" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>HyperIndex V3 Alpha adds experimental <strong>ClickHouse Storage</strong>, Postgres stays as the primary database, and your entity data is replicated to ClickHouse for analytics workloads.</li>
<li>ClickHouse is a columnar database built for heavy analytical queries on datasets in the 100s of GBs or TBs, a natural fit for onchain data, which can easily reach billions of events for a single token.</li>
<li>You can enable it on Envio Cloud by setting four environment variables: <code>ENVIO_CLICKHOUSE_HOST</code>, <code>ENVIO_CLICKHOUSE_DATABASE</code>, <code>ENVIO_CLICKHOUSE_USERNAME</code>, and <code>ENVIO_CLICKHOUSE_PASSWORD</code>.</li>
<li>Currently supported on the <strong>Dedicated Plan</strong> only, and you need to bring your own ClickHouse instance. Managed ClickHouse is coming to Envio Cloud, <a href="https://forms.gle/P19S7KXYfdHQM8J69" target="_blank" rel="noopener noreferrer"><strong>fill out this form</strong></a> if you want to be one of the first users.</li>
</ul></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-we-built-clickhouse-storage">Why We Built ClickHouse Storage<a class="hash-link" aria-label="Direct link to Why We Built ClickHouse Storage" title="Direct link to Why We Built ClickHouse Storage" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#why-we-built-clickhouse-storage">​</a></h2>
<p>Since day one, HyperIndex has used Postgres as its primary database. Postgres is battle-tested, runs well for small and large indexers alike, and gives you GraphQL out of the box through Hasura. It is a solid default for almost every indexer.</p>
<p>But over the last few months, enough teams have asked the same question that we knew we had to do something about it: <strong>can we replicate the data to ClickHouse?</strong></p>
<p>Most teams asking were building on DEXes, or DeFi protocols where data volumes are large enough that even a well-tuned Postgres query to do analytics starts to slow down. That is exactly the workload ClickHouse is built for. So in HyperIndex V3, we shipped experimental ClickHouse Storage support.</p>
<p>V3 is in alpha at the time of writing, and ClickHouse Storage is flagged as experimental. Both will be marked stable once V3 reaches its stable launch, at which point you can use ClickHouse Storage in production without the experimental label. If you want to try ClickHouse on Envio Cloud today, <a href="https://forms.gle/P19S7KXYfdHQM8J69" target="_blank" rel="noopener noreferrer"><strong>fill out this form</strong></a>, it is currently supported only on the Dedicated Plan.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-clickhouse">What is ClickHouse?<a class="hash-link" aria-label="Direct link to What is ClickHouse?" title="Direct link to What is ClickHouse?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#what-is-clickhouse">​</a></h2>
<p>ClickHouse is a <strong>columnar database</strong> designed for analytical workloads. Most transactional databases, including Postgres, store data row by row, which is fast when you are reading or writing a single record by its primary key but slow when you are scanning millions of rows to compute an aggregate. A columnar database flips that around, values for each column are stored together on disk, so aggregations across billions of rows finish in seconds instead of minutes.</p>
<p>This matters a lot for blockchain data. For example, just USDC on Ethereum has hundreds of millions of <strong><code>Transfer</code></strong> events. Add in every other chain USDC is deployed on, and you cross into the billions. Now imagine you want to group those transfers by sender, bucket them by hour, and compute the sum per chain. A row store will struggle no matter how many indexes you throw at it. A columnar engine was built for exactly that kind of query.</p>
<p>Onchain data has three properties that make it a near-perfect match for ClickHouse:</p>
<ul>
<li><strong>Append-heavy</strong> - once an event is emitted, it rarely changes.</li>
<li><strong>Highly structured</strong> - every event of the same type has the same shape.</li>
<li><strong>Queried in aggregate</strong> - most analytics questions are counts, sums, averages, or time-bucketed views, not single-row lookups.</li>
</ul>
<p>If your indexer is powering a dashboard, a leaderboard, historical charts, or any kind of reporting layer on top of a large dataset, ClickHouse is the right tool for that read path. Postgres is still great for your day-to-day indexer writes and GraphQL reads, ClickHouse Storage just gives you a second surface that is optimised for the analytical side.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-clickhouse-storage-works-in-hyperindex">How ClickHouse Storage Works in HyperIndex<a class="hash-link" aria-label="Direct link to How ClickHouse Storage Works in HyperIndex" title="Direct link to How ClickHouse Storage Works in HyperIndex" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#how-clickhouse-storage-works-in-hyperindex">​</a></h2>
<p>HyperIndex runs two storage layers in parallel. Postgres remains the primary indexed state that your app queries through GraphQL. ClickHouse is a purpose-built analytics mirror, not a fallback. On every batch, events parsed by your handlers are flushed to both: Postgres gets the current state, ClickHouse gets the history.</p>
<p>ClickHouse Storage writes two things:</p>
<ul>
<li><strong>Entity history tables</strong> - every change to every entity as an <strong><code>INSERT</code></strong>, tagged with a <strong><code>SET</code></strong> or <strong><code>DELETE</code></strong> action and a checkpoint ID linking it to a specific block. ClickHouse never receives an <strong><code>UPDATE</code></strong>, it is optimised for inserts, not mutation.</li>
<li><strong>Checkpoints table</strong> - one row per processed block with block number, block hash, chain ID, and event count.</li>
</ul>
<p>"Current state" is served by <strong>views</strong> that sit on top of the history table and select the latest <strong>SET</strong> row per entity ID. You get a full audit trail for free, and you can query state at any past block just by filtering on checkpoint ID.</p>
<p>Reorgs are handled by a single <strong><code>DELETE</code></strong> per table that removes all rows above the reorg checkpoint, the append only model makes rollbacks trivial, with no partial state to unwind. Schemas are auto-created on startup from your <strong><code>schema.graphql</code></strong>, with type mappings handled for you (<code>BigInt</code> → <code>Decimal</code>, <code>Date</code> → <code>DateTime64</code>, <code>enums</code> → <code>Enum8</code>/<code>Enum16</code>, and so on). No DDL to write.</p>
<p>Both backends are <strong>restart- and reorg-resistant</strong>, the checkpoints table lets the indexer resume cleanly after a crash, and Prometheus metrics carry a <strong><code>storage-name</code></strong> label so you can monitor Postgres and ClickHouse write paths separately.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Note</div><div class="admonitionContent_BuS1"><p>During historical backfill, ClickHouse Storage does not store every intermediate entity change. If an entity is modified multiple times within a single batch, only the final state of that batch is written to ClickHouse. Once the indexer reaches the head and is processing live, every change is captured.</p></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="admonitionContent_BuS1"><p>Do not run multiple indexers writing to the same ClickHouse database at the same time.</p></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-enable-clickhouse-on-envio-cloud"><strong>How to Enable ClickHouse on Envio Cloud</strong><a class="hash-link" aria-label="Direct link to how-to-enable-clickhouse-on-envio-cloud" title="Direct link to how-to-enable-clickhouse-on-envio-cloud" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#how-to-enable-clickhouse-on-envio-cloud">​</a></h2>
<p>To scaffold a new V3 alpha indexer, run:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This will set up a fresh project on the latest alpha release. Enable both storage backends in <code>config.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">storage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">postgres</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token key atrule">clickhouse</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>ClickHouse connection is configured via four environment variables, set them in your <code>.env</code> file for local development (<code>envio dev</code> will spin up a ClickHouse Docker container alongside), or from the Envio Cloud dashboard for hosted deployments:</p>
<table><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td><code>ENVIO_CLICKHOUSE_HOST</code></td><td>The host of your ClickHouse instance.</td></tr><tr><td><code>ENVIO_CLICKHOUSE_DATABASE</code></td><td>The ClickHouse database to write into.</td></tr><tr><td><code>ENVIO_CLICKHOUSE_USERNAME</code></td><td>Username for the ClickHouse connection.</td></tr><tr><td><code>ENVIO_CLICKHOUSE_PASSWORD</code></td><td>Password for the ClickHouse connection.</td></tr></tbody></table>
<p>Once those are set, HyperIndex will replicate the same entity data it writes to Postgres into your ClickHouse database. Every entity in your <code>schema.graphql</code> becomes a ClickHouse table with a matching schema, so you can point your analytics queries, BI tools, or dashboards directly at ClickHouse, no extra ETL pipeline needed.</p>
<p>Postgres and GraphQL keep working exactly as they do today. ClickHouse Storage is additive: you get a second read-optimised surface without giving up the one you already have.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="who-can-use-clickhouse-storage">Who Can Use ClickHouse Storage?<a class="hash-link" aria-label="Direct link to Who Can Use ClickHouse Storage?" title="Direct link to Who Can Use ClickHouse Storage?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#who-can-use-clickhouse-storage">​</a></h2>
<p>Right now, ClickHouse Storage is available on the <strong>Dedicated Plan</strong>, and you need to bring your own ClickHouse instance. If you are already running ClickHouse (or you are comfortable standing one up), you can plug it into your indexer today using the environment variables above.</p>
<p>We are also working on a managed ClickHouse offering on Envio Cloud so teams won't have to run their own instance. If you want to be one of the first users when that rolls out, <a href="https://forms.gle/P19S7KXYfdHQM8J69" target="_blank" rel="noopener noreferrer"><strong>fill out this form</strong></a>. Tell us a bit about your indexer and the kind of analytics you are trying to run and we will get you onboarded.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started"><strong>Get Started</strong><a class="hash-link" aria-label="Direct link to get-started" title="Direct link to get-started" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#get-started">​</a></h2>
<p>ClickHouse Storage is available today on the Dedicated Plan for teams running their own ClickHouse instance. For teams that want managed ClickHouse on Envio Cloud, fill out the waitlist form to be one of the first users when it rolls out.</p>
<ul>
<li>Envio docs: <a href="https://docs.envio.dev/" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/</a></li>
<li>HyperIndex V3 migration guide: <a href="https://docs.envio.dev/docs/HyperIndex/migrate-to-v3" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperIndex/migrate-to-v3</a></li>
<li>Managed ClickHouse waitlist: <a href="https://forms.gle/P19S7KXYfdHQM8J69" target="_blank" rel="noopener noreferrer">https://forms.gle/P19S7KXYfdHQM8J69</a></li>
<li>Discord: <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">https://discord.gg/envio</a></li>
<li>Telegram: <a href="https://t.me/+kAIGElzPjApiMjI0" target="_blank" rel="noopener noreferrer">https://t.me/+kAIGElzPjApiMjI0</a></li>
<li>Follow us on X: <a href="https://x.com/envio_indexer" target="_blank" rel="noopener noreferrer">https://x.com/envio_indexer</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions"><strong>Frequently Asked Questions</strong><a class="hash-link" aria-label="Direct link to frequently-asked-questions" title="Direct link to frequently-asked-questions" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="clickhouse-vs-postgres-when-should-i-use-which">ClickHouse vs Postgres: When Should I Use Which?<a class="hash-link" aria-label="Direct link to ClickHouse vs Postgres: When Should I Use Which?" title="Direct link to ClickHouse vs Postgres: When Should I Use Which?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#clickhouse-vs-postgres-when-should-i-use-which">​</a></h3>
<p>Use Postgres for transactional reads, your GraphQL API, single-entity lookups, and anything latency-sensitive that your application serves directly to users. Use ClickHouse for analytical queries: large aggregations, time-bucketed views, leaderboards, historical charts, and BI dashboards. The rule of thumb is that if a query scans millions of rows to compute a result, it belongs on ClickHouse. If a query fetches a specific record by ID, it belongs on Postgres.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-use-bi-tools-like-metabase-superset-or-grafana-with-clickhouse-storage">Can I Use BI Tools Like Metabase, Superset, or Grafana With ClickHouse Storage?<a class="hash-link" aria-label="Direct link to Can I Use BI Tools Like Metabase, Superset, or Grafana With ClickHouse Storage?" title="Direct link to Can I Use BI Tools Like Metabase, Superset, or Grafana With ClickHouse Storage?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#can-i-use-bi-tools-like-metabase-superset-or-grafana-with-clickhouse-storage">​</a></h3>
<p>Yes. Once ClickHouse Storage is running, your ClickHouse database is a standard ClickHouse instance as far as any external tool is concerned. Any tool with a ClickHouse connector (Metabase, Superset, Grafana, Tableau, Hex, Redash, and most others) can connect directly. Point it at the same host, database, and credentials you configured on Envio Cloud.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-clickhouse-storage-slow-down-my-indexer">Does ClickHouse Storage Slow Down My Indexer?<a class="hash-link" aria-label="Direct link to Does ClickHouse Storage Slow Down My Indexer?" title="Direct link to Does ClickHouse Storage Slow Down My Indexer?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#does-clickhouse-storage-slow-down-my-indexer">​</a></h3>
<p>ClickHouse Storage writes in the same batches HyperIndex uses for Postgres, so there is some additional write work per batch. In practice, ClickHouse inserts are designed to be fast and writes are batched, so the overhead is small for most workloads. If you are seeing lag, the usual culprit is your ClickHouse instance's write capacity or network latency between the indexer and ClickHouse, not HyperIndex itself.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-query-past-state-in-clickhouse">How Do I Query Past State in ClickHouse?<a class="hash-link" aria-label="Direct link to How Do I Query Past State in ClickHouse?" title="Direct link to How Do I Query Past State in ClickHouse?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#how-do-i-query-past-state-in-clickhouse">​</a></h3>
<p>Because the history tables store every change with a checkpoint ID tied to a specific block, you can reconstruct state at any historical point by filtering on checkpoint ID. This gives you time-travel queries for free, without needing snapshots or a separate archive. The latest-state views handle the "current state" case automatically, so you only reach for checkpoint filtering when you specifically want a past view.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-add-custom-tables-or-indexes-to-my-clickhouse-database">Can I Add Custom Tables or Indexes to My ClickHouse Database?<a class="hash-link" aria-label="Direct link to Can I Add Custom Tables or Indexes to My ClickHouse Database?" title="Direct link to Can I Add Custom Tables or Indexes to My ClickHouse Database?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#can-i-add-custom-tables-or-indexes-to-my-clickhouse-database">​</a></h3>
<p>ClickHouse Storage manages its own tables based on your <code>schema.graphql</code> and will create them on startup. You can add your own tables, materialised views, or downstream aggregations in the same database alongside the managed tables, as long as you don't modify or collide with them. A common pattern is to build materialised views on top of the history tables to pre-aggregate heavy queries.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-happens-if-my-clickhouse-instance-goes-down">What Happens If My ClickHouse Instance Goes Down?<a class="hash-link" aria-label="Direct link to What Happens If My ClickHouse Instance Goes Down?" title="Direct link to What Happens If My ClickHouse Instance Goes Down?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#what-happens-if-my-clickhouse-instance-goes-down">​</a></h3>
<p>Postgres and your GraphQL API keep serving as normal. ClickHouse Storage is additive, so a ClickHouse outage does not stop your indexer from processing events or serving queries from Postgres. Once ClickHouse is back, replication resumes from where it left off using the checkpoints table.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-there-a-cost-difference-between-running-with-and-without-clickhouse-storage">Is There a Cost Difference Between Running With and Without ClickHouse Storage?<a class="hash-link" aria-label="Direct link to Is There a Cost Difference Between Running With and Without ClickHouse Storage?" title="Direct link to Is There a Cost Difference Between Running With and Without ClickHouse Storage?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#is-there-a-cost-difference-between-running-with-and-without-clickhouse-storage">​</a></h3>
<p>On Envio Cloud, ClickHouse Storage itself is available on the Dedicated Plan. The main cost consideration is your ClickHouse instance, you are bringing your own, so storage, compute, and egress costs depend on your provider (ClickHouse Cloud, self-hosted, Altinity, etc.) and the size of your dataset. Entity history tables grow faster than Postgres state tables because every change is stored rather than just the current value.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-did-envio-build-this-instead-of-just-recommending-an-etl-pipeline">Why Did Envio Build This Instead of Just Recommending an ETL Pipeline?<a class="hash-link" aria-label="Direct link to Why Did Envio Build This Instead of Just Recommending an ETL Pipeline?" title="Direct link to Why Did Envio Build This Instead of Just Recommending an ETL Pipeline?" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#why-did-envio-build-this-instead-of-just-recommending-an-etl-pipeline">​</a></h3>
<p>Running a separate ETL pipeline (CDC from Postgres to ClickHouse, a Kafka connector, a custom script) adds another system to maintain, another place for data to drift, and another source of lag. Building ClickHouse Storage into HyperIndex means entity data lands in ClickHouse as part of the same batch that writes to Postgres, with reorg handling and schema management already solved. One indexer, two read surfaces, no extra pipeline.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/clickhouse-storage-hyperindex-v3#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, plus analytics that keep up with your indexer, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a></p>]]></content:encoded>
            <category>tutorials</category>
        </item>
        <item>
            <title><![CDATA[How to Track Native ETH Transfers Using Envio's HyperSync]]></title>
            <link>https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync</link>
            <guid>https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync</guid>
            <pubDate>Fri, 24 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Native ETH transfers don't emit event logs, so tracking them over RPC means slow trace calls. This guide shows how to stream native transfers efficiently using HyperSync's trace filtering with the Node.js client in a Bun project.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="Cover image for the blog with title" src="https://docs.envio.dev/assets/images/tracking-native-eth-transfers-hypersync-c82b046e0f79cdcb9b7c63a6a5ed7305.png" width="1600" height="936" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Tracking native ETH transfers onchain requires parsing traces rather than event logs, which is slow over standard RPC.</li>
<li>HyperSync exposes trace filtering directly, letting you stream native transfers by filtering on <code>call_type=call</code> with a value threshold.</li>
<li>Full working example uses the Node.js client in a Bun project, streaming results until 10 transfers above 0.005 ETH are collected.</li>
<li>Trace support is available on Ethereum, Base, Arbitrum, Gnosis, and Monad.</li>
</ul></div></div>
<p>Tracking native token transfers onchain is trickier than ERC-20 transfers. There's no event log to index, so you have to dig through traces. With a standard RPC node, that means calling eth_traceBlock and iterating every trace in every block, which is slow.
HyperSync gives you a faster alternative: a data retrieval layer with native trace filtering.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="prerequisites">Prerequisites<a class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#prerequisites">​</a></h2>
<p>We are going to use <a href="https://bun.com/docs/installation" target="_blank" rel="noopener noreferrer">Bun</a> for this article, so make sure you have it installed. If you want to use another runtime that supports TypeScript, you can do that too.</p>
<p>You will also need an Envio API token to access HyperSync. If you don't have one, go to <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">envio.dev/app/api-tokens</a> to create one. Step-by-step instructions are at <a href="https://docs.envio.dev/docs/HyperSync/api-tokens#generating-api-tokens" target="_blank" rel="noopener noreferrer">docs.envio.dev/docs/HyperSync/api-tokens</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hypersync--queries">HyperSync &amp; Queries<a class="hash-link" aria-label="Direct link to HyperSync &amp; Queries" title="Direct link to HyperSync &amp; Queries" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#hypersync--queries">​</a></h2>
<p>HyperSync is optimized for data retrieval, not consensus, so it's far faster than RPC nodes. To fetch data, you send a query describing what you want and HyperSync returns only that data.</p>
<p>A typical query looks like this:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"fromBlock"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"transactions"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token property">"from"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"0x5a830d7a5149b2f1a2e72d15cd51b84379ee81e5"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token property">"to"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"0x5a830d7a5149b2f1a2e72d15cd51b84379ee81e5"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"fieldSelection"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"transaction"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"BlockNumber"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Hash"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"From"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"To"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Value"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Every query has three main parts: <code>fromBlock</code>, a filter section (one of <code>transactions</code>, <code>blocks</code>, <code>logs</code>, or <code>traces</code>), and <code>fieldSelection</code>. See the <a href="https://docs.envio.dev/docs/HyperSync/hypersync-query#query-structure-reference" target="_blank" rel="noopener noreferrer">full query reference</a> for all available options.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="filtering-for-native-transfers">Filtering for Native Transfers<a class="hash-link" aria-label="Direct link to Filtering for Native Transfers" title="Direct link to Filtering for Native Transfers" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#filtering-for-native-transfers">​</a></h3>
<p>Native ETH transfers occur only in traces where <code>call_type</code> is <code>call</code> — not <code>staticcall</code> or <code>delegatecall</code>. Filtering on <code>callType</code> directly is more efficient than filtering on trace <code>kind</code>, since it lets HyperSync skip irrelevant trace types upfront.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="building-the-fetcher">Building the Fetcher<a class="hash-link" aria-label="Direct link to Building the Fetcher" title="Direct link to Building the Fetcher" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#building-the-fetcher">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="setup">Setup<a class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#setup">​</a></h3>
<p>Create a new Bun project and install the HyperSync client:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">bun init </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-y</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> bun </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> @envio-dev/hypersync-client</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Add your API token to a <code>.env</code> file. If you don't have one, generate it at <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">envio.dev/app/api-tokens</a>.</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">ENVIO_API_TOKEN</span><span class="token operator">=</span><span class="token plain">your_token_here</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<blockquote>
<p><strong>Note:</strong> HyperSync trace support is currently available on Ethereum, Base, Arbitrum, Gnosis, and Monad. <a href="mailto:nikhil@envio.dev" target="_blank" rel="noopener noreferrer">Reach out</a> if you need trace support for other chains.</p>
</blockquote>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="imports--helpers">Imports &amp; Helpers<a class="hash-link" aria-label="Direct link to Imports &amp; Helpers" title="Direct link to Imports &amp; Helpers" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#imports--helpers">​</a></h3>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">TraceField</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@envio-dev/hypersync-client"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>We'll filter out dust transfers using a minimum threshold and format values as human-readable ETH:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">THRESHOLD_WEI</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">BigInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"5000000000000000"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 0.005 ETH</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">WEI_PER_ETH</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">BigInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"1000000000000000000"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1 ETH</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DECIMALS</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">6</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">weiToEth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">wei</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> whole </span><span class="token operator">=</span><span class="token plain"> wei </span><span class="token operator">/</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">WEI_PER_ETH</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> remainder </span><span class="token operator">=</span><span class="token plain"> wei </span><span class="token operator">%</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">WEI_PER_ETH</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> remainderStr </span><span class="token operator">=</span><span class="token plain"> remainder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toString</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">padStart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">18</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">slice</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DECIMALS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">whole</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">remainderStr</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="creating-the-client">Creating the Client<a class="hash-link" aria-label="Direct link to Creating the Client" title="Direct link to Creating the Client" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#creating-the-client">​</a></h3>
<p>Use the Ethereum traces endpoint:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://eth-traces.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="query">Query<a class="hash-link" aria-label="Direct link to Query" title="Direct link to Query" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#query">​</a></h3>
<p>Request only <code>call</code> type traces and select the fields we care about:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> query </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fromBlock</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">22000000</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  traces</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      callType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"call"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fieldSelection</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    trace</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"From"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"To"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Value"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"CallType"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"BlockNumber"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> TraceField</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="streaming-results">Streaming Results<a class="hash-link" aria-label="Direct link to Streaming Results" title="Direct link to Streaming Results" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#streaming-results">​</a></h3>
<p>HyperSync offers two fetch modes: <code>get</code> (single response) and <code>stream</code> (continuous). We'll stream and stop once we've collected 10 transfers above the threshold:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Fetching native transfers (call_type=call, value &gt; 0.005 ETH)...\n"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> results</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> from</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> to</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> valueEth</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> stream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">outer</span><span class="token operator">:</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> res </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">recv</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res </span><span class="token operator">===</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// stream exhausted</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data</span><span class="token operator">?.</span><span class="token plain">traces</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> trace </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">of</span><span class="token plain"> res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">traces</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value </span><span class="token operator">===</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">undefined</span><span class="token plain"> </span><span class="token operator">||</span><span class="token plain"> trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value </span><span class="token operator">===</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">continue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value </span><span class="token operator">&lt;=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">THRESHOLD_WEI</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">continue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">push</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        from</span><span class="token operator">:</span><span class="token plain"> trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from </span><span class="token operator">??</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"unknown"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        to</span><span class="token operator">:</span><span class="token plain"> trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to </span><span class="token operator">??</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"unknown"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        valueEth</span><span class="token operator">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">weiToEth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trace</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">length </span><span class="token operator">&gt;=</span><span class="token plain"> </span><span class="token number">10</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token plain"> outer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">close</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">length </span><span class="token operator">===</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"No results found."</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">table</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">r</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      From</span><span class="token operator">:</span><span class="token plain"> r</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      To</span><span class="token operator">:</span><span class="token plain"> r</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string-property property">"Value (ETH)"</span><span class="token operator">:</span><span class="token plain"> r</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">valueEth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Run it with:</p>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">bun run index.ts</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" alt="Output table showing native transfers" src="https://docs.envio.dev/assets/images/native-transfers-cli-output-eeca422b5c46c70a27b11be8f7bf5cef.png" width="880" height="318" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="next-steps">Next Steps<a class="hash-link" aria-label="Direct link to Next Steps" title="Direct link to Next Steps" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#next-steps">​</a></h2>
<p>We only used callType as a filter here. From this starting point you can track a specific wallet by adding from or to address filters to the trace selection, narrow further using other TraceSelection fields like sighash or kind, or switch the endpoint to another HyperSync trace-enabled network to run the same query across chains.</p>
<p>See the HyperSync query reference for the full TraceSelection schema and field list.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hypersync">What Is HyperSync?<a class="hash-link" aria-label="Direct link to What Is HyperSync?" title="Direct link to What Is HyperSync?" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#what-is-hypersync">​</a></h3>
<p><a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync</a> is Envio's high-performance blockchain data retrieval layer, built as an alternative to traditional JSON-RPC endpoints. It gives developers direct access to onchain data up to 2000x faster than standard RPC methods, with client libraries for Python, Rust, Node.js, and Go across <!-- -->87+<!-- --> EVM chains.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-cant-i-track-native-eth-transfers-using-event-logs">Why Can't I Track Native ETH Transfers Using Event Logs?<a class="hash-link" aria-label="Direct link to Why Can't I Track Native ETH Transfers Using Event Logs?" title="Direct link to Why Can't I Track Native ETH Transfers Using Event Logs?" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#why-cant-i-track-native-eth-transfers-using-event-logs">​</a></h3>
<p>Native ETH transfers don't emit events. The ERC-20 <code>Transfer</code> event is a standard contract event, but native ETH moves at the protocol level and only shows up in transaction traces. To track them, you have to query traces directly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="whats-the-difference-between-call_type-and-kind-when-filtering-traces">What's the Difference Between <code>call_type</code> and <code>kind</code> When Filtering Traces?<a class="hash-link" aria-label="Direct link to whats-the-difference-between-call_type-and-kind-when-filtering-traces" title="Direct link to whats-the-difference-between-call_type-and-kind-when-filtering-traces" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#whats-the-difference-between-call_type-and-kind-when-filtering-traces">​</a></h3>
<p><code>kind</code> is the trace type (<code>call</code>, <code>create</code>, <code>suicide</code>, <code>reward</code>). <code>call_type</code> is the sub-type of a call trace (<code>call</code>, <code>delegatecall</code>, <code>staticcall</code>). Native ETH transfers only occur when <code>call_type</code> is <code>call</code>, so filtering on <code>call_type</code> directly is more efficient than filtering on <code>kind</code> and then narrowing down.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="which-chains-support-trace-queries-on-hypersync">Which Chains Support Trace Queries on HyperSync?<a class="hash-link" aria-label="Direct link to Which Chains Support Trace Queries on HyperSync?" title="Direct link to Which Chains Support Trace Queries on HyperSync?" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#which-chains-support-trace-queries-on-hypersync">​</a></h3>
<p>Trace support is currently available on Ethereum, Base, Arbitrum, Gnosis, and Monad. If you need trace support on another chain, reach out at <a href="mailto:nikhil@envio.dev" target="_blank" rel="noopener noreferrer">nikhil@envio.dev</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-fast-is-hypersync-compared-to-rpc-for-trace-queries">How Fast Is HyperSync Compared to RPC for Trace Queries?<a class="hash-link" aria-label="Direct link to How Fast Is HyperSync Compared to RPC for Trace Queries?" title="Direct link to How Fast Is HyperSync Compared to RPC for Trace Queries?" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#how-fast-is-hypersync-compared-to-rpc-for-trace-queries">​</a></h3>
<p>HyperSync is up to 2000x faster than standard JSON-RPC for data retrieval workloads. For trace queries specifically, the gap is even wider since RPC trace methods like <code>eth_traceBlock</code> are among the slowest calls on most nodes.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-use-this-approach-for-erc-20-transfers-too">Can I Use This Approach for ERC-20 Transfers Too?<a class="hash-link" aria-label="Direct link to Can I Use This Approach for ERC-20 Transfers Too?" title="Direct link to Can I Use This Approach for ERC-20 Transfers Too?" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#can-i-use-this-approach-for-erc-20-transfers-too">​</a></h3>
<p>Yes, but for ERC-20 you'd query logs instead of traces since ERC-20 contracts emit a <code>Transfer</code> event. Use the <code>logs</code> filter with the Transfer event signature as <code>topic0</code>. See the <a href="https://docs.envio.dev/docs/HyperSync/hypersync-query" target="_blank" rel="noopener noreferrer">HyperSync query reference</a> for details.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/tracking-native-eth-transfers-hypersync#build-with-envio">​</a></h2>
<p>Envio HyperIndex is independently benchmarked as the fastest EVM blockchain indexer available. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, or come talk to us about your data needs.
Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.
<a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.com/invite/gt7yEUZKeB" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>tutorials</category>
        </item>
        <item>
            <title><![CDATA[Introducing the Envio Docs MCP Server]]></title>
            <link>https://docs.envio.dev/blog/envio-docs-mcp-server</link>
            <guid>https://docs.envio.dev/blog/envio-docs-mcp-server</guid>
            <pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio's documentation is now available as an MCP server. Connect Claude Code, Cursor, or any MCP-compatible assistant for always up-to-date Envio context.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/envio-docs-mcp-server.png" alt="Introducing the Envio Docs MCP Server" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Envio's documentation is now directly accessible to your AI coding assistant via MCP.</li>
<li>Connect Claude Code, Cursor, Copilot, or any MCP-compatible client in one step.</li>
<li>Your assistant searches and fetches live Envio docs on demand, no copy-pasting required.</li>
<li>Envio Docs MCP quicklink: <a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperIndex/mcp-server</a></li>
</ul></div></div>
<p>Envio now has a hosted MCP server for its documentation. Point your AI coding assistant at it and it can search and read Envio docs on demand. No more copy-pasting links into chat and no more watching your model confidently invent a config field that does not exist.</p>
<p>Whether you are building an indexer, querying onchain data with HyperSync, or just exploring what Envio can do, the MCP server gives your agent a direct line to the real documentation while it works.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-an-mcp-server">What is an MCP server?<a class="hash-link" aria-label="Direct link to What is an MCP server?" title="Direct link to What is an MCP server?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#what-is-an-mcp-server">​</a></h2>
<p>Model Context Protocol (MCP) is an open standard for connecting AI assistants to external tools and data sources. An MCP server exposes a set of capabilities, like searching a knowledge base, fetching a document, or calling an API, that any MCP-compatible client can call on demand.</p>
<p>In practice, this means you can give your AI assistant a stable, structured way to reach into a real system, instead of relying on whatever happened to be in its training data or fumbling around the web trying to find something relevant.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-envio-docs-mcp-server">What is the Envio Docs MCP Server?<a class="hash-link" aria-label="Direct link to What is the Envio Docs MCP Server?" title="Direct link to What is the Envio Docs MCP Server?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#what-is-the-envio-docs-mcp-server">​</a></h2>
<p>The Envio Docs MCP server is a hosted MCP server that gives AI coding assistants direct access to Envio's documentation. It exposes two tools:</p>
<table><thead><tr><th>Tool</th><th>Description</th></tr></thead><tbody><tr><td><code>docs_search</code></td><td>Full-text search across all Envio documentation. Returns matching pages with titles, URLs, and content snippets.</td></tr><tr><td><code>docs_fetch</code></td><td>Retrieves the full content of a documentation page as markdown.</td></tr></tbody></table>
<p>The server is hosted at:
<a href="https://docs.envio.dev/mcp" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/mcp</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-this-matters-for-envio-users">Why this matters for Envio users<a class="hash-link" aria-label="Direct link to Why this matters for Envio users" title="Direct link to Why this matters for Envio users" href="https://docs.envio.dev/blog/envio-docs-mcp-server#why-this-matters-for-envio-users">​</a></h2>
<p>Without an MCP server, an AI assistant trying to use Envio docs is mostly working blind. It either falls back on whatever it remembers from training, or hops between links and fetches raw HTML pages to parse out the parts it needs. That is slow, noisy, and easy to get wrong: the model ends up sifting through navigation, sidebars, and styling just to find a single config option.</p>
<p>The Envio Docs MCP server replaces that with a structured way for your assistant to ask the docs a question directly. Instead of scraping pages, it can search across all of Envio's documentation and pull back exactly the content it needs.</p>
<p>That means:</p>
<ul>
<li><strong>Always up to date.</strong> The MCP server reads from the same docs site you read. When the docs change, your assistant sees the change immediately.</li>
<li><strong>Grounded in source docs.</strong> Your agent looks up the exact answer in the documentation instead of guessing.</li>
<li><strong>Less copy-paste.</strong> No more shuttling doc snippets back and forth between your browser and your editor.</li>
<li><strong>Useful across the whole stack.</strong> Whether you are building an indexer, pulling onchain data with HyperSync, or exploring Envio Cloud, your assistant has the right context for the job.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-connect-it">How to connect it<a class="hash-link" aria-label="Direct link to How to connect it" title="Direct link to How to connect it" href="https://docs.envio.dev/blog/envio-docs-mcp-server#how-to-connect-it">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="claude-code">Claude Code<a class="hash-link" aria-label="Direct link to Claude Code" title="Direct link to Claude Code" href="https://docs.envio.dev/blog/envio-docs-mcp-server#claude-code">​</a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">claude mcp </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">--transport</span><span class="token plain"> http envio-docs https://docs.envio.dev/mcp</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="cursor--vs-code">Cursor / VS Code<a class="hash-link" aria-label="Direct link to Cursor / VS Code" title="Direct link to Cursor / VS Code" href="https://docs.envio.dev/blog/envio-docs-mcp-server#cursor--vs-code">​</a></h3>
<p>Add the following to your MCP configuration (<code>.cursor/mcp.json</code> or your VS Code MCP settings):</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"mcpServers"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">"envio-docs"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"url"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://docs.envio.dev/mcp"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="other-mcp-clients">Other MCP clients<a class="hash-link" aria-label="Direct link to Other MCP clients" title="Direct link to Other MCP clients" href="https://docs.envio.dev/blog/envio-docs-mcp-server#other-mcp-clients">​</a></h3>
<p>Point any MCP-compatible client to <code>https://docs.envio.dev/mcp</code> using the Streamable HTTP transport.</p>
<p>For full, always-current setup instructions, see the Envio Docs MCP Server guide.</p>
<p>Once connected, your assistant can search the docs and pull back full pages whenever it needs context, with no extra prompting from you.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/envio-docs-mcp-server#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-an-mcp-server-1">What Is an MCP Server?<a class="hash-link" aria-label="Direct link to What Is an MCP Server?" title="Direct link to What Is an MCP Server?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#what-is-an-mcp-server-1">​</a></h3>
<p>An MCP server is a server that implements the Model Context Protocol, an open standard for connecting AI assistants to external tools and data sources. It lets AI coding assistants like Claude Code and Cursor access real, structured information on demand rather than relying on training data.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-envio-docs-mcp-server-1">What Is the Envio Docs MCP Server?<a class="hash-link" aria-label="Direct link to What Is the Envio Docs MCP Server?" title="Direct link to What Is the Envio Docs MCP Server?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#what-is-the-envio-docs-mcp-server-1">​</a></h3>
<p>The Envio Docs MCP server is a hosted server at <a href="https://docs.envio.dev/mcp" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/mcp</a> that gives AI coding assistants direct access to Envio's documentation. It supports two operations: searching across all docs and fetching the full content of any documentation page.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="which-ai-assistants-does-the-envio-mcp-server-support">Which AI Assistants Does the Envio MCP Server Support?<a class="hash-link" aria-label="Direct link to Which AI Assistants Does the Envio MCP Server Support?" title="Direct link to Which AI Assistants Does the Envio MCP Server Support?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#which-ai-assistants-does-the-envio-mcp-server-support">​</a></h3>
<p>The Envio Docs MCP server works with any MCP-compatible client. Setup instructions are available for Claude Code and Cursor / VS Code. Any other client that supports the Streamable HTTP transport can connect using the endpoint URL directly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-the-envio-mcp-server-always-up-to-date">Is the Envio MCP Server Always Up to Date?<a class="hash-link" aria-label="Direct link to Is the Envio MCP Server Always Up to Date?" title="Direct link to Is the Envio MCP Server Always Up to Date?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#is-the-envio-mcp-server-always-up-to-date">​</a></h3>
<p>Yes. The MCP server reads directly from the live Envio docs site. When documentation is updated, your assistant has access to the latest version immediately.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-get-started-with-envio-hyperindex">How Do I Get Started with Envio HyperIndex?<a class="hash-link" aria-label="Direct link to How Do I Get Started with Envio HyperIndex?" title="Direct link to How Do I Get Started with Envio HyperIndex?" href="https://docs.envio.dev/blog/envio-docs-mcp-server#how-do-i-get-started-with-envio-hyperindex">​</a></h3>
<p>Run <code>pnpx envio init</code> to scaffold your first indexer in minutes. Write event handlers in TypeScript, configure your chains and contracts in <code>config.yaml</code>, and deploy to Envio Cloud for managed hosting. See the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">HyperIndex overview</a> and <a href="https://docs.envio.dev/docs/HyperIndex/getting-started" target="_blank" rel="noopener noreferrer">getting started guide</a> for full documentation.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-docs-mcp-server#build-with-envio">​</a></h2>
<p>Envio HyperIndex is independently benchmarked as the fastest EVM blockchain indexer available. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, or come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[How Envio Indexed 4 Billion Polymarket Events]]></title>
            <link>https://docs.envio.dev/blog/polymarket-hyperindex-case-study</link>
            <guid>https://docs.envio.dev/blog/polymarket-hyperindex-case-study</guid>
            <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio HyperIndex replaced 8 Polymarket subgraphs with one TypeScript indexer on Polygon, syncing 4 billion events in 6 days. Open source reference included.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/polymarket-hyperindex-case-study.png" alt="Indexing 4 Billion Polymarket Events Using Envio HyperIndex" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Polymarket's 8 independent subgraphs on The Graph were replaced with a single Envio HyperIndex indexer written in TypeScript.</li>
<li>The unified indexer synced over 4,000,000,000 events from block 3,764,531 on Polygon Mainnet in 6 days.</li>
<li>Handler merging processes each shared contract event once, updating all relevant domains simultaneously rather than redundantly across multiple subgraphs.</li>
<li>The full indexer is open source at <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a>.</li>
</ul></div></div>
<p><a href="https://polymarket.com/" target="_blank" rel="noopener noreferrer">Polymarket</a> is one of the most data-intensive protocols in Web3. Every trade, position, fee, liquidity event, and oracle resolution across its entire prediction market ecosystem lives onchain on Polygon. Querying any of it meaningfully requires a serious blockchain indexer.</p>
<p>For years, Polymarket's data infrastructure relied on 8 independent subgraphs on <a href="https://thegraph.com/" target="_blank" rel="noopener noreferrer">The Graph</a>, each written in AssemblyScript, each tracking a separate domain, all running since 2021. This post documents how all 8 were replaced with a single Envio HyperIndex indexer, syncing over 4,000,000,000 events in 6 days on Polygon Mainnet.</p>
<p>The indexer is fully open source: <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-hyperindex-the-fastest-blockchain-indexer-available">Envio HyperIndex: The Fastest Blockchain Indexer Available<a class="hash-link" aria-label="Direct link to Envio HyperIndex: The Fastest Blockchain Indexer Available" title="Direct link to Envio HyperIndex: The Fastest Blockchain Indexer Available" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#envio-hyperindex-the-fastest-blockchain-indexer-available">​</a></h2>
<p>Envio is a real-time multichain blockchain indexing framework for EVM chains. Developers write event handlers in TypeScript and deploy a single indexer that covers multiple contracts, chains, and domains simultaneously.</p>
<p>HyperIndex is independently benchmarked as the fastest blockchain indexer available. In the Uniswap V2 Factory <a href="https://github.com/enviodev/open-indexer-benchmark" target="_blank" rel="noopener noreferrer">benchmark run by Sentio</a> in May 2025, HyperIndex completed in 1 minute, 143x faster than The Graph and 15x faster than the nearest competitor. In the LBTC benchmark (April 2025), HyperIndex completed in 3 minutes versus 3 hours 9 minutes for The Graph.</p>
<p>This performance comes from <a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync</a>, Envio's proprietary data engine. Instead of querying RPC endpoints block by block, HyperSync fetches filtered event data in bulk directly from a purpose-built data lake, delivering up to 2,000x faster data access than standard RPC. Polygon is one of <!-- -->87+<!-- --> EVM chains supported with native HyperSync coverage.</p>
<p>See full list of HyperSync supported networks here: <a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks</a></p>
<table><thead><tr><th>Indexer</th><th>Time (Uniswap V2 Factory benchmark, Sentio May 2025)</th><th>vs HyperIndex</th></tr></thead><tbody><tr><td>Envio HyperIndex</td><td>1 minute</td><td>baseline</td></tr><tr><td>Subsquid (SQD)</td><td>~15 minutes</td><td>15x slower</td></tr><tr><td>The Graph</td><td>~143 minutes</td><td>143x slower</td></tr><tr><td>Ponder</td><td>~158 minutes</td><td>158x slower</td></tr></tbody></table>
<p>For a full breakdown of how HyperIndex compares across all major blockchain indexers, see the <a href="https://docs.envio.dev/docs/HyperIndex/benchmarks" target="_blank" rel="noopener noreferrer">complete benchmark comparison</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem-8-subgraphs-one-protocol-4-years-of-fragmentation">The Problem: 8 Subgraphs, One Protocol, 4 Years of Fragmentation<a class="hash-link" aria-label="Direct link to The Problem: 8 Subgraphs, One Protocol, 4 Years of Fragmentation" title="Direct link to The Problem: 8 Subgraphs, One Protocol, 4 Years of Fragmentation" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#the-problem-8-subgraphs-one-protocol-4-years-of-fragmentation">​</a></h2>
<p>Polymarket's indexing infrastructure grew organically alongside the protocol. By the time the architecture was fully established, 8 independent subgraphs were running in parallel on The Graph:</p>
<table><thead><tr><th>Subgraph</th><th>Domain</th></tr></thead><tbody><tr><td>fee-module</td><td>Fee refunds from FeeModule and NegRiskFeeModule</td></tr><tr><td>sports-oracle</td><td>UMA sports oracle games, markets, and scores</td></tr><tr><td>wallet</td><td>Wallet creation (Gnosis Safe proxies) and USDC balances</td></tr><tr><td>orderbook</td><td>Exchange order fills, matches, per-token and global volume</td></tr><tr><td>open-interest</td><td>Global and per-market open interest via splits, merges, and redemptions</td></tr><tr><td>activity</td><td>Splits, merges, redemptions, and neg-risk conversions</td></tr><tr><td>pnl</td><td>User positions, weighted average cost basis, and realized PnL</td></tr><tr><td>fpmm</td><td>Fixed Product Market Maker analytics: AMM pools, liquidity, and pricing</td></tr></tbody></table>
<p>The core problem with this setup is shared contracts. A single <code>ConditionalTokens</code> event was being listened for and processed independently across 3 or 4 separate subgraphs. Every shared event meant redundant processing, redundant infrastructure, and fragmented data that required joining across multiple APIs at query time. Handlers were written in AssemblyScript, a stricter WebAssembly-compiled subset of TypeScript, adding tooling overhead and limiting what logic could run inside a handler.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-solution-one-hyperindex-indexer-on-polygon">The Solution: One HyperIndex Indexer on Polygon<a class="hash-link" aria-label="Direct link to The Solution: One HyperIndex Indexer on Polygon" title="Direct link to The Solution: One HyperIndex Indexer on Polygon" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#the-solution-one-hyperindex-indexer-on-polygon">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="handler-merging">Handler Merging<a class="hash-link" aria-label="Direct link to Handler Merging" title="Direct link to Handler Merging" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#handler-merging">​</a></h3>
<p>The defining architectural decision in this indexer is handler merging. Rather than running separate listeners per domain for the same contract event, a single handler fires and updates all relevant entities simultaneously.</p>
<p>A <code>ConditionalTokens.PositionSplit</code> event previously triggered separate processing across the open-interest, activity, and pnl subgraphs. In the unified HyperIndex indexer, one handler fires once and simultaneously updates open interest, records the split activity, and adjusts user PnL positions. The event is processed once. That's it.</p>
<p>The full handler structure:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">src/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  handlers/</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">ConditionalTokens.ts       # Open interest + activity + PnL (merged from 4 subgraphs)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Exchange.ts                # Orderbook + PnL</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">NegRiskAdapter.ts          # Open interest + activity + PnL</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">FixedProductMarketMaker.ts # FPMM analytics + PnL + LP tracking</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">FPMMFactory.ts             # Dynamic contract registration</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">FeeModule.ts               # Fee refund tracking</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">UmaSportsOracle.ts         # Sports oracle</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Wallet.ts                  # Wallet creation + USDC balances</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="contracts-indexed">Contracts Indexed<a class="hash-link" aria-label="Direct link to Contracts Indexed" title="Direct link to Contracts Indexed" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#contracts-indexed">​</a></h3>
<p>The indexer covers the full surface area of Polymarket's onchain contracts on Polygon:</p>
<ul>
<li><strong>Exchange + NegRiskExchange</strong>: OrderFilled, OrdersMatched, TokenRegistered</li>
<li><strong>ConditionalTokens</strong>: ConditionPreparation, ConditionResolution, PositionSplit, PositionsMerge, PayoutRedemption</li>
<li><strong>NegRiskAdapter</strong>: MarketPrepared, QuestionPrepared, PositionSplit, PositionsMerge, PayoutRedemption, PositionsConverted</li>
<li><strong>FPMMFactory</strong>: FixedProductMarketMakerCreation, with dynamic contract registration for all FPMM instances</li>
<li><strong>FixedProductMarketMaker (dynamic)</strong>: FPMMBuy, FPMMSell, FPMMFundingAdded, FPMMFundingRemoved, Transfer</li>
<li><strong>FeeModule + NegRiskFeeModule</strong>: FeeRefunded</li>
<li><strong>UmaSportsOracle</strong>: GameCreated, GameSettled, MarketCreated, MarketResolved, and more</li>
<li><strong>USDC / RelayHub / SafeProxyFactory</strong>: Transfer, TransactionRelayed, ProxyCreation</li>
</ul>
<p>Dynamic contract registration is handled through <code>FPMMFactory</code>. As new Fixed Product Market Maker instances are created onchain, the indexer registers them automatically without a redeployment.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="schema-25-entity-types-across-all-domains">Schema: 25+ Entity Types Across All Domains<a class="hash-link" aria-label="Direct link to Schema: 25+ Entity Types Across All Domains" title="Direct link to Schema: 25+ Entity Types Across All Domains" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#schema-25-entity-types-across-all-domains">​</a></h3>
<p>The schema covers every domain previously spread across 8 separate subgraphs, all queryable from a single GraphQL endpoint:</p>
<ul>
<li><strong>Orderbook</strong>: <code>OrderFilledEvent</code>, <code>OrdersMatchedEvent</code>, <code>Orderbook</code>, <code>OrdersMatchedGlobal</code>, <code>MarketData</code></li>
<li><strong>Open Interest</strong>: <code>Condition</code>, <code>MarketOpenInterest</code>, <code>GlobalOpenInterest</code>, <code>NegRiskEvent</code></li>
<li><strong>Activity</strong>: <code>Split</code>, <code>Merge</code>, <code>Redemption</code>, <code>NegRiskConversion</code>, <code>Position</code></li>
<li><strong>PnL</strong>: <code>UserPosition</code>, tracking amount, average price, realized PnL, and total bought per user per token</li>
<li><strong>FPMM</strong>: <code>FixedProductMarketMaker</code>, <code>FpmmTransaction</code>, <code>FpmmFundingAddition</code>, <code>FpmmFundingRemoval</code>, <code>FpmmPoolMembership</code>, <code>Collateral</code></li>
<li><strong>Wallet</strong>: <code>Wallet</code>, <code>GlobalUSDCBalance</code></li>
<li><strong>Fee Module</strong>: <code>FeeRefunded</code></li>
<li><strong>Sports Oracle</strong>: <code>Game</code>, <code>Market</code></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-hyperindex-vs-the-graph-before-and-after">Envio HyperIndex vs The Graph: Before and After<a class="hash-link" aria-label="Direct link to Envio HyperIndex vs The Graph: Before and After" title="Direct link to Envio HyperIndex vs The Graph: Before and After" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#envio-hyperindex-vs-the-graph-before-and-after">​</a></h2>
<table><thead><tr><th></th><th>The Graph (8 subgraphs)</th><th>Envio HyperIndex (1 indexer)</th></tr></thead><tbody><tr><td>Language</td><td>AssemblyScript</td><td>TypeScript</td></tr><tr><td>Subgraphs / indexers</td><td>8</td><td>1</td></tr><tr><td>Event processing</td><td>Redundant across subgraphs</td><td>Once per event, merged handlers</td></tr><tr><td>Cross-domain queries</td><td>Requires joining multiple APIs</td><td>Single GraphQL endpoint</td></tr><tr><td>Deployments to maintain</td><td>8</td><td>1</td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-results">The Results<a class="hash-link" aria-label="Direct link to The Results" title="Direct link to The Results" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#the-results">​</a></h2>
<p>The indexer synced Polymarket's full onchain history on Polygon from block 3,764,531 to 100% sync in 6 days, processing over 4,000,000,000 events. The repo includes 29 tests covering all handler phases, including a HyperSync integration test.</p>
<p>Run it locally with <code>pnpm dev</code> and compare the data with data from Polymarket subgraphs.</p>
<img src="https://docs.envio.dev/blog-assets/polymarket-hyperindex-case-study-1.png" alt="Polymarket indexer sync results" width="100%">
<p>Live deployment: <a href="https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad" target="_blank" rel="noopener noreferrer">https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-teams-migrate-to-hyperindex-from-the-graph">Why Teams Migrate to HyperIndex from The Graph<a class="hash-link" aria-label="Direct link to Why Teams Migrate to HyperIndex from The Graph" title="Direct link to Why Teams Migrate to HyperIndex from The Graph" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#why-teams-migrate-to-hyperindex-from-the-graph">​</a></h2>
<p>Polymarket's setup before this migration is a pattern that shows up across the ecosystem: multiple subgraphs, shared contracts, AssemblyScript handlers, fragmented data. Here is what changes when teams move to HyperIndex:</p>
<p><strong>Speed.</strong> HyperIndex is 143x faster than The Graph on independent benchmarks. For protocols with years of history like Polymarket, that directly translates to days versus months on historical sync.</p>
<p><strong>TypeScript, not AssemblyScript.</strong> Handlers are standard TypeScript with generated types from both the schema and ABIs. Any npm package works. No WebAssembly compilation. No AssemblyScript-specific constraints.</p>
<p><strong>One codebase.</strong> All domains, all contracts, all chains in a single indexer. One deployment to ship, one codebase to maintain, one endpoint to query.</p>
<p><strong>Single source of truth.</strong> Cross-domain queries happen at the database level, not at the application layer. No joining across APIs at runtime.</p>
<p><strong>Dynamic contract registration.</strong> Factory contracts that create new instances onchain register them automatically, without requiring a redeployment.</p>
<p>Envio offers white-glove migration support for teams moving from The Graph or any other indexer. The Polymarket indexer is an open-source reference for what a large-scale migration looks like end to end.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-polymarket">What Is Polymarket?<a class="hash-link" aria-label="Direct link to What Is Polymarket?" title="Direct link to What Is Polymarket?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-is-polymarket">​</a></h3>
<p>Polymarket is the world's largest decentralized prediction market, built on Polygon. Users trade outcome shares on real-world events using USDC. All positions, trades, and settlements are handled entirely onchain via smart contracts with no central custodian.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-a-blockchain-indexer">What Is a Blockchain Indexer?<a class="hash-link" aria-label="Direct link to What Is a Blockchain Indexer?" title="Direct link to What Is a Blockchain Indexer?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-is-a-blockchain-indexer">​</a></h3>
<p>A blockchain indexer is a system that listens to onchain events and organises them into a structured, queryable database. Developers use blockchain indexers to build fast backends for DeFi protocols, trading interfaces, analytics tools, and onchain AI agents without querying slow RPC endpoints directly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-fastest-blockchain-indexer">What Is the Fastest Blockchain Indexer?<a class="hash-link" aria-label="Direct link to What Is the Fastest Blockchain Indexer?" title="Direct link to What Is the Fastest Blockchain Indexer?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-is-the-fastest-blockchain-indexer">​</a></h3>
<p>Envio HyperIndex is independently benchmarked as the fastest blockchain indexer available. In the Uniswap V2 Factory benchmark run by Sentio in May 2025, HyperIndex completed in 1 minute, 143x faster than The Graph and 15x faster than the nearest competitor (Subsquid).</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hyperindex">What Is HyperIndex?<a class="hash-link" aria-label="Direct link to What Is HyperIndex?" title="Direct link to What Is HyperIndex?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-is-hyperindex">​</a></h3>
<p>HyperIndex is a multichain blockchain indexing framework for EVM chains built by Envio. Developers write event handlers in TypeScript and deploy a single indexer covering multiple contracts, chains, and domains. It uses HyperSync, Envio's proprietary data engine, for historical sync speeds not achievable through standard RPC polling.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hypersync">What Is HyperSync?<a class="hash-link" aria-label="Direct link to What Is HyperSync?" title="Direct link to What Is HyperSync?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-is-hypersync">​</a></h3>
<p>HyperSync is Envio's high-performance data engine. Instead of querying RPC endpoints block by block, HyperSync fetches filtered event data in bulk from a purpose-built data lake, delivering up to 2,000x faster data access than traditional RPC. <!-- -->87+<!-- --> EVM chains have native HyperSync coverage, with any EVM chain accessible via standard RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-index-polymarket-data">How Do I Index Polymarket Data?<a class="hash-link" aria-label="Direct link to How Do I Index Polymarket Data?" title="Direct link to How Do I Index Polymarket Data?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#how-do-i-index-polymarket-data">​</a></h3>
<p>The fastest way to index Polymarket data on Polygon is with Envio HyperIndex and HyperSync. The full open-source reference implementation is available at <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">github.com/enviodev/polymarket-indexer</a>. It covers all 8 domains of Polymarket's onchain activity and syncs the full history in 6 days.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-long-does-it-take-to-index-polymarkets-full-history-on-polygon">How Long Does It Take to Index Polymarket's Full History on Polygon?<a class="hash-link" aria-label="Direct link to How Long Does It Take to Index Polymarket's Full History on Polygon?" title="Direct link to How Long Does It Take to Index Polymarket's Full History on Polygon?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#how-long-does-it-take-to-index-polymarkets-full-history-on-polygon">​</a></h3>
<p>Using Envio HyperIndex with HyperSync, the full historical sync of Polymarket's onchain data on Polygon, over 4,000,000,000 events from block 3,764,531, completed in 6 days.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-migrate-from-the-graph-to-hyperindex">How Do I Migrate From The Graph to HyperIndex?<a class="hash-link" aria-label="Direct link to How Do I Migrate From The Graph to HyperIndex?" title="Direct link to How Do I Migrate From The Graph to HyperIndex?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#how-do-i-migrate-from-the-graph-to-hyperindex">​</a></h3>
<p>Because HyperIndex handlers are written in TypeScript, and AssemblyScript is a subset of TypeScript, most handler logic can be carried across directly. Envio also provides a full <a href="https://docs.envio.dev/docs/HyperIndex/migration-guide" target="_blank" rel="noopener noreferrer">migration guide</a>, a CLI validation tool to compare output between both endpoints, and white-glove migration support. The Polymarket indexer is a concrete open-source reference for a large-scale migration from The Graph.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-hyperindex-support-dynamic-contract-registration">Does HyperIndex Support Dynamic Contract Registration?<a class="hash-link" aria-label="Direct link to Does HyperIndex Support Dynamic Contract Registration?" title="Direct link to Does HyperIndex Support Dynamic Contract Registration?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#does-hyperindex-support-dynamic-contract-registration">​</a></h3>
<p>Yes. New contract instances created onchain, like Polymarket's FPMM pools, are registered dynamically by a factory handler without requiring a redeployment.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-chains-does-envio-support">What Chains Does Envio Support?<a class="hash-link" aria-label="Direct link to What Chains Does Envio Support?" title="Direct link to What Chains Does Envio Support?" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#what-chains-does-envio-support">​</a></h3>
<p>Envio supports any EVM chain. <!-- -->87+<!-- --> EVM chains have native HyperSync coverage for maximum speed, including Polygon, Ethereum, Base, Arbitrum, Optimism, and more. Any EVM chain without native HyperSync support can be indexed via standard RPC.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-started">Get Started<a class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#get-started">​</a></h2>
<p>The Polymarket indexer is fully open source and available as a production reference for anyone building on Polygon or migrating from The Graph. For a hands-on guide to streaming Polymarket trade data in real time, see <a href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync" target="_blank" rel="noopener noreferrer">How to Track Polymarket Trades Using Envio HyperSync</a>.</p>
<ul>
<li>Repo: <a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/polymarket-indexer</a></li>
<li>Live deployment: <a href="https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad" target="_blank" rel="noopener noreferrer">https://envio.dev/app/moose-code/polymarket-indexer/7cad3ad</a></li>
<li>Envio docs: <a href="https://docs.envio.dev/" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/</a></li>
<li>Discord: <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">https://discord.gg/envio</a></li>
<li>Telegram: <a href="https://t.me/+kAIGElzPjApiMjI0" target="_blank" rel="noopener noreferrer">https://t.me/+kAIGElzPjApiMjI0</a></li>
<li>Follow us on X: <a href="https://x.com/envio_indexer" target="_blank" rel="noopener noreferrer">https://x.com/envio_indexer</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study#build-with-envio">​</a></h2>
<p>Envio HyperIndex is independently benchmarked as the fastest EVM blockchain indexer available. The Polymarket indexer is one example of what's possible. If you're building onchain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, or talk to us about your data needs.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>case-studies</category>
        </item>
        <item>
            <title><![CDATA[How to Track Polymarket Trades Using Envio's HyperSync]]></title>
            <link>https://docs.envio.dev/blog/track-polymarket-trades-hypersync</link>
            <guid>https://docs.envio.dev/blog/track-polymarket-trades-hypersync</guid>
            <pubDate>Tue, 24 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Track Polymarket trades in real time using Envio HyperSync. Stream OrderFilled events on Polygon and decode trade data using TypeScript and Bun.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/polymarket-trades-hypersync.png" alt="Cover Image: Track Polymarket Trades in Real-Time" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Build a real-time Polymarket trade tracker using Envio HyperSync and TypeScript with Bun.</li>
<li>Stream block heights from Polygon and query OrderFilled events from the Polymarket Exchange contracts on each new block.</li>
<li>Decode events with Viem, identify buy vs sell trades by checking <code>makerAssetId</code>, and calculate price per share.</li>
<li>Extend with filters for trade amount or specific wallet addresses to track high-conviction traders.</li>
</ul></div></div>
<p>Since the rise of prediction markets like <a href="https://polymarket.com/" target="_blank" rel="noopener noreferrer">Polymarket</a> and <a href="https://kalshi.com/" target="_blank" rel="noopener noreferrer">Kalshi</a>, many people have been tracking activity on them to get a sense of where the money is going. If we try to track every trade on these prediction markets, you will see many people betting like $10 here, $15 there. If you want a stronger signal, then you should track trades with higher amounts, since those traders have more conviction in the outcome they are betting on.</p>
<p>In this article, we are going to build a tool with HyperSync where you can track Polymarket trades above a certain amount. We also have one feature where you can track trades from certain addresses. If you know some addresses from good traders, you can follow them too.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="prerequisites">Prerequisites<a class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#prerequisites">​</a></h2>
<p>We are going to use Bun for this article, so make sure you have it installed. If not, please check the <a href="https://bun.com/docs/installation" target="_blank" rel="noopener noreferrer">Bun documentation</a> for installation instructions. If you want to use some other runtime that supports TypeScript, you can do that too.</p>
<p>You will also need an Envio API token to access HyperSync. If you don’t have it already, go to <a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">https://envio.dev/app/api-tokens</a> and you can find your token there.</p>
<p>Here are step-by-step instructions for creating new API tokens: <a href="https://docs.envio.dev/docs/HyperSync/api-tokens#generating-api-tokens" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperSync/api-tokens#generating-api-tokens</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hypersync">What is HyperSync<a class="hash-link" aria-label="Direct link to What is HyperSync" title="Direct link to What is HyperSync" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#what-is-hypersync">​</a></h2>
<p><a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync</a> is Envio's high-performance blockchain data retrieval layer, built as an alternative to traditional JSON-RPC endpoints. It gives developers direct access to onchain data up to 2000x faster than standard RPC methods.</p>
<p>For this article, we are using HyperSync to stream real-time block heights and query Polymarket trade events on Polygon as they happen. Client libraries are available for Python, Rust, Node.js, and Go. HyperSync supports <!-- -->87+<!-- --> EVM chains, so the same approach works across any supported network.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="orderfilled-event">OrderFilled Event<a class="hash-link" aria-label="Direct link to OrderFilled Event" title="Direct link to OrderFilled Event" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#orderfilled-event">​</a></h2>
<p>Before we start writing the script, let’s talk about the <code>OrderFilled</code> event. This event is emitted when a trade has been filled, so these are confirmed trades where a user is buying or selling shares. Here is the event:</p>
<div class="language-solidity codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-solidity codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">    event OrderFilled(</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        bytes32 indexed orderHash,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        address indexed maker,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        address indexed taker,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        uint256 makerAssetId,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        uint256 takerAssetId,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        uint256 makerAmountFilled,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        uint256 takerAmountFilled,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        uint256 fee</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    );</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Most of the fields are self-explanatory, but we still haven’t answered one question: if this event is emitted for all orders, then how do we know which one is buy vs sell? If the value of <code>makerAssetId</code> is <code>0</code>, then that is a buy order where the user is buying shares, and vice versa.</p>
<p>To calculate price per share for a buy trade, we can use <code>makerAmountFilled</code> and <code>takerAmountFilled</code>.</p>
<p>Price per share in a buy trade = <code>makerAmountFilled / takerAmountFilled</code></p>
<p>To calculate per-share price in a sell trade, we just switch those values. Now that we have a basic understanding of what data to fetch and what that data tells us, we can start writing our script with Bun.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="using-hypersync-client">Using HyperSync Client<a class="hash-link" aria-label="Direct link to Using HyperSync Client" title="Direct link to Using HyperSync Client" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#using-hypersync-client">​</a></h2>
<p>To create a Bun project and install the HyperSync client along with Viem for decoding events, you can use the following commands:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">mkdir</span><span class="token plain"> track-trades </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> track-trades</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">bun init </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-y</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">bun </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> @envio-dev/hypersync-client viem</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If you’re new to HyperSync clients, please start by going through these examples: <a href="https://docs.envio.dev/docs/HyperSync/hypersync-clients" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/docs/HyperSync/hypersync-clients</a>.</p>
<p>Let’s discuss how we are going to structure our script. Instead of streaming events directly, we are going to stream height. When we get a new height, we query HyperSync to fetch the data we need. Here is a visual representation of that:</p>
<p><img decoding="async" loading="lazy" alt="Visual representation of the script&amp;#39;s data flow" src="https://docs.envio.dev/assets/images/polymarket-data-flow-f286c84bfdd1ad66bc87dda1efd7d90a.png" width="3924" height="2802" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="stream-height">Stream Height<a class="hash-link" aria-label="Direct link to Stream Height" title="Direct link to Stream Height" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#stream-height">​</a></h2>
<p>We already have a height-streaming example in the HyperSync Node client, and we are going to use that here. Open <code>index.ts</code> and paste the following snippet, then we can go over it.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// for later use</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name">QueryResponseData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// for later use</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@envio-dev/hypersync-client"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> decodeEventLog </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"viem"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// for later use</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">main</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Create hypersync client using the mainnet hypersync endpoint</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> client </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://polygon.hypersync.xyz"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    apiToken</span><span class="token operator">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">ENVIO_API_TOKEN</span><span class="token operator">!</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Create a height stream to monitor blockchain height changes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> heightStream </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">streamHeight</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Height stream created. Listening for height updates..."</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Track the last known height to detect changes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">// Receive the next event from the height stream</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> event </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> heightStream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">recv</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event </span><span class="token operator">===</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Height stream ended by server"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">// Handle different types of events</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">type</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Height"</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">fetchOrderFilledEvents</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">height</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// will be explained later</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Connected"</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">Connected to height stream</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Reconnecting"</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">Reconnecting to height stream in </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">delayMillis</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">ms due to error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">event</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">errorMsg</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">break</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token comment" style="color:rgb(98, 114, 164)">// Tells the typescript compiler that we have covered all possible event types</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> _exhaustiveCheck</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">never</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Unhandled event type"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Error in height stream:"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// Always close the stream to clean up resources</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> heightStream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">close</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Height stream closed"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">main</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">catch</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The first thing we are doing in <code>main</code> is creating the HyperSync client with <code>url</code> and <code>apiToken</code> (which should be stored in a <code>.env</code> file, so create one and store your Envio API token there).</p>
<p>We have a <code>streamHeight</code> function on the client that emits 3 types of events: <code>Height</code>, <code>Connected</code>, and <code>Reconnecting</code>. When we get a new <code>Height</code> event with the latest block number, we call <code>fetchOrderFilledEvents</code>, where our parsing logic will live.</p>
<p>After creating the stream with <code>streamHeight</code>, we need to listen to those events, so we created a <code>while</code> loop that checks data from <code>.recv()</code> and a <code>switch</code> statement to act on the event type we get. The rest is mostly boilerplate error handling, so we don’t need to go too deep into that.</p>
<p>Now we have our streaming logic, so we can move to <code>fetchOrderFilledEvents</code>, which will handle the event parsing.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="fetchorderfilledevents-function">fetchOrderFilledEvents Function<a class="hash-link" aria-label="Direct link to fetchOrderFilledEvents Function" title="Direct link to fetchOrderFilledEvents Function" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#fetchorderfilledevents-function">​</a></h2>
<p>This function will take the height we got from <code>streamHeight</code> and query blocks to get the events we want. Let’s start with a few basic things we need for fetching and decoding the data:</p>
<ul>
<li>Contract addresses</li>
<li>ABI of the event</li>
<li>Event signature hash (aka <code>Topic0</code>)</li>
</ul>
<p>Here they are, so add them somewhere at the top of the file.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">export</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">EXCHANGE_ADDRESSES</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"0xc5d563a36ae78145c45a50134d48a1215220f80a"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">a</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> a</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toLowerCase</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_TOPIC</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token string" style="color:rgb(255, 121, 198)">"0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toLowerCase</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_ABI</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  anonymous</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  inputs</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bytes32"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"orderHash"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bytes32"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"maker"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"taker"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"makerAssetId"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"takerAssetId"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"makerAmountFilled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"takerAmountFilled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      indexed</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      internalType</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"fee"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uint256"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  name</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrderFilled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  type</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"event"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_ABI_ITEMS</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_ABI</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// we can push it to query directly as an array</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Let's define the function signature. We are going to pass the HyperSync client and block height to this function.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">fetchOrderFilledEvents</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">client</span><span class="token operator">:</span><span class="token plain"> HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> height</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>To fetch the data from HyperSync, we need to create a query. If you're not familiar with HyperSync queries, the query builder at <a href="https://builder.hypersync.xyz/" target="_blank" rel="noopener noreferrer">https://builder.hypersync.xyz/</a> is a good starting point. In short, in this query we define which event from which contracts we want to fetch, and what fields we want in the response.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> query</span><span class="token operator">:</span><span class="token plain"> Query </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fromBlock</span><span class="token operator">:</span><span class="token plain"> height</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  logs</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      address</span><span class="token operator">:</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">EXCHANGE_ADDRESSES</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      topics</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_TOPIC</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  fieldSelection</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    log</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic3"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"TransactionHash"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token string" style="color:rgb(255, 121, 198)">"BlockNumber"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Use the <code>get</code> function to fetch the data and store the logs/events in an array that we can loop over.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> res </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> logs </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> QueryResponseData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logs </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Let’s loop over that array and use <code>decodeEventLog</code> from Viem to decode the data so we can analyze it.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> log </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">of</span><span class="token plain"> logs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> decoded </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">decodeEventLog</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    abi</span><span class="token operator">:</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_ABI_ITEMS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    data</span><span class="token operator">:</span><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    topics</span><span class="token operator">:</span><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">topics </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token operator">...</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">decoded</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventName </span><span class="token operator">!==</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrderFilled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">continue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> makerAssetId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> makerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> takerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> maker</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> taker </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    decoded</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">args </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      makerAssetId</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      makerAmountFilled</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      takerAmountFilled</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      maker</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      taker</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// TODO: Check if trade is Buy if yes, then log details along with price per share</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The last part of this script is checking if the trade is a buy trade, which we can confirm when <code>makerAssetId</code> is <code>0</code>. We also need to calculate price per share. We already know the formula: <code>makerAmountFilled / takerAmountFilled</code>. That value should be formatted to 6 decimals, and then we have the price per share.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">formatRatio</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  numerator</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  denominator</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  precision </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">6</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">denominator </span><span class="token operator">===</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> scale </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">10n</span><span class="token plain"> </span><span class="token operator">**</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">BigInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">precision</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> scaled </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">numerator </span><span class="token operator">*</span><span class="token plain"> scale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain"> denominator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> whole </span><span class="token operator">=</span><span class="token plain"> scaled </span><span class="token operator">/</span><span class="token plain"> scale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> fraction </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">scaled </span><span class="token operator">%</span><span class="token plain"> scale</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toString</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">padStart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">precision</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">whole</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">.</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">fraction</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>fetchOrderFilledEvents</code> should look like this at the end.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">fetchOrderFilledEvents</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">client</span><span class="token operator">:</span><span class="token plain"> HypersyncClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> height</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Topic0: 0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> query</span><span class="token operator">:</span><span class="token plain"> Query </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    fromBlock</span><span class="token operator">:</span><span class="token plain"> height</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    logs</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        address</span><span class="token operator">:</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">EXCHANGE_ADDRESSES</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        topics</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_TOPIC</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    fieldSelection</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      log</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Data"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Address"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"Topic3"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"TransactionHash"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token string" style="color:rgb(255, 121, 198)">"BlockNumber"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> res </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> logs </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> QueryResponseData</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">logs </span><span class="token operator">??</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> log </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">of</span><span class="token plain"> logs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> decoded </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">decodeEventLog</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      abi</span><span class="token operator">:</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ORDER_FILLED_ABI_ITEMS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      data</span><span class="token operator">:</span><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">data </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      topics</span><span class="token operator">:</span><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">topics </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token operator">...</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">0x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation builtin" style="color:rgb(189, 147, 249)">string</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">decoded</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">eventName </span><span class="token operator">!==</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OrderFilled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">continue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> makerAssetId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> makerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> takerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> maker</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> taker </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      decoded</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">args </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        makerAssetId</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        makerAmountFilled</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        takerAmountFilled</span><span class="token operator">:</span><span class="token plain"> bigint</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        maker</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        taker</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// TODO: Check if trade is Buy if yes, then log details along with price per share</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">makerAssetId </span><span class="token operator">===</span><span class="token plain"> </span><span class="token number">0n</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> pricePerShare </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">formatRatio</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">makerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> takerAmountFilled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token builtin" style="color:rgb(189, 147, 249)">console</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">[BUY] block=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">log</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">blockNumber</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)"> tx=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">log</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation">transactionHash</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)"> maker=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">maker</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)"> taker=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">taker</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)"> pricePerShare=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">pricePerShare</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="complete-project">Complete Project<a class="hash-link" aria-label="Direct link to Complete Project" title="Direct link to Complete Project" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#complete-project">​</a></h2>
<p>You can check the project code in this repo: <a href="https://github.com/enviodev/track-poly-trades" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/track-poly-trades</a></p>
<p>For the full production-scale Polymarket indexer covering all 8 subgraph domains and 4 billion events, see the <a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" target="_blank" rel="noopener noreferrer">Polymarket HyperIndex Case Study</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="next-steps">Next Steps<a class="hash-link" aria-label="Direct link to Next Steps" title="Direct link to Next Steps" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#next-steps">​</a></h2>
<p>Our aim was to create a tracker that filters trades based on amount and addresses, but we haven’t completed that aim yet. This article gave you the main steps you need to create that tool, so your next step is to add filtering for amount and addresses.</p>
<p>Don’t forget to share it with us on socials or in our Discord. Looking forward to seeing what you build on top of this.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="poly-whales-tui">Poly-Whales TUI<a class="hash-link" aria-label="Direct link to Poly-Whales TUI" title="Direct link to Poly-Whales TUI" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#poly-whales-tui">​</a></h2>
<p>Don’t want to set up the full project but still want to try it out? You can use the Poly-Whales TUI.</p>
<p>Run the following command in your terminal:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx poly-whales</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><img decoding="async" loading="lazy" alt="poly-whales TUI screenshot" src="https://docs.envio.dev/assets/images/poly-whales-tui-ab4fc08e86382db675161b5dbeff658b.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-envio-hypersync">What is Envio HyperSync?<a class="hash-link" aria-label="Direct link to What is Envio HyperSync?" title="Direct link to What is Envio HyperSync?" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#what-is-envio-hypersync">​</a></h3>
<p>HyperSync is Envio's high-performance blockchain data retrieval layer, built as an alternative to traditional JSON-RPC endpoints. It delivers up to 2,000x faster data access than standard RPC methods. Client libraries are available for TypeScript/Node.js, Python, Rust, and Go, with support for <!-- -->87+<!-- --> EVM chains including Polygon.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-track-polymarket-trades-in-real-time">How do I track Polymarket trades in real time?<a class="hash-link" aria-label="Direct link to How do I track Polymarket trades in real time?" title="Direct link to How do I track Polymarket trades in real time?" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#how-do-i-track-polymarket-trades-in-real-time">​</a></h3>
<p>Use the Envio HyperSync Node.js client to stream block heights from Polygon, then query the Exchange contract for OrderFilled events on each new block. Decode the event data with Viem to extract maker, taker, asset IDs, and amounts. A <code>makerAssetId</code> of 0 indicates a buy trade.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-identify-buy-vs-sell-trades-on-polymarket">How do I identify buy vs sell trades on Polymarket?<a class="hash-link" aria-label="Direct link to How do I identify buy vs sell trades on Polymarket?" title="Direct link to How do I identify buy vs sell trades on Polymarket?" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#how-do-i-identify-buy-vs-sell-trades-on-polymarket">​</a></h3>
<p>In the OrderFilled event, if <code>makerAssetId</code> is 0, the order is a buy where the maker is spending USDC to purchase shares. If <code>makerAssetId</code> is non-zero, the order is a sell. Price per share for a buy trade is <code>makerAmountFilled / takerAmountFilled</code>, formatted to 6 decimal places.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-are-the-polymarket-exchange-contract-addresses-on-polygon">What are the Polymarket Exchange contract addresses on Polygon?<a class="hash-link" aria-label="Direct link to What are the Polymarket Exchange contract addresses on Polygon?" title="Direct link to What are the Polymarket Exchange contract addresses on Polygon?" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#what-are-the-polymarket-exchange-contract-addresses-on-polygon">​</a></h3>
<p>The Polymarket Exchange contracts on Polygon are <code>0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e</code> and <code>0xc5d563a36ae78145c45a50134d48a1215220f80a</code>. The OrderFilled event topic0 is <code>0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="is-there-a-ready-made-polymarket-trade-tracker-i-can-run">Is there a ready-made Polymarket trade tracker I can run?<a class="hash-link" aria-label="Direct link to Is there a ready-made Polymarket trade tracker I can run?" title="Direct link to Is there a ready-made Polymarket trade tracker I can run?" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#is-there-a-ready-made-polymarket-trade-tracker-i-can-run">​</a></h3>
<p>Yes. The full project is available at <a href="https://github.com/enviodev/track-poly-trades" target="_blank" rel="noopener noreferrer">github.com/enviodev/track-poly-trades</a>. For a terminal UI version, run <code>pnpx poly-whales</code> to launch the Poly-Whales TUI, which tracks Polymarket whale activity in real time.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>tutorials</category>
        </item>
        <item>
            <title><![CDATA[Envio Developer Update March 2026]]></title>
            <link>https://docs.envio.dev/blog/envio-developer-update-march-2026</link>
            <guid>https://docs.envio.dev/blog/envio-developer-update-march-2026</guid>
            <pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio Developer Update March 2026: HyperIndex alpha.15-19, agentic indexing workflows, subgraph hosting, ecosystem highlights, and upcoming events.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026.png" alt="Cover Image Envio Developer Update March 2026" width="100%">
<p>March saw continued progress across HyperIndex, tooling, and the wider Envio ecosystem. We shipped multiple alpha releases focused on improving scale, flexibility, testing, and observability, alongside new workflows that make it easier to go from idea to production-ready indexers.
This month we also rebranded our Hosted Service to Envio Cloud. Alongside this, we introduced updates across subgraph hosting, agentic indexing workflows, and new ways to explore and interact with prediction market data. Across the ecosystem, we saw strong developer contributions, new projects being built with Envio, and continued momentum leading into upcoming events.</p>
<p>Let's dive in!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="alpha-releases-alpha15---alpha19">Alpha Releases: Alpha.15 -&gt; Alpha.19<a class="hash-link" aria-label="Direct link to Alpha Releases: Alpha.15 -> Alpha.19" title="Direct link to Alpha Releases: Alpha.15 -> Alpha.19" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#alpha-releases-alpha15---alpha19">​</a></h2>
<p>Loads of exciting progress landed across the latest alpha releases this month. This stretch focused on improving scale, flexibility, testing, and the overall developer experience across HyperIndex, with a mix of new features, internal improvements, and important updates to observability.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="alpha15">Alpha.15<a class="hash-link" aria-label="Direct link to Alpha.15" title="Direct link to Alpha.15" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#alpha15">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="new-getwhere-operators-_gte-_lte-_in">New getWhere operators: <code>_gte</code>, <code>_lte</code>, <code>_in</code><a class="hash-link" aria-label="Direct link to new-getwhere-operators-_gte-_lte-_in" title="Direct link to new-getwhere-operators-_gte-_lte-_in" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#new-getwhere-operators-_gte-_lte-_in">​</a></h4>
<p>Three new filter operators have been added for getWhere queries, following Hasura-style conventions:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Entity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getWhere</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> amount</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> _gte</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">100n</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Entity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getWhere</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> amount</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> _lte</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">500n</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Entity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getWhere</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> status</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> _in</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"active"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"pending"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="support-double-handler-registration">Support double handler registration<a class="hash-link" aria-label="Direct link to Support double handler registration" title="Direct link to Support double handler registration" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#support-double-handler-registration">​</a></h4>
<p>Allows double handler registration for the same event with similar filters:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ERC20</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"generated"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token constant" style="color:rgb(189, 147, 249)">ERC20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Transfer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">handler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Your logic here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token constant" style="color:rgb(189, 147, 249)">ERC20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Transfer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">handler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// And here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="other-improvements">Other improvements<a class="hash-link" aria-label="Direct link to Other improvements" title="Direct link to Other improvements" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#other-improvements">​</a></h4>
<p>We consistently improve HyperIndex to make it easier to contribute to for both humans and AI. Recent work includes:</p>
<ul>
<li>Restructuring HyperIndex into a pnpm workspace</li>
<li>Moving tests from mocha/chai to vitest</li>
<li>Reworking the CI pipeline to run faster and reuse the production artifact for both testing and publishing</li>
<li>Developing a highly customisable internal testing framework so AI can create reproduction tests for tricky edge cases</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="alpha18">Alpha.18<a class="hash-link" aria-label="Direct link to Alpha.18" title="Direct link to Alpha.18" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#alpha18">​</a></h3>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="support-indexers-with-21b-events-per-chain">Support indexers with 2.1B+ events per chain<a class="hash-link" aria-label="Direct link to Support indexers with 2.1B+ events per chain" title="Direct link to Support indexers with 2.1B+ events per chain" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#support-indexers-with-21b-events-per-chain">​</a></h4>
<p>Scale indexers approaching int32 limits. Now you can build even larger, more performant indexers with HyperIndex.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-official-metrics-endpoint">Breaking: Official <code>/metrics</code> endpoint<a class="hash-link" aria-label="Direct link to breaking-official-metrics-endpoint" title="Direct link to breaking-official-metrics-endpoint" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#breaking-official-metrics-endpoint">​</a></h4>
<p>Existing Prometheus metrics just got a major upgrade.</p>
<p>We cleaned up metric names and measured data, switched time units to seconds instead of milliseconds, and started following Prometheus naming conventions more closely.</p>
<p>We also added metrics for data points previously covered by the <code>--bench</code> feature.</p>
<p>Starting with v3.0.0, Prometheus metrics are no longer experimental. The <code>/metrics</code> endpoint now follows semver and will be documented.</p>
<p>For more information and to stay up to date with all current and past releases, be sure to check out our release notes below.</p>
<p>See full <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">release notes</a><br>
<!-- -->Star us on <a href="https://github.com/enviodev/hyperindex" target="_blank" rel="noopener noreferrer">GitHub</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hosted-service-is-now-envio-cloud">Hosted Service is now Envio Cloud<a class="hash-link" aria-label="Direct link to Hosted Service is now Envio Cloud" title="Direct link to Hosted Service is now Envio Cloud" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#hosted-service-is-now-envio-cloud">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/envio-cloud-1.png" alt="Hosted Service renamed to Envio Cloud" width="100%">
<p>We've renamed the Hosted Service to Envio Cloud. Same product, same infrastructure, no changes required on your end.
For those new to it, Envio Cloud is a fully managed hosting solution for your indexers, taking care of all infrastructure, scaling, and monitoring so you can focus on building. Plans range from free dev environments through to enterprise-grade dedicated hosting, with static production endpoints, built-in alerts, and production-ready infrastructure across all tiers.</p>
<p>Learn more in our <a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">docs</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="agentic-blockchain-indexing-with-envio">Agentic blockchain indexing with Envio<a class="hash-link" aria-label="Direct link to Agentic blockchain indexing with Envio" title="Direct link to Agentic blockchain indexing with Envio" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#agentic-blockchain-indexing-with-envio">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-1.png" alt="Agentic blockchain indexing with Envio" width="100%">
<p>We explored what it looks like to go from prompt to production-ready indexers using Envio.</p>
<p>This walkthrough shows how to scaffold an indexer for any EVM-compatible chain, push it to GitHub, and deploy it to Envio's Cloud (previously Hosted Service) without manually touching a config file.</p>
<p>As an example, <strong>400,000+ wstETH events were indexed on Monad in ~20 seconds.</strong></p>
<p>Use the following command to scaffold your indexer:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init template </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-t</span><span class="token plain"> erc20 </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-l</span><span class="token plain"> typescript </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-d</span><span class="token plain"> ./my-indexer</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Learn more in our blog and test it yourself here: <a href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="host-your-subgraphs-on-envio">Host your subgraphs on Envio<a class="hash-link" aria-label="Direct link to Host your subgraphs on Envio" title="Direct link to Host your subgraphs on Envio" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#host-your-subgraphs-on-envio">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-2.png" alt="Host your subgraphs on Envio" width="100%">
<p>Deploy and host your subgraphs with HyperIndex, with a fully subgraph-compatible GraphQL endpoint and no client changes required.</p>
<p>Migrate your existing subgraphs and keep the same API, with faster sync, quicker backfills, and deployments live in less than a day.</p>
<p>The process is handled end-to-end, converting your subgraph to HyperIndex and getting it up and running without needing to manage infrastructure.</p>
<p>Learn more here: <a href="https://envio.dev/pricing/subgraphs" target="_blank" rel="noopener noreferrer">https://envio.dev/pricing/subgraphs</a><br>
<!-- -->Get started on Discord - open a support ticket: <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">https://discord.gg/envio</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="heatbook-polymarket-orderbooks-as-heatmaps">Heatbook: Polymarket Orderbooks as Heatmaps<a class="hash-link" aria-label="Direct link to Heatbook: Polymarket Orderbooks as Heatmaps" title="Direct link to Heatbook: Polymarket Orderbooks as Heatmaps" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#heatbook-polymarket-orderbooks-as-heatmaps">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-3.png" alt="Heatbook" width="100%">
<p>An interface for visualising Polymarket orderbooks using historical heatmaps. Orderbook heatmaps for prediction markets, with 115M+ fills visualised. View any market and explore activity over time.</p>
<p>Supports <a href="https://polymarket.com/predictions/all" target="_blank" rel="noopener noreferrer">Polymarket</a>, <a href="https://limitless.exchange/markets" target="_blank" rel="noopener noreferrer">Limitless</a>, and more soon.</p>
<p>More here: <a href="https://heatbook.xyz/" target="_blank" rel="noopener noreferrer">https://heatbook.xyz/</a><br>
<!-- -->See original post: <a href="https://x.com/jonjonclark/status/2031016707309949042?s=20" target="_blank" rel="noopener noreferrer">https://x.com/jonjonclark/status/2031016707309949042?s=20</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="ethcc9-sapphire-sponsor">EthCC[9]: Sapphire Sponsor<a class="hash-link" aria-label="Direct link to EthCC[9]: Sapphire Sponsor" title="Direct link to EthCC[9]: Sapphire Sponsor" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#ethcc9-sapphire-sponsor">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-4.png" alt="EthCC sponsorship" width="100%">
<p>Envio is a Sapphire sponsor of <a href="https://ethcc.io/" target="_blank" rel="noopener noreferrer">EthCC[9]</a>, taking place at Palais des Festivals in Cannes from March 30 to April 2, 2026.</p>
<p>EthCC is an annual Ethereum community conference bringing together developers, researchers, and teams from across the ecosystem.</p>
<p>The team will be there across the week. Catch our <a href="https://ethcc.io/speakers/jonjon-clark" target="_blank" rel="noopener noreferrer">talk</a> on the Monroe stage and swing by our booth - let's chat about your data needs.</p>
<p>P.S. be sure to get your hands on one of our snazzy Envio caps and stickers.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="developer-contributions-uniswap-cca-indexer">Developer contributions: Uniswap CCA indexer<a class="hash-link" aria-label="Direct link to Developer contributions: Uniswap CCA indexer" title="Direct link to Developer contributions: Uniswap CCA indexer" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#developer-contributions-uniswap-cca-indexer">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-5.png" alt="Uniswap CCA indexer" width="100%">
<p>Check out this Uniswap CCA indexer built with HyperIndex to index continuous clearing auction contracts across Ethereum, Base, Arbitrum, and Unichain. It tracks auctions, bids, ticks, steps, and checkpoints, using HyperSync for logs and selective RPC reads for derived onchain state.</p>
<p>Shoutout to <a href="https://x.com/0xdivergence" target="_blank" rel="noopener noreferrer">@0xdivergence</a> for sharing this and building with Envio.</p>
<p>Check it out on GitHub: <a href="https://github.com/dzmbs/uniswap-cca-indexer" target="_blank" rel="noopener noreferrer">https://github.com/dzmbs/uniswap-cca-indexer</a><br>
<!-- -->Original post on X: <a href="https://x.com/0xdivergence/status/1769735600377133273" target="_blank" rel="noopener noreferrer">https://x.com/0xdivergence/status/1769735600377133273</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="open-indexer-benchmark">Open Indexer Benchmark<a class="hash-link" aria-label="Direct link to Open Indexer Benchmark" title="Direct link to Open Indexer Benchmark" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#open-indexer-benchmark">​</a></h2>
<p>We believe tech should speak for itself.</p>
<p>That's why we started working on and maintaining the Open Indexer Benchmark (originally forked from Sentio).</p>
<p>An honest, objective benchmark for blockchain indexers.</p>
<p>We're reopening it to benchmark new use cases and warmly welcome all contributions:<br>
<a href="https://github.com/enviodev/open-indexer-benchmark" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/open-indexer-benchmark</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="wonderland-ctf">Wonderland CTF<a class="hash-link" aria-label="Direct link to Wonderland CTF" title="Direct link to Wonderland CTF" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#wonderland-ctf">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-6.png" alt="Wonderland CTF" width="100%">
<p>Envio is a proud sponsor of the Wonderland CTF. The event takes place on April 1, 2026, in person at EthCC[9] in Cannes.</p>
<p>Wonderland CTF is a capture-the-flag event featuring Solidity and Aztec Noir challenges, with tracks ranging from beginner to advanced and teams of 1 to 5 members.</p>
<p>Create your team and learn more here: <a href="https://ctf.wonderland.xyz/" target="_blank" rel="noopener noreferrer">https://ctf.wonderland.xyz</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="polymarket-whale-tracker-tui">Polymarket Whale Tracker TUI<a class="hash-link" aria-label="Direct link to Polymarket Whale Tracker TUI" title="Direct link to Polymarket Whale Tracker TUI" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#polymarket-whale-tracker-tui">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-7.png" alt="Polymarket Whale Tracker TUI" width="100%">
<p>We put together a simple whale tracker using HyperSync to track Polymarket whale activity in real time. It follows large traders on Polymarket and surfaces what they're doing as it happens, making it easier to monitor higher-conviction activity without sifting through smaller trades.</p>
<p>Clean, fast, and easy to plug into your workflows.</p>
<p>More here: <a href="https://github.com/enviodev/poly-whale-tracker" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/poly-whale-tracker</a></p>
<p>Run:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">npx poly-whales</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>For a step-by-step guide on how to build your own, see: <a href="https://docs.envio.dev/blog/track-polymarket-trades-hypersync" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/track-polymarket-trades-hypersync</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="best-blockchain-indexers-in-2026">Best blockchain indexers in 2026<a class="hash-link" aria-label="Direct link to Best blockchain indexers in 2026" title="Direct link to Best blockchain indexers in 2026" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#best-blockchain-indexers-in-2026">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-8.png" alt="Best blockchain indexers in 2026" width="100%">
<p>We put together a benchmark-driven comparison of blockchain indexers, looking at how different solutions perform in practice. The guide focuses on how indexers handle real workloads, comparing performance, sync speeds, and overall reliability across different approaches.</p>
<p>It's a practical breakdown of the trade-offs between tools and what to consider when choosing an indexer for your use case.</p>
<p>Learn and compare in our latest blog: <a href="https://docs.envio.dev/blog/best-blockchain-indexers-2026" target="_blank" rel="noopener noreferrer">https://docs.envio.dev/blog/best-blockchain-indexers-2026</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="current--upcoming-events--hackathons">Current &amp; Upcoming Events &amp; Hackathons<a class="hash-link" aria-label="Direct link to Current &amp; Upcoming Events &amp; Hackathons" title="Direct link to Current &amp; Upcoming Events &amp; Hackathons" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#current--upcoming-events--hackathons">​</a></h2>
<ul>
<li><a href="https://ethcc.io/" target="_blank" rel="noopener noreferrer">EthCC - Cannes</a>: March 30th -&gt; April 2nd</li>
<li><a href="https://ethconf.com/" target="_blank" rel="noopener noreferrer">EthConf - New York</a>: June 8th -&gt; 10th</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="featured-developer-praveen-matheesha">Featured Developer: Praveen Matheesha<a class="hash-link" aria-label="Direct link to Featured Developer: Praveen Matheesha" title="Direct link to Featured Developer: Praveen Matheesha" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#featured-developer-praveen-matheesha">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-9.png" alt="Featured developer Praveen Matheesha" width="100%">
<p>This month's featured developer is Praveen Matheesha, a developer focused on building advanced onchain analytics infrastructure. He is currently working on <a href="https://x.com/paralensdotai" target="_blank" rel="noopener noreferrer">@paralensdotai</a>, a next-generation blockchain analytics engine designed to extract economic behavior and strategy-level insights from raw blockchain transactions. His focus is on turning complex onchain data into meaningful signals for traders, researchers, and analysts, with a particular interest in transaction-level intelligence, MEV analysis, and understanding the economic intent behind smart contract interactions.</p>
<p><strong>What Praveen had to say about Envio:</strong></p>
<blockquote>
<p><em><strong>"Before discovering Envio, I was building my own EVM indexer from scratch in Rust. I implemented support for chain reorg handling, historical backfilling, batched RPC ingestion, and WebSocket streams for real-time updates. While it worked, a significant amount of time went into building and maintaining the infrastructure layer itself. When I discovered Envio and HyperSync, it immediately stood out as a much more efficient approach. It solves many of the challenges around reliable, high-performance blockchain data access that developers often end up rebuilding from scratch. If I had found it earlier, I likely could have saved weeks of work and focused more on the actual analytics and business logic rather than the ingestion pipeline. I also wrote a detailed article about building a production-ready EVM indexer in Rust, where I mentioned Envio as a great option for developers who want to avoid spending weeks building indexing infrastructure themselves. Overall, HyperSync makes it significantly easier to work with large volumes of onchain data and allows developers to focus on building insights and applications instead of reinventing core data infrastructure."</strong></em></p>
</blockquote>
<p>Well done, Praveen. Be sure to follow the team on <a href="https://x.com/hpmszk" target="_blank" rel="noopener noreferrer">X</a> and check out their <a href="https://github.com/matheeshame" target="_blank" rel="noopener noreferrer">GitHub</a> to stay up to date with their latest developments.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="playlist-of-the-month">Playlist of the Month<a class="hash-link" aria-label="Direct link to Playlist of the Month" title="Direct link to Playlist of the Month" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#playlist-of-the-month">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-march-2026-10.png" alt="Playlist of the month" width="100%">
<p>▶ <a href="https://open.spotify.com/playlist/240pHTCbwvf6kBMdfWGmw9?si=bb40d616e82a49f3" target="_blank" rel="noopener noreferrer">Open Spotify</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-developer-update-march-2026#build-with-envio">​</a></h2>
<p>Envio is a multichain EVM blockchain indexer for querying real-time and historical data. If you're working on a Web3 project and want a smoother development process, Envio's got your back(end). Check out our docs, join the community, and let's talk about your data needs.</p>
<p>Stay tuned for more monthly updates by subscribing to our newsletter, following us on X, or hopping into our Discord for more up-to-date information.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>product-updates</category>
        </item>
        <item>
            <title><![CDATA[Agentic Blockchain Indexing with Envio Cloud]]></title>
            <link>https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex</link>
            <guid>https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex</guid>
            <pubDate>Fri, 20 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how an AI agent can scaffold, configure, and deploy an EVM indexer to Envio Cloud using the envio-cloud CLI, with no manual config required.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/agentic-blockchain-indexing-updated.png" alt="Cover Image Agentic Blockchain Indexing" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Envio HyperIndex and the <code>envio-cloud</code> CLI enable end-to-end agentic deployment of blockchain indexers with no manual config.</li>
<li>An AI agent scaffolded, configured, pushed to GitHub, and deployed a wstETH indexer on Monad Mainnet from a single prompt.</li>
<li>400,000 events indexed in approximately 20 seconds.</li>
<li>Every step is CLI-driven and scriptable, with JSON output for downstream agent logic.</li>
</ul></div></div>
<p>Agentic development works best when an AI agent can take a single prompt and run with it, end-to-end, without handing back to a human at every step. For blockchain indexing, that's exactly what we've built at Envio.</p>
<p>With the Envio Cloud CLI (<code>envio-cloud</code>) and HyperIndex, an agent can scaffold a production-ready indexer, configure it for any EVM-compatible chain, push it to GitHub, and deploy it to Envio Cloud, without a human ever touching a config file.</p>
<p><strong>The result: 400,000 events indexed in ~20 seconds</strong></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hyperindex">What is HyperIndex?<a class="hash-link" aria-label="Direct link to What is HyperIndex?" title="Direct link to What is HyperIndex?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#what-is-hyperindex">​</a></h2>
<p><a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">HyperIndex</a> is Envio's high-performance blockchain indexing framework. It's designed to make indexing fast to build and even faster to run, with support for EVM-compatible networks and a developer experience built around real workflows.</p>
<p>HyperIndex is the default indexing framework for agentic development with the Envio Cloud CLI tool and comprehensive Claude skills. That means when an AI agent needs to spin up a blockchain data pipeline, HyperIndex is the go-to solution.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-envio-cloud-cli-envio-cloud">The Envio Cloud CLI: <code>envio-cloud</code><a class="hash-link" aria-label="Direct link to the-envio-cloud-cli-envio-cloud" title="Direct link to the-envio-cloud-cli-envio-cloud" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#the-envio-cloud-cli-envio-cloud">​</a></h2>
<p>The <a href="https://www.npmjs.com/package/envio-cloud" target="_blank" rel="noopener noreferrer">envio-cloud</a> CLI is the command-line interface for Envio Cloud, the managed infrastructure layer that runs your HyperIndex indexers in production.</p>
<p>With it you can:</p>
<ul>
<li>Authenticate via GitHub (<code>envio-cloud login</code>)</li>
<li>Register a new indexer pointing to your GitHub repo (<code>envio-cloud indexer add</code>)</li>
<li>Monitor sync progress and deployment status in real-time (<code>envio-cloud deployment status</code>, <code>envio-cloud deployment metrics</code>)</li>
<li>Promote deployments to production (<code>envio-cloud deployment promote</code>)</li>
<li>Pull JSON output for any command (<code>-o json</code>), making it fully scriptable and agent-friendly</li>
</ul>
<p><em>No dashboard required. Everything that matters is exposed through the CLI.</em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="end-to-end-agentic-deployment-of-a-wsteth-indexer-on-monad">End-to-End: Agentic deployment of a wstETH indexer on Monad<a class="hash-link" aria-label="Direct link to End-to-End: Agentic deployment of a wstETH indexer on Monad" title="Direct link to End-to-End: Agentic deployment of a wstETH indexer on Monad" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#end-to-end-agentic-deployment-of-a-wsteth-indexer-on-monad">​</a></h2>
<p>Here's the full workflow an agent ran to deploy a live ERC20 indexer for wstETH on <a href="https://www.monad.xyz/" target="_blank" rel="noopener noreferrer">Monad</a> Mainnet, start to finish.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-1-scaffold-the-indexer">Step 1: Scaffold the indexer<a class="hash-link" aria-label="Direct link to Step 1: Scaffold the indexer" title="Direct link to Step 1: Scaffold the indexer" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-1-scaffold-the-indexer">​</a></h3>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init template -t erc20 -l typescript -d ./my-indexer</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The <code>envio</code> CLI scaffolds a TypeScript ERC20 indexer template. No API token is needed at this stage as authentication is handled through the hosted service at deployment time.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-2-configure-for-monad">Step 2: Configure for Monad<a class="hash-link" aria-label="Direct link to Step 2: Configure for Monad" title="Direct link to Step 2: Configure for Monad" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-2-configure-for-monad">​</a></h3>
<p>The agent edits <code>config.yaml</code> to target the wstETH contract on Monad Mainnet (chain ID 143, contract address <code>0x10Aeaf63194db8d453d4D85a06E5eFE1dd0b5417, start_block: 0</code>).</p>
<p>Then runs codegen and a type check to confirm everything is clean:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpm codegen</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpm tsc --noEmit</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><em>Note: the ERC20 template test file references a different contract address and network, so any resulting type errors need to be fixed before the type check passes.</em></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-3-push-to-github">Step 3: Push to GitHub<a class="hash-link" aria-label="Direct link to Step 3: Push to GitHub" title="Direct link to Step 3: Push to GitHub" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-3-push-to-github">​</a></h3>
<p>Create a public repo and push:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">gh repo create wsteth-monad-indexer-demo --public</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">git init &amp;&amp; git add . &amp;&amp; git commit -m "init"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">git push -u origin main</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If the push fails because your GitHub token lacks permission to push workflow files (like <code>.github/workflows/test.yaml</code>), refresh auth with workflow scope:
<code>gh auth refresh -s workflow</code></p>
<p>Envio Cloud deploys from the <code>envio</code> branch by default, so create and push it:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">git checkout -b envio &amp;&amp; git push -u origin envio</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-4-connect-the-envio-github-bot">Step 4: Connect the Envio GitHub Bot<a class="hash-link" aria-label="Direct link to Step 4: Connect the Envio GitHub Bot" title="Direct link to Step 4: Connect the Envio GitHub Bot" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-4-connect-the-envio-github-bot">​</a></h3>
<p>The Envio GitHub App must have access to the repo before deployments will trigger. If the repo is not already linked, visit:</p>
<p><a href="https://github.com/apps/envio-deployments/installations/select_target" target="_blank" rel="noopener noreferrer">https://github.com/apps/envio-deployments/installations/select_target</a></p>
<p>Then grant the bot access to the <code>wsteth-monad-indexer-demo</code> repository.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-5-deploy">Step 5: Deploy<a class="hash-link" aria-label="Direct link to Step 5: Deploy" title="Direct link to Step 5: Deploy" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-5-deploy">​</a></h3>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud login</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud indexer add</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --name wsteth-monad-indexer-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --repo wsteth-monad-indexer-demo</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --description "wstETH ERC20 indexer on Monad"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --branch envio</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --skip-repo-check</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  --yes</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="step-6-verify">Step 6: Verify<a class="hash-link" aria-label="Direct link to Step 6: Verify" title="Direct link to Step 6: Verify" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#step-6-verify">​</a></h3>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud indexer get wsteth-monad-indexer-demo {org}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio-cloud deployment status wsteth-monad-indexer-demo &lt;commit-hash&gt; {org}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Once synced, the indexer is viewable in the browser at <code>https://envio.dev/app/{org}/{indexer-name}/{commit-hash}.</code></p>
<p>Check the live deployment from this demo here:
<a href="https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35" target="_blank" rel="noopener noreferrer">https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35</a></p>
<p><strong>400,000 events indexed. ~20 seconds</strong></p>
<img src="https://docs.envio.dev/blog-assets/agentic-blockchain-indexing-1.png" alt="Cover Image Agentic Blockchain Indexing" width="100%">
<p>See the full walkthrough on <a href="https://www.loom.com/share/09cdac43b18f4143ad78b18c8c8a492b" target="_blank" rel="noopener noreferrer">Loom</a>, covering the complete agent driven workflow from scaffold to deployment.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-this-matters-for-agentic-development">Why this matters for agentic development<a class="hash-link" aria-label="Direct link to Why this matters for agentic development" title="Direct link to Why this matters for agentic development" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#why-this-matters-for-agentic-development">​</a></h2>
<p>The blockchain data layer has historically been one of the friction points in agentic workflows. Spinning up an indexer meant reading docs, manually editing configs, managing infrastructure, and waiting for sync.</p>
<p>HyperIndex and the <code>envio-cloud</code> CLI change that equation. Every step in the workflow above is scriptable, CLI-driven, and designed to be executed by an agent without human intervention. The JSON output flag (<code>-o json</code>) makes it straightforward to pipe deployment status into downstream logic. The GitHub-native deployment flow means agents that can commit code can deploy indexers.</p>
<p>This is what it looks like in practice for HyperIndex to be the default indexing framework for agentic development.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started">Getting started<a class="hash-link" aria-label="Direct link to Getting started" title="Direct link to Getting started" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#getting-started">​</a></h2>
<p>Install the Envio Cloud CLI:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">npm install -g envio-cloud</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Scaffold your first indexer:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init template -t erc20 -l typescript -d ./my-indexer</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Whether you're building on Monad, Ethereum, or any other EVM compatible network, Envio enables agent driven indexing from first prompt to live deployment. The GitHub-native deployment flow means agents that can commit code can deploy indexers in minutes.</p>
<p>Be sure to check out our <a href="https://docs.envio.dev/blog/envio-docs-mcp-server" target="_blank" rel="noopener noreferrer">Envio Docs MCP Server</a> for AI-assisted indexer development.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently Asked Questions<a class="hash-link" aria-label="Direct link to Frequently Asked Questions" title="Direct link to Frequently Asked Questions" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-agentic-blockchain-indexing">What is agentic blockchain indexing?<a class="hash-link" aria-label="Direct link to What is agentic blockchain indexing?" title="Direct link to What is agentic blockchain indexing?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#what-is-agentic-blockchain-indexing">​</a></h3>
<p>Agentic blockchain indexing is the process of using an AI agent to scaffold, configure, and deploy a blockchain indexer without manual human intervention. With Envio HyperIndex and the envio-cloud CLI, an agent can go from a single prompt to a live production indexer in minutes.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-envio-cloud-cli">What is the envio-cloud CLI?<a class="hash-link" aria-label="Direct link to What is the envio-cloud CLI?" title="Direct link to What is the envio-cloud CLI?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#what-is-the-envio-cloud-cli">​</a></h3>
<p>The envio-cloud CLI is the command-line interface for Envio Cloud, the managed infrastructure layer that runs HyperIndex indexers in production. It supports login, indexer registration, deployment monitoring, and promotion, all scriptable with JSON output via the <code>-o json</code> flag.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-fast-is-envio-hyperindex-for-historical-sync">How fast is Envio HyperIndex for historical sync?<a class="hash-link" aria-label="Direct link to How fast is Envio HyperIndex for historical sync?" title="Direct link to How fast is Envio HyperIndex for historical sync?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#how-fast-is-envio-hyperindex-for-historical-sync">​</a></h3>
<p>In independent benchmarks run by Sentio, HyperIndex completed the Uniswap V2 Factory sync in 1 minute, 143x faster than The Graph. In the agentic deployment demo, 400,000 wstETH events on Monad Mainnet were indexed in approximately 20 seconds.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="which-chains-does-envio-support-for-agentic-indexing">Which chains does Envio support for agentic indexing?<a class="hash-link" aria-label="Direct link to Which chains does Envio support for agentic indexing?" title="Direct link to Which chains does Envio support for agentic indexing?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#which-chains-does-envio-support-for-agentic-indexing">​</a></h3>
<p>Envio supports any EVM-compatible chain. HyperSync natively covers <!-- -->87+<!-- --> EVM chains for maximum speed, including Ethereum, Base, Arbitrum, Optimism, Polygon, and Monad. Any EVM chain without native HyperSync support can be indexed via standard RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-get-started-with-agentic-indexing-on-envio">How do I get started with agentic indexing on Envio?<a class="hash-link" aria-label="Direct link to How do I get started with agentic indexing on Envio?" title="Direct link to How do I get started with agentic indexing on Envio?" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#how-do-i-get-started-with-agentic-indexing-on-envio">​</a></h3>
<p>Install the Envio Cloud CLI with <code>npm install -g envio-cloud</code>, then scaffold your first indexer with <code>pnpx envio init template -t erc20 -l typescript -d ./my-indexer</code>. Push to GitHub and deploy with the envio-cloud CLI.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="about-envio-cloud">About Envio Cloud<a class="hash-link" aria-label="Direct link to About Envio Cloud" title="Direct link to About Envio Cloud" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#about-envio-cloud">​</a></h2>
<p><a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">Envio Cloud</a> is a managed environment for running HyperIndex indexers in production.</p>
<p>It handles infrastructure, scaling, and monitoring, so indexers can run reliably without managing operational overhead. Multiple plans are available, from free development environments to dedicated production deployments, each with features such as static endpoints, built in alerts, and production ready infrastructure.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/agentic-blockchain-indexing-envio-hyperindex#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data (<a href="https://github.com/enviodev/open-indexer-benchmark" target="_blank" rel="noopener noreferrer">Sentio benchmark, May 2025</a>). If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>ai</category>
        </item>
        <item>
            <title><![CDATA[Best Blockchain Indexers in 2026: Real Benchmark Comparison]]></title>
            <link>https://docs.envio.dev/blog/best-blockchain-indexers-2026</link>
            <guid>https://docs.envio.dev/blog/best-blockchain-indexers-2026</guid>
            <pubDate>Fri, 20 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The most accurate, benchmark-backed comparison of the best blockchain indexers in 2026, including the fastest EVM indexer (Envio HyperIndex) and top alternatives to The Graph. Covers Envio, The Graph, Goldsky, SubQuery, Subsquid, Ormi, and Ponder.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/best-blockchain-indexers.png" alt="Cover Image Best Blockchain Indexers" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Envio HyperIndex is the fastest blockchain indexer in independent benchmarks: 1 minute on the Sentio Uniswap V2 Factory workload (May 2025), 143x faster than The Graph and 15x faster than the nearest competitor.</li>
<li>It is the only indexer in this comparison with true wildcard indexing, multichain from a single indexer, TypeScript handlers, and a proprietary data engine (HyperSync, up to 2000x faster than standard RPC).</li>
<li>If you need non-EVM chains, use SubQuery or Subsquid. If you need access to public subgraphs, use The Graph.</li>
<li>Every claim in this article is sourced. Raw benchmark data is open and reproducible: <a href="https://github.com/enviodev/open-indexer-benchmark" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/open-indexer-benchmark</a></li>
</ul></div></div>
<p>Choosing a blockchain indexer should be straightforward, but most comparisons rely on self-reported metrics or product descriptions rather than independently benchmarked data and publicly verifiable sources.</p>
<p>This article takes a different approach. Every claim is backed by public documentation or third-party benchmarks, with clear notes where only self-reported data exists.</p>
<p>We cover seven blockchain indexers: Envio, <a href="https://thegraph.com/" target="_blank" rel="noopener noreferrer">The Graph</a> (Subgraphs), <a href="https://goldsky.com/" target="_blank" rel="noopener noreferrer">Goldsky</a>, <a href="https://subquery.network/" target="_blank" rel="noopener noreferrer">SubQuery</a>, <a href="https://www.sqd.ai/" target="_blank" rel="noopener noreferrer">Subsquid</a> (SQD), <a href="https://ormilabs.com/" target="_blank" rel="noopener noreferrer">Ormi</a> and <a href="https://ponder.sh/" target="_blank" rel="noopener noreferrer">Ponder</a>.</p>
<p>If you would like to review the raw benchmark data yourself, it is fully open:
<a href="https://github.com/enviodev/open-indexer-benchmark" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/open-indexer-benchmark</a></p>
<p>An open, honest, and objective benchmark for blockchain indexers across EVM, Solana, and more. It compares historical backfill speed, latency, data storage, developer experience, and anything else that matters.</p>
<p>We welcome anyone to contribute, run it, test it, and explore the results. We encourage you to share what you find.</p>
<p>This is a benchmark-backed comparison of custom indexing frameworks, the category of tools developers use to define schemas, write handlers, and expose queryable APIs over onchain data. Custom indexers are distinct from RPC providers like Alchemy, QuickNode, and Infura, which serve raw blockchain data but do not index it. They are also distinct from pre-indexed data APIs like Dune Analytics and Covalent, which expose read-only datasets that cannot be customised. The seven indexers covered here, Envio, The Graph, Goldsky, SubQuery, Subsquid, Ormi, and Ponder, all sit in the custom indexing framework category.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="quick-verdict-which-indexer-is-right-for-you">Quick verdict: which indexer is right for you<a class="hash-link" aria-label="Direct link to Quick verdict: which indexer is right for you" title="Direct link to Quick verdict: which indexer is right for you" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#quick-verdict-which-indexer-is-right-for-you">​</a></h2>
<table><thead><tr><th>Indexer</th><th>Best For</th></tr></thead><tbody><tr><td>Envio</td><td>The fastest independently benchmarked EVM indexer. True wildcard indexing, multichain in a single indexer, TypeScript throughout. Fully managed or self-hosted.</td></tr><tr><td>The Graph</td><td>Ecosystem access, existing public subgraphs, decentralised network</td></tr><tr><td>Goldsky</td><td>Managed subgraphs plus real-time data streaming to your own database</td></tr><tr><td>SubQuery</td><td>Non-EVM chains, broadest network coverage</td></tr><tr><td>Subsquid (SQD)</td><td>Fast historical backfills, non-EVM</td></tr><tr><td>Ormi</td><td>Fully managed, Graph-compatible</td></tr><tr><td>Ponder</td><td>Self-hosted TypeScript stack, full control</td></tr></tbody></table>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-we-evaluated">How we evaluated<a class="hash-link" aria-label="Direct link to How we evaluated" title="Direct link to How we evaluated" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#how-we-evaluated">​</a></h2>
<p>Feature lists rarely tell the full story. We evaluated each indexer on six criteria that matter in production:</p>
<ul>
<li>
<p><strong>Indexing speed</strong>: How fast can it sync historical data and stay at the chain head? We used the open benchmark results from Sentio (April 2025) as our primary reference, cross-checked against each indexer's own documentation.</p>
</li>
<li>
<p><strong>Feature completeness</strong>: Does it support event handlers, block handlers, wildcard indexing, and multichain from a single indexer? These are not nice-to-haves once you are building at scale.</p>
</li>
<li>
<p><strong>Developer experience</strong>: What language do you write handlers in? TypeScript is the standard. AssemblyScript adds friction.</p>
</li>
<li>
<p><strong>Chain support</strong>: EVM-only vs multi-ecosystem matters depending on what you are building.</p>
</li>
<li>
<p><strong>Operational model</strong>: Fully managed vs self-hosted vs decentralised. Each has real trade-offs.</p>
</li>
<li>
<p><strong>AI compatibility</strong>: Does the indexer have first-class support for AI-assisted development workflows? This includes Claude Code markdown, Claude skills, and tooling that integrates naturally into AI-native development environments.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-rankings">The rankings<a class="hash-link" aria-label="Direct link to The rankings" title="Direct link to The rankings" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#the-rankings">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-envio-fastest-evm-indexer-with-one-of-the-most-complete-feature-sets">#1 Envio: Fastest EVM indexer with one of the most complete feature sets<a class="hash-link" aria-label="Direct link to #1 Envio: Fastest EVM indexer with one of the most complete feature sets" title="Direct link to #1 Envio: Fastest EVM indexer with one of the most complete feature sets" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#1-envio-fastest-evm-indexer-with-one-of-the-most-complete-feature-sets">​</a></h3>
<p><strong>Best for:</strong> Teams building on EVM chains who need the fastest possible indexing with minimal infrastructure overhead.</p>
<p>Envio is the only indexer in this list powered by a proprietary high-performance data engine. <a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync</a> delivers up to 2000x faster data access than traditional RPC. Two independent benchmarks run by Sentio confirm this: in the LBTC benchmark (April 2025), HyperIndex completed in 3 minutes versus 3 hours 9 minutes for The Graph. In the Uniswap V2 Factory benchmark (May 2025), HyperIndex completed in 1 minute, 15x faster than the nearest competitor (Subsquid), 143x faster than The Graph, and 158x faster than Ponder.</p>
<p>HyperSync's speed also makes HyperIndex the fastest data source for onchain AI agents, where query latency and data freshness directly impact decision quality.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths">​</a></h4>
<ul>
<li>Powered by HyperSync, up to 2000x faster than RPC</li>
<li>Independently benchmarked as fastest in class: 15x faster than nearest competitor, 158x faster than Ponder, 143x faster than The Graph (Sentio, May 2025, Uniswap V2 Factory benchmark)</li>
<li>Wildcard indexing (only indexer in this list with full support)</li>
<li>Single indexer across multiple chains with unordered multichain mode</li>
<li>Write handlers in TypeScript or ReScript (no AssemblyScript required)</li>
<li>Full block handler support</li>
<li>Fully managed hosted service available, no infrastructure management required</li>
<li>White glove migration support for teams moving from any stack</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats">​</a></h4>
<p>HyperSync native support covers <!-- -->87+<!-- --> EVM chains and Fuel. For chains not supported by HyperSync, indexing falls back to standard RPC speed, which is subject to the RPS limits of the endpoint. If you need non-EVM chains like Polkadot or Cosmos, SubQuery or Subsquid are better options.</p>
<p><strong>Get started:</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-the-graph-best-for-ecosystem-access-and-public-subgraphs">#2 The Graph: Best for ecosystem access and public subgraphs<a class="hash-link" aria-label="Direct link to #2 The Graph: Best for ecosystem access and public subgraphs" title="Direct link to #2 The Graph: Best for ecosystem access and public subgraphs" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#2-the-graph-best-for-ecosystem-access-and-public-subgraphs">​</a></h3>
<p><strong>Best for:</strong> Teams that need access to the existing ecosystem of public subgraphs, or who want a decentralised indexing network.</p>
<p>The Graph pioneered declarative blockchain indexing and remains the most established player in the space. Its decentralised network of indexers and curators provides a layer of resilience that no single managed service can replicate. If you need access to community-maintained subgraphs for major protocols such as Uniswap, Aave, and Compound, The Graph is where those live.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-1">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-1">​</a></h4>
<ul>
<li>Largest ecosystem of existing public subgraphs</li>
<li>Decentralised network (not reliant on a single vendor's uptime)</li>
<li>40+ chains on The Graph Network, 90+ chains total</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-1">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-1">​</a></h4>
<p>Handlers are written in <a href="https://thegraph.com/docs/en/subgraphs/developing/creating/assemblyscript-mappings/" target="_blank" rel="noopener noreferrer">AssemblyScript</a>, a TypeScript subset compiled to WebAssembly. It is stricter than TypeScript and adds a learning curve. Subgraphs are deployed per chain. There is no native single-subgraph multichain indexing. Based on the April 2025 Sentio benchmarks, The Graph was over 63x slower than HyperIndex on the same workload.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-goldsky-best-for-data-streaming-to-your-own-database">#3 Goldsky: Best for data streaming to your own database<a class="hash-link" aria-label="Direct link to #3 Goldsky: Best for data streaming to your own database" title="Direct link to #3 Goldsky: Best for data streaming to your own database" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#3-goldsky-best-for-data-streaming-to-your-own-database">​</a></h3>
<p><strong>Best for:</strong> Teams that want to stream raw blockchain data directly into their own infrastructure alongside managed subgraph hosting.</p>
<p>Goldsky is the most infrastructure-oriented indexer in this list. Its two primary products are Subgraphs (instant GraphQL APIs, fully Graph-compatible, zero maintenance) and Mirror ( streaming of blockchain and some offchain data directly into your own database or data warehouse, no configuration needed). The Mirror product is particularly suited for data-heavy teams who want to own their entire downstream data pipeline.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-2">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-2">​</a></h4>
<ul>
<li>150+ chains supported</li>
<li>Fully managed, no infrastructure to run</li>
<li>Mirror pipelines stream data directly to your own database automatically</li>
<li>Reorg handling is fully automatic for Mirror pipelines (no configuration needed). For Compose pipelines, reorg handling is built-in but requires configuration via a <strong><code>depth</code></strong> setting and a chosen behaviour such as <strong><code>replay</code></strong> or <code>log</code></li>
<li>Graph-compatible subgraphs for instant GraphQL APIs</li>
<li>Compose product for event-triggered onchain and offchain workflows</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-2">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-2">​</a></h4>
<p>Goldsky does not support traditional block handlers in the subgraph sense. Their docs do not cover this as a feature. For block-level data access, Goldsky provides pre-indexed Blocks Subgraphs. Block-triggered processing via Compose requires additional setup. Subgraph handlers are written in AssemblyScript (Graph-compatible), not TypeScript. Wildcard indexing is not documented as a feature.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="4-subquery-best-for-non-evm-chain-coverage">#4 SubQuery: Best for non-EVM chain coverage<a class="hash-link" aria-label="Direct link to #4 SubQuery: Best for non-EVM chain coverage" title="Direct link to #4 SubQuery: Best for non-EVM chain coverage" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#4-subquery-best-for-non-evm-chain-coverage">​</a></h3>
<p><strong>Best for:</strong> Teams building across EVM and non-EVM ecosystems, including Polkadot, Cosmos, Bitcoin, and more.</p>
<p>SubQuery stands out for its chain coverage. With support for <a href="https://subquery.network/networks" target="_blank" rel="noopener noreferrer">300+ chains</a> across EVM and non-EVM ecosystems,it is one of the most chain-inclusive indexers in this list. If your product lives on Polkadot or Cosmos and you also need EVM support, SubQuery is the most natural fit for now.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-3">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-3">​</a></h4>
<ul>
<li>300+ chains, broadest coverage including non-EVM</li>
<li>Single project can index data across multiple chains</li>
<li>TypeScript handlers</li>
<li>Block handlers supported</li>
<li>Decentralised hosted service via SubQuery Network</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-3">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-3">​</a></h4>
<p>Data ingestion runs on standard RPC speed. Block handlers are noted in SubQuery's own documentation to slow indexing as they fire on every block.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="5-subsquid-sqd-best-option-with-fast-historical-backfills">#5 Subsquid (SQD): Best option with fast historical backfills<a class="hash-link" aria-label="Direct link to #5 Subsquid (SQD): Best option with fast historical backfills" title="Direct link to #5 Subsquid (SQD): Best option with fast historical backfills" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#5-subsquid-sqd-best-option-with-fast-historical-backfills">​</a></h3>
<p><strong>Best for:</strong> Teams who want fast historical data access, and non-EVM chain support.</p>
<p>Subsquid's decentralised data lake processes historical blockchain data at tens of thousands of blocks per second. SQD describes this approach as up to 1000x faster than traditional methods like subgraphs, based on their own published benchmarks (<a href="https://blog.sqd.dev/fastest-web3-indexer-explained/" target="_blank" rel="noopener noreferrer">source</a>).</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-4">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-4">​</a></h4>
<ul>
<li>Decentralised data lake, significantly faster than RPC for historical data (SQD’s own claim: up to 1000x faster than traditional methods like subgraphs (<a href="https://blog.sqd.dev/fastest-web3-indexer-explained/" target="_blank" rel="noopener noreferrer">source</a>))</li>
<li>100+ chains including EVM and non-EVM</li>
<li>TypeScript handlers</li>
<li>Block handlers supported</li>
<li>Factory contract wildcard patterns supported</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-4">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-4">​</a></h4>
<p>The wildcard support is scoped to factory contract patterns and is not the same as Envio's fully address-free wildcard indexing. Live chain-head performance is not independently benchmarked against the other indexers in this list.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="6-ormi-0xgraph-best-fully-managed-option-for-graph-compatible-subgraphs">#6 Ormi (0xGraph): Best fully managed option for Graph-compatible subgraphs<a class="hash-link" aria-label="Direct link to #6 Ormi (0xGraph): Best fully managed option for Graph-compatible subgraphs" title="Direct link to #6 Ormi (0xGraph): Best fully managed option for Graph-compatible subgraphs" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#6-ormi-0xgraph-best-fully-managed-option-for-graph-compatible-subgraphs">​</a></h3>
<p><strong>Best for:</strong> Teams already using The Graph's subgraph standard who want a managed, low-latency alternative without rebuilding their indexing logic.</p>
<p>Ormi's main pitch is a managed, high-performance layer on top of the subgraph standard. If you have existing subgraphs and want to migrate to a lower-latency managed service without rewriting your handlers, Ormi is a credible path. They also offer GraphQL, REST, and SQL query interfaces in a single platform, which is a genuine differentiator.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-5">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-5">​</a></h4>
<ul>
<li>Fully managed service</li>
<li>GraphQL, REST, and SQL query interfaces</li>
<li>The Graph subgraph standard compatible</li>
<li>87+<!-- --> EVM chains</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-5">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-5">​</a></h4>
<p>Ormi's performance claims (sub-30ms query latency at 4,000 RPS) are self-reported and have not been independently verified in third-party benchmarks. Handlers are written in AssemblyScript only, with no native TypeScript support. Wildcard indexing is not documented.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="7-ponder-best-for-self-hosted-typescript-stacks">#7 Ponder: Best for self-hosted TypeScript stacks<a class="hash-link" aria-label="Direct link to #7 Ponder: Best for self-hosted TypeScript stacks" title="Direct link to #7 Ponder: Best for self-hosted TypeScript stacks" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#7-ponder-best-for-self-hosted-typescript-stacks">​</a></h3>
<p><strong>Best for:</strong> Teams with strong DevOps capability who want full control over every layer of their indexing infrastructure.</p>
<p>Ponder is a TypeScript-native, self-hosted indexer designed for developers who want maximum flexibility and no managed dependency. It is clean, well-designed, and has a growing community. If you want to own your entire stack and have the engineering capacity to manage it, Ponder is worth evaluating.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="key-strengths-6">Key strengths:<a class="hash-link" aria-label="Direct link to Key strengths:" title="Direct link to Key strengths:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#key-strengths-6">​</a></h4>
<ul>
<li>TypeScript-native throughout</li>
<li>Full control over infrastructure</li>
<li>Block handlers via configurable block intervals</li>
<li>Multichain support</li>
</ul>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="honest-caveats-6">Honest caveats:<a class="hash-link" aria-label="Direct link to Honest caveats:" title="Direct link to Honest caveats:" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#honest-caveats-6">​</a></h4>
<p>There is no official hosted service. You deploy and manage your own infrastructure. Data ingestion relies on standard RPC endpoints. Not suited for teams who want managed reliability out of the box.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="feature-comparison">Feature comparison<a class="hash-link" aria-label="Direct link to Feature comparison" title="Direct link to Feature comparison" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#feature-comparison">​</a></h2>
<div class="scroll-table" tabindex="0" role="region" aria-label="Feature comparison table"><table><thead><tr><th>Feature</th><th>Envio</th><th>The Graph</th><th>Goldsky</th><th>SubQuery</th><th>Subsquid (SQD)</th><th>Ormi</th><th>Ponder</th></tr></thead><tbody><tr><td>Event handlers</td><td>Yes</td><td>Yes</td><td>Yes (subgraphs)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Block handlers</td><td>Yes</td><td>Yes</td><td>No direct support. Pre-indexed Blocks Subgraphs available. Compose task triggers for event processing</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes (intervals)</td></tr><tr><td>Multichain single indexer</td><td>Yes</td><td>No</td><td>No (Mirror can stream multiple chains, but subgraphs are per-chain)</td><td>Yes</td><td>Yes</td><td>No (subgraphs are deployed per chain)</td><td>Yes</td></tr><tr><td>Reorg handling</td><td>Yes (automatic, configurable)</td><td>Yes</td><td>Yes (automatic for Mirror, configurable for Compose)</td><td>Yes</td><td>Yes</td><td>Yes (claimed)</td><td>Yes</td></tr><tr><td>Handler language</td><td>TypeScript, JavaScript, ReScript</td><td>AssemblyScript</td><td>AssemblyScript for subgraphs, TypeScript for Mirror transforms</td><td>TypeScript</td><td>TypeScript</td><td>AssemblyScript</td><td>TypeScript</td></tr><tr><td>GraphQL API</td><td>Yes (auto-generated). SQL access available on dedicated plans.</td><td>Yes (auto-generated)</td><td>Yes (subgraphs)</td><td>Yes</td><td>Yes</td><td>Yes, plus REST and SQL</td><td>Yes</td></tr><tr><td>Hosted service</td><td>Yes</td><td>Yes (decentralised network)</td><td>Yes (fully managed)</td><td>Yes (SubQuery Network)</td><td>Yes (SQD Network)</td><td>Yes (fully managed)</td><td>No</td></tr><tr><td>Wildcard indexing</td><td>Yes</td><td>No</td><td>Not documented</td><td>No</td><td>Factory patterns only</td><td>No</td><td>No</td></tr><tr><td>Supported networks</td><td>87+<!-- --> EVM chains and Fuel via HyperSync, Solana (experimental) and any EVM via RPC</td><td>40+ on network, 90+ total</td><td>150+ chains</td><td>300+ (EVM and non-EVM)</td><td>100+ (EVM and non-EVM)</td><td>70+ EVM</td><td>Any EVM via RPC</td></tr><tr><td>Independently benchmarked speed</td><td>Fastest: 1 min (Sentio Uniswap V2 Factory benchmark, May 2025)</td><td>2h23m (Sentio Uniswap V2 Factory benchmark, May 2025)</td><td>Benchmarked (Goldsky_Subgraph, Sentio benchmarks)</td><td>Benchmarked (single-contract benchmark)</td><td>15 min (Sentio Uniswap V2 Factory benchmark, May 2025)</td><td>Not benchmarked</td><td>2h38m (Sentio Uniswap V2 Factory benchmark, May 2025)</td></tr><tr><td>White glove migration</td><td>Yes</td><td>No</td><td>No</td><td>No</td><td>No</td><td>Partial</td><td>No</td></tr><tr><td>AI-assisted development</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>No</td></tr></tbody></table></div>
<p>Across this comparison, Envio is the only indexer with true wildcard indexing, supports multichain from a single indexer, and is independently benchmarked as fastest in class at 143x faster than The Graph on the Sentio Uniswap V2 Factory workload (May 2025). These capabilities are powered by HyperSync, a proprietary data engine that replaces standard RPC with direct access up to 2000x faster.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-choose-the-right-blockchain-indexer">How to choose the right blockchain indexer<a class="hash-link" aria-label="Direct link to How to choose the right blockchain indexer" title="Direct link to How to choose the right blockchain indexer" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#how-to-choose-the-right-blockchain-indexer">​</a></h2>
<p>The right indexer depends on what you are building, which chains you need, and how much infrastructure you want to manage.</p>
<p><strong>If you need the fastest EVM indexing with the most complete feature set.</strong> Use Envio. It is the only indexer independently benchmarked as fastest in class, powered by HyperSync rather than standard RPC. It also has wildcard indexing, multichain in a single indexer, TypeScript throughout, a fully managed hosted service, and first-class support for AI-assisted development.</p>
<p><strong>If you need non-EVM chains (Polkadot, Cosmos, Bitcoin, etc.).</strong> Use SubQuery (300+ chains) or Subsquid (100+ chains). Both support EVM and non-EVM networks in a single framework.</p>
<p><strong>If you have existing Graph subgraphs and want a managed upgrade.</strong> Migrate to Envio for significantly faster indexing with white glove migration support. Or use Goldsky (150+ chains, Mirror streaming, fully managed) or Ormi (fully managed, GraphQL/REST/SQL) for a near-zero-rewrite migration. Both are Graph-compatible.</p>
<p><strong>If you want to stream raw blockchain data into your own database.</strong> Use Envio HyperSync for custom pipelines, up to 2000x faster than RPC with client libraries for Python, Rust, Node.js, and Go. Or use Goldsky Mirror for automatic streaming to Postgres and other sinks with no code required.</p>
<p><strong>If you need a self-hosted indexer with maximum performance</strong>. Use Envio. It is self-hostable via Docker, powered by HyperSync, and independently benchmarked as the fastest blockchain indexer available. 143x faster than The Graph on the Uniswap V2 Factory benchmark (Sentio, May 2025).</p>
<p><strong>If you need access to the broadest ecosystem of existing community subgraphs.</strong> Use The Graph. Its decentralised network has the largest collection of publicly maintained subgraphs for major protocols.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-honest-bottom-line">The honest bottom line<a class="hash-link" aria-label="Direct link to The honest bottom line" title="Direct link to The honest bottom line" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#the-honest-bottom-line">​</a></h2>
<p>For most teams building on EVM chains, Envio HyperIndex is the strongest choice. It is the only indexer in this list independently benchmarked as fastest in class, the only one with true wildcard indexing, and the only one powered by a purpose-built data engine rather than standard RPC. It supports multichain indexing from a single indexer, offers fully managed hosting or self-hosted via Docker, and has white glove migration support for teams moving from The Graph or any other indexer.</p>
<p>If you are not on EVM chains, SubQuery or Subsquid cover the broadest non-EVM network range. If you need access to existing community subgraphs for major protocols, The Graph remains the largest ecosystem for those. For every other use case, start with Envio.</p>
<p>Get started in under 5 minutes: <strong><code>pnpx envio init</code></strong></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently asked questions<a class="hash-link" aria-label="Direct link to Frequently asked questions" title="Direct link to Frequently asked questions" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-a-blockchain-indexer">What is a blockchain indexer?<a class="hash-link" aria-label="Direct link to What is a blockchain indexer?" title="Direct link to What is a blockchain indexer?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-is-a-blockchain-indexer">​</a></h3>
<p>A blockchain indexer is a system that listens to onchain events (transactions, logs, state changes, blocks) and organises them into a structured, queryable database. Developers use indexers to build fast, reliable backends for dApps, DeFi protocols, NFT platforms, and analytics tools without querying slow RPC endpoints directly.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-fastest-blockchain-indexer-in-2026">What is the fastest blockchain indexer in 2026?<a class="hash-link" aria-label="Direct link to What is the fastest blockchain indexer in 2026?" title="Direct link to What is the fastest blockchain indexer in 2026?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-is-the-fastest-blockchain-indexer-in-2026">​</a></h3>
<p>Based on two independent benchmarks run by Sentio, Envio HyperIndex is the fastest blockchain indexer in independent benchmarks. In the Uniswap V2 Factory benchmark (May 2025), HyperIndex completed in 1 minute, 15x faster than the nearest competitor (Subsquid), 143x faster than The Graph, and 158x faster than Ponder. In a separate LBTC workload (April 2025), HyperIndex completed in 3 minutes versus 3 hours 9 minutes for The Graph. All benchmark data is publicly available. HyperIndex handles both real-time event streaming at chain head and historical backfill in the same indexer, with automatic transition between the two modes.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="which-blockchain-indexer-supports-the-most-chains">Which blockchain indexer supports the most chains?<a class="hash-link" aria-label="Direct link to Which blockchain indexer supports the most chains?" title="Direct link to Which blockchain indexer supports the most chains?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#which-blockchain-indexer-supports-the-most-chains">​</a></h3>
<p>SubQuery supports the most chains at 300+, including both EVM and non-EVM networks such as Polkadot, Cosmos, and Bitcoin. Subsquid supports 100+ chains. Goldsky supports 150+ chains. Envio supports <!-- -->87+<!-- --> EVM chains with native HyperSync support for maximum speed, plus any EVM chain via RPC.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-difference-between-a-blockchain-indexer-and-a-data-api-like-dune-or-covalent">What is the difference between a blockchain indexer and a data API like Dune or Covalent?<a class="hash-link" aria-label="Direct link to What is the difference between a blockchain indexer and a data API like Dune or Covalent?" title="Direct link to What is the difference between a blockchain indexer and a data API like Dune or Covalent?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-is-the-difference-between-a-blockchain-indexer-and-a-data-api-like-dune-or-covalent">​</a></h3>
<p>A custom indexing framework (HyperIndex, The Graph, Ponder, etc.) lets you define exactly what data to track, write handler logic that transforms onchain events into your own schema, and query the results via a generated API. A pre-built data API like Dune Analytics or Covalent exposes pre-indexed, read-only data. You query what they have already indexed, but you cannot define custom indexing logic or schemas. Both are useful, but they solve different problems.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-migrate-from-the-graph-to-envio-hyperindex">How do I migrate from The Graph to Envio HyperIndex?<a class="hash-link" aria-label="Direct link to How do I migrate from The Graph to Envio HyperIndex?" title="Direct link to How do I migrate from The Graph to Envio HyperIndex?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#how-do-i-migrate-from-the-graph-to-envio-hyperindex">​</a></h3>
<p>HyperIndex has a <a href="https://docs.envio.dev/docs/HyperIndex/migration-guide" target="_blank" rel="noopener noreferrer">dedicated migration guide</a> that walks you through it in 3 simple steps. Envio also offers white glove migration support for teams moving from any stack. Reach out to us via <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> for support.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-hypersync">What is HyperSync?<a class="hash-link" aria-label="Direct link to What is HyperSync?" title="Direct link to What is HyperSync?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-is-hypersync">​</a></h3>
<p>HyperSync is Envio's high-performance blockchain data engine that powers HyperIndex. It provides a low-level data access layer that is up to 2000x faster than traditional JSON-RPC endpoints. HyperSync can also be used directly for custom data pipelines in Python, Rust, Node.js, and Go. It supports <!-- -->87+<!-- --> EVM chains and Fuel.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-are-the-best-alternatives-to-the-graph-for-production-dapps">What are the best alternatives to The Graph for production dApps?<a class="hash-link" aria-label="Direct link to What are the best alternatives to The Graph for production dApps?" title="Direct link to What are the best alternatives to The Graph for production dApps?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-are-the-best-alternatives-to-the-graph-for-production-dapps">​</a></h3>
<p>Envio HyperIndex is the fastest alternative, with independent benchmarks showing a 143x speed advantage over The Graph on the Uniswap V2 Factory workload (Sentio, May 2025). Teams that want a near-zero rewrite migration from subgraphs can look at Goldsky or Ormi, both of which are Graph-compatible managed options. Teams that need non-EVM coverage alongside EVM should consider Subsquid or SubQuery, which support Polkadot, Cosmos, Bitcoin, and other non-EVM networks. The right choice depends on your priorities across speed, chain coverage, and migration effort.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-the-best-blockchain-indexer-for-hyperliquid-monad-or-arbitrum-dapps">What is the best blockchain indexer for Hyperliquid, Monad, or Arbitrum dApps?<a class="hash-link" aria-label="Direct link to What is the best blockchain indexer for Hyperliquid, Monad, or Arbitrum dApps?" title="Direct link to What is the best blockchain indexer for Hyperliquid, Monad, or Arbitrum dApps?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#what-is-the-best-blockchain-indexer-for-hyperliquid-monad-or-arbitrum-dapps">​</a></h3>
<p>Envio is the recommended choice for these chains. Hyperliquid (HyperEVM), Monad, and Arbitrum all have native HyperSync coverage, placing them among the <!-- -->87+<!-- --> EVM chains that run at maximum sync speed. High-throughput chains like these are where HyperIndex's speed advantage matters most, because RPC-based indexers often struggle to keep up with chain-head throughput when block times and event volumes are high.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-do-i-reduce-query-latency-for-a-defi-dashboard-reading-onchain-data">How do I reduce query latency for a DeFi dashboard reading onchain data?<a class="hash-link" aria-label="Direct link to How do I reduce query latency for a DeFi dashboard reading onchain data?" title="Direct link to How do I reduce query latency for a DeFi dashboard reading onchain data?" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#how-do-i-reduce-query-latency-for-a-defi-dashboard-reading-onchain-data">​</a></h3>
<p>Indexing speed and query latency are two different problems. Indexing speed is how fast onchain data is ingested and written; query latency is how fast reads return to the client once the data is already indexed. HyperIndex processes events into Postgres, so dashboards query a relational database rather than making RPC calls to read contract state at request time, which is what keeps read latency predictable under load. For production workloads, Envio Cloud offers production and dedicated plans with SLAs sized for high-throughput indexers.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/best-blockchain-indexers-2026#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Envio Developer Update February 2026]]></title>
            <link>https://docs.envio.dev/blog/envio-developer-update-february-2026</link>
            <guid>https://docs.envio.dev/blog/envio-developer-update-february-2026</guid>
            <pubDate>Wed, 25 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio Developer Update February 2026: HyperIndex v3 alpha.13, 3x faster backfills, MegaETH and Sei indexing, new builder series, and Uniswap v4 alert bots.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26.png" alt="Cover Image Envio Developer Update Feb 2026" width="100%">
<p>February brings a couple new HyperIndex V3 alpha release along with expanded network support and feature updates. We shipped HyperIndex v3.0.0 alpha.13 &amp; alpha.14 with 3x faster historical backfills, support for DESC indices, improved RPC source support, experimental WebSocket support, and a breaking configuration change with <code>rpc_config</code> removed in favour of <code>rpc</code>, new getWhere API, removed ordered multichain mode support, big Cursor/Claude update and much more!</p>
<p>We expanded our indexing support to MegaETH mainnet and Sei. This month also includes a new multi-part YouTube series on building with HyperIndex and updates to our Uniswap v4 alert bots. Let’s dive in!</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="new-release-hyperindex-v300---alpha13--alpha14">New release: HyperIndex v3.0.0 - alpha.13 &amp; alpha.14<a class="hash-link" aria-label="Direct link to New release: HyperIndex v3.0.0 - alpha.13 &amp; alpha.14" title="Direct link to New release: HyperIndex v3.0.0 - alpha.13 &amp; alpha.14" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#new-release-hyperindex-v300---alpha13--alpha14">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="alpha14">Alpha.14<a class="hash-link" aria-label="Direct link to Alpha.14" title="Direct link to Alpha.14" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#alpha14">​</a></h3>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-new-getwhere-api">&nbsp;Breaking: New getWhere API<a class="hash-link" aria-label="Direct link to &nbsp;Breaking: New getWhere API" title="Direct link to &nbsp;Breaking: New getWhere API" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#breaking-new-getwhere-api">​</a></h3>
<p>We updated our getWhere API to enable support for multiple filters at a time in future HyperIndex versions. Instead of chaining, it now uses a single function call with filters that match GraphQL style for familiarity.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Old: context.Entity.getWhere.fieldName.eq(value)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">New: context.Entity.getWhere({ fieldName: { _eq: value } })</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-removed-ordered-multichain-mode-support">Breaking: Removed Ordered Multichain Mode Support<a class="hash-link" aria-label="Direct link to Breaking: Removed Ordered Multichain Mode Support" title="Direct link to Breaking: Removed Ordered Multichain Mode Support" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#breaking-removed-ordered-multichain-mode-support">​</a></h3>
<p>Ordered Multichain Mode forced events across all processed chains into global onchain order, causing significant latency and allowing one bad chain to freeze the entire indexing process.</p>
<p>Events are still processed in onchain order per chain.
For cross-chain interactions, create a partial entity on one chain and finalize it when the related event arrives on another chain. This provides lower latency and a more reliable system.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="big-cursorclaude-skills-update">&nbsp;Big Cursor/Claude Skills Update<a class="hash-link" aria-label="Direct link to &nbsp;Big Cursor/Claude Skills Update" title="Direct link to &nbsp;Big Cursor/Claude Skills Update" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#big-cursorclaude-skills-update">​</a></h3>
<p>We updated <code>envio init</code> to create projects with multiple skills to support agentic driven development.</p>
<p>The LLM landscape changes quickly, so we welcome feedback to improve the skills and the development experience with them.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="chain-info-for-test-indexer">&nbsp;Chain Info for Test Indexer<a class="hash-link" aria-label="Direct link to &nbsp;Chain Info for Test Indexer" title="Direct link to &nbsp;Chain Info for Test Indexer" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#chain-info-for-test-indexer">​</a></h3>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">const indexer = createTestIndexer();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chainIds</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].name</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].startBlock</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].endBlock</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].ERC20.abi</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">indexer.chains[1].ERC20.addresses // Useful to test dynamic registrations</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="alpha13">Alpha.13<a class="hash-link" aria-label="Direct link to Alpha.13" title="Direct link to Alpha.13" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#alpha13">​</a></h3>
<p>This alpha release focused on performance improvements, expanded indexing capabilities, and RPC configuration changes as we continue iterating on V3.</p>
<p>Historical backfills are significantly faster, query flexibility has improved with support for descending indices, RPC sources now expose additional receipt level fields, and configuration has been streamlined with the removal of <code>rpc_config</code> in favour of a unified <strong><code>rpc</code></strong> structure.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="3x-historical-backfill-performance">3x Historical Backfill Performance<a class="hash-link" aria-label="Direct link to 3x Historical Backfill Performance" title="Direct link to 3x Historical Backfill Performance" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#3x-historical-backfill-performance">​</a></h3>
<p>We introduced chunking logic to request events across multiple ranges at once, fixed overfetching for contracts with much later <code>start_block</code> values, and sped up dynamic contract registration.</p>
<p>If data fetching was your bottleneck, this release helps.</p>
<p><strong><span style="text-decoration:underline">25k events per second is now standard</span></strong></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="support-for-desc-indices">Support for DESC Indices<a class="hash-link" aria-label="Direct link to Support for DESC Indices" title="Direct link to Support for DESC Indices" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#support-for-desc-indices">​</a></h3>
<p>You can now define indices with descending order to improve query performance:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">type PoolDayData</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  @index(fields: ["poolId", ["date", "DESC"]]) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  id: ID!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  poolId: String!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  date: Timestamp!</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="improved-rpc-source-support">Improved RPC Source Support<a class="hash-link" aria-label="Direct link to Improved RPC Source Support" title="Direct link to Improved RPC Source Support" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#improved-rpc-source-support">​</a></h3>
<p>Added support for receipt-only fields:</p>
<p>• <strong><code>gasUsed</code></strong></p>
<p>• <strong><code>cumulativeGasUsed</code></strong></p>
<p>• <strong><code>effectiveGasPrice</code></strong></p>
<p>When one of these fields is added in <code>field_selection</code>, HyperIndex will automatically perform an additional <code>eth_getTransactionReceipt</code> request.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="websocket-support-for-rpc-experimental">WebSocket Support for RPC (Experimental)<a class="hash-link" aria-label="Direct link to WebSocket Support for RPC (Experimental)" title="Direct link to WebSocket Support for RPC (Experimental)" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#websocket-support-for-rpc-experimental">​</a></h3>
<p>Experimental WebSocket support for RPC sources to improve head latency.</p>
<p>If you run into issues, please open a GitHub issue.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">chains:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - id: 1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    rpc:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      url: ${ENVIO_RPC_ENDPOINT}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      ws: ${ENVIO_WS_ENDPOINT}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      for: live</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-rpc_config-removed">Breaking: rpc_config Removed<a class="hash-link" aria-label="Direct link to Breaking: rpc_config Removed" title="Direct link to Breaking: rpc_config Removed" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#breaking-rpc_config-removed">​</a></h3>
<p><code>rpc_config</code> has been removed in favour of <strong><code>rpc</code></strong>.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">- rpc_config</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+ rpc:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      url: ${ENVIO_RPC_ENDPOINT}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+     for: sync # Add to force RPC usage instead of HyperSync</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Additionally, you can specify multiple rpcs by providing a list:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">rpc:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - url: ${ENVIO_RPC_ENDPOINT}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    for: sync</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  - url: ${ENVIO_RPC_FALLBACK_ENDPOINT}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    for: fallback</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If <strong><code>for</code></strong> is not provided, the RPC URL is used as a fallback for HyperSync or as the main source when HyperSync is not supported.</p>
<p>We recommend migrating to v3.0.0 alpha. 13 to take advantage of the performance improvements and configuration updates. Give it a test and let us know how it goes. We welcome any feedback as we continue refining V3.</p>
<p>For information, be sure to check out the full release notes. More updates coming soon.</p>
<p>See full <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">release notes</a></p>
<p>Star us on <a href="https://github.com/enviodev/hyperindex" target="_blank" rel="noopener noreferrer">GitHub</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="indexing-data-on-megaeth-mainnet">Indexing Data on MegaEth Mainnet<a class="hash-link" aria-label="Direct link to Indexing Data on MegaEth Mainnet" title="Direct link to Indexing Data on MegaEth Mainnet" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#indexing-data-on-megaeth-mainnet">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-1.gif" alt="MegaEth Mainnet" width="100%">
<p><a href="https://rabbithole.megaeth.com/" target="_blank" rel="noopener noreferrer">MegaETH</a> launched its public Mainnet on February 9, 2026, marking the transition from testnet experimentation to a live production network. As a performance focused Ethereum Layer 2, MegaETH is built to support high throughput and low latency execution for onchain applications.</p>
<p>With mainnet now live, developers can deploy and operate applications directly on the network.</p>
<p>Envio proudly supports developers building on MegaETH Mainnet, providing efficient access to real-time and historical data for teams building in the ecosystem.</p>
<p>For more information, see the original <a href="https://x.com/envio_indexer/status/2020882703583727665?s=20" target="_blank" rel="noopener noreferrer">post</a> on X.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="building-indexers-with-hyperindex">Building Indexers with HyperIndex<a class="hash-link" aria-label="Direct link to Building Indexers with HyperIndex" title="Direct link to Building Indexers with HyperIndex" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#building-indexers-with-hyperindex">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-2.png" alt="Building Indexers with HyperIndex" width="100%">
<p>Check out Decrypted Bytes’ new multi-part YouTube series that walks through how to build with HyperIndex. The series covers building an indexer using HyperIndex from scratch. It follows the full process in a live coding format, showing how to set up, iterate, and expand an indexer step by step.</p>
<p>If you want to learn how to build with HyperIndex in practice, this series is a great place to start.</p>
<p>Be sure to check out the series on <a href="https://www.youtube.com/@decryptedbytes/streams" target="_blank" rel="noopener noreferrer">YouTube</a> and subscribe to follow along as more parts are released.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="tyde-terminal-tide-visualiser">Tyde Terminal Tide Visualiser<a class="hash-link" aria-label="Direct link to Tyde Terminal Tide Visualiser" title="Direct link to Tyde Terminal Tide Visualiser" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#tyde-terminal-tide-visualiser">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-3.gif" alt="Tyde" width="100%">
<p>Tyde is an open source terminal based tool that visualises real world tide levels directly in the command line. It renders an animated tide scene with waves, sand, and foam, alongside a 24-hour tide chart showing the current position in the cycle. Sunrise and sunset times are also displayed, with support for a day and night cycle.</p>
<p>Tide predictions are computed locally using harmonic analysis across more than 50 global stations, with no external APIs required.</p>
<p>You can run Tyde directly in your terminal on macOS or Linux, or build it from source.</p>
<p>For more information, see the <a href="https://github.com/moose-code/tyde" target="_blank" rel="noopener noreferrer">GitHub repo</a> or the original <a href="https://x.com/jonjonclark/status/2022313741593858297?s=20" target="_blank" rel="noopener noreferrer">post</a> on X.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="index-data-on-sei">Index Data on Sei<a class="hash-link" aria-label="Direct link to Index Data on Sei" title="Direct link to Index Data on Sei" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#index-data-on-sei">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-4.png" alt="Index data on Sei" width="100%">
<p>Just Sei it.</p>
<p>Build, index &amp; scale high performance apps on <a href="https://www.sei.io/" target="_blank" rel="noopener noreferrer">Sei</a> using Envio.</p>
<p>Instantly access real-time &amp; historical data on one of the fastest L1 EVMs. Sync millions of events in minutes, 2000× faster than RPC.</p>
<p>Easy. Fast. Fully customizable.</p>
<p>For more information, see the original <a href="https://x.com/envio_indexer/status/2021981848557986255?s=20" target="_blank" rel="noopener noreferrer">post</a> on X.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-alerts-uniswap-v4-alert-bots">Envio Alerts: Uniswap v4 Alert Bots<a class="hash-link" aria-label="Direct link to Envio Alerts: Uniswap v4 Alert Bots" title="Direct link to Envio Alerts: Uniswap v4 Alert Bots" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#envio-alerts-uniswap-v4-alert-bots">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-5.png" alt="Envio alert bots" width="100%">
<p>Get automated alerts when a Uniswap v4 pool crosses 1m in TVL, including when an MEV bot trade causes the threshold to be hit.</p>
<p>Each alert includes:</p>
<ul>
<li>Token pair</li>
<li>TVL threshold hit</li>
<li>Chain</li>
</ul>
<p>The <a href="https://t.me/+5uldwTve8ns3MDFk" target="_blank" rel="noopener noreferrer">MEV Alerts bot</a> highlights MEV driven TVL events, while the <a href="https://t.me/+0eUs4YO6HMJlNzBk" target="_blank" rel="noopener noreferrer">Liquid Token Alerts bot</a> tracks pools crossing the 1m TVL mark.</p>
<p>Be sure to join the bot groups on Telegram to receive alerts in real-time and stay up to date on Uniswap v4 pool activity.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="current--upcoming-events--hackathons">Current &amp; Upcoming Events &amp; Hackathons<a class="hash-link" aria-label="Direct link to Current &amp; Upcoming Events &amp; Hackathons" title="Direct link to Current &amp; Upcoming Events &amp; Hackathons" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#current--upcoming-events--hackathons">​</a></h2>
<ul>
<li><a href="https://ethdenver.com/" target="_blank" rel="noopener noreferrer">EthDenver - Denver</a>: Feb 17th → 21st</li>
<li><a href="https://ethcc.io/" target="_blank" rel="noopener noreferrer">EthCC - Cannes</a>: March 30th → April 2nd</li>
<li><a href="https://ethconf.com/" target="_blank" rel="noopener noreferrer">EthConf - New York</a>: June 8th → 10th</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="playlist-of-the-month">Playlist of the Month<a class="hash-link" aria-label="Direct link to Playlist of the Month" title="Direct link to Playlist of the Month" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#playlist-of-the-month">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-feb-26-7.png" alt="PLOTM Feb 2026" width="100%">
<p>▶ <a href="https://open.spotify.com/playlist/0CNf2YeAWBGUii76h6xilv?si=575e6a3e76c844b5" target="_blank" rel="noopener noreferrer">Open Spotify</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-developer-update-february-2026#build-with-envio">​</a></h2>
<p>Envio is a multichain EVM blockchain indexer for querying real-time and historical data. If you’re working on a Web3 project and want a smoother development process, Envio’s got your back(end). Check out our docs, join the community, and let’s talk about your data needs.</p>
<p>Stay tuned for more monthly updates by subscribing to our newsletter, following us on X, or hopping into our Discord for more up-to-date information.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>product-updates</category>
        </item>
        <item>
            <title><![CDATA[Blockchain Indexer For Application Backends]]></title>
            <link>https://docs.envio.dev/blog/blockchain-indexer-application-backends</link>
            <guid>https://docs.envio.dev/blog/blockchain-indexer-application-backends</guid>
            <pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How blockchain indexers are used in practice to build reliable application backends and how Envio fits into that workflow.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/blockchain-indexer-backends.png" alt="Blockchain Indexer For Application Backends" width="100%">
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TL;DR</div><div class="admonitionContent_BuS1"><ul>
<li>Blockchain indexers sit between the chain and your application backend, transforming raw events into structured, queryable data your app can depend on.</li>
<li>Without an indexer, backends must reconstruct state from history, handle reorgs, and translate raw logs. This complexity compounds as projects scale.</li>
<li>Envio handles this with a single <code>config.yaml</code>, TypeScript event handlers, HyperSync for fast historical sync, and a hosted GraphQL API that works across multiple chains.</li>
</ul></div></div>
<p>A blockchain indexer is rarely the end product. For most teams, it is a core part of the backend that sits between the blockchain and their application.</p>
<p>This post covers how developers actually use a blockchain indexer in practice, the problems it solves at the backend layer, and how Envio fits into that workflow.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-a-blockchain-indexer">What is a blockchain indexer<a class="hash-link" aria-label="Direct link to What is a blockchain indexer" title="Direct link to What is a blockchain indexer" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#what-is-a-blockchain-indexer">​</a></h2>
<p>A blockchain indexer is a specialised tool that ingests raw blockchain data and transforms it into structured data that application backends can query efficiently.</p>
<p>Rather than querying blocks, transactions, or logs directly through RPC on every request, developers define how blockchain events should be processed and stored. The indexer applies this logic consistently as new data is produced and as historical data is processed.</p>
<p>The result is a reliable, queryable data layer built from onchain activity.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-blockchain-indexers-work">How blockchain indexers work<a class="hash-link" aria-label="Direct link to How blockchain indexers work" title="Direct link to How blockchain indexers work" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#how-blockchain-indexers-work">​</a></h2>
<p>In practice, a blockchain indexer follows a simple model:</p>
<ul>
<li>Read blockchain data: blocks, transactions, and event logs</li>
<li>Apply developer-defined logic to the data</li>
<li>Store the results as structured entities</li>
</ul>
<p>This logic is deterministic and repeatable. Given the same inputs, the indexer produces the same outputs, which makes indexed data predictable and safe to depend on in application backends.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-backend-problem-blockchain-apps-run-into">The backend problem blockchain apps run into<a class="hash-link" aria-label="Direct link to The backend problem blockchain apps run into" title="Direct link to The backend problem blockchain apps run into" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#the-backend-problem-blockchain-apps-run-into">​</a></h2>
<p>Application backends need structured state. Blockchains expose raw data. When applications rely directly on RPC endpoints, backend logic quickly becomes responsible for:</p>
<ul>
<li>Reconstructing state from historical events</li>
<li>Tracking contract changes over time</li>
<li>Handling retries, partial failures, and reorgs</li>
<li>Translating low-level logs into usable application data</li>
</ul>
<p>As a project scales, this logic becomes difficult to manage and expensive to maintain. Blockchain indexers absorb this complexity by transforming onchain events into structured, queryable data that backends can depend on.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="what-role-a-blockchain-indexer-plays">What role a blockchain indexer plays<a class="hash-link" aria-label="Direct link to What role a blockchain indexer plays" title="Direct link to What role a blockchain indexer plays" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#what-role-a-blockchain-indexer-plays">​</a></h2>
<p>Rather than serving as an analytics layer, a blockchain indexer functions as backend infrastructure. It continuously processes blockchain data and maintains an up-to-date representation of application state that backends can query directly.</p>
<p>In practice, this means:</p>
<ul>
<li>Indexing contract events once instead of repeatedly</li>
<li>Converting raw logs into structured entities</li>
<li>Persisting derived state that applications can rely on</li>
<li>Keeping blockchain-specific logic out of application code</li>
</ul>
<p>This separation makes backends simpler, more predictable, and easier to scale.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="where-the-indexed-data-gets-used">Where the indexed data gets used<a class="hash-link" aria-label="Direct link to Where the indexed data gets used" title="Direct link to Where the indexed data gets used" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#where-the-indexed-data-gets-used">​</a></h2>
<p>Once data is indexed, application backends can:</p>
<ul>
<li>Serve APIs backed by indexed blockchain state</li>
<li>Power user interfaces with pre-processed data</li>
<li>Track contract state without rescanning history</li>
<li>Build features that depend on event-driven updates</li>
</ul>
<p>Because the indexing logic is deterministic and versioned, teams can evolve their schema and handlers without rewriting application logic.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="when-a-blockchain-indexer-becomes-necessary">When a blockchain indexer becomes necessary<a class="hash-link" aria-label="Direct link to When a blockchain indexer becomes necessary" title="Direct link to When a blockchain indexer becomes necessary" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#when-a-blockchain-indexer-becomes-necessary">​</a></h2>
<p>Most teams reach for a blockchain indexer when:</p>
<ul>
<li>Application logic depends on more than the latest block</li>
<li>The application needs access to real-time and historical onchain data</li>
<li>Data needs to be queried frequently or predictably</li>
<li>The application spans multiple networks and needs a unified data layer</li>
<li>Backend reliability becomes a priority</li>
</ul>
<p>At that point, indexing once and querying structured data becomes the simplest approach.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="building-a-blockchain-indexer-with-envio">Building a blockchain indexer with Envio<a class="hash-link" aria-label="Direct link to Building a blockchain indexer with Envio" title="Direct link to Building a blockchain indexer with Envio" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#building-a-blockchain-indexer-with-envio">​</a></h2>
<p>Envio is designed around a developer-first indexing workflow. Developers define the contracts and events relevant to their application, write deterministic event handlers that map blockchain data into entities, and run the indexer locally to develop and validate logic. The same indexing code runs in hosted environments without changes.</p>
<p>Other indexers like The Graph require separate subgraph deployments per chain and charge query fees through a decentralized network. With Envio, all chains are configured in a single <code>config.yaml</code> and exposed through one GraphQL endpoint, with no per-chain deployment overhead.</p>
<p>As projects scale, Envio provides capabilities that support more advanced indexing and production requirements:</p>
<ul>
<li><strong>TypeScript-first:</strong> Write event handling logic in JavaScript or TypeScript.</li>
<li><strong><a href="https://docs.envio.dev/docs/HyperSync/overview" target="_blank" rel="noopener noreferrer">HyperSync</a>:</strong> A high-performance data retrieval layer that delivers up to 2000x faster historical sync than standard RPC. HyperSync is used automatically for all supported networks.</li>
<li><strong>No-code quickstart:</strong> Autogenerate a complete indexer project from a single contract address or ABI using <code>pnpx envio init</code>. Deploy within minutes.</li>
<li><strong>Multichain indexing:</strong> Aggregate data across multiple networks into a single database. Query everything through a unified GraphQL API.</li>
<li><strong>Onchain and offchain data:</strong> Combine indexed onchain events with offchain sources such as NFT metadata, token prices from aggregators, or current chain state via RPC.</li>
<li><strong>Factory contract support:</strong> Automatically register and process events from child contracts created by a factory or dynamic contract.</li>
<li><strong><a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" target="_blank" rel="noopener noreferrer">Hosted service</a>:</strong> A managed hosting platform for building, hosting, and querying Envio indexers, with 99.99% uptime SLA and GitHub-based auto-deploy.</li>
</ul>
<p>The result is a backend data layer that remains consistent and reliable across development and production.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started">Getting started<a class="hash-link" aria-label="Direct link to Getting started" title="Direct link to Getting started" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#getting-started">​</a></h2>
<p>Envio is designed to start small and scale as requirements grow:</p>
<ul>
<li>Index single or multiple contracts</li>
<li>Map a small set of events into entities</li>
<li>Run the indexer locally during development with <code>pnpm dev</code></li>
<li>Expand the schema and handlers as application requirements grow</li>
</ul>
<p>For many applications, a blockchain indexer becomes a core part of the backend. Envio supports this workflow from early development through production using the same indexing code across environments.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="frequently-asked-questions">Frequently asked questions<a class="hash-link" aria-label="Direct link to Frequently asked questions" title="Direct link to Frequently asked questions" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#frequently-asked-questions">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-does-a-blockchain-indexer-do-in-an-application-backend">What does a blockchain indexer do in an application backend?<a class="hash-link" aria-label="Direct link to What does a blockchain indexer do in an application backend?" title="Direct link to What does a blockchain indexer do in an application backend?" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#what-does-a-blockchain-indexer-do-in-an-application-backend">​</a></h3>
<p>A blockchain indexer reads raw onchain events, applies developer-defined logic, and stores the results as structured entities in a database. Application backends query this database directly instead of hitting RPC endpoints on every request.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="when-should-i-use-a-blockchain-indexer-instead-of-direct-rpc-calls">When should I use a blockchain indexer instead of direct RPC calls?<a class="hash-link" aria-label="Direct link to When should I use a blockchain indexer instead of direct RPC calls?" title="Direct link to When should I use a blockchain indexer instead of direct RPC calls?" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#when-should-i-use-a-blockchain-indexer-instead-of-direct-rpc-calls">​</a></h3>
<p>When your application needs historical data, depends on multiple events across contracts or chains, or needs to serve data at scale. Direct RPC calls force the backend to reconstruct state on every query and cannot efficiently handle historical lookups or cross-chain aggregation.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="how-does-envio-differ-from-the-graph-for-backend-indexing">How does Envio differ from The Graph for backend indexing?<a class="hash-link" aria-label="Direct link to How does Envio differ from The Graph for backend indexing?" title="Direct link to How does Envio differ from The Graph for backend indexing?" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#how-does-envio-differ-from-the-graph-for-backend-indexing">​</a></h3>
<p>The Graph requires a separate subgraph per chain and charges query fees through a decentralized network. Envio uses a single <code>config.yaml</code> for all chains, a single GraphQL endpoint, and TypeScript handlers with no per-query fees. HyperSync also makes historical sync orders of magnitude faster than The Graph's RPC-based approach.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="does-envio-support-multichain-backends">Does Envio support multichain backends?<a class="hash-link" aria-label="Direct link to Does Envio support multichain backends?" title="Direct link to Does Envio support multichain backends?" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#does-envio-support-multichain-backends">​</a></h3>
<p>Yes. All networks are defined in one <code>config.yaml</code>. Envio processes events from each chain in parallel and writes them to a shared database. Your GraphQL API reflects the combined state of all configured chains through a single endpoint.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-run-envio-locally-during-development">Can I run Envio locally during development?<a class="hash-link" aria-label="Direct link to Can I run Envio locally during development?" title="Direct link to Can I run Envio locally during development?" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#can-i-run-envio-locally-during-development">​</a></h3>
<p>Yes. Running <code>pnpm dev</code> spins up the full stack locally using Docker, including the database and GraphQL API. The same handler logic runs locally and in production without modification.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/blockchain-indexer-application-backends#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Envio Developer Update January 2026]]></title>
            <link>https://docs.envio.dev/blog/envio-developer-update-january-2026</link>
            <guid>https://docs.envio.dev/blog/envio-developer-update-january-2026</guid>
            <pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Envio Developer Update January 2026: HyperIndex V3 alpha with a new testing framework, Vitest support, init improvements, and ecosystem updates.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26.png" alt="Cover Image Envio Developer Update Jan 2026" width="100%">
<p>Over the past month, we’ve continued making steady progress on HyperIndex V3, with a strong focus on improving how developers build, test, and operate indexers day to day.</p>
<p>This update covers the latest V3 alpha features including a new testing framework, Vitest adoption, improvements to envio init, configuration and state access updates, and several quality of life enhancements across the CLI and TUI. We’re also sharing recent ecosystem updates, production migration examples, and highlights from teams building with Envio.</p>
<p>As always, these changes are incremental building blocks toward a more reliable and flexible indexing workflow, from local development through to production.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hyperindex-v3-alpha-exciting-feature-updates">HyperIndex V3 (alpha): Exciting Feature Updates<a class="hash-link" aria-label="Direct link to HyperIndex V3 (alpha): Exciting Feature Updates" title="Direct link to HyperIndex V3 (alpha): Exciting Feature Updates" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#hyperindex-v3-alpha-exciting-feature-updates">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="big-feature-alert-new-testing-framework-experimental">BIG feature alert: New Testing Framework (experimental)<a class="hash-link" aria-label="Direct link to BIG feature alert: New Testing Framework (experimental)" title="Direct link to BIG feature alert: New Testing Framework (experimental)" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#big-feature-alert-new-testing-framework-experimental">​</a></h3>
<p>V3 supports testing handler logic using real blockchain data, programmatic debugging, &amp; testing block handlers together with event handlers.</p>
<p>The framework also enables LLM workflows using a TDD approach, supports snapshotting indexer behaviour, &amp; runs multiple tests in parallel using isolated worker threads.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">import { describe, it, expect } from "vitest"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import { createTestIndexer } from "generated"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">describe("Indexer Testing", () =&gt; {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  it("Should create accounts from ERC20 Transfer events", async () =&gt; {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    const indexer = createTestIndexer();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    expect(</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      await indexer.process({</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        chains: {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          1: {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            startBlock: 10_861_674,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            endBlock: 10_861_674,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      }),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      "Should find the first mint at block 10_861_674"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    ).toMatchInlineSnapshot(`</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        "changes": [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            "Account": {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              "sets": [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  "balance": -1000000000000000000000000000n,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  "id": "0x0000000000000000000000000000000000000000",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  "balance": 1000000000000000000000000000n,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                  "id": "0x41653c7d61609d856f29355e404f310ec4142cfb",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">              ],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            "block": 10861674,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            "blockHash": "0x32e4dd857b5b7e756551a00271e44b61dbda0a91db951cf79a3e58adb28f5c09",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            "chainId": 1,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">            "eventsProcessed": 1,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">          },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        ],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    `);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}   </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="vitest---recommended-testing-framework">Vitest - Recommended Testing Framework<a class="hash-link" aria-label="Direct link to Vitest - Recommended Testing Framework" title="Direct link to Vitest - Recommended Testing Framework" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#vitest---recommended-testing-framework">​</a></h3>
<p>V3 recommends Vitest as the testing framework for indexer projects.</p>
<p>It replaces <strong><code>mocha</code></strong>, <strong><code>chai</code></strong>, and <strong><code>tsx</code></strong> with a single package that works out of the box, and supports features like snapshot testing.</p>
<p>All envio init templates have been updated to use Vitest, with tests living directly in src and support for handler specific test files.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">"scripts": {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "mocha": "tsc --noEmit &amp;&amp; NODE_OPTIONS='--no-warnings --import tsx' mocha --exit test/**/*.ts",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "test": "pnpm mocha",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+ "test": "vitest run"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">},</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">"devDependencies": {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "@types/chai": "^4.3.11",    </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "@types/mocha": "10.0.6",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "chai": "4.3.10",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "tsx": "4.21.0",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">- "mocha": "10.2.0"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+ "vitest": "4.0.16"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="envio-init-improvements">Envio Init Improvements<a class="hash-link" aria-label="Direct link to Envio Init Improvements" title="Direct link to Envio Init Improvements" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#envio-init-improvements">​</a></h3>
<p>V3 improves the <strong><code>envio init</code></strong> flow to make project setup quicker and smoother.</p>
<p>The ERC20 template has been updated to be multichain and includes the new testing framework as a reference. New projects can also initialize git automatically.</p>
<p>The improved init flow can include additional setup options from upcoming releases, such as configured GitHub CI and an <a href="http://agents.md/" target="_blank" rel="noopener noreferrer">AGENTS.md</a> file to support LLM-based development.</p>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-1.png" alt="Envio init improvements" width="100%">
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="expose-indexer-config--state">Expose Indexer Config &amp; State<a class="hash-link" aria-label="Direct link to Expose Indexer Config &amp; State" title="Direct link to Expose Indexer Config &amp; State" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#expose-indexer-config--state">​</a></h3>
<p>V3 introduces the indexer value as a replacement for <strong><code>getGeneratedByChainId</code></strong>.</p>
<p>It provides typed chains and contract data from config, along with current indexing state such as <strong><code>isLive</code></strong> and <strong><code>addresses</code></strong>.</p>
<p>New official types are also introduced:</p>
<p><strong><code>Indexer</code></strong>, <strong><code>EvmChainId</code></strong>, <strong><code>FuelChainId</code></strong>, <strong><code>SvmChainId</code></strong>.</p>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-2.png" alt="Expose Indexer Config &amp; State" width="100%">
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="automatic-contract-configuration">Automatic Contract Configuration<a class="hash-link" aria-label="Direct link to Automatic Contract Configuration" title="Direct link to Automatic Contract Configuration" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#automatic-contract-configuration">​</a></h3>
<p>V3 automatically configures all globally defined contracts.</p>
<p>Globally defined contracts are handled automatically, even when they aren’t linked to a specific chain or address.</p>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-3.png" alt="Automatic Contract Configuration" width="100%">
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="conditional-event-handlers">Conditional Event Handlers<a class="hash-link" aria-label="Direct link to Conditional Event Handlers" title="Direct link to Conditional Event Handlers" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#conditional-event-handlers">​</a></h3>
<p>V3 allows event handlers to be enabled or disabled conditionally.</p>
<p>You can now return a boolean value from the eventFilters function to control whether a handler runs.</p>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-4.png" alt="Conditional Event Handlers" width="100%">
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="tui-love">TUI Love<a class="hash-link" aria-label="Direct link to TUI Love" title="Direct link to TUI Love" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#tui-love">​</a></h3>
<p>V3 brings updates to the TUI, making it even more beautiful &amp; compact.</p>
<p>It uses fewer resources, shares a link to the Hasura playground, and adjusts dynamically to the terminal width.</p>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-5.png" alt="TUI" width="100%">
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="envio-api-token-required">Envio API Token Required<a class="hash-link" aria-label="Direct link to Envio API Token Required" title="Direct link to Envio API Token Required" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#envio-api-token-required">​</a></h3>
<p>For indexers using HyperSync as a data source, setting an <code>ENVI0_API_TOKEN</code> is now required.</p>
<p>You can learn more about API tokens or create one for free at:</p>
<p><a href="https://envio.dev/app/api-tokens" target="_blank" rel="noopener noreferrer">https://envio.dev/app/api-tokens</a></p>
<p>Alongside this, HyperIndex V3 also supports using <a href="https://podman.io/" target="_blank" rel="noopener noreferrer">Podman</a> for local development, in addition to Docker.</p>
<p>This is just the beginning for V3. Many of these features are early building blocks, with loads more improvements, refinements, and additions already in underway.</p>
<p>For a deeper dive into everything included so far, be sure to check out the full release notes. More updates coming soon.</p>
<p>See full <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">release notes</a></p>
<p>Star us on <a href="https://github.com/enviodev/hyperindex" target="_blank" rel="noopener noreferrer">GitHub</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="indexing-data-on-injective">Indexing Data on Injective<a class="hash-link" aria-label="Direct link to Indexing Data on Injective" title="Direct link to Indexing Data on Injective" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#indexing-data-on-injective">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-6.png" alt="Indexing Data on Injective" width="100%">
<p>Envio proudly supports developers and analysts building on <a href="https://injective.com/" target="_blank" rel="noopener noreferrer">Injective</a> by providing efficient access to real-time and historical onchain data to help teams build robust apps on Injective.</p>
<p>With Envio, teams can sync and query Injective data and define fully customizable indexing logic based on their application needs, without managing indexing infrastructure themselves.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="migrating-production-subgraphs-polymarket-indexer">Migrating Production Subgraphs: Polymarket Indexer<a class="hash-link" aria-label="Direct link to Migrating Production Subgraphs: Polymarket Indexer" title="Direct link to Migrating Production Subgraphs: Polymarket Indexer" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#migrating-production-subgraphs-polymarket-indexer">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-7.png" alt="Polymarket indexer" width="100%">
<p>A common question we hear is what migrating a real production subgraph setup actually looks like in practice.</p>
<p>This example shows every Polymarket subgraph migrated into a single Envio indexer, providing a concrete reference for teams looking to consolidate or migrate existing subgraph infrastructure.</p>
<p>The full implementation is available here:</p>
<p><a href="https://github.com/enviodev/polymarket-indexer" target="_blank" rel="noopener noreferrer">https://github.com/enviodev/polymarket-indexer</a></p>
<p><em><span style="text-decoration:underline"> Note: This example is still a work in progress and under active testing</span></em></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="blockchain-indexer-for-application-backends">Blockchain Indexer For Application Backends<a class="hash-link" aria-label="Direct link to Blockchain Indexer For Application Backends" title="Direct link to Blockchain Indexer For Application Backends" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#blockchain-indexer-for-application-backends">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/blockchain-indexer-backends.png" alt="Blockchain Indexer asset" width="100%">
<p>Indexers are a core part of most application backends, sitting between the blockchain and the app. By transforming raw onchain data into structured, queryable state, indexing removes a lot of complexity from backend logic and makes applications easier to build and scale as they grow. Envio fits into this workflow by providing a consistent indexing layer teams can use from local development through production, without changing how their backend logic is defined.</p>
<p>For more details, read the full <a href="https://docs.envio.dev/blog/blockchain-indexer-application-backends" target="_blank" rel="noopener noreferrer">blog</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-powers-funnel-with-efficient-data-indexing">Envio Powers Funnel with Efficient Data Indexing<a class="hash-link" aria-label="Direct link to Envio Powers Funnel with Efficient Data Indexing" title="Direct link to Envio Powers Funnel with Efficient Data Indexing" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#envio-powers-funnel-with-efficient-data-indexing">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-9.png" alt="Envio &amp; Funnel" width="100%">
<p><a href="https://funnel.markets/" target="_blank" rel="noopener noreferrer">Funnel</a> is back after completing a successful backend migration to Envio, which has improved the performance and reliability of the onchain data powering their application heading into 2026.</p>
<p>Funnel uses Envio as its indexing layer to ingest and query onchain data used across the app, including data supporting trading views and listings built on Hyperliquid.</p>
<p>The migration gives the Funnel team a more robust and maintainable data pipeline, allowing them to focus on shipping product without managing indexing infrastructure.</p>
<p>See this post on <a href="https://x.com/funnel_markets/status/2009670839940329711" target="_blank" rel="noopener noreferrer">X</a> for more info.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="current--upcoming-events--hackathons">Current &amp; Upcoming Events &amp; Hackathons<a class="hash-link" aria-label="Direct link to Current &amp; Upcoming Events &amp; Hackathons" title="Direct link to Current &amp; Upcoming Events &amp; Hackathons" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#current--upcoming-events--hackathons">​</a></h2>
<ul>
<li><a href="https://ethdenver.com/" target="_blank" rel="noopener noreferrer">EthDenver - Denver</a>: Feb 17th → 21st</li>
<li><a href="https://ethcc.io/" target="_blank" rel="noopener noreferrer">EthCC - Cannes</a>: March 30th → April 2nd</li>
<li><a href="https://ethconf.com/" target="_blank" rel="noopener noreferrer">EthConf - New York</a>: June 8th → 10th</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="featured-developer-zod">Featured Developer: Zod<a class="hash-link" aria-label="Direct link to Featured Developer: Zod" title="Direct link to Featured Developer: Zod" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#featured-developer-zod">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-10.png" alt="DOTM Jan 2026" width="100%">
<p>This month’s featured developer is Zod. They’ve been building for a few decades and working onchain since 2019. Over the past year, they’ve been actively using tools like Cursor and exploring in-the-loop agentic development.</p>
<p>In August 2024, Zod took over <a href="https://scale.farm/" target="_blank" rel="noopener noreferrer">Scale</a> from <a href="https://migrate.equalizer.exchange/" target="_blank" rel="noopener noreferrer">Equalizer</a> and began transforming it into what they describe as a MetaIndex. This concept focuses on generating revenue across DeFi, rather than limiting revenue to V2 pools, to reduce fresh emissions by earning treasury revenue through other protocols such as Aerodrome.</p>
<p>Scale continues to emit its own token and run liquidity, while integrating Manual CL as part of this evolution.</p>
<p><em><strong>“To power our instant-on, data-rich experience across millions of transactions, I need fast, real-time data and deep historical depth with tight latency. I run multiple Envio indexers in parallel with an orchestration layer, which gives us exactly that. Having the full source as a git submodule means I can do deep dives when facing issues, and the team has been super helpful. After previously unhappy experiences with other indexers, Envio has been a massive win.” - Zod, Co-Founder &amp; Lead Developer at Scale</strong></em></p>
<p>Well done, Zod. Be sure to check out Scale and follow the team on <a href="https://x.com/Scale_Farm" target="_blank" rel="noopener noreferrer">X</a> to stay up to date with their latest developments.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="playlist-of-the-month">Playlist of the Month<a class="hash-link" aria-label="Direct link to Playlist of the Month" title="Direct link to Playlist of the Month" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#playlist-of-the-month">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-jan-26-11.png" alt="PLOTM Jan 2026" width="100%">
<p>▶ <a href="https://open.spotify.com/playlist/3LismooWdej6nDxwY9486d?si=00ab83ef26874d81" target="_blank" rel="noopener noreferrer">Open Spotify</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-developer-update-january-2026#build-with-envio">​</a></h2>
<p>Envio is a multichain EVM blockchain indexer for querying real-time and historical data. If you’re working on a Web3 project and want a smoother development process, Envio’s got your back(end). Check out our docs, join the community, and let’s talk about your data needs.</p>
<p>Stay tuned for more monthly updates by subscribing to our newsletter, following us on X, or hopping into our Discord for more up-to-date information.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>product-updates</category>
        </item>
        <item>
            <title><![CDATA[Envio Developer Update December 2025]]></title>
            <link>https://docs.envio.dev/blog/envio-developer-update-december-2025</link>
            <guid>https://docs.envio.dev/blog/envio-developer-update-december-2025</guid>
            <pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[What Envio shipped in December 2025: an early look at HyperIndex v3.0.0, Solana experimentation, Sonic support, and a USDT0 indexing example.]]></description>
            <content:encoded><![CDATA[<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25.png" alt="Cover Image Envio Developer Update Dec 2025" width="100%">
<p>Welcome to the Envio monthly developer update. Here is what shipped in December 2025.</p>
<p>As we wrap up the end of the year, this update shares what's next for Envio and what we've been working on across the product and community.</p>
<p>This month includes an early look at HyperIndex v3.0.0, early experimentation with Solana support, continued support for teams building on Sonic, updates from Decypted Bytes streams, a new USDT0 indexing example, and our featured developer for December, and much more.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="hyperindex-v300-is-coming">HyperIndex v3.0.0 is Coming<a class="hash-link" aria-label="Direct link to HyperIndex v3.0.0 is Coming" title="Direct link to HyperIndex v3.0.0 is Coming" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#hyperindex-v300-is-coming">​</a></h2>
<p>HyperIndex v3.0.0 is an alpha release introducing ESM support with top-level await and automatic handler registration, alongside lower HyperSync latency and faster queries. The release also includes an experimental ClickHouse Sink, cleaner configuration and defaults, and early experimental Solana support, and much more to come.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="commonjs--esm">CommonJS → ESM<a class="hash-link" aria-label="Direct link to CommonJS → ESM" title="Direct link to CommonJS → ESM" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#commonjs--esm">​</a></h3>
<p>HyperIndex now runs ESM-only.</p>
<p>This unlocks support for modern libraries and enables <strong>top-level await</strong> across handlers, and <code>envio init</code> now comes with new templates and an updated <code>tsconfig.json</code>.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  /* For details: https://www.totaltypescript.com/tsconfig-cheat-sheet */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  "compilerOptions": {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    /* Base Options: */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "esModuleInterop": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "skipLibCheck": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "target": "es2022",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "allowJs": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "resolveJsonModule": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "moduleDetection": "force",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "isolatedModules": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "verbatimModuleSyntax": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    /* Strictness */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "strict": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "noUncheckedIndexedAccess": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "noImplicitOverride": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    /* For running Envio: */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "module": "ESNext",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "moduleResolution": "bundler",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "noEmit": true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    /* Code doesn't run in the DOM: */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    "lib": ["es2022"]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="top-level-await">Top-level await<a class="hash-link" aria-label="Direct link to Top-level await" title="Direct link to Top-level await" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#top-level-await">​</a></h3>
<p>You can now use top-level await directly in handlers files in HyperIndex V3.</p>
<p>This makes it easy to load things like whitelisted addresses or config from a server instead of hardcoding values into the codebase.</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">import { ERC20 } from "generated";</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">// THIS IS NEW</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">const addressesFromServer = await loadWhitelistedAddresses();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">ERC20.Transfer.handler(</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  async ({ event, context }) =&gt; {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    //... your handler logic</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wildcard: true,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> eventFilters: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      { from: ZERO_ADDRESS, to: addressesFromServer },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      { from: addressesFromServer, to: ZERO_ADDRESS },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    ],</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">);</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="srchandlers-auto-registration">src/handlers auto registration<a class="hash-link" aria-label="Direct link to src/handlers auto registration" title="Direct link to src/handlers auto registration" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#srchandlers-auto-registration">​</a></h3>
<p>HyperIndex v3 automatically registers handler files from src/handlers. You no longer need to list explicit handler paths in <code>config.yaml</code>. Just place your files in src/handlers and they will be picked up automatically.</p>
<p>If you prefer a different structure, you can override this using the handlers option. Explicit handler paths still work as before.</p>
<p><em>Deprecation: Explicit handler paths are still supported, so no changes are required.</em></p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="block-handler-indexers">Block handler indexers<a class="hash-link" aria-label="Direct link to Block handler indexers" title="Direct link to Block handler indexers" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#block-handler-indexers">​</a></h3>
<p>It is now possible to create indexers using only block handlers. Event handlers are no longer required, and contracts are optional in config.yaml.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="flexible-entity-fields">Flexible entity fields<a class="hash-link" aria-label="Direct link to Flexible entity fields" title="Direct link to Flexible entity fields" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#flexible-entity-fields">​</a></h3>
<p>Restrictions on entity field names have been removed. Improvements have also been made to ensure database columns are generated in the same order as they are defined in schema.graphql.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="hypersync-source-improvements">HyperSync source improvements<a class="hash-link" aria-label="Direct link to HyperSync source improvements" title="Direct link to HyperSync source improvements" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#hypersync-source-improvements">​</a></h3>
<p>Several updates on the HyperSync side reduce latency and unnecessary traffic. These include using server sent events for block updates, more efficient query serialization, and caching for repetitive queries.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="experimental-clickhouse-sink-support">Experimental ClickHouse Sink support<a class="hash-link" aria-label="Direct link to Experimental ClickHouse Sink support" title="Direct link to Experimental ClickHouse Sink support" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#experimental-clickhouse-sink-support">​</a></h3>
<p>HyperIndex v3 adds experimental ClickHouse Sink support. Postgres remains the primary database. You can additionally sink entities to ClickHouse for restart and reorg resistant workloads.</p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="experimental-additions-solana-support">Experimental additions: Solana Support<a class="hash-link" aria-label="Direct link to Experimental additions: Solana Support" title="Direct link to Experimental additions: Solana Support" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#experimental-additions-solana-support">​</a></h3>
<p>V3 introduces experimental Solana support using RPC as a source. Be sure to check out our <a href="https://docs.envio.dev/docs/HyperIndex/solana" target="_blank" rel="noopener noreferrer">docs</a> for more information.</p>
<p>Try it out with:</p>
<div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pnpx envio init solana</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="cleanups-and-defaults">Cleanups and defaults<a class="hash-link" aria-label="Direct link to Cleanups and defaults" title="Direct link to Cleanups and defaults" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#cleanups-and-defaults">​</a></h3>
<p>Deprecated APIs and legacy options have been removed, defaults have been updated, and Node.js 22 is now the minimum supported version. Internal naming and metrics have also been cleaned up for consistency.</p>
<p>This is just the start, with a lot more to come. Stay tuned!</p>
<p>See full <a href="https://github.com/enviodev/hyperindex/releases" target="_blank" rel="noopener noreferrer">release notes</a></p>
<p>Star us on <a href="https://github.com/enviodev/hyperindex" target="_blank" rel="noopener noreferrer">GitHub</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-supports-developers-building-on-sonic">Envio Supports Developers Building on Sonic<a class="hash-link" aria-label="Direct link to Envio Supports Developers Building on Sonic" title="Direct link to Envio Supports Developers Building on Sonic" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#envio-supports-developers-building-on-sonic">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-1.png" alt="Envio supports Sonic" width="100%">
<p>Envio supports developers and analysts building on Sonic by providing access to real-time and historical onchain data through a reliable indexing layer designed for high-throughput environments.</p>
<p>With Sonic's fast finality and high transaction volumes, teams need indexing infrastructure that can keep up without adding operational complexity. Envio is built to handle these conditions, allowing developers and analysts to query, monitor, and analyze Sonic data efficiently.</p>
<p>This support makes it easier for teams to build data-heavy applications, analytics dashboards, and monitoring tools on Sonic without having to manage indexing infrastructure themselves.</p>
<p><a href="https://docs.envio.dev/docs/HyperIndex/sonic" target="_blank" rel="noopener noreferrer">Start building on Sonic</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="monad-testnet-re-genesis-reindex-required-for-envio-users">Monad Testnet Re-Genesis: Reindex Required for Envio Users<a class="hash-link" aria-label="Direct link to Monad Testnet Re-Genesis: Reindex Required for Envio Users" title="Direct link to Monad Testnet Re-Genesis: Reindex Required for Envio Users" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#monad-testnet-re-genesis-reindex-required-for-envio-users">​</a></h2>
<p>The Monad testnet underwent a full re-genesis, restarting the network from block 1.</p>
<p>For Envio users indexing Monad, this means indexers need to reindex from block 1 now that the refreshed testnet is live. As part of the re-genesis, all existing onchain state was reset and any deployed contracts needed to be redeployed.</p>
<p>This update removes legacy behaviours from early testnet phases and is expected to reduce state sync time going forward. Teams indexing Monad can continue building against the refreshed testnet.</p>
<p>If you need support reindexing or redeploying after the re-genesis, feel free to reach out to the Envio team in our <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-at-solana-breakpoint-2025-in-abu-dhabi">Envio at Solana Breakpoint 2025 in Abu Dhabi<a class="hash-link" aria-label="Direct link to Envio at Solana Breakpoint 2025 in Abu Dhabi" title="Direct link to Envio at Solana Breakpoint 2025 in Abu Dhabi" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#envio-at-solana-breakpoint-2025-in-abu-dhabi">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-2.png" alt="Solana Breakpoint 2025" width="100%">
<p>The Envio team attended <a href="https://solana.com/breakpoint" target="_blank" rel="noopener noreferrer">Solana Breakpoint</a> in Abu Dhabi this month, spending time with teams across the Solana ecosystem and learning more about their data needs and how they're building on Solana.</p>
<p>We had a great few days of conversations with builders, protocols, and infrastructure teams, getting a better sense of the tools, patterns, and challenges teams are working through as the ecosystem continues to grow.</p>
<p>Alongside the event, we've been experimenting with early, <a href="https://docs.envio.dev/docs/HyperIndex/solana" target="_blank" rel="noopener noreferrer">experimental Solana support</a> in Envio. These conversations were valuable in helping us better understand Solana use cases and how indexing infrastructure can support developers and analysts building on the network.</p>
<p>Big thanks to everyone we met and spoke with at Solana Breakpoint. We're looking forward to continuing these conversations as our Solana support evolves. Watch this space.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-developer-workshops-decypted-bytes-is-back">Envio Developer Workshops: Decypted Bytes Is Back<a class="hash-link" aria-label="Direct link to Envio Developer Workshops: Decypted Bytes Is Back" title="Direct link to Envio Developer Workshops: Decypted Bytes Is Back" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#envio-developer-workshops-decypted-bytes-is-back">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-3.png" alt="Decrypt Bytes" width="100%">
<p>Decypted Bytes streams are back and now running daily at 3:00pm UTC, focused on hands-on developer workflows using Envio.</p>
<p>Recent and upcoming sessions cover practical indexing patterns and data pipelines built with HyperIndex and HyperSync, walking through real examples end-to-end.</p>
<h4 class="anchor anchorWithStickyNavbar_LWe7" id="recent-streams-include">Recent streams include:<a class="hash-link" aria-label="Direct link to Recent streams include:" title="Direct link to Recent streams include:" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#recent-streams-include">​</a></h4>
<ul>
<li>
<p><a href="https://www.youtube.com/watch?v=yWfw5gfTibI" target="_blank" rel="noopener noreferrer">Base–Solana Bridge Indexer with HyperIndex</a>, showing how to track cross-chain token transfers between Base and Solana</p>
</li>
<li>
<p><a href="https://www.youtube.com/watch?v=8wNprGmbN24" target="_blank" rel="noopener noreferrer">DuckDB Sink for HyperSync</a>, covering how to write indexed blockchain data into DuckDB for local analytics and querying</p>
</li>
</ul>
<p>All stream links, topics, and the full schedule are available via the <a href="https://decrypted-bytes.notion.site/2c30f730c03780d8a0a5dfba76689f96?v=2c30f730c03780b7b59b000c65b4467d" target="_blank" rel="noopener noreferrer">Decypted Bytes stream schedule</a>. Be sure to subscribe to stay up to date with upcoming sessions.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-adds-support-for-tempo">Envio Adds Support for Tempo<a class="hash-link" aria-label="Direct link to Envio Adds Support for Tempo" title="Direct link to Envio Adds Support for Tempo" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#envio-adds-support-for-tempo">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-4.png" alt="Envio supports Tempo" width="100%">
<p>Envio now supports <a href="https://tempo.xyz/" target="_blank" rel="noopener noreferrer">Tempo</a>, giving teams an easier way to index and query data in real-time and build fully customizable data pipelines.</p>
<p>This support makes it simpler for developers to work with Tempo data using <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">HyperIndex</a>, without needing to set up or maintain custom indexing infrastructure. Teams can define their own indexing logic and query patterns while keeping full control over how data flows through their pipelines.</p>
<p>To get started and learn how to index data on Tempo, check out the <a href="https://docs.envio.dev/docs/HyperIndex/tempo-testnet" target="_blank" rel="noopener noreferrer">setup guide</a> in the Envio docs.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-to-index-cross-chain-usdt0-transfers-with-envio">How to Index Cross-Chain USDT0 Transfers with Envio<a class="hash-link" aria-label="Direct link to How to Index Cross-Chain USDT0 Transfers with Envio" title="Direct link to How to Index Cross-Chain USDT0 Transfers with Envio" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#how-to-index-cross-chain-usdt0-transfers-with-envio">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-5.png" alt="Index USDT0 with Envio" width="100%">
<p>Learn how to build a <a href="https://usdt0.to/" target="_blank" rel="noopener noreferrer">USDT0</a> Indexer using Envio by exploring this example repository, which demonstrates how to track USDT0 transfers across multiple chains.</p>
<p>The repository shows how to use Envio and HyperSync to index USDT0 activity across supported networks, providing a practical reference for teams working with cross-chain token flows.</p>
<p>You can explore the full example, code, and setup instructions in the <a href="https://github.com/enviodev/usdt0-indexer" target="_blank" rel="noopener noreferrer">GitHub repository</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="envio-powers-slabcash-with-efficient-data-indexing">Envio Powers Slab.cash with Efficient Data Indexing<a class="hash-link" aria-label="Direct link to Envio Powers Slab.cash with Efficient Data Indexing" title="Direct link to Envio Powers Slab.cash with Efficient Data Indexing" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#envio-powers-slabcash-with-efficient-data-indexing">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-6.png" alt="Slab Cash" width="100%">
<p><a href="https://slab.cash/" target="_blank" rel="noopener noreferrer">Slab.cash</a> recently went live, bringing onchain collectibles to users.</p>
<p>Envio proudly powers Slab.cash with efficient data indexing, giving the team easy and reliable access to real-time and historical blockchain data so their app can run smoothly as usage grows.</p>
<p>Big congrats to the Slab.cash team on the launch.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started-with-envio-for-the-metamask-advanced-permissions-hackathon">Getting Started with Envio for the MetaMask Advanced Permissions Hackathon<a class="hash-link" aria-label="Direct link to Getting Started with Envio for the MetaMask Advanced Permissions Hackathon" title="Direct link to Getting Started with Envio for the MetaMask Advanced Permissions Hackathon" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#getting-started-with-envio-for-the-metamask-advanced-permissions-hackathon">​</a></h2>
<iframe width="560" height="315" src="https://www.youtube.com/embed/0CeEiNPQRh4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>
<p>As part of the <a href="https://www.hackquest.io/hackathons/MetaMask-Advanced-Permissions-Dev-Cook-Off" target="_blank" rel="noopener noreferrer">MetaMask x Envio Advanced Permissions Hackathon</a>, we ran a workshop walking developers through how to get started with Envio and how it can be used during the hackathon.</p>
<p>The session covered setting up an indexer, exploring demos and examples, and understanding how Envio can support data needs while building.</p>
<p>The MetaMask Advanced Permissions Hackathon is live and runs until December 31, 2025. If you're taking part and building with Envio, we're happy to help support teams throughout the hack.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="current--upcoming-events">Current &amp; Upcoming Events<a class="hash-link" aria-label="Direct link to Current &amp; Upcoming Events" title="Direct link to Current &amp; Upcoming Events" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#current--upcoming-events">​</a></h2>
<ul>
<li><a href="https://www.hackquest.io/hackathons/MetaMask-Advanced-Permissions-Dev-Cook-Off" target="_blank" rel="noopener noreferrer">MetaMask x Envio: Advanced Permissions Dev Cook-Off Hackathon</a>: 18th Nov → 31st Dec 2025</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="featured-developer-port">Featured Developer: Port<a class="hash-link" aria-label="Direct link to Featured Developer: Port" title="Direct link to Featured Developer: Port" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#featured-developer-port">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-7.png" alt="DOTM Dec 2025" width="100%">
<p>This month's featured developer is Port, a builder who loves experimenting with ideas and shipping fast. His journey into development started a few years ago after a health scare, which pushed him to rethink how he wanted to spend his time. Coming from a non-technical background, he began learning web development through The Odin Project and quickly found his way into Web3.</p>
<p>After discovering Monad, Port became deeply involved in the ecosystem, moving on to Speedrun Ethereum and joining <a href="https://buidlguidl.com/" target="_blank" rel="noopener noreferrer">BuidlGuidl</a>. Along the way, he built and contributed to a wide range of open source and community projects, including the block explorer for <a href="https://scaffoldeth.io/" target="_blank" rel="noopener noreferrer">Scaffold ETH</a>, <a href="https://address.vision/" target="_blank" rel="noopener noreferrer">address.vision</a>, and contributions to <a href="https://abi.ninja/" target="_blank" rel="noopener noreferrer">abi.ninja</a>.</p>
<p>Today, Port is part of the Monad devrel team, where he continues to explore what the tech makes possible while building and experimenting whenever he gets the chance. Some of his recent and notable projects include <a href="https://nft-snapshot-beta.vercel.app/" target="_blank" rel="noopener noreferrer">NFT Snapshot</a>, <a href="https://github.com/portdeveloper/monad-monitor" target="_blank" rel="noopener noreferrer">Monad Monitor</a>, <a href="https://oracle-dashboard-seven.vercel.app/" target="_blank" rel="noopener noreferrer">Oracle Dashboard</a>, <a href="https://calculate-my-pnl.vercel.app/" target="_blank" rel="noopener noreferrer">Calculate My PnL</a>, <a href="https://monadclip.fun/" target="_blank" rel="noopener noreferrer">MonadClip</a>, <a href="https://github.com/portdeveloper/splait" target="_blank" rel="noopener noreferrer">Splait</a>, <a href="https://github.com/portdeveloper/gulltoppr" target="_blank" rel="noopener noreferrer">Gulltoppr</a>, <a href="https://github.com/portdeveloper/converteth" target="_blank" rel="noopener noreferrer">ConvertETH</a>, <a href="https://github.com/portdeveloper/anvuil" target="_blank" rel="noopener noreferrer">Anvuil</a>, and <a href="https://github.com/portdeveloper/vanitoor" target="_blank" rel="noopener noreferrer">Vanitoor</a>.</p>
<p><em><strong>"I had an idea, asked it to Claude, and Claude suggested and built the app with Envio without me interfering at any point. I just added the API key to the env file. It was very easy to build with Envio, and the founders are very responsive so you can just ask them questions about how you should be using it." - Port, DevRel at Monad</strong></em></p>
<p>Be sure to follow them on <a href="https://x.com/port_dev" target="_blank" rel="noopener noreferrer">X</a> and check out their work on <a href="https://github.com/portdeveloper?tab=repositories" target="_blank" rel="noopener noreferrer">GitHub</a> to stay up to date with what they are building.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="merry-xmas-from-the-envio-team">Merry Xmas from the Envio Team<a class="hash-link" aria-label="Direct link to Merry Xmas from the Envio Team" title="Direct link to Merry Xmas from the Envio Team" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#merry-xmas-from-the-envio-team">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-8.png" alt="Envio Xmas 2025" width="100%">
<p>As the year comes to a close, we want to say a big thank you to everyone building with Envio for your contributions, feedback, and continued support throughout the year.</p>
<p>We're wishing many of you a fantastic time over the festive season. The Envio team will still be fully available throughout the Christmas period, so feel free to reach out if you need support or want to chat about what you're building.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="playlist-of-the-month">Playlist of the Month<a class="hash-link" aria-label="Direct link to Playlist of the Month" title="Direct link to Playlist of the Month" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#playlist-of-the-month">​</a></h2>
<img src="https://docs.envio.dev/blog-assets/dev-update-dec-25-9.png" alt="PLOTM Dec 2025" width="100%">
<p><a href="https://open.spotify.com/playlist/757HncfHabgU6rpMv9748b?si=94a19e83ccdc4f0d" target="_blank" rel="noopener noreferrer">Open Spotify</a></p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="build-with-envio">Build With Envio<a class="hash-link" aria-label="Direct link to Build With Envio" title="Direct link to Build With Envio" href="https://docs.envio.dev/blog/envio-developer-update-december-2025#build-with-envio">​</a></h2>
<p>Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data. If you are building onchain and need indexing that keeps up with your chain, check out the <a href="https://docs.envio.dev/docs/HyperIndex/overview" target="_blank" rel="noopener noreferrer">docs</a>, run the benchmarks yourself, and come talk to us about your data needs.</p>
<p>Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.</p>
<p><a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;utm_medium=newsletter&amp;utm_campaign=new-post" target="_blank" rel="noopener noreferrer">Subscribe to our newsletter</a> 💌</p>
<p><a href="https://envio.dev/" target="_blank" rel="noopener noreferrer">Website</a> | <a href="https://twitter.com/envio_indexer" target="_blank" rel="noopener noreferrer">X</a> | <a href="https://discord.gg/envio" target="_blank" rel="noopener noreferrer">Discord</a> | <a href="https://t.me/+5mI61oZibEM5OGQ8" target="_blank" rel="noopener noreferrer">Telegram</a> | <a href="https://github.com/enviodev" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" target="_blank" rel="noopener noreferrer">YouTube</a> | <a href="https://www.reddit.com/user/Envio_indexer" target="_blank" rel="noopener noreferrer">Reddit</a></p>]]></content:encoded>
            <category>product-updates</category>
        </item>
    </channel>
</rss>