Skip to content
hopper
Get started
Operations / onchain-schema

On-chain schema proposal

A clearly labeled design for future manifest pointers, separate from the shipped Program Metadata IDL path.

This reference covers Hopper 0.5.0, published on crates.io. See the release status for package verification, dated benchmarks, and remaining audit work.

Status: design document. A HopperSchemaPointer data type exists in source, but its PDA derivation, publication authority, hopper publish command, and Manager --address discovery workflow are not implemented. It is not a shipped on-chain discovery surface.

The shipped public-cluster path is narrower: hopper publish-idl projects a local Hopper manifest into validated Solana IDL v0.1.0 JSON and writes that JSON through the official Program Metadata program. The projection carries instruction names, Hopper's actual instruction/account/event discriminators, account roles, and arguments. Account bodies use custom hopper-zero-copy-v1 serialization, so the IDL does not make Hopper accounts Anchor-Borsh decodable.

Projection and publication fail closed on dynamic account tails, unsupported bounded wire encodings, remaining-account contracts, unresolved or unsafe PDA seeds, unresolved fixed addresses, and ambiguous discriminator prefixes. They do not publish the Hopper manifest, declared byte ranges, or a Grillo effect contract. A dry run has no network access and sends nothing. Live publication defaults to devnet; named Mainnet and every raw, custom, or SOLANA_RPC_URL endpoint require confirmation unless --yes is supplied.

Shipped publication workflows

hopper publish-manifest publishes the normalized Hopper manifest through Program Metadata under the custom hopper-manifest seed. It supports readback and authority-baseline tooling. The seed is a Hopper convention, not a reserved standard. hopper publish-idl publishes the supported Solana IDL projection. Neither publication alone binds the declaration to the deployed ELF; use release verification for that check. These workflows do not implement the proposed HopperSchemaPointer account format described below.

Problem

Without on-chain schema, tools must obtain manifests out-of-band (via Git repos, package registries, or JSON files). On-chain publication enables program address → schema lookup.

Design

Truth Hierarchy

ProgramManifest    ← rich internal truth (local / version control)
ProgramIdl         ← public schema (published or stored off-chain)
CodamaProjection   ← interop subset (for Codama/Kinobi tooling)
HopperSchemaPointer ← on-chain pointer to the above

The on-chain account stores hashes and URIs, not the full manifest. This keeps account size small and avoids rent-exempt bloat.

Proposed HopperSchemaPointer account

#[repr(C)]
pub struct HopperSchemaPointer {
    // -- Hopper header (16 bytes) --
    // disc: 255 (reserved discriminator for schema pointers)
    // version: 1
    // flags: 0x0001 (INITIALIZED)
    // layout_id: sha256("hopper:v1:SchemaPointer:1:...")[..8]

    // -- Payload --
    pub schema_version: u16,      // Schema format version (1)
    pub pointer_flags: u16,       // Feature flags (see below)
    pub manifest_hash: [u8; 32],  // SHA-256 of hopper.manifest.json
    pub idl_hash: [u8; 32],       // SHA-256 of hopper.idl.json
    pub codama_hash: [u8; 32],    // SHA-256 of hopper.codama.json
    pub uri_len: u16,             // Length of the URI string
    pub uri: [u8; 192],           // UTF-8 URI to the manifest
    // Total payload: 2 + 2 + 32 + 32 + 32 + 2 + 192 = 294 bytes
    // Total with header: 294 + 16 = 310 bytes
}

Pointer Flags

Bit Name Description
0 FLAG_HAS_MANIFEST manifest_hash is populated
1 FLAG_HAS_IDL idl_hash is populated
2 FLAG_HAS_CODAMA codama_hash is populated
3 FLAG_HAS_URI uri contains a valid URI
4 FLAG_URI_IS_IPFS URI points to IPFS (content-addressed)
5 FLAG_URI_IS_ARWEAVE URI points to Arweave (permanent storage)

Proposed account address derivation

The schema pointer account is at a deterministic PDA:

seeds = ["hopper-schema", program_id]

If implemented, this would let a client derive the pointer from a program ID.

URI Strategies

Strategy URI Format Pros Cons
IPFS ipfs://Qm... Content-addressed, cheap Needs pinning
Arweave ar://... Permanent, no pinning Costs AR
HTTPS https://... Simple Mutable, trust required
On-chain hopper://account/... Fully on-chain Expensive rent

Recommended: IPFS for manifests (content-addressed, hash-verifiable), with the SHA-256 hash on-chain for integrity verification.

Proposed workflow

  1. Build: hopper schema export --manifest @manifest.json > hopper.manifest.json
  2. Hash: sha256sum hopper.manifest.json
  3. Upload: Pin to IPFS, Arweave, or host via HTTPS
  4. Publish (not implemented): hopper publish --program <PROGRAM_ID> --manifest-hash <HASH> --uri <URI>
  5. Discover (not implemented): hopper manager summary --address <PROGRAM_ID> fetches schema pointer, downloads manifest, verifies hash, decodes program.

Manager Integration

Hopper Manager currently accepts @manifest.json for local files. The proposed pointer workflow would add --address <PROGRAM_ID>:

# Local (current)
hopper manager summary @manifest.json

# Proposed; not implemented
hopper manager summary --address <PROGRAM_ID>

The proposed flow:

  1. Derive PDA from program ID
  2. Fetch HopperSchemaPointer account data
  3. Extract URI and manifest hash
  4. Fetch manifest from URI
  5. Verify SHA-256 matches on-chain hash
  6. Deserialize and use as ProgramManifest

Security Considerations

  • Hash verification: Always compare the fetched manifest's SHA-256 against the on-chain manifest_hash. Reject mismatches.
  • Authority: Only the program's upgrade authority (or a designated schema authority) should be able to update the schema pointer.
  • Immutability: Consider making the schema pointer non-closeable to prevent denial-of-service via account deletion.

Implementation Status

  • HopperSchemaPointer type defined in hopper-schema
  • Layout with hopper_layout! macro
  • Spec document (this file)
  • PDA derivation helper
  • CLI hopper publish command
  • Manager --address flag for on-chain lookup
  • IPFS upload integration