pina_cli 0.8.0

CLI tool for Pina Solana programs (IDL generation and more)
Documentation
# Rules for Reliable IDL Generation

Follow these rules so `pina idl` can extract complete and accurate metadata from program source.

1. **Single-file programs** Keep the program entrypoint, accounts, instructions, and macros in `src/lib.rs`. Multi-file module traversal is not supported yet.

2. **`declare_id!` is required** Declare exactly one program ID using `declare_id!("...")`.

3. **Validation must live in `process()`** Signer, writable, PDA, and default-address inference is collected from `impl ProcessAccountInfos for ... { fn process(...) { ... } }` bodies.

4. **Use direct `self.<field>.assert_*()` chains** Validation inference expects assertions on direct `self.field` chains. Indirection through helper functions or temporaries may be missed.

5. **Use `match` dispatch in `process_instruction`** Instruction wiring is inferred from a `match` over the discriminator in `process_instruction` (top-level or inside `mod entrypoint`) that calls `<Accounts>::try_from(accounts)?.process(data)`.

6. **Use explicit discriminator values** All `#[discriminator]` enum variants should define explicit integer values (`Initialize = 0`, `Update = 1`, ...).

7. **Seed macros must include `seeds` in the macro name** PDA macro discovery is heuristic and only scans `macro_rules!` names containing `seeds` (for example `counter_seeds!` or `seeds_counter!`).

8. **Seed constants must be byte-string constants** Use `const NAME: &[u8] = b"...";` for constant PDA seeds so they can be lifted into IDL.

9. **Reference discriminator enums in attributes** Account and instruction structs should always point to their discriminator enums via attributes such as `#[account(discriminator = AccountDiscriminator)]` and `#[instruction(discriminator = InstructionDiscriminator, ...)]`.

10. **Use known program ID paths for default-value inference** For automatic default account public keys, use `assert_address` with these paths: `system::ID`, `token::ID`, `token_2022::ID`, or `associated_token_account::ID`.