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
orappendSequencerBatch
. - State roots (transaction results) that have been published to the StateCommitmentChain via
appendStateBatch
.
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.
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.
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
This section describes the HTTP API for accessing indexed Layer 1 data.
GET /eth/context/latest
{
"blockNumber": number,
"timestamp": number
}
GET /enqueue/index/{index: number}
{
"index": number,
"target": string,
"data": string,
"gasLimit": number,
"origin": string,
"blockNumber": number,
"timestamp": number
}
GET /transaction/index/{index: number}
{
"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
}
}
GET /batch/transaction/index/{index: number}
{
"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,
}
]
}
GET /stateroot/index/{index: number}
{
"stateRoot": {
"index": number,
"batchIndex": number,
"value": string
},
"batch": {
"index": number,
"blockNumber": number,
"timestamp": number,
"submitter": string,
"size": number,
"root": string,
"prevTotalElements": number,
"extraData": string
},
}
GET /batch/stateroot/index/{index: number}
{
"batch": {
"index": number,
"blockNumber": number,
"timestamp": number,
"submitter": string,
"size": number,
"root": string,
"prevTotalElements": number,
"extraData": string
},
"stateRoots": [
{
"index": number,
"batchIndex": number,
"value": string
}
]
}