Skip to content

Add Token-2022 memo-transfer Pinocchio example - #792

Open
MarkFeder wants to merge 5 commits into
solana-foundation:mainfrom
MarkFeder:tokens-token-2022-memo-transfer-pinocchio
Open

MarkFeder wants to merge 5 commits into
solana-foundation:mainfrom
MarkFeder:tokens-token-2022-memo-transfer-pinocchio

Conversation

@MarkFeder

@MarkFeder MarkFeder commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Linked issue

Fixes #785

Replaces #700, which the PR-hygiene bot closed before the issue was accepted; GitHub doesn't let the author reopen it.

What and why

Adds a Pinocchio version of tokens/token-2022/memo-transfer, which only had an Anchor one. It follows the same kit + LiteSVM + @solana-program template as the merged Token-2022 Pinocchio examples and builds on the account-extension shape from immutable-owner (#696).

The single instruction creates a Token-2022 token account with the MemoTransfer extension enabled, so every transfer into it must be preceded by a memo. The program hand-builds three CPIs:

  1. CreateAccount, with space for the extension.
  2. InitializeAccount3 (variant 18): [18] + owner(32).
  3. EnableRequiredMemoTransfers: MemoTransferExtension (30), sub-instruction Enable (0) → [30, 0].

Unlike ImmutableOwner, this extension is enabled after the account is initialized, and the enable must be signed by the account owner (the payer here). The account is 171 bytes: 165 base + 1 account-type byte + a 5-byte MemoTransfer TLV.

The JS dependencies match the versions #765 set for the other non-anchor examples.

Testing

pnpm install --frozen-lockfile, tsc --noEmit, pnpm build, pnpm build-and-test and pnpm audit in a Linux container, plus cargo fmt --check, cargo clippy -D warnings and prettier --check:

Token-2022 Memo Transfer (Pinocchio)
  ✔ Creates a Token-2022 token account with required memo transfers enabled
  ✔ Requires a memo on incoming transfers
2 passing
No known vulnerabilities found

The first test decodes the account with the official Token-2022 codec and checks the program owner, size, mint, token owner and requireIncomingTransferMemos. The second checks that a transfer without a memo is rejected and the same transfer with a memo moves the balance.

bash cicd.sh and pnpm run deploy both name token_2022_memo_transfer_pinocchio_program.so, the file cargo build-sbf writes; checked in Linux with a real build (same check as #794). The name is explicit rather than a *.so glob because pnpm runs scripts through cmd.exe on Windows, which doesn't expand globs.

AI disclosure

Check exactly one. See CONTRIBUTING.md.

  • No AI tooling was used beyond editor autocomplete.
  • AI tooling was used. Tool and extent: Claude Code helped write the program, the tests and this description; I reviewed the changes and the build and test results.

MarkFeder and others added 3 commits November 4, 2026 19:19
Ports the memo-transfer Token-2022 example to Pinocchio (the anchor example
has no native sibling), matching the token-2022 pinocchio account-extension
template (kit + litesvm, official @solana-program packages, real Rent::get()).

The program hand-rolls three Token-2022 CPIs to create a token account with
the MemoTransfer extension enabled: it creates the account, runs
InitializeAccount3, then (unlike ImmutableOwner, which is pre-init) enables
required memo transfers via EnableRequiredMemoTransfers after initialization,
which the account owner signs. The owner is the payer. Account size is 171
bytes (a 1-byte MemoTransfer TLV value). The litesvm test decodes the account
with the official Token-2022 codec and asserts the requirement is enabled.
Adds a behavior test alongside the extension-state assertion: it funds a
source account, then verifies a TransferChecked into the memo-required
account is rejected without a preceding memo and succeeds when preceded by
one (SPL Memo program, bundled by LiteSVM). Addresses review feedback that
the example's advertised transfer behavior was untested.
Matches the versions solana-foundation#765 set for the other non-anchor examples (kit 8.5, mocha 12, typescript 7) and adds the same pnpm-workspace.yaml overrides, which clears pnpm-audit. The signer roles in the hand-built instruction take 'as const' so kit 8 keeps them as signer roles, as the sibling tests on main do.
@greptile-apps

greptile-apps Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues remain from this review.

Summary

Adds a Pinocchio example that creates a Token-2022 account with MemoTransfer enabled.

  • Pinocchio can create Token-2022 accounts that require memos for incoming transfers.

Reviews (3) · Last reviewed commit: "token-2022 memo-transfer pinocchio: depl..." · Reviewed by Greptile

cargo build-sbf names the artifact after the crate, so deploy the *.so in the output dir instead of program.so, and stop cicd.sh if the build fails. pinocchio-token-2022 now exists in the workspace, so the comment says the instructions are hand-built to show their layout rather than claiming there is no crate.
pnpm runs package.json scripts through cmd.exe on Windows, which does not expand the *.so glob. Name the file cargo build-sbf writes instead, matching solana-foundation#794.
@MarkFeder

Copy link
Copy Markdown
Contributor Author

@dev-jodee #792 and #793 only fail build-and-test-group-7, on transfer-hook/block-list/pinocchio (Command "tsc" not found), which fails the same way on main. Its package.json is missing typescript; adding "typescript": "^7.0.2" to devDependencies (+ lockfile) fixes it, verified locally. I can't open a PR for it under the 3-PR limit. #794 is green, and all three link accepted issues with review comments addressed.

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.

token-2022/memo-transfer: add a Pinocchio version

1 participant