---
title: "Flashblocks RPC"
description: "Read preconfirmed Base state and stream sub-block updates over JSON-RPC and WebSocket."
source: https://basehub.org/integration-guides/flashblocks-rpc/
---
import CodeColumns from '../../../components/CodeColumns.astro';

Flashblocks are sub-block preconfirmations produced every 200ms on Base. Read preconfirmed balances, nonces, receipts, and block data through standard JSON-RPC, or stream every flashblock as it lands.

## Overview

A single Base block (produced every 2 seconds) is divided into ten **flashblocks** streamed at 200ms intervals. Each flashblock is a delta containing new transactions and the resulting state changes. The Flashblocks RPC exposes this preconfirmed state through the standard Ethereum JSON-RPC interface by supporting the `"pending"` block tag.

```
Block N (2s)
├── Flashblock 0  (0ms)
├── Flashblock 1  (200ms)
├── Flashblock 2  (400ms)
├── Flashblock 3  (600ms)
├── Flashblock 4  (800ms)
├── Flashblock 5  (1000ms)
├── Flashblock 6  (1200ms)
├── Flashblock 7  (1400ms)
├── Flashblock 8  (1600ms)
└── Flashblock 9  (1800ms)
Block N+1 (2s)
└── ...
```

## Querying preconfirmed state

Pass `"pending"` to any supported JSON-RPC method to read the latest preconfirmed state. The same call against `"latest"` returns the last sealed block.

### Check an account balance

<CodeColumns>
<div>

`eth_getBalance` with the `"pending"` tag returns the balance reflecting every transaction included in the most recent flashblock — usually within 200ms of the user's submission.

The hex `result` is the balance in wei.

</div>

```bash
curl -X POST https://your-base-rpc-endpoint \
  -H "Content-Type: application/json" \
  -d '{
    "method": "eth_getBalance",
    "params": ["0xYourAddress", "pending"],
    "id": 1,
    "jsonrpc": "2.0"
  }'

# {
#   "id": 1,
#   "jsonrpc": "2.0",
#   "result": "0x1bc16d674ec80000"
# }
```

</CodeColumns>

### Get a transaction receipt

<CodeColumns>
<div>

After submitting a transaction, poll `eth_getTransactionReceipt` immediately — no need to wait for the next sealed block.

A preconfirmed receipt is identifiable by its zero `blockHash`. Once the parent block seals, the same receipt comes back with a real block hash.

</div>

```bash
curl -X POST https://your-base-rpc-endpoint \
  -H "Content-Type: application/json" \
  -d '{
    "method": "eth_getTransactionReceipt",
    "params": ["0xYourTxHash"],
    "id": 1,
    "jsonrpc": "2.0"
  }'

# {
#   "result": {
#     "transactionHash": "0x...",
#     "blockHash": "0x000...000",
#     "blockNumber": "0x123",
#     "status": "0x1",
#     "gasUsed": "0x5208",
#     "logs": []
#   }
# }
```

</CodeColumns>

### Get the pending block

<CodeColumns>
<div>

`eth_getBlockByNumber` with `"pending"` returns the in-progress block including every transaction landed in flashblocks so far.

Pass `true` as the second parameter for full transaction objects, `false` for hashes only.

</div>

```bash
curl -X POST https://your-base-rpc-endpoint \
  -H "Content-Type: application/json" \
  -d '{
    "method": "eth_getBlockByNumber",
    "params": ["pending", true],
    "id": 1,
    "jsonrpc": "2.0"
  }'
```

</CodeColumns>

### Get the pending nonce

<CodeColumns>
<div>

`eth_getTransactionCount` against `"pending"` returns a nonce that already accounts for transactions sitting in flashblocks.

This avoids nonce collisions when an account submits many transactions in rapid succession.

</div>

```bash
curl -X POST https://your-base-rpc-endpoint \
  -H "Content-Type: application/json" \
  -d '{
    "method": "eth_getTransactionCount",
    "params": ["0xYourAddress", "pending"],
    "id": 1,
    "jsonrpc": "2.0"
  }'

# {
#   "result": "0x5"
# }
```

</CodeColumns>

## Using ethers.js or viem

### ethers.js

<CodeColumns>
<div>

Pass `"pending"` as the block tag to any read method to get preconfirmed values.

For receipts, poll `getTransactionReceipt` on a 200ms interval — that matches the flashblock cadence.

</div>

```javascript
import { JsonRpcProvider } from "ethers";

const provider = new JsonRpcProvider("https://your-base-rpc-endpoint");

const balance = await provider.getBalance("0xYourAddress", "pending");
const nonce = await provider.getTransactionCount("0xYourAddress", "pending");

async function waitForFlashblockReceipt(txHash, intervalMs = 200) {
  while (true) {
    const receipt = await provider.getTransactionReceipt(txHash);
    if (receipt) return receipt;
    await new Promise((r) => setTimeout(r, intervalMs));
  }
}
```

</CodeColumns>

### viem

<CodeColumns>
<div>

viem accepts `blockTag: "pending"` on every read method. Receipts return as soon as the transaction is included in a flashblock.

</div>

```typescript
import { createPublicClient, http } from "viem";
import { base } from "viem/chains";

const client = createPublicClient({
  chain: base,
  transport: http("https://your-base-rpc-endpoint"),
});

const balance = await client.getBalance({
  address: "0xYourAddress",
  blockTag: "pending",
});

const nonce = await client.getTransactionCount({
  address: "0xYourAddress",
  blockTag: "pending",
});

const receipt = await client.getTransactionReceipt({
  hash: "0xYourTxHash",
});
```

</CodeColumns>

## WebSocket streaming

For real-time updates, connect to the WebSocket endpoint and subscribe to `flashblocks_v1`. Each flashblock arrives as it is produced — five times per second.

### Subscribing

<CodeColumns>
<div>

Open a WebSocket, send an `eth_subscribe` request with the `flashblocks_v1` topic, and handle each `eth_subscription` message as it arrives.

`flashblock.diff` carries the new transactions and state changes since the previous flashblock; `flashblock.index` runs from 0 to 9 within each parent block.

</div>

```javascript
import WebSocket from "ws";

const ws = new WebSocket("wss://your-base-ws-endpoint");

ws.on("open", () => {
  ws.send(
    JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "eth_subscribe",
      params: ["flashblocks_v1"],
    })
  );
});

ws.on("message", (data) => {
  const msg = JSON.parse(data);

  if (msg.method === "eth_subscription") {
    const flashblock = msg.params.result;
    console.log("Index:", flashblock.index);
    console.log("Txs:", flashblock.diff.transactions?.length ?? 0);
  }
});
```

</CodeColumns>

### Flashblock payload structure

Each streamed flashblock contains:

| Field | Description |
|-------|-------------|
| `payload_id` | Identifier for the parent payload (block being built). |
| `index` | Flashblock index within the current block (0, 1, 2, ...). |
| `base` | Present only on index 0. Contains the base execution payload. |
| `diff` | Delta of transactions, receipts, and state changes since the previous flashblock. |
| `metadata` | Additional metadata, including the flashblock access list if enabled. |

## Error handling and fallback

### Automatic fallback

When the `"pending"` tag is used but no preconfirmed data is available — for example, during sequencer downtime or between blocks — the RPC falls back to the `"latest"` confirmed state. That means:

- Applications do not need special error handling for missing flashblock state.
- Results are always consistent: either preconfirmed or latest confirmed.
- The caller cannot distinguish a "pending equals latest" response from a fallback, so applications should not assume the data is fresher than the latest block.

### Error responses

Standard JSON-RPC error codes apply:

| Scenario | Behavior |
|----------|----------|
| Invalid method parameters | Standard JSON-RPC error response with error code and message. |
| Transaction not found | `null` result (not an error). |
| Block not found | `null` result (not an error). |
| Flashblocks disabled | Falls back to standard RPC behavior. No error is returned. |

### Detecting preconfirmed vs. finalized

<CodeColumns>
<div>

A preconfirmed receipt can be identified by its `blockHash`:

- **Preconfirmed** — `blockHash` is the zero hash.
- **Finalized** — `blockHash` is a real block hash.

</div>

```javascript
function isPreconfirmed(receipt) {
  return (
    receipt.blockHash ===
    "0x0000000000000000000000000000000000000000000000000000000000000000"
  );
}
```

</CodeColumns>

## Further reading

- [Flashblocks specification](/specifications/flashblocks/) — full RPC method reference with parameter and return type details.
- [Access lists specification](/specifications/access-lists/) — the FAL spec that accompanies flashblocks.
- [Flashblocks pipeline](/architecture/flashblocks-pipeline/) — how flashblocks are produced and streamed internally.
