Skip to content

Braga has been retired. The next public testnet is coming in September 2026. Read the announcement →

SelectQueryBuilder

Defined in: src/query/queryBuilder.ts:42

Builds and runs a query.

The selection is fixed when the builder is created and the filter is added by chaining, so the result type is known before a single predicate is written. Create one with client.select(...) rather than constructing it directly — that is what infers the entity shape from the selection.

Every filter added with where, ownedBy and createdBy must hold; use or for alternatives inside one call.

import { createPublicClient } from "@arkiv-network/sdk"
import { i32 } from "@arkiv-network/sdk/attr"
import { cheesecake } from "@arkiv-network/sdk/chains"
import { eq, gte, or } from "@arkiv-network/sdk/query"
import { http } from "viem"
const client = createPublicClient({ chain: cheesecake, transport: http() })
const page = await client
.select({ key: true, attributes: true })
.where(gte("level", i32(10)), or(eq("status", "open"), eq("status", "review")))
.ownedBy(owner)
.limit(100)
.fetch()
for (const entity of page.entities) console.log(entity.key, entity.attributes)

TEntity = Entity

The projected entity shape, inferred from the selection by client.select().

new SelectQueryBuilder<TEntity>(client, selection?): SelectQueryBuilder<TEntity>

Defined in: src/query/queryBuilder.ts:52

ArkivClient

"*" | Required<Pick<SelectionFields, "key">> & Partial<Omit<SelectionFields, "key">> | Required<Pick<SelectionFields, "payload">> & Partial<Omit<SelectionFields, "payload">> | Required<Pick<SelectionFields, "contentType">> & Partial<Omit<SelectionFields, "contentType">> | Required<Pick<SelectionFields, "attributes">> & Partial<Omit<SelectionFields, "attributes">> | Required<Pick<SelectionFields, "attributeSchema">> & Partial<Omit<SelectionFields, "attributeSchema">> | Required<Pick<SelectionFields, "creationFlags">> & Partial<Omit<SelectionFields, "creationFlags">> | Required<Pick<SelectionFields, "owner">> & Partial<Omit<SelectionFields, "owner">> | Required<Pick<SelectionFields, "creator">> & Partial<Omit<SelectionFields, "creator">> | Required<Pick<SelectionFields, "createdAt">> & Partial<Omit<SelectionFields, "createdAt">> | Required<Pick<SelectionFields, "updatedAt">> & Partial<Omit<SelectionFields, "updatedAt">> | Required<Pick<SelectionFields, "expiresAt">> & Partial<Omit<SelectionFields, "expiresAt">>

SelectQueryBuilder<TEntity>

[asyncIterator](): AsyncGenerator<TEntity>

Defined in: src/query/queryBuilder.ts:184

Walks every page, yielding one entity at a time.

AsyncGenerator<TEntity>

for await (const entity of client.select({ key: true }).where(eq("category", "docs"))) {
console.log(entity.key)
}

atBlock(block): this

Defined in: src/query/queryBuilder.ts:127

Reads the state as of a given block rather than the head. The block must be within the range the node retains.

bigint

this

builder.atBlock(1_297_000n)

createdBy(creator): this

Defined in: src/query/queryBuilder.ts:92

Restricts the results to entities this account created — shorthand for where(eq("$creator", addr(creator))). Calling it again replaces the filter.

The creator never changes; the owner does, so these differ after a transfer.

`0x${string}`

this


cursor(cursor): this

Defined in: src/query/queryBuilder.ts:115

Starts from a cursor returned by an earlier page.

Pagination normally goes through QueryResult.next, which carries the cursor for you; this is for resuming a walk in a later process. A cursor is bound to the query, block and selection it came from, so it must be used with an identically-built query.

string

this


fetch(): Promise<QueryResult<TEntity>>

Defined in: src/query/queryBuilder.ts:163

Runs the query and returns the first page.

Promise<QueryResult<TEntity>>

If no filter has been added.

If the node rejects the query.

const page = await client.select({ key: true }).where(eq("category", "docs")).fetch()
page.entities // this page
await page.next() // the next one

limit(limit): this

Defined in: src/query/queryBuilder.ts:103

Sets the page size, up to the node maximum of 200. Without it the node picks the page size.

number

this

builder.limit(100)

ownedBy(owner): this

Defined in: src/query/queryBuilder.ts:81

Restricts the results to entities this account owns — shorthand for where(eq("$owner", addr(owner))). Calling it again replaces the filter.

`0x${string}`

this

builder.ownedBy("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")

toString(): string

Defined in: src/query/queryBuilder.ts:137

The query string this builder will send — the same text the node parses.

string

If no filter has been added.


where(expressions): this

Defined in: src/query/queryBuilder.ts:67

Adds filters. Everything passed here, and across repeated calls, must hold.

readonly Expression[]

The expressions, as separate arguments or one array.

this

builder.where(eq("category", "docs"))
builder.where(gte("level", i32(10)), lt("level", i32(20)))
builder.where(or(eq("status", "open"), not(exists("closedAt"))))

where(…expressions): this

Defined in: src/query/queryBuilder.ts:68

Adds filters. Everything passed here, and across repeated calls, must hold.

Expression[]

The expressions, as separate arguments or one array.

this

builder.where(eq("category", "docs"))
builder.where(gte("level", i32(10)), lt("level", i32(20)))
builder.where(or(eq("status", "open"), not(exists("closedAt"))))