add skill for Pinocchio framework#1
Conversation
WalkthroughAdds Pinocchio framework support alongside Anchor in SKILL and delegation docs, adjusts examples to Pinocchio-style account dispatch and new public entry points, and clarifies that only delegated accounts may be writable in Ephemeral Rollups instructions. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@skill/delegation.md`:
- Around line 124-129: The module imports undelegate from
ephemeral_rollups_pinocchio::instruction and also defines a local pub fn
undelegate, causing a name collision; fix it by aliasing the imported symbol
(e.g., use undelegate as instr_undelegate) or by switching to the
fully-qualified path when calling the instruction, then update all call sites
that currently call undelegate from the import to use the alias (or
fully-qualified path); apply the same aliasing/update for the other occurrences
noted between the later example block (the additional import/use sites around
the second undelegate example).
- Around line 241-248: The docs currently mention process_undelegation_callback
but the example and callback name used elsewhere is undelegation_callback;
update the text so the callback name is consistent—either rename the example to
process_undelegation_callback or (preferably) change the doc text to reference
undelegation_callback so it matches the example and any code that calls
undelegation_callback; also keep the adjacent note about calling undelegate()
and the copy-semantics note for commit_accounts / commit_and_undelegate_accounts
unchanged.
- Around line 113-120: Update the dependency versions in the Cargo manifest
snippet so they match published releases: change pinocchio from "0.10.2" to
"0.10.1", pinocchio-log from "0.5" to "0.5.1", and ephemeral-rollups-pinocchio
from "0.8.5" to "0.8.4" while leaving pinocchio's features ["cpi","copy"] and
pinocchio-system = "0.5" unchanged; ensure the updated versions replace the
entries for pinocchio, pinocchio-log, and ephemeral-rollups-pinocchio in the
shown Cargo.toml block.
| ```toml | ||
| # Cargo.toml | ||
| [dependencies] | ||
| pinocchio = { version = "0.10.2", features = ["cpi", "copy"] } | ||
| pinocchio-log = { version = "0.5" } | ||
| pinocchio-system = { version = "0.5" } | ||
| ephemeral-rollups-pinocchio = { version = "0.8.5" } | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
pinocchio rust crate latest version 2025 2026 crates.io
💡 Result:
As of February 7, 2026, the latest pinocchio Rust crate version on crates.io is 0.10.1. [1][2]
🌐 Web query:
pinocchio-log pinocchio-system ephemeral-rollups-pinocchio latest versions
💡 Result:
Latest published crate versions (per docs.rs “latest” / crate page):
- pinocchio-log: 0.5.1 [1]
- pinocchio-system: 0.5.0 [2]
- ephemeral-rollups-pinocchio: 0.8.4 [3]
Sources: [1] pinocchio-log docs.rs, [2] pinocchio-system docs.rs, [3] ephemeral-rollups-pinocchio docs.rs.
🌐 Web query:
pinocchio 0.10.2 crate features cpi copy deprecated
💡 Result:
As of February 7, 2026, I don’t see a pinocchio crate release 0.10.2 on crates.io; the latest published version appears to be 0.10.1 (published ~4 weeks ago). [1]
In the current docs for pinocchio (latest = 0.10.1), the Cargo features are:
cpi: enables cross-program invocation (CPI) helpers and related instruction/signer types. Not shown as deprecated. [2]copy: enables derivingCopyfor types (and enablescopyon some re-exports). Not shown as deprecated. [2]
What is deprecated is the pinocchio::program module (deprecated since 0.8.0) with guidance to use the cpi module instead—this is about a module path, not the cpi feature flag. [3]
Sources: [1] [2] [3]
Update Cargo.toml to use valid published versions.
pinocchioversion 0.10.2 does not exist; latest published is 0.10.1ephemeral-rollups-pinocchioversion 0.8.5 does not exist; latest published is 0.8.4pinocchio-logshould be updated to 0.5.1 (latest)
The cpi and copy features remain valid and are not deprecated. Correct the versions to ensure the documentation reflects resolvable dependencies:
[dependencies]
pinocchio = { version = "0.10.1", features = ["cpi", "copy"] }
pinocchio-log = { version = "0.5.1" }
pinocchio-system = { version = "0.5" }
ephemeral-rollups-pinocchio = { version = "0.8.4" }🤖 Prompt for AI Agents
In `@skill/delegation.md` around lines 113 - 120, Update the dependency versions
in the Cargo manifest snippet so they match published releases: change pinocchio
from "0.10.2" to "0.10.1", pinocchio-log from "0.5" to "0.5.1", and
ephemeral-rollups-pinocchio from "0.8.5" to "0.8.4" while leaving pinocchio's
features ["cpi","copy"] and pinocchio-system = "0.5" unchanged; ensure the
updated versions replace the entries for pinocchio, pinocchio-log, and
ephemeral-rollups-pinocchio in the shown Cargo.toml block.
| ### Pinocchio Gotchas | ||
|
|
||
| #### Undelegation Callback Required | ||
| You must implement a `process_undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating. | ||
|
|
||
| #### Copy Semantics for Account References | ||
| `commit_accounts` and `commit_and_undelegate_accounts` take `&[AccountView]` (copied), not references like Anchor's `&AccountInfo`. This requires the `copy` feature on the `pinocchio` crate. | ||
|
|
There was a problem hiding this comment.
Use the same callback name as the example (undelegation_callback).
The gotcha says process_undelegation_callback, but the earlier example defines undelegation_callback. Align the naming to avoid confusion.
✏️ Suggested wording fix
-You must implement a `process_undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating.
+You must implement an `undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ### Pinocchio Gotchas | |
| #### Undelegation Callback Required | |
| You must implement a `process_undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating. | |
| #### Copy Semantics for Account References | |
| `commit_accounts` and `commit_and_undelegate_accounts` take `&[AccountView]` (copied), not references like Anchor's `&AccountInfo`. This requires the `copy` feature on the `pinocchio` crate. | |
| ### Pinocchio Gotchas | |
| #### Undelegation Callback Required | |
| You must implement an `undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating. | |
| #### Copy Semantics for Account References | |
| `commit_accounts` and `commit_and_undelegate_accounts` take `&[AccountView]` (copied), not references like Anchor's `&AccountInfo`. This requires the `copy` feature on the `pinocchio` crate. | |
🤖 Prompt for AI Agents
In `@skill/delegation.md` around lines 241 - 248, The docs currently mention
process_undelegation_callback but the example and callback name used elsewhere
is undelegation_callback; update the text so the callback name is
consistent—either rename the example to process_undelegation_callback or
(preferably) change the doc text to reference undelegation_callback so it
matches the example and any code that calls undelegation_callback; also keep the
adjacent note about calling undelegate() and the copy-semantics note for
commit_accounts / commit_and_undelegate_accounts unchanged.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
skill/delegation.md (1)
241-271: 🧹 Nitpick | 🔵 TrivialAdd blank lines around headings and code fences in Pinocchio sections.
The markdown linter flags missing blank lines around headings (lines 243, 246, 251) and a code fence (line 264). Apply the same formatting consistency as suggested for the Anchor sections.
📝 Suggested formatting fixes
### Pinocchio Gotchas #### Undelegation Callback Required + You must implement a `process_undelegation_callback` handler that calls `undelegate()` — the delegation program invokes this on your program when undelegating. #### Copy Semantics for Account References + `commit_accounts` and `commit_and_undelegate_accounts` take `&[AccountView]` (copied), not references like Anchor's `&AccountInfo`. This requires the `copy` feature on the `pinocchio` crate. ## Common Gotchas ### PDA Seeds Must Match + Seeds in delegate instruction must exactly match account definition. **Anchor:** **Pinocchio:** + ```rust
🤖 Fix all issues with AI agents
In `@skill/delegation.md`:
- Line 150: Add documentation above the optional validator extraction (the line
using rest.first().map to set validator) explaining when callers should include
this extra account and what it does; e.g., state that the validator is optional
and should be provided only when you want an external validator to enforce
checks on the ER (otherwise leave it empty), mention expected signer/ownership
requirements and that absence means no external validation is performed; update
the comment near the validator variable (referencing validator and
rest.first().map(|account| *account.address())) to clearly describe purpose and
usage.
- Around line 97-108: Add blank lines before and after the "Method Name
Convention" heading, the Rust code fence that shows the delegate example (pub
my_account: AccountInfo<'info>, // => ctx.accounts.delegate_my_account()), and
before the "Don't use `Account<>` in delegate context" and "Don't skip the
`#[commit]` macro" headings so the markdown linter stops flagging missing
surrounding blank lines; ensure there is an empty line above and below each
heading and the fenced code block to comply with Markdown conventions.
- Line 152: The seed usage is inconsistent between the Anchor example (using
uid.as_bytes() in the seeds array) and the Pinocchio example (using
payer.address().as_ref()), so update the documentation around the seeds
declaration (the lines referencing seeds, uid, and payer.address()) to either
unify the pattern or add a concise explanatory comment: state that Anchor
examples use a user-specific UID byte slice (uid.as_bytes()) for PDA derivation
while the Pinocchio example demonstrates a payer-address-based seed
(payer.address().as_ref()) for a different use case; reference the symbols
seeds, uid, and payer.address() in the comment so readers understand which
pattern to choose.
| #### Method Name Convention | ||
| The delegate method is auto-generated as `delegate_<field_name>`: | ||
| ```rust | ||
| pub my_account: AccountInfo<'info>, // => ctx.accounts.delegate_my_account() | ||
| ``` | ||
|
|
||
| #### Don't use `Account<>` in delegate context | ||
| Use `AccountInfo` with `del` constraint instead. | ||
|
|
||
| #### Don't skip the `#[commit]` macro | ||
| Required for undelegate context. | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Add blank lines around headings and code fences for markdown compliance.
The markdown linter flags missing blank lines around several headings (lines 97, 103, 106) and a code fence (line 99). While this doesn't affect rendering in most viewers, it's good practice to follow markdown conventions for consistency across the documentation.
📝 Suggested formatting fixes
### Anchor Gotchas
#### Method Name Convention
+
The delegate method is auto-generated as `delegate_<field_name>`:
+
```rust
pub my_account: AccountInfo<'info>, // => ctx.accounts.delegate_my_account()Don't use Account<> in delegate context
Use AccountInfo with del constraint instead.
Don't skip the #[commit] macro
Required for undelegate context.
</details>
<details>
<summary>🧰 Tools</summary>
<details>
<summary>🪛 markdownlint-cli2 (0.20.0)</summary>
[warning] 97-97: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
---
[warning] 99-99: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
---
[warning] 103-103: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
---
[warning] 106-106: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
</details>
</details>
<details>
<summary>🤖 Prompt for AI Agents</summary>
In @skill/delegation.md around lines 97 - 108, Add blank lines before and after
the "Method Name Convention" heading, the Rust code fence that shows the
delegate example (pub my_account: AccountInfo<'info>, // =>
ctx.accounts.delegate_my_account()), and before the "Don't use Account<> in
delegate context" and "Don't skip the #[commit] macro" headings so the
markdown linter stops flagging missing surrounding blank lines; ensure there is
an empty line above and below each heading and the fenced code block to comply
with Markdown conventions.
</details>
<!-- fingerprinting:phantom:triton:puma -->
<!-- This is an auto-generated comment by CodeRabbit -->
| else { | ||
| return Err(ProgramError::NotEnoughAccountKeys); | ||
| }; | ||
| let validator = rest.first().map(|account| *account.address()); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Document when the optional validator account should be provided.
The code extracts an optional validator from remaining accounts but doesn't explain when this should be included or what it's used for. Users following this example may not know whether to pass this account or leave it empty.
📖 Suggested documentation addition
Add a comment above line 150:
} else {
return Err(ProgramError::NotEnoughAccountKeys);
};
+ // Optional: provide a validator account to enforce validation on the ER
let validator = rest.first().map(|account| *account.address());🤖 Prompt for AI Agents
In `@skill/delegation.md` at line 150, Add documentation above the optional
validator extraction (the line using rest.first().map to set validator)
explaining when callers should include this extra account and what it does;
e.g., state that the validator is optional and should be provided only when you
want an external validator to enforce checks on the ER (otherwise leave it
empty), mention expected signer/ownership requirements and that absence means no
external validation is performed; update the comment near the validator variable
(referencing validator and rest.first().map(|account| *account.address())) to
clearly describe purpose and usage.
| }; | ||
| let validator = rest.first().map(|account| *account.address()); | ||
|
|
||
| let seeds: &[&[u8]] = &[b"seed", payer.address().as_ref()]; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Seeds differ between Anchor and Pinocchio examples - clarify the pattern.
The Anchor example uses &[b"seed", uid.as_bytes()] while the Pinocchio example uses &[b"seed", payer.address().as_ref()]. This inconsistency may confuse users about which seed pattern to follow. If this is intentional (different use cases), consider adding a comment explaining why the seed patterns differ.
💡 Suggested clarification
+ // Seeds for PDA derivation (adjust based on your program's needs)
+ // Example: using payer address as seed component
let seeds: &[&[u8]] = &[b"seed", payer.address().as_ref()];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let seeds: &[&[u8]] = &[b"seed", payer.address().as_ref()]; | |
| // Seeds for PDA derivation (adjust based on your program's needs) | |
| // Example: using payer address as seed component | |
| let seeds: &[&[u8]] = &[b"seed", payer.address().as_ref()]; |
🤖 Prompt for AI Agents
In `@skill/delegation.md` at line 152, The seed usage is inconsistent between the
Anchor example (using uid.as_bytes() in the seeds array) and the Pinocchio
example (using payer.address().as_ref()), so update the documentation around the
seeds declaration (the lines referencing seeds, uid, and payer.address()) to
either unify the pattern or add a concise explanatory comment: state that Anchor
examples use a user-specific UID byte slice (uid.as_bytes()) for PDA derivation
while the Pinocchio example demonstrates a payer-address-based seed
(payer.address().as_ref()) for a different use case; reference the symbols
seeds, uid, and payer.address() in the comment so readers understand which
pattern to choose.
Used the pinnochio-counter and e-ata repositories as inspiration to create the skill for
pinocchioframework.Summary by CodeRabbit