Skip to content
Agentmart
Submit a tool

arkiv-query

Read Arkiv entities with the SDK select builder or raw arkiv_query JSON-RPC.

Skill by Arkiv-Network

IndexedMIT★ 1
Write a review

Chalk Labs

Need help deploying arkiv-query?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

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.

We use your email only for this newsletter. Privacy

About

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.

No 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 and code. Checked Nov 1, 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 Arkiv entities on Rabdi

Inspect the installed SDK 1.0.0 declarations and the write schema. Use modeling when encodings/indexes are undecided and troubleshooting for an existing error. Only indexed columns support predicates; bytes columns are selectable but cannot be filtered or sorted.

## Typed filters and flat rows

```typescript
import { createPublicClient } from '@arkiv-network/sdk';
import { rabdi } from '@arkiv-network/sdk/chains';
import { defineSchema, str, bytes, u64, u256, key } from '@arkiv-network/sdk/schema';
import { asc, gt, gte } from '@arkiv-network/sdk/query';
import { http, type Address, type Hex } from 'viem';

// Diagnostics contain only fixed messages and validated local transaction identifiers.
type SafeDetails = { txHash?: string; entityKey?: string; expiresAt?: bigint };
const safeErrors = new WeakMap<object, { message: string; details: SafeDetails }>();
function safeError(message = 'Arkiv operation failed', details: SafeDetails = {}): Error & SafeDetails {
  const allowed: SafeDetails = {};
  for (const field of ['txHash', 'entityKey'] as const) {
    const value = details[field];
    if (typeof value === 'string' && /^0x[0-9a-fA-F]{64}$/.test(value)) allowed[field] = value;
  }
  if (typeof details.expiresAt === 'bigint' && details.expiresAt >= 0n && details.expiresAt < 2n ** 64n) allowed.expiresAt = details.expiresAt;
  const result = Object.assign(new Error(message), allowed);
  safeErrors.set(result, { message, details: { ...allowed } });
  return result;
}
function sanitizedFailure(error: unknown, fallback = 'Arkiv request failed; reconcile any admitted write before retrying'): Error & SafeDetails {
  const own = error !== null && typeof error === 'object' ? safeErrors.get(error) : undefined;
  if (own) return safeError(own.message, own.details);
  // Preserve this exact cross-recipe preflight verdict, never any attached diagnostics.
  try { if (error instanceof Error && error.message === 'Unsigned preparation/estimate failed') return safeError('Unsigned preparation/estimate failed'); } catch {}
  return safeError(fallback);
}



export const Listings = defineSchema('example_listings', {
  listing_id: str().indexed(), price_minor: u256().indexed(),
  created_at: u64().indexed(), title: str(), details: bytes(),
});
export function queryClient(accessKey: string) {
  try {
    return createPublicClient({ chain: rabdi({ accessKey }), cacheTime: 0,
      transport: http(undefined, { timeout: 8000, retryCount: 0,
        fetchOptions: { cache: 'no-store', redirect: 'error' } }) });
  } catch (error) {
    throw sanitizedFailure(error);
  }
}
type Reader = ReturnType<typeof queryClient>;

export async function cheapestPage(client: Reader, creator: Address) {
  try {
    const page = await client.select({ $key: true, title: true, price_minor: true })
      .from(Listings).createdBy(creator).where(gte('price_minor', u256(0n)))
      .orderBy(asc('price_minor')).withCount().limit(20).offset(0).fetch();
    return await { entities: page.entities, block: page.blockNumber, count: page.count, skipped: page.skipped };
  } catch (error) {
    throw sanitizedFailure(error);
  }
}

// Bounded traversal of current observations, not an atomic snapshot.
export async function fetchAllListings(client: Reader, creator: Address, maxPages = 50) {
  try {
    if (!Number.isSafeInteger(maxPages) || maxPages < 1) throw safeError('Invalid page budget');
    const entities = [];
    const blocks: bigint[] = [];
    let last: Hex | undefined;
    for (let index = 0; index < maxPages; index++) {
      const builder = client.select({ $key: true, title: true, price_minor: true })
        .from(Listings, { onMismatch: 'throw' }).createdBy(creator)
        .orderBy(asc('$key')).limit(100);
      if (last) builder.where(gt('$key', key(last)));
      const page = await builder.fetch();
      blocks.push(page.blockNumber);
      entities.push(...page.entities);
      if (page.entities.length < 100) return await { entities, observedBlocks: blocks };
      const next = page.entities.at(-1)?.$key;
      if (!next || (last && next.toLowerCase() <= last.toLowerCase())) throw safeError('Keyset did not advance');
      last = next;
    }
    throw safeError('Page budget exhausted; discard incomplete traversal');
  } catch (error) {
    throw sanitizedFailure(error);
  }
}
```

Write selection objects inline or `as const`; widened boolean fields make result fields optional. Rows are flat: `$key` and the selected typed column values, such as `row.price_minor.value`. Select `$attributes` for the typed map of all attributes, or `$attributeSchema` for name/type/indexing without large values. The latter is never included automatically by `select('*')`.

`from(schema)` verifies only selected columns. The default mismatch mode skips nonmatching entities and reports `page.skipped`. A page can be empty even when later matches exist. For offset traversal advance by `entities.length + skipped`, not only returned rows; a page covering fewer than the explicit limit is the end. Keyset traversal needs `{ onMismatch: 'throw' }` so a skipped page cannot hide its continuation key.

## Ordering, pages and counts

- `orderBy(asc(...))` or `desc(...)` accepts one key; another call replaces it. Any non-bytes schema column can be sorted, even when unindexed. Queryable system sort keys are `$key`, `$owner`, `$creator`, `$expiresAt`; not creation/update blocks or flags. Without a schema supply the attribute type to the order helper.
- `limit` is 1–100; `offset` is a nonnegative safe integer. Sorting is across the matched set. Ties have node-defined order; use `$key` when stable identity order matters.
- Every request reads latest state; there is no SDK snapshot/block argument, opaque cursor, `next()` or historical query. Inserts/deletes shift offsets. Keyset traversal avoids repeating prior keys but can miss new keys below its boundary, and values/deletions can change between pages. For a certified backup, pause/co-ordinate writers and verify an unchanged source head or use an independently authenticated snapshot service.
- `client.count().from(schema).where(...).fetch()` returns a filtered bigint. `withCount()` returns that total in the same page request. Counts include matching entities skipped for schema mismatch; they are observations at that request's block, not a retained snapshot or count of validated rows.

## Predicate behavior

Use `eq`, `gt/gte/lt/lte`, `between`, `startsWith`, `exists`, `hasType`, `and` and `or` from the query subpath. SDK 1.0.0 does not export `not` or `ne`. Ordered comparisons work on every indexable type; `startsWith` requires `str`. `between` requires both bounds with the same type. Match write constructors; a bare timestamp becomes an invalid i32, and a bigint predicate defaults to u256 rather than u64.

System predicates cover `$key: key`, `$owner: addr`, `$creator: addr`, `$expiresAt: u64`. Selection is broader than filtering. A named schema supplies its own tag filter; an unnamed schema still needs a deliberate `where`, `ownedBy` or `createdBy`. Repeated owner/creator scopes replace their respective scope; use an explicit `or(eq('$creator', addr(a)), ...)` for alternatives. Namespaces/schema tags are not authentication.

SDK rendering escapes apostrophes by doubling them. Build expressions through constructors rather than interpolating user strings. Raw decimal literals are unquoted `dec(3.5)`; booleans are bare `true`/`false`. See [raw RPC](references/json-rpc.md).

## Errors and budgets

`QueryError.kind` covers `parse`, `type`, `literal`, `limits` (codes -32001 through -32004). Narrow unknown diagnostic data and sanitize literal values. Invalid filters are not empty successful results. Check wrong chain, exact name/case, stored type, indexing flag, creator/current owner and expiration before broadening scope.

Every `arkiv_query`, including a count, costs 10 quota units under current provider policy; each access key has 100,000,000 units. Missing keys fail SDK construction unless explicitly empty; keyless calls can return HTTP 429. Preserve HTTP status and honor Retry-After; do not return empty results or loop through keys to bypass quota. Never log keyed URLs or raw provider errors.

Sources: [SDK 1.0.0 source](https://unpkg.com/@arkiv-network/sdk@1.0.0/src/), [SDK README](https://unpkg.com/@arkiv-network/sdk@1.0.0/README.md). Inspect the installed declarations before adapting executable examples.

From Arkiv-Network/skills, MIT.

More from Arkiv-Network/skills

Signals

Stars
1
Forks
1
Open issues
9
Last commit (this folder)
Oct 16, 2026 (16 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from Arkiv-Network

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get arkiv-query running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying arkiv-query?

CallGet help
Cite this page

arkiv-query skill. Agent Mart. https://agentmart.dev/skills/arkiv-network-arkiv-query (last updated 2026-10-24)