Skip to main content

AccountList

Struct AccountList 

Source
pub struct AccountList<'a> { /* private fields */ }
Expand description

Iterator-style account accessor with inline constraint checks.

In raw pinocchio you typically write:

if accounts.len() < 4 {
    return Err(ProgramError::NotEnoughAccountKeys);
}
let payer  = &accounts[0];
check_signer(payer)?;
let vault  = &accounts[1];
check_writable(vault)?;
let system = &accounts[2];
check_system_program(system)?;
let state  = &accounts[3];
check_account(state, program_id, STATE_DISC, STATE_LEN)?;

AccountList collapses that to:

let mut accs = AccountList::new(accounts);
let payer  = accs.next_signer()?;
let vault  = accs.next_writable()?;
let system = accs.next_system_program()?;
let state  = accs.next_account(program_id, STATE_DISC, STATE_LEN)?;

Same instructions generated at the end - just far less noise.

Implementations§

Source§

impl<'a> AccountList<'a>

Source

pub fn new(accounts: &'a [AccountView]) -> Self

Source

pub fn remaining(&self) -> usize

How many accounts haven’t been consumed yet.

Source

pub fn next(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account with no additional checks.

Use this for accounts where you want to do custom validation immediately after, or for accounts that only need to exist.

Source

pub fn next_signer(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it signed the transaction.

Source

pub fn next_writable(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is marked writable.

Source

pub fn next_writable_signer(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is a writable signer.

Common pattern for the fee payer or the instruction authority that is also being mutated (e.g. depositing lamports).

Source

pub fn next_system_program(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is the system program.

Source

pub fn next_with_address( &mut self, expected: &Address, ) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify its address matches expected.

Use this to assert any well-known program or sysvar address:

let token_prog = accs.next_with_address(&jiminy::programs::TOKEN)?;
Source

pub fn next_account( &mut self, program_id: &Address, discriminator: u8, min_len: usize, ) -> Result<&'a AccountView, ProgramError>

Consume the next account and run the combined ownership + size + discriminator check. This is the most common pattern for your program’s own state accounts.

Source

pub fn next_writable_account( &mut self, program_id: &Address, discriminator: u8, min_len: usize, ) -> Result<&'a AccountView, ProgramError>

Consume the next account as a writable state account.

Combines next_account with a writable check - the most common pattern for accounts being modified in an instruction.

Source

pub fn next_executable(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is an executable program.

Use for CPI target programs passed as instruction accounts, where you want to confirm the caller didn’t pass a regular data account.

Source

pub fn next_signer_writable_account( &mut self, program_id: &Address, discriminator: u8, min_len: usize, ) -> Result<&'a AccountView, ProgramError>

Consume the next account as a writable signer state account.

Combines signer + writable + ownership + size + discriminator checks. The full equivalent of Anchor’s #[account(mut, signer)] for a program-owned state account.

let state = accs.next_signer_writable_account(program_id, STATE_DISC, STATE_LEN)?;
Source

pub fn next_token_account( &mut self, expected_mint: &Address, expected_owner: &Address, ) -> Result<&'a AccountView, ProgramError>

Consume the next account as a validated token account.

Verifies: data size ≥ 165, mint matches, owner matches. This is the zero-copy equivalent of Anchor’s:

#[account(token::mint = expected_mint, token::authority = expected_owner)]
let user_token = accs.next_token_account(&usdc_mint, user.address())?;
Source

pub fn next_mint( &mut self, expected_token_program: &Address, ) -> Result<&'a AccountView, ProgramError>

Consume the next account as a validated mint.

Verifies: data size ≥ 82 and owned by the expected token program.

let mint = accs.next_mint(&programs::TOKEN)?;
Source

pub fn next_clock(&mut self) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is the Clock sysvar.

let clock = accs.next_clock()?;
let (slot, timestamp) = jiminy::sysvar::read_clock(clock)?;
Source

pub fn next_sysvar_instructions( &mut self, ) -> Result<&'a AccountView, ProgramError>

Consume the next account and verify it is the Sysvar Instructions account.

Required for CPI guard checks (check_no_cpi_caller).

let sysvar_ix = accs.next_sysvar_instructions()?;
jiminy::cpi_guard::check_no_cpi_caller(sysvar_ix, program_id)?;

Auto Trait Implementations§

§

impl<'a> Freeze for AccountList<'a>

§

impl<'a> RefUnwindSafe for AccountList<'a>

§

impl<'a> !Send for AccountList<'a>

§

impl<'a> !Sync for AccountList<'a>

§

impl<'a> Unpin for AccountList<'a>

§

impl<'a> UnsafeUnpin for AccountList<'a>

§

impl<'a> UnwindSafe for AccountList<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.