Schema architecture
Program manifests, layout IDs, Codama projection, Anchor-shaped IDL, and compatibility diffs.
One canonical schema model
Hopper has one source of truth for state and program semantics: the Rust code. Layout macros, instruction declarations, event definitions, and policy bindings are the authoritative definitions. From that single source, Hopper generates two output formats:
- Hopper Manifest -- rich internal schema for tooling
- Hopper IDL -- lighter public schema for clients and integrations
This keeps one truth while supporting two audiences.
Code-First Doctrine
Canonical truth lives in code. The authoritative declarations are:
hopper_layout!-- fields, offsets, sizes, versions, fingerprintshopper_segment!/ segmented layouts -- segment structure, roleshopper_dispatch!-- instruction set, discriminatorshopper_error!-- error codes and variants- Policy constants -- capability-requirement bindings
hopper_interface!-- cross-program read-only views
These declarations produce compile-time constants (LAYOUT_ID, LEN, DISC, VERSION) that are deterministic and verifiable. The schema layer reads these constants to build manifests and IDLs without duplicating truth.
Proc Macro Policy
No proc macros are required for correctness or core functionality. Proc macros are allowed only for:
- Schema derivation (
#[derive(HopperSchema)]) - Manifest export
- IDL generation
- Optional boilerplate reduction
See PROC_MACRO_POLICY.md for the full doctrine.
The Hopper Manifest
Purpose
The Manifest is Hopper's rich internal schema. It powers:
hopper explain/hopper inspecthopper compat/hopper diff/hopper planhopper manager(program introspection)- Receipt rendering and migration planning
- Docs generation and test tooling
File format
hopper.manifest.json
Structure
{
"format": "hopper-manifest",
"version": 1,
"program": {
"name": "hopper_registry",
"program_id": "...",
"version": "0.2.1",
"description": "Segmented registry example"
},
"layouts": [
{
"name": "Vault",
"kind": "fixed",
"version": 1,
"discriminator": 1,
"layout_id": "a1b2c3d4e5f60718",
"size": 57,
"header_size": 16,
"fields": [
{ "name": "authority", "type": "[u8;32]", "size": 32, "offset": 16 },
{ "name": "balance", "type": "WireU64", "size": 8, "offset": 48 },
{ "name": "bump", "type": "u8", "size": 1, "offset": 56 }
],
"segments": [],
"compatibility": {
"append_safe": true,
"compatible_from": [1],
"migration_required_from": []
}
}
],
"instructions": [
{
"name": "deposit",
"tag": 1,
"args": [
{ "name": "amount", "type": "u64", "size": 8 }
],
"accounts": [
{ "name": "depositor", "writable": false, "signer": true },
{ "name": "vault", "writable": true, "signer": false, "layout_ref": "Vault" }
],
"capabilities": ["MutatesState", "MutatesTreasury"],
"policy_pack": "TREASURY_WRITE",
"receipt_expected": true
}
],
"events": [
{
"name": "DepositEvent",
"tag": 1,
"fields": [
{ "name": "authority", "type": "[u8;32]", "size": 32 },
{ "name": "amount", "type": "u64", "size": 8 }
]
}
],
"policies": [
{
"name": "TREASURY_WRITE",
"capabilities": ["MutatesState", "MutatesTreasury"],
"requirements": ["Authority", "StateSnapshot", "LamportConservation", "InvariantCheck"]
}
],
"compatibility": {
"pairs": [
{
"from": "Vault@1",
"to": "Vault@2",
"toVersion": 2,
"policy": "append-only",
"backwardReadable": true
}
]
}
}
Segment metadata in manifests
For segmented accounts, each segment entry includes:
| Field | Type | Meaning |
|---|---|---|
| name | string | Segment identifier |
| role | string | Core / Extension / Journal / Index / Cache / Audit / Shard |
| segment_id | hex | FNV-1a hash of segment name |
| layout_ref | string | Layout name for this segment |
| required | bool | Must be present in every account instance |
| append_only | bool | Only append operations allowed |
| rebuildable | bool | Can be reconstructed from other data |
| immutable | bool | Cannot be modified after init |
The Hopper IDL
Purpose
The IDL is the public-facing schema for:
- TypeScript client generation
- Kotlin, Python, and Rust client generation
- Block explorers
- External integrations
- Codama-compatible tooling
File format
hopper.idl.json
Structure
{
"format": "hopper-idl",
"version": 1,
"program": {
"name": "hopper_registry",
"program_id": "...",
"version": "0.2.1"
},
"instructions": [
{
"name": "deposit",
"discriminator": [1],
"args": [{ "name": "amount", "type": "u64" }],
"accounts": [
{ "name": "depositor", "writable": false, "signer": true },
{ "name": "vault", "writable": true, "signer": false }
]
}
],
"accounts": [
{
"name": "Vault",
"discriminator": [1],
"size": 57,
"fields": [
{ "name": "authority", "type": "publicKey", "offset": 16 },
{ "name": "balance", "type": "u64", "offset": 48 },
{ "name": "bump", "type": "u8", "offset": 56 }
]
}
],
"events": [
{
"name": "DepositEvent",
"discriminator": [1],
"fields": [
{ "name": "authority", "type": "publicKey" },
{ "name": "amount", "type": "u64" }
]
}
]
}
What IDL excludes
- Migration planning data
- Trust profile internals
- Policy wiring details
- Receipt render metadata
- Unsafe invariant catalog
- Segment migration hints
These live in the Manifest only.
Codama Compatibility
Hopper is Codama-compatible where it improves developer experience:
- Client generation
- Instruction/account metadata for explorers
- TypeScript ecosystem interop
Hopper does not flatten its richer state model to fit Codama. The Manifest preserves full richness; the IDL exposes the clean public subset; a Codama projection can be generated from the IDL.
hopper schema export --manifest # Full manifest
hopper schema export --idl # Public IDL
hopper schema export --codama # Codama-compatible projection
Generation Pipeline
Rust declarations (hopper_layout!, hopper_dispatch!, etc.)
|
v
Schema extraction (hopper-schema crate)
|
v
Hopper Manifest + Hopper IDL + Codama projection
|
v
CLI / Manager / Clients / Planner / Receipts
The extraction layer lives in hopper-schema. It reads LayoutManifest
constants generated by macros and assembles them into the output formats.
No runtime reflection. No dynamic discovery. Everything is compile-time
deterministic.
File Layout
project/
hopper.manifest.json # Rich manifest (generated)
hopper.idl.json # Public IDL (generated)
src/
lib.rs # Canonical code declarations
docs/
SCHEMA_ARCHITECTURE.md
PROC_MACRO_POLICY.md
