Skip to content

Arete documentation

Connect to Live Views

For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending .md to the URL or sending Accept: text/markdown.

For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /using-stacks/connect.md.

A live view is data from one or more programs, arranged the way your app wants it and kept current for you. Reach for one when reading accounts by address stops being enough, because you need collections, joins, totals, rankings, recent activity, or a continuous stream of updates.

Search the catalog each time. Example deployments come and go, so don’t build on a fixed one:

Terminal window
a4 explore catalog --query "<intent>" --kind stack --mode subscribe --json
a4 explore catalog stack <slug> --json

Every stack result carries live: true when it has a hosted stream to subscribe to now, false when it is definition-only (it installs as an SDK and streams once you deploy it yourself). The exact descriptor lists the stack’s views, programs, sign-in requirements, connection details, verified SDK targets, and install command. If the search returns nothing that is subscribe-ready, stop there. Don’t construct a URL from a package name.

The quickest way to check a view is through MCP. Ask your agent to inspect the view schema, connect, take a small bounded sample, and tell you whether the data answers your application’s question.

Explore on-chain with MCP →

Terminal window
a4 install stack <slug> --ts

Use the target and command the descriptor gives you. The dependency you asked for is saved in arete.toml, and the exact composition and package identities go into arete.lock.

The install summary ends with what the project still needs and where the stack’s SDK reference is: a README.md in the generated folder (for example generated/typescript/stacks/ore/README.md), also printed by a4 sdk describe <alias> and the describe_sdk MCP tool. It lists what is specific to that stack: the import, each view, the row fields with their TypeScript names, wire names, types and units, and the stack’s reads (derived values such as ORE’s read.currentRound()). Rows use camelCase paths (id.roundId), while a4 get and the MCP tools print wire names (id.round_id); copy field paths from the reference, not from that output.

In a directory with no package.json, the install still succeeds, and the summary names what the generated TypeScript is missing and how to add it. Set the project up your own way (npm, pnpm, bun, a workspace), or let a4 do it with npm:

Terminal window
a4 install stack <slug> --ts --setup

--setup writes an ES module package.json and a tsconfig.json, then installs the runtime and typescript, tsx and @types/node. It never replaces existing files. In an existing project, install the TypeScript runtime when needed:

Terminal window
npm install @usearete/sdk

For React:

Terminal window
npm install @usearete/react @usearete/sdk zod

Use the import and names from the SDK reference (README.md in the generated folder, or a4 sdk describe <alias>):

import { createSession } from "@usearete/sdk";
import { MY_STACK } from "./generated/my-stack";
const session = await createSession(
{ stacks: { app: MY_STACK } },
{ auth: { secretKey: process.env.ARETE_API_KEY } },
);
const current = await session.stacks.app.views.Position.list.get({ take: 20 });
for await (const update of session.stacks.app.views.Position.list.watch({
take: 20,
})) {
if (update.type === "upsert") {
console.log(update.data);
} else {
console.log(update.type, update.key);
}
}

MY_STACK, Position, and the query options shown here are placeholders. The generated declarations in your installed package have the real names.

This session runs on a server or in a local script, so it authenticates with an agent key (a4_ak_...) or secret key (a4_sk_...) as secretKey. With no auth option at all, outside browsers the SDK uses ARETE_API_KEY if it is set, and otherwise the key from your a4 login, so a script on a machine logged in with a4 needs no key setup. If several a4 profiles hold a key, set ARETE_PROFILE to pick one. secretKey throws in a browser: anything shipped to a browser uses an origin-bound publishableKey instead, as in the React example below. Create one with a4 auth keys create-publishable --origin <scheme://host[:port]>.

When your app’s users are signed in to Arete, the session can act for the user instead: hand it the user’s Arete API credential with tokenKind: 'api'. See Sign in with an Arete API credential.

The stack already contains its default endpoints. Override them only when you deliberately want a local or alternate connection.

import { AreteProvider, useArete } from "@usearete/react";
import { MY_STACK } from "./generated/my-stack";
function Positions() {
const arete = useArete(MY_STACK);
const positions = arete.views.Position.list.use({ take: 20 });
if (arete.status === "error") {
return <button onClick={() => void arete.retry()}>Reconnect</button>;
}
if (positions.status !== "ready") return <p>Loading…</p>;
if (positions.isEmpty) return <p>No matching positions.</p>;
return <pre>{JSON.stringify(positions.data, null, 2)}</pre>;
}
export default function App() {
return (
<AreteProvider
stack={MY_STACK}
auth={{ publishableKey: import.meta.env.VITE_ARETE_PUBLISHABLE_KEY }}
>
<Positions />
</AreteProvider>
);
}

Reading hosted data may require you to sign in, but it never requires a wallet. In your interface, treat connecting, ready but empty, ready with data, refreshing, validation failure, and connection failure as different states.

To combine this stack with programs or protocols in one session, see Compose a session in React.

Generated view clients commonly expose:

MethodUse
.get(...)Fetch a point-in-time result
.getOne(...)Fetch the first result of a list view
.use(...)Consume merged entities as an async iterable or React hook
.watch(...)Consume the full update taxonomy
.watchRich(...)Consume updates with before/after information where supported
.getSync(...)Read the already-active local subscription state

The exact methods vary by language and by view. Two things to remember: a point-in-time request is not a live subscription, and getSync never makes a network request.

Keys, filters, partitions, pagination, and bounded snapshot windows all count as part of a subscription’s identity. Two queries that normalize to the same thing can share one connection. Queries with different windows stay independent.

When an entity drops out of one filtered query, it hasn’t necessarily been deleted everywhere. Keep the update types the generated SDK gives you, so your application state stays correct.

Filtering and query windows →

A generated stack can also include its Program SDKs. They appear under the stack and, where identities permit, the session’s canonical program surface:

session.stacks.app.programs.myProgram;
session.programs.myProgram;

Use those program clients when you need the authoritative account data or want to build a transaction. Use views when you want data that is already shaped and maintained for your app.

Live queries, Program Read, generic chain reads, and transactions each have their own descriptor and their own authentication scope. Don’t reuse a WebSocket or HTTP query URL as a program, chain, or transaction endpoint.

For transaction execution, the wallet signs locally and the connected client selects the correct transaction transport per invocation.

Use a4 install stack <slug> --rust or --python only when the descriptor verifies the target. Continue with the Rust SDK or Python SDK for language-specific patterns.