Install
$ agentstack add skill-wshobson-agents-nft-standards ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
NFT Standards
Master ERC-721 and ERC-1155 NFT standards, metadata best practices, and advanced NFT features.
When to Use This Skill
- Creating NFT collections (art, gaming, collectibles)
- Implementing marketplace functionality
- Building on-chain or off-chain metadata
- Creating soulbound tokens (non-transferable)
- Implementing royalties and revenue sharing
- Developing dynamic/evolving NFTs
ERC-721 (Non-Fungible Token Standard)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract MyNFT is ERC721URIStorage, ERC721Enumerable, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
uint256 public constant MAX_SUPPLY = 10000;
uint256 public constant MINT_PRICE = 0.08 ether;
uint256 public constant MAX_PER_MINT = 20;
constructor() ERC721("MyNFT", "MNFT") {}
function mint(uint256 quantity) external payable {
require(quantity > 0 && quantity = MINT_PRICE * quantity, "Insufficient payment");
for (uint256 i = 0; i uint256) public tokenSupply;
mapping(uint256 => uint256) public maxSupply;
constructor() ERC1155("ipfs://QmBaseHash/{id}.json") {
maxSupply[SWORD] = 1000;
maxSupply[SHIELD] = 500;
maxSupply[POTION] = 10000;
}
function mint(
address to,
uint256 id,
uint256 amount
) external onlyOwner {
require(tokenSupply[id] + amount Traits) public tokenTraits;
function tokenURI(uint256 tokenId) public view override returns (string memory) {
Traits memory traits = tokenTraits[tokenId];
string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "NFT #', Strings.toString(tokenId), '",',
'"description": "On-chain NFT",',
'"image": "data:image/svg+xml;base64,', generateSVG(traits), '",',
'"attributes": [',
'{"trait_type": "Background", "value": "', Strings.toString(traits.background), '"},',
'{"trait_type": "Rarity", "value": "', getRarityName(traits.rarity), '"}',
']}'
)
)
)
);
return string(abi.encodePacked("data:application/json;base64,", json));
}
function generateSVG(Traits memory traits) internal pure returns (string memory) {
// Generate SVG based on traits
return "...";
}
}
Royalties (EIP-2981)
import "@openzeppelin/contracts/interfaces/IERC2981.sol";
contract NFTWithRoyalties is ERC721, IERC2981 {
address public royaltyRecipient;
uint96 public royaltyFee = 500; // 5%
constructor() ERC721("Royalty NFT", "RNFT") {
royaltyRecipient = msg.sender;
}
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
return (royaltyRecipient, (salePrice * royaltyFee) / 10000);
}
function setRoyalty(address recipient, uint96 fee) external onlyOwner {
require(fee <= 1000, "Royalty fee too high"); // Max 10%
royaltyRecipient = recipient;
royaltyFee = fee;
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, IERC165)
returns (bool)
{
return interfaceId == type(IERC2981).interfaceId ||
super.supportsInterface(interfaceId);
}
}
Additional patterns and templates
More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: wshobson
- Source: wshobson/agents
- License: MIT
- Homepage: https://sethhobson.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.