> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# EVM RPC

The EVM RPC provider extracts Ethereum, and chains compatible with its virtual machine (the EVM) like Base, Arbitrum,
or Polygon, from a standard JSON-RPC endpoint: the API every Ethereum node and node provider serves. [Raw
datasets](/datasets/raw-datasets) of kind `evm-rpc` extract through it into three tables: blocks, transactions with
their receipts, and event logs (see [EVM RPC Tables](/datasets/tables/evm-rpc)).

## Prerequisites

* A running Amp you can manage, like one in [solo mode](/running-amp/solo-mode), and [`ampctl`](/clis/ampctl).
* A JSON-RPC endpoint for the chain, over HTTP, WebSocket, or a local IPC socket. It must serve
  `eth_getBlockByNumber`, and `eth_getBlockReceipts` unless you set [`fetch_receipts_per_tx`](/providers/evm-rpc#receipts). To extract
  history, it must keep the blocks and receipts you extract: some endpoints drop old ones.
* The endpoint's URL in the environment `ampd` runs in. The examples extract Ethereum mainnet from block 24,000,000, so
  the endpoint must serve that block and its receipts:

  ```bash
  export RPC_URL=…
  ```

  Amp reads it when it extracts, not when you register the provider (see
  [Environment variables](/providers#environment-variables)).

To try Amp without a node provider, run a local chain with Anvil, from
[Foundry](https://getfoundry.sh): its endpoint is `http://127.0.0.1:8545`, and its network is `anvil`.

## Configure the provider

The minimal configuration names the network and the endpoint:

```toml [mainnet.toml]
kind = "evm-rpc"
network = "mainnet"
url = "${RPC_URL}"
```

A fuller one, for a node provider that limits requests and expects its key in a header:

```toml [mainnet.toml]
kind = "evm-rpc"
network = "mainnet"
url = "https://lb.drpc.org/ogrpc?network=ethereum"
auth_header = "Drpc-Key"
auth_token = "${DRPC_KEY}"
rate_limit_per_minute = 600
concurrent_request_limit = 64
timeout_secs = 60
```

* `network`: the network's name, like `mainnet`, `base`, or `arbitrum-one`. It must match your datasets' `network`.
* `url`: the endpoint. Its scheme picks the connection: `http://` or `https://`, `ws://` or `wss://` for WebSocket,
  and `ipc://` followed by a socket's path for a node on the same machine, like `ipc:///home/user/.ethereum/geth.ipc`.
* `auth_token`: a token Amp sends with each request, as `Authorization: Bearer <token>`. Amp keeps it out of its logs.
* `auth_header`: sends the token in this header instead, as is, for endpoints that expect their key in their own
  header.
* `rate_limit_per_minute`: the most requests Amp sends per minute. Set it to your plan's limit.
* `concurrent_request_limit`: the most requests Amp has in flight at once. Defaults to `1024`.
* `timeout_secs`: how long Amp waits for a response before it fails the request and retries. Defaults to `30`.

The [configuration reference](/providers/configuration-reference#evm-rpc) lists every field, with its type and default.
Over IPC, Amp ignores `auth_token`, `auth_header`, and `timeout_secs`.

## Register it and extract a chain

::::steps
### Register the provider

```bash
ampctl provider register mainnet_rpc ./mainnet.toml
```

### Create a dataset

Generate a manifest for the network, register it, and deploy it, here for the 100 blocks from 24,000,000 to 24,000,099:

```bash
ampctl manifest generate --kind evm-rpc --network mainnet --start-block 24000000 -o eth_mainnet.json
ampctl dataset register acme/eth_mainnet ./eth_mainnet.json --tag 1.0.0
ampctl dataset deploy acme/eth_mainnet@1.0.0 --end-block 24000099
```

[Raw Datasets](/datasets/raw-datasets#create-a-raw-dataset) walks through these steps and their output.

### Query it

:::terminal
```bash
ampsql 'SELECT block_num, timestamp, gas_used FROM "acme/eth_mainnet".blocks ORDER BY block_num LIMIT 3'
```

```
+-----------+----------------------+----------+
| block_num | timestamp            | gas_used |
+-----------+----------------------+----------+
| 24000000  | 2025-12-13T00:06:11Z | 57860235 |
| 24000001  | 2025-12-13T00:06:23Z | 27660983 |
| 24000002  | 2025-12-13T00:06:35Z | 17602635 |
+-----------+----------------------+----------+
```
:::
::::

## Receipts

A transaction's receipt holds its outcome: whether it succeeded, the gas it used, and its logs. Amp needs every
receipt of each block it extracts, and gets them one of two ways:

* **By block**, the default: one `eth_getBlockReceipts` call per block. Fast, but not every endpoint serves it.
* **By transaction**, with `fetch_receipts_per_tx = true`: one `eth_getTransactionReceipt` call per transaction.
  Every endpoint serves it, but it takes many more requests, which count against your rate limit.

Use the default unless your endpoint lacks `eth_getBlockReceipts`.

## Rate limits and concurrency

Node providers limit how many requests you send. Set `rate_limit_per_minute` to your plan's limit, so Amp spaces its
requests out instead of hitting the limit and retrying. For 10 requests per second:

```toml
rate_limit_per_minute = 600
```

The limits apply to each provider separately, within one job: two jobs using the same provider, or two workers, each
send up to the limit. To extract faster than one endpoint allows, register several providers for the same network: a job
spreads its requests over all of them (see [How datasets find their
provider](/providers#how-datasets-find-their-provider)).

## Final blocks

By default, Amp extracts each block as soon as the endpoint reports it. When a dataset's manifest sets
`finalized_blocks_only`, Amp only extracts up to the endpoint's `finalized` block, which
[reorgs](/get-started/concepts/reorgs) can't replace. See [Finalized blocks](/datasets/raw-datasets#finalized-blocks).

## Limitations

* IPC only reaches a node on the same machine as the `ampd` that extracts.
* Some chains report values too large for a column's type, like a `difficulty` past 38 digits: Amp stores them as
  `NULL`.

## Errors

### `No provider found for kind 'evm-rpc' and network 'mainnet'`

No usable provider matches the dataset's network. Check `ampctl provider list`, the provider's `network`, and that the
variables its configuration uses are set where `ampd` runs (see [Environment
variables](/providers#environment-variables)).

### `HTTP status client error (403 Forbidden)`

The endpoint refused Amp's requests, often because the key is missing or wrong: dRPC answers this way to a key that
isn't valid. The job fails with `Failed to get latest block number`, which the
[dataset's status](/managing-amp/dataset-status) shows, and retries. Check the key, that the variable `auth_token` names
is set where `ampd` runs, and that `auth_header` is the header the endpoint expects.
