NTS-1
The Numbered Token Standard.
A layout for fungible tokens that are also numbered members of a capped collection. Built on Solana's Token-2022 and adding nothing to it: no new program is needed to read an NTS-1 token. Any explorer that understands Token-2022's group and metadata extensions reads “member 42 of 1000” straight from the mint.
What it fuses
Mint layout
| Mint | Extensions | Meaning |
|---|---|---|
| Member (a numbered coin) | MetadataPointer + TokenMetadata; GroupMemberPointer + TokenGroupMember | Identity in the metadata, the name carries the number (“Prefix #042”). Membership and member_number from Token-2022, assigned in initialize_member, never changed. |
| Collection (a capped group) | GroupPointer + TokenGroup; MetadataPointer + TokenMetadata; optionally TokenGroupMember of a parent | max_size is the cap, size the count. The collection's identity and policy live in its metadata. A collection may itself be numbered in a parent (depth 2). |
| Authority | mint_authority and every update_authority | A program-derived address of the issuing program. Never a wallet. A number cannot be forged because only the group's authority can add a member. |
Metadata contract
Keys in additional_metadata, values are strings. Every mint declares standard = nts-1.
| Member key | Value | Written |
|---|---|---|
| number | decimal copy of member_number | at creation |
| max | decimal copy of the collection's max_size | at creation |
| seed | sha256(group ‖ number ‖ slot ‖ prompt), 64 hex | at creation |
| traits | compact layer indices, e.g. b3;e7;m1;a0;f2 | at creation |
| special | first, repdigit, palindrome, round (optional) | at creation |
| prompt | the minter's words, if the collection allows them (optional) | at creation |
| creator, claimed_at | wallet and time (optional until claim) | at claim |
| nickname | 1 to 24 chars, once (optional) | at claim or later |
| Collection key | Value |
|---|---|
| kind | root or launchpad |
| max, number, creator, theme | cap copy, own number in the parent, owner at creation, base theme |
| style | optional encoded style: family, palette, vocabulary |
| naming | fixed or nickname: may members receive a nickname |
| prompt | 0 or 1: may minters pass a prompt into the seed |
| description, url | optional, set only before the first member exists |
Rules
- 01The number comes from Token-2022's member_number, never from a counter in the issuing program.
- 02The cap is max_size; the token program refuses the max_size + 1th member.
- 03Identity is on-chain and immutable after creation: seed, traits, number, max, prompt.
- 04The image is a rendering of the seed and traits. The uri is deterministic and anyone can regenerate it from the chain. It is never a source of truth.
- 05A collection's policy (naming, prompt, description, url) is frozen once its first member exists.
- 06A member may carry a bonding curve, as every cryptid does. The curve is not part of NTS-1: the standard is the identity layer, liquidity is a separate concern.
Detecting an NTS-1 token
is_nts1(mint):
has TokenMetadata with additional_metadata.standard == "nts-1"
and (has TokenGroupMember -> member: number, max, seed, traits present; number == member_number
or has TokenGroup -> collection: kind, max, naming, prompt present; max == max_size)Reference implementation: checkNts1(mintInfo, meta) in the SDK. Reference issuer: program 5ZmEp1vQ… on devnet.
Why not a new token program
Token-2022 already serialises group membership and refuses the cap on-chain. A new program for that would add an audit surface and lose every wallet and explorer that already reads Token-2022. A standard is cheaper than a program and stronger than a convention: it is a promise about what any reader will find in the mint.