# Examples (Carbon 2.0)

> Every runnable example in the Carbon 2.0.0 repository, what it shows, what it needs, the command to run it and the output to expect.

The Carbon repository ships nine example pipelines in [`examples/`](https://github.com/sevenlabs-hq/carbon/tree/v2.0.0/examples). Each one is a small, complete indexer for one pattern. Use this page to pick one, check what it needs, and run it from a checkout of the `v2.0.0` tag.

| Example                                               | Shows                                                 | Datasource                                                 | Decoder                               | Needs                                                  |
| ----------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------ |
| [`versioned-decoders`](#versioned-decoders)           | Two decoder versions routed by slot                   | Mock, in the example                                       | Two generated `simple-dex` decoders   | Nothing                                                |
| [`gpa-rpc`](#gpa-rpc)                                 | One-shot load of a program's accounts                 | `GpaDatasource`                                            | `carbon-marginfi-v2-decoder`          | Public RPC works                                       |
| [`transaction-crawler-rpc`](#transaction-crawler-rpc) | Backfill a program's transaction history              | `RpcTransactionCrawler`                                    | `carbon-meteora-dlmm-decoder`         | Public RPC works, slowly                               |
| [`custom-datasource`](#custom-datasource)             | Writing your own `Datasource`                         | `HttpPollDatasource`, in the example                       | `carbon-jupiter-swap-decoder`         | Public RPC works, slowly                               |
| [`block-subscribe-rpc`](#block-subscribe-rpc)         | Real-time blocks over WebSocket                       | `RpcBlockSubscribe`                                        | `carbon-raydium-clmm-decoder`         | An RPC provider with `blockSubscribe`                  |
| [`yellowstone-grpc`](#yellowstone-grpc)               | Real-time transactions over Geyser gRPC               | `YellowstoneGrpcGeyserClient` or `LaserStreamGeyserClient` | `carbon-jupiter-swap-decoder`         | A Yellowstone or LaserStream endpoint                  |
| [`postgres-graphql`](#postgres-graphql)               | Persist accounts to Postgres, serve them with GraphQL | `YellowstoneGrpcGeyserClient`                              | `carbon-token-program-decoder`        | Postgres and a Yellowstone endpoint                    |
| [`snapshot-validator`](#snapshot-validator)           | Load accounts from a validator snapshot               | `SnapshotDatasource`                                       | A pass-through decoder in the example | `libclang`, a snapshot, lots of disk                   |
| [`jetstreamer`](#jetstreamer)                         | Archive backfill over Old Faithful                    | `JetstreamerDatasource` (Carbon 1)                         | `carbon-token-2022-decoder`           | A Carbon 1 project; doesn't build in the 2.0 workspace |

## Run an example

Every example except `jetstreamer` is a member of the Carbon workspace, so you build it from a checkout of the repository. You need Rust 1.96.1 (the checkout's `rust-toolchain.toml` pins it, and `rustup` installs it on first use) and a few GB of disk for the first build.

```sh
git clone --branch v2.0.0 https://github.com/sevenlabs-hq/carbon.git
cd carbon/examples/gpa-rpc
RPC_URL=https://api.mainnet-beta.solana.com RUST_LOG=info cargo run --release -p gpa-rpc-carbon-example
```

Git prints a "detached HEAD" note after the clone; that's expected for a tag checkout. The first build compiles the Solana dependencies and takes a few minutes; later runs start in seconds.

Two things apply to every example:

- **Logging.** Examples print through `log` and `env_logger`, so nothing appears unless `RUST_LOG` is set. `RUST_LOG=info` shows decoded items and the [`LogMetrics`](https://carbon.sevenlabs.org/concepts/metrics.md) summary every five seconds; `RUST_LOG=debug` also shows the variants the processors log at debug level.
- **`.env` files.** Each example calls `dotenv::dotenv()`, which reads a `.env` file from the current directory or one of its parents. Put the file in the example's directory and run `cargo run` from there. Running from the repository root doesn't pick up `examples/<name>/.env`. Setting the variables inline, as in the commands on this page, works from anywhere.

## `versioned-decoders`

Indexes a program that was upgraded with a breaking instruction layout change. A fictional DEX adds a `fee_tier: u8` field to `Swap` at slot 500, transaction index 10. The example registers two generated decoders, `carbon-simple-dex-decoder-v1` and `-v2` (in `decoder-v1/` and `decoder-v2/`, generated from the IDLs in `idls/`), each with `instruction_with_filters` and a [`SlotRangeFilter`](https://carbon.sevenlabs.org/reference/filters.md) so every instruction reaches only the version that was live at its slot. One processor implements `Processor` for both instruction types and normalizes them to a shared struct.

The datasource is a mock inside `src/main.rs` that sends four synthetic transactions and returns, so the pipeline exits on its own. The pattern is explained in [Versioned decoders](https://carbon.sevenlabs.org/guides/versioned-decoders.md).

**Needs:** nothing. No environment variables, no network.

```sh
cd carbon/examples/versioned-decoders
RUST_LOG=info cargo run --release -p versioned-decoders-carbon-example
```

Output:

```text
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] === Versioned Decoders Example ===
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] Program upgrade at slot=500, tx_index=10
[2026-11-08T23:48:10Z INFO  carbon_core::pipeline] starting pipeline. num_datasources: 1, num_exporters: 0, num_account_pipes: 0, num_account_deletion_pipes: 0, num_instruction_pipes: 2, num_transaction_pipes: 0
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] [V1] Swap | slot=499 tx_idx=Some(0) | amount_in=1000000 min_amount_out=990000
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] [V1] Swap | slot=500 tx_idx=Some(9) | amount_in=2000000 min_amount_out=1980000
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] [V2] Swap | slot=500 tx_idx=Some(10) | amount_in=3000000 min_amount_out=2970000 fee_tier=5
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] [V2] Swap | slot=501 tx_idx=Some(0) | amount_in=4000000 min_amount_out=3960000 fee_tier=10
[2026-11-08T23:48:10Z INFO  carbon_core::pipeline] update_receiver closed, shutting down.
[2026-11-08T23:48:10Z INFO  carbon_core::pipeline] pipeline shutdown complete.
[2026-11-08T23:48:10Z INFO  versioned_decoders_carbon_example] Done.
```

The filters do the routing. The decoders alone can't tell the versions apart reliably: generated decoders ignore trailing bytes, so the V1 decoder also accepts V2 data and silently drops `fee_tier`.

## `gpa-rpc`

Loads every account owned by the Marginfi v2 program once, with a single `getProgramAccounts` call, decodes each into `MarginfiV2Account`, and exits when the datasource has sent everything. It logs banks and groups at `info` and user accounts at `debug`. `src/variants.rs` also has a Helius gPA v2 variant (paginated, with `changed_since_slot` for incremental syncs); switch by editing the `let datasource = …` line in `main.rs`. See [Load account state](https://carbon.sevenlabs.org/guides/load-account-state.md).

**Needs:**

| Variable         | Required                         | Used by                                                           |
| ---------------- | -------------------------------- | ----------------------------------------------------------------- |
| `RPC_URL`        | Yes, for the default RPC variant | `GpaDatasource`. The public endpoint works for Marginfi's size.   |
| `HELIUS_RPC_URL` | Only for the Helius variant      | `HeliusGpaV2Datasource`. A Helius RPC URL with the API key in it. |

```sh
cd carbon/examples/gpa-rpc
RPC_URL=https://api.mainnet-beta.solana.com RUST_LOG=info cargo run --release -p gpa-rpc-carbon-example
```

Against the public endpoint the run took about 12 seconds and processed 171,340 accounts. The end of the output:

Output:

```text
[2026-11-08T23:48:31Z INFO  gpa_rpc_carbon_example] bank pubkey=J5mxC3hLXqmsJB4Nauf9YrtbNMSTHGz7FWfAmy1v6Fzr mint=So11111111111111111111111111111111111111112 group=4qp6Fx6tnZkY5Wropq9wUYgtFxXKwE6viZxFHg3rdAG8
[2026-11-08T23:48:31Z INFO  gpa_rpc_carbon_example] group pubkey=J9VZnaMGTELGCPsqMxk8aoyEGYcVzhorj48HvtDdEtc8 admin=J525txDGqSuPisS3NQwySwDEDExVhjJNUfx94PGQUNJR
[2026-11-08T23:48:31Z INFO  carbon_core::pipeline] update_receiver closed, shutting down.
[2026-11-08T23:48:31Z INFO  carbon_log_metrics] 00:00:11 (+1.82520643s) | 171340 processed (100%), 171340 successful, 0 failed (0%), 0 in queue
[2026-11-08T23:48:31Z INFO  carbon_log_metrics]   carbon_account_updates_processed_total: 171340
[2026-11-08T23:48:31Z INFO  carbon_log_metrics]   rpc_gpa_accounts_processed_total: 171340
[2026-11-08T23:48:31Z INFO  carbon_log_metrics]   rpc_gpa_fetch_duration_milliseconds: count=1
[2026-11-08T23:48:31Z INFO  carbon_core::pipeline] pipeline shutdown complete.
[2026-11-08T23:48:31Z INFO  gpa_rpc_carbon_example] snapshot complete
```

## `transaction-crawler-rpc`

Backfills Meteora DLMM activity by walking the program's signatures backwards from the newest (`getSignaturesForAddress`), fetching each transaction (`getTransaction`), and decoding it. It logs `Swap`, `AddLiquidity` and `RemoveLiquidity` at `info` and every other instruction at `debug`. After it reaches the oldest signature it can see, it keeps polling for new ones every five seconds. `src/variants.rs` also has a Helius GTFA variant that pages through a fixed slot window and then exits. See [Backfill transactions](https://carbon.sevenlabs.org/guides/backfill-transactions.md).

**Needs:**

| Variable          | Required                         | Used by                                                                                                                                   |
| ----------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `RPC_URL`         | Yes, for the default RPC variant | `RpcTransactionCrawler`. The public endpoint works but is heavily rate limited.                                                           |
| `UNTIL_SIGNATURE` | No                               | Stops the backward walk at this signature. The crawler still keeps polling for new transactions afterwards, so the pipeline doesn't exit. |
| `HELIUS_RPC_URL`  | Only for the GTFA variant        | `HeliusGtfaDatasource`.                                                                                                                   |

```sh
cd carbon/examples/transaction-crawler-rpc
RPC_URL=https://api.mainnet-beta.solana.com RUST_LOG=info cargo run --release -p transaction-crawler-rpc-carbon-example
```

On the public endpoint, expect a handful of swaps per minute, with pauses. This excerpt is from a 60-second run that processed 17 transactions:

Output:

```text
[2026-11-08T23:48:38Z ERROR carbon_rpc_transaction_crawler_datasource] Failed to fetch signatures after 0 retries: Error { request: Some(GetSignaturesForAddress), kind: Reqwest(reqwest::Error { kind: Status(413, Some(ReasonPhrase(b"Request Entity Too Large"))), url: "https://api.mainnet-beta.solana.com/" }) }
[2026-11-08T23:48:42Z INFO  transaction_crawler_rpc_carbon_example] swap slot=467105207 sig=5FVRVLgohHkAMTsqb5M5vCKJ8xpWGuQddfMBtdaifGFeDtnHQ3TFDSBdZAsUFezqimgh2i2RB94c3qtchJScyvWz data=Swap { amount_in: 367843, min_amount_out: 0 }
[2026-11-08T23:48:42Z INFO  transaction_crawler_rpc_carbon_example] swap slot=467105207 sig=2cFZ9cJkYpQGtnyLi9TMDTFErAkxktDRdwnjiHwz2BAEYLTFLYGzGx86mmPpMbSuarJxZeeFR4BXKVUWpPiMZKfC data=Swap { amount_in: 91821913, min_amount_out: 7958851 }
[2026-11-08T23:48:46Z INFO  carbon_log_metrics] 00:00:10 (+5.00022008s) | 8 processed (100%), 8 successful, 0 failed (0%), 0 in queue
…
[2026-11-08T23:49:36Z INFO  carbon_log_metrics]   transaction_crawler_signatures_fetched_total: 1000
[2026-11-08T23:49:36Z INFO  carbon_log_metrics]   transaction_crawler_transactions_fetched_total: 26
```

The example sets `RetryConfig::no_retry()`, so a rejected `getSignaturesForAddress` call is logged once and retried on the next poll, as in the first line above. The crawler fetches a thousand signatures quickly and then waits on `getTransaction`, which the public endpoint limits hard: it answers HTTP 429 with `retry-after: 10`, and the Solana RPC client sleeps without logging anything at `info`. See [Crawler prints nothing for seconds at a time](https://carbon.sevenlabs.org/troubleshooting.md#crawler-prints-nothing-for-seconds-at-a-time).

## `custom-datasource`

A complete hand-written [`Datasource`](https://carbon.sevenlabs.org/guides/custom-datasource.md), `HttpPollDatasource`, that polls `getSignaturesForAddress` for the Jupiter v6 program every five seconds, fetches each transaction with `getTransaction` in Base64, converts the metadata with `transaction_metadata_from_original_meta`, and sends `Update::Transaction`s. It shows the parts a real source needs: cancellation checks at every sleep, a watermark (`until`) so it doesn't re-send old transactions, backoff on failed calls, skipping failed transactions, and two custom [`Counter`](https://carbon.sevenlabs.org/reference/metrics.md) metrics registered in the global registry. The processor logs the discriminant of each decoded `JupiterSwapInstruction`.

**Needs:**

| Variable  | Required | Used by                                                  |
| --------- | -------- | -------------------------------------------------------- |
| `RPC_URL` | Yes      | `HttpPollDatasource`. The public endpoint works, slowly. |

```sh
cd carbon/examples/custom-datasource
RPC_URL=https://api.mainnet-beta.solana.com RUST_LOG=info cargo run --release -p custom-datasource-carbon-example
```

Output:

```text
[2026-11-08T23:50:51Z INFO  custom_datasource_carbon_example] ix slot=467105803 sig=2r4uo4VNLHHy9KZQi4KjCFqQM4ugBJgc5tQgMS1RGjKrMzsfYoAFG9AkiGdcRL24YpY9zUziRMXMhmMZuDmhXXcx variant=Discriminant(11)
[2026-11-08T23:50:51Z INFO  custom_datasource_carbon_example] ix slot=467105803 sig=2r4uo4VNLHHy9KZQi4KjCFqQM4ugBJgc5tQgMS1RGjKrMzsfYoAFG9AkiGdcRL24YpY9zUziRMXMhmMZuDmhXXcx variant=Discriminant(9)
[2026-11-08T23:50:51Z INFO  custom_datasource_carbon_example] ix slot=467105803 sig=2r4uo4VNLHHy9KZQi4KjCFqQM4ugBJgc5tQgMS1RGjKrMzsfYoAFG9AkiGdcRL24YpY9zUziRMXMhmMZuDmhXXcx variant=Discriminant(17)
[2026-11-08T23:50:55Z INFO  carbon_log_metrics] 00:00:05 (+4.999159689s) | 2 processed (100%), 2 successful, 0 failed (0%), 0 in queue
…
[2026-11-08T23:51:49Z INFO  carbon_log_metrics]   custom_http_poll_transactions_fetched_total: 12
[2026-11-08T23:51:49Z INFO  carbon_log_metrics]   custom_http_poll_fetch_failures_total: 0
```

One transaction produces several lines because the processor runs for every Jupiter instruction in it, including inner instructions and the events Jupiter emits through self-CPI ([nested instructions](https://carbon.sevenlabs.org/concepts/instructions.md)). It runs until you press Ctrl-C; the example uses `ShutdownStrategy::Immediate`.

## `block-subscribe-rpc`

Subscribes to confirmed blocks that mention the Raydium CLMM program over the RPC WebSocket method `blockSubscribe`, decodes Raydium CLMM instructions (`Swap`, `SwapV2` and `OpenPosition` at `info`), and logs every block's header with a `block_details` processor. The `RpcBlockSubscribeConfig` it passes asks for Base64 encoding, full transaction details and `max_supported_transaction_version: Some(1)`, which Carbon 2 requires. See [Stream with RPC](https://carbon.sevenlabs.org/guides/stream-with-rpc.md).

**Needs:** an RPC provider that enables `blockSubscribe`. Solana's public endpoint doesn't.

| Variable     | Required         | Used by                                                                                                           |
| ------------ | ---------------- | ----------------------------------------------------------------------------------------------------------------- |
| `RPC_WS_URL` | In practice, yes | `RpcBlockSubscribe`. A `wss://` URL. Falls back to `wss://api.mainnet-beta.solana.com`, which rejects the method. |

```sh
cd carbon/examples/block-subscribe-rpc
RPC_WS_URL="wss://your-provider.example/?api-key=…" RUST_LOG=info cargo run --release -p block-subscribe-rpc-carbon-example
```

With a provider that supports the method, `block slot=… hash=… parent=… time=…` lines interleave with decoded `swap`, `swap_v2` and `open_position` lines. Without `RPC_WS_URL`, the run against the public endpoint looks like this and the process exits after about 40 seconds:

Output:

```text
[2026-11-08T23:51:57Z ERROR carbon_rpc_block_subscribe_datasource] Failed to subscribe to block updates: SubscribeFailed { reason: "Method not found (-32601)", message: "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32601,\"message\":\"Method not found\"},\"id\":1}" }
…
[2026-11-08T23:52:37Z ERROR carbon_core::pipeline] error consuming datasource: Custom("Failed to subscribe after 10 attempts: subscribe failed: Method not found (-32601)")
[2026-11-08T23:52:37Z INFO  carbon_core::pipeline] update_receiver closed, shutting down.
[2026-11-08T23:52:37Z INFO  carbon_core::pipeline] pipeline shutdown complete.
```

## `yellowstone-grpc`

The standard real-time setup: a Yellowstone Geyser gRPC subscription to confirmed, successful transactions that include the Jupiter v6 program (`account_required`, `vote: false`, `failed: false`), decoded with `JupiterSwapDecoder`. It logs `Route` and `SharedAccountsRoute` at `info`. `src/variants.rs` has a Helius LaserStream variant built with `LaserStreamClientConfig` and replay enabled. `main` installs the `aws_lc_rs` rustls crypto provider before connecting. See [Stream with Yellowstone gRPC](https://carbon.sevenlabs.org/guides/stream-with-yellowstone.md) and [Stream with Helius LaserStream](https://carbon.sevenlabs.org/guides/stream-with-laserstream.md).

**Needs:** a Yellowstone gRPC endpoint (Triton, Helius, QuickNode, a self-hosted Geyser plugin) or a Helius LaserStream plan.

| Variable          | Required                         | Used by                                                                           |
| ----------------- | -------------------------------- | --------------------------------------------------------------------------------- |
| `GEYSER_URL`      | Yes, for the default variant     | `YellowstoneGrpcGeyserClient`. Include the scheme and port, e.g. `https://…:443`. |
| `X_TOKEN`         | If your provider requires it     | Sent as the `x-token` header.                                                     |
| `LASERSTREAM_URL` | Only for the LaserStream variant | `LaserStreamGeyserClient`.                                                        |
| `API_KEY`         | Only for the LaserStream variant | Your Helius API key.                                                              |

```sh
cd carbon/examples/yellowstone-grpc
GEYSER_URL=https://your-yellowstone-endpoint:443 X_TOKEN=your-x-token RUST_LOG=info cargo run --release -p yellowstone-grpc-carbon-example
```

The example compiles at `v2.0.0`; it wasn't run for this page because it needs a paid endpoint. With a working endpoint, `route slot=… sig=… data=Route { … }` and `shared_accounts_route …` lines stream continuously between `LogMetrics` summaries until you press Ctrl-C. If `GEYSER_URL` is missing the example panics with `GEYSER_URL must be set: NotPresent`.

## `postgres-graphql`

Streams SPL Token account updates from Yellowstone, stores each decoded account as JSON in Postgres with `PostgresJsonAccountProcessor<TokenProgramAccount>` (Carbon's `postgres` feature), and serves a small GraphQL API over the same table with Carbon's `graphql` feature: a `mints(limit)` query and a `mint(pubkey)` lookup. The migration in `migrations/001_init.sql` creates the `accounts` table (`__pubkey BYTEA`, `__slot BIGINT`, `data JSONB`) and runs at startup. The GraphQL server starts before the pipeline, on `/graphql`, with a GraphiQL playground on `/graphiql`. See [Postgres](https://carbon.sevenlabs.org/guides/postgres.md) and [GraphQL](https://carbon.sevenlabs.org/guides/graphql.md).

**Needs:** Postgres and a Yellowstone endpoint. The subscription covers every account owned by the Token program, which is a high-volume stream.

| Variable       | Required                     | Used by                                         |
| -------------- | ---------------------------- | ----------------------------------------------- |
| `DATABASE_URL` | Yes                          | `sqlx` connection pool.                         |
| `GEYSER_URL`   | Yes                          | `YellowstoneGrpcGeyserClient`.                  |
| `X_TOKEN`      | If your provider requires it | Yellowstone `x-token`.                          |
| `BIND_ADDR`    | No                           | GraphQL server address. Default `0.0.0.0:8080`. |

The bundled `compose.yaml` starts Postgres 16 with user, password and database `carbon` / `carbon` / `carbon_example`, published on host port **5433**. The example's README uses port 5432 in `DATABASE_URL`; with the bundled database, use 5433:

```sh
cd carbon/examples/postgres-graphql
docker compose up -d
DATABASE_URL=postgres://carbon:carbon@localhost:5433/carbon_example \
GEYSER_URL=https://your-yellowstone-endpoint:443 X_TOKEN=your-x-token \
RUST_LOG=info cargo run --release -p postgres-graphql-carbon-example
```

The first log line is `graphiql at http://0.0.0.0:8080/graphiql`. Open `http://localhost:8080/graphiql` and run:

```graphql
{
  mints(limit: 5) {
    pubkey
    slot
    decimals
    supply
  }
}
```

The example compiles at `v2.0.0`; it wasn't run end to end for this page (no Postgres or Geyser endpoint was available). Without a reachable database it fails at startup with:

Output:

```text
Error: Custom("failed to connect to Postgres: pool timed out while waiting for an open connection")
```

## `snapshot-validator`

Loads accounts from a Solana validator snapshot, either downloaded or already extracted on disk, filtered by owner program or account address. A pass-through `AccountDecoder` hands each raw `Account` to the processor, which logs pubkey, slot, lamports, data size and owner; an `account_deletions` processor logs deletions. It uses `ShutdownStrategy::ProcessPending` and exits when the snapshot has been read. See [Load a snapshot](https://carbon.sevenlabs.org/guides/load-a-snapshot.md).

**Needs:**

- `libclang` at build time: `carbon-validator-snapshot-datasource` depends on `solana-ledger`, which builds RocksDB with `bindgen`. Install `libclang-dev` on Debian and Ubuntu or `llvm` with Homebrew. It's the only example that needs it.
- Disk and memory for a snapshot. The current mainnet full snapshot was about 126 GB on 2026-11-09. The remote source downloads `genesis.tar.bz2` and the snapshot into a `ledger/` directory under the current directory.

| Variable         | Required                  | Used by                                                                                                                                               |
| ---------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `VALIDATOR_URL`  | One of these two          | Base URL of an RPC node that serves snapshots, e.g. `https://api.mainnet-beta.solana.com`. Carbon appends `/genesis.tar.bz2` and `/snapshot.tar.bz2`. |
| `SNAPSHOT_PATH`  | One of these two          | An extracted ledger directory containing `genesis.tar.bz2` and `snapshots/`.                                                                          |
| `PROGRAM_OWNERS` | At least one of these two | Comma-separated owner program IDs.                                                                                                                    |
| `ACCOUNT_IDS`    | At least one of these two | Comma-separated account addresses.                                                                                                                    |

> **Warning: The example README's VALIDATOR_URL is wrong.** The README sets `VALIDATOR_URL=https://api.mainnet-beta.solana.com/snapshot.tar.bz2`. Carbon treats the value as a base URL, so it requests `…/snapshot.tar.bz2/genesis.tar.bz2`, gets `HTTP error: 405 Method Not Allowed` three times and gives up. Set the base URL only.

```sh
cd carbon/examples/snapshot-validator
VALIDATOR_URL=https://api.mainnet-beta.solana.com \
PROGRAM_OWNERS=TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA \
RUST_LOG=info cargo run --release -p snapshot-validator-carbon-example
```

The example compiles at `v2.0.0` with `libclang` installed; a full mainnet load wasn't run for this page. Loaded accounts print as `account pubkey=… slot=… lamports=… data_size=… owner=…`, followed by `snapshot bootstrap complete`. That last line also prints when loading failed, because the pipeline returns `Ok` after a datasource error; check the log for `error consuming datasource` (see [Pipeline exits with status 0 after a datasource error](https://carbon.sevenlabs.org/troubleshooting.md#pipeline-exits-with-status-0-after-a-datasource-error)).

## `jetstreamer`

Backfills Token-2022 activity over a slot range from Old Faithful through the Jetstreamer datasource, with server-side transaction filters and parallel workers, then exits.

This is a Carbon 1 / Solana 3 example. Jetstreamer doesn't support the Solana 4 crates yet, so `carbon-jetstreamer-datasource` was not published on the 2.0 line (crates.io has 1.0.0 only), and the workspace `Cargo.toml` excludes `examples/jetstreamer`. It doesn't build from a `v2.0.0` checkout: from the repository root, `cargo run -p jetstreamer-carbon-example` fails with ``package(s) `jetstreamer-carbon-example` not found in workspace``, and from its own directory with ``error inheriting `edition` from workspace root manifest's `workspace.package.edition` ``. To use it, copy the pattern into a project that depends on Carbon 1.0.0 crates throughout. Don't combine it with Carbon 2 crates ([why](https://carbon.sevenlabs.org/troubleshooting.md#instructiondecoder-is-not-implemented-for-a-decoder)).

It reads `START_SLOT` (default `415500000`), `END_SLOT` (`415931999`), `WORKER_COUNT` (`4`) and `PAGE_SIZE` (`100`), all optional.

## Next steps

- [Quickstart](https://carbon.sevenlabs.org/quickstart.md): Build a pipeline from an empty project instead of a checkout.
- [Datasources](https://carbon.sevenlabs.org/datasources.md): Choose the datasource for your use case.
- [Troubleshooting](https://carbon.sevenlabs.org/troubleshooting.md): Errors you'll see while running these examples, and fixes.

---

Carbon 2.0.0 documentation · Web: https://carbon.sevenlabs.org/examples · Last updated 2026-11-09 · Index of all pages: https://carbon.sevenlabs.org/llms.txt
