arkiv-query
Read Arkiv entities with the SDK select builder or raw arkiv_query JSON-RPC.
Skill by Arkiv-Network
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/arkiv-network-arkiv-query
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/arkiv-query
What's inside
- Skill name
arkiv-query- Description
- Read Arkiv entities with the SDK select builder or raw arkiv_query JSON-RPC. Use for typed predicates, escaping, creator scoping, all-page pagination, cursor recovery, filtered counts, historical block arguments and raw native-operation encoding for non-TypeScript clients. For an existing error string, use arkiv-troubleshooting first.
- License
- MIT
- Metadata
- network: tiramisu · verified: 2026-10-08 · arkiv-sdk: >=0.8.1 <0.9
- Instructions
- 189 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Files (2)
- SKILL.md
- json-rpc.md · references/
SKILL.md (first lines)
# Query a consistent set of Arkiv entities
## When to use
Use this skill to turn a known entity model into a read query. Use arkiv-data-modeling when field encodings or relationships are undecided, arkiv-security-trust for publisher/auth decisions, and arkiv-troubleshooting first when the task includes an existing error.
Inspect the installed SDK version and declarations. This guidance targets SDK 0.8.1 and Tiramisu; SDK exports and node capabilities differ. For Python, Rust or tools without this SDK, read [json-rpc.md](references/json-rpc.md) for the current wire protocol instead of adapting an older SDK API from memory.
## Rules that change the result
- `.fetch()` requires at least one filter: `.where(...)`, `.ownedBy(...)` or `.createdBy(...)`. Raw `arkiv_query` also accepts `*`; use a bounded, scoped query for application reads rather than scanning the shared database.
- `.where()` accumulates predicates with AND. Repeated `.ownedBy()` or `.createdBy()` replaces that respective filter. Use `or(...)` for alternatives.
- Pair every predicate with its write constructor. A bare number is `i32`, bigint is `u256`, string is `str`, boolean is `bool`. `u64` timestamps and expiry blocks must remain `u64` in queries.
- Millisecond timestamps such as `Date.now()` exceed the signed `i32` range (-2147483648 to 2147483647), even though they fit a JavaScript safe integer. SDK 0.8.1 rejects a bare timestamp predicate with `InvalidValueError` before sending a query; do not promise an empty result. Import `u64` from `@arkiv-network/sdk/attr` and preserve the stored type, for example `eq('created_at', u64(timestamp))`. Exact equality also requires the stored timestamp value, not a newly sampled clock value.
- A typed predicate matches only cells stored with that type. `gte('price_minor', u256(0n))` also excludes legacy `i32` prices; a bare-number predicate does the reverse. Do not replace this with unsupported `EXISTS` or `TYPEOF`.
- Use `.createdBy(trustedAddress)` or `$creator = addr(...)` for original publisher scope. `$owner` is current mutation authority and can change after transfer. `project` and `entity_type` are namespaces, not authentication.
- Pin a block from `getBlockNumber({ cacheTime: 0 })` with `.atBlock(snapshot)` for a complete walk. Preserve query, projection and snapshot across its opaque cursors. `page.next()` returns a new immutable page; reassign the variable. The previous page stays readable.
- Pages hold at most 200 entities; `.limit(n)` sets the size of each page, not the total matches across a walk. A short or full page does not prove completion: check `hasNextPage()`. Bound requests and restarts; return complete results or an explicit error, never silently treat a partial set as complete.
- A typed `QueryError` with `kind === 'cursor'` can restart the complete walk. Discard accumulated rows. For a current-state read, choose a fresh snapshot; for an explicitly historical read, keep its requested block. A block error must preserve that historical intent and surface the failure.
- Current Tiramisu returns matches newest first by creation block, with descending keys within a block. For the latest N by creation, a first page with `limit(N)` suffices when N is at most 200. There is no arbitrary attribute ordering or general aggregate API: fetch every page in scope and sort a copy for attribute-based top-N. A raw filtered count is available; SDK `getEntityCount()` is chain-wide.
## Worked all-page read with bounded recovery
The page/restart budgets below are application policies, not node limits. Configure a request timeout on the supplied transport. The provided client factory uses eight seconds and no transport retries; viem otherwise retries `-32005` as `LimitExceededRpcError`, delaying cursor recovery. The walker permits one cursor restart by default. It never retries parse, type, literal, block, quota or ordinary network errors. An optional access key stays server-side and is sent only to the factory's fixed official Tiramisu RPC; redirects fail closed.
```typescript
import { createPublicClient } from '@arkiv-network/sdk';
import { addr, bool, str, u256 } from '@arkiv-network/sdk/attr';
import { tiramisu } from '@arkiv-network/sdk/chains';
import { and, eq, gte, render, QueryError } from '@arkiv-network/sdk/query';
import { http, type Address } from 'viem';
type Public = ReturnType<typeof createPublicClient>;
type ReadPolicy = { maxPages?: number; maxRestarts?: number; historicalBlock?: bigint };
export function queryClient(accessKey?: string) {
return createPublicClient({
chain: tiramisu,
cacheTime: 0,
transport: http(tiramisu.rpcUrls.default.http[0], {
timeout: 8_000,
retryCount: 0,
fetchOptions: { cache: 'no-store', redirect: 'error',
...(accessKey ? { headers: { 'X-API-KEY': accessKey } } : {}) },
}),
});
}
export function listingPredicates(creator: Address) {
return [eq('project', str('example_marketplace')), eq('entity_type', str('listing')),
eq('active', bool(true)), gte('price_minor', u256(0n)), eq('$creator', addr(creator))];
}
export function listingExpression(creator: Address) {
return render(and(...listingPredicates(creator)));
}
export async function countListings(client: Public, creator: Address, snapshot: bigint) {
if (snapshot < 0n || snapshot > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error('Unsafe count block');
// SDK 0.8.1's count schema exposes only empty params. Widen this one raw boundary.
const request = client.request as unknown as (args: {
method: 'arkiv_getEntityCount'; params: [{ query: string; block: number }];
}) => Promise<unknown>;
const count = await request({ method: 'arkiv_getEntityCount',
params: [{ query: listingExpression(creator), block: Number(snapshot) }] });
if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 0) {
throw new Error('Invalid filtered count response');
}
return count;
}
export async function fetchAllListings(
client: Public,
creator: Address,
{ maxPages = 50, maxRestarts = 1, historicalBlock }: ReadPolicy = {},
) {
if (!Number.isInteger(maxPages) || maxPages < 1) throw new Error('Invalid page budget');
if (!Number.isInteger(maxRestarts) || maxRestarts < 0 || maxRestarts > 3) {
throw new Error('Invalid cursor restart budget');
}
let requests = 0; // Total page requests across all attempts, including failed ones.
for (let attempt = 0; ; attempt++) {
const snapshot = historicalBlock ?? await client.getBlockNumber({ cacheTime: 0 });
try {
if (requests >= maxPages) throw new Error('Query page budget exhausted; discard incomplete results');
requests++;
let page = await client.select({ key: true, attributes: true })
.where(...listingPredicates(creator)).atBlock(snapshot).limit(100).fetch();
if (page.blockNumber !== snapshot) throw new Error('Query snapshot mismatch');
const entities = [...page.entities];
while (page.hasNextPage()) {
if (requests >= maxPages) throw new Error('Query page budget exhausted; discard incomplete results');
requests++;
page = await page.next();
if (page.blockNumber !== snapshot) throw new Error('Query snapshot mismatch');
entities.push(...page.entities);
}
return { snapshot, entities };
} catch (error) {
if (!(error instanceof QueryError && error.kind === 'cursor')) throw error;
if (attempt >= maxRestarts) throw new Error('Cursor restart budget exhausted', { cause: error });
// A new attempt owns a new array; no rows from this partial walk escape.
}
}
}
```
If the budget is too small for the workload, fail and let the application choose a larger authorized budget or an incremental workflow that explicitly exposes incompleteness. Do not automatically fall back to an unscoped query.
Use the returned complete set for a global top-N within that scope. Compare exact typed values; do not convert large prices to JavaScript numbers:
```typescript
import { createPublicClient } from '@arkiv-network/sdk';
type ListingRow = {
key: `0x${string}`;
attributes: Awaited<ReturnType<ReturnType<typeof createPublicClient>['getEntity']>>['attributes'];
};From Arkiv-Network/skills, MIT.
More from Arkiv-Network/skills
- 0.592score
arkiv-write-safety
Arkiv-Network
Submit and reconcile Arkiv writes with @arkiv-network/sdk.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-app-integration
Arkiv-Network
Integrate Arkiv SDK 0.8.x into server APIs, injected-wallet apps and event-driven caches.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-social-graph
Arkiv-Network
Model follows, likes and entity references with arkiv-graph.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-troubleshooting
Arkiv-Network
Diagnose Arkiv SDK, query, RPC, wallet and stale-read failures and validate RPC/chain configuration from concrete request evidence.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv
Arkiv-Network
Route development tasks involving Arkiv, @arkiv-network/sdk, DB-Chain or Tiramisu to the appropriate skill and explain native entity operations, query…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-data-modeling
Arkiv-Network
Design typed Arkiv entity models for application queries, PostgreSQL mappings, marketplace schemas and relationships.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-encryption
Arkiv-Network
Encrypt and decrypt Arkiv entity payloads with the published arkiv-encryption package.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-entity-lifecycle
Arkiv-Network
Create, patch, transfer, replace, or delete Arkiv entities with @arkiv-network/sdk.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-feedback
Arkiv-Network
Draft and submit an Arkiv bug report or feature request using the official GitHub issue forms.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-first-write
Arkiv-Network
Set up @arkiv-network/sdk on a verified Arkiv testnet and make a first entity write with funding, safe key custody, explicit expiration, seed reconciliation…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-indexing
Arkiv-Network
Design and verify Arkiv-to-application entity mirrors from native operation logs, with checkpoints, replay, reorganization recovery and Entity Expiration…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-mcp
Arkiv-Network
Explain an already connected Arkiv MCP or plugin, including whether its bundled connection contains Global Tour Stop event sources and whether another…
SkillAFreshness: A★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 1
- Open issues
- 9
- Last commit (this folder)
- Oct 16, 2026 (12 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/Arkiv-Network/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from Arkiv-Network
- 0.592score
arkiv-app-integration
Arkiv-Network
Integrate Arkiv SDK 0.8.x into server APIs, injected-wallet apps and event-driven caches.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-entity-lifecycle
Arkiv-Network
Create, patch, transfer, replace, or delete Arkiv entities with @arkiv-network/sdk.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-data-modeling
Arkiv-Network
Design typed Arkiv entity models for application queries, PostgreSQL mappings, marketplace schemas and relationships.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-encryption
Arkiv-Network
Encrypt and decrypt Arkiv entity payloads with the published arkiv-encryption package.
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv
Arkiv-Network
Route development tasks involving Arkiv, @arkiv-network/sdk, DB-Chain or Tiramisu to the appropriate skill and explain native entity operations, query…
SkillAFreshness: A★ 1Claude Code +9 - 0.592score
arkiv-feedback
Arkiv-Network
Draft and submit an Arkiv bug report or feature request using the official GitHub issue forms.
SkillAFreshness: A★ 1Claude Code +9
Cite this page
arkiv-query skill. Agent Mart. https://agentmart.dev/skills/arkiv-network-arkiv-query (last updated 2026-10-24)