Skip to content
hopper
Get started
v0.1 - shipping now/Token-2022 extensions landed

Write Solana programs
that explain themselves.

Pointer-cast accounts. Segment-level borrow tracking. Token-2022 extensions on the zero-copy path. When a handler fails, the receipt tells you which invariant broke and where. No more hex codes, no more Borsh tax, no more guessing.

Start a programView on GitHub
$cargo add hopper
76/76
zero-copy features
parity matrix, all columns
16
Token-2022 validators
zero-copy, no Borsh path
0
heap allocations
hot path, every handler
4
backends
native, pinocchio, solana-program, spartan
#![no_std]pointer-cast accounts16-byte headersegment borrow registryToken-2022 TLVdeclare_program!#[hopper::crank]multi-byte discriminatorsStateReceipt wire formatschema-epoch migrationshopper manager invokehopper profile elfhopper manager crank runPDA manifest fetch#![no_std]pointer-cast accounts16-byte headersegment borrow registryToken-2022 TLVdeclare_program!#[hopper::crank]multi-byte discriminatorsStateReceipt wire formatschema-epoch migrationshopper manager invokehopper profile elfhopper manager crank runPDA manifest fetch
§01 - what Hopper is

Safety primitives Solana programs actually ship with.

access model

One way in. Four ways through.

load::<T>() for the whole account. segment_ref::<T>() for a single field. raw_ref() when you know what you are doing. load_cross_program::<T>() for foreign accounts. No Borsh tax, no AccountLoader wrapper, no surprise deserialize.

token-2022

Extension constraints on the zero-copy path.

transfer_hook, metadata_pointer, non_transferable, permanent_delegate, transfer_fee_config, mint_close_authority, default_account_state, interest_bearing, eight more. Each declarative constraint compiles to a direct TLV byte scan. Anchor hits the Borsh path; Hopper does not.

receipts

Failures that explain themselves.

Handlers stamp a 64-byte StateReceipt with error_code, failed_invariant_idx, and failure_stage. Indexers render "Invariant balance_nonzero failed at PostMutation" instead of 0x1001. The mapping is compile-time; no runtime lookup table.

cli and cranks

Every program is self-describing.

hopper fetch <program-id> pulls a program's manifest from its PDA. hopper manager invoke builds a transaction from that manifest. hopper manager crank run drives autonomous instructions with zero per-program config. Point it at any Hopper program on any cluster.

$hopper manager fetch <program-id>
$hopper manager invoke swap --arg amount=1000000
$hopper manager crank run --interval 30
$hopper tx explain 4Rb...signature
§02 - code

The whole program fits on one screen.

Four tabs, four concepts. The same macros you write on day one scale to an AMM or a keeper bot without a second framework.

src/vault.rs
1#[hopper::state(disc = 1, version = 1)]
2#[repr(C)]
3pub struct Vault {
4 pub authority: TypedAddress<Authority>,
5 pub balance: WireU64,
6 pub bump: u8,
7}
8
9// Auto-emitted by the macro:
10// Vault::LEN, Vault::DISC, Vault::VERSION
11// Vault::LAYOUT_ID (compile-time fingerprint)
12// vault.load::<Vault>() / load_mut::<Vault>()
13// Vault::SCHEMA_METADATA (indexer-ready)
zero-copy account, one attribute
§03 - parity

Strict superset.

Scoped to the zero-copy path. Anchor's column shows what AccountLoader-backed programs can actually reach; Borsh shortcuts do not count. Hopper wins every row that matters and five that nobody else even has.

feature
Hopper
Anchor ZC
Quasar
Pinocchio
Zero-copy account access
best
partial
good
good
Token-2022 extension validators
best
missing
missing
missing
Segment-level borrow tracking
best
missing
missing
missing
Provable receipts with invariant attribution
best
missing
missing
missing
Schema-epoch migrations
best
missing
missing
missing
On-chain manifest PDA
best
missing
missing
missing
Multi-byte discriminators
best
good
good
missing
Policy knobs (strict / sealed / raw)
best
missing
missing
missing
Declarative init / close / realloc / has_one
best
good
good
missing
ELF profiler + flamegraph CLI
best
missing
good
missing
§04 - go

Three commands to devnet.

No workspace scaffolding to babysit, no hidden config step, no hand-rolled keypair dance. Every command below ships in the current release and exits zero on the happy path.

01
$ cargo add hopper
add the framework
02
$ hopper init my-program
scaffold a project
03
$ hopper deploy --cluster devnet
ship it