Tenzro Testnet is live. Get testnet TNZO

NFT Infrastructure

Tenzro Ledger provides native NFT support through the NFT Factory precompile at address 0x1006. NFTs on Tenzro follow the same cross-VM pointer model used for fungible tokens — a single NFT record exists in the unified registry, and each VM (EVM, SVM, DAML) exposes a thin pointer contract that reads and writes against the same underlying ownership data. This means an NFT minted on EVM is immediately visible and transferable from SVM or DAML without bridging.

Architecture Overview

The NftRegistry stores all NFT state in a DashMap backed by the CF_NFTS RocksDB column family. Each collection is identified by a deterministic CollectionId computed as SHA-256(creator_address || nonce). Individual tokens within a collection are keyed by (collection_id, token_id).

NFT Factory Precompile

The NFT Factory is a Tenzro-specific EVM precompile deployed at address 0x1006. It provides gas-efficient native operations without requiring Solidity contract deployment.

Function SelectorFunctionDescriptionGas Cost
0x01createCollectionCreate a new NFT collection with name, symbol, max supply, and standard (721 or 1155)50,000
0x02mintMint a new token in a collection to a recipient address with metadata URI30,000
0x03mintBatchBatch mint multiple tokens in a single transaction (ERC-1155)30,000 + 5,000/token
0x04transferTransfer an NFT between addresses (same or cross-VM)25,000
0x05burnBurn a token (only by owner or approved operator)20,000
0x06approveApprove an operator for a specific token or entire collection15,000
0x07ownerOfQuery the owner of a specific token (read-only, no gas in static call)2,600
0x08tokenURIGet the metadata URI for a token2,600
0x09collectionInfoGet collection metadata (name, symbol, total supply, max supply, standard)2,600

Supported Standards

ERC-721 (Non-Fungible)

Each token is unique with a distinct token ID and single owner. Used for unique digital assets like art, identity credentials, domain names, and real-world asset certificates.

Pointer contract: Standard ERC-721 interface (ownerOf, transferFrom, approve, balanceOf) backed by NftRegistry

ERC-1155 (Multi-Token)

A single contract manages multiple token types, where each token ID can have a supply greater than one. Used for gaming items, event tickets, membership passes, and semi-fungible assets.

Pointer contract: Standard ERC-1155 interface (balanceOf, safeTransferFrom, safeBatchTransferFrom) backed by NftRegistry

Cross-VM NFT Pointer Model

NFTs use the same Sei V2 pointer architecture as fungible tokens. When a collection is created through the NFT Factory, three pointer representations are automatically registered:

VMInterfaceBehavior
EVMERC-721 / ERC-1155 pointer contractReads/writes directly to NftRegistry. Full Solidity compatibility.
SVMMetaplex-compatible programMaps Metaplex metadata account structure to NftRegistry entries. PDAs derived from collection mint + token ID.
DAMLCIP-NFT DAML templateTwo-step transfer flow (create-offer, accept/reject) with party-to-address mapping.

No bridge risk — Cross-VM NFT transfers do not lock and mint. When you transfer an NFT from EVM to SVM, the NftRegistry updates the owner address in place. The EVM pointer reflects the new owner, and the SVM pointer sees the same owner. There is never a wrapped or synthetic NFT.

Code Example

use tenzro_vm::nft::{NftRegistry, NftStandard, CollectionConfig, MintParams};

// Initialize the NFT registry with storage
let registry = NftRegistry::with_storage(storage.clone())?;

// Create a new ERC-721 collection
let collection = registry.create_collection(CollectionConfig {
    name: "Tenzro Agents".to_string(),
    symbol: "TAGENT".to_string(),
    standard: NftStandard::Erc721,
    max_supply: Some(10_000),
    base_uri: "https://metadata.tenzro.network/agents/".to_string(),
    royalty_bps: Some(250),        // 2.5% royalties
    creator: creator_address,
})?;

println!("Collection ID: {}", collection.id);

// Mint a token
let token = registry.mint(MintParams {
    collection_id: collection.id,
    token_id: 1,
    recipient: recipient_address,
    metadata_uri: Some("https://metadata.tenzro.network/agents/1.json".to_string()),
    amount: 1,                     // Always 1 for ERC-721
})?;

// Transfer (works across VMs — same operation regardless of source VM)
registry.transfer(
    collection.id,
    1,                             // token_id
    recipient_address,             // from
    new_owner_address,             // to (can be EVM, SVM, or DAML address)
)?;

// Query ownership
let owner = registry.owner_of(collection.id, 1)?;
assert_eq!(owner, new_owner_address);

// ERC-1155 batch mint example
let collection_1155 = registry.create_collection(CollectionConfig {
    name: "Tenzro Items".to_string(),
    symbol: "TITEM".to_string(),
    standard: NftStandard::Erc1155,
    max_supply: None,              // No global cap
    base_uri: "https://metadata.tenzro.network/items/".to_string(),
    royalty_bps: Some(500),        // 5% royalties
    creator: creator_address,
})?;

// Batch mint: 100 copies each of token IDs 1, 2, and 3
registry.mint_batch(
    collection_1155.id,
    vec![
        MintParams { token_id: 1, amount: 100, ..Default::default() },
        MintParams { token_id: 2, amount: 100, ..Default::default() },
        MintParams { token_id: 3, amount: 100, ..Default::default() },
    ],
    recipient_address,
)?;

CLI Usage

# Create a new ERC-721 collection
tenzro nft create-collection --name "Tenzro Agents" --symbol TAGENT \
  --standard erc721 --max-supply 10000 \
  --base-uri "https://metadata.tenzro.network/agents/"

# Mint a token
tenzro nft mint --collection <collection-id> --token-id 1 \
  --recipient 0xrecipient...abc \
  --metadata-uri "https://metadata.tenzro.network/agents/1.json"

# Batch mint (ERC-1155)
tenzro nft mint-batch --collection <collection-id> \
  --tokens "1:100,2:100,3:50" --recipient 0xrecipient...abc

# Transfer an NFT
tenzro nft transfer --collection <collection-id> --token-id 1 \
  --to 0xnewowner...def

# Cross-VM transfer (EVM -> SVM)
tenzro nft transfer --collection <collection-id> --token-id 1 \
  --to <solana-pubkey> --target-vm svm

# Query token info
tenzro nft info --collection <collection-id> --token-id 1

# List collections by creator
tenzro nft collections --creator 0xcreator...abc

# Get collection stats
tenzro nft collection-info --collection <collection-id>

Comparison with Other Chains

FeatureTenzroSei V2Solana (Metaplex)Unique Network
NFT storageNative precompile + registryCosmWasm + pointerOn-chain accountsNative pallet
Cross-VMEVM + SVM + DAML (pointer model)EVM + CosmWasm (pointer)SVM onlySubstrate only
StandardsERC-721, ERC-1155CW-721Metaplex Token StandardNative NFT pallet
Batch operationsNative batch mint (ERC-1155)Multi-message txCompressed NFTs (Bubblegum)Bulk mint extrinsic
Mint cost30,000 gas (~0.00003 TNZO)~100,000 gas~0.01 SOL (compressed: ~0.00005 SOL)~0.1 UNQ
Enterprise supportDAML template (Canton)NoNoLimited
Identity bindingTDIP DID linked to collectionsNo native identityNo native identityNo native identity

Metadata Standard

Tenzro NFTs follow the standard JSON metadata schema used across the ecosystem. Metadata is stored off-chain at the URI specified during minting and can point to IPFS, Arweave, or any HTTP endpoint.

{
  "name": "Tenzro Agent #1",
  "description": "A verified AI agent on the Tenzro Network",
  "image": "ipfs://Qm.../agent-1.png",
  "external_url": "https://tenzro.network/agents/1",
  "attributes": [
    { "trait_type": "Agent Type", "value": "Validator" },
    { "trait_type": "TEE Verified", "value": "true" },
    { "trait_type": "Reputation Score", "value": 95 },
    { "trait_type": "Capabilities", "value": "inference,settlement,verification" }
  ]
}