pinocchio-derive

Crates.iopinocchio-derive
lib.rspinocchio-derive
version0.1.0
created_at2025-07-09 04:18:18.281698+00
updated_at2025-07-09 04:18:18.281698+00
descriptionHelper derive macros for Pinocchio programs
homepage
repositoryhttps://github.com/joeymeere/pinocchio-util
max_upload_size
id1744148
size16,883
Joey Meere (joeymeere)

documentation

README

pinocchio-util

Overview

pinocchio-util is crate designed to make your life just a little bit easier when building pinocchio programs.

While only being around for a relatively short time, Pinocchio has quickly become a go-to library for building efficient Solana programs. It strikes an effective balance between low-level control and developer ergonomics, which is one of the reasons I love it.

That being said, I've noticed a variety of recurring patterns between my own programs, and programs built by others. This crate encompasses some of the tools I've used over time to make implementing those patterns a bit easier.

Installation

Install this crate with the following command:

cargo add pinocchio-util

or add this to your Cargo.toml:

pinocchio-util = "0.0.1"

Usage

Load an immutable reference to an account's data as an arbitrary type

let account_data = load::<UserData>(&account)?;

Load a mutable reference to an account's data as an arbitrary type:

let mut account_data = load_mut::<UserData>(&account)?;

Extract an account's discriminator:

/// Defaults to first 8 bytes like classic Anchor does
let discriminator = load_discriminator(&account, None).unwrap();

/// You can also define an arbitrary length, which some programs
/// >= Anchor 0.30.0 do to save bytes
let discriminator = load_discriminator(&account, Some(4)).unwrap();

This crate also exposes various traits like DataLen, AccountUpdates, Validate, and Context. These are useful in their own right, but are best used with the derive feature outlined below.

Derive Macros

Enable the derive feature to leverage various procedural macros:

pinocchio-util = { version = "0.0.1", features = ["derive"] }

Now that you've enabled them, you can add them to the various structs in your program:

#[derive(Context, Validate)]
pub struct BasicContext<'info> {
    // This is the signer
    #[validate(is_signer)]
    pub from: &'info AccountInfo,

    // This does match my random id
    #[validate(id = RANDOM_ID)]
    pub to: &'info AccountInfo,

    // This is a program, and this is the system program
    #[validate(is_executable, id = pinocchio_system::ID)]
    pub system_program: &'info AccountInfo,
}

// ...

let ctx = BasicContext::build(accounts)
    .map_err(|_| ProgramError::InvalidArgument)?;

Commit count: 0

cargo fmt