Every persistent piece of state in a Quasar program lives in an on-chain account described by theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/blueshift-gg/quasar/llms.txt
Use this file to discover all available pages before exploring further.
#[account] attribute macro. Unlike frameworks that deserialize account data into heap-allocated Rust structs, Quasar pointer-casts the raw SVM input buffer directly into a #[repr(C)] companion struct — zero copies, zero allocations, zero deserialization overhead.
The #[account] Attribute
Annotate a Rust struct with #[account(discriminator = N)] to turn it into a typed on-chain account. The macro automatically generates:
Discriminatortrait impl withDISCRIMINATOR: &'static [u8]Ownertrait impl binding the account tocrate::IDSpacetrait impl summing the discriminator length and all field sizes- A
#[repr(C)]zero-copy companion struct (the “Zc” type) used for direct pointer access
1 becomes a single-byte discriminator [1u8] prepended to the account’s data. Setting discriminator to 0 (all-zero bytes) is banned at compile time — the macro emits an error to prevent uninitialized data from accidentally passing validation.
Core Traits Generated
Discriminator
DISCRIMINATOR: &'static [u8] — the byte prefix stored at offset 0. Checked during every account parse.Owner
OWNER: Address = crate::ID — the program that must own the account. Validated when Account<T> is parsed.Space
SPACE: usize — total byte length including the discriminator. Used by init to size the create_account CPI.Account Data Layout
Zero-Copy Access and #[repr(C)]
Quasar generates a #[repr(C)] companion struct (the “Zc” type) for each #[account] struct. Accessing account fields goes through a pointer cast into the account’s data region — no heap allocation and no copying. The Account<T> wrapper implements Deref and DerefMut to this Zc type.
All field types used in an
#[account] struct must be Pod (plain-old-data) types with alignment 1. Use the zeropod types provided by Quasar (PodU64, PodBool, etc.) or Address (a 32-byte array) for every field.Pod Types from zeropod
Quasar re-exports alignment-safe integer types from the zeropod crate under quasar_lang::pod:
| Quasar type | Rust primitive |
|---|---|
PodU64 | u64 |
PodU32 | u32 |
PodU16 | u16 |
PodU8 / u8 | u8 |
PodBool | bool |
PodString (aliased as quasar_lang::String) | variable-length string |
PodVec (aliased as quasar_lang::Vec) | variable-length bytes |
Address | [u8; 32] — a Solana public key |
u64, u32, etc. are also valid when they already have the right alignment in a #[repr(C)] struct. Use Address directly for public keys.
PDA Seeds with #[seeds]
Combine #[account] with a #[seeds] attribute to declare typed PDA derivation:
Escrow::seeds(maker: &Address) -> impl SeedSpec method used by the address = constraint:
bump: u8 field, Discriminator::BUMP_OFFSET is automatically set so that PDA verification reads the bump from account data (~200 CU) instead of re-deriving it (~544 CU).
set_inner for Account Initialization
When set_inner is included in the #[account] attribute, the macro generates a set_inner method on the account wrapper. This is the idiomatic way to write all fields at once after init:
set_inner accepts an EscrowInner value (a plain Rust struct with the same fields) and writes each field into the account’s data region through the zero-copy companion.
AccountView Methods
Every account wrapper exposes its underlying AccountView through the AsAccountView trait. The most commonly used methods are:
Escrow State: Full Example
Here is the complete state definition from the escrow example program:All-Zero Discriminator Ban
Quasar bans all-zero discriminators at compile time. A freshly created account’s data buffer is zeroed, so an all-zero discriminator would allow uninitialized accounts to pass the discriminator check. The macro emits a compile error:1 or higher.