Skip to content

feat(tokens): add native flavor for tokens/nft-operations (Fixes #754) - #769

Closed
sehaha wants to merge 1 commit into
solana-foundation:mainfrom
sehaha:feat/nft-ops-native
Closed

sehaha wants to merge 1 commit into
solana-foundation:mainfrom
sehaha:feat/nft-ops-native

Conversation

@sehaha

@sehaha sehaha commented Oct 28, 2026

Copy link
Copy Markdown

Linked issue

Fixes #754

What and why

tokens/nft-operations previously shipped only anchor/ and pinocchio/. This PR delivers tokens/nft-operations/native/ to complete the trio for NFT examples, matching the pattern established across tokens/create-token, tokens/transfer-tokens, and tokens/pda-mint-authority.

Approach

  • Zero mpl crate dependency: Hand-builds the wire format for Metaplex Token Metadata instructions (CreateMetadataAccountV3, CreateMasterEditionV3, and Verify with VerificationArgs::CollectionV1) in mpl_util.rs, adhering strictly to AGENTS.md.
  • Instruction set: Dispatches on a single-byte discriminator:
    • 0 -> CreateCollection: Creates 0-decimal mint, user ATA, mints 1 token, creates sized collection metadata and master edition signed by the [b"authority"] PDA.
    • 1 -> MintNft: Creates 0-decimal mint, user ATA, mints 1 token, creates metadata referencing collection mint, and master edition.
    • 2 -> VerifyCollection: Verifies the NFT against the collection mint via Metaplex CPI signed by the program authority PDA.
  • On-chain authority validation: Dynamically derives the canonical [b"authority"], asserts account matches, and signs CPIs with seeds.
  • Workspace membership: Adds tokens/nft-operations/native/program to root Cargo.toml.

Testing

  • cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures: compiled clean SBF binary (nft_operations_native_program.so).
  • pnpm run build-and-test (Mocha + tsx + LiteSVM 1.x):
    NFT Operations (Native)
      ✔ Creates a collection NFT
      ✔ Mints an NFT into the collection
      ✔ Verifies the NFT as part of the collection
    
    3 passing (21ms)
    
  • cargo fmt --check: clean.
  • cargo clippy -- -D warnings: zero warnings.

AI disclosure

  • No AI tooling was used beyond editor autocomplete.
  • AI tooling was used. Tool and extent: Antigravity IDE and Claude 3.5 Sonnet assisted in drafting the hand-rolled Metaplex wire serialization; I architected the instruction layout, account validations, and verified tests against LiteSVM.

…na-foundation#754)

- Implements tokens/nft-operations/native/ to complete the anchor/native/pinocchio trio

- Uses native Solana SBF entrypoint with hand-built Metaplex Token Metadata CPIs in mpl_util.rs (no external mpl crate dependency)

- Supports CreateCollection, MintNft, and VerifyCollection instructions matching the Anchor and Pinocchio interfaces

- Validates canonical mint authority PDA derivation on-chain

- Adds LiteSVM unit tests with @solana/kit and litesvm 1.x
@sehaha
sehaha requested a review from dev-jodee as a code owner October 28, 2026 04:39
@github-actions github-actions Bot added the needs-issue PR does not reference an issue a maintainer has accepted label Oct 28, 2026
@github-actions

Copy link
Copy Markdown

Hi @sehaha,

Thanks for the pull request. We ask that every change references an issue a maintainer has accepted, and there isn't one linked here.

These examples are a teaching resource and each one has to stay small enough to read in one sitting, so whether a new example or framework flavor belongs here is worth settling before anyone writes it. Agreeing on the approach in an issue first means nobody writes code that can't be merged. See CONTRIBUTING.md for the full workflow.

Please open an issue describing the change, or comment on the existing one. Once a maintainer has labelled it accepted, put Fixes #<issue> in this description and reopen this pull request; the check runs again and clears itself. Typos, broken links and comment-only fixes are exempt: write Linked issue: trivial instead.

@github-actions github-actions Bot closed this Oct 28, 2026
@greptile-apps

greptile-apps Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] The changes are centered on a new native NFT example and its local setup.

Fix the shared lockfile and the broken deployment filename before merging.

Findings

  1. P1 Lockfile adds undeclared dependencies ▶
  2. P1 Deploy script names wrong file ▶
  3. P2 Install changes the saved cluster ▶
  4. P2 Test misses skipped verification ▶

Summary

Adds a native NFT example alongside the Anchor and Pinocchio versions.

  • The native program creates a zero-decimal collection NFT.
  • Users can mint a one-token NFT linked to a collection.
  • The native program can verify an NFT's collection membership.
  • Developers can build and run the native NFT example.

Reviews (1) · Last reviewed commit: "feat(tokens): add native flavor for toke..." · Reviewed by Greptile

Comment thread Cargo.lock
Comment on lines +10 to +14
"litesvm",
"solana-keypair",
"solana-message",
"solana-signer",
"solana-transaction",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Lockfile adds undeclared dependencies

Cargo.lock adds test dependencies to existing Anchor packages whose manifests do not declare them. For example, account-data-anchor-program declares only anchor-lang, but its lock entry now includes litesvm and four Solana packages. Builds that require an unchanged lockfile cannot use it as committed. Regenerate the lockfile from the committed manifests.

# Run this bad boy with "bash cicd.sh" or "./cicd.sh"

cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so
solana program deploy ./program/target/so/program.so

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Deploy script names wrong file

cicd.sh deploys program.so, but this crate builds nft_operations_native_program.so. On a clean checkout, the build can succeed and deployment will still fail because the requested file does not exist. Use the same filename as the deploy script in package.json.

Suggested change
solana program deploy ./program/target/so/program.so
solana program deploy ./program/target/so/nft_operations_native_program.so

Comment on lines +24 to +25
// Point the Solana CLI at mainnet, where the canonical program lives.
execSync('solana config set -um', { stdio: 'inherit' });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Install changes the saved cluster

prepare.mjs changes the user's saved Solana cluster to mainnet during package installation and never restores it. A developer using localhost or devnet will run later CLI commands against mainnet instead. Pass --url mainnet-beta to solana program dump rather than changing the saved configuration.

Comment on lines +216 to +218
const metadataAccount = svm.getAccount(metadata);
if (!metadataAccount?.exists) throw new Error('NFT metadata not found');
assert.equal(metadataAccount.programAddress, TOKEN_METADATA_PROGRAM_ID);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test misses skipped verification

The verification test only checks that the metadata account still belongs to Metaplex. That was already true before verification, so the test also passes if verify_collection returns success without doing anything. Decode the metadata and assert that collection.verified changes to true. Also check that the sized collection's count increases.

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

Labels

needs-issue PR does not reference an issue a maintainer has accepted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tokens/nft-operations: add the native (Solana Native) flavor to complete the anchor/native/pinocchio trio

1 participant