Skip to content

Arete documentation

Programs, Views, and Stacks

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 /concepts/programs-views-stacks.md.

Arete has two building blocks: Program SDKs and live views. Stacks group them. Keeping the three apart in your head makes both the catalog and the generated code much easier to follow.

In short: a program is the on-chain app, a view is its data arranged the way your app wants it, and a stack groups views with the Program SDKs they use, as one package you install.

A Solana program defines accounts (its data) and instructions (the actions it accepts). Arete normalizes that interface and generates a Program SDK containing whatever capabilities exist for the exact published release.

Program
├── accounts and schemas
├── account reads
├── PDAs and known addresses
├── raw instruction builders
├── application operations
├── transactions and flows
└── errors, constants, defaults, and calculations

A Program SDK is useful on its own. It doesn’t need a live deployment or a stack. Install one on its own whenever your app needs to read from a program or act through it without live views. When your app uses a stack that covers the program, the stack already includes its Program SDK.

The exact descriptor has the final say. It lists which account readers, operations, hosted connections, and SDK targets are available for that release. Registry packages also carry their own Arete semantic version, which is derived from changes to their exact program and SDK artifacts.

The way accounts are laid out on-chain rarely matches what ends up on a product screen. A view maintains a version of the data shaped for your app, such as:

  • one position assembled from several accounts;
  • a filtered collection of active pools;
  • a leaderboard ordered by a running total;
  • recent activity derived from instructions; or
  • a model that combines several programs around one lasting key.

You can query a view for its state at a point in time. When a WebSocket connection is available, you can also subscribe to live updates. Views are built for current application state and bounded live windows. They are not a place to run arbitrary historical SQL.

An agent can query and subscribe to deployed views through MCP before any application code has been generated.

A stack is a named group of live views and Program SDKs for one useful area of functionality:

Stack
├── selected live views
├── Program SDKs, including one for each program the views read from
├── stack-level reads and flows, when defined
├── typed addresses, constants, defaults, and math
└── descriptors for the hosted capabilities it can use

A Program SDK in a stack is the same one you would install on its own: the same program package release that a4 install program installs, with the same generated surface and identity. Installing a stack therefore gives your app its views and the Program SDK for each program they read from. Each one sits under the stack’s programs and uses the stack’s authentication and transaction transport, so you don’t need a separate program install to get a stack’s operations. a4 explore stack <ref> --summary lists the Program SDKs a stack includes.

Choose by what your app needs:

  • Live views, with or without operations: install a stack.
  • Reads and transactions only: install a Program SDK on its own.
  • Views and Program SDKs that no stack groups: compose a stack from published stacks and program packages, or install each one and use them together in one session.

A project can still install a program standalone next to a stack that includes it. The CLI recognizes the shared Program SDK, and at runtime the two are one program.

Several live views may happen to run in the same hosted deployment. That says nothing about how they relate at the application level. Your client code should depend on the generated stack and its selected views. It shouldn’t try to work out how things are hosted or build endpoints itself.

In TypeScript, one session can hold many stacks and standalone programs:

const session = await createSession({
stacks: {
markets: MARKETS_STACK,
positions: POSITIONS_STACK,
},
programs: {
token: SPL_TOKEN_PROGRAM,
},
});
session.stacks.markets.views;
session.stacks.positions.views;
session.programs.token.accounts;
session.chain;

Programs that arrive inside a stack are also reachable at session.programs.<key>. A Program SDK’s identity is its program package release, so the same program installed standalone and inside a stack is one program with one client. Local builds have no release identity: a local standalone copy of a stack’s program (the same program spec) takes session.programs.<key> with a warning, and the stack keeps its own at session.stacks.<name>.programs.<key>. A different program under a key a stack already uses is rejected with PROGRAM_KEY_CONFLICT, which tells you to use session.stacks.<name>.programs.<key> or attach the standalone program under another key. There is no need to merge program clients by hand.

Portable definitions and hosted capabilities

Section titled “Portable definitions and hosted capabilities”

The definitions of programs, live behavior, and composition are portable and content-addressed, meaning each one is identified by a hash of its contents. Hosting then attaches working services to those exact definitions:

CapabilityWhat it provides
Program ReadTyped decoding and reads for an exact program release
Chain readGeneric Solana state such as lamports, clocks, mints, and raw accounts
Live query and streamPoint-in-time and subscribed view access
TransactionInspection and submission of locally signed transactions

Each of these is independent. A stack may support live views while one of its programs has no hosted account reader. A Program SDK may support reads and transactions with no live views at all. Check the descriptor instead of assuming that one endpoint implies another.

Most application developers never need the artifact layer. It matters when you are authoring, validating, or deploying custom live data:

ArtifactRole
ProgramSpecPortable normalized program identity and interface
LiveSpecEntity, mapping, resolver, and view behavior over exact programs
StackManifestExact composition of programs, live specifications, and selected views

A StackManifest does not contain a deployment URL. Generated hosted packages attach connection details separately, so the portable content never changes silently when infrastructure does.

A StackManifest also lists ProgramSpecs, not Program SDKs. A stack package references each Program SDK by its program package release, next to the manifest, so a change to a Program SDK alone never changes the StackManifest a hosted runtime serves.

Arete can know about a program or stack before every way of using it is ready. Catalog results therefore spell out where each one stands:

  • cataloged: Arete has reviewed knowledge about the subject;
  • installable: an exact package and SDK target can be resolved;
  • read-ready: hosted typed account reads are available;
  • build-ready: generated transaction construction is available; and
  • subscribe-ready: a hosted live deployment serves the selected views.

Filter for the mode your task needs, and open the exact descriptor before writing code.