Skip to content

Add Token-2022 cpi-guard Pinocchio example - #701

Open
MarkFeder wants to merge 1 commit into
solana-foundation:mainfrom
MarkFeder:tokens-token-2022-cpi-guard-pinocchio
Open

Add Token-2022 cpi-guard Pinocchio example#701
MarkFeder wants to merge 1 commit into
solana-foundation:mainfrom
MarkFeder:tokens-token-2022-cpi-guard-pinocchio

Conversation

@MarkFeder

Copy link
Copy Markdown
Contributor

What

Adds a Pinocchio implementation of the Token-2022 cpi-guard example. The example previously had only an anchor version (no native), so this is a fresh port, following the same kit + litesvm template as the other Token-2022 pinocchio examples.

How it works — and why it's different

The CpiGuard extension prevents privileged token operations (transfer, burn, approve, close) from being performed through a CPI when they're authorized by the account owner — a protection against malicious programs redirecting funds.

Crucially, CpiGuard cannot be enabled or disabled through a CPI (Token-2022 requires those to be transaction-level). So — unlike every other extension example — the program cannot initialize this extension. Instead:

  • The program exposes a single cpi_transfer instruction that performs a Token-2022 TransferChecked CPI (variant 12) from a source account to a destination, signed by the source's owner. It reads the mint's decimals directly from the mint account data (offset 44) so the checked transfer matches the mint.
  • The example demonstrates the guard's effect: enabling/disabling CpiGuard happens client-side in the test.

Test

litesvm + @solana/kit. The test:

  1. Creates a mint and a source account with CpiGuard enabled (client-side, via getEnableCpiGuardInstruction), funded with tokens, plus a plain destination account.
  2. Invokes the program's cpi_transfer while the guard is enabled → asserts it is rejected (FailedTransactionMetadata).
  3. Disables CpiGuard, then invokes cpi_transfer again → asserts it succeeds, and that the destination balance is 1.
Token-2022 CPI Guard (Pinocchio)
  ✔ Blocks a CPI transfer while CpiGuard is enabled and allows it once disabled
1 passing

The success-after-disable (with the balance moving) proves the guard is the cause of the rejection, not a mechanical transfer error.

Verified locally: cargo build-sbf, the litesvm test, tsc --noEmit, Prettier, cargo fmt --check, Clippy, and pnpm install --frozen-lockfile all clean.

Ports the cpi-guard Token-2022 example to Pinocchio (the anchor example has
no native sibling). Unlike the other extension examples, CpiGuard cannot be
enabled or disabled through a CPI, so the program cannot initialize it;
instead the program exposes a cpi_transfer instruction (a Token-2022
TransferChecked CPI, reading the mint's decimals from account data) and the
example demonstrates the guard's effect.

The litesvm test creates a source account with CpiGuard enabled (client-side)
and funded, then shows the program's CPI transfer is rejected while the guard
is on and succeeds once it is disabled, asserting the destination balance.
Matches the kit + litesvm template of the other token-2022 pinocchio examples.
@MarkFeder
MarkFeder requested a review from dev-jodee as a code owner August 26, 2026 20:44
@greptile-apps

greptile-apps Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a Pinocchio implementation and LiteSVM test for demonstrating Token-2022 CPI Guard behavior.

  • Adds a hand-built TransferChecked CPI that reads the mint’s decimals.
  • Tests rejection while CPI Guard is enabled and successful transfer after it is disabled.
  • Adds workspace, package, lockfile, build, and deployment configuration.

Confidence Score: 4/5

The program and test behavior appear sound, but the broken artifact paths in both deployment commands should be corrected before merging.

The build emits token_2022_cpi_guard_pinocchio_program.so, while both newly added deployment paths attempt to deploy program.so, causing the documented deployment workflow to fail.

Files Needing Attention: tokens/token-2022/cpi-guard/pinocchio/cicd.sh; tokens/token-2022/cpi-guard/pinocchio/package.json

Important Files Changed

Filename Overview
tokens/token-2022/cpi-guard/pinocchio/program/src/instructions/cpi_transfer.rs Builds the Token-2022 TransferChecked instruction and forwards the expected source, mint, destination, and authority accounts.
tokens/token-2022/cpi-guard/pinocchio/tests/test.ts Exercises both guarded rejection and unguarded success, including verification of the destination balance.
tokens/token-2022/cpi-guard/pinocchio/cicd.sh Builds the program but deploys a nonexistent generic program.so artifact.
tokens/token-2022/cpi-guard/pinocchio/package.json Defines the test and build workflow, but its deployment script repeats the incorrect artifact filename.
tokens/token-2022/cpi-guard/pinocchio/program/src/processor.rs Dispatches the example’s sole data-free instruction directly to the CPI transfer handler.

Reviews (1): Last reviewed commit: "token-2022 cpi-guard: add pinocchio exam..." | Re-trigger Greptile

Comment thread tokens/token-2022/cpi-guard/pinocchio/cicd.sh
@MarkFeder

Copy link
Copy Markdown
Contributor Author

@amilz could you take a look at this one when you get a chance?

No open review threads left on it, so it is ready for maintainer review. It is one of 23 open Pinocchio ports I have up — they are independent and self-contained, so they can be reviewed and merged in any order: https://github.com/solana-developers/program-examples/pulls/MarkFeder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant