npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@eth-optimism/data-transport-layer

v0.1.3

Published

## What is this?

Readme

@eth-optimism/data-transport-layer

What is this?

The Optimistic Ethereum Data Transport Layer is a long-running software service (written in TypeScript) designed to reliably index Optimistic Ethereum transaction data from Layer 1 (Ethereum). Specifically, this service indexes:

  • Transactions that have been enqueued for submission to the CanonicalTransactionChain via enqueue.
  • Transactions that have been included in the CanonicalTransactionChain via appendQueueBatch or appendSequencerBatch.
  • State roots (transaction results) that have been published to the StateCommitmentChain via appendStateBatch.

How does it work?

We run two sub-services, the L1IngestionService and the L1TransportServer. The L1IngestionService is responsible for querying for the various events and transaction data necessary to accurately index information from our Layer 1 (Ethereum) smart contracts. The L1TransportServer simply provides an API for accessing this information.

Getting started

Configuration

See an example config at .env.example; copy into a .env file before running.

L1_TRANSPORT__L1_RPC_ENDPOINT can be the JSON RPC endpoint of any L1 Ethereum node. L1_TRANSPORT__ADDRESS_MANAGER should be the contract addresss of the Address Manager on the corresponding network; find their values in the Regenesis repo.

Building and usage

After cloning and switching to the repository, install dependencies:

$ yarn

Use the following commands to build, use, test, and lint:

$ yarn build
$ yarn start
$ yarn test
$ yarn lint

Configuration

We're using dotenv for our configuration. Copy .env.example into .env, feel free to modify it. Here's the list of environment variables you can change:

| Variable | Default | Description | | ------------------------------------------------------- | --------- | ------------ | | DATA_TRANSPORT_LAYER__DB_PATH | ./db | Path to the database for this service. | | DATA_TRANSPORT_LAYER__ADDRESS_MANAGER | - | Address of the AddressManager contract on L1. See regenesis repo to find this address for mainnet or kovan. | | DATA_TRANSPORT_LAYER__POLLING_INTERVAL | 5000 | Period of time between execution loops. | | DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS | false | If true, will catch all errors without throwing. | | DATA_TRANSPORT_LAYER__CONFIRMATIONS | 12 | Number of confirmations to wait before accepting transactions as "canonical". | | DATA_TRANSPORT_LAYER__SERVER_HOSTNAME | localhost | Host to run the API on. | | DATA_TRANSPORT_LAYER__SERVER_PORT | 7878 | Port to run the API on. | | DATA_TRANSPORT_LAYER__SYNC_FROM_L1 | true | Whether or not to sync from L1. | | DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT | - | RPC endpoint for an L1 node. | | DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL | 2000 | Logs to sync per polling interval. | | DATA_TRANSPORT_LAYER__SYNC_FROM_L2 | false | Whether or not to sync from L2. | | DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT | - | RPC endpoint for an L2 node. | | DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL | 1000 | Number of L2 transactions to query per polling interval. | | DATA_TRANSPORT_LAYER__L2_CHAIN_ID | - | L2 chain ID. | | DATA_TRANSPORT_LAYER__LEGACY_SEQUENCER_COMPATIBILITY | false | Whether or not to enable "legacy" sequencer sync (without the custom eth_getBlockRange endpoint) |

HTTP API

This section describes the HTTP API for accessing indexed Layer 1 data.

Latest Ethereum Block Context

Request

GET /eth/context/latest

Response

{
    "blockNumber": number,
    "timestamp": number
}

Enqueue by Index

Request

GET /enqueue/index/{index: number}

Response

{
  "index": number,
  "target": string,
  "data": string,
  "gasLimit": number,
  "origin": string,
  "blockNumber": number,
  "timestamp": number
}

Transaction by Index

Request

GET /transaction/index/{index: number}

Response

{
    "transaction": {
        "index": number,
        "batchIndex": number,
        "data": string,
        "blockNumber": number,
        "timestamp": number,
        "gasLimit": number,
        "target": string,
        "origin": string,
        "queueOrigin": string,
        "type": string | null,
        "decoded": {
            "sig": {
                "r": string,
                "s": string,
                "v": string
            },
            "gasLimit": number,
            "gasPrice": number,
            "nonce": number,
            "target": string,
            "data": string
        } | null,
        "queueIndex": number | null,
    },
    
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    }
}

Transaction Batch by Index

Request

GET /batch/transaction/index/{index: number}

Response

{
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
    
    "transactions": [
      {
        "index": number,
        "batchIndex": number,
        "data": string,
        "blockNumber": number,
        "timestamp": number,
        "gasLimit": number,
        "target": string,
        "origin": string,
        "queueOrigin": string,
        "type": string | null,
        "decoded": {
            "sig": {
                "r": string,
                "s": string,
                "v": string
            },
            "gasLimit": number,
            "gasPrice": number,
            "nonce": number,
            "target": string,
            "data": string
        } | null,
        "queueIndex": number | null,
      }
    ]
}

State Root by Index

Request

GET /stateroot/index/{index: number}

Response

{
    "stateRoot": {
        "index": number,
        "batchIndex": number,
        "value": string
    },

    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
}

State Root Batch by Index

Request

GET /batch/stateroot/index/{index: number}

Response

{
    "batch": {
        "index": number,
        "blockNumber": number,
        "timestamp": number,
        "submitter": string,
        "size": number,
        "root": string,
        "prevTotalElements": number,
        "extraData": string
    },
    
    "stateRoots": [
        {
            "index": number,
            "batchIndex": number,
            "value": string
        }
    ]
}