A Rust CLI for Pinocchio programs. It scaffolds a project, builds and deploys it, keeps program IDs in sync, generates an IDL and a standalone Rust client from it, and lints for Solana-specific safety issues. Sensible defaults, no required configuration.
Installation
# Latest from GitHub
# From source
&&
Quick start
Commands
| Command | Description |
|---|---|
pinoc init <name> |
Create a new project |
pinoc build |
Build the program and regenerate the IDL |
pinoc test |
Build the program, then run tests |
pinoc check |
Lint for Solana-specific safety issues (account, CPI, zero-copy) |
pinoc deploy |
Deploy to a cluster |
pinoc clean |
Clean build artifacts (keypairs preserved) |
pinoc add <package> |
Add a Pinocchio package |
pinoc search [query] |
Search packages |
pinoc keys list |
List program keypairs |
pinoc keys sync |
Sync the program ID in source with its keypair |
pinoc idl |
Regenerate the IDL JSON |
pinoc client generate |
Generate a Rust client from the IDL |
pinoc config init |
Create a Pinoc.toml for the project |
Common options:
pinoc init <name> --with-example: scaffold a worked PDA-account example instead of a no-op programpinoc init <name> --no-git: skip git initializationpinoc deploy --cluster <cluster> --wallet <path>: override deployment settingspinoc build --program-id <ADDRESS>: set the IDL program address for programs that don't calldeclare_id!pinoc build --features <FEATURES>/pinoc test --features <FEATURES>: activate cargo features, passed tocargo build-sbfandcargo test(repeatable or comma-separated, like cargo's own flag)pinoc test --no-build: skip the SBF build and test against the existingtarget/deploy/*.sopinoc clean --no-preserve: clean everything, including keypairs
Testing
pinoc test runs cargo build-sbf before cargo test, because SVM tests (mollusk-svm, litesvm, solana-program-test) load target/deploy/*.so, which cargo test does not build. Without the build step, tests silently run against the last-built binary. --features applies to both steps, so the tested artifact and the test code always agree on the feature set. Pass --no-build to skip the build when iterating on tests that don't load the .so.
Project structure
pinoc init produces a blank, buildable program with a single no-op instruction:
my_app/
├── Cargo.toml
├── Pinoc.toml # deployment configuration
├── src/lib.rs
└── target/deploy/my_app-keypair.json
A full PDA-account creation example, annotated so pinoc idl works out of the box:
my_app/
├── src/
│ ├── lib.rs
│ ├── entrypoint.rs
│ ├── errors.rs
│ ├── instructions/{mod.rs, initialize.rs}
│ └── states/{mod.rs, state.rs, utils.rs}
├── tests/tests.rs
└── target/deploy/my_app-keypair.json
Configuration
Pinoc.toml holds deployment defaults and is optional:
[]
= "localhost"
= "~/.config/solana/id.json"
Without it, pinoc deploy falls back to solana config get; --cluster/--wallet always override. Create one on demand with pinoc config init.
Key management
keys sync finds the program's own ID declaration anywhere under src/ (either declare_id! or a const ID) and updates it in place.
IDL and client generation
pinoc build regenerates the IDL at target/idl/ on every build, and pinoc client generate renders a standalone Rust client crate from it. Both understand shank programs and programs using native Codama derive macros.
- IDL generation (files produced, generator selection, error handling, the zero-copy padding lint): src/idl/README.md
- Client generation (the shank and Codama generators, CPI variants,
fetch_*helpers, output paths): src/client_gen/README.md
Linting
pinoc check statically lints a program for Solana-specific safety issues that rustc, clippy, and rust-analyzer do not model: account ownership and signer checks, cross-program invocation safety, and zero-copy memory layout. Configurable severity, inline // pinoc:allow(CODE) suppression, and --json output for CI.
- Lint codes, configuration, and suppression: src/check/README.md
Prerequisites
- Rust 1.70+
- Solana CLI
- Node.js/npm (only for the Codama client generator)
Contributing
Fork, branch, make your change with tests, and open a pull request.
&& &&
License
Apache 2.0. See LICENSE.
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Pinocchio: anza-xyz/pinocchio
Acknowledgements
Pinoc began as a fork of solana-chio by Arjun.