Overview

The NFT layer represents unique, non-fungible assets — a single land parcel deed, a single property title, a single mining license, a single certified warehouse receipt. It mirrors the ERC-20 layer’s architecture (UUPS proxies, role-based access, pluggable identity verifier) but issues ERC721Upgradeable tokens instead of fungible balances.

AnkaraNFTBase

Abstract base contract inherited by all four NFT templates. Provides:
  • ERC721Upgradeable — standard non-fungible token
  • ERC721PausableUpgradeable — halt transfers
  • ERC721BurnableUpgradeable — token burning
  • AccessControlUpgradeable — role-based permissions
  • UUPSUpgradeable — upgrade authorization

Roles

All roles are granted to admin_ at initialization, same as the ERC-20 base.

State

linkToERC20() (MANAGER_ROLE) lets an NFT deed reference a companion fungible token — for example, a RealEstateNFT deed backing a RealEstateToken that represents fractional ownership of the same property.

Minting

Templates call the internal _mintNext(to) helper, which auto-increments the token ID starting at 1 and runs the identity-verifier check before minting:

Transfer Hook

Every mint, burn, and transfer passes through _update(), exactly like the ERC-20 base’s _update() — the identity verifier is checked for both from and to when set (skipped on mint for from, skipped on burn for to):

Templates

Each template extends AnkaraNFTBase with its own metadata struct (e.g. RealEstateNFTMetadata has propertyId, propertyType, locationAddress, titleDocumentHash, valuationUSD, rentalYieldBps, etc.) and a mint(address to, ...metadata) function restricted to MINTER_ROLE.

NFTFactory

Deploys all four NFT templates via ERC1967Proxy, following the exact same pattern as TokenFactory:
  1. Owner registers an implementation address per template via registerTemplate()
  2. Developer calls deployFarmlandNFT() / deployRealEstateNFT() / deployMiningRightsNFT() / deployCommodityVaultNFT()
  3. Factory deploys an ERC1967Proxy pointing at the registered implementation
  4. The developer’s admin_ address receives full role-based control of the new NFT contract
  5. An optional native-token deployment fee is collected (0 during testnet)
Deploy event:
Registry views: totalDeployedNFTs(), getDeployerNFTs(address deployer).

SDK Integration

TokenFactory.deployFarmlandNFT() / deployRealEstateNFT() / deployMiningRightsNFT() / deployCommodityVaultNFT() wrap the factory calls, plus getDeployedNFTs() and totalDeployedNFTs() for the registry views. See the CLI’s ankara deploy-nft command for an interactive example.

Running the NFT Tests Locally