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.mdto the URL or sendingAccept: 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.
Find a subscribe-ready stack
Section titled “Find a subscribe-ready stack”Search the catalog each time. Example deployments come and go, so don’t build on a fixed one:
a4 explore catalog --query "<intent>" --kind stack --mode subscribe --jsona4 explore catalog stack <slug> --jsonEvery 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.
Explore it before writing code
Section titled “Explore it before writing code”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.
Install the stack
Section titled “Install the stack”a4 install stack <slug> --tsUse 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:
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:
npm install @usearete/sdkFor React:
npm install @usearete/react @usearete/sdk zodTypeScript session
Section titled “TypeScript session”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.
Point-in-time versus live
Section titled “Point-in-time versus live”Generated view clients commonly expose:
| Method | Use |
|---|---|
.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.
Query semantics
Section titled “Query semantics”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.
Programs packaged by a stack
Section titled “Programs packaged by a stack”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.
Independent hosted capabilities
Section titled “Independent hosted capabilities”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.
Other languages
Section titled “Other languages”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.