#![no_std]
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(any(
all(feature = "hopper-native-backend", feature = "legacy-pinocchio-compat"),
all(feature = "hopper-native-backend", feature = "solana-program-backend"),
all(
feature = "legacy-pinocchio-compat",
feature = "solana-program-backend"
),
))]
compile_error!("Enable exactly one Hopper backend: hopper-native-backend, legacy-pinocchio-compat, or solana-program-backend.");
#[doc(hidden)]
pub mod __macro_support;
pub mod guards;
pub mod pda;
pub mod prelude;
pub mod receipts;
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;
pub mod account {
pub use hopper_core::abi::{
Authority, Mint, Token, TokenAccount, TypedAddress, UntypedAddress,
};
pub use hopper_core::accounts::{
HopperAccount, HopperAccounts, HopperCtx, HopperIx, ProgramAccount, ProgramRef,
SegmentedAccount, SignerAccount, ValidateAccount,
};
pub use hopper_runtime::{
Account, AccountView, HopperSigner as Signer, InitAccount, Interface, InterfaceAccount,
InterfaceAccountLayout, InterfaceAccountResolve, InterfaceSpec, Program, ProgramId,
SystemAccount, SystemId, UncheckedAccount,
};
pub type System = SystemId;
}
pub mod context {
pub use hopper_core::accounts::{hopper_entry, HopperAccounts, HopperCtx, HopperIx};
pub use hopper_runtime::Context;
}
pub mod cpi {
pub use hopper_core::cpi::*;
pub use hopper_runtime::cpi::{
invoke, invoke_signed, invoke_signed_unchecked, invoke_signed_with_bounds,
invoke_unchecked, invoke_with_bounds, set_return_data, MAX_CPI_ACCOUNTS, MAX_RETURN_DATA,
MAX_STATIC_CPI_ACCOUNTS,
};
pub use hopper_runtime::{CpiAccount, InstructionAccount, InstructionView, Seed, Signer};
}
#[allow(unused_imports)]
pub mod system {
pub use hopper_system::instructions::*;
pub use hopper_system::SYSTEM_PROGRAM_ID;
pub use hopper_system::*;
}
#[allow(ambiguous_glob_reexports, unused_imports)]
pub mod token {
pub use hopper_runtime::token::*;
pub use hopper_solana::interface::{
interface_transfer_checked, interface_transfer_checked_signed, InterfaceMint,
InterfaceTokenAccount, TokenProgramKind,
};
pub use hopper_token::instructions::*;
pub use hopper_token::TOKEN_PROGRAM_ID;
pub use hopper_token::*;
}
#[allow(ambiguous_glob_reexports, unused_imports)]
pub mod token_2022 {
pub use hopper_runtime::token_2022_ext::*;
pub use hopper_token_2022::instructions::*;
pub use hopper_token_2022::TOKEN_2022_PROGRAM_ID;
pub use hopper_token_2022::*;
}
#[allow(unused_imports)]
pub mod associated_token {
pub use hopper_associated_token::instructions::*;
pub use hopper_associated_token::ATA_PROGRAM_ID;
pub use hopper_associated_token::*;
}
pub mod memo {
pub use hopper_memo::*;
}
pub mod events {
pub use crate::receipts::{emit_receipt, emit_tagged_receipt, emit_typed_receipt, Receipt};
#[cfg(feature = "cpi")]
pub use hopper_core::event::emit_event_cpi;
pub use hopper_core::event::{emit_event, emit_event_tagged, emit_slices};
pub use hopper_runtime::{hopper_emit_cpi, hopper_log, msg};
}
pub mod layout {
pub use hopper_core::abi::{FingerprintTransition, LayoutFingerprint, WireType};
pub use hopper_core::account::{
check_header, read_discriminator, read_header_flags, read_layout_id, read_version,
write_header, AccountHeader, AccountReader, FixedLayout, HEADER_FORMAT, HEADER_LEN,
};
pub use hopper_core::field_map::{FieldInfo, FieldMap};
pub use hopper_runtime::layout::{init_header, HopperHeader, LayoutContract, LayoutInfo};
pub use hopper_runtime::{AccountLayout, Pod, WireLayout, ZeroCopy};
}
pub mod segment {
pub use hopper_core::account::segment_role::{
SegmentRole, SEG_ROLE_AUDIT, SEG_ROLE_CACHE, SEG_ROLE_CORE, SEG_ROLE_EXTENSION,
SEG_ROLE_INDEX, SEG_ROLE_JOURNAL, SEG_ROLE_SHARD,
};
pub use hopper_core::account::{
segment_id, SegmentDescriptor, SegmentEntry, SegmentId, SegmentRegistry,
SegmentRegistryMut, SegmentSlice, SegmentSliceMut, SegmentTable, SegmentTableMut,
MAX_REGISTRY_SEGMENTS, MAX_SEGMENTS, REGISTRY_HEADER_SIZE, REGISTRY_OFFSET,
SEGMENT_DESC_SIZE, SEGMENT_ENTRY_SIZE, SEG_FLAG_DYNAMIC, SEG_FLAG_FROZEN, SEG_FLAG_LOCKED,
};
pub use hopper_core::segment_map::{assert_segment_field_alignment, SegmentMap, StaticSegment};
pub use hopper_runtime::{
AccessKind, Ref, RefMut, SegRef, SegRefMut, Segment, SegmentBorrow, SegmentBorrowGuard,
SegmentBorrowRegistry, SegmentLease, TypedSegment,
};
}
pub mod receipt {
pub use crate::receipts::{emit_receipt, emit_tagged_receipt, emit_typed_receipt, Receipt};
#[cfg(feature = "receipt")]
pub use hopper_core::receipt::*;
}
pub mod migration {
#[cfg(feature = "migrate")]
pub use hopper_core::migrate::*;
pub use hopper_runtime::{apply_pending_migrations, LayoutMigration, MigrationEdge};
}
pub mod interface {
pub use hopper_runtime::{
ForeignLens, ForeignManifest, Interface, InterfaceAccount, InterfaceAccountLayout,
InterfaceAccountResolve, InterfaceSpec, TransparentAddress,
};
pub use hopper_solana::interface::*;
}
pub mod schema {
pub use hopper_schema::*;
}
pub mod policy {
#[cfg(feature = "policy")]
pub use hopper_core::policy::*;
pub use hopper_runtime::{HopperInstructionPolicy, HopperProgramPolicy};
}
#[allow(ambiguous_glob_reexports, unused_imports)]
pub mod systems {
pub use crate::interface::*;
pub use crate::layout::*;
pub use crate::migration::*;
pub use crate::policy::*;
pub use crate::receipt::*;
pub use crate::schema::*;
pub use crate::segment::*;
pub use crate::{interface, layout, migration, policy, receipt, schema, segment};
pub use hopper_core::account::{
overlay, overlay_mut, read_dynamic_u16, read_dynamic_u32, read_dynamic_u8, safe_close,
safe_close_with_sentinel, safe_realloc, write_dynamic_u16, write_dynamic_u32,
write_dynamic_u8, DynamicView, DynamicViewMut, ReallocGuard, VerifiedAccount,
VerifiedAccountMut, CLOSE_SENTINEL,
};
pub use hopper_core::check::{find_and_verify_pda, rent_exempt_min};
pub use hopper_core::prelude_advanced::*;
pub use hopper_core::prelude_core::*;
pub use hopper_runtime::{
fast_entrypoint, hopper_entrypoint, hopper_fast_entrypoint, hopper_lazy_entrypoint,
lazy_entrypoint, no_allocator, nostd_panic_handler, program_entrypoint, BoundedString,
BoundedVec, CpiAccount, HopperString, HopperVec, InstructionAccount, InstructionView, Seed,
TailCodec, TailElement,
};
pub use crate::{
const_assert_pod, hopper_accounts, hopper_assert_compatible, hopper_assert_fingerprint,
hopper_check, hopper_close, hopper_dynamic_fields, hopper_dynamic_tail, hopper_error,
hopper_init, hopper_interface, hopper_invariant, hopper_layout, hopper_load,
hopper_manifest, hopper_register_discs, hopper_require, hopper_segment, hopper_validate,
hopper_verify_pda, hopper_virtual, layout_migrations,
};
#[cfg(feature = "proc-macros")]
pub use crate::{args, declare_program, dynamic, migrate, pod, state};
}
#[cfg(feature = "finance")]
pub mod finance {
pub use hopper_finance::*;
}
#[cfg(feature = "lending")]
pub mod lending {
pub use hopper_lending::*;
}
#[cfg(feature = "staking")]
pub mod staking {
pub use hopper_staking::*;
}
#[cfg(feature = "vesting")]
pub mod vesting {
pub use hopper_vesting::*;
}
#[cfg(feature = "distribute")]
pub mod distribute {
pub use hopper_distribute::*;
}
#[cfg(feature = "multisig")]
pub mod multisig {
pub use hopper_multisig::*;
}
#[cfg(feature = "anchor-interop")]
pub mod anchor {
pub use hopper_anchor::*;
}
#[doc(hidden)]
pub mod internal {
pub use crate::{hopper_core, hopper_runtime, hopper_schema, hopper_solana};
}
#[cfg(feature = "metaplex")]
pub use hopper_metaplex;
pub use hopper_runtime::utils;
pub use hopper_core::hopper_dispatch;
pub use hopper_macros::{
const_assert_pod, hopper_accounts, hopper_assert_compatible, hopper_assert_fingerprint,
hopper_check, hopper_close, hopper_error, hopper_init, hopper_interface, hopper_invariant,
hopper_layout, hopper_manifest, hopper_register_discs, hopper_require, hopper_segment,
hopper_validate, hopper_verify_pda, hopper_virtual,
};
pub use hopper_runtime::layout_migrations;
#[macro_export]
macro_rules! hopper_load {
( $slice:expr => [ $($binding:ident),+ $(, ..)? $(,)? ] ) => {
let [ $($binding,)+ .. ] = $slice else {
return ::core::result::Result::Err(
$crate::hopper_runtime::error::ProgramError::NotEnoughAccountKeys,
);
};
};
}
#[macro_export]
macro_rules! hopper_dynamic_tail {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident {
$( $field:ident : $ty:ty ),* $(,)?
}
) => {
$(#[$meta])*
#[derive(Clone, Copy, Default)]
$vis struct $name {
$( pub $field: $ty, )*
}
impl $crate::__runtime::TailCodec for $name {
const MAX_ENCODED_LEN: usize = 0 $(+ <$ty as $crate::__runtime::TailCodec>::MAX_ENCODED_LEN)*;
#[inline]
fn encode(
&self,
out: &mut [u8],
) -> ::core::result::Result<usize, $crate::__runtime::ProgramError> {
let mut cursor = 0usize;
$(
let written = <$ty as $crate::__runtime::TailCodec>::encode(
&self.$field,
&mut out[cursor..],
)?;
cursor = cursor
.checked_add(written)
.ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?;
)*
Ok(cursor)
}
#[inline]
fn decode(
input: &[u8],
) -> ::core::result::Result<(Self, usize), $crate::__runtime::ProgramError> {
let mut cursor = 0usize;
$(
let ($field, consumed) = <$ty as $crate::__runtime::TailCodec>::decode(
&input[cursor..],
)?;
cursor = cursor
.checked_add(consumed)
.ok_or($crate::__runtime::ProgramError::InvalidAccountData)?;
)*
Ok((Self { $( $field, )* }, cursor))
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __hopper_dynamic_fields_tail {
(@emit [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]) => {
$crate::hopper_dynamic_tail! {
$($meta)*
$vis struct $name {
$($fields)*
}
}
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]) => {
$crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name] [$($fields)*]);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*] ,) => {
$crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name] [$($fields)*]);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : string < $cap:literal >, $($rest:tt)+
) => {
$crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
[$($fields)* $field: $crate::__runtime::HopperString<$cap>,]
$($rest)+
);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : string < $cap:literal > $(,)?
) => {
$crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
[$($fields)* $field: $crate::__runtime::HopperString<$cap>,]
);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : vec < $ty:ty, $cap:literal >, $($rest:tt)+
) => {
$crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
[$($fields)* $field: $crate::__runtime::HopperVec<$ty, $cap>,]
$($rest)+
);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : vec < $ty:ty, $cap:literal > $(,)?
) => {
$crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
[$($fields)* $field: $crate::__runtime::HopperVec<$ty, $cap>,]
);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : $ty:ty, $($rest:tt)+
) => {
$crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
[$($fields)* $field: $ty,]
$($rest)+
);
};
(@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
$field:ident : $ty:ty $(,)?
) => {
$crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
[$($fields)* $field: $ty,]
);
};
}
#[macro_export]
macro_rules! hopper_dynamic_fields {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident {
$($body:tt)*
}
) => {
$crate::__hopper_dynamic_fields_tail!(@parse [$(#[$meta])*] [$vis] [$name] [] $($body)*);
};
}
pub use hopper_runtime::{
address, err, error, fast_entrypoint, hopper_emit_cpi, hopper_entrypoint,
hopper_fast_entrypoint, hopper_lazy_entrypoint, hopper_log, hopper_unsafe_region,
lazy_entrypoint, msg, no_allocator, nostd_panic_handler, program_entrypoint, require,
require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq, require_lt,
require_lte, require_neq,
};
#[macro_export]
macro_rules! interface_account_set {
(
$(#[$marker_meta:meta])*
$vis:vis struct $marker:ident : $interface:ty;
$(#[$resolved_meta:meta])*
$enum_vis:vis enum $resolved:ident {
$($variant:ident($layout:ty)),+ $(,)?
}
) => {
$(#[$marker_meta])*
#[derive(Clone, Copy, Debug, Default)]
$vis struct $marker;
impl $crate::__runtime::FieldMap for $marker {
const FIELDS: &'static [$crate::__runtime::FieldInfo] = &[];
}
impl $crate::__runtime::LayoutContract for $marker {
const DISC: u8 = 0;
const VERSION: u8 = 0;
const LAYOUT_ID: [u8; 8] = [0; 8];
const SIZE: usize = $crate::__runtime::HopperHeader::SIZE;
}
impl $crate::__runtime::InterfaceAccountLayout for $marker {
type Interface = $interface;
#[inline]
fn validate_interface_account(
view: &$crate::__runtime::AccountView,
) -> ::core::result::Result<(), $crate::__runtime::ProgramError> {
let data = view.try_borrow()?;
let info = $crate::__runtime::LayoutInfo::from_data(&data)
.ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?;
if false $(|| info.matches::<$layout>())+ {
Ok(())
} else {
Err($crate::__runtime::ProgramError::InvalidAccountData)
}
}
}
$(#[$resolved_meta])*
$enum_vis enum $resolved<'a> {
$($variant($crate::__runtime::Ref<'a, $layout>)),+
}
impl $crate::__runtime::InterfaceAccountResolve for $marker {
type Resolved<'a> = $resolved<'a>;
#[inline]
fn resolve<'a>(
view: &'a $crate::__runtime::AccountView,
) -> ::core::result::Result<Self::Resolved<'a>, $crate::__runtime::ProgramError> {
let info = {
let data = view.try_borrow()?;
$crate::__runtime::LayoutInfo::from_data(&data)
.ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?
};
$(
if info.matches::<$layout>() {
return Ok($resolved::$variant(view.load_cross_program::<$layout>()?));
}
)+
Err($crate::__runtime::ProgramError::InvalidAccountData)
}
}
};
}
#[macro_export]
macro_rules! program_dispatch {
($program_mod:ident) => {
#[cfg(target_os = "solana")]
$crate::program_entrypoint!(__hopper_process_instruction);
#[doc(hidden)]
fn __hopper_process_instruction(
program_id: &$crate::__runtime::Address,
accounts: &[$crate::__runtime::AccountView],
instruction_data: &[u8],
) -> ::core::result::Result<(), $crate::__runtime::ProgramError> {
let mut ctx = $crate::prelude::Context::new(program_id, accounts, instruction_data);
$program_mod::process_instruction(&mut ctx)
}
};
}
#[cfg(feature = "proc-macros")]
pub use hopper_macros_proc::{
account, accounts, args, constant, context, crank, declare_program, dynamic, dynamic_account,
error as error_code, event, hopper_args, hopper_constant, hopper_context, hopper_crank,
hopper_dynamic, hopper_dynamic_account, hopper_event, hopper_migrate, hopper_pod,
hopper_program, hopper_state, migrate, pod, program, state, Accounts, HopperInitSpace,
};
#[doc(hidden)]
pub mod __runtime {
pub use hopper_runtime::{
apply_pending_migrations, borrow_address_slice, borrow_bounded_str, read_tail,
read_tail_len, tail_capacity, tail_payload, write_tail, Account, AccountLayout,
AccountView, Address, BoundedString, BoundedVec, Context, FieldInfo, FieldMap,
HopperHeader, HopperInstructionPolicy, HopperProgramPolicy, HopperSigner, HopperString,
HopperVec, InitAccount, InstructionAccount, InstructionView, Interface, InterfaceAccount,
InterfaceAccountLayout, InterfaceAccountResolve, InterfaceSpec, LayoutContract, LayoutInfo,
LayoutMigration, MigrationEdge, Pod, Program, ProgramError, ProgramId, Ref, RefMut, SegRef,
SegRefMut, SegmentLease, SystemAccount, SystemId, TailCodec, TailElement, UncheckedAccount,
};
pub use hopper_runtime::crank::CrankMarker;
pub use hopper_runtime::dyn_cpi::DynCpi;
#[cfg(feature = "hopper-native-backend")]
pub use hopper_runtime::__hopper_native;
pub use hopper_runtime::__sealed;
pub use hopper_runtime::token;
}