<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Envio</title>
    <description>The latest articles on DEV Community by Envio (@envio).</description>
    <link>https://dev.to/envio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1208820%2F6d83bf5b-2025-4bab-a10e-7b023a7813c2.png</url>
      <title>DEV Community: Envio</title>
      <link>https://dev.to/envio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/envio"/>
    <language>en</language>
    <item>
      <title>Envio Developer Update September 2026</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Tue, 29 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/envio/envio-developer-update-september-2026-no3</link>
      <guid>https://dev.to/envio/envio-developer-update-september-2026-no3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8lccxcgnn67u6owamtao.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8lccxcgnn67u6owamtao.webp" alt="Cover Image Envio Developer Update September 2026" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solana support in HyperIndex is now stable. The API is final and follows semver. Config and handlers look much like they do on EVM, with the same GraphQL server on top.&lt;/p&gt;

&lt;p&gt;We put out five HyperIndex releases, v3.10.0 to v3.13.0. Indexers can now split across worker processes, the RPC source is written in Rust, and a rollback on one chain can stay on that chain. On top of that we published tutorials for Arc, Robinhood Chain, HyperEVM and Solana stablecoins, added docs for Envio Cloud troubleshooting and trace decoding, moved HyperPipe to community support, and put up a page comparing Envio with other indexers.&lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  HyperIndex v3.10.0 -&amp;gt; v3.13.0
&lt;/h2&gt;

&lt;p&gt;Most of this month's work went into speed and keeping chains apart in multichain indexers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4x faster in many cases with automatic multiprocess indexing&lt;/li&gt;
&lt;li&gt;RPC source rewritten in Rust, 2 to 17x faster on our open benchmark&lt;/li&gt;
&lt;li&gt;Solana support is stable and follows semver&lt;/li&gt;
&lt;li&gt;Each chain can run in its own process&lt;/li&gt;
&lt;li&gt;A rollback on one chain no longer rolls back the others&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  HyperIndex v3.13.0: Multiprocess Indexing and a Rust RPC Source
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Automatic Multiprocess Indexing
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk7rqomc8cn64pbxno7x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk7rqomc8cn64pbxno7x.gif" alt="An indexer splitting into four worker processes" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When every entity is isolated per chain and &lt;code&gt;ENVIO_PG_MAX_CONNECTIONS&lt;/code&gt; is large enough, the indexer now splits itself into up to 4 worker processes on its own.&lt;/p&gt;

&lt;p&gt;It uses more resources, and in return it is 4x faster in many cases and more reliable. On Envio Cloud it is available on demand for Dedicated plans.&lt;/p&gt;

&lt;h3&gt;
  
  
  RPC Source Rewritten in Rust
&lt;/h3&gt;

&lt;p&gt;If you index over your own RPC, upgrade. The RPC source is now written in Rust, with reworked logic and concurrency, and it handles bad provider responses without crashing. It is 2 to 17x faster on the &lt;a href="https://github.com/enviodev/open-indexer-benchmark" rel="noopener noreferrer"&gt;Open Indexer Benchmark&lt;/a&gt; cases.&lt;/p&gt;

&lt;p&gt;It also adds the &lt;code&gt;accessList&lt;/code&gt; and &lt;code&gt;authorizationList&lt;/code&gt; transaction fields, so the RPC source now selects the same transaction fields as the HyperSync source.&lt;/p&gt;

&lt;h2&gt;
  
  
  HyperIndex v3.12.0: One Process Per Chain
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Run Chains in Separate Processes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftked8cbjk7a1e20gf40s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftked8cbjk7a1e20gf40s.gif" alt="Running each chain of a multichain indexer in its own process" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;envio start --chain &amp;lt;CHAIN_ID&amp;gt;&lt;/code&gt; lets several processes index different chains of the same indexer in parallel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;envio &lt;span class="nb"&gt;local &lt;/span&gt;db-migrate &lt;span class="nv"&gt;upENVIO_INDEXER_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8080 envio start &lt;span class="nt"&gt;--chain&lt;/span&gt; &lt;span class="nv"&gt;1ENVIO_INDEXER_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8081 envio start &lt;span class="nt"&gt;--chain&lt;/span&gt; 137 &lt;span class="nt"&gt;--chain&lt;/span&gt; 5042
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Create the database once with &lt;code&gt;envio local db-migrate up&lt;/code&gt;, give each chain to exactly one process, and give each process its own port. Every process runs independently of the others. It needs a schema where every entity is per chain, with no &lt;code&gt;@crossChain&lt;/code&gt; entities, and it can't be combined with &lt;code&gt;--restart&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Head Lag With Progress Block Time
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqp1lbw4xa8ynj6nk0ct8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqp1lbw4xa8ynj6nk0ct8.gif" alt="Measuring how far behind chain time an indexer is with progress block time" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The new &lt;code&gt;envio_progress_block_time_seconds&lt;/code&gt; metric, also exposed as &lt;code&gt;_meta.progressBlockTime&lt;/code&gt;, gives the timestamp of the block each chain has processed up to. &lt;code&gt;now() - progress_block_time&lt;/code&gt; is your real lag, even when a data source reports itself at the head while sitting behind the chain.&lt;/p&gt;

&lt;p&gt;Chains that reach their &lt;code&gt;endBlock&lt;/code&gt; freeze the value, so leave them out of alerts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Every Account a Solana Transaction Touches
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fagzqsl04ly1l9dr2eqkt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fagzqsl04ly1l9dr2eqkt.gif" alt="Solana account keys including addresses from lookup tables" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;accountKeys&lt;/code&gt; now includes addresses resolved through Address Lookup Tables, so handlers see every account a versioned transaction touches. The &lt;code&gt;envio init&lt;/code&gt; Solana templates are replaced by &lt;code&gt;usdc-transfers&lt;/code&gt;, which indexes SPL Token transfers on mainnet.&lt;/p&gt;

&lt;p&gt;v3.12.1 rounded the release out with 4x faster &lt;code&gt;getWhere&lt;/code&gt; in handlers and more reliable progress block time reporting at the head.&lt;/p&gt;

&lt;h2&gt;
  
  
  HyperIndex v3.11.0: Solana Goes Stable
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Solana Support Is Now Stable
&lt;/h3&gt;

&lt;p&gt;The HyperIndex API for Solana is final and follows semver from here, so you can build on it without expecting breaking changes between minor versions. More on where Solana is at &lt;a href="https://docs.envio.dev/blog/developer-update-september-2026#solana-is-stable-heres-where-were-at" rel="noopener noreferrer"&gt;below&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start From the Latest Block
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7y3cxgy82egvox9jd17x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7y3cxgy82egvox9jd17x.gif" alt="Setting the start block to latest in config.yaml" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The start block now accepts &lt;code&gt;"latest"&lt;/code&gt;. The indexer checks the chain height on startup and starts from there, so there's no block number to look up first. You can see it in the Solana config below.&lt;/p&gt;

&lt;h2&gt;
  
  
  HyperIndex v3.10.0: Per-Chain Rollbacks and Rust ClickHouse Storage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rollbacks Stay on Their Own Chain
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;disable_default_cross_chain: true&lt;/code&gt; and no entities marked &lt;code&gt;@crossChain&lt;/code&gt;, a rollback now applies only to the chain that triggered it. Multichain indexers get better isolation, better performance and lower latency.&lt;/p&gt;

&lt;h3&gt;
  
  
  ClickHouse Storage in Rust
&lt;/h3&gt;

&lt;p&gt;The ClickHouse storage backend is now written in Rust. It's faster and more reliable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose How Bytes Are Stored
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzr3r8px9ghyfa7s9p9ad.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzr3r8px9ghyfa7s9p9ad.gif" alt="Storing Bytes fields as raw bytes in Postgres" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Bytes&lt;/code&gt; fields used to be a plain alias for the GraphQL &lt;code&gt;String&lt;/code&gt; type. You can now switch them to &lt;code&gt;Uint8Array&lt;/code&gt; in your handlers, which also makes the Postgres column &lt;code&gt;bytea&lt;/code&gt;. Hex strings stay the default. Solana indexers always use &lt;code&gt;uint8array&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;bytes_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;uint8array&lt;/span&gt; &lt;span class="c1"&gt;# default is hex&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  More Reliable Head Tracking
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftpbge3rukxfv3luzo2nz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftpbge3rukxfv3luzo2nz.gif" alt="Height stream connect and disconnect metrics" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HyperIndex streams new block heights from the HyperSync SSE endpoint by default, with RPC WebSocket as an option and polling as the fallback. The stream now stays alive more reliably and falls back to polling without the 10 to 20 second gap, which lowers latency and keeps new block tracking steady. Two new Prometheus metrics come with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;envio_source_height_stream_connects_totalenvio_source_height_stream_disconnects_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solana Instruction Filtering
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1uk2qskrta9gkpv8kr9r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1uk2qskrta9gkpv8kr9r.gif" alt="Filtering Solana instructions with where" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solana instruction handlers now take &lt;code&gt;where&lt;/code&gt; filters on named accounts, inner or outer instructions, and a minimum slot. Discriminators can be any byte length, and more than one instruction can share a discriminator.&lt;/p&gt;

&lt;p&gt;See full &lt;a href="https://github.com/enviodev/hyperindex/releases" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Star us on &lt;a href="https://github.com/enviodev/hyperindex" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana Is Stable, Here's Where We're At
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ozeroaecg3u0b00ug92.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ozeroaecg3u0b00ug92.gif" alt="Indexing a Solana program with an onInstruction handler" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configuration, handlers and payload types now follow semver like the rest of HyperIndex, so what you build on Solana today keeps working as HyperIndex moves forward.&lt;/p&gt;

&lt;p&gt;Start with &lt;code&gt;pnpx envio init&lt;/code&gt; and pick a Solana template. HyperSync is the data source by default, and the config looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# yaml-language-server: $schema=./node_modules/envio/svm.schema.jsonname: usdc-transfersdescription: USDC Token Transfersecosystem: svmchains: - id: solana start_slot: "latest"programs: - name: SplToken program_id: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA idl: ./idls/spl-token.codama.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;And a handler for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;indexer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;envio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;USDC_MINT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;indexer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onInstruction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SplToken&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transferChecked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accounts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;args&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;signature&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;accountActivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token.mint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;USDC_MINT&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Transfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;txSignature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;You get automatic decoding and filtering, Anchor and Codama IDLs, writes to Postgres and ClickHouse, a GraphQL server on top of your Solana data, and hosting on Envio Cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where We're At With Solana
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HyperIndex on Solana is stable.&lt;/strong&gt; The API has been final since v3.11.0 and follows semver.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solana HyperSync is live on mainnet&lt;/strong&gt; at &lt;code&gt;https://solana.hypersync.xyz&lt;/code&gt;, serving slots, transactions, instruction calls, logs and account activity from one endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;History starts around slot 391,000,000&lt;/strong&gt; , not at genesis. We keep extending it backwards as we backfill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It runs end to end.&lt;/strong&gt; Local dev, Postgres or ClickHouse, the GraphQL API and hosting on Envio Cloud all work the same as on EVM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One ecosystem per indexer.&lt;/strong&gt; An indexer covers Solana or EVM chains, not both at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This month also added &lt;code&gt;where&lt;/code&gt; filters on instructions, account keys resolved through Address Lookup Tables, and a USDC Transfers starter template in &lt;code&gt;envio init&lt;/code&gt;. For a worked example, our &lt;a href="https://docs.envio.dev/blog/index-solana-stablecoin-transfers" rel="noopener noreferrer"&gt;Solana stablecoin tutorial&lt;/a&gt; indexes a full day of USDC, USDT, PYUSD and USDG transfers.&lt;/p&gt;

&lt;p&gt;On the Solana USDC transfers scenario on our &lt;a href="https://envio.dev/compare" rel="noopener noreferrer"&gt;compare page&lt;/a&gt;, HyperIndex was the fastest indexer in the latest run.&lt;/p&gt;

&lt;p&gt;If you're building on Solana, we highly recommend testing it against the programs you want to index. Reach out to the team on &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; with your use case and we'll test it with you. Any feedback you have shapes what we prioritise next.&lt;/p&gt;

&lt;p&gt;Read the docs: &lt;a href="https://docs.envio.dev/docs/HyperIndex/solana" rel="noopener noreferrer"&gt;Indexing on Solana&lt;/a&gt; and &lt;a href="https://docs.envio.dev/docs/HyperSync/solana" rel="noopener noreferrer"&gt;Solana HyperSync&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why HyperSync Checks Blocks Against Their Roots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohw0osf09b8ar4yd1ych.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fohw0osf09b8ar4yd1ych.webp" alt="Nodes silently miss events, verifying data against block roots with HyperSync" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A node can drop logs and still hand you a response that looks completely fine. There's no error, and nothing in the JSON tells you anything is missing.&lt;/p&gt;

&lt;p&gt;Block headers commit to every transaction and receipt through Merkle roots, but you need the whole block to check them. Because HyperSync ingests whole blocks, it recomputes both roots before serving anything and refetches from another source if they don't match. That way missing logs tend to get caught early, rather than turning up later in your database.&lt;/p&gt;

&lt;p&gt;More here: &lt;a href="https://docs.envio.dev/blog/nodes-silently-miss-events" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/nodes-silently-miss-events&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What HyperEVM Sends to HyperCore
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fevb4wnmqz2bloeecgelb.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fevb4wnmqz2bloeecgelb.webp" alt="How to build a HyperEVM indexer on Hyperliquid" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We wanted to know how much of Hyperliquid an EVM indexer can actually see, so we built one that tracks everything HyperEVM sends to HyperCore, every action, HYPE transfer and spot token transfer, and ran it from genesis. The biggest CoreWriter user isn't a trading bot or a DEX. It's Circle's USDC deposit wallet, behind 57.5% of all the actions we indexed.&lt;/p&gt;

&lt;p&gt;One thing worth knowing going in is that the data only flows one way. Anything HyperEVM sends to HyperCore leaves a log, but what comes back from HyperCore doesn't. The tutorial walks through what you can and can't see, how to check what HyperCore actually did with each request, and how to index your own HyperEVM contract with three small files.&lt;/p&gt;

&lt;p&gt;Read the full tutorial: &lt;a href="https://docs.envio.dev/blog/index-hyperevm-data" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/index-hyperevm-data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Envio Side by Side With Other Indexers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ydrcp2nv50u4t8s69d5.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ydrcp2nv50u4t8s69d5.webp" alt="Envio's compare indexers page" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The compare page puts Envio side by side with the other popular indexers, and every claim links to its source.&lt;/p&gt;

&lt;p&gt;Indexing isn't one workload, so one number can't rank it. The benchmark section runs several scenarios from the &lt;a href="https://github.com/enviodev/open-indexer-benchmark" rel="noopener noreferrer"&gt;Open Indexer Benchmark&lt;/a&gt;, with each tool on the EVM scenarios running in GitHub CI and started the way its own docs recommend for production. The tables refresh automatically.&lt;/p&gt;

&lt;p&gt;The head-to-heads cover things like speed, chain coverage, pricing and self-hosting, and each one says plainly when the other tool is the better choice. There are also migration paths, from moving a subgraph to migrating with AI, plus an FAQ.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://envio.dev/compare" rel="noopener noreferrer"&gt;https://envio.dev/compare&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Every Tokenised Stock on Robinhood Chain, From One Contract
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ld7qwxgmmsw20ckmk6n.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1ld7qwxgmmsw20ckmk6n.webp" alt="How to index every tokenised asset on Robinhood Chain" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We wanted to know which tokenised stocks exist on Robinhood Chain and which ones people actually trade. It turns out every stock is deployed by the same factory contract, so we built an indexer that reads its deploy events, picks up each token (including any Robinhood adds later) and indexes their transfers. Twenty of those tokens carry 90.9% of all transfers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fztyf1k1n7309lvaungl4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fztyf1k1n7309lvaungl4.gif" alt="Pointing Envio at a Robinhood Chain contract in config.yaml" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want to build on Robinhood Chain yourself? HyperSync, HyperRPC and HyperIndex all work there out of the box, and the &lt;a href="https://envio.dev/chains/robinhood" rel="noopener noreferrer"&gt;chain page&lt;/a&gt; has the connection details.&lt;/p&gt;

&lt;p&gt;Read the full tutorial: &lt;a href="https://docs.envio.dev/blog/index-robinhood-chain-data" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/index-robinhood-chain-data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Most Solana Stablecoin Transfers Aren't Top-Level
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zh4t0p6jt9ngtty5lh0.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3zh4t0p6jt9ngtty5lh0.webp" alt="How to index and track stablecoin transfers on Solana" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tracking stablecoin transfers on Solana sounds like one filter, but we had a feeling a lot was being missed. So we built an indexer for USDC, USDT, PYUSD and USDG transfers and ran it over a full day. Only 23.3% of those transfers were top-level instructions, and the rest happened inside other programs like swaps and lending deposits.&lt;/p&gt;

&lt;p&gt;That matters because a transfer on Solana can come through any of three instructions on two different token programs. If your indexer only handles some of them, nothing breaks, your numbers are just quietly incomplete. The tutorial has the mint addresses and an indexer that catches all of them.&lt;/p&gt;

&lt;p&gt;Learn more here: &lt;a href="https://docs.envio.dev/blog/index-solana-stablecoin-transfers" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/index-solana-stablecoin-transfers&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why USDC on Arc Gets Logged Twice
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcnzj4eyexhjwqzc980qd.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcnzj4eyexhjwqzc980qd.webp" alt="How to index USDC transfers on Arc" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We noticed something odd about USDC on Arc. It's both the gas token and an ERC-20, which means a transfer can be logged twice. A system address logs every transfer, native sends included, and the USDC contract logs ERC-20 calls again on top.&lt;/p&gt;

&lt;p&gt;So we indexed a 100,000 block sample to see how much it matters. Indexing both sources would have double counted 48.3% of transfers, and indexing only the contract would have missed 51.7%. The tutorial shows which one to index, and the three-file indexer in it matched HyperSync's count exactly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhdn205o4yrhafvi6dx8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhhdn205o4yrhafvi6dx8.gif" alt="Indexing Arc in real time with a HyperIndex config" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We provide first-class support for Arc on Envio, so you can backfill its history and follow new blocks with HyperSync, query it through HyperRPC, or spin up a HyperIndex indexer with a GraphQL API on top. Arc Testnet is supported as well, and the &lt;a href="https://envio.dev/chains/arc" rel="noopener noreferrer"&gt;chain page&lt;/a&gt; has everything you need to get connected.&lt;/p&gt;

&lt;p&gt;Read the full tutorial: &lt;a href="https://docs.envio.dev/blog/index-arc-usdc-transfers" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/index-arc-usdc-transfers&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Apps Are Actually Live on Robinhood Chain
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmfqgd94emrc2juu0lopf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmfqgd94emrc2juu0lopf.webp" alt="Robinhood Chain ecosystem, live apps and how to index them" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Robinhood lists plenty of ecosystem partners, but a listing doesn't tell you what's actually running. So we checked each app against its own docs and its contracts on Robinhood Chain, and wrote up the ones that are live, with the contracts to index and a week of onchain activity for most of them. Uniswap is the busiest by a long way, with 2,552,298 transactions from 321,551 wallets in a single week.&lt;/p&gt;

&lt;p&gt;Read it here: &lt;a href="https://docs.envio.dev/blog/robinhood-chain-ecosystem" rel="noopener noreferrer"&gt;https://docs.envio.dev/blog/robinhood-chain-ecosystem&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Monad Metropolis Hackathon
&lt;/h2&gt;



&lt;p&gt;Monad's Metropolis hackathon runs from September 1st to October 13th with $250,000+ in prizes, and there's a dedicated track for the best use of Envio.&lt;/p&gt;

&lt;p&gt;We've put up $1,000 for the best use of Envio, and winning teams get $5,000 of free Envio Cloud hosting. If your build has reached the onchain data part, reach out to our team with your contract address and we'll help you get it indexed.&lt;/p&gt;

&lt;p&gt;Check out the video above to learn how an indexer fits into your build, and why your frontend shouldn't have to query the blockchain for everything.&lt;/p&gt;

&lt;p&gt;Find the Envio track here: &lt;a href="https://hackathon.monad.xyz/tracks/best-use-of-envio" rel="noopener noreferrer"&gt;https://hackathon.monad.xyz/tracks/best-use-of-envio&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New in the Docs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eukbgcopnofy9z0lvds.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0eukbgcopnofy9z0lvds.gif" alt="New in the Envio docs, troubleshooting, traces and Uniswap v4" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fixing Common Envio Cloud Deploy Issues
&lt;/h3&gt;

&lt;p&gt;A new page answers the questions we get most about deploying on Envio Cloud. Why an indexer builds locally but fails on Envio Cloud, why a push didn't start a deployment, why an organisation or repository is missing, how to add or remove people, and why an indexer is paused.&lt;/p&gt;

&lt;p&gt;Read it here: &lt;a href="https://docs.envio.dev/docs/HyperIndex/envio-cloud-troubleshooting" rel="noopener noreferrer"&gt;https://docs.envio.dev/docs/HyperIndex/envio-cloud-troubleshooting&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Seeing What a Transaction Actually Did
&lt;/h3&gt;

&lt;p&gt;Traces show what a transaction did once it started running, including internal ETH transfers, calls that emit no event and calls that reverted. None of that is in the logs. The new HyperSync tutorial queries traces and decodes the call data with viem, and ends with a prompt you can hand to your coding agent.&lt;/p&gt;

&lt;p&gt;Read the tutorial: &lt;a href="https://docs.envio.dev/docs/HyperSync/tutorial-decoding-traces" rel="noopener noreferrer"&gt;https://docs.envio.dev/docs/HyperSync/tutorial-decoding-traces&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Uniswap v4 Walkthrough
&lt;/h3&gt;

&lt;p&gt;The Uniswap v4 page now has a walkthrough for building a minimal swap indexer yourself, alongside the production indexer that powers &lt;a href="https://v4.xyz/" rel="noopener noreferrer"&gt;v4.xyz&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More here: &lt;a href="https://docs.envio.dev/docs/HyperIndex/example-uniswap-v4-multi-chain-indexer" rel="noopener noreferrer"&gt;https://docs.envio.dev/docs/HyperIndex/example-uniswap-v4-multi-chain-indexer&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HyperPipe Is Now Community-Supported
&lt;/h2&gt;

&lt;p&gt;HyperPipe has been open source for a while, and from here it's a community-supported project rather than something we develop in-house. The core is solid and works end to end, so it's in good shape to build on.&lt;/p&gt;

&lt;p&gt;If you're running WASM data pipelines on HyperSync, or want to add a processor, sink or feature, PRs are welcome. We'll keep reviewing and merging contributions, we just won't be driving the roadmap ourselves.&lt;/p&gt;

&lt;p&gt;Check it out on GitHub: &lt;a href="https://github.com/enviodev/hyperpipe" rel="noopener noreferrer"&gt;https://github.com/enviodev/hyperpipe&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Current &amp;amp; Upcoming Events &amp;amp; Hackathons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://monad.xyz/developers/hackathons/metropolis" rel="noopener noreferrer"&gt;Monad Metropolis&lt;/a&gt;: September 1st -&amp;gt; October 13th&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devcon.org/" rel="noopener noreferrer"&gt;Devcon 8 - Mumbai&lt;/a&gt;: November 3rd -&amp;gt; 6th&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://solana.com/breakpoint" rel="noopener noreferrer"&gt;Solana Breakpoint - London&lt;/a&gt;: November 15th -&amp;gt; 17th&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Featured Developer: deif
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flexi5ue396d9jz5oz4ao.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flexi5ue396d9jz5oz4ao.webp" alt="Featured developer deif" width="799" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This month's featured developer is &lt;a href="https://x.com/thedeif" rel="noopener noreferrer"&gt;deif&lt;/a&gt;, lead developer at Paintswap and a jack-of-all-trades software engineer with around 20 years of experience. Crypto caught their interest with the promise of trustless applications, composability between them and user-centric values.&lt;/p&gt;

&lt;p&gt;When Paintswap released &lt;a href="https://x.com/EstforKingdom" rel="noopener noreferrer"&gt;Estfor Kingdom&lt;/a&gt;, an idle RPG browser game, deif got hooked, started building third-party tools for its players and was eventually hired by Paintswap. Now lead developer, they work across the whole stack to keep improving the game and push what's possible for onchain games.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What deif had to say about Envio:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;"Before Envio Estfor ran on legacy The Graph and considering we had tens of millions of tracked events it would take over a day to release new features or fix bugs due to the extremely lengthy backfill times. I decided to give Envio a go to see if the speed improvements that they advertised could be remotely achieved internally in Estfor. Our expectations were surpassed not only in terms of speed, but in migration ease, developer support by the Envio team, and developer tooling to help diagnose bottlenecks and better optimise our data handling methods. After the latest optimisation pass our custom deployment using Envio's HyperSync processes &amp;gt;10k events per second, allowing us to backfill 2 years of historical data in under an hour (over 30x speed improvement)! I would not hesitate to recommend Envio to anyone that needs to track onchain event data."&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- deif, Lead Developer at Paintswap on &lt;a href="https://estfor.com/" rel="noopener noreferrer"&gt;Estfor Kingdom&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well done, deif. Be sure to follow them on &lt;a href="https://x.com/thedeif" rel="noopener noreferrer"&gt;X&lt;/a&gt; and check out their &lt;a href="https://github.com/hmmdeif" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to stay up to date with their latest developments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Playlist of the Month
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi2s5zfuvacz56xb0lw9i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi2s5zfuvacz56xb0lw9i.webp" alt="Playlist of the month, Sep 26 by Jordy Baby, 23 songs" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://open.spotify.com/playlist/5w8DAYA4SiuKNH4ohdLUkN?si=060ce48a702c49e3" rel="noopener noreferrer"&gt;Open Spotify&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;Envio is a multichain blockchain indexer for EVM chains and Solana, for querying real-time and historical data. If you're building something that needs reliable onchain data, check out our docs, join the community, and tell us what you're working on.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+5mI61oZibEM5OGQ8" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productupdates</category>
    </item>
    <item>
      <title>Robinhood Chain Ecosystem: Live Apps and How to Index Them</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/envio/robinhood-chain-ecosystem-live-apps-and-how-to-index-them-37j0</link>
      <guid>https://dev.to/envio/robinhood-chain-ecosystem-live-apps-and-how-to-index-them-37j0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr9l0s89n0288aquy9s3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr9l0s89n0288aquy9s3n.png" alt="Robinhood Chain Ecosystem: Live Apps and How to Index Them" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;We checked the apps Robinhood lists as ecosystem partners, plus others we found onchain and in other ecosystem lists.&lt;/strong&gt; Each had to pass two tests. Its own docs say it's on &lt;a href="https://docs.robinhood.com/chain/" rel="noopener noreferrer"&gt;Robinhood Chain&lt;/a&gt; mainnet (chain ID &lt;code&gt;4663&lt;/code&gt;), and its contracts are deployed there.&lt;/li&gt;
&lt;li&gt;They cover trading, launchpads, lending, stablecoins and bridges. Each one comes with the contracts to index, and most with a week of onchain activity.&lt;/li&gt;
&lt;li&gt;After Uniswap, the most wallets went to USDG (108,678), Relay (101,360) and Pons (55,370).&lt;/li&gt;
&lt;li&gt;The biggest single vault is Steakhouse's steakUSDG on Morpho. It reported about 499 million USDG, roughly 72% of all USDG on Robinhood Chain when we read it onchain.&lt;/li&gt;
&lt;li&gt;Every activity count here came from one &lt;a href="https://docs.envio.dev/docs/HyperSync/overview" rel="noopener noreferrer"&gt;HyperSync&lt;/a&gt; script you can rerun. To go further, clone &lt;a href="https://github.com/enviodev/robinhood-ecosystem-indexer" rel="noopener noreferrer"&gt;our indexer&lt;/a&gt; for four of these apps, or hand the job to your coding agent with &lt;a href="https://docs.envio.dev/blog/robinhood-chain-ecosystem#replicate-this-with-your-own-agent" rel="noopener noreferrer"&gt;our prompt&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uniswap took 2,552,298 transactions from 321,551 wallets on Robinhood Chain in one week. It's the busiest app we confirmed live, from each app's own docs and from onchain data.&lt;/p&gt;

&lt;p&gt;This blog is for builders. It shows which apps are deployed, which contracts they use, how busy those contracts are and how to utilise Envio to get their data.&lt;/p&gt;

&lt;p&gt;We started from Robinhood's &lt;a href="https://robinhood.com/us/en/chain/ecosystem" rel="noopener noreferrer"&gt;ecosystem page&lt;/a&gt;, then added apps we found onchain and in other ecosystem lists. A listing doesn't tell you what's running, so we checked each app. This blog only covers apps with their own contracts on Robinhood Chain. For connection details and a full tokenized stock indexer, see &lt;a href="https://docs.envio.dev/blog/index-robinhood-chain-data" rel="noopener noreferrer"&gt;How to Index Every Tokenized Asset on Robinhood Chain&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Checked Each App
&lt;/h2&gt;

&lt;p&gt;An app had to pass two checks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Its own source says it's live on mainnet.&lt;/strong&gt; That means the project's docs, API, GitHub or blog, or &lt;a href="https://docs.robinhood.com/chain/" rel="noopener noreferrer"&gt;Robinhood's chain docs&lt;/a&gt;. Third-party roundups didn't count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Its contracts are deployed.&lt;/strong&gt; We confirmed contract code at each published address, then counted a week of activity with HyperSync.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Txs&lt;/strong&gt; counts transactions sent straight to the listed contracts, with the unique wallets behind them in brackets. &lt;strong&gt;Events&lt;/strong&gt; counts logs those contracts emitted. Apps that are usually reached through a router or an aggregator can show few direct transactions and plenty of events, so read the two together. Neither is trading volume, and wallet counts include bots.&lt;/p&gt;

&lt;p&gt;We left out any project we couldn't confirm from its own source. Being listed here isn't a recommendation from us, just a record of what's deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Stands Out
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiokprlfrlhxjk5ue1ap3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiokprlfrlhxjk5ue1ap3.png" alt="Unique wallets by app over one week on Robinhood Chain. Uniswap 321,551, USDG 108,678, Relay 101,360, Pons 55,370, 0x 34,944, OpenSea 22,825, LI.FI 17,227, 1inch 12,980, Across 6,915, Lighter 3,969" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unique wallets sending transactions straight to each app's contracts over one week. Wallet counts include bots.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uniswap is about three times bigger than anything else.&lt;/strong&gt; 321,551 wallets called its contracts in the week. The next biggest, USDG, had 108,678.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One vault is worth about 72% of all USDG.&lt;/strong&gt; There were 691 million USDG on Robinhood Chain when we read it, and steakUSDG reported 499 million in assets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most lending sits in one market.&lt;/strong&gt; Morpho's USDG market backed by USDe collateral had 331.6 million USDG supplied and 299.6 million borrowed, about 90% used, according to the &lt;a href="https://docs.morpho.org/developers/api/get-started/" rel="noopener noreferrer"&gt;Morpho API&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trading venues hold a lot of USDG too.&lt;/strong&gt; Lighter's contract held 91 million and Uniswap's v4 pool manager held 69 million.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trading and DEXs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;App&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Contracts&lt;/th&gt;
&lt;th&gt;Txs (wallets)&lt;/th&gt;
&lt;th&gt;Events&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developers.uniswap.org/docs/protocols/v4/deployments" rel="noopener noreferrer"&gt;Uniswap&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Swaps across v2, v3 and v4 pools, plus UniswapX&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://robinhoodchain.blockscout.com/address/0x8366a39cc670b4001a1121b8f6a443a643e40951" rel="noopener noreferrer"&gt;v4 pool manager&lt;/a&gt;, &lt;a href="https://robinhoodchain.blockscout.com/address/0x8876789976decbfcbbbe364623c63652db8c0904" rel="noopener noreferrer"&gt;Universal Router&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;2,552,298 (321,551)&lt;/td&gt;
&lt;td&gt;21,221,501&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.0x.org/changelog" rel="noopener noreferrer"&gt;0x&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Swap API used inside other apps and wallets&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x0000000000001ff3684f28c67538d4d072c22734" rel="noopener noreferrer"&gt;allowance holder&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;224,772 (34,944)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://help.1inch.com/en/articles/15618946-robinhood-chain" rel="noopener noreferrer"&gt;1inch&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Swap aggregator&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x5A705DE8982235a7fa45bB83dCaCf03a211389C7" rel="noopener noreferrer"&gt;Router&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;49,060 (12,980)&lt;/td&gt;
&lt;td&gt;2,899&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.robinhood.com/chain/lighter-domains/" rel="noopener noreferrer"&gt;Lighter&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Perpetuals and spot, on its own Lighter instance for Robinhood Chain&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x94bAB9693Ba2f6358507eFfcbd372b0660AFfF9d" rel="noopener noreferrer"&gt;Lighter contract&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;34,171 (3,969)&lt;/td&gt;
&lt;td&gt;64,241&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.rialto.xyz/developers/router-registries" rel="noopener noreferrer"&gt;Rialto&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Spot exchange quoted by market makers (PropAMM)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0xc94135b63772b91d79d0a2daab2a8801f32359bd" rel="noopener noreferrer"&gt;active router&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;1,664 (433)&lt;/td&gt;
&lt;td&gt;63,632&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.meridian.xyz/protocol-reference/contracts" rel="noopener noreferrer"&gt;Meridian&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Prediction markets and perpetuals&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://robinhoodchain.blockscout.com/address/0xE4cea507b19796362A5a28Fa7cb705A3F1866213" rel="noopener noreferrer"&gt;prediction escrow&lt;/a&gt;, &lt;a href="https://robinhoodchain.blockscout.com/address/0xD540F47F214dC7D6D244E62A6aE7e06B586Ef44A" rel="noopener noreferrer"&gt;perps&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;1,492 (15)&lt;/td&gt;
&lt;td&gt;5,339&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/EkuboProtocol/evm-contracts/blob/main/freelp.md" rel="noopener noreferrer"&gt;Ekubo&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;AMM with TWAMM orders and MEV capture&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x00000000000014aA86C5d3c41765bb24e11bd701" rel="noopener noreferrer"&gt;Core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;73,347&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/pancakeswap/pancake-developer/blob/master/docs/pages/contracts/infinity/resources/addresses.mdx" rel="noopener noreferrer"&gt;PancakeSwap&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Swaps on PancakeSwap Infinity and v3 pools&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://robinhoodchain.blockscout.com/address/0xeE04c68742e6Bf434bE8039580D2e89BBE55bc6f" rel="noopener noreferrer"&gt;CL pool manager&lt;/a&gt;, &lt;a href="https://robinhoodchain.blockscout.com/address/0x57fc55F719DF19B4b90A03F9D78E1177D002E504" rel="noopener noreferrer"&gt;Universal Router&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;38 (19)&lt;/td&gt;
&lt;td&gt;64,286&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Ekubo is reached through other contracts, which is why it shows events but no direct transactions. 0x's allowance holder emits no events of its own, and its swaps show up as token transfers instead.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.native.org/native-dev/resources/addresses" rel="noopener noreferrer"&gt;Native&lt;/a&gt; is live too, supplying RFQ liquidity for aggregators through its &lt;a href="https://robinhoodchain.blockscout.com/address/0x45F4D4AED68A04E9a48EED69E1C8b15d7875d25F" rel="noopener noreferrer"&gt;RFQPool&lt;/a&gt;. &lt;a href="https://docs.arcus.xyz/concepts/spot-router" rel="noopener noreferrer"&gt;Arcus&lt;/a&gt; also lists Robinhood Chain as a supported chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launchpads and NFTs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;App&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Contracts&lt;/th&gt;
&lt;th&gt;Txs (wallets)&lt;/th&gt;
&lt;th&gt;Events&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.ponsfamily.com/" rel="noopener noreferrer"&gt;Pons&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Token launchpad with a bonding curve&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://robinhoodchain.blockscout.com/address/0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e" rel="noopener noreferrer"&gt;V2 factory&lt;/a&gt;, &lt;a href="https://robinhoodchain.blockscout.com/address/0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9e" rel="noopener noreferrer"&gt;fee escrow&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;118,057 (55,370)&lt;/td&gt;
&lt;td&gt;2,237,675&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://opensea.io/blog/articles/robinhood-chain-is-live-on-opensea" rel="noopener noreferrer"&gt;OpenSea&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;NFT marketplace&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x0000000000000068F116a894984e2DB1123eB395" rel="noopener noreferrer"&gt;Seaport&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;121,560 (22,825)&lt;/td&gt;
&lt;td&gt;394,556&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/whetstoneresearch/doppler/blob/main/deployments/4663.md" rel="noopener noreferrer"&gt;Doppler&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Token launch protocol that other launchpads build on&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0xeb7c034704ef8dcd2d32324c1545f62fb4ad0862" rel="noopener noreferrer"&gt;Airlock&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;4,468 (2,562)&lt;/td&gt;
&lt;td&gt;19,073&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://blog.uniswap.org/pools-trade-a-new-way-to-launch-on-robinhood-chain" rel="noopener noreferrer"&gt;Pools&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Token launchpad built by Uniswap Labs&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://robinhoodchain.blockscout.com/address/0x0000FffFBE8efE702c8703aE3477FF5dE3d319C0" rel="noopener noreferrer"&gt;Liquidity Launcher&lt;/a&gt;, &lt;a href="https://robinhoodchain.blockscout.com/address/0x23f8209572b4a1C2AD88A42749E830791Fb027f1" rel="noopener noreferrer"&gt;instant launch strategy&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;825 (573)&lt;/td&gt;
&lt;td&gt;5,957&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.bankr.bot/token-launching/overview/" rel="noopener noreferrer"&gt;Bankr&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Token launches through Doppler, with BNKR onchain&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x178E54df3D091EE4D0B2534742eF9e3692b76526" rel="noopener noreferrer"&gt;BNKR&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;170 (81)&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.ponsfamily.com/" rel="noopener noreferrer"&gt;Pons&lt;/a&gt; was the busiest launchpad we measured. &lt;a href="https://whitepaper.virtuals.io/info-hub/important-links-and-resources/virtuals-protocol-contract-addresses" rel="noopener noreferrer"&gt;Virtuals&lt;/a&gt; runs its AI agent launchpad on Robinhood Chain too, through its &lt;a href="https://robinhoodchain.blockscout.com/address/0xd4cCBFA37e2f35611b3042e4096Ad7a3459Bd007" rel="noopener noreferrer"&gt;bonding curve&lt;/a&gt;. &lt;a href="https://hood.fun/whitepaper" rel="noopener noreferrer"&gt;hood.fun&lt;/a&gt;, a fair-launch memecoin protocol, is also deployed on Robinhood Chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lending, Yield and Stablecoins
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;App&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Contracts&lt;/th&gt;
&lt;th&gt;Txs (wallets)&lt;/th&gt;
&lt;th&gt;Events&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.paxos.com/guides/stablecoin/usdg/mainnet" rel="noopener noreferrer"&gt;USDG by Paxos&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Dollar stablecoin issued by Paxos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168" rel="noopener noreferrer"&gt;USDG token&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;442,570 (108,678)&lt;/td&gt;
&lt;td&gt;30,187,268&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.morpho.org/developers/contracts/addresses/" rel="noopener noreferrer"&gt;Morpho&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Lending markets and vaults&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x9D53d5E3bd5E8d4Cbfa6DB1ca238AEA02E651010" rel="noopener noreferrer"&gt;Morpho core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;1,953 (372)&lt;/td&gt;
&lt;td&gt;147,033&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.morpho.org/robinhood-chain/vault/0xBeEff033F34C046626B8D0A041844C5d1A5409dd/steakhouse-usdg" rel="noopener noreferrer"&gt;Steakhouse Financial&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Curates steakUSDG, a USDG vault on Morpho&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0xBeEff033F34C046626B8D0A041844C5d1A5409dd" rel="noopener noreferrer"&gt;steakUSDG&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;518 (62)&lt;/td&gt;
&lt;td&gt;197,919&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developers.merkl.xyz/resources/chains-and-contracts" rel="noopener noreferrer"&gt;Merkl&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Reward campaigns for other protocols&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x3Ef3D8bA38EBe18DB133cEc108f4D14CE00Dd9Ae" rel="noopener noreferrer"&gt;Distributor&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;1,649 (432)&lt;/td&gt;
&lt;td&gt;7,946&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;steakUSDG held 499,361,949 USDG when we called &lt;code&gt;totalAssets()&lt;/code&gt;, the largest of the vaults we checked.&lt;/p&gt;

&lt;p&gt;Also live on Robinhood Chain are &lt;a href="https://github.com/sparkdotfi/spark-address-registry/blob/master/src/Robinhood.sol" rel="noopener noreferrer"&gt;Spark&lt;/a&gt; with its USDG savings vault (&lt;a href="https://robinhoodchain.blockscout.com/address/0xde770c84FE66E063336b31737cFE9790f18c4087" rel="noopener noreferrer"&gt;spUSDG&lt;/a&gt;), &lt;a href="https://docs.maple.finance/integrate/crosschain/syrupusd-crosschain" rel="noopener noreferrer"&gt;Maple&lt;/a&gt; with &lt;a href="https://robinhoodchain.blockscout.com/address/0x40858070814a57FdF33a613ae84fE0a8b4a874f7" rel="noopener noreferrer"&gt;syrupUSDG&lt;/a&gt; and &lt;a href="https://robinhoodchain.blockscout.com/address/0xC6a4854eeB493224d5f9485E12Dd3A81f22EEE14" rel="noopener noreferrer"&gt;syrupUSDC&lt;/a&gt;, &lt;a href="https://etherfi.gitbook.io/etherfi/developers/contracts-and-integrations/deployed-contracts" rel="noopener noreferrer"&gt;ether.fi&lt;/a&gt; with &lt;a href="https://robinhoodchain.blockscout.com/address/0xA3D68b74bF0528fdD07263c60d6488749044914b" rel="noopener noreferrer"&gt;weETH&lt;/a&gt;, &lt;a href="https://docs.mellow.finance/core-vaults/core-deployments" rel="noopener noreferrer"&gt;Mellow&lt;/a&gt; with its &lt;a href="https://robinhoodchain.blockscout.com/address/0xCe939C136cFfd80747e61f45F17EFdcd4D4abD3B" rel="noopener noreferrer"&gt;rUSDG vault&lt;/a&gt; and &lt;a href="https://docs.midas.app/resources/smart-contracts-registry" rel="noopener noreferrer"&gt;Midas&lt;/a&gt; with mGLO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bridges, Messaging and Oracles
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;App&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Contracts&lt;/th&gt;
&lt;th&gt;Txs (wallets)&lt;/th&gt;
&lt;th&gt;Events&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://relay.link/" rel="noopener noreferrer"&gt;Relay&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Fast bridging and swaps across chains&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x4cd00e387622c35bddb9b4c962c136462338bc31" rel="noopener noreferrer"&gt;Depository&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;231,257 (101,360)&lt;/td&gt;
&lt;td&gt;1,362,053&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://li.fi/knowledge-hub/li.fi-is-live-on-robinhood-chain-from-day-one" rel="noopener noreferrer"&gt;LI.FI&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Bridge and swap aggregator, also behind Jumper&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0xB477751B76CF82d00a686A1232f5fCD772414Af3" rel="noopener noreferrer"&gt;Diamond&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;59,895 (17,227)&lt;/td&gt;
&lt;td&gt;455,393&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.across.to/chains-and-contracts" rel="noopener noreferrer"&gt;Across&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Intent-based bridge&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0xD29C85F15DF544bA632C9E25829fd29d767d7978" rel="noopener noreferrer"&gt;SpokePool&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;57,948 (6,915)&lt;/td&gt;
&lt;td&gt;134,699&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://docs.layerzero.network/v2/deployments/deployed-contracts" rel="noopener noreferrer"&gt;LayerZero&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Cross-chain messaging and OFT tokens&lt;/td&gt;
&lt;td&gt;&lt;a href="https://robinhoodchain.blockscout.com/address/0x6f475642a6e85809b1c36fa62763669b1b48dd5b" rel="noopener noreferrer"&gt;EndpointV2&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;764 (47)&lt;/td&gt;
&lt;td&gt;17,725&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://docs.chain.link/ccip/directory/mainnet/chain/robinhood-mainnet" rel="noopener noreferrer"&gt;Chainlink&lt;/a&gt; runs price feeds, CCIP and Data Streams on Robinhood Chain, with a &lt;a href="https://robinhoodchain.blockscout.com/address/0x06fC836cf9839B1cd891C440A0a45242DA6Ae1c9" rel="noopener noreferrer"&gt;CCIP Router&lt;/a&gt; and a &lt;a href="https://robinhoodchain.blockscout.com/address/0xcE73c8ad08CBDEaCa6078BF0627C8fe0a9a536E7" rel="noopener noreferrer"&gt;Data Streams verifier&lt;/a&gt;. Its ETH/USD feed at &lt;a href="https://robinhoodchain.blockscout.com/address/0x78F3556b67E17Df817D51Ef5a990cDaF09E8d3A9" rel="noopener noreferrer"&gt;&lt;code&gt;0x78F3…d3A9&lt;/code&gt;&lt;/a&gt; was updating normally when we read it. &lt;a href="https://github.com/hyperlane-xyz/hyperlane-registry/tree/main/chains/robinhood" rel="noopener noreferrer"&gt;Hyperlane&lt;/a&gt; (&lt;a href="https://robinhoodchain.blockscout.com/address/0x3a867fCfFeC2B790970eeBDC9023E75B0a172aa7" rel="noopener noreferrer"&gt;Mailbox&lt;/a&gt;), &lt;a href="https://docs.pyth.network/price-feeds/pro/contract-addresses" rel="noopener noreferrer"&gt;Pyth&lt;/a&gt; (Pyth Pro) and &lt;a href="https://docs.polymerlabs.org/docs/build/start/" rel="noopener noreferrer"&gt;Polymer&lt;/a&gt; also have contracts deployed on Robinhood Chain.&lt;/p&gt;

&lt;p&gt;For moving funds with Robinhood's own canonical bridge, see &lt;a href="https://docs.robinhood.com/chain/bridging/" rel="noopener noreferrer"&gt;Robinhood's bridging docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Can Build With This Data
&lt;/h2&gt;

&lt;p&gt;Each of these is one contract and a couple of events, which makes for a small indexer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Swap volume by pool.&lt;/strong&gt; Uniswap's v4 pool manager emits a &lt;code&gt;Swap&lt;/code&gt; event for every trade in every v4 pool, with the pool ID and both token amounts. Index it and you have volume by pool, by hour or by wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vault flows.&lt;/strong&gt; steakUSDG emits &lt;code&gt;Deposit&lt;/code&gt; and &lt;code&gt;Withdraw&lt;/code&gt; with the assets and shares involved, so you can chart money moving in and out of the largest vault on Robinhood Chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token launches.&lt;/strong&gt; The Pons factory emits &lt;code&gt;TokenLaunched&lt;/code&gt; for every new token and &lt;code&gt;PoolGraduated&lt;/code&gt; when a token graduates from its bonding curve into a pool. That's a live feed of launches and which ones make it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bridge traffic.&lt;/strong&gt; Across's SpokePool emits &lt;code&gt;FundsDeposited&lt;/code&gt; when funds leave Robinhood Chain and &lt;code&gt;FilledRelay&lt;/code&gt; when they arrive. Together they show what's moving where.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All four are in one tested indexer you can clone from &lt;a href="https://github.com/enviodev/robinhood-ecosystem-indexer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. The &lt;a href="https://docs.envio.dev/blog/robinhood-chain-ecosystem#replicate-this-with-your-own-agent" rel="noopener noreferrer"&gt;agent prompt&lt;/a&gt; below builds your own version using Envio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring Any App Yourself
&lt;/h2&gt;

&lt;p&gt;New to Envio?&lt;/p&gt;

&lt;p&gt;Grab a free &lt;a href="https://envio.dev/app/api-tokens" rel="noopener noreferrer"&gt;Envio API token&lt;/a&gt; first. &lt;a href="https://docs.envio.dev/docs/HyperIndex/quickstart-with-ai" rel="noopener noreferrer"&gt;Quickstart with AI&lt;/a&gt; covers the rest of the setup.&lt;/p&gt;

&lt;p&gt;One script produced every activity count above. Give it an app's contracts and a block range, and it counts the direct transactions, the unique wallets behind them and the events those contracts emitted. It reads your token from &lt;code&gt;ENVIO_API_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Show the script
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;collectionsTOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ENVIO_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://robinhood.hypersync.xyz/query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="c1"&gt;# Morpho on Robinhood Chain, from docs.morpho.orgCONTRACTS = ["0x9D53d5E3bd5E8d4Cbfa6DB1ca238AEA02E651010"]START, END = 65_779_486, 71_782_334 # one week of blockswanted = {a.lower() for a in CONTRACTS}txs, events, senders = 0, 0, set()block = STARTwhile block &amp;lt; END: d = query({ "from_block": block, "to_block": END, "transactions": [{"to": CONTRACTS}], # calls made straight to it "logs": [{"address": CONTRACTS}], # events it emitted "field_selection": {"transaction": ["from", "to"], "log": ["address"]}, "join_mode": "JoinNothing", # don't pull extra rows }) for batch in d.get("data", []): for tx in batch.get("transactions", []): if (tx.get("to") or "").lower() in wanted: txs += 1 senders.add(tx["from"]) events += len(batch.get("logs", [])) nxt = d.get("next_block") if not nxt or nxt &amp;lt;= block: break block = nxtprint(f"{txs:,} transactions from {len(senders):,} senders, {events:,} events")
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For Morpho over our week it printed this, in about 30 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,953 transactions from 372 senders, 147,033 events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Swap in any contracts from the tables above. &lt;code&gt;join_mode&lt;/code&gt; matters for busy contracts. Without it, HyperSync also returns the transaction behind every event, which for USDG means pulling millions of extra rows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replicate This With Your Own Agent
&lt;/h2&gt;

&lt;p&gt;To get an app's events into a database you can query, build a &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt; indexer for it. The prompt below hands that job to a coding agent.&lt;/p&gt;

&lt;p&gt;Give the agent our current docs first, so it works from the latest syntax instead of whatever it remembers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http envio-docs &lt;span class="se"&gt;\ &lt;/span&gt;https://docs.envio.dev/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Agents with shell access can use &lt;code&gt;envio tools search-docs&lt;/code&gt; instead. Both are covered on the &lt;a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" rel="noopener noreferrer"&gt;MCP server page&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Show the full prompt
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build me an Envio HyperIndex indexer for one app on Robinhood Chain.The app is: &amp;lt;APP NAME&amp;gt;Its contract on Robinhood Chain is: &amp;lt;CONTRACT ADDRESS&amp;gt;Before writing any code, read the current Envio docs rather than working frommemory. If you have the envio-docs MCP server, use docs_search and docs_fetch.Otherwise run `envio tools search-docs &amp;lt;query&amp;gt;` and `envio tools fetch-docs &amp;lt;url&amp;gt;`.Read the configuration file, event handlers and testing pages first.Robinhood Chain is chain ID 4663 and HyperSync supports it, so the config needsno rpc block.1. Check the address against the app's own docs before using it. Don't trust an address you haven't confirmed from the project itself.2. Scaffold from the verified ABI on the block explorer: envio init contract-import explorer -b robinhood -c &amp;lt;CONTRACT ADDRESS&amp;gt; \ --single-contract --all-events -n &amp;lt;project-name&amp;gt; -l typescript Non-interactive runs need ENVIO_API_TOKEN set.3. If the import fails with "All events have unsupported parameter types", the ABI uses types the generator can't map (Morpho's core contract does this). Write config.yaml and schema.graphql by hand for the events you need instead.4. If the contract is a proxy, check that the imported ABI has the events you expect. If it doesn't, take the implementation's ABI from the explorer.5. The project needs Node.js 22 or newer. On Node 20 the tests fail with "Promises.glob is not a function".6. Run `pnpm test` and make it pass, then `pnpm dev` and let it sync.Report back:- the events you indexed and why- the start block you used and how you picked it- how many of each entity the indexer wrote, with one example row- anything that didn't match these instructionsGive the real numbers you got. Don't assume anything in the blog still holds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Apps Are Live on Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;These are the apps we confirmed live on Robinhood Chain mainnet (chain ID &lt;code&gt;4663&lt;/code&gt;), each one checked against its own docs and against its contracts onchain. They include DEXs and aggregators (Uniswap, 0x, 1inch, PancakeSwap, Ekubo, Native, Rialto), perpetuals and prediction markets (Lighter, Meridian), launchpads (Pons, Pools, Doppler, Virtuals, Bankr, hood.fun), OpenSea, lending and yield (Morpho, Steakhouse, Spark, Maple, Merkl, Mellow, ether.fi, Midas), the USDG stablecoin from Paxos, and bridges, messaging and oracles (Relay, LI.FI, Across, LayerZero, Chainlink, Hyperlane, Pyth, Polymer). Robinhood's own &lt;a href="https://robinhood.com/us/en/chain/ecosystem" rel="noopener noreferrer"&gt;ecosystem page&lt;/a&gt; also lists infrastructure and data providers that don't run their own contracts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is the Most Used App on Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;Uniswap, by a wide margin. In the week we measured, its v4 PoolManager and UniversalRouter received 2,552,298 transactions from 321,551 unique wallets and emitted 21,221,501 events. Next by unique wallets were the USDG stablecoin (108,678), the Relay bridge (101,360) and the Pons launchpad (55,370). These count transactions and wallets rather than trading volume, and wallet counts include bots.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Can I Lend or Earn Yield on Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.morpho.org/developers/contracts/addresses/" rel="noopener noreferrer"&gt;Morpho&lt;/a&gt; is the main lending protocol we found live on Robinhood Chain, and most of the yield products we found sit on top of USDG. The largest is Steakhouse Financial's steakUSDG vault on Morpho, which held 499,361,949 USDG when we read it onchain. Spark (spUSDG), Maple (syrupUSDG and syrupUSDC), Mellow (rUSDG), ether.fi (weETH) and Midas (mGLO) also have contracts deployed, and Merkl runs reward campaigns for several of them. This is a list of what's deployed, not investment advice.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Bridge to Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;The trustless route is the canonical Arbitrum bridge, which Robinhood documents on its &lt;a href="https://docs.robinhood.com/chain/bridging/" rel="noopener noreferrer"&gt;bridging page&lt;/a&gt;. Deposits take around 10 minutes and withdrawals go through the 7-day challenge period. For faster transfers, Relay, LI.FI (and Jumper, which runs on it), Across, LayerZero, Chainlink CCIP and Hyperlane are all live on Robinhood Chain. Relay was the busiest in our week, with 231,257 transactions from 101,360 wallets to its depository contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Can I Check That a Project Is Really Deployed on Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;Get the contract address from the project's own docs, not from a roundup article, then confirm there's code at that address with &lt;code&gt;eth_getCode&lt;/code&gt; on any Robinhood Chain RPC. Code alone doesn't prove the contract is used, so also count its transactions and events over a recent window. The script in &lt;a href="https://docs.envio.dev/blog/robinhood-chain-ecosystem#measuring-any-app-yourself" rel="noopener noreferrer"&gt;Measuring Any App Yourself&lt;/a&gt; does that with HyperSync in one pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Track a Robinhood Chain App's Activity in Real Time?
&lt;/h3&gt;

&lt;p&gt;Point a &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt; indexer at the app's contracts. It backfills the history through HyperSync, then enters realtime mode and keeps writing new events as Robinhood Chain produces blocks, roughly every 0.1 seconds. If you only need what happens from now on, set &lt;code&gt;start_block: latest&lt;/code&gt; in &lt;code&gt;config.yaml&lt;/code&gt; and the indexer starts from the chain's current head instead of the full history, as the &lt;a href="https://docs.envio.dev/docs/HyperIndex/configuration-file#start-block" rel="noopener noreferrer"&gt;configuration docs&lt;/a&gt; describe. For lower head latency you can also add your own WebSocket RPC for realtime use, covered under &lt;a href="https://docs.envio.dev/docs/HyperIndex/configuration-file#websocket-height-streaming" rel="noopener noreferrer"&gt;WebSocket height streaming&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I Index Several Robinhood Chain Apps in One Indexer?
&lt;/h3&gt;

&lt;p&gt;Yes. List each app's contract under &lt;a href="https://docs.envio.dev/docs/HyperIndex/configuration-file#contracts-definition" rel="noopener noreferrer"&gt;&lt;code&gt;contracts&lt;/code&gt;&lt;/a&gt; in one &lt;code&gt;config.yaml&lt;/code&gt;, give each its own events and handlers, and one indexer serves all of them from the same GraphQL API. We tested it with Doppler's Airlock and the Pons launch factory in a single indexer. Over about 700 blocks of real Robinhood Chain data, it picked up one Doppler &lt;code&gt;Create&lt;/code&gt; event and three Pons &lt;code&gt;TokenLaunched&lt;/code&gt; events. That's the setup for a dashboard that compares launchpads, or DEXs, side by side.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Index an App's Data on Robinhood Chain?
&lt;/h3&gt;

&lt;p&gt;Use &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt;. HyperSync supports Robinhood Chain (chain ID &lt;code&gt;4663&lt;/code&gt;), so an indexer needs no RPC endpoint and backfills from any start block. For verified contracts, &lt;code&gt;envio init contract-import explorer -b robinhood -c &amp;lt;address&amp;gt;&lt;/code&gt; scaffolds a project from the explorer's ABI. We tested it on Doppler's Airlock contract and the generated tests passed. If you'd rather not do it by hand, the &lt;a href="https://docs.envio.dev/blog/robinhood-chain-ecosystem#replicate-this-with-your-own-agent" rel="noopener noreferrer"&gt;agent prompt&lt;/a&gt; above hands the job to a coding agent. For a full worked example, see our &lt;a href="https://docs.envio.dev/blog/index-robinhood-chain-data" rel="noopener noreferrer"&gt;tokenized asset indexer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;Envio is a real-time multichain blockchain indexer that turns onchain events into a queryable GraphQL API. Robinhood Chain has first-class support, so HyperSync, HyperRPC and HyperIndex all work on it out of the box. &lt;a href="https://envio.dev/chains/robinhood" rel="noopener noreferrer"&gt;Start indexing Robinhood Chain&lt;/a&gt;, deploy on Envio Cloud or self-host, and if you're building on Robinhood Chain, come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+5mI61oZibEM5OGQ8" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorials</category>
    </item>
    <item>
      <title>How to Index USDC Transfers on Arc</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 24 Sep 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/envio/how-to-index-usdc-transfers-on-arc-1jai</link>
      <guid>https://dev.to/envio/how-to-index-usdc-transfers-on-arc-1jai</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8m5874h5b6fw3s6rx2db.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8m5874h5b6fw3s6rx2db.png" alt="How to Index USDC Transfers on Arc" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;USDC is Arc's gas token. Every USDC transfer is logged as a standard &lt;code&gt;Transfer&lt;/code&gt; from the system address &lt;code&gt;0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE&lt;/code&gt;, in &lt;strong&gt;18 decimals&lt;/strong&gt;. The USDC contract at &lt;code&gt;0x3600…0000&lt;/code&gt; logs a second copy of ERC-20 calls, in 6 decimals.&lt;/li&gt;
&lt;li&gt;Index the system address and nothing else. In a 100,000 block sample, indexing both would have counted &lt;strong&gt;48.3%&lt;/strong&gt; of transfers twice, and indexing only the contract would have missed &lt;strong&gt;51.7%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Arc is chain ID &lt;code&gt;5042&lt;/code&gt;, on &lt;a href="https://docs.envio.dev/docs/HyperSync/overview" rel="noopener noreferrer"&gt;HyperSync&lt;/a&gt; at &lt;code&gt;https://arc.hypersync.xyz&lt;/code&gt;. Endpoints and testnet details are on our &lt;a href="https://envio.dev/chains/arc" rel="noopener noreferrer"&gt;Arc chain page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The indexer below is three files and matched HyperSync's count exactly. Copy it, clone it from &lt;a href="https://github.com/enviodev/arc-usdc-indexer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, or &lt;a href="https://docs.envio.dev/blog/index-arc-usdc-transfers#build-it-with-your-coding-agent" rel="noopener noreferrer"&gt;hand the build to your coding agent&lt;/a&gt; with our prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a 14 hour sample of Arc blocks, 906,915 USDC transfers were logged, and 469,254 of them never touched the USDC contract. They were native movements, like a plain send from one wallet to another, and on Arc those get a standard &lt;code&gt;Transfer&lt;/code&gt; log from a system address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.arc.io/" rel="noopener noreferrer"&gt;Arc&lt;/a&gt; is an open Layer 1 blockchain that uses USDC as its gas token, so USDC is the native coin and an ERC-20 at the same time. It implements &lt;a href="https://eips.ethereum.org/EIPS/eip-7708" rel="noopener noreferrer"&gt;EIP-7708&lt;/a&gt;, which logs native movements the same way as token transfers. On a standard EVM chain, a plain native send leaves no log at all. The one thing an indexer has to get right is which stream to count. This guide covers that, then builds a small indexer using Envio's &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt;, the base for payment tracking, treasury reconciliation or any USDC dashboard on Arc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to Arc
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chain ID&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;5042&lt;/code&gt; (mainnet), &lt;code&gt;5042002&lt;/code&gt; (testnet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gas token&lt;/td&gt;
&lt;td&gt;USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyperSync (mainnet)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://arc.hypersync.xyz&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyperSync (testnet)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://arc-testnet.hypersync.xyz&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyperRPC (mainnet, read only)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://arc.rpc.hypersync.xyz&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HyperRPC (testnet, read only)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://arc-testnet.rpc.hypersync.xyz&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public RPC (mainnet)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://rpc.mainnet.arc.io&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public RPC (testnet)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://rpc.testnet.arc.io&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explorer&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://explorer.arc.io/" rel="noopener noreferrer"&gt;explorer.arc.io&lt;/a&gt; (mainnet), &lt;a href="https://explorer.testnet.arc.io/" rel="noopener noreferrer"&gt;explorer.testnet.arc.io&lt;/a&gt; (testnet)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Arc and Arc Testnet both have first-class support on Envio, so HyperSync serves their data and HyperIndex doesn't need an RPC to index them. The public RPCs and explorers come from Arc's &lt;a href="https://docs.arc.io/arc/references/connect-to-arc" rel="noopener noreferrer"&gt;connection docs&lt;/a&gt;, and more details are on our &lt;a href="https://envio.dev/chains/arc" rel="noopener noreferrer"&gt;Arc&lt;/a&gt; and &lt;a href="https://envio.dev/chains/arc-testnet" rel="noopener noreferrer"&gt;Arc Testnet&lt;/a&gt; chain pages.&lt;/p&gt;

&lt;p&gt;Blocks come about every half second. Order by block number rather than timestamp, because several blocks can share one. Finality is deterministic, so there are no reorgs to handle.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Arc Logs USDC Transfers
&lt;/h2&gt;

&lt;p&gt;USDC has one balance on Arc and two ways to move it. Arc's &lt;a href="https://docs.arc.io/arc/references/usdc-system-events" rel="noopener noreferrer"&gt;USDC system events reference&lt;/a&gt; covers both.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stream&lt;/th&gt;
&lt;th&gt;Emitter&lt;/th&gt;
&lt;th&gt;Decimals&lt;/th&gt;
&lt;th&gt;What it covers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native USDC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0xffff…fFfE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Every USDC transfer, including native sends, mints and burns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ERC-20 USDC&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x3600…0000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Only calls made through the ERC-20 interface&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The system address isn't a contract, just the address Arc's EIP-7708 logs come from. An ERC-20 &lt;code&gt;transfer()&lt;/code&gt; on USDC produces a log from both addresses, while a plain native send produces only the system one.&lt;/p&gt;

&lt;p&gt;Here's what we counted over blocks 22,477,236 to 22,577,235.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What we counted&lt;/th&gt;
&lt;th&gt;Logs&lt;/th&gt;
&lt;th&gt;Share of system logs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Transfer&lt;/code&gt; from the system address&lt;/td&gt;
&lt;td&gt;906,915&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Also logged by the USDC contract&lt;/td&gt;
&lt;td&gt;437,661&lt;/td&gt;
&lt;td&gt;48.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Only logged by the system address&lt;/td&gt;
&lt;td&gt;469,254&lt;/td&gt;
&lt;td&gt;51.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Matched on transaction hash, sender, receiver and value, with the 6 decimal value scaled up by 10¹². Read through HyperSync.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The USDC contract logged 446,270 transfers in the same window. All but 8,609 matched a system log, and every one of those 8,609 was either a zero value transfer (4,808) or a transfer to yourself (3,801). No USDC moved in any of them, and Arc's docs say the system address skips both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;21.7%&lt;/strong&gt; of the system transfers, 197,025 of them, carried digits past the sixth decimal place, which a 6 decimal view can't represent. The window also had 1,013 mints and 446 burns, logged as transfers from and to the zero address.&lt;/p&gt;

&lt;p&gt;For a USDC total, index the system address and nothing else. If you need to know which transfers went through the ERC-20 interface, join the contract's logs the same way we matched them above, but don't add them to the count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build It With Your Coding Agent
&lt;/h2&gt;

&lt;p&gt;The quickest way to build this is to hand it to a coding agent. We wrote the prompt below from the finished indexer, so it already knows the traps. Give the agent our current docs first so it works from live syntax, then paste the prompt. If you'd rather build it by hand, the &lt;a href="https://docs.envio.dev/blog/index-arc-usdc-transfers#building-the-arc-usdc-indexer" rel="noopener noreferrer"&gt;steps are below&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http envio-docs https://docs.envio.dev/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Cursor and VS Code use the same endpoint, and an agent with shell access can use &lt;code&gt;envio tools search-docs&lt;/code&gt; instead. Both are on the &lt;a href="https://docs.envio.dev/docs/HyperIndex/mcp-server" rel="noopener noreferrer"&gt;MCP server page&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Show the full prompt
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build me an Envio HyperIndex indexer that counts every USDC transfer on Arcexactly once.Before writing code, read the current HyperIndex docs rather than working frommemory. Use the envio-docs MCP server (docs_search, docs_fetch) if you have it,otherwise `envio tools search-docs &amp;lt;query&amp;gt;`. Look up the configuration file,schema and event handlers.THE CHAINArc is chain ID 5042. HyperSync is the default data source, so the config needsno rpc block. USDC is Arc's native gas token.WHICH ADDRESS TO INDEXEvery USDC transfer on Arc, including native sends, mints and burns, is loggedas a standard Transfer(address indexed from, address indexed to, uint256 value)from the system address 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE, with valuesin 18 decimals. Put that address in config.yaml as if it were a contract.Do not also index Transfer from the USDC ERC-20 contract at0x3600000000000000000000000000000000000000. It logs a second copy of everyERC-20 interface transfer, in 6 decimals, so adding it double counts. Never mixthe 6 and 18 decimal values.Mints are transfers from the zero address and burns are transfers to it. Thesystem address never logs zero value transfers or transfers to yourself.WHAT TO STOREPer account, net USDC movement across the indexed window (call it net movement,not balance, because anything held before the start block is invisible), plustransfers in and transfers out. The zero address is not an account, so it getsno row. Per UTC day, transfer count, volume, and the number of mints and burns.SETUP mkdir arc-usdc-indexer &amp;amp;&amp;amp; cd arc-usdc-indexer pnpm init pnpm add envio --allow-build=esbuild pnpm add -D typescript @types/node npm pkg set type=moduleHandlers auto-load from src/handlers/. Put an Envio API token fromhttps://envio.dev/app/api-tokens in .env as ENVIO_API_TOKEN and keep .env out ofgit. For a quick first run, set start_block about 100,000 blocks below thecurrent height from https://arc.hypersync.xyz/height. Run `pnpm envio codegen`then `pnpm envio dev`, with Docker running.TRAPS- Use Node.js 22 or newer. Older versions fail to auto-load handlers.- Neither codegen nor dev typechecks. Add a tsconfig.json that includes src and the generated envio-env.d.ts, and run `pnpm exec tsc --noEmit`.- If `envio dev` says the config is incompatible with existing indexer data, the local Postgres holds another indexer. Don't reset it. Run with ENVIO_PG_SCHEMA and ENVIO_INDEXER_PORT set to new values instead.- If you sort or bucket events, use block number, not timestamp. Arc blocks are about half a second apart and can share a timestamp.- On Arc Testnet (5042002), native USDC history from before the Zero5 hard fork uses NativeCoin* events from 0x1800000000000000000000000000000000000000 instead. Mainnet has used the system Transfer log since genesis.REPORT BACKProgress is in the envio_chains table (progress_block, source_block,events_processed). Report the exact block range you indexed, the number ofTransfer events processed, the number of accounts, and mints and burns. Givethe numbers you actually got. Don't assume ours still hold.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Arc USDC Indexer
&lt;/h2&gt;

&lt;p&gt;New to Envio?&lt;/p&gt;

&lt;p&gt;Check the &lt;a href="https://docs.envio.dev/docs/HyperIndex/quickstart#prerequisites" rel="noopener noreferrer"&gt;prerequisites&lt;/a&gt; before running anything below.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/enviodev/arc-usdc-indexer" rel="noopener noreferrer"&gt;Arc USDC indexer&lt;/a&gt; is three files. &lt;code&gt;config.yaml&lt;/code&gt; names the chain and the event, &lt;code&gt;schema.graphql&lt;/code&gt; defines what gets stored, and one handler file does the work. &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt; reads the logs from HyperSync and gives you a GraphQL API over the result. You'll also need a free &lt;a href="https://envio.dev/app/api-tokens" rel="noopener noreferrer"&gt;Envio API token&lt;/a&gt; in a &lt;code&gt;.env&lt;/code&gt; file as &lt;code&gt;ENVIO_API_TOKEN&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;arc-usdc-indexer &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;arc-usdc-indexerpnpm initpnpm add envio &lt;span class="nt"&gt;--allow-build&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esbuildpnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/nodenpm pkg &lt;span class="nb"&gt;set type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  config.yaml
&lt;/h3&gt;

&lt;p&gt;The system address goes in as if it were a contract. Arc is on HyperSync, so there's no &lt;code&gt;rpc&lt;/code&gt; block to configure. Start from a recent block so a first run is quick. &lt;code&gt;curl https://arc.hypersync.xyz/height&lt;/code&gt; returns the current height, and 100,000 blocks is about 14 hours of chain time. The config below uses the first block of our sample. Set &lt;code&gt;start_block&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt; for everything since genesis, and budget for a much longer sync.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# yaml-language-server: $schema=./node_modules/envio/evm.schema.jsonname: arc-usdc-indexerdescription: Every USDC transfer on Arc (chain 5042)contracts: # Arc's system address logs a standard Transfer for every USDC movement, # with values in 18 decimals. It is not a deployed contract. - name: NativeUSDC events: - event: "Transfer(address indexed from, address indexed to, uint256 value)"chains: - id: 5042 # Arc. HyperSync is the default data source. start_block: 22477236 # the first block of our sample. Use a recent block. contracts: - name: NativeUSDC address: "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  schema.graphql
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://docs.envio.dev/docs/HyperIndex/schema" rel="noopener noreferrer"&gt;schema&lt;/a&gt; keeps totals per account and per day. &lt;code&gt;netChange&lt;/code&gt; is movement across the indexed window, not a balance, because anything held before the start block is invisible to the indexer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# account address # Net USDC movement across the indexed window, 18 decimals. Not a balance. netChange: BigInt! transfersIn: Int! transfersOut: Int!}type DailyStat { id: ID! # day index transfers: Int! volume: BigInt! mints: Int! burns: Int!}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Handler
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://docs.envio.dev/docs/HyperIndex/event-handlers" rel="noopener noreferrer"&gt;handler&lt;/a&gt; goes in &lt;code&gt;src/handlers/NativeUSDC.ts&lt;/code&gt;. Values stay in 18 decimals, so divide by 10¹⁸ when you display them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;indexer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;envio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ZERO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x0000000000000000000000000000000000000000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;86&lt;/span&gt;&lt;span class="nx"&gt;_400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;indexer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NativeUSDC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;day&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// The system emitter skips self transfers, so from and to always differ. // Mints come from the zero address and burns go to it. const [sender, receiver, stat] = await Promise.all([from === ZERO ? undefined : context.Account.get(from), to === ZERO ? undefined : context.Account.get(to), context.DailyStat.getOrCreate({ id: day, transfers: 0, volume: 0n, mints: 0, burns: 0, }),]); if (from !== ZERO) { context.Account.set({ id: from, netChange: (sender?.netChange ?? 0n) - value, transfersIn: sender?.transfersIn ?? 0, transfersOut: (sender?.transfersOut ?? 0) + 1, }); } if (to !== ZERO) { context.Account.set({ id: to, netChange: (receiver?.netChange ?? 0n) + value, transfersIn: (receiver?.transfersIn ?? 0) + 1, transfersOut: receiver?.transfersOut ?? 0, }); } context.DailyStat.set({ ...stat, transfers: stat.transfers + 1, volume: stat.volume + value, mints: stat.mints + (from === ZERO ? 1 : 0), burns: stat.burns + (to === ZERO ? 1 : 0), }); },);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Running It
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm envio codegenpnpm envio dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;envio dev&lt;/code&gt; starts Postgres and Hasura in Docker and begins syncing. Over the same 100,000 blocks, our run processed &lt;strong&gt;906,915 events&lt;/strong&gt; , exactly the number HyperSync returned, across 106,129 accounts.&lt;/p&gt;

&lt;p&gt;Once it's running, &lt;code&gt;http://localhost:8080&lt;/code&gt; opens a &lt;a href="https://docs.envio.dev/docs/HyperIndex/navigating-hasura" rel="noopener noreferrer"&gt;Hasura console&lt;/a&gt;, and the local admin secret is &lt;code&gt;testing&lt;/code&gt;. This query returns the accounts with the largest net inflow over the window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TopReceivers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;netChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;desc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;netChange&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;transfersIn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;transfersOut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The finished indexer is on GitHub at &lt;a href="https://github.com/enviodev/arc-usdc-indexer" rel="noopener noreferrer"&gt;enviodev/arc-usdc-indexer&lt;/a&gt;, along with the script behind the numbers above. For stablecoins on other chains, see &lt;a href="https://docs.envio.dev/blog/index-solana-stablecoin-transfers" rel="noopener noreferrer"&gt;how to index and track stablecoin transfers on Solana&lt;/a&gt; and &lt;a href="https://docs.envio.dev/blog/how-to-build-rwa-dashboard" rel="noopener noreferrer"&gt;how to build an open source RWA stablecoin dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you want it online, push the project to GitHub and deploy it on &lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;Envio Cloud&lt;/a&gt;, which runs the database, the GraphQL API and the syncing for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Which Address Should I Index for USDC Transfers on Arc?
&lt;/h3&gt;

&lt;p&gt;Index &lt;code&gt;Transfer&lt;/code&gt; from the system address &lt;code&gt;0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE&lt;/code&gt;. It logs every USDC transfer, including native sends, mints and burns, in 18 decimals. The USDC contract at &lt;code&gt;0x3600…0000&lt;/code&gt; only logs ERC-20 interface calls, and those also appear in the system stream. In our 100,000 block sample, indexing only the contract missed 51.7% of transfers, and indexing both double counted 48.3%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does USDC on Arc Have Both 18 and 6 Decimals?
&lt;/h3&gt;

&lt;p&gt;USDC on Arc has one balance with two interfaces. The native interface, used for gas and plain value transfers, has 18 decimals. The ERC-20 interface at &lt;code&gt;0x3600000000000000000000000000000000000000&lt;/code&gt; has 6 decimals and is there for things like &lt;code&gt;approve&lt;/code&gt; and &lt;code&gt;transferFrom&lt;/code&gt;. Raw values differ by 10¹², and the 6 decimal view truncates any digits past the sixth decimal place, which applied to 21.7% of the transfers in our sample.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Don't Gas Fees Show Up as USDC Transfers on Arc?
&lt;/h3&gt;

&lt;p&gt;Gas on Arc is paid in USDC, but gas deductions don't emit a &lt;code&gt;Transfer&lt;/code&gt; log, so an indexer built on transfer events won't see them. Arc's &lt;a href="https://docs.arc.io/arc/references/usdc-system-events" rel="noopener noreferrer"&gt;USDC system events page&lt;/a&gt; says to work out gas from the transaction receipt as &lt;code&gt;gasUsed × effectiveGasPrice&lt;/code&gt;. If you're reconciling an account's USDC, take gas from receipts separately from the transfers you index.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Match a Payment Memo to a USDC Transfer on Arc?
&lt;/h3&gt;

&lt;p&gt;Arc's &lt;a href="https://docs.arc.io/arc/concepts/transaction-memos" rel="noopener noreferrer"&gt;Memo contract&lt;/a&gt; at &lt;code&gt;0x5294E9927c3306DcBaDb03fe70b92e01cCede505&lt;/code&gt; lets a wallet attach a reference, like an invoice ID, to a call such as a USDC transfer. It emits &lt;code&gt;Memo(address indexed sender, address indexed target, bytes32 callDataHash, bytes32 indexed memoId, bytes memo, uint256 memoIndex)&lt;/code&gt; in the same transaction. Add the contract to &lt;code&gt;config.yaml&lt;/code&gt; with that event, list &lt;code&gt;hash&lt;/code&gt; in the &lt;a href="https://docs.envio.dev/docs/HyperIndex/event-handlers#selecting-block-and-transaction-fields" rel="noopener noreferrer"&gt;&lt;code&gt;fields&lt;/code&gt; option&lt;/a&gt; of both the Memo and &lt;code&gt;NativeUSDC&lt;/code&gt; handlers to read &lt;code&gt;event.transaction.hash&lt;/code&gt;, and match memos to transfers on transaction hash. If a transaction holds more than one transfer, compare &lt;code&gt;callDataHash&lt;/code&gt; with the hash of the transfer calldata, as Arc's memo docs suggest. Match on the system &lt;code&gt;Transfer&lt;/code&gt; log rather than the memo alone, since a memo can also wrap a call that moves no USDC, like a zero value transfer.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Index USDC on Arc Testnet?
&lt;/h3&gt;

&lt;p&gt;Change the chain ID to &lt;code&gt;5042002&lt;/code&gt; and set a testnet &lt;code&gt;start_block&lt;/code&gt; from &lt;code&gt;https://arc-testnet.hypersync.xyz/height&lt;/code&gt;. Arc Testnet logs USDC transfers from the same system address. Before the Zero5 hard fork, testnet logged native USDC movements as &lt;code&gt;NativeCoin*&lt;/code&gt; events from &lt;code&gt;0x1800000000000000000000000000000000000000&lt;/code&gt; instead, so a backfill across that point needs both. Arc's &lt;a href="https://docs.arc.io/arc/references/usdc-system-events" rel="noopener noreferrer"&gt;USDC system events page&lt;/a&gt; has the event signatures, and testnet USDC comes from &lt;a href="https://faucet.circle.com/" rel="noopener noreferrer"&gt;Circle's faucet&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do I Index EURC or Other Tokens on Arc?
&lt;/h3&gt;

&lt;p&gt;The same way as on any EVM chain. EURC at &lt;code&gt;0xbEf5f6d51CB62b58e6A8f77868681825C6fe21c1&lt;/code&gt; and other ERC-20 tokens on Arc emit &lt;code&gt;Transfer&lt;/code&gt; from their own contract addresses, so you add each contract to &lt;code&gt;config.yaml&lt;/code&gt; as usual. Arc's &lt;a href="https://docs.arc.io/arc/references/contract-addresses" rel="noopener noreferrer"&gt;contract addresses page&lt;/a&gt; lists the official tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;Envio is a real-time multichain blockchain indexer that turns onchain events into a queryable GraphQL API. Arc has first-class support, so HyperSync, HyperRPC and HyperIndex all work on it out of the box. &lt;a href="https://envio.dev/chains/arc" rel="noopener noreferrer"&gt;Start indexing Arc&lt;/a&gt;, deploy on Envio Cloud or self-host, and if you're building on Arc, come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+5mI61oZibEM5OGQ8" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorials</category>
    </item>
    <item>
      <title>Indexing and Reorgs</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:42:41 +0000</pubDate>
      <link>https://dev.to/envio/indexing-and-reorgs-432d</link>
      <guid>https://dev.to/envio/indexing-and-reorgs-432d</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzk9knyg0q666r0pglaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhzk9knyg0q666r0pglaz.png" alt="Indexing and Reorgs" width="799" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Author: &lt;a href="https://x.com/DenhamPreen" rel="noopener noreferrer"&gt;Denham Preen&lt;/a&gt;, Co-Founder at Envio&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chain reorganizations (reorgs) affect any indexer processing data near the chain head. Stateful indexers (those using updates and deletes) require rollback logic. Stateless ones (create-only) just need orphaned entities deleted.&lt;/li&gt;
&lt;li&gt;Multichain indexers face additional complexity: a reorg on one chain may require rolling back state that was affected by events from other chains.&lt;/li&gt;
&lt;li&gt;Envio handles reorg detection and rollback automatically, so developers do not need to implement rollback logic themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we unpack the implications of chain reorganizations on consuming and aggregating onchain data, considerations in a multichain environment, and how to design for them.&lt;/p&gt;

&lt;p&gt;We assume you have a strong understanding of what a chain reorganization is. If you want a refresher, skip to the &lt;a href="https://docs.envio.dev/blog/indexing-and-reorgs#what-are-chain-reorgs" rel="noopener noreferrer"&gt;bottom&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Handling reorgs is only important if you are indexing at the head, or handling data within the range of the head and the network's finalized block.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chain reorgs and independent data
&lt;/h2&gt;

&lt;p&gt;Independent data is data that &lt;strong&gt;does not require the previous state in order to process the current state&lt;/strong&gt;. In an indexer, this means only "create" operations. If the only CRUD operations your handlers perform are writing entities, your indexer is handling stateless data, and handling reorgs is straightforward: delete all entities from orphaned blocks and re-ingest them with the canonical block's data. This is possible because stateless data allows for parallel processing.&lt;/p&gt;

&lt;p&gt;In practice, we usually need to perform some aggregation on data to turn it into meaningful information. In that context, our indexer is dealing with stateful data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Side tangent: Stateless indexing can be handled incredibly fast by parallelization, such as indexers like &lt;a href="https://flair.dev" rel="noopener noreferrer"&gt;Flair&lt;/a&gt; that achieve impressive speed with only RPC.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chain reorgs and stateful data
&lt;/h2&gt;

&lt;p&gt;Stateful data is data that &lt;strong&gt;depends on the previous state&lt;/strong&gt; (think update and delete operations) in order to process the current state. When handling stateful data, your indexer needs to account for the current state of entities, and reorgs become notably more complex.&lt;/p&gt;

&lt;p&gt;During a chain reorg, rather than simply replacing orphaned data, you need to &lt;strong&gt;revert previous operations or changes&lt;/strong&gt; and ensure that the entity state is rolled back correctly. This requires tracking the history of changes to each entity so that when a reorg occurs, you can accurately undo or adjust state based on the adopted canonical chain's data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: We can periodically prune the entity history, retaining only the changes relevant to unfinalized blocks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Reorgs and multichain indexing
&lt;/h2&gt;

&lt;p&gt;When it comes to multichain indexing, we face additional complexity because we process events from multiple sources that interact and update the same entity state. When one chain undergoes a reorg, we need to roll back the state to a known correct point and reprocess any events from all chains that affected the state after the reorg on the affected chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reorgs in the wild
&lt;/h2&gt;

&lt;p&gt;In practice, different networks exhibit varying levels of exposure to reorgs based on their design. Some networks, like Base and the &lt;a href="https://x.com/ShivanshuMadan/status/1811492866818212024" rel="noopener noreferrer"&gt;OP stack&lt;/a&gt;, are largely reorg-resistant with block finality occurring at the head, though &lt;a href="https://optimistic.etherscan.io/blocks_forked" rel="noopener noreferrer"&gt;exceptions&lt;/a&gt; do exist. On the other hand, networks like Polygon frequently experience deeper reorgs, where forked chains can extend over 10 blocks deep. One notable instance involved a reorg of &lt;a href="https://forum.polygon.technology/t/157-block-reorg-at-block-height-39599624/11388" rel="noopener noreferrer"&gt;157 blocks&lt;/a&gt;. Both &lt;a href="https://etherscan.io/blocks_forked" rel="noopener noreferrer"&gt;Etherscan&lt;/a&gt; and &lt;a href="https://gnosis.blockscout.com/blocks?tab=reorgs" rel="noopener noreferrer"&gt;Blockscout&lt;/a&gt; provide data on reorg occurrences. According to Ethereum Mainnet Etherscan, roughly 1% of blocks undergo reorgs, meaning that, assuming a 50/50 chance of a transaction being included in either the orphaned or canonical chain, about 1 in 200 transactions is likely to be in a reorged block.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Reorgs are a crucial consideration in blockchain indexing. Understanding their implications and designing with flexibility allows you to properly account for them in your indexer. Envio handles reorg detection and state rollback automatically, so developers building on HyperIndex get correct data at the head without needing to implement rollback logic themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are chain reorgs?
&lt;/h2&gt;

&lt;p&gt;In order to understand reorgs, let's break down the fundamental concepts and build up to a definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fundamental concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block&lt;/li&gt;
&lt;li&gt;Chain&lt;/li&gt;
&lt;li&gt;Miners&lt;/li&gt;
&lt;li&gt;Chain fork&lt;/li&gt;
&lt;li&gt;Orphaned chain&lt;/li&gt;
&lt;li&gt;Canonical chain&lt;/li&gt;
&lt;li&gt;Block finality&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Block
&lt;/h3&gt;

&lt;p&gt;A container that stores transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chain
&lt;/h3&gt;

&lt;p&gt;A series of sequential blocks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Miners
&lt;/h3&gt;

&lt;p&gt;Actors that try to submit the next valid block.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chain fork
&lt;/h3&gt;

&lt;p&gt;A chain fork occurs when more than one miner submits a valid block at the same time, causing a split where two valid chains exist simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  Orphaned chain and canonical chain
&lt;/h3&gt;

&lt;p&gt;When a chain forks, eventually one chain becomes accepted as the valid chain, known as the canonical chain. The forked chain that is not accepted becomes the orphaned chain. Orphaned blocks cease to exist, and transactions that occurred in those blocks cease to exist as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orphaned chain&lt;/strong&gt;: The forked chain that is dropped&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Canonical chain&lt;/strong&gt;: The chain adopted as the valid chain&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Info: We do not know which fork will be orphaned and which will become canonical until after the fact.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Block finality
&lt;/h3&gt;

&lt;p&gt;The minimum number of blocks needed to confirm that blocks will not become part of an orphaned chain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Info: Block finality is the reason bridges and centralized exchanges require a confirmation delay after a transaction is confirmed, to ensure blocks will not become orphaned.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Reorg
&lt;/h3&gt;

&lt;p&gt;A reorg is a set of events that results in a chain rolling back to a previous point in time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does every blockchain indexer need to handle reorgs?
&lt;/h3&gt;

&lt;p&gt;Not necessarily. If your indexer only processes finalized blocks (past the finality threshold), reorgs are not a concern. Reorg handling is only important if you are indexing at the head or within the range between the head and the network's finalized block.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between stateless and stateful indexing in the context of reorgs?
&lt;/h3&gt;

&lt;p&gt;A stateless indexer only creates new entities. On a reorg, you delete orphaned entities and re-ingest from the canonical chain. A stateful indexer also updates and deletes entities based on previous state, which requires tracking the history of changes so that state can be accurately rolled back when a reorg occurs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which networks experience the most frequent or deepest reorgs?
&lt;/h3&gt;

&lt;p&gt;Polygon is known for frequent and sometimes deep reorgs (a 157-block reorg has been recorded). Base and OP stack chains are largely reorg-resistant due to single-slot finality. Ethereum mainnet sees roughly 1% of blocks affected by reorgs. Networks with faster block times and probabilistic finality tend to have more reorg activity.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Envio handle reorgs automatically?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do reorgs affect multichain indexers?
&lt;/h3&gt;

&lt;p&gt;In a multichain indexer, events from multiple chains may update the same entity. If one chain reorgs, any state changes that depended on post-reorg events from that chain must also be rolled back and reprocessed, even if those changes involved events from other chains. This makes multichain reorg handling significantly more complex than single-chain reorg handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Blockchain Indexer For Application Backends</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:42:35 +0000</pubDate>
      <link>https://dev.to/envio/blockchain-indexer-for-application-backends-11mb</link>
      <guid>https://dev.to/envio/blockchain-indexer-for-application-backends-11mb</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8z9gwou0q9cvmd4bqrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8z9gwou0q9cvmd4bqrk.png" alt="Blockchain Indexer For Application Backends" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blockchain indexers sit between the chain and your application backend, transforming raw events into structured, queryable data your app can depend on.&lt;/li&gt;
&lt;li&gt;Without an indexer, backends must reconstruct state from history, handle reorgs, and translate raw logs. This complexity compounds as projects scale.&lt;/li&gt;
&lt;li&gt;Envio handles this with a single &lt;code&gt;config.yaml&lt;/code&gt;, TypeScript event handlers, HyperSync for fast historical sync, and a hosted GraphQL API that works across multiple chains.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a blockchain indexer
&lt;/h2&gt;

&lt;p&gt;A blockchain indexer is a specialised tool that ingests raw blockchain data and transforms it into structured data that application backends can query efficiently.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The result is a reliable, queryable data layer built from onchain activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How blockchain indexers work
&lt;/h2&gt;

&lt;p&gt;In practice, a blockchain indexer follows a simple model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read blockchain data: blocks, transactions, and event logs&lt;/li&gt;
&lt;li&gt;Apply developer-defined logic to the data&lt;/li&gt;
&lt;li&gt;Store the results as structured entities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The backend problem blockchain apps run into
&lt;/h2&gt;

&lt;p&gt;Application backends need structured state. Blockchains expose raw data. When applications rely directly on RPC endpoints, backend logic quickly becomes responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reconstructing state from historical events&lt;/li&gt;
&lt;li&gt;Tracking contract changes over time&lt;/li&gt;
&lt;li&gt;Handling retries, partial failures, and reorgs&lt;/li&gt;
&lt;li&gt;Translating low-level logs into usable application data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What role a blockchain indexer plays
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In practice, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Indexing contract events once instead of repeatedly&lt;/li&gt;
&lt;li&gt;Converting raw logs into structured entities&lt;/li&gt;
&lt;li&gt;Persisting derived state that applications can rely on&lt;/li&gt;
&lt;li&gt;Keeping blockchain-specific logic out of application code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation makes backends simpler, more predictable, and easier to scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the indexed data gets used
&lt;/h2&gt;

&lt;p&gt;Once data is indexed, application backends can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serve APIs backed by indexed blockchain state&lt;/li&gt;
&lt;li&gt;Power user interfaces with pre-processed data&lt;/li&gt;
&lt;li&gt;Track contract state without rescanning history&lt;/li&gt;
&lt;li&gt;Build features that depend on event-driven updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the indexing logic is deterministic and versioned, teams can evolve their schema and handlers without rewriting application logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a blockchain indexer becomes necessary
&lt;/h2&gt;

&lt;p&gt;Most teams reach for a blockchain indexer when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application logic depends on more than the latest block&lt;/li&gt;
&lt;li&gt;The application needs access to real-time and historical onchain data&lt;/li&gt;
&lt;li&gt;Data needs to be queried frequently or predictably&lt;/li&gt;
&lt;li&gt;The application spans multiple networks and needs a unified data layer&lt;/li&gt;
&lt;li&gt;Backend reliability becomes a priority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, indexing once and querying structured data becomes the simplest approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a blockchain indexer with Envio
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;config.yaml&lt;/code&gt; and exposed through one GraphQL endpoint, with no per-chain deployment overhead.&lt;/p&gt;

&lt;p&gt;As projects scale, Envio provides capabilities that support more advanced indexing and production requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript-first:&lt;/strong&gt; Write event handling logic in JavaScript or TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://docs.envio.dev/docs/HyperSync/overview" rel="noopener noreferrer"&gt;HyperSync&lt;/a&gt;:&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No-code quickstart:&lt;/strong&gt; Autogenerate a complete indexer project from a single contract address or ABI using &lt;code&gt;pnpx envio init&lt;/code&gt;. Deploy within minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multichain indexing:&lt;/strong&gt; Aggregate data across multiple networks into a single database. Query everything through a unified GraphQL API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Onchain and offchain data:&lt;/strong&gt; Combine indexed onchain events with offchain sources such as NFT metadata, token prices from aggregators, or current chain state via RPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factory contract support:&lt;/strong&gt; Automatically register and process events from child contracts created by a factory or dynamic contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;Hosted service&lt;/a&gt;:&lt;/strong&gt; A managed hosting platform for building, hosting, and querying Envio indexers, with 99.99% uptime SLA and GitHub-based auto-deploy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a backend data layer that remains consistent and reliable across development and production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Envio is designed to start small and scale as requirements grow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Index single or multiple contracts&lt;/li&gt;
&lt;li&gt;Map a small set of events into entities&lt;/li&gt;
&lt;li&gt;Run the indexer locally during development with &lt;code&gt;pnpm dev&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Expand the schema and handlers as application requirements grow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What does a blockchain indexer do in an application backend?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I use a blockchain indexer instead of direct RPC calls?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Envio differ from The Graph for backend indexing?
&lt;/h3&gt;

&lt;p&gt;The Graph requires a separate subgraph per chain and charges query fees through a decentralized network. Envio uses a single &lt;code&gt;config.yaml&lt;/code&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Envio support multichain backends?
&lt;/h3&gt;

&lt;p&gt;Yes. All networks are defined in one &lt;code&gt;config.yaml&lt;/code&gt;. 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I run Envio locally during development?
&lt;/h3&gt;

&lt;p&gt;Yes. Running &lt;code&gt;pnpm dev&lt;/code&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exploring Real-time Oracle Behavior and Push Based Feeds</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:42:29 +0000</pubDate>
      <link>https://dev.to/envio/exploring-real-time-oracle-behavior-and-push-based-feeds-2a4p</link>
      <guid>https://dev.to/envio/exploring-real-time-oracle-behavior-and-push-based-feeds-2a4p</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvchrrezd4wn0rtx29aex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvchrrezd4wn0rtx29aex.png" alt="Exploring Real-time Oracle Behavior and Push Based Feeds" width="800" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Co-authors: &lt;a href="https://x.com/j_o_r_d_y_s" rel="noopener noreferrer"&gt;Jordyn Laurier&lt;/a&gt;, Head of Marketing, and &lt;a href="https://x.com/jonjonclark" rel="noopener noreferrer"&gt;Jonjon Clark&lt;/a&gt;, Co-Founder at Envio&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oracle Wars is a live dashboard that visualizes real-time oracle behavior on MegaETH, built with Envio HyperIndex in under two hours.&lt;/li&gt;
&lt;li&gt;Push oracles use heartbeat intervals and deviation thresholds to trigger updates. A 0.5% deviation threshold does not mean consecutive onchain prices only differ by 0.5%.&lt;/li&gt;
&lt;li&gt;HyperIndex makes building real-time monitoring tools for high-throughput chains like MegaETH straightforward, with no RPC rate limit concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oracles are the connection between blockchains and real-world data, enabling smart contracts to interact with off-chain events like asset prices, market rates, or real-time sports scores. Visualizing how they behave in practice offers a new level of clarity for developers building onchain apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.oraclewars.xyz/" rel="noopener noreferrer"&gt;Oracle Wars&lt;/a&gt; is a live feed of onchain oracle data that shows how different providers behave in real time. It helps developers visualize and better understand how oracles function under different market conditions, so they can design more reliable and secure smart contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please note&lt;/strong&gt;: The multi-oracle comparison dashboard shown in earlier versions is no longer live on the site. Oracle Wars currently displays live ETH/USD price oracle updates from the &lt;a href="https://blog.redstone.finance/2025/04/08/introducing-redstone-bolt-the-fastest-blockchain-oracle-to-date/" rel="noopener noreferrer"&gt;Redstone Bolt&lt;/a&gt; oracle feed on MegaETH. Oracle Wars remains an educational and experimental tool for surfacing real-time data from various oracle providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a blockchain oracle?
&lt;/h2&gt;

&lt;p&gt;In simple terms, oracles allow smart contracts to react to external data sources. Whether it is the latest price of an asset or the outcome of a sporting event, oracles are how the blockchain sees the world.&lt;/p&gt;

&lt;p&gt;Over time, oracle architectures have evolved, giving rise to push-based oracles, pull-based oracles, and many more. Each design has trade-offs. This post focuses on push oracles and how they behave from a data perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Push oracles in practice
&lt;/h3&gt;

&lt;p&gt;A push oracle periodically pushes data onto the blockchain. Your contract reads that data and responds accordingly, whether it is executing a trade, adjusting a loan-to-value ratio, or triggering another onchain action.&lt;/p&gt;

&lt;p&gt;Most push oracles use two primary mechanisms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Heartbeat intervals&lt;/strong&gt;: Regular updates (e.g., every 24 hours)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deviation thresholds&lt;/strong&gt;: Immediate updates when data shifts significantly (e.g., 0.5% price movement)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Visualizing real-time oracle activity with Oracle Wars
&lt;/h2&gt;

&lt;p&gt;Wonder what happens in live conditions during periods of high volatility? That is where Oracle Wars came in. The earlier version of the dashboard showed a live comparison between price feeds from different oracle providers such as &lt;a href="https://chain.link/" rel="noopener noreferrer"&gt;Chainlink&lt;/a&gt; and &lt;a href="https://www.redstone.finance/" rel="noopener noreferrer"&gt;RedStone&lt;/a&gt;. Oracle Wars now focuses on Redstone Bolt ETH/USD updates on MegaETH, but the patterns below still apply to the earlier multi-oracle view.&lt;/p&gt;

&lt;p&gt;You will notice that updates are not always evenly spaced. That is the deviation threshold kicking in: when markets get volatile, updates come in fast. When things are calm, fewer updates appear. This is a valuable pattern to observe if you are designing a protocol that depends on accurate and real-time data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the limitations of deviation thresholds in push oracles
&lt;/h2&gt;

&lt;p&gt;Oracle Wars also shows the maximum deviation between any two consecutive price points over 24 hours. Every DeFi protocol relies on timely and accurate price data, and large shifts between updates can lead to exploit risk, broken assumptions, or cascading failures. This metric gives developers a real-world view of how much price movement can actually occur between updates, even when using well-known oracle providers.&lt;/p&gt;

&lt;p&gt;This brings us to a common misunderstanding: deviation thresholds are not strict limits.&lt;/p&gt;

&lt;p&gt;Take Chainlink and RedStone, for instance. Both use a 0.5% deviation threshold for price feeds. That should mean the oracle updates whenever the price moves more than 0.5%. But here is the catch:&lt;/p&gt;

&lt;p&gt;A 0.5% deviation threshold does not mean consecutive onchain prices will only differ by 0.5%.&lt;/p&gt;

&lt;p&gt;In practice, you might see larger deviations. Over 24 hours alone, Oracle Wars recorded deviations of around 0.67% for both providers. This does not mean the oracles were broken. It means they are working as designed. The threshold is more of a trigger condition than a strict upper bound.&lt;/p&gt;

&lt;p&gt;If you are competing in security audits on platforms like Sherlock, Code4rena, or CodeHawks, these edge cases are worth thinking through. Your protocol logic needs to account for potentially higher-than-expected changes, especially in volatile markets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is a super-fast push oracle now better than a pull oracle?
&lt;/h2&gt;

&lt;p&gt;With the advent of high-speed chains like MegaETH and Monad, we are starting to see ultra-fast push oracles that update data with each block. This near-instantaneous data feed challenges traditional push oracles, offering freshness comparable to pull oracles, provided transaction costs remain manageable.&lt;/p&gt;

&lt;p&gt;On Oracle Wars, you can observe how these super-fast push oracles behave in real time, with feeds like the ETH/USD price on MegaETH. The data is continuously updated, providing a new level of insight into how push oracles might evolve to rival the responsiveness of pull models.&lt;/p&gt;

&lt;p&gt;One aspect that remains intriguing is the frequent occurrence of multiple price updates at the same timestamp. This raises questions about whether these oracles are pushing multiple updates within the same block and the rationale behind this granularity.&lt;/p&gt;

&lt;p&gt;While Redstone's Bolt push oracle is an exciting development, it is still early days. It will be interesting to see how other oracle providers and chains approach the super-fast push model. The key question remains: can ultra-fast push oracles maintain the freshness and reliability of pull oracles without significant cost overhead?&lt;/p&gt;

&lt;h2&gt;
  
  
  Oracle Wars: powered by Envio's HyperIndex
&lt;/h2&gt;

&lt;p&gt;Oracle Wars was built in under two hours using Envio's HyperIndex, which made indexing real-time oracle data smooth and straightforward. No custom RPC infrastructure was needed, and no rate limit concerns applied.&lt;/p&gt;

&lt;p&gt;If you are building dashboards, simulations, or monitoring tools, it is worth checking out. Need help getting started? Feel free to reach out in our Discord or on Telegram.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helpful resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/contract-import" rel="noopener noreferrer"&gt;HyperIndex Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/configuration-file" rel="noopener noreferrer"&gt;Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/example-uniswap-v4-multi-chain-indexer" rel="noopener noreferrer"&gt;Examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/enviodev/hyperindex" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Background posts on X that kicked this off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/jonjonclark/status/1890426833088246054" rel="noopener noreferrer"&gt;Thinking through oracles with data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/jonjonclark/status/1892208677815300350" rel="noopener noreferrer"&gt;Understanding the Limitations of Deviation Thresholds in Push Oracles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/jonjonclark/status/1903109614318575809" rel="noopener noreferrer"&gt;How Much Latency Do High-Frequency Oracle Push Feeds Actually Have?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://x.com/jonjonclark/status/1909635483182789020" rel="noopener noreferrer"&gt;Is a super-fast push oracle now better than a pull oracle?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the difference between a push oracle and a pull oracle?
&lt;/h3&gt;

&lt;p&gt;A push oracle periodically writes updated data directly to the blockchain. A pull oracle does not write data proactively. Instead, it allows consumers to request data on demand, usually with a small fee. Pull oracles can offer fresher data per request, but push oracles are simpler to integrate since the data is already onchain when your contract needs it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why can the actual price deviation between oracle updates exceed the stated deviation threshold?
&lt;/h3&gt;

&lt;p&gt;Deviation thresholds are trigger conditions, not strict caps. When the threshold is set at 0.5%, the oracle updates whenever the price moves 0.5% from the last onchain price. However, by the time the update transaction is confirmed, the actual market price may have moved further. During high volatility, you can observe deviations larger than the configured threshold.&lt;/p&gt;

&lt;h3&gt;
  
  
  How was Oracle Wars built so quickly using Envio?
&lt;/h3&gt;

&lt;p&gt;Oracle Wars was built in under two hours because Envio HyperIndex handles all data ingestion, storage, and GraphQL API generation automatically. The developer only needed to define the oracle contract's ABI, configure the events of interest in &lt;code&gt;config.yaml&lt;/code&gt;, and write event handlers to store price updates. Envio handles the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can HyperIndex handle the data throughput of high-frequency oracle feeds on MegaETH?
&lt;/h3&gt;

&lt;p&gt;Yes. HyperIndex is designed for high-throughput chains and uses HyperSync as its data retrieval layer, which bypasses RPC entirely for historical data and keeps up with real-time blocks efficiently. Oracle Wars on MegaETH demonstrates this with continuous ETH/USD price streaming at sub-millisecond block times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use Oracle Wars for production smart contract design decisions?
&lt;/h3&gt;

&lt;p&gt;Oracle Wars is an educational and experimental tool, not a production monitoring service. It is useful for understanding how push oracles behave under real market conditions and for informing your protocol design. For production systems, use the oracle provider's official documentation and run your own analysis of historical deviation data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Optimizing Blockchain Indexers on AWS</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:42:01 +0000</pubDate>
      <link>https://dev.to/envio/optimizing-blockchain-indexers-on-aws-23c9</link>
      <guid>https://dev.to/envio/optimizing-blockchain-indexers-on-aws-23c9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6orslzebaayy9gi5zxb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl6orslzebaayy9gi5zxb.png" alt="Optimizing Blockchain Indexers on AWS" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running blockchain indexers on AWS has three main cost drivers: networking (NAT Gateway, cross-AZ data transfer), compute (instance sizing, spot instances), and storage (RDS vs Aurora I/O-Optimized).&lt;/li&gt;
&lt;li&gt;Practical strategies like single-AZ deployment, Bottlerocket OS, and Aurora I/O-Optimized can cut costs significantly without sacrificing reliability.&lt;/li&gt;
&lt;li&gt;These are the same optimizations Envio uses internally to power its Hosted Service, so teams using Envio Cloud get these benefits without configuring them manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When running any application on cloud infrastructure, one of the first questions that comes up is: where did all the money go? In the &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; ecosystem, expenses like hidden EC2 charges, complex data transfer costs, or the confusing &lt;a href="https://aws.amazon.com/rds/aurora/pricing/" rel="noopener noreferrer"&gt;Aurora pricing model&lt;/a&gt; can quickly add up.&lt;/p&gt;

&lt;p&gt;Whether you are running Envio's &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt; on your own AWS setup or are curious about how Envio optimizes cloud resources to deliver its Hosted Service, this guide walks through practical techniques to maximize your blockchain indexer's performance while keeping costs as low as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges of running indexers on AWS
&lt;/h2&gt;

&lt;p&gt;Understanding these challenges helps you prepare and optimize your setup effectively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost management&lt;/strong&gt;: Navigating AWS pricing is complex. Hidden charges, especially for data transfer and compute, can lead to unexpected bills if not carefully monitored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration complexity&lt;/strong&gt;: Setting up an efficient architecture requires a solid understanding of AWS services. Misconfigurations lead to increased costs and reduced reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance tuning&lt;/strong&gt;: Indexers handle fluctuating workloads. Balancing performance with cost-effectiveness requires constant monitoring and adjustments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High availability&lt;/strong&gt;: Achieving true high availability without significant costs requires careful trade-offs between cost and redundancy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data management&lt;/strong&gt;: As indexers scale, managing large volumes of data efficiently becomes critical for maintaining performance while keeping costs low.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The costs of running an indexer
&lt;/h2&gt;

&lt;p&gt;The cost of running an indexer breaks down into three key areas:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Networking
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Avoid NAT Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the core of every indexer is fetching data from external sources (like HyperSync or an RPC provider) and indexing it into a storage layer (PostgreSQL). If you are running your indexer in an AWS private subnet, network traffic passes through a NAT Gateway, costing $0.045/GB (US-East) for both requests and responses.&lt;/p&gt;

&lt;p&gt;Think of a NAT Gateway as a hotel doorman: it handles your packages and ensures your privacy, but it comes at a cost. If you have carefully assessed your security needs and set up proper security groups, running your indexer in a public subnet is a perfectly acceptable option. In that case, you can bypass the NAT Gateway entirely and use an Internet Gateway, allowing communication with the outside world without the added cost of NAT traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transferring data within a region&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When deploying an indexer in &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; (EKS) or on an EC2 instance, it is easy for your indexer and storage layer to end up in different availability zones (AZs). AWS charges $0.01/GB (US-East) for data transferred between AZs, both in and out. To minimize costs, deploy both your indexer and storage layer within the same AZ.&lt;/p&gt;

&lt;p&gt;You might wonder: does this compromise high availability? Somewhat. If one AZ goes down, both your indexer and storage layer go down together. But since these two components are tightly coupled, if one fails the other is effectively unusable anyway.&lt;/p&gt;

&lt;p&gt;For true HA with low costs, consider AWS Aurora. Aurora replicates data across multiple AZs at no extra cost (baked into Aurora's pricing), and your indexer can connect to an Aurora instance within its own AZ. If one AZ fails, your indexer can redeploy in another AZ where another Aurora instance is ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compute
&lt;/h3&gt;

&lt;p&gt;Figuring out the right amount of compute power for your indexer requires balancing two distinct phases. When first deployed, your indexer processes historical data. Once caught up, it only needs to handle real-time indexing. The compute resources required for these two stages are quite different: historical indexing demands more resources while real-time indexing requires less.&lt;/p&gt;

&lt;p&gt;To optimize costs, use different EC2 instance types for each stage. Start with a larger, more powerful instance to process historical data as quickly as possible, then switch to a smaller, cheaper instance once you are caught up. Since AWS charges by the hour, find the smallest instance that can sync historical data quickly enough, then downsize for real-time indexing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spot instances&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/ec2/spot/" rel="noopener noreferrer"&gt;Spot instances&lt;/a&gt; can save up to 90% on EC2 costs. They are unused EC2 capacity offered at a discount but can be terminated when AWS needs the capacity. For HyperIndex indexers, which are stateless by nature, this is less of an issue since moving an indexer from one instance to another is straightforward. If staying close to real-time is critical, the interruptions of spot instances may be a headache.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Bottlerocket OS for EC2 instances&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One way to minimize downtime when using spot instances, especially if running your indexer in &lt;a href="https://aws.amazon.com/eks/" rel="noopener noreferrer"&gt;EKS&lt;/a&gt;, is to use &lt;a href="https://aws.amazon.com/bottlerocket/" rel="noopener noreferrer"&gt;Bottlerocket OS&lt;/a&gt; for your EC2 instances. Bottlerocket is a lightweight, container-optimized operating system that boots up much faster than Ubuntu or Amazon Linux. By using Bottlerocket, you can significantly cut downtime when a spot instance gets replaced. Since it is lightweight, more of your resources are dedicated to the indexer itself.&lt;/p&gt;

&lt;p&gt;Tip: when using spot instances with tools like EKS and Karpenter, specify as many EC2 instance types as possible. If one type runs out of spot capacity, Karpenter can try another before falling back to an on-demand instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Storage
&lt;/h3&gt;

&lt;p&gt;When hosting indexers on AWS, your primary options for PostgreSQL are AWS RDS and Aurora.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IOPS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Indexers are high-IOPS applications that handle a relentless stream of inserts and updates, meaning they need a storage solution that can support high IOPS. Serverless options will not cut it for indexers, as they cannot manage the constant load.&lt;/p&gt;

&lt;p&gt;For indexers on Aurora, Aurora I/O-Optimized is worth considering. Released in May 2023, this configuration eliminates IOPS charges, allowing you to avoid significant I/O costs that can make up 50% of expenses on standard Aurora. By switching to Aurora I/O-Optimized, you effectively get unlimited IOPS. The higher storage costs are offset by the elimination of per-IOPS billing, making it a more predictable and potentially cheaper option for high-I/O workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With RDS, you provision storage upfront, which can lead to over-provisioning. Aurora offers a pay-as-you-go storage option that scales automatically as your data grows. This flexibility can result in significant savings, especially when dealing with historical indexing or unpredictable storage growth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource requirements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A key component of Aurora is its separation of compute and storage. Unlike RDS, where storage is tightly coupled with compute, Aurora allows you to scale these independently. This is particularly useful when your indexer's compute and storage requirements fluctuate at different stages of the indexing process.&lt;/p&gt;

&lt;p&gt;In short: since indexers are high-I/O applications that scale up and down over time, Aurora I/O-Optimized can provide significant cost savings while delivering the performance you need. RDS remains a more affordable option for smaller indexers or a more hands-on approach to storage management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Running indexers on AWS does not have to be expensive. By understanding the key cost drivers in networking, compute, and storage and using the right AWS tools and configurations, you can significantly reduce your cloud bill while maintaining high performance. Whether you are optimizing your network with a single-AZ setup or taking advantage of spot instances for compute savings, there is always a smart way to balance performance and cost.&lt;/p&gt;

&lt;p&gt;These are the same optimizations Envio uses to power its Hosted Service. Teams using Envio Cloud get these benefits automatically, without needing to configure them manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS?
&lt;/h2&gt;

&lt;p&gt;AWS (Amazon Web Services) is a cloud computing platform providing on-demand services including computing power, storage, and networking. It allows businesses to scale their infrastructure without owning physical servers, offering flexibility and cost efficiency. Whether you are running a simple website or a complex application like a blockchain indexer, AWS helps you manage resources while paying only for what you use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Should I run my blockchain indexer in a public or private AWS subnet?
&lt;/h3&gt;

&lt;p&gt;For most indexers, a public subnet with well-configured security groups is a perfectly acceptable and cost-effective option. It avoids NAT Gateway charges ($0.045/GB) while still maintaining security through security groups. Private subnets add privacy but add cost and complexity that may not be justified for an indexer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Aurora always cheaper than RDS for blockchain indexers?
&lt;/h3&gt;

&lt;p&gt;Not always, but for high-IOPS indexers Aurora I/O-Optimized is typically more cost-effective. Standard Aurora and RDS charge per I/O operation, which adds up fast for indexers doing constant inserts and updates. Aurora I/O-Optimized eliminates per-IOPS billing in favor of higher storage costs, which is usually a net win for indexing workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use spot instances for a production blockchain indexer?
&lt;/h3&gt;

&lt;p&gt;Yes, with caveats. HyperIndex indexers are stateless, so recovering from a spot termination is straightforward. If you need to stay as close to real-time as possible, spot interruptions may cause brief gaps. Using Bottlerocket OS and specifying multiple instance types in Karpenter minimizes downtime when instances are replaced.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Envio's hosted service compare to self-managing on AWS?
&lt;/h3&gt;

&lt;p&gt;Envio's Hosted Service applies the same optimizations described in this post (single-AZ networking, Aurora I/O-Optimized, Bottlerocket OS on EKS) internally. Self-managing on AWS gives you more control but requires engineering time to configure and maintain these optimizations yourself. For most teams, the hosted service is faster and cheaper to operate.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the biggest hidden cost when running indexers on AWS?
&lt;/h3&gt;

&lt;p&gt;NAT Gateway charges and cross-AZ data transfer fees are the most commonly overlooked costs. A single indexer processing large volumes of HyperSync data through a NAT Gateway can generate hundreds of dollars per month in transfer fees. Deploying in a public subnet or consolidating your indexer and database in the same AZ eliminates most of this cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Envio Simplifies Data Retrieval for Multichain dApps</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:41:55 +0000</pubDate>
      <link>https://dev.to/envio/how-envio-simplifies-data-retrieval-for-multichain-dapps-4d7d</link>
      <guid>https://dev.to/envio/how-envio-simplifies-data-retrieval-for-multichain-dapps-4d7d</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1gf9rexcjpcstapuap6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1gf9rexcjpcstapuap6.png" alt="How Envio Simplifies Data Retrieval for Multichain dApps" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploying a dApp across multiple chains creates a fragmented data problem. Each chain has its own events, its own state, and no native way to query across them together.&lt;/li&gt;
&lt;li&gt;Envio HyperIndex solves this with a single indexer instance that reads events from multiple networks and exposes everything through one GraphQL endpoint.&lt;/li&gt;
&lt;li&gt;Configuration is a single &lt;code&gt;config.yaml&lt;/code&gt; file. No separate deployments, no cross-service data joins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The multichain future is already here. Protocols like &lt;a href="https://app.uniswap.org/" rel="noopener noreferrer"&gt;Uniswap&lt;/a&gt;, &lt;a href="https://aave.com/" rel="noopener noreferrer"&gt;Aave&lt;/a&gt;, and &lt;a href="https://compound.finance/" rel="noopener noreferrer"&gt;Compound&lt;/a&gt; are deployed across Ethereum, Arbitrum, Optimism, Base, Polygon, and more. Reaching users on multiple chains means accepting the data fragmentation that comes with it.&lt;/p&gt;

&lt;p&gt;For developers, this fragmentation is a real infrastructure problem. Traditional indexing approaches require a separate indexer and database per chain. Aggregating that data in your frontend means either stitching together multiple API calls or building additional backend logic to consolidate it. Both approaches add complexity and maintenance overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Multichain Data Problem
&lt;/h2&gt;

&lt;p&gt;When a dApp is deployed across multiple chains, every interaction that matters (swaps, transfers, liquidations, mints) is emitted as an event on each respective chain. There is no native cross-chain view of this data.&lt;/p&gt;

&lt;p&gt;The conventional approach requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One indexer deployment per chain&lt;/li&gt;
&lt;li&gt;One database per chain&lt;/li&gt;
&lt;li&gt;Custom aggregation logic in the frontend or a separate backend layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This compounds quickly. A protocol on five chains needs five indexer deployments to maintain, five databases to keep in sync, and aggregation logic that breaks every time a new chain is added.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multichain Indexing with Envio HyperIndex
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;Envio HyperIndex&lt;/a&gt; handles multichain indexing from a single indexer instance. All networks are defined in one &lt;code&gt;config.yaml&lt;/code&gt;. All indexed data lands in one database. Everything is queryable through one GraphQL endpoint.&lt;/p&gt;

&lt;p&gt;Other indexers require a separate subgraph or pipeline per chain. With Envio, adding a new chain is a config change, not a new deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Greeter Contract on Polygon and Linea
&lt;/h2&gt;

&lt;p&gt;The following example walks through a multichain Greeter indexer that listens for &lt;code&gt;NewGreeting&lt;/code&gt; events from contracts deployed on both Polygon and Linea.&lt;/p&gt;

&lt;h3&gt;
  
  
  config.yaml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Greeter&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Greeter indexer&lt;/span&gt;
&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;137&lt;/span&gt; &lt;span class="c1"&gt;# Polygon&lt;/span&gt;
    &lt;span class="na"&gt;start_block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45336336&lt;/span&gt;
    &lt;span class="na"&gt;contracts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Greeter&lt;/span&gt;
        &lt;span class="na"&gt;abi_file_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./abis/greeter-abi.json&lt;/span&gt;
        &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./src/EventHandlers.ts&lt;/span&gt;
        &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NewGreeting&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;59144&lt;/span&gt; &lt;span class="c1"&gt;# Linea&lt;/span&gt;
    &lt;span class="na"&gt;start_block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;367801&lt;/span&gt;
    &lt;span class="na"&gt;contracts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Greeter&lt;/span&gt;
        &lt;span class="na"&gt;abi_file_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./abis/greeter-abi.json&lt;/span&gt;
        &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./src/EventHandlers.ts&lt;/span&gt;
        &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NewGreeting&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both networks share the same handler and ABI. Adding a third chain means adding another network block. The handler logic stays unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  schema.graphql
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!]!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;latestGreeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;numberOfGreetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Event handler
&lt;/h3&gt;

&lt;p&gt;A single TypeScript handler processes &lt;code&gt;NewGreeting&lt;/code&gt; events from both chains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;generated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NewGreeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;latestGreeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;numberOfGreetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;numberOfGreetings&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;greetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...(&lt;/span&gt;&lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]),&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The handler runs identically for events from any network in the config. Chain-specific context (like &lt;code&gt;event.chainId&lt;/code&gt;) is available if you need it for cross-chain logic.&lt;/p&gt;

&lt;p&gt;For the full multichain indexing documentation, see the &lt;a href="https://docs.envio.dev/docs/HyperIndex/multichain-indexing" rel="noopener noreferrer"&gt;Envio docs&lt;/a&gt;. For a more complex multichain example, see the &lt;a href="https://docs.envio.dev/docs/HyperIndex/example-uniswap-v4-multi-chain-indexer" rel="noopener noreferrer"&gt;Uniswap V4 Multichain Indexer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How does Envio handle events from multiple chains in one indexer?
&lt;/h3&gt;

&lt;p&gt;All networks are defined in a single &lt;code&gt;config.yaml&lt;/code&gt;. HyperIndex processes events from each network in parallel and writes them to a shared database. Your GraphQL API reflects the combined state of all indexed chains.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need separate deployments for each chain?
&lt;/h3&gt;

&lt;p&gt;No. A single HyperIndex instance handles all configured networks. One deployment, one database, one GraphQL endpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can the same handler logic run across different chains?
&lt;/h3&gt;

&lt;p&gt;Yes. A single handler function processes matching events from all networks in your config. If you need to apply chain-specific logic, &lt;code&gt;event.chainId&lt;/code&gt; is available in the handler context.&lt;/p&gt;

&lt;h3&gt;
  
  
  How many chains does Envio support?
&lt;/h3&gt;

&lt;p&gt;HyperSync natively supports 80+ EVM chains. Any supported chain can be added to your &lt;code&gt;config.yaml&lt;/code&gt;. For chains not yet covered by HyperSync, you can fall back to an RPC endpoint without changing your handler code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where can I see a full multichain indexing example?
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://docs.envio.dev/docs/greeter-tutorial" rel="noopener noreferrer"&gt;Greeter tutorial&lt;/a&gt; in the Envio docs walks through multichain indexing step by step. The &lt;a href="https://docs.envio.dev/docs/HyperIndex/example-uniswap-v4-multi-chain-indexer" rel="noopener noreferrer"&gt;Uniswap V4 Multichain Indexer&lt;/a&gt; is a more complex real-world example covering many chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dedicated Hosting for Blockchain Indexers</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:41:50 +0000</pubDate>
      <link>https://dev.to/envio/dedicated-hosting-for-blockchain-indexers-2192</link>
      <guid>https://dev.to/envio/dedicated-hosting-for-blockchain-indexers-2192</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyms2zp7ryk299tzijxl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyms2zp7ryk299tzijxl1.png" alt="Dedicated Hosting for Blockchain Indexers" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running a blockchain indexer in production requires a database, a GraphQL API layer, uptime monitoring, and infrastructure that scales with your data.&lt;/li&gt;
&lt;li&gt;Envio Cloud handles all of this as a managed service, so teams can focus on handler logic rather than infrastructure.&lt;/li&gt;
&lt;li&gt;Self-hosting via Docker is also supported for teams that want full infrastructure control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deploying a blockchain indexer locally is straightforward. Keeping one running reliably in production is a different problem. You need a database, a GraphQL API layer, uptime guarantees, and a deployment process that does not require manual intervention every time your handler logic changes.&lt;/p&gt;

&lt;p&gt;This article covers what a dedicated hosted indexer service provides, how Envio Cloud works, and how to decide between managed hosting and self-hosting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Hosted Indexer Service Provides
&lt;/h2&gt;

&lt;p&gt;A hosted indexer service takes your indexer configuration, schema, and handler code and runs the full stack for you. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Storing indexed events and entity tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL API&lt;/strong&gt;: Auto-generated from your schema via Hasura, queryable by your frontend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uptime&lt;/strong&gt;: The service monitors availability and handles restarts automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Syncing from your repository so new versions deploy without manual steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a hosted service, each of these components needs to be provisioned, maintained, and scaled independently. For teams focused on building a product rather than managing infrastructure, this is significant overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Envio Cloud Works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;Envio Cloud&lt;/a&gt; is the managed hosting option for HyperIndex. It runs on AWS infrastructure with Kubernetes orchestration and Hasura for the GraphQL layer.&lt;/p&gt;

&lt;p&gt;Deployment is integrated with GitHub. An Envio GitHub bot monitors your repository and triggers new deployments when changes land in your specified branch. There is no manual deploy step once the integration is configured.&lt;/p&gt;

&lt;p&gt;The stack Envio Cloud manages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt;: Cloud infrastructure and compute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes&lt;/strong&gt;: Container orchestration and scaling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hasura&lt;/strong&gt;: Real-time GraphQL API generation from your schema&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HyperSync&lt;/strong&gt;: The data engine powering historical sync, up to 2000x faster than standard RPC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For local development, the full stack runs with a single &lt;code&gt;pnpm dev&lt;/code&gt; command using Docker Desktop. The same handler logic runs locally and in production without modification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managed Hosting vs Self-Hosting
&lt;/h2&gt;

&lt;p&gt;HyperIndex supports both options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Envio Cloud&lt;/th&gt;
&lt;th&gt;Self-hosted (Docker)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure setup&lt;/td&gt;
&lt;td&gt;Handled by Envio&lt;/td&gt;
&lt;td&gt;You manage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uptime monitoring&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;You manage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;GitHub bot auto-deploy&lt;/td&gt;
&lt;td&gt;Manual or custom CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Free tier and paid plans&lt;/td&gt;
&lt;td&gt;Your infrastructure costs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control&lt;/td&gt;
&lt;td&gt;Standard configuration&lt;/td&gt;
&lt;td&gt;Full control&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For most teams, Envio Cloud is the faster path to production. For teams with specific compliance requirements or existing infrastructure preferences, self-hosting via Docker gives full control without changing any handler code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Deploy to Envio Cloud from the &lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;hosted service docs&lt;/a&gt;. If you do not have an indexer yet, the contract import quickstart generates a working indexer from any deployed contract address in under 5 minutes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx envio init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What infrastructure does Envio Cloud run on?
&lt;/h3&gt;

&lt;p&gt;Envio Cloud uses AWS for compute, Kubernetes for orchestration, and Hasura for the GraphQL API layer. HyperSync powers historical data retrieval for all supported networks.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does deployment work with Envio Cloud?
&lt;/h3&gt;

&lt;p&gt;Envio Cloud integrates with GitHub via a bot that monitors your repository. When changes land in your configured branch, a new deployment is triggered automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I self-host HyperIndex instead of using Envio Cloud?
&lt;/h3&gt;

&lt;p&gt;Yes. HyperIndex can be self-hosted using Docker. The same handler logic and schema work identically in both environments. See the &lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;hosting docs&lt;/a&gt; for setup instructions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is included in the free tier?
&lt;/h3&gt;

&lt;p&gt;See the &lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;Envio Cloud docs&lt;/a&gt; for current plan details and limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does Envio Cloud support multichain indexers?
&lt;/h3&gt;

&lt;p&gt;Yes. A single HyperIndex instance can index multiple networks and all data is queryable through one GraphQL endpoint, whether hosted on Envio Cloud or self-hosted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Agentic Blockchain Indexing with Envio Cloud</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:41:21 +0000</pubDate>
      <link>https://dev.to/envio/agentic-blockchain-indexing-with-envio-cloud-36bj</link>
      <guid>https://dev.to/envio/agentic-blockchain-indexing-with-envio-cloud-36bj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe47msswfxxnispozdx1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe47msswfxxnispozdx1y.png" alt="Agentic Blockchain Indexing with Envio Cloud" width="799" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Envio HyperIndex and the &lt;code&gt;envio-cloud&lt;/code&gt; CLI enable end-to-end agentic deployment of blockchain indexers with no manual config.&lt;/li&gt;
&lt;li&gt;An AI agent scaffolded, configured, pushed to GitHub, and deployed a wstETH indexer on Monad Mainnet from a single prompt.&lt;/li&gt;
&lt;li&gt;400,000 events indexed in approximately 20 seconds.&lt;/li&gt;
&lt;li&gt;Every step is CLI-driven and scriptable, with JSON output for downstream agent logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;With the Envio Cloud CLI (&lt;code&gt;envio-cloud&lt;/code&gt;) 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result: 400,000 events indexed in ~20 seconds&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HyperIndex?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;HyperIndex&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Envio Cloud CLI: &lt;code&gt;envio-cloud&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.npmjs.com/package/envio-cloud" rel="noopener noreferrer"&gt;envio-cloud&lt;/a&gt; CLI is the command-line interface for Envio Cloud, the managed infrastructure layer that runs your HyperIndex indexers in production.&lt;/p&gt;

&lt;p&gt;With it you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate via GitHub (&lt;code&gt;envio-cloud login&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Register a new indexer pointing to your GitHub repo (&lt;code&gt;envio-cloud indexer add&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Monitor sync progress and deployment status in real-time (&lt;code&gt;envio-cloud deployment status&lt;/code&gt;, &lt;code&gt;envio-cloud deployment metrics&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Promote deployments to production (&lt;code&gt;envio-cloud deployment promote&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Pull JSON output for any command (&lt;code&gt;-o json&lt;/code&gt;), making it fully scriptable and agent-friendly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;No dashboard required. Everything that matters is exposed through the CLI.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  End-to-End: Agentic deployment of a wstETH indexer on Monad
&lt;/h2&gt;

&lt;p&gt;Here's the full workflow an agent ran to deploy a live ERC20 indexer for wstETH on &lt;a href="https://www.monad.xyz" rel="noopener noreferrer"&gt;Monad&lt;/a&gt; Mainnet, start to finish.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Scaffold the indexer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx envio init template &lt;span class="nt"&gt;-t&lt;/span&gt; erc20 &lt;span class="nt"&gt;-l&lt;/span&gt; typescript &lt;span class="nt"&gt;-d&lt;/span&gt; ./my-indexer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;envio&lt;/code&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure for Monad
&lt;/h3&gt;

&lt;p&gt;The agent edits &lt;code&gt;config.yaml&lt;/code&gt; to target the wstETH contract on Monad Mainnet (chain ID 143, contract address &lt;code&gt;0x10Aeaf63194db8d453d4D85a06E5eFE1dd0b5417, start_block: 0&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Then runs codegen and a type check to confirm everything is clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm codegen
pnpm tsc &lt;span class="nt"&gt;--noEmit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;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.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Push to GitHub
&lt;/h3&gt;

&lt;p&gt;Create a public repo and push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo create wsteth-monad-indexer-demo &lt;span class="nt"&gt;--public&lt;/span&gt;
git init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git add &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"init"&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the push fails because your GitHub token lacks permission to push workflow files (like &lt;code&gt;.github/workflows/test.yaml&lt;/code&gt;), refresh auth with workflow scope:&lt;br&gt;
&lt;code&gt;gh auth refresh -s workflow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Envio Cloud deploys from the &lt;code&gt;envio&lt;/code&gt; branch by default, so create and push it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; envio &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin envio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Connect the Envio GitHub Bot
&lt;/h3&gt;

&lt;p&gt;The Envio GitHub App must have access to the repo before deployments will trigger. If the repo is not already linked, visit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apps/envio-deployments/installations/select_target" rel="noopener noreferrer"&gt;https://github.com/apps/envio-deployments/installations/select_target&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then grant the bot access to the &lt;code&gt;wsteth-monad-indexer-demo&lt;/code&gt; repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Deploy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx envio-cloud login
pnpx envio-cloud indexer add
  &lt;span class="nt"&gt;--name&lt;/span&gt; wsteth-monad-indexer-demo
  &lt;span class="nt"&gt;--repo&lt;/span&gt; wsteth-monad-indexer-demo
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"wstETH ERC20 indexer on Monad"&lt;/span&gt;
  &lt;span class="nt"&gt;--branch&lt;/span&gt; envio
  &lt;span class="nt"&gt;--skip-repo-check&lt;/span&gt;
  &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Verify
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx envio-cloud indexer get wsteth-monad-indexer-demo &lt;span class="o"&gt;{&lt;/span&gt;org&lt;span class="o"&gt;}&lt;/span&gt;
pnpx envio-cloud deployment status wsteth-monad-indexer-demo &amp;lt;commit-hash&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;org&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once synced, the indexer is viewable in the browser at &lt;code&gt;https://envio.dev/app/{org}/{indexer-name}/{commit-hash}.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Check the live deployment from this demo here:&lt;br&gt;
&lt;a href="https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35" rel="noopener noreferrer"&gt;https://envio.dev/app/denhampreen/wsteth-monad-indexer-demo/5d55d35&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;400,000 events indexed. ~20 seconds&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;See the full walkthrough on &lt;a href="https://www.loom.com/share/09cdac43b18f4143ad78b18c8c8a492b" rel="noopener noreferrer"&gt;Loom&lt;/a&gt;, covering the complete agent driven workflow from scaffold to deployment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this matters for agentic development
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;HyperIndex and the &lt;code&gt;envio-cloud&lt;/code&gt; 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 (&lt;code&gt;-o json&lt;/code&gt;) makes it straightforward to pipe deployment status into downstream logic. The GitHub-native deployment flow means agents that can commit code can deploy indexers.&lt;/p&gt;

&lt;p&gt;This is what it looks like in practice for HyperIndex to be the default indexing framework for agentic development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Install the Envio Cloud CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; envio-cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scaffold your first indexer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx envio init template &lt;span class="nt"&gt;-t&lt;/span&gt; erc20 &lt;span class="nt"&gt;-l&lt;/span&gt; typescript &lt;span class="nt"&gt;-d&lt;/span&gt; ./my-indexer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Be sure to check out our &lt;a href="https://docs.envio.dev/blog/envio-docs-mcp-server" rel="noopener noreferrer"&gt;Envio Docs MCP Server&lt;/a&gt; for AI-assisted indexer development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is agentic blockchain indexing?
&lt;/h3&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the envio-cloud CLI?
&lt;/h3&gt;

&lt;p&gt;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 &lt;code&gt;-o json&lt;/code&gt; flag.&lt;/p&gt;

&lt;h3&gt;
  
  
  How fast is Envio HyperIndex for historical sync?
&lt;/h3&gt;

&lt;p&gt;In independent benchmarks run by Sentio, HyperIndex completed the Uniswap V2 Factory sync in 8 seconds, 142x faster than The Graph and 15x faster than the nearest competitor (Subsquid). In the agentic deployment demo, 400,000 wstETH events on Monad Mainnet were indexed in approximately 20 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which chains does Envio support for agentic indexing?
&lt;/h3&gt;

&lt;p&gt;Envio supports any EVM-compatible chain. HyperSync natively covers 80+ 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I get started with agentic indexing on Envio?
&lt;/h3&gt;

&lt;p&gt;Install the Envio Cloud CLI with &lt;code&gt;npm install -g envio-cloud&lt;/code&gt;, then scaffold your first indexer with &lt;code&gt;pnpx envio init template -t erc20 -l typescript -d ./my-indexer&lt;/code&gt;. Push to GitHub and deploy with the envio-cloud CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Envio Cloud
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/hosted-service" rel="noopener noreferrer"&gt;Envio Cloud&lt;/a&gt; is a managed environment for running HyperIndex indexers in production.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;Envio is the fastest independently benchmarked EVM blockchain indexer for querying real-time and historical data (&lt;a href="https://github.com/enviodev/open-indexer-benchmark" rel="noopener noreferrer"&gt;Sentio benchmark, May 2025&lt;/a&gt;). If you are building onchain and need indexing that keeps up with your chain, check out the &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Envio Now Supports 70+ Blockchains</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:41:14 +0000</pubDate>
      <link>https://dev.to/envio/envio-now-supports-70-blockchains-44jc</link>
      <guid>https://dev.to/envio/envio-now-supports-70-blockchains-44jc</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0mr9zg1j95t4yyr03rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0mr9zg1j95t4yyr03rq.png" alt="Envio Now Supports 70+ Blockchains" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Envio's HyperSync now supports over 70 EVM-compatible networks plus Fuel, providing reliable real-time data access at speeds up to 2000x faster than standard RPC.&lt;/li&gt;
&lt;li&gt;HyperIndex adds full multichain indexing with a single config.yaml and a single GraphQL endpoint, making it structurally simpler than The Graph or Goldsky for cross-chain data.&lt;/li&gt;
&lt;li&gt;If your network is not yet supported, you can request HyperSync support directly in the Envio Discord.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Envio's HyperSync supports over 70 EVM-compatible networks along with Fuel, providing reliable real-time data access across the Web3 ecosystem. This milestone advances the goal of making decentralized data more efficient and accessible for developers and analysts building across multiple blockchains.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HyperSync?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperSync/overview" rel="noopener noreferrer"&gt;HyperSync&lt;/a&gt; is Envio's advanced data node, built in Rust to dramatically speed up blockchain data retrieval. It operates as a real-time, high-speed query layer, offering a low-level API compatible with Python, Rust, Node.js, and Go. With HyperSync, you can query millions of events in seconds, delivering sync speeds up to 2000x faster than traditional RPC methods.&lt;/p&gt;

&lt;p&gt;HyperSync is well suited for performance-heavy applications like block explorers, data analytics platforms, and blockchain bridges. Traditional syncing methods can be slow and resource-intensive, especially across multiple networks. HyperSync optimizes these processes with intelligent caching and efficient data retrieval, giving you faster access to both real-time and historical blockchain data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multichain indexing support
&lt;/h2&gt;

&lt;p&gt;Envio HyperIndex provides multichain indexing support, enabling you to efficiently index and query multiple blockchains with a single indexer. This eliminates redundant tools, streamlines workflows, and ensures high performance at scale.&lt;/p&gt;

&lt;p&gt;Unlike The Graph (which requires a separate subgraph per chain with separate endpoints) or Goldsky (which requires separate pipelines per chain), Envio uses a single &lt;code&gt;config.yaml&lt;/code&gt; to define all networks and exposes a single GraphQL endpoint. This makes cross-chain data access significantly simpler to build and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported networks
&lt;/h2&gt;

&lt;p&gt;Envio supports any EVM chain and Fuel with an expanding list of networks, including &lt;a href="https://arbitrum.io/" rel="noopener noreferrer"&gt;Arbitrum&lt;/a&gt;, &lt;a href="https://www.base.org/" rel="noopener noreferrer"&gt;Base&lt;/a&gt;, &lt;a href="https://blast.io/en" rel="noopener noreferrer"&gt;Blast&lt;/a&gt;, &lt;a href="https://celo.org/" rel="noopener noreferrer"&gt;Celo&lt;/a&gt;, &lt;a href="https://www.chiliz.com/" rel="noopener noreferrer"&gt;Chiliz&lt;/a&gt;, &lt;a href="https://citrea.xyz/" rel="noopener noreferrer"&gt;Citrea&lt;/a&gt;, &lt;a href="https://darwinia.network/" rel="noopener noreferrer"&gt;Darwinia&lt;/a&gt;, &lt;a href="https://ethereum.org/en/" rel="noopener noreferrer"&gt;Ethereum&lt;/a&gt;, &lt;a href="https://www.gnosis.io/" rel="noopener noreferrer"&gt;Gnosis&lt;/a&gt;, &lt;a href="https://www.metis.io/" rel="noopener noreferrer"&gt;Metis&lt;/a&gt;, &lt;a href="https://www.monad.xyz/" rel="noopener noreferrer"&gt;Monad&lt;/a&gt;, &lt;a href="https://www.morphl2.io/" rel="noopener noreferrer"&gt;Morph&lt;/a&gt;, &lt;a href="https://www.optimism.io/" rel="noopener noreferrer"&gt;Optimism&lt;/a&gt;, &lt;a href="https://polygon.technology/" rel="noopener noreferrer"&gt;Polygon&lt;/a&gt;, &lt;a href="https://rootstock.io/" rel="noopener noreferrer"&gt;Rootstock&lt;/a&gt;, &lt;a href="https://scroll.io/" rel="noopener noreferrer"&gt;Scroll&lt;/a&gt;, and many more.&lt;/p&gt;

&lt;p&gt;See the full list of supported networks in the &lt;a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are rapidly adding new supported networks. If your network is not listed or you would like HyperSync support added, pop us a message in our &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Envio?
&lt;/h2&gt;

&lt;p&gt;Envio HyperIndex offers a developer-centric blockchain data indexing solution, empowering you to efficiently access and process both real-time and historical smart contract data served via GraphQL API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible language support&lt;/strong&gt;: Configure your event handling in JavaScript, TypeScript, or ReScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HyperSync&lt;/strong&gt;: Delivers up to 2000x faster indexing than standard RPC for historical onchain data. Use of RPC is optional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No-code quickstart&lt;/strong&gt;: Autogenerate the key boilerplate for an entire indexer project from single or multiple smart contracts. Deploy within minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multichain support&lt;/strong&gt;: Aggregate data across multiple networks into a single database. Query all your data with a unified GraphQL API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factory contracts&lt;/strong&gt;: Automatically register and process events emitted by all child contracts created by a specified factory or dynamic contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted service&lt;/strong&gt;: A managed service platform for building, hosting, and querying Envio's Indexers with guaranteed uptime and performance service level agreements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Useful resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/getting-started" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/configuration-file" rel="noopener noreferrer"&gt;Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.envio.dev/docs/HyperIndex/tutorial-op-bridge-deposits" rel="noopener noreferrer"&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Get support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Envio is a powerful alternative to traditional blockchain indexing methods. Its single-config multichain approach simplifies cross-chain data access and eliminates the per-chain overhead that comes with The Graph subgraphs or Goldsky pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I check if my network is supported by Envio HyperSync?
&lt;/h3&gt;

&lt;p&gt;Visit the &lt;a href="https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks" rel="noopener noreferrer"&gt;HyperSync supported networks page&lt;/a&gt; in the documentation. If your network is not listed, you can request support by opening a message in the &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use Envio on a network that HyperSync does not yet support?
&lt;/h3&gt;

&lt;p&gt;Yes. For networks without HyperSync support, Envio HyperIndex falls back to standard RPC for data retrieval. You provide an RPC URL in your config, and the indexer works the same way, just without the HyperSync speed boost. HyperSync support is added regularly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What languages can I use with the HyperSync API?
&lt;/h3&gt;

&lt;p&gt;HyperSync exposes a low-level API with clients for Python, Rust, Node.js, and Go. You can retrieve data in JSON, Arrow, or Parquet formats depending on your pipeline needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Envio's multichain support compare to The Graph?
&lt;/h3&gt;

&lt;p&gt;The Graph requires a separate subgraph deployment for each chain, with separate GraphQL endpoints per network. Envio uses a single &lt;code&gt;config.yaml&lt;/code&gt; to define all networks and a single GraphQL endpoint for all chains. This means less boilerplate, fewer deployments to manage, and simpler cross-chain queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is HyperSync available as a standalone API, or only through HyperIndex?
&lt;/h3&gt;

&lt;p&gt;HyperSync is available both as the underlying data layer for HyperIndex and as a standalone API. Data analysts can query HyperSync directly using the Python, Rust, Node.js, or Go clients for custom data pipelines, analytics, and research use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Track Polymarket Trades Using Envio's HyperSync</title>
      <dc:creator>Envio</dc:creator>
      <pubDate>Thu, 17 Sep 2026 14:41:10 +0000</pubDate>
      <link>https://dev.to/envio/how-to-track-polymarket-trades-using-envios-hypersync-3gaj</link>
      <guid>https://dev.to/envio/how-to-track-polymarket-trades-using-envios-hypersync-3gaj</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2mmesjjxbh7on66jich.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2mmesjjxbh7on66jich.png" alt="How to Track Polymarket Trades Using Envio's HyperSync" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a real-time Polymarket trade tracker using Envio HyperSync and TypeScript with Bun.&lt;/li&gt;
&lt;li&gt;Stream block heights from Polygon and query OrderFilled events from the Polymarket Exchange contracts on each new block.&lt;/li&gt;
&lt;li&gt;Decode events with Viem, identify buy vs sell trades by checking &lt;code&gt;makerAssetId&lt;/code&gt;, and calculate price per share.&lt;/li&gt;
&lt;li&gt;Extend with filters for trade amount or specific wallet addresses to track high-conviction traders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the rise of prediction markets like &lt;a href="https://polymarket.com" rel="noopener noreferrer"&gt;Polymarket&lt;/a&gt; and &lt;a href="https://kalshi.com" rel="noopener noreferrer"&gt;Kalshi&lt;/a&gt;, 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;We are going to use Bun for this article, so make sure you have it installed. If not, please check the &lt;a href="https://bun.com/docs/installation" rel="noopener noreferrer"&gt;Bun documentation&lt;/a&gt; for installation instructions. If you want to use some other runtime that supports TypeScript, you can do that too.&lt;/p&gt;

&lt;p&gt;You will also need an Envio API token to access HyperSync. If you don’t have it already, go to &lt;a href="https://envio.dev/app/api-tokens" rel="noopener noreferrer"&gt;https://envio.dev/app/api-tokens&lt;/a&gt; and you can find your token there.&lt;/p&gt;

&lt;p&gt;Here are step-by-step instructions for creating new API tokens: &lt;a href="https://docs.envio.dev/docs/HyperSync/api-tokens#generating-api-tokens" rel="noopener noreferrer"&gt;https://docs.envio.dev/docs/HyperSync/api-tokens#generating-api-tokens&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HyperSync
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.envio.dev/docs/HyperSync/overview" rel="noopener noreferrer"&gt;HyperSync&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;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 80+ EVM chains, so the same approach works across any supported network.&lt;/p&gt;

&lt;h2&gt;
  
  
  OrderFilled Event
&lt;/h2&gt;

&lt;p&gt;Before we start writing the script, let’s talk about the &lt;code&gt;OrderFilled&lt;/code&gt; 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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    event OrderFilled(
        bytes32 indexed orderHash,
        address indexed maker,
        address indexed taker,
        uint256 makerAssetId,
        uint256 takerAssetId,
        uint256 makerAmountFilled,
        uint256 takerAmountFilled,
        uint256 fee
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 &lt;code&gt;makerAssetId&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, then that is a buy order where the user is buying shares, and vice versa.&lt;/p&gt;

&lt;p&gt;To calculate price per share for a buy trade, we can use &lt;code&gt;makerAmountFilled&lt;/code&gt; and &lt;code&gt;takerAmountFilled&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Price per share in a buy trade = &lt;code&gt;makerAmountFilled / takerAmountFilled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using HyperSync Client
&lt;/h2&gt;

&lt;p&gt;To create a Bun project and install the HyperSync client along with Viem for decoding events, you can use the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;track-trades &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;track-trades
bun init &lt;span class="nt"&gt;-y&lt;/span&gt;
bun add @envio-dev/hypersync-client viem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re new to HyperSync clients, please start by going through these examples: &lt;a href="https://docs.envio.dev/docs/HyperSync/hypersync-clients" rel="noopener noreferrer"&gt;https://docs.envio.dev/docs/HyperSync/hypersync-clients&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7eor2u5xwsp22sih3emd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7eor2u5xwsp22sih3emd.png" alt="Sequence diagram showing index.ts streaming new block heights from HyperSync and querying OrderFilled events on each new height" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream Height
&lt;/h2&gt;

&lt;p&gt;We already have a height-streaming example in the HyperSync Node client, and we are going to use that here. Open &lt;code&gt;index.ts&lt;/code&gt; and paste the following snippet, then we can go over it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;HypersyncClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// for later use&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;QueryResponseData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// for later use&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@envio-dev/hypersync-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;decodeEventLog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// for later use&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Create hypersync client using the mainnet hypersync endpoint&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HypersyncClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://polygon.hypersync.xyz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;apiToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ENVIO_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a height stream to monitor blockchain height changes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heightStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;streamHeight&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Height stream created. Listening for height updates...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Track the last known height to detect changes&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Receive the next event from the height stream&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;heightStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Height stream ended by server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Handle different types of events&lt;/span&gt;
      &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchOrderFilledEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will be explained later&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Connected to height stream`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reconnecting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;`Reconnecting to height stream in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;delayMillis&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms due to error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errorMsg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;// Tells the typescript compiler that we have covered all possible event types&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;_exhaustiveCheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;never&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unhandled event type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error in height stream:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Always close the stream to clean up resources&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;heightStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Height stream closed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing we are doing in &lt;code&gt;main&lt;/code&gt; is creating the HyperSync client with &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;apiToken&lt;/code&gt; (which should be stored in a &lt;code&gt;.env&lt;/code&gt; file, so create one and store your Envio API token there).&lt;/p&gt;

&lt;p&gt;We have a &lt;code&gt;streamHeight&lt;/code&gt; function on the client that emits 3 types of events: &lt;code&gt;Height&lt;/code&gt;, &lt;code&gt;Connected&lt;/code&gt;, and &lt;code&gt;Reconnecting&lt;/code&gt;. When we get a new &lt;code&gt;Height&lt;/code&gt; event with the latest block number, we call &lt;code&gt;fetchOrderFilledEvents&lt;/code&gt;, where our parsing logic will live.&lt;/p&gt;

&lt;p&gt;After creating the stream with &lt;code&gt;streamHeight&lt;/code&gt;, we need to listen to those events, so we created a &lt;code&gt;while&lt;/code&gt; loop that checks data from &lt;code&gt;.recv()&lt;/code&gt; and a &lt;code&gt;switch&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Now we have our streaming logic, so we can move to &lt;code&gt;fetchOrderFilledEvents&lt;/code&gt;, which will handle the event parsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  fetchOrderFilledEvents Function
&lt;/h2&gt;

&lt;p&gt;This function will take the height we got from &lt;code&gt;streamHeight&lt;/code&gt; 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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contract addresses&lt;/li&gt;
&lt;li&gt;ABI of the event&lt;/li&gt;
&lt;li&gt;Event signature hash (aka &lt;code&gt;Topic0&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here they are, so add them somewhere at the top of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EXCHANGE_ADDRESSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xc5d563a36ae78145c45a50134d48a1215220f80a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ORDER_FILLED_TOPIC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ORDER_FILLED_ABI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;anonymous&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bytes32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;orderHash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bytes32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;taker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;makerAssetId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takerAssetId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;indexed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;internalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uint256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OrderFilled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;event&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ORDER_FILLED_ABI_ITEMS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ORDER_FILLED_ABI&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// we can push it to query directly as an array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's define the function signature. We are going to pass the HyperSync client and block height to this function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchOrderFilledEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HypersyncClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fetch the data from HyperSync, we need to create a query. If you're not familiar with HyperSync queries, the query builder at &lt;a href="https://builder.hypersync.xyz/" rel="noopener noreferrer"&gt;https://builder.hypersync.xyz/&lt;/a&gt; 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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;fromBlock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EXCHANGE_ADDRESSES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;ORDER_FILLED_TOPIC&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[]],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;fieldSelection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TransactionHash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BlockNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the &lt;code&gt;get&lt;/code&gt; function to fetch the data and store the logs/events in an array that we can loop over.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;QueryResponseData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s loop over that array and use &lt;code&gt;decodeEventLog&lt;/code&gt; from Viem to decode the data so we can analyze it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeEventLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ORDER_FILLED_ABI_ITEMS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topics&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;[]],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eventName&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OrderFilled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makerAssetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;makerAssetId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;maker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;taker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// TODO: Check if trade is Buy if yes, then log details along with price per share&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last part of this script is checking if the trade is a buy trade, which we can confirm when &lt;code&gt;makerAssetId&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;. We also need to calculate price per share. We already know the formula: &lt;code&gt;makerAmountFilled / takerAmountFilled&lt;/code&gt;. That value should be formatted to 6 decimals, and then we have the price per share.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formatRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;numerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;precision&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;denominator&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numerator&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;denominator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;whole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scaled&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fraction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scaled&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;precision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;whole&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fraction&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;fetchOrderFilledEvents&lt;/code&gt; should look like this at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchOrderFilledEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HypersyncClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Topic0: 0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fromBlock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EXCHANGE_ADDRESSES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="nx"&gt;ORDER_FILLED_TOPIC&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[]],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;fieldSelection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Topic3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TransactionHash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BlockNumber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;QueryResponseData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeEventLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ORDER_FILLED_ABI_ITEMS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topics&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;[]],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eventName&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OrderFilled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makerAssetId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;makerAssetId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bigint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;maker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;taker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// TODO: Check if trade is Buy if yes, then log details along with price per share&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makerAssetId&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pricePerShare&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;formatRatio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;takerAmountFilled&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`[BUY] block=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; tx=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transactionHash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; maker=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;maker&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; taker=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;taker&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; pricePerShare=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pricePerShare&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Project
&lt;/h2&gt;

&lt;p&gt;You can check the project code in this repo: &lt;a href="https://github.com/enviodev/track-poly-trades" rel="noopener noreferrer"&gt;https://github.com/enviodev/track-poly-trades&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the full production-scale Polymarket indexer covering all 8 subgraph domains and 4 billion events, see the &lt;a href="https://docs.envio.dev/blog/polymarket-hyperindex-case-study" rel="noopener noreferrer"&gt;Polymarket HyperIndex Case Study&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Poly-Whales TUI
&lt;/h2&gt;

&lt;p&gt;Don’t want to set up the full project but still want to try it out? You can use the Poly-Whales TUI.&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpx poly-whales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Furbsl6y2a79v35a26k0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Furbsl6y2a79v35a26k0w.png" alt="Terminal UI titled &amp;quot;Polymarket Whale Tracker&amp;quot; with a $500 threshold panel, watch addresses panel, and a live trades list of BUY orders with USD amounts, maker addresses, and timestamps" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why use HyperSync for Polymarket trade tracking instead of RPC?
&lt;/h3&gt;

&lt;p&gt;HyperSync provides up to 2,000x faster data access than standard RPC and exposes a streaming interface tailored to filtered event queries. For Polymarket's high-throughput Exchange contracts on Polygon, this avoids the RPC rate limits and polling overhead that constrain real-time trade trackers built on standard JSON-RPC. Polygon is one of 80+ EVM chains with native HyperSync coverage, and HyperSync client libraries are available for TypeScript/Node.js, Python, Rust, and Go.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I track Polymarket trades in real time?
&lt;/h3&gt;

&lt;p&gt;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 &lt;code&gt;makerAssetId&lt;/code&gt; of 0 indicates a buy trade.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I identify buy vs sell trades on Polymarket?
&lt;/h3&gt;

&lt;p&gt;In the OrderFilled event, if &lt;code&gt;makerAssetId&lt;/code&gt; is 0, the order is a buy where the maker is spending USDC to purchase shares. If &lt;code&gt;makerAssetId&lt;/code&gt; is non-zero, the order is a sell. Price per share for a buy trade is &lt;code&gt;makerAmountFilled / takerAmountFilled&lt;/code&gt;, formatted to 6 decimal places.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the Polymarket Exchange contract addresses on Polygon?
&lt;/h3&gt;

&lt;p&gt;The Polymarket Exchange contracts on Polygon are &lt;code&gt;0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e&lt;/code&gt; and &lt;code&gt;0xc5d563a36ae78145c45a50134d48a1215220f80a&lt;/code&gt;. The OrderFilled event topic0 is &lt;code&gt;0xd0a08e8c493f9c94f29311604c9de1b4e8c8d4c06bd0c789af57f2d65bfec0f6&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there a ready-made Polymarket trade tracker I can run?
&lt;/h3&gt;

&lt;p&gt;Yes. The full project is available at &lt;a href="https://github.com/enviodev/track-poly-trades" rel="noopener noreferrer"&gt;github.com/enviodev/track-poly-trades&lt;/a&gt;. For a terminal UI version, run &lt;code&gt;pnpx poly-whales&lt;/code&gt; to launch the Poly-Whales TUI, which tracks Polymarket whale activity in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build With Envio
&lt;/h2&gt;

&lt;p&gt;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 &lt;a href="https://docs.envio.dev/docs/HyperIndex/overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, run the benchmarks yourself, and come talk to us about your data needs.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates by subscribing to our newsletter, following us on X, or hopping into our Discord.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.beehiiv.com/subscribe?utm_source=envio.beehiiv.com&amp;amp;utm_medium=newsletter&amp;amp;utm_campaign=new-post" rel="noopener noreferrer"&gt;Subscribe to our newsletter&lt;/a&gt; 💌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://envio.dev/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; | &lt;a href="https://twitter.com/envio_indexer" rel="noopener noreferrer"&gt;X&lt;/a&gt; | &lt;a href="https://discord.gg/envio" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | &lt;a href="https://t.me/+BeS5ihVUFONjNGFk" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | &lt;a href="https://github.com/enviodev" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://www.youtube.com/channel/UCR7nZ2yzEtc5SZNM0dhrkhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.reddit.com/user/Envio_indexer" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
