ListAccountsRequest
ListAccountsRequest lists accounts using CEL filters.
The filter expression supports filtering on account metadata fields using CEL (Common Expression Language). A filter expression is REQUIRED for all ListAccounts requests.
Available fields for filtering:
- account.address.value (bytes): The account’s public key address
- account.meta.owner.value (bytes): The account owner’s public key
- account.meta.balance (uint64): Account balance in native units
- account.meta.seq (uint64): Account sequence number / state counter
- account.meta.nonce (uint64): Account transaction nonce
- account.meta.data_size (uint32): Size of account data in bytes
- account.meta.version (uint32): Account version number
- account.meta.flags (AccountFlags): Account capability flags (message type)
- account.meta.flags.is_program (bool): Flag indicating if account is a program
- account.meta.flags.is_privileged (bool): Flag indicating if account is privileged
- account.meta.flags.is_uncompressable (bool): Flag indicating if account data cannot be compressed
- account.meta.flags.is_ephemeral (bool): Flag indicating if account is ephemeral
- account.meta.flags.is_deleted (bool): Flag indicating if account is deleted
- account.meta.flags.is_new (bool): Flag indicating if account is new
- account.meta.flags.is_compressed (bool): Flag indicating if account data is compressed
- account.meta.last_updated_slot (uint64): Slot when account was last modified
Available CEL functions:
- has(field): Check if optional field exists
- uint(value): Convert to uint type
- int(value): Convert to int type
- string(value): Convert to string type
- bytes(value): Convert to bytes type
Available filter parameters (accessible via params.* in expressions):
- params.owner_bytes (bytes): Owner public key for owner filtering (REQUIRED when filtering by owner)
- params.prefix (bytes): Byte prefix for range-based filtering
- params.tag (any): Custom tag parameter
- params.min_slot (uint64): Minimum slot parameter
- params.min_updated_slot (uint64): Minimum last_updated_slot for filtering
Filter examples:
-
Filter by balance: filter.expression = “account.meta.balance > uint(1000000)”
-
Filter by balance range: filter.expression = “account.meta.balance >= uint(100) && account.meta.balance <= uint(10000)”
-
Filter by owner (requires params.owner_bytes): filter.expression = “account.meta.owner.value == params.owner_bytes” filter.params[“owner_bytes”].bytes_value = <32-byte owner pubkey>
-
Filter by data size: filter.expression = “account.meta.data_size > uint(0)” filter.expression = “account.meta.data_size >= uint(100) && account.meta.data_size <= uint(1000)”
-
Filter by nonce: filter.expression = “account.meta.nonce == uint(0)”
-
Filter by sequence number: filter.expression = “account.meta.seq >= uint(100)”
-
Filter by version: filter.expression = “account.meta.version == uint(1)”
-
Filter by specific address (using inline bytes literal with octal escaping): filter.expression = “account.address.value == b’\001\002\003…’” Note: Binary bytes must be properly escaped using octal notation (\NNN) for non-printable bytes
-
Filter by address prefix (using range comparison): filter.expression = “account.address.value >= b’\001\002\003\004’ && account.address.value <= b’\001\002\003\004\377\377…’” Note: Create upper bound by appending 0xff bytes after prefix
-
Combine multiple conditions with AND: filter.expression = “account.meta.balance > uint(0) && account.meta.data_size == uint(0)”
-
Combine multiple conditions with OR: filter.expression = “account.meta.balance == uint(0) || account.meta.balance > uint(50000)”
-
Complex combined filters: filter.expression = “(account.meta.balance > uint(100) && account.meta.balance < uint(10000)) || account.meta.data_size > uint(1000)”
-
Check for optional field existence: filter.expression = “has(account.address.value)” filter.expression = “has(account.meta.owner.value)” // Requires params.owner_bytes
-
Use inequality operators: filter.expression = “account.meta.balance < uint(5000)” filter.expression = “account.meta.balance <= uint(5000)” filter.expression = “account.meta.balance >= uint(100)” filter.expression = “account.meta.balance != uint(999)”
-
Type conversions: filter.expression = “account.meta.balance == uint(100)” filter.expression = “uint(account.meta.data_size) > uint(0)”
-
Filter by account flags (individual flag fields): filter.expression = “account.meta.flags.is_program == true” filter.expression = “account.meta.flags.is_privileged == true” filter.expression = “account.meta.flags.is_uncompressable == true” filter.expression = “account.meta.flags.is_ephemeral == true” filter.expression = “account.meta.flags.is_deleted == true” filter.expression = “account.meta.flags.is_new == true” filter.expression = “account.meta.flags.is_compressed == true”
-
Combine flag filters with other conditions: filter.expression = “account.meta.flags.is_program == true && account.meta.balance > uint(0)”
-
Filter by last_updated_slot: filter.expression = “account.meta.last_updated_slot >= uint(1000)”
-
Filter by last_updated_slot with params: filter.expression = “account.meta.last_updated_slot >= params.min_updated_slot” filter.params[“min_updated_slot”].uint_value = 1000
Limitations:
- The startsWith() function only works with strings, not bytes
- The bytesPrefix() function is NOT available for ListAccounts (use range comparison instead)
- Parameter names other than owner_bytes, prefix, tag, min_slot, min_updated_slot are NOT permitted
- All filters are pushed down to SQL for optimal performance where possible
Package: thru.services.v1
Fields
Section titled “Fields”| Field | Type | # | Description |
|---|---|---|---|
view | thru.core.v1.AccountView | 1 · optional | |
version_context | thru.common.v1.VersionContext | 2 · optional | |
filter | thru.common.v1.Filter | 3 · optional | CEL filter expression (REQUIRED). See message documentation for examples. |
page | thru.common.v1.PageRequest | 4 · optional | |
min_consensus | thru.common.v1.ConsensusStatus | 5 · optional |