> For the complete documentation index, see [llms.txt](https://docs.envio.dev/llms.txt).

## Introduction

This tutorial will guide you through indexing Optimism Standard Bridge deposits in under 5 minutes using Envio HyperIndex's no-code [contract import](/docs/HyperIndex/quickstart) feature.

The Optimism Standard Bridge enables the movement of ETH and ERC-20 tokens between Ethereum and Optimism. We'll index bridge deposit events by extracting `DepositFinalized` logs on Optimism and `ETHDepositInitiated` logs on Ethereum Mainnet.

[Video](https://www.youtube.com/watch?v=9U2MTFU9or0)

## Prerequisites

Before starting, ensure you have the following installed:

- **[Node.js](https://nodejs.org/en/download/current)** _(v22 or newer recommended)_
- **[pnpm](https://pnpm.io/installation)** _(recommended but not required)_
- **[Docker Desktop](https://www.docker.com/products/docker-desktop/)** _(required to run the Envio indexer locally)_

> **Note:** Docker is specifically required to run your blockchain indexer locally. You can skip Docker installation if you plan only to use Envio Cloud.

## Step 1: Initialize Your Indexer

1. Open your terminal in an empty directory and run:

```bash
pnpx envio init
```

2. Enter a folder name for your indexer (we'll use "optimism-bridge-indexer" in this example). The indexer takes its name from the folder.

```
? Specify a folder name (ENTER to skip):  (.) optimism-bridge-indexer
```

The indexer is generated in TypeScript by default.

## Step 2: Import the Optimism Bridge Contract

1. Select **Evm** → **From Address - Lookup ABI from block explorer** → **optimism** (type to filter the chain list)

2. Enter the Optimism bridge contract address:

   ```
   0x4200000000000000000000000000000000000010
   ```

   [View on Optimistic Etherscan](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000010)

3. Select only the `DepositFinalized` event. All events start selected, so:
   - Press ← to clear all
   - Move to `DepositFinalized` with the arrow keys (↑↓)
   - Press spacebar to select it, then Enter

> **Tip:** You can select multiple events to index simultaneously.

## Step 3: Add the Ethereum Mainnet Bridge Contract

1. When prompted, select **Add a new contract (with a different ABI)**

2. Choose **Block Explorer** → **ethereum-mainnet**

3. Enter the Ethereum Mainnet gateway contract address:

   ```
   0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1
   ```

   [View on Etherscan](https://etherscan.io/address/0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1)

4. Select only the `ETHDepositInitiated` event (press ← to clear all, then space on `ETHDepositInitiated`, then Enter)

5. When finished adding contracts, select **I'm finished**

6. Add your Envio API token. Pick **Create a new API token** to open the token page, or **Add an existing API token**, then paste it at the `? Add your API token:` prompt:

```
? Add an Envio API token to your .env file?
> Create a new API token (Opens https://envio.dev/app/api-tokens)
  Add an existing API token
```

## Step 4: Start Your Indexer

1. If you have any running indexers, stop them first:

```bash
pnpm envio stop
```

2. Start your new indexer:

```bash
pnpm dev
```

This command:

- Starts the required Docker containers
- Sets up your database
- Launches the indexing process
- Opens the Hasura GraphQL interface

## Step 5: Understanding the Generated Code

Let's examine the key files that Envio generated:

### 1. `config.yaml`

This configuration file defines:

- Chains to index (Optimism and Ethereum Mainnet)
- Starting blocks for each chain
- Contract addresses and ABIs
- Events to track

```yaml title="config.yaml"
# yaml-language-server: $schema=./node_modules/envio/evm.schema.json
name: optimism-bridge-indexer
disable_default_cross_chain: true
chains:
- id: 1
  start_block: 0
  contracts:
  - name: L1ChugSplashProxy
    address:
    - "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"
    events:
    - event: ETHDepositInitiated(address indexed from, address indexed to, uint256 amount, bytes extraData)
- id: 10
  start_block: 0
  contracts:
  - name: Proxy
    address:
    - "0x4200000000000000000000000000000000000010"
    events:
    - event: DepositFinalized(address indexed l1Token, address indexed l2Token, address indexed from, address to, uint256 amount, bytes extraData)
```

### 2. `schema.graphql`

This schema defines the data structures for our selected events:

- Entity types based on event data
- Field types matching the event parameters
- Relationships between entities (if applicable)

```graphql title="schema.graphql"
type L1ChugSplashProxy_ETHDepositInitiated {
  id: ID!
  from: String!
  to: String!
  amount: BigInt!
  extraData: String!
}

type Proxy_DepositFinalized {
  id: ID!
  l1Token: String!
  l2Token: String!
  from: String!
  to: String!
  amount: BigInt!
  extraData: String!
}
```

### 3. `src/handlers`

This folder has one file per contract (`Proxy.ts` and `L1ChugSplashProxy.ts`) containing the business logic for processing events:

- Functions that execute when events are detected
- Data transformation and storage logic
- Entity creation and relationship management

```typescript title="src/handlers/Proxy.ts"
/*
 * Please refer to https://docs.envio.dev for a thorough guide on all Envio indexer features
 */
import { indexer } from "envio";
import type {
  Proxy_DepositFinalized,
} from "envio";

indexer.onEvent({ contract: "Proxy", event: "DepositFinalized" }, async ({ event, context }) => {
  const entity: Proxy_DepositFinalized = {
    id: `${event.chainId}_${event.block.number}_${event.logIndex}`,
    l1Token: event.params.l1Token,
    l2Token: event.params.l2Token,
    from: event.params.from,
    to: event.params.to,
    amount: event.params.amount,
    extraData: event.params.extraData,
  };

  context.Proxy_DepositFinalized.set(entity);
});
```

## Step 6: Exploring Your Indexed Data

Now you can interact with your indexed data:

### Accessing Hasura

1. Open Hasura at [http://localhost:8080](http://localhost:8080)
2. When prompted, enter the admin password: `testing`

### Monitoring Indexing Progress

In the **API** tab, run this query to see which blocks each chain has processed:

```graphql
query IndexingProgress {
  _meta {
    chainId
    progressBlock
    sourceBlock
    eventsProcessed
    isReady
  }
}
```

> **Note:** Thanks to Envio's [HyperSync](https://docs.envio.dev/docs/hypersync), indexing happens significantly faster than with standard RPC methods.

### Querying Indexed Events

1. Click the **API** tab
2. Construct a GraphQL query to explore your data

Entity names follow the `<ContractName>_<EventName>` pattern. The block explorer names the Optimism contract `Proxy` and the Ethereum Mainnet contract `L1ChugSplashProxy`, so the tables are `Proxy_DepositFinalized` and `L1ChugSplashProxy_ETHDepositInitiated`.

Here's an example query to fetch the 10 largest bridge deposits:

```graphql
query LargestDeposits {
  Proxy_DepositFinalized(limit: 10, order_by: { amount: desc }) {
    l1Token
    l2Token
    from
    to
    amount
  }
}
```

3. Click the **Play** button to execute your query

## Conclusion

Congratulations! You've successfully created an indexer for Optimism Bridge deposits across both Ethereum and Optimism.

### What You've Learned

- How to initialize a multi-network indexer using Envio
- How to import contracts from different blockchains
- How to query and explore indexed blockchain data

### Next Steps

- Try customizing the event handlers to add additional logic
- Create relationships between events on different networks
- Deploy your indexer to Envio Cloud

For more tutorials and advanced features, check out our [documentation](https://docs.envio.dev) or watch our [video walkthroughs](https://www.youtube.com/watch?v=9U2MTFU9or0) on YouTube.
