Expand description
§Hopper
A zero-copy Solana program framework. One access model, one dispatch
path, one set of safety rules. Unsafe is available when you need it,
and it is spelled unsafe so you can find it again.
The goals, in priority order:
- Safety by default. Every account byte you touch has been owner-checked, signer-checked, layout-checked, and borrow-checked before you see it. Unsafe is an opt-in escape hatch, never a default.
- Low-overhead performance. Account data points directly at the runtime input region. No deserialization pass, no heap allocation, no hidden format machinery. If it costs compute, it is because you asked for it.
- Anchor-grade ergonomics.
#[hopper::state],#[hopper::context],#[hopper::program], and the#[account(...)]constraint vocabulary read the same way an Anchor program reads. Porting is a rename, not a rewrite. - Schema that travels. Every layout, instruction, event, and error is emitted as inspectable compile-time metadata. Off-chain SDKs, IDLs, client generators, and diff tools consume it without parsing source.
§Crate map
hopper_core: wire types, account header, segment maps, validation, collections, and opt-in advanced subsystems (frame, receipt, policy, diff, migration) behind feature gates.hopper_runtime: the runtime surface a program actually calls. Context, Account, Pod, guards, CPI, migrations, log macros, entrypoint bridges.hopper_macros: declarative macros.hopper_layout!,hopper_check!,hopper_error!,hopper_init!,hopper_close!,hopper_require!,hopper_manifest!,hopper_segment!,hopper_validate!,hopper_virtual!,hopper_interface!,hopper_assert_compatible!,hopper_assert_fingerprint!.hopper_macros_proc: proc-macro DX layer.#[hopper::state],#[hopper::pod],#[hopper::context],#[hopper::program],#[hopper::migrate],#[hopper::args],#[hopper::error],#[hopper::event],#[hopper::dynamic].hopper_solana: SPL Token/Mint readers, Token-2022 checks, CPI guards, Pyth oracle, TWAP, Ed25519/Merkle crypto, authority rotation.hopper_system: System Program instruction builders.hopper_token: SPL Token instruction builders.hopper_token_2022: Token-2022 instruction builders plus extension screening helpers.hopper_associated_token: ATA derivation and instruction builders.hopper_schema: layout manifests, fingerprinting, field-level diffing, compatibility verdicts, Codama/IDL projections, client generation.
§Access model
Four reads, one rule: safety first, unsafe by name.
Safe full: account.load::<T>() / account.load_mut::<T>()
Safe segment: ctx.segment_ref::<T>(i,o) / ctx.segment_mut::<T>(i,o)
Explicit raw: unsafe { account.raw_ref() / account.raw_mut() }
Cross-prog: account.load_cross_program::<T>()load and segment_ref are the defaults. raw_ref is the escape
hatch. load_cross_program is the Hopper-specific verb for reading
an account owned by another program (foreign-ownership checked at
the type level).
§Quick start
Declare a layout, declare a context, ship a handler.
ⓘ
use hopper::prelude::*;
use hopper::hopper_layout;
hopper_layout! {
pub struct Vault, disc = 1, version = 1 {
authority: [u8; 32] = 32,
mint: [u8; 32] = 32,
balance: WireU64 = 8,
bump: u8 = 1,
}
}That is it. Vault is now a zero-copy layout with a 16-byte Hopper
header, a segment map, a schema export for the manifest, and a
load::<Vault>() accessor on every AccountView. No derives, no
Borsh, no writeback pass.
Re-exports§
pub use hopper_associated_token;pub use hopper_core;pub use hopper_runtime;pub use hopper_schema;pub use hopper_solana;pub use hopper_system;pub use hopper_token;pub use hopper_token_2022;
Modules§
- address
- Hopper-owned address type for Solana programs.
- error
- Hopper-owned program error type for Solana on-chain programs.
- guards
- Validation guards for Hopper programs.
- pda
- PDA (Program Derived Address) helpers for Hopper programs.
- prelude
- One-import path for authored Hopper programs.
- receipts
- State receipts and event emission.
- utils
- Small utilities. Re-exported at the crate root so
use hopper::utils::hint::likely;just works. Small utilities for Hopper program authors.
Macros§
- address
- Compile-time base58 address literal.
- const_
assert_ pod - Compile-time assertion for safe manual
Podimplementations. - err
- Return an error immediately. Parallel to Anchor’s
err!. - error
- Alias for
err!. Anchor compatibility shim so ported code needs no rename. Functionally identical. - hopper_
accounts - Generate a typed instruction context struct with validated account parsing.
- hopper_
assert_ compatible - Assert that two layout versions have compatible fingerprints.
- hopper_
assert_ fingerprint - Assert that a layout’s fingerprint matches an expected value.
- hopper_
check - Composable account constraint checking.
- hopper_
close - Safely close an account with sentinel protection.
- hopper_
dispatch - Macro for instruction dispatch.
- hopper_
emit_ cpi - Emit a Hopper event via self-CPI for reliable indexing.
- hopper_
error - Generate sequential error codes.
- hopper_
init - Initialize an account: create via CPI, zero-init, write header.
- hopper_
interface - Declare a cross-program interface view.
- hopper_
invariant - Invariant checking macro.
- hopper_
layout - Define a zero-copy account layout.
- hopper_
load - Destructuring sugar for raw-dispatch handlers.
- hopper_
log - Cheap structured logging for hot handlers.
- hopper_
manifest - Generate a layout manifest for schema tooling.
- hopper_
register_ discs - Discriminator registry – compile-time uniqueness enforcement.
- hopper_
require - Require a condition, returning a custom error if false.
- hopper_
segment - Declare a segmented account with typed segments.
- hopper_
unsafe_ region - Auditable raw-pointer boundary.
- hopper_
validate - Build a validation pipeline declaratively.
- hopper_
verify_ pda - PDA verification with BUMP_OFFSET optimization.
- hopper_
virtual - Declare a multi-account virtual state mapping.
- layout_
migrations - Compose a layout’s
LayoutMigration::MIGRATIONSchain from a list of#[hopper::migrate]-emitted edge constants. - msg
- Backend-neutral logging macro.
- require
- Early-return with an error if the condition is false.
- require_
eq - Assert two values are equal, returning an error on mismatch.
- require_
gt - Assert
left > rightstrictly. - require_
gte - Assert
left >= right, returning the supplied error on underrun. Useful for lamport / balance checks. - require_
keys_ eq - Assert two public keys (or any byte slices convertible via
[
AsRef<[u8; 32]>]) are equal. Narrower thanrequire_eq!but matches the ergonomic spelling ecosystem migrators coming from Anchor / Jiminy are familiar with. - require_
keys_ neq - Assert two public keys are not equal. Used for pinning distinct
accounts (authority != user, source != destination). Same coercion
and error semantics as
require_keys_eq!. - require_
lt - Assert
left < rightstrictly. Anchor-parity sibling ofrequire_gt!. Default error isProgramError::InvalidArgumentbecause a failed ordering check most often flags a bad user input. - require_
lte - Assert
left <= right. Anchor-parity sibling ofrequire_gte!. - require_
neq - Assert two values are not equal. Early-returns with the supplied
error on match (or
ProgramError::InvalidArgumentin the short form). Symmetric withrequire_eq!.