> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# General settings

> Configure the Solana DataSourceBuilder — Portal endpoint, block range, queries, and metrics.

`@subsquid/solana-stream` is the Portal-native Solana data source for Squid SDK. Configure a `DataSourceBuilder`, call [`build()`](#build), then pass the resulting data source to [`run()` or `Processor`](../batch-processor) — or consume it directly.

<Warning>
  `SolanaBatchProcessor`, `SolanaRpcClient`, `setGateway()`, `setRpc()`, and `setRpcEndpoint()` are not part of `@subsquid/solana-stream@1.1.2`. Use [`setPortal()`](#set-portal).
</Warning>

<Tip>
  The method documentation is also available inline and can be accessed via suggestions in most IDEs.
</Tip>

The following setters configure the global settings of `DataSourceBuilder` for Solana. They return the modified instance and can be chained.

<h3 id="set-portal">
  `setPortal(portal: string | PortalClientOptions | PortalClient)`
</h3>

Required. Points the data source at a [SQD Portal](/en/portal/overview) dataset:

```typescript theme={"system"}
const dataSource = new DataSourceBuilder()
  .setPortal('https://portal.sqd.dev/datasets/solana-mainnet')
```

The argument is a URL string, a `PortalClientOptions` object or a ready `PortalClient`. `build()` throws `Portal settings not set` when this call is omitted.

<h3 id="set-block-range">
  `setBlockRange(\{from: number, to?: number\})`
</h3>

Limits the range of blocks to be processed. Solana ranges use slot numbers — the same values that are returned as `block.header.number` in the [block data](./context-interfaces). When the upper bound is specified, the processor will terminate with exit code 0 once it reaches it.

Note that block ranges can also be specified separately for each data request. This method sets global bounds for all block ranges in the configuration.

<h3 id="include-all-blocks">
  `includeAllBlocks(range?: \{from: number, to?: number\})`
</h3>

By default, the data source will fetch only blocks that contain the requested items. This method modifies such behavior to fetch all chain blocks. Optionally a range of blocks can be specified for which the setting should be effective.

### Data requests

Subscriptions are added with shorthand methods documented on their own pages:

* [`addTransaction()`](./transactions)
* [`addInstruction()`](./instructions)
* [`addLog()`](./logs)
* [`addBalance()`](./balances)
* [`addTokenBalance()`](./token-balances)
* [`addReward()`](./rewards)

The exact fields retrieved for each data item are set with [`setFields()`](./field-selection). There are no default optional fields — request every field your handler reads.

<h4 id="add-query">
  `addQuery(query: Query | QueryBuilder)`
</h4>

A lower-level alternative to the shorthands above: adds a whole Portal query — a set of item filters that share one block range. Use it when several filters must be scoped to the same range:

```typescript theme={"system"}
dataSource.addQuery(new QueryBuilder()
  .setRange({from: 250_000_000})
  .addInstruction({where: {programId: [PROGRAM_ID]}, include: {logs: true}})
  .addTransaction({where: {feePayer: [FEE_PAYER]}})
  .build()
)
```

<h3 id="build">
  `build()`
</h3>

Returns the Solana data source. Pass it to `run()` or `Processor` from `@subsquid/batch-processor` for restart-safe processing. The [handler context](../batch-processor#handler-context) is `{store, blocks, isHead}`; it does not inject `ctx.log`.

You can also call `getHead()`, `getFinalizedHead()`, `getStream()`, `getFinalizedStream()`, and the optional `getBlocksCountInRange()` helper on the data source directly. See [Read a data source directly](../batch-processor#read-a-data-source-directly).

### Prometheus metrics

Metrics are exposed by the processor, not by the data source: pass a `PrometheusServer` through the fourth `run()` argument as described in the [batch processor reference](../batch-processor#prometheus). Without an explicit server, `PROCESSOR_PROMETHEUS_PORT` takes precedence over `PROMETHEUS_PORT`; metrics are disabled if neither variable is set.

## Complete example

The fixed block range makes this a bounded example that exits after processing one slot. Its in-memory checkpoint is intentionally temporary; use a persistent [Database implementation](../data-stores/store-interface) for an indexer that must resume after a restart.

<Accordion title="Bounded runnable example">
  ```typescript theme={"system"}
  import {run, type FinalDatabase} from '@subsquid/batch-processor'
  import {DataSourceBuilder, type FieldSelection} from '@subsquid/solana-stream'

  const JUPITER = 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'
  const TEST_SLOT = 432_825_258

  const fields = {
    block: {parentNumber: true, timestamp: true},
    instruction: {programId: true, accounts: true, data: true},
    transaction: {signatures: true, err: true, computeUnitsConsumed: true},
    log: {programId: true, kind: true, message: true},
  } satisfies FieldSelection

  const dataSource = new DataSourceBuilder()
    .setPortal('https://portal.sqd.dev/datasets/solana-mainnet')
    .setBlockRange({from: TEST_SLOT, to: TEST_SLOT})
    .setFields(fields)
    .addInstruction({
      where: {programId: [JUPITER]},
      include: {transaction: true, logs: true, innerInstructions: true},
    })
    .build()

  let checkpoint = {
    height: TEST_SLOT - 1,
    hash: '4YqZcfbBdoADF7FDtmWFpGKwYmasi1mXzdqu7yeAE9dX',
  }
  const db: FinalDatabase<void> = {
    async connect() {
      return checkpoint
    },
    async transact({nextHead}, cb) {
      await cb(undefined)
      checkpoint = nextHead
    },
  }

  run(dataSource, db, async (ctx) => {
    for (const block of ctx.blocks) {
      console.log(block.header.number, block.instructions.length)
    }
  })
  ```
</Accordion>

To decode the retrieved instructions and log messages, generate typed helpers with [Solana typegen](../solana-typegen).
