NFT Standard
Rivellum supports non-fungible tokens (NFTs) and semi-fungible tokens (SFTs) as native protocol operations.
Overview
NFTs on Rivellum are first-class intent operations — no smart contract deployment required. Collections, minting, transfers, and burns are handled through native intent payloads.
Data Model
Collection
| Field | Type | Description |
|---|---|---|
id | CollectionId (32 bytes) | BLAKE3 hash of "COLLECTION:" || creator || name |
creator | Address | Collection creator address |
name | String | Collection display name |
description | String (optional) | Description text |
max_supply | u64 (optional) | Maximum mintable tokens (none = unlimited) |
minted_count | u64 | Current number minted |
royalty_bps | u16 | Royalty in basis points (100 = 1%) |
royalty_recipient | Address | Address receiving royalties on secondary sales |
NFT
| Field | Type | Description |
|---|---|---|
id | NftId (32 bytes) | BLAKE3 hash of "NFT:" || collection || creator || mint_nonce |
collection | CollectionId | Parent collection |
owner | Address | Current owner |
name | String | Token name |
description | String (optional) | Description |
media_uri | String (optional) | URI to off-chain media |
attributes | Map<String, String> | Key-value metadata |
Semi-Fungible Token (SFT)
SFTs share a variant within a collection but can have multiple copies:
| Field | Type | Description |
|---|---|---|
id | SftId (32 bytes) | BLAKE3 hash of "SFT:" || collection || variant_id |
Intent Operations
Create Collection
{
"type": "CreateCollection",
"name": "My Collection",
"description": "A sample NFT collection",
"max_supply": 10000,
"royalty_bps": 250,
"royalty_recipient": "0x..."
}
Mint NFT
{
"type": "MintNft",
"collection_id": "0x...",
"name": "Token #1",
"description": "First token",
"media_uri": "ipfs://...",
"attributes": { "rarity": "legendary" },
"recipient": "0x..."
}
Transfer NFT
{
"type": "TransferNft",
"nft_id": "0x...",
"to": "0x..."
}
Burn NFT
{
"type": "BurnNft",
"nft_id": "0x..."
}
SDK Usage
import { RivellumClient } from '@rivellum/sdk';
const client = new RivellumClient({ nodeUrl: 'https://rpc.rivellum.network' });
// List collections
const collections = await client.listCollections(1, 20);
// Get collection details
const collection = await client.getCollection('collection_id_hex');
// Get NFT metadata
const nft = await client.getNftMetadata('nft_id_hex');
// List NFTs owned by address
const owned = await client.getNftsOwnedBy('0x1234...', 1, 20);
// Transfer history
const history = await client.getNftTransferHistory('nft_id_hex', 1, 20);
Design Decisions
- Deterministic IDs: All identifiers derived via BLAKE3 — no sequential counters
- Minimal on-chain data: Metadata stored on-chain; media referenced by URI
- Native operations: No contract deployment needed; handled at the protocol level
- Royalties: Enforced at the protocol level on secondary transfers; configurable per collection