macro_rules! hopper_interface {
(
$(#[$attr:meta])*
pub struct $name:ident, disc = $disc:literal, version = $ver:literal
{
$(
$(#[$field_attr:meta])*
$field:ident : $fty:ty = $fsize:literal
),+ $(,)?
}
) => { ... };
}Expand description
Declare a cross-program interface view.
Generates a read-only overlay struct for reading accounts owned by
another program without any crate dependency. The interface is
pinned by LAYOUT_ID – the same deterministic SHA-256 fingerprint
used by hopper_layout!. If the originating program changes its
layout, the fingerprint will differ and load_foreign() will reject
the account at runtime.
The generated struct includes:
#[repr(C)]zero-copy overlay with alignment-1 guarantee- Deterministic
LAYOUT_IDmatching the originating layout load_foreign(account, expected_owner)for Tier-2 cross-program readsload_foreign_multi(account, owners)for multi-owner scenariosload_with_profile(account, TrustProfile)for configurable trust- Compile-time size and alignment assertions
§Example
Program A defines a Vault:
ⓘ
hopper_layout! {
pub struct Vault, disc = 1, version = 1 {
authority: TypedAddress<Authority> = 32,
balance: WireU64 = 8,
bump: u8 = 1,
}
}Program B reads it without importing Program A:
ⓘ
hopper_interface! {
/// Read-only view of Program A's Vault.
pub struct VaultView, disc = 1, version = 1 {
authority: TypedAddress<Authority> = 32,
balance: WireU64 = 8,
bump: u8 = 1,
}
}
let verified = VaultView::load_foreign(vault_account, &PROGRAM_A_ID)?;
let balance = verified.get().balance.get();If the fields match Program A’s Vault exactly, the LAYOUT_IDs will
be identical and load_foreign succeeds. Any structural divergence
produces a different hash and the load fails.