SolanaQueryBuilder assembles a typed portal query from a field selection and one or more data-request clauses. Pass .build() to outputs (or to .pipe()) on a Solana source. The resulting object is consumed by solanaPortalStream() and by the solanaInstructionDecoder which composes on top of it.
solanaQuery()
Returns a fresh SolanaQueryBuilder.
SolanaQueryBuilder<F>
F narrows the block type produced by the stream — only fields explicitly selected with .addFields() appear on the decoded records, at both compile and runtime.
RequestOptions<R> and Range
PortalRange.from defaults to 0; a Date or numeric timestamp is resolved to a slot via the portal at query start. 'latest' is resolved to the current head. includeAllBlocks() accepts the stricter Range, so dates and 'latest' are not allowed there.
In Solana, number identifies a slot. Slot and block height differ: skipped slots do not increment height.
.addFields(fields)
Add to the field selection. Repeated calls are merged recursively.
block
transaction
instruction
log
balance
SOL balance change for one account within one transaction.
tokenBalance
SPL-token balance change. Records are a tagged union: some updates carry only pre* fields (token account removed), some only post* (token account created), and some both.
reward
.addInstruction(options)
Filter instructions. List filters AND across fields; values within a field OR. Matches instructions anywhere in the call tree, not just top-level.
An empty
request: {} matches every instruction in the range.
The portal accepts account-position filters up to
a15 and a mentionsAccount filter that matches an account anywhere in the list. These are not exposed by the builder; use a raw query via portal.getStream() if you need them..addTransaction(options)
Filter transactions.
.addLog(options)
Filter program log messages.
.addBalance(options)
Filter SOL balance updates.
.addTokenBalance(options)
Filter SPL-token balance updates.
.addReward(options)
Filter validator rewards.
.includeAllBlocks(range?)
Request every slot in range regardless of whether any other filter matches. Useful when you want uninterrupted timestamps or slot progression even across slots with no targeted activity. Without range, applies from slot 0 onward.
.addRange(range)
Push a range-only request with no filters — typically used to bound a stream built from other sources.
.merge(other)
Merge another builder’s requests and fields in-place. Overlapping ranges are reconciled at build time.
.build(opts?)
Return a QueryAwareTransformer suitable for use as a source output.
opts.setupQuery is an advanced hook called when the query is finalized: it receives { query, logger } and can mutate query (e.g. merge additional requests from runtime data). Default behaviour is to merge this into the stream’s root query.
See also
- Source — how queries attach to the stream.
- solanaInstructionDecoder — typed wrapper that emits a pre-built query plus instruction decoding.
- Handling program instructions — higher-level guide.
- Portal API (Solana) OpenAPI — raw wire protocol this builder serialises to.