Skills · Coding

Nft Standards

Unverified30/40

Implement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.

Originally by wshobson · MIT

Claude CodePartialHas SKILL.md but declares no allowed-tools — Claude Code will ask for permission each time
CursorPartialPlain prose you can paste in — but no Cursor rules file
CodexPartialPlain prose you can paste in — but no AGENTS.md
Gemini CLIPartialPlain prose you can paste in
CopilotPartialPlain prose you can paste in — but no Copilot instructions file
npx agentalley add nft-standards

This command does not work yet — the CLI is still being built. Until then, use Raw in the reader below to take the file.

Who is stuck, and on what

Implement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.

The whole source

No sign-in, no blur, nothing truncated
nft-standards/SKILL.md264 lines7.5 KBRawView on GitHub
Frontmatter — 2 properties
namenft-standards
descriptionImplement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.
1---
2name: nft-standards
3description: Implement NFT standards (ERC-721, ERC-1155) with proper metadata handling, minting strategies, and marketplace integration. Use when creating NFT contracts, building NFT marketplaces, or implementing digital asset systems.
4---A5No allowed-tools declared — no way to tell what this skill may touch
5 
6# NFT Standards
7 
8Master ERC-721 and ERC-1155 NFT standards, metadata best practices, and advanced NFT features.
9 
10## When to Use This Skill
11 
12- Creating NFT collections (art, gaming, collectibles)
13- Implementing marketplace functionality
14- Building on-chain or off-chain metadata
15- Creating soulbound tokens (non-transferable)
16- Implementing royalties and revenue sharing
17- Developing dynamic/evolving NFTs
18 
19## ERC-721 (Non-Fungible Token Standard)
20 
21```solidity
22// SPDX-License-Identifier: MIT
23pragma solidity ^0.8.0;
24 
25import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
26import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
27import "@openzeppelin/contracts/access/Ownable.sol";
28import "@openzeppelin/contracts/utils/Counters.sol";
29 
30contract MyNFT is ERC721URIStorage, ERC721Enumerable, Ownable {
31 using Counters for Counters.Counter;
32 Counters.Counter private _tokenIds;
33 
34 uint256 public constant MAX_SUPPLY = 10000;
35 uint256 public constant MINT_PRICE = 0.08 ether;
36 uint256 public constant MAX_PER_MINT = 20;
37 
38 constructor() ERC721("MyNFT", "MNFT") {}
39 
40 function mint(uint256 quantity) external payable {
41 require(quantity > 0 && quantity <= MAX_PER_MINT, "Invalid quantity");
42 require(_tokenIds.current() + quantity <= MAX_SUPPLY, "Exceeds max supply");
43 require(msg.value >= MINT_PRICE * quantity, "Insufficient payment");
44 
45 for (uint256 i = 0; i < quantity; i++) {
46 _tokenIds.increment();
47 uint256 newTokenId = _tokenIds.current();
48 _safeMint(msg.sender, newTokenId);
49 _setTokenURI(newTokenId, generateTokenURI(newTokenId));
50 }
51 }
52 
53 function generateTokenURI(uint256 tokenId) internal pure returns (string memory) {
54 // Return IPFS URI or on-chain metadata
55 return string(abi.encodePacked("ipfs://QmHash/", Strings.toString(tokenId), ".json"));
56 }
57 
58 // Required overrides
59 function _beforeTokenTransfer(
60 address from,
61 address to,
62 uint256 tokenId,
63 uint256 batchSize
64 ) internal override(ERC721, ERC721Enumerable) {
65 super._beforeTokenTransfer(from, to, tokenId, batchSize);
66 }
67 
68 function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
69 super._burn(tokenId);
70 }
71 
72 function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {
73 return super.tokenURI(tokenId);
74 }
75 
76 function supportsInterface(bytes4 interfaceId)
77 public
78 view
79 override(ERC721, ERC721Enumerable)
80 returns (bool)
81 {
82 return super.supportsInterface(interfaceId);
83 }
84 
85 function withdraw() external onlyOwner {
86 payable(owner()).transfer(address(this).balance);
87 }
88}
89```
90 
91## ERC-1155 (Multi-Token Standard)
92 
93```solidity
94// SPDX-License-Identifier: MIT
95pragma solidity ^0.8.0;
96 
97import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
98import "@openzeppelin/contracts/access/Ownable.sol";
99 
100contract GameItems is ERC1155, Ownable {
101 uint256 public constant SWORD = 1;
102 uint256 public constant SHIELD = 2;
103 uint256 public constant POTION = 3;
104 
105 mapping(uint256 => uint256) public tokenSupply;
106 mapping(uint256 => uint256) public maxSupply;
107 
108 constructor() ERC1155("ipfs://QmBaseHash/{id}.json") {
109 maxSupply[SWORD] = 1000;
110 maxSupply[SHIELD] = 500;
111 maxSupply[POTION] = 10000;
112 }
113 
114 function mint(
115 address to,
116 uint256 id,
117 uint256 amount
118 ) external onlyOwner {
119 require(tokenSupply[id] + amount <= maxSupply[id], "Exceeds max supply");
120 
121 _mint(to, id, amount, "");
122 tokenSupply[id] += amount;
123 }
124 
125 function mintBatch(
126 address to,
127 uint256[] memory ids,
128 uint256[] memory amounts
129 ) external onlyOwner {
130 for (uint256 i = 0; i < ids.length; i++) {
131 require(tokenSupply[ids[i]] + amounts[i] <= maxSupply[ids[i]], "Exceeds max supply");
132 tokenSupply[ids[i]] += amounts[i];
133 }
134 
135 _mintBatch(to, ids, amounts, "");
136 }
137 
138 function burn(
139 address from,
140 uint256 id,
141 uint256 amount
142 ) external {
143 require(from == msg.sender || isApprovedForAll(from, msg.sender), "Not authorized");
144 _burn(from, id, amount);
145 tokenSupply[id] -= amount;
146 }
147}
148```
149 
150## Metadata Standards
151 
152### Off-Chain Metadata (IPFS)
153 
154```json
155{
156 "name": "NFT #1",
157 "description": "Description of the NFT",
158 "image": "ipfs://QmImageHash",
159 "attributes": [
160 {
161 "trait_type": "Background",
162 "value": "Blue"
163 },
164 {
165 "trait_type": "Rarity",
166 "value": "Legendary"
167 },
168 {
169 "trait_type": "Power",
170 "value": 95,
171 "display_type": "number",
172 "max_value": 100
173 }
174 ]
175}
176```
177 
178### On-Chain Metadata
179 
180```solidity
181contract OnChainNFT is ERC721 {
182 struct Traits {
183 uint8 background;
184 uint8 body;
185 uint8 head;
186 uint8 rarity;
187 }
188 
189 mapping(uint256 => Traits) public tokenTraits;
190 
191 function tokenURI(uint256 tokenId) public view override returns (string memory) {
192 Traits memory traits = tokenTraits[tokenId];
193 
194 string memory json = Base64.encode(
195 bytes(
196 string(
197 abi.encodePacked(
198 '{"name": "NFT #', Strings.toString(tokenId), '",',
199 '"description": "On-chain NFT",',
200 '"image": "data:image/svg+xml;base64,', generateSVG(traits), '",',
201 '"attributes": [',
202 '{"trait_type": "Background", "value": "', Strings.toString(traits.background), '"},',
203 '{"trait_type": "Rarity", "value": "', getRarityName(traits.rarity), '"}',
204 ']}'
205 )
206 )
207 )
208 );
209 
210 return string(abi.encodePacked("data:application/json;base64,", json));
211 }
212 
213 function generateSVG(Traits memory traits) internal pure returns (string memory) {
214 // Generate SVG based on traits
215 return "...";
216 }
217}
218```
219 
220## Royalties (EIP-2981)
221 
222```solidity
223import "@openzeppelin/contracts/interfaces/IERC2981.sol";
224 
225contract NFTWithRoyalties is ERC721, IERC2981 {
226 address public royaltyRecipient;
227 uint96 public royaltyFee = 500; // 5%
228 
229 constructor() ERC721("Royalty NFT", "RNFT") {
230 royaltyRecipient = msg.sender;
231 }
232 
233 function royaltyInfo(uint256 tokenId, uint256 salePrice)
234 external
235 view
236 override
237 returns (address receiver, uint256 royaltyAmount)
238 {
239 return (royaltyRecipient, (salePrice * royaltyFee) / 10000);
240 }
241 
242 function setRoyalty(address recipient, uint96 fee) external onlyOwner {
243 require(fee <= 1000, "Royalty fee too high"); // Max 10%
244 royaltyRecipient = recipient;
245 royaltyFee = fee;
246 }
247 
248 function supportsInterface(bytes4 interfaceId)
249 public
250 view
251 override(ERC721, IERC165)
252 returns (bool)
253 {
254 return interfaceId == type(IERC2981).interfaceId ||
255 super.supportsInterface(interfaceId);
256 }
257}
258```
259 
260## Additional patterns and templates
261 
262More detailed templates and worked examples live in `references/details.md`. Read that file for the full pattern library.
263 
264 

Reviews

Installed this one?Write the first review and take the Trailblazer badge.

Reviews only open after a real install, so this is empty — and we leave it empty rather than invent one.

Alternatives

Also in Coding