Skip to main content
The NFT Program manages NFT mint accounts and individual NFT accounts on Thru. From a developer perspective, the current public view of the program is driven mainly by the flattened NFT ABI and the runtime tests that exercise minting, transfers, burns, metadata updates, and authority changes.

Use This When

  • you need an on-chain mint plus per-NFT account model
  • you need to reason about NFT ownership, mint authority, or metadata updates
  • you are working from the ABI and runtime behavior rather than a first-class public SDK

Quickstart

Fetch the ABI, generate TypeScript builders, then build instruction bytes and send the transaction.
thru-cli abi account get --include-data --out ./nft-program.abi.yaml <ABI_ACCOUNT_ADDRESS>

thru-cli abi codegen \
  --files ./nft-program.abi.yaml \
  --language typescript \
  --output ./generated
import { decodeAddress } from "@thru/helpers";
import {
  NftInstruction,
  NftTransferArgs,
} from "./generated/thru/program/nft_token/types";

const instructionData = NftInstruction.builder()
  .payload()
  .select("transfer")
  .writePayload(
    NftTransferArgs.builder()
      .set_nft_account_idx(2)
      .set_dest_account_idx(3)
      .set_mint_account_idx(4)
  )
  .finish()
  .build();

const tx = await thru.transactions.build({
  feePayer: { publicKey: decodeAddress(feePayerAddress) },
  program: nftProgramAddress,
  accounts: {
    readWrite: [nftAccountAddress, destinationOwnerAddress, mintAccountAddress],
    readOnly: [],
  },
  instructionData,
});

const signedWire = await signTransaction(tx.toWireForSigning());
const signature = await thru.transactions.send(signedWire);

How It Works

The program separates collection-level mint state from per-NFT state:
  • the mint account stores the mint authority, total supply, and the next sequential NFT id
  • each NFT account stores its mint, current owner, id, and metadata blob
Typical flows look like this:
  1. initialize the NFT mint with a state proof for the new mint account
  2. mint an NFT, which creates a new NFT account tied to that mint and the next id
  3. transfer, burn, or update metadata on the per-NFT account
  4. update the mint authority if ownership of the mint itself changes

Account Model

AccountWhat it storesNotes
NftMintAccountmint_authority, supply, next_idTracks collection-level state and the next id to mint.
NftAccountmint, owner, id, metadataRepresents one NFT instance under a mint.
NftMetadataflags, external_metadata_uriThe flattened ABI reserves 256 bytes for the external metadata URI.
NftProgramAccountSize-discriminated envelope over mint and NFT accountsThe ABI distinguishes mint_account and nft_account by expected size.

Events

The current flattened NFT ABI does not define an event envelope. That means agents should not assume a stable NFT event stream exists in the same way it does for the Token Program or Passkey Manager Program. For current integration work, the safer sources of truth are account state and transaction-level inspection.

Instructions

InstructionUse it whenNotes
initialize_mintCreate a new NFT mintIncludes the mint seed and a state proof for the new mint account.
mint_toMint a new NFT account under the mintThe mint account controls supply and the next sequential NFT id.
transferTransfer ownership of an NFT accountChanges the owner field on the NFT account.
burnBurn an NFTRemoves the NFT from circulation and updates mint state.
update_metadataChange the NFT metadata payloadUse when the external metadata URI or flags need to change.
set_authorityChange the mint authorityUse when control over future minting should move to another authority.

What Is Not Covered Here

This page is grounded in the published flattened ABI and the runtime tests, not in a dedicated public SDK package. If you need deeper binary-layout rules, open Specification or the related ABI pages next.
  • Public explorer page: not currently documented in these docs