Instructions are the entry points into your Quasar program. Each handler consists of two parts: an accounts struct annotated withDocumentation 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.
#[derive(Accounts)] that declares and validates every account the instruction touches, and a function inside the #[program] module annotated with #[instruction(discriminator = N)] that contains the business logic.
#[instruction(discriminator = N)]
Place #[instruction(discriminator = N)] on a handler function inside a #[program] module to assign it a fixed dispatch byte:
dispatch! macro generated by #[program] matches the first byte(s) of the incoming instruction data against each registered discriminator and routes execution to the correct handler.
#[derive(Accounts)]
The accounts struct carries every account the handler needs. Annotate it with #[derive(Accounts)] and describe each field with #[account(...)] constraint attributes:
ParseAccounts impl that walks the SVM input buffer, validates every account (owner, discriminator, signer flags, writable flags, PDA addresses, and custom constraints), and returns the typed struct ready for use in the handler.
Account Constraint Attributes
Constraint attributes are placed on individual fields inside the#[derive(Accounts)] struct using #[account(...)]:
mut — require writable
mut — require writable
Mark an account as writable. The runtime rejects instructions where this account was not passed as writable.
init — create account
init — create account
Initialize a new on-chain account via a System Program CPI. Requires Use
payer = <field> to designate who pays rent.init(idempotent) to silently accept an account that is already initialized:has_one — foreign-key check
has_one — foreign-key check
Verify that a field on the account’s inner data equals the address of another account in the struct. Prevents substituting a different account for a related one.The check reads
escrow.maker and asserts it equals maker.address().address — exact address constraint
address — exact address constraint
Verify the account’s public key matches an expression. Used to enforce PDA addresses:
close — close account in epilogue
close — close account in epilogue
Transfer this account’s lamports to
dest and zero its data at the end of the instruction:constraints — arbitrary expression
constraints — arbitrary expression
Evaluate a boolean expression and return
ConstraintViolation if it is false:dup — allow duplicate account
dup — allow duplicate account
Allow the same account to appear more than once in a transaction. By default Quasar rejects duplicate accounts to prevent accidental aliasing:
token — SPL token account init
token — SPL token account init
When combined with
init or init(idempotent), configure token account initialization parameters:Ctx<T> — the Handler Context
Every instruction handler receives a Ctx<T> where T is the accounts struct:
ctx.accounts— the fully parsed and validated accounts structctx.bumps— auto-generated bump seeds for every PDA accountctx.program_id— the calling program’s addressctx.data— instruction data with the discriminator already consumed
CtxWithRemaining<T> for Remaining Accounts
When your handler needs to inspect or forward trailing accounts, use CtxWithRemaining<T> instead:
remaining_accounts() returns a RemainingAccounts iterator over account views beyond the declared fields.
Auto-Generated Bumps Struct
For every PDA account in the#[derive(Accounts)] struct, Quasar generates a <StructName>Bumps companion with one u8 field per PDA. Access bumps through ctx.bumps:
Instruction Data Parameters
Handler functions can accept additional typed parameters afterctx. These are deserialized from the remaining instruction data bytes after the discriminator:
InstructionArg. Built-in implementations cover all primitive integer types, bool, Address, and user types derived with #[derive(QuasarSerialize)]:
Full Escrow Example
- Make Instruction
- Refund Instruction
- Counter Instruction
The
#[inline(always)] attribute on impl methods is a Quasar convention. Because handlers call these small methods only once, inlining eliminates the call overhead and allows the compiler to optimize across the combined body.