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.
cargo install pinocOther methods
# Latest from GitHub
cargo install --git https://github.com/A91y/pinoc --force
# From source
git clone https://github.com/A91y/pinoc.git
cd pinoc && cargo install --path .pinoc init my_app # scaffold a project
cd my_app
pinoc build # build + regenerate the IDL
pinoc test # run tests (mollusk-svm)
pinoc check # lint for Solana safety issues
pinoc deploy # deploy to the configured cluster| Command | Description |
|---|---|
pinoc init <name> |
Create a new project |
pinoc build |
Build the program and regenerate the IDL |
pinoc test |
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 clean --no-preserve: clean everything, including keypairs
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
--with-example layout
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
Pinoc.toml holds deployment defaults and is optional:
[provider]
cluster = "localhost"
wallet = "~/.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.
pinoc keys list # list program keypairs and their addresses
pinoc keys sync # rewrite the program ID in source to match the keypairkeys sync finds the program's own ID declaration anywhere under src/ (either declare_id! or a const ID) and updates it in place.
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
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.
pinoc check # report findings, exit nonzero on a deny
pinoc check --deny '*' # promote every check to a hard failure- Lint codes, configuration, and suppression: src/check/README.md
- Rust 1.70+
- Solana CLI
- Node.js/npm (only for the Codama client generator)
Fork, branch, make your change with tests, and open a pull request.
git clone https://github.com/A91y/pinoc.git
cd pinoc && cargo build --release && cargo install --path .Apache 2.0. See LICENSE.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Pinocchio: anza-xyz/pinocchio
Pinoc began as a fork of solana-chio by Arjun.
