1#![no_std]
111#![deny(unsafe_op_in_unsafe_fn)]
112
113#[cfg(any(
114 all(feature = "hopper-native-backend", feature = "legacy-pinocchio-compat"),
115 all(feature = "hopper-native-backend", feature = "solana-program-backend"),
116 all(
117 feature = "legacy-pinocchio-compat",
118 feature = "solana-program-backend"
119 ),
120))]
121compile_error!("Enable exactly one Hopper backend: hopper-native-backend, legacy-pinocchio-compat, or solana-program-backend.");
122
123#[doc(hidden)]
126pub mod __macro_support;
127pub mod guards;
128pub mod pda;
129pub mod prelude;
130pub mod receipts;
131
132pub use hopper_associated_token;
134pub use hopper_core;
135pub use hopper_runtime;
136pub use hopper_schema;
137pub use hopper_solana;
138pub use hopper_system;
139pub use hopper_token;
140pub use hopper_token_2022;
141
142pub mod account {
149 pub use hopper_core::abi::{
150 Authority, Mint, Token, TokenAccount, TypedAddress, UntypedAddress,
151 };
152 pub use hopper_core::accounts::{
153 HopperAccount, HopperAccounts, HopperCtx, HopperIx, ProgramAccount, ProgramRef,
154 SegmentedAccount, SignerAccount, ValidateAccount,
155 };
156 pub use hopper_runtime::{
157 Account, AccountView, HopperSigner as Signer, InitAccount, Interface, InterfaceAccount,
158 InterfaceAccountLayout, InterfaceAccountResolve, InterfaceSpec, Program, ProgramId,
159 SystemAccount, SystemId, UncheckedAccount,
160 };
161
162 pub type System = SystemId;
164}
165
166pub mod context {
168 pub use hopper_core::accounts::{hopper_entry, HopperAccounts, HopperCtx, HopperIx};
169 pub use hopper_runtime::Context;
170}
171
172pub mod cpi {
174 pub use hopper_core::cpi::*;
175 pub use hopper_runtime::cpi::{
176 invoke, invoke_signed, invoke_signed_unchecked, invoke_signed_with_bounds,
177 invoke_unchecked, invoke_with_bounds, set_return_data, MAX_CPI_ACCOUNTS, MAX_RETURN_DATA,
178 MAX_STATIC_CPI_ACCOUNTS,
179 };
180 pub use hopper_runtime::{CpiAccount, InstructionAccount, InstructionView, Seed, Signer};
181}
182
183#[allow(unused_imports)]
185pub mod system {
186 pub use hopper_system::instructions::*;
187 pub use hopper_system::SYSTEM_PROGRAM_ID;
188 pub use hopper_system::*;
189}
190
191#[allow(ambiguous_glob_reexports, unused_imports)]
193pub mod token {
194 pub use hopper_runtime::token::*;
195 pub use hopper_solana::interface::{
196 interface_transfer_checked, interface_transfer_checked_signed, InterfaceMint,
197 InterfaceTokenAccount, TokenProgramKind,
198 };
199 pub use hopper_token::instructions::*;
200 pub use hopper_token::TOKEN_PROGRAM_ID;
201 pub use hopper_token::*;
202}
203
204#[allow(ambiguous_glob_reexports, unused_imports)]
206pub mod token_2022 {
207 pub use hopper_runtime::token_2022_ext::*;
208 pub use hopper_token_2022::instructions::*;
209 pub use hopper_token_2022::TOKEN_2022_PROGRAM_ID;
210 pub use hopper_token_2022::*;
211}
212
213#[allow(unused_imports)]
215pub mod associated_token {
216 pub use hopper_associated_token::instructions::*;
217 pub use hopper_associated_token::ATA_PROGRAM_ID;
218 pub use hopper_associated_token::*;
219}
220
221pub mod memo {
223 pub use hopper_memo::*;
224}
225
226pub mod events {
228 pub use crate::receipts::{emit_receipt, emit_tagged_receipt, emit_typed_receipt, Receipt};
229 #[cfg(feature = "cpi")]
230 pub use hopper_core::event::emit_event_cpi;
231 pub use hopper_core::event::{emit_event, emit_event_tagged, emit_slices};
232 pub use hopper_runtime::{hopper_emit_cpi, hopper_log, msg};
233}
234
235pub mod layout {
237 pub use hopper_core::abi::{FingerprintTransition, LayoutFingerprint, WireType};
238 pub use hopper_core::account::{
239 check_header, read_discriminator, read_header_flags, read_layout_id, read_version,
240 write_header, AccountHeader, AccountReader, FixedLayout, HEADER_FORMAT, HEADER_LEN,
241 };
242 pub use hopper_core::field_map::{FieldInfo, FieldMap};
243 pub use hopper_runtime::layout::{init_header, HopperHeader, LayoutContract, LayoutInfo};
244 pub use hopper_runtime::{AccountLayout, Pod, WireLayout, ZeroCopy};
245}
246
247pub mod segment {
249 pub use hopper_core::account::segment_role::{
250 SegmentRole, SEG_ROLE_AUDIT, SEG_ROLE_CACHE, SEG_ROLE_CORE, SEG_ROLE_EXTENSION,
251 SEG_ROLE_INDEX, SEG_ROLE_JOURNAL, SEG_ROLE_SHARD,
252 };
253 pub use hopper_core::account::{
254 segment_id, SegmentDescriptor, SegmentEntry, SegmentId, SegmentRegistry,
255 SegmentRegistryMut, SegmentSlice, SegmentSliceMut, SegmentTable, SegmentTableMut,
256 MAX_REGISTRY_SEGMENTS, MAX_SEGMENTS, REGISTRY_HEADER_SIZE, REGISTRY_OFFSET,
257 SEGMENT_DESC_SIZE, SEGMENT_ENTRY_SIZE, SEG_FLAG_DYNAMIC, SEG_FLAG_FROZEN, SEG_FLAG_LOCKED,
258 };
259 pub use hopper_core::segment_map::{assert_segment_field_alignment, SegmentMap, StaticSegment};
260 pub use hopper_runtime::{
261 AccessKind, FieldCapability, Ref, RefMut, SegRef, SegRefMut, Segment, SegmentBorrow,
262 SegmentBorrowGuard, SegmentBorrowRegistry, SegmentLease, TypedSegment,
263 FIELD_POLICY_AUTHORITY_GATED, FIELD_POLICY_CHECKED_MATH, FIELD_POLICY_IMMUTABLE_AFTER_INIT,
264 FIELD_ROLE_AUTHORITY, FIELD_ROLE_BALANCE, FIELD_ROLE_DATA, FIELD_ROLE_VERSION,
265 };
266}
267
268pub mod receipt {
270 pub use crate::receipts::{emit_receipt, emit_tagged_receipt, emit_typed_receipt, Receipt};
271 #[cfg(feature = "receipt")]
272 pub use hopper_core::receipt::*;
273}
274
275pub mod migration {
277 #[cfg(feature = "migrate")]
278 pub use hopper_core::migrate::*;
279 pub use hopper_runtime::{apply_pending_migrations, LayoutMigration, MigrationEdge};
280}
281
282pub mod interface {
284 pub use hopper_runtime::{
285 ForeignLens, ForeignManifest, Interface, InterfaceAccount, InterfaceAccountLayout,
286 InterfaceAccountResolve, InterfaceSpec, TransparentAddress,
287 };
288 pub use hopper_solana::interface::*;
289}
290
291pub mod schema {
293 pub use hopper_schema::*;
294}
295
296pub mod policy {
298 #[cfg(feature = "policy")]
299 pub use hopper_core::policy::*;
300 pub use hopper_runtime::{HopperInstructionPolicy, HopperProgramPolicy, HopperProgramProfile};
301}
302
303#[allow(ambiguous_glob_reexports, unused_imports)]
309pub mod systems {
310 pub use crate::interface::*;
311 pub use crate::layout::*;
312 pub use crate::migration::*;
313 pub use crate::policy::*;
314 pub use crate::receipt::*;
315 pub use crate::schema::*;
316 pub use crate::segment::*;
317 pub use crate::{interface, layout, migration, policy, receipt, schema, segment};
318
319 pub use hopper_core::account::{
320 overlay, overlay_mut, read_dynamic_u16, read_dynamic_u32, read_dynamic_u8, safe_close,
321 safe_close_with_sentinel, safe_realloc, write_dynamic_u16, write_dynamic_u32,
322 write_dynamic_u8, DynamicView, DynamicViewMut, ReallocGuard, VerifiedAccount,
323 VerifiedAccountMut, CLOSE_SENTINEL,
324 };
325 pub use hopper_core::check::{find_and_verify_pda, rent_exempt_min};
326 pub use hopper_core::prelude_advanced::*;
327 pub use hopper_core::prelude_core::*;
328 pub use hopper_runtime::{
329 fast_entrypoint, hopper_entrypoint, hopper_fast_entrypoint, hopper_lazy_entrypoint,
330 lazy_entrypoint, no_allocator, nostd_panic_handler, program_entrypoint, AccountProof,
331 BoundedString, BoundedVec, CpiAccount, ExecutableChecked, HasOneChecked, HopperString,
332 HopperVec, InstructionAccount, InstructionView, LayoutChecked, OwnerChecked, Seed,
333 SeedsChecked, SignerChecked, TailCodec, TailElement, TokenExtensionsChecked, Unchecked,
334 WritableChecked,
335 };
336
337 pub use crate::{
338 const_assert_pod, hopper_accounts, hopper_assert_compatible, hopper_assert_fingerprint,
339 hopper_check, hopper_close, hopper_dynamic_fields, hopper_dynamic_tail, hopper_error,
340 hopper_init, hopper_interface, hopper_invariant, hopper_layout, hopper_load,
341 hopper_manifest, hopper_register_discs, hopper_require, hopper_segment, hopper_validate,
342 hopper_verify_pda, hopper_virtual, layout_migrations,
343 };
344
345 #[cfg(feature = "proc-macros")]
346 pub use crate::{args, declare_program, dynamic, migrate, pod, state};
347}
348
349#[allow(ambiguous_glob_reexports, unused_imports)]
356pub mod substrate {
357 pub use hopper_runtime::{
358 AccountView, Address, CpiAccount, InstructionAccount, InstructionView, ProgramError,
359 ProgramResult, Ref, RefMut, Seed, Signer, SUCCESS,
360 };
361
362 #[cfg(feature = "hopper-native-backend")]
363 pub use hopper_runtime::__hopper_native::{
364 account_view, address, batch, budget, capability, entrypoint, error, hash, introspect,
365 lazy, lens, log, mem, pda, pod, raw, raw_account, raw_input, return_data, safe, syscalls,
366 sysvar, verify, wire, AccountView as NativeAccountView, Address as NativeAddress, CuBudget,
367 DataFingerprint, LamportSnapshot, ReturnData,
368 };
369
370 #[cfg(feature = "hopper-native-backend")]
371 pub use hopper_runtime::__hopper_native::{
372 find_bump_for_address, read_bump_from_account, verify_pda_from_stored_bump,
373 verify_pda_strict, RuntimeAccount,
374 };
375}
376
377#[cfg(feature = "finance")]
379pub mod finance {
380 pub use hopper_finance::*;
381}
382
383#[cfg(feature = "lending")]
385pub mod lending {
386 pub use hopper_lending::*;
387}
388
389#[cfg(feature = "staking")]
391pub mod staking {
392 pub use hopper_staking::*;
393}
394
395#[cfg(feature = "vesting")]
397pub mod vesting {
398 pub use hopper_vesting::*;
399}
400
401#[cfg(feature = "distribute")]
403pub mod distribute {
404 pub use hopper_distribute::*;
405}
406
407#[cfg(feature = "multisig")]
409pub mod multisig {
410 pub use hopper_multisig::*;
411}
412
413#[cfg(feature = "anchor-interop")]
415pub mod anchor {
416 pub use hopper_anchor::*;
417}
418
419#[doc(hidden)]
421pub mod internal {
422 pub use crate::{hopper_core, hopper_runtime, hopper_schema, hopper_solana};
423}
424
425#[cfg(feature = "metaplex")]
430pub use hopper_metaplex;
431
432pub use hopper_runtime::utils;
435
436pub use hopper_core::hopper_dispatch;
438pub use hopper_macros::{
439 const_assert_pod, hopper_accounts, hopper_assert_compatible, hopper_assert_fingerprint,
440 hopper_check, hopper_close, hopper_error, hopper_init, hopper_interface, hopper_invariant,
441 hopper_layout, hopper_manifest, hopper_register_discs, hopper_require, hopper_segment,
442 hopper_validate, hopper_verify_pda, hopper_virtual,
443};
444
445pub use hopper_runtime::layout_migrations;
450
451#[macro_export]
505macro_rules! hopper_load {
506 ( $slice:expr => [ $($binding:ident),+ $(, ..)? $(,)? ] ) => {
507 let [ $($binding,)+ .. ] = $slice else {
508 return ::core::result::Result::Err(
509 $crate::hopper_runtime::error::ProgramError::NotEnoughAccountKeys,
510 );
511 };
512 };
513}
514
515#[macro_export]
535macro_rules! hopper_dynamic_tail {
536 (
537 $(#[$meta:meta])*
538 $vis:vis struct $name:ident {
539 $( $field:ident : $ty:ty ),* $(,)?
540 }
541 ) => {
542 $(#[$meta])*
543 #[derive(Clone, Copy, Default)]
544 $vis struct $name {
545 $( pub $field: $ty, )*
546 }
547
548 impl $crate::__runtime::TailCodec for $name {
549 const MAX_ENCODED_LEN: usize = 0 $(+ <$ty as $crate::__runtime::TailCodec>::MAX_ENCODED_LEN)*;
550
551 #[inline]
552 fn encode(
553 &self,
554 out: &mut [u8],
555 ) -> ::core::result::Result<usize, $crate::__runtime::ProgramError> {
556 let mut cursor = 0usize;
557 $(
558 let written = <$ty as $crate::__runtime::TailCodec>::encode(
559 &self.$field,
560 &mut out[cursor..],
561 )?;
562 cursor = cursor
563 .checked_add(written)
564 .ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?;
565 )*
566 Ok(cursor)
567 }
568
569 #[inline]
570 fn decode(
571 input: &[u8],
572 ) -> ::core::result::Result<(Self, usize), $crate::__runtime::ProgramError> {
573 let mut cursor = 0usize;
574 $(
575 let ($field, consumed) = <$ty as $crate::__runtime::TailCodec>::decode(
576 &input[cursor..],
577 )?;
578 cursor = cursor
579 .checked_add(consumed)
580 .ok_or($crate::__runtime::ProgramError::InvalidAccountData)?;
581 )*
582 Ok((Self { $( $field, )* }, cursor))
583 }
584 }
585 };
586}
587
588#[doc(hidden)]
589#[macro_export]
590macro_rules! __hopper_dynamic_fields_tail {
591 (@emit [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]) => {
592 $crate::hopper_dynamic_tail! {
593 $($meta)*
594 $vis struct $name {
595 $($fields)*
596 }
597 }
598 };
599
600 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]) => {
601 $crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name] [$($fields)*]);
602 };
603 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*] ,) => {
604 $crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name] [$($fields)*]);
605 };
606
607 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
608 $field:ident : string < $cap:literal >, $($rest:tt)+
609 ) => {
610 $crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
611 [$($fields)* $field: $crate::__runtime::HopperString<$cap>,]
612 $($rest)+
613 );
614 };
615 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
616 $field:ident : string < $cap:literal > $(,)?
617 ) => {
618 $crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
619 [$($fields)* $field: $crate::__runtime::HopperString<$cap>,]
620 );
621 };
622
623 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
624 $field:ident : vec < $ty:ty, $cap:literal >, $($rest:tt)+
625 ) => {
626 $crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
627 [$($fields)* $field: $crate::__runtime::HopperVec<$ty, $cap>,]
628 $($rest)+
629 );
630 };
631 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
632 $field:ident : vec < $ty:ty, $cap:literal > $(,)?
633 ) => {
634 $crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
635 [$($fields)* $field: $crate::__runtime::HopperVec<$ty, $cap>,]
636 );
637 };
638
639 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
640 $field:ident : $ty:ty, $($rest:tt)+
641 ) => {
642 $crate::__hopper_dynamic_fields_tail!(@parse [$($meta)*] [$vis] [$name]
643 [$($fields)* $field: $ty,]
644 $($rest)+
645 );
646 };
647 (@parse [$($meta:tt)*] [$vis:vis] [$name:ident] [$($fields:tt)*]
648 $field:ident : $ty:ty $(,)?
649 ) => {
650 $crate::__hopper_dynamic_fields_tail!(@emit [$($meta)*] [$vis] [$name]
651 [$($fields)* $field: $ty,]
652 );
653 };
654}
655
656#[macro_export]
673macro_rules! hopper_dynamic_fields {
674 (
675 $(#[$meta:meta])*
676 $vis:vis struct $name:ident {
677 $($body:tt)*
678 }
679 ) => {
680 $crate::__hopper_dynamic_fields_tail!(@parse [$(#[$meta])*] [$vis] [$name] [] $($body)*);
681 };
682}
683
684pub use hopper_runtime::{
690 address, err, error, fast_entrypoint, hopper_emit_cpi, hopper_entrypoint,
691 hopper_fast_entrypoint, hopper_lazy_entrypoint, hopper_log, hopper_unsafe_region,
692 lazy_entrypoint, msg, no_allocator, nostd_panic_handler, program_entrypoint, require,
693 require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq, require_lt,
694 require_lte, require_neq,
695};
696
697#[macro_export]
713macro_rules! interface_account_set {
714 (
715 $(#[$marker_meta:meta])*
716 $vis:vis struct $marker:ident : $interface:ty;
717 $(#[$resolved_meta:meta])*
718 $enum_vis:vis enum $resolved:ident {
719 $($variant:ident($layout:ty)),+ $(,)?
720 }
721 ) => {
722 $(#[$marker_meta])*
723 #[derive(Clone, Copy, Debug, Default)]
724 $vis struct $marker;
725
726 impl $crate::__runtime::FieldMap for $marker {
727 const FIELDS: &'static [$crate::__runtime::FieldInfo] = &[];
728 }
729
730 impl $crate::__runtime::LayoutContract for $marker {
731 const DISC: u8 = 0;
732 const VERSION: u8 = 0;
733 const LAYOUT_ID: [u8; 8] = [0; 8];
734 const SIZE: usize = $crate::__runtime::HopperHeader::SIZE;
735 }
736
737 impl $crate::__runtime::InterfaceAccountLayout for $marker {
738 type Interface = $interface;
739
740 #[inline]
741 fn validate_interface_account(
742 view: &$crate::__runtime::AccountView,
743 ) -> ::core::result::Result<(), $crate::__runtime::ProgramError> {
744 let data = view.try_borrow()?;
745 let info = $crate::__runtime::LayoutInfo::from_data(&data)
746 .ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?;
747 if false $(|| info.matches::<$layout>())+ {
748 Ok(())
749 } else {
750 Err($crate::__runtime::ProgramError::InvalidAccountData)
751 }
752 }
753 }
754
755 $(#[$resolved_meta])*
756 $enum_vis enum $resolved<'a> {
757 $($variant($crate::__runtime::Ref<'a, $layout>)),+
758 }
759
760 impl $crate::__runtime::InterfaceAccountResolve for $marker {
761 type Resolved<'a> = $resolved<'a>;
762
763 #[inline]
764 fn resolve<'a>(
765 view: &'a $crate::__runtime::AccountView,
766 ) -> ::core::result::Result<Self::Resolved<'a>, $crate::__runtime::ProgramError> {
767 let info = {
768 let data = view.try_borrow()?;
769 $crate::__runtime::LayoutInfo::from_data(&data)
770 .ok_or($crate::__runtime::ProgramError::AccountDataTooSmall)?
771 };
772 $(
773 if info.matches::<$layout>() {
774 return Ok($resolved::$variant(view.load_cross_program::<$layout>()?));
775 }
776 )+
777 Err($crate::__runtime::ProgramError::InvalidAccountData)
778 }
779 }
780 };
781}
782
783#[macro_export]
800macro_rules! program_dispatch {
801 ($program_mod:ident) => {
802 #[cfg(target_os = "solana")]
803 $crate::program_entrypoint!(__hopper_process_instruction);
804
805 #[doc(hidden)]
806 fn __hopper_process_instruction(
807 program_id: &$crate::__runtime::Address,
808 accounts: &[$crate::__runtime::AccountView],
809 instruction_data: &[u8],
810 ) -> ::core::result::Result<(), $crate::__runtime::ProgramError> {
811 let mut ctx = $crate::prelude::Context::new(program_id, accounts, instruction_data);
812 $program_mod::process_instruction(&mut ctx)
813 }
814 };
815}
816
817#[cfg(feature = "proc-macros")]
819pub use hopper_macros_proc::{
820 account, accounts, args, constant, context, crank, declare_program, dynamic, dynamic_account,
821 error as error_code, event, hopper_args, hopper_constant, hopper_context, hopper_crank,
822 hopper_dynamic, hopper_dynamic_account, hopper_event, hopper_migrate, hopper_pod,
823 hopper_program, hopper_state, migrate, pod, program, state, Accounts, HopperInitSpace,
824};
825
826#[doc(hidden)]
828pub mod __runtime {
829 pub use hopper_runtime::token_2022_ext;
830 pub use hopper_runtime::{
831 apply_pending_migrations, borrow_address_slice, borrow_bounded_str, read_tail,
832 read_tail_len, tail_capacity, tail_payload, write_tail, Account, AccountLayout,
833 AccountView, Address, BoundedString, BoundedVec, Context, FieldInfo, FieldMap,
834 HopperHeader, HopperInstructionPolicy, HopperProgramPolicy, HopperProgramProfile,
835 HopperSigner, HopperString, HopperVec, InitAccount, InstructionAccount, InstructionView,
836 Interface, InterfaceAccount, InterfaceAccountLayout, InterfaceAccountResolve,
837 InterfaceSpec, LayoutContract, LayoutInfo, LayoutMigration, MigrationEdge, Pod, Program,
838 ProgramError, ProgramId, Ref, RefMut, SegRef, SegRefMut, SegmentLease, SystemAccount,
839 SystemId, TailCodec, TailElement, UncheckedAccount,
840 };
841
842 pub use hopper_runtime::crank::CrankMarker;
848 pub use hopper_runtime::dyn_cpi::DynCpi;
849
850 #[cfg(feature = "hopper-native-backend")]
855 pub use hopper_runtime::__hopper_native;
856
857 pub use hopper_runtime::__sealed;
862
863 pub use hopper_runtime::token;
871}