Skip to content
hopper
Get started
Model / layers

Hopper layers

A map of the framework, runtime, schema, SPL, CLI, and example layers.

Hopper is one framework with progressive disclosure. The framework path, the Quasar-shaped migration path, and the systems-mode path all use the same account headers, layout fingerprints, runtime checks, and CPI machinery.

Level 1: Framework Mode

Use this for new programs, tutorials, and ports that should feel like a normal Solana framework before they expose the deeper machinery.

use hopper::prelude::*;

#[account(discriminator = 1, version = 1)]
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Vault {
    pub authority: Address,
    pub balance: WireU64,
    pub bump: u8,
}

Framework mode centers these pieces:

  • #[account], #[derive(Accounts)], Ctx<T>, and #[program].
  • Account<'info, T>, InitAccount<'info, T>, Signer<'info>, and Program<'info, P>.
  • hopper::account, hopper::context, hopper::cpi, hopper::system, hopper::token, hopper::token_2022, hopper::associated_token, and hopper::memo.

This path is published as hopper-lang and imported as hopper:

hopper = { package = "hopper-lang", version = "0.2.1", features = ["proc-macros"] }

There is no separate beginner crate. The main framework crate is the canonical facade, and it grows into the same systems layer when needed.

Level 2: Structured State

Use this when account compatibility, schema publication, dynamic tails, or client generation matters.

  • hopper::layout exposes headers, layout contracts, fingerprints, field maps, and wire types.
  • hopper::schema exposes manifests, IDL projection, resolver metadata, and generated client inputs.
  • #[hopper::account] auto-detects Quasar-style bounded String<'a, N> and Vec<'a, T, N> fields while lowering to Hopper's fixed-body + compact-tail model. Address / Pubkey vectors keep borrowed views; other TailElement vectors return HopperVec<T, N> values.
  • #[hopper::dynamic_account] plus #[tail(...)] remains the explicit systems-mode spelling for the same compact-tail model.
  • hopper_dynamic_tail! and hopper_dynamic_fields! attach explicit bounded dynamic payloads to fixed zero-copy layouts for custom TailCodec tails.
  • declare_program! consumes a manifest and generates typed CPI builders plus static account/effect specs.

This is the right layer for serious applications that still want one-account state contracts and predictable upgrade paths.

Level 3: Systems Mode

Use this when the program needs field leases, segmented layouts, policy receipts, explicit migrations, or foreign layout contracts.

  • hopper::systems::* is the branded one-import path for protocol-grade work.
  • hopper::segment exposes segment registries, segment roles, field-level borrow tracking, and typed segment references.
  • hopper::receipt exposes execution receipts and tagged event receipts.
  • hopper::policy exposes capability policies and policy packs.
  • hopper::migration exposes layout migration edges and pending migration application.
  • hopper::interface exposes foreign manifest and interface helpers for cross-program reads.
  • hopper::internal is an explicit lower-crate escape hatch for authors who are deliberately working below the framework facade.

The systems layer publishes as hopper-systems. The source still lives in crates/hopper-core for now to preserve history and keep this rename focused; the package name is the public ecosystem name.

Level 4: Substrate Mode

Use this when a handler or benchmark target deliberately wants raw Hopper Native control.

  • hopper::substrate exports Hopper Runtime account, instruction, and result types.
  • With the Hopper Native backend, it also exports raw account views, raw input parsing, syscall modules, hashes, PDA helpers, memory helpers, CU budget probes, return data, and CPI verification primitives.
  • This is the place for audited hot paths. It is not the first-contact import path for normal application code.

Mental Mapping

Concept Anchor-shaped mental model Quasar-shaped mental model Hopper path
Program state #[account] struct fixed account struct #[hopper::account] or #[hopper::state]
Context/accounts #[derive(Accounts)] account list plus checks #[derive(Accounts)], #[hopper::accounts], typed wrappers
Signer Signer<'info> signer account check hopper::account::Signer<'info>
Typed account Account<'info, T> fixed account view hopper::account::Account<'info, T>
Dynamic string/vector String, Vec<T> with serialization bounded dynamic fields #[hopper::account] pretty fields, #[hopper::dynamic_account], or explicit hopper_dynamic_fields!
CPI generated CPI clients manual/generated CPI declare_program!, hopper::cpi, SPL facade modules
Upgrade/migration discriminator/version conventions layout evolution discipline layout fingerprints, hopper::migration, schema manifests
Advanced safety constraints and runtime checks zero-copy constraints segment leases, receipts, policy graphs, Kani-checked invariants

Import Guide

Prefer the smallest import surface that matches the job:

use hopper::prelude::*;              // main app framework surface
use hopper::systems::*;              // protocol-grade state architecture
use hopper::substrate::*;            // raw Hopper Native substrate surface
use hopper::{layout, segment};       // explicit systems modules
use hopper::{schema, cpi, token};     // tooling, CPI, and token facades

The public modules are additive. New users start with the main prelude and only open the systems modules when the design calls for them.