add pinocchio token-2022 mint-close-authority example#624
Conversation
Greptile SummaryThis PR adds a Pinocchio port of the
Confidence Score: 5/5Safe to merge; all three hand-rolled Token-2022 CPIs are correctly encoded and the test validates mint ownership, size, extension type, and the stored close authority using the official codec. The instruction data layouts (34-byte InitializeMintCloseAuthority, 67-byte InitializeMint) are consistent with Token-2022's unpack_pubkey_option (1-byte COption tag + 32-byte key). MINT_SIZE=202 matches ExtensionType::try_calculate_account_len. The test now uses a distinct closeAuthority keypair, making the stored-authority assertion genuinely meaningful. No functional gaps were found. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as Test Client
participant Program as Pinocchio Program
participant SysProg as System Program
participant T22 as Token-2022 Program
Client->>Program: CreateMint (decimals, 7 accounts)
activate Program
Program->>Program: Rent::get() → compute lamports for 202 bytes
Program->>SysProg: "CreateAccount(payer→mint, 202 bytes, owner=Token-2022)"
SysProg-->>Program: ✓ mint account created
Program->>T22: "InitializeMintCloseAuthority(variant=25) [1-byte tag + 32-byte close authority]"
T22-->>Program: ✓ MintCloseAuthority TLV written
Program->>T22: "InitializeMint(variant=0) [decimals + mint_authority + freeze_authority]"
T22-->>Program: ✓ base mint initialized
Program-->>Client: Ok(())
deactivate Program
Client->>Client: getMintDecoder().decode(mintData) assert decimals, MintCloseAuthority extension, close authority address
Reviews (10): Last reviewed commit: "token-2022 mint-close-authority pinocchi..." | Re-trigger Greptile |
|
Hi @Perelyn-sama — thanks again for merging my previous pinocchio examples! This one adds the |
6a49f60 to
b40292f
Compare
|
@Perelyn-sama @dev-jodee — rebased onto latest main (picks up the ASM sbpf/Solana pin from #625), CI is now fully green. Ready for review whenever you have a chance 🙏 |
3f941a9 to
87b819a
Compare
dev-jodee
left a comment
There was a problem hiding this comment.
need signed commits please
Use a distinct close-authority keypair so the stored-authority check verifies sourcing from account index 2, and assert the TLV length field (32) explicitly.
… run
Move the async bankrun setup out of the `describe` callback and into a
`before` hook so Mocha collects the `it` block (an async `describe` body
registers tests after the suite is already collected, so nothing ran).
With the test now executing, replace `Rent::try_minimum_balance` with the
integer rent formula: its floating-point exemption-threshold path emits an
opcode the bankrun VM rejects ("unsupported BPF instruction"). Matches the
create-token example.
Build the transaction with @solana/kit (addresses, instruction, message, signing) instead of @solana/web3.js. A thin web3.js shim remains only where solana-bankrun@0.3.1's BanksClient still requires it (start()/getAccount() PublicKey, processTransaction() VersionedTransaction). Bump tsconfig target/lib to es2020 for kit's BigInt usage.
Move the test runtime from solana-bankrun to litesvm, which is kit-native, so web3.js is dropped entirely. The kit transaction returned by signTransactionMessageWithSigners is handed straight to LiteSVM.sendTransaction (no VersionedTransaction shim), and getAccount/airdrop take kit Addresses. - deps: drop @solana/web3.js + solana-bankrun, add litesvm; pin @solana/kit to ^6.10.0 (litesvm's kit major) so there is a single kit in the tree - tsconfig: bump typescript to ^5 and lib to es2022+dom (kit's types), add @types/node; the suite is now type-clean under tsc --noEmit - LiteSVM()'s standard runtime bundles Token-2022, so no fixture load is needed beyond the program .so
cd5cf69 to
3a8f9e7
Compare
dev-jodee
left a comment
There was a problem hiding this comment.
couple more things :) we're getting close ! (also apply them to all the other prs too when it makes sense)
…al Rent Address @dev-jodee review feedback on solana-foundation#624: - program: now that tests run on litesvm (not bankrun), compute rent with Rent::get()?.try_minimum_balance() instead of the integer-math workaround that avoided the f64 opcode the old bankrun VM rejected. - test: source program ids and the rent sysvar from the official packages (@solana-program/token-2022, @solana-program/system, @solana/sysvars) and decode the mint + its MintCloseAuthority extension with getMintDecoder() instead of hand-rolled address constants and raw byte offsets. - tsconfig: switch to moduleResolution 'bundler' so the packages' subpath exports type-check.
Mirror the solana-foundation#624 review refinements here: - program: compute rent with Rent::get()?.try_minimum_balance() now that the tests run on litesvm instead of bankrun. - test: source the program ids and rent sysvar from the official packages (@solana-program/token-2022, @solana-program/system, @solana/sysvars) and decode the mint + its NonTransferable extension with getMintDecoder() instead of hand-rolled address constants and raw byte offsets. - tsconfig: moduleResolution 'bundler' so the packages' subpath exports type-check.
|
thanks for the work @MarkFeder, can you do the pr to fix the previous one we already merged with the feedback from this one please :) |
* add pinocchio token-2022 non-transferable example
* token-2022 non-transferable pinocchio: make bankrun test actually run
Move the async bankrun setup out of the `describe` callback and into a
`before` hook so Mocha collects the `it` block (an async `describe` body
registers tests after the suite is already collected, so nothing ran).
With the test now executing, replace `Rent::try_minimum_balance` with the
integer rent formula: its floating-point exemption-threshold path emits an
opcode the bankrun VM rejects ("unsupported BPF instruction"). Matches the
create-token example (#599).
* token-2022 non-transferable pinocchio: migrate test to kit + litesvm
Apply the kit + litesvm template from the mint-close-authority example:
build and sign the transaction with @solana/kit and run it on litesvm,
dropping @solana/web3.js and solana-bankrun entirely.
- deps: drop @solana/web3.js + solana-bankrun, add litesvm; pin @solana/kit
to ^6.10.0 (litesvm's kit major) so there is a single kit in the tree
- tsconfig: bump typescript to ^5 and lib to es2022+dom (kit's types), add
@types/node; the suite is type-clean under tsc --noEmit
- LiteSVM's standard runtime bundles Token-2022, so no fixture load is needed
beyond the program .so
* token-2022 non-transferable pinocchio: use official packages + real Rent
Mirror the #624 review refinements here:
- program: compute rent with Rent::get()?.try_minimum_balance() now that the
tests run on litesvm instead of bankrun.
- test: source the program ids and rent sysvar from the official packages
(@solana-program/token-2022, @solana-program/system, @solana/sysvars) and
decode the mint + its NonTransferable extension with getMintDecoder()
instead of hand-rolled address constants and raw byte offsets.
- tsconfig: moduleResolution 'bundler' so the packages' subpath exports
type-check.
---------
Co-authored-by: MarkFeder <5670736+MarkFeder@users.noreply.github.com>
|
Thanks for merging @dev-jodee! 🙏 Opened the follow-up you asked for — #641 brings the already-merged create-token example up to this same |
Applies dev-jodee's solana-foundation#624 review refinements on top of the kit + litesvm test: - program: compute rent with Rent::get()?.try_minimum_balance(MINT_SIZE)? instead of the integer-math workaround (only needed to dodge the f64 opcode the old bankrun VM rejected; litesvm runs the real syscall). - test: source the token, associated-token and system program ids from the official @solana-program/token and @solana-program/system packages, and read the minted amount with getTokenDecoder().decode(...).amount instead of a raw byte offset. Token Metadata has no official @solana-program client, so its id stays hand-rolled. - tsconfig: moduleResolution bundler for the packages' subpath exports. Verified locally: cargo build-sbf + ts-mocha -> 2 passing, tsc --noEmit and biome clean, frozen-lockfile OK.
Applies dev-jodee's solana-foundation#624 review refinements on top of the kit + litesvm test: - program: compute rent with Rent::get()?.try_minimum_balance(MINT_SIZE)? instead of the integer-math workaround (only needed to dodge the f64 opcode the old bankrun VM rejected; litesvm runs the real syscall). - test: source the token, associated-token and system program ids from the official @solana-program/token and @solana-program/system packages, and read the minted amount with getTokenDecoder().decode(...).amount instead of a raw byte offset. Token Metadata has no official @solana-program client, so its id stays hand-rolled. - tsconfig: moduleResolution bundler for the packages' subpath exports. Verified locally: cargo build-sbf + ts-mocha -> 2 passing, tsc --noEmit and biome clean, frozen-lockfile OK.
Applies dev-jodee's solana-foundation#624 review refinements on top of the kit + litesvm test: - program: compute rent with Rent::get()?.try_minimum_balance(..)? in both the Init (PDA account) and Create (mint) instructions, instead of the integer-math workaround (only needed to dodge the f64 opcode the old bankrun VM rejected; litesvm runs the real syscall). - test: source the token, associated-token and system program ids from the official @solana-program/token and @solana-program/system packages, and read the minted amount with getTokenDecoder().decode(...).amount instead of a raw byte offset. Token Metadata has no official @solana-program client, so its id stays hand-rolled. - tsconfig: moduleResolution bundler for the packages' subpath exports. Verified locally: cargo build-sbf + ts-mocha -> 3 passing, tsc --noEmit and biome clean, frozen-lockfile OK.
…ackages + real Rent (#641) Applies the kit + litesvm + official-package treatment from the token-2022 mint-close-authority example (#624) to the already-merged create-token example: - program: compute rent with Rent::get()?.try_minimum_balance(Mint::LEN)? instead of the integer-math workaround (that was only needed to dodge the f64 opcode the old bankrun VM rejected; litesvm runs the real syscall). - test: drop @solana/web3.js + solana-bankrun; build and sign transactions with @solana/kit and run them on litesvm. Program ids come from the official @solana-program/token and @solana-program/system packages, and the metadata PDA is derived with getProgramDerivedAddress. Token Metadata has no official @solana-program client, so its id stays hand-rolled. - tsconfig: es2022 + dom, moduleResolution bundler for the packages' subpath exports; pin @solana-program/*@^0.12/^0.14 + @solana/kit@^6.10 to stay on the single kit that litesvm@1.3 requires. Verified locally: cargo build-sbf + ts-mocha -> 2 passing, tsc --noEmit and biome clean, frozen-lockfile OK. Co-authored-by: MarkFeder <5670736+MarkFeder@users.noreply.github.com>
Applies dev-jodee's solana-foundation#624 review refinements on top of the kit + litesvm test: - program: compute rent with Rent::get()?.try_minimum_balance(MINT_SIZE)? in both the create-collection and mint-nft instructions, instead of the integer-math workaround (only needed to dodge the f64 opcode the old bankrun VM rejected; litesvm runs the real syscall). - test: source the token, associated-token and system program ids and the instructions sysvar from the official @solana-program/token, @solana-program/system and @solana/sysvars packages, and read the minted amount with getTokenDecoder().decode(...).amount instead of a raw byte offset. Token Metadata has no official @solana-program client, so its id stays hand-rolled. - tsconfig: moduleResolution bundler for the packages' subpath exports. Verified locally: cargo build-sbf + ts-mocha -> 3 passing, tsc --noEmit and biome clean, frozen-lockfile OK.
Adds a Pinocchio port of the
tokens/token-2022/mint-close-authorityexample, alongside the existinganchorandnativeversions.What it does
A single instruction creates an SPL Token-2022 mint carrying the
MintCloseAuthorityextension, so a designated authority can later close the mint and reclaim its rent.Notes
Token-2022 has no Pinocchio wrapper crate (
pinocchio-tokentargets the legacy SPL Token program), so the Token-2022 instructions are built by hand and CPI'd:CreateAccountfor the mint, sized to202bytes (baseAccountlength 165 + account-type byte + oneMintCloseAuthorityTLV entry) and owned by the Token-2022 program.InitializeMintCloseAuthority(variant25) — must run before the mint is initialized.InitializeMint(variant0).The bankrun test asserts the resulting mint is owned by Token-2022, is exactly 202 bytes, has the correct decimals, and that the extension header (account type
Mint, TLV typeMintCloseAuthority) and stored close authority were written correctly.