Skip to main content

Create a Non-Fungible Token

On Sui, everything is an object. Moreover, in Sui, everything is a non-fungible token (NFT) as its objects are unique, non-fungible, and owned. So technically, a basic type publishing is enough to create a specific NFT.

module examples::devnet_nft {
use sui::url::{Self, Url};
use std::string;
use sui::object::{Self, ID, UID};
use sui::event;
use sui::transfer;
use sui::tx_context::{Self, TxContext};

/// An example NFT that can be minted by anybody
struct DevNetNFT has key, store {
id: UID,
/// Name for the token
name: string::String,
/// Description of the token
description: string::String,
/// URL for the token
url: Url,
// TODO: allow custom attributes
}

// ===== Events =====

struct NFTMinted has copy, drop {
// The Object ID of the NFT
object_id: ID,
// The creator of the NFT
creator: address,
// The name of the NFT
name: string::String,
}

// ===== Public view functions =====

/// Get the NFT's `name`
public fun name(nft: &DevNetNFT): &string::String {
&nft.name
}

/// Get the NFT's `description`
public fun description(nft: &DevNetNFT): &string::String {
&nft.description
}

/// Get the NFT's `url`
public fun url(nft: &DevNetNFT): &Url {
&nft.url
}

// ===== Entrypoints =====

/// Create a new devnet_nft
public fun mint_to_sender(
name: vector<u8>,
description: vector<u8>,
url: vector<u8>,
ctx: &mut TxContext
) {
let sender = tx_context::sender(ctx);
let nft = DevNetNFT {
id: object::new(ctx),
name: string::utf8(name),
description: string::utf8(description),
url: url::new_unsafe_from_bytes(url)
};

event::emit(NFTMinted {
object_id: object::id(&nft),
creator: sender,
name: nft.name,
});

transfer::public_transfer(nft, sender);
}

/// Transfer `nft` to `recipient`
public fun transfer(
nft: DevNetNFT, recipient: address, _: &mut TxContext
) {
transfer::public_transfer(nft, recipient)
}

/// Update the `description` of `nft` to `new_description`
public fun update_description(
nft: &mut DevNetNFT,
new_description: vector<u8>,
_: &mut TxContext
) {
nft.description = string::utf8(new_description)
}

/// Permanently delete `nft`
public fun burn(nft: DevNetNFT, _: &mut TxContext) {
let DevNetNFT { id, name: _, description: _, url: _ } = nft;
object::delete(id)
}
}