Skip to main content

hopper_core/accounts/
entry.rs

1//! Typed instruction entry model.
2//!
3//! Provides `HopperIx` trait for instruction definition and `hopper_entry()`
4//! for clean instruction dispatch. Bridges the Account DSL to Hopper's
5//! existing dispatch system.
6
7use hopper_runtime::error::ProgramError;
8use hopper_runtime::{AccountView, Address};
9
10use super::context::{HopperAccounts, HopperCtx};
11
12/// Trait defining a Hopper instruction.
13///
14/// Combines argument parsing with account construction into a single
15/// instruction definition. Used with `hopper_entry()` for typed dispatch.
16pub trait HopperIx<'a>: Sized {
17    /// The account struct for this instruction.
18    type Accounts: HopperAccounts<'a>;
19    /// The parsed argument type.
20    type Args;
21
22    /// Parse instruction arguments from raw data (after dispatch tag).
23    fn parse_args(data: &'a [u8]) -> Result<Self::Args, ProgramError>;
24}
25
26/// Typed instruction entry point.
27///
28/// Parses arguments, constructs the validated context, and invokes the handler.
29/// One-line replacement for manual dispatch + parse + validate + execute.
30///
31/// ```ignore
32/// hopper_entry::<DepositIx, _>(program_id, accounts, data, |ctx, args| {
33///     deposit(ctx, args.amount)
34/// })
35/// ```
36#[inline]
37pub fn hopper_entry<'a, I, F>(
38    program_id: &'a Address,
39    accounts: &'a [AccountView],
40    instruction_data: &'a [u8],
41    handler: F,
42) -> Result<(), ProgramError>
43where
44    I: HopperIx<'a>,
45    F: FnOnce(HopperCtx<'a, I::Accounts>, I::Args) -> Result<(), ProgramError>,
46{
47    let args = I::parse_args(instruction_data)?;
48    let (accts, bumps) = I::Accounts::try_from_accounts(program_id, accounts, instruction_data)?;
49    let consumed = I::Accounts::ACCOUNT_COUNT;
50    let remaining = if consumed < accounts.len() {
51        &accounts[consumed..]
52    } else {
53        &[]
54    };
55    let ctx = HopperCtx::new(accts, bumps, program_id, instruction_data, remaining);
56    handler(ctx, args)
57}