0x0::nft

Module defining the OriginByte NFT type

OriginByte's NFT protocol brings dynamism, composability and extendability to NFTs. The current design allows creators to create NFTs with custom domain-specific fields, with their own bespoke behavior.

OriginByte provides a set of standard domains which implement common NFT use-cases such as DisplayDomain which allows wallets and marketplaces to easily display your NFT.

Structs

nft::Nft<C> has store, key

Fields:

Name Type Description
id object::UID

Nft ID

name string::String

Nft name

url url::Url

Nft URL

logical_owner address

Represents the logical owner of an NFT

It allows for the traceability of the owner of an NFT even when the NFT is owned by a shared Safe object.

Nft object

OriginByte collections and NFTs have a generic parameter C which is a one-time witness created by the creator's NFT collection module. This allows Collection and Nft to be linked via type association, but also ensures that NFTs can only be minted by the contract that initially deployed them.

An Nft exclusively owns domains of different types, which can be dynamically acquired and lost over its lifetime. OriginByte NFTs are modelled after Entity Component Systems, where their domains are accessible by type. See borrow_domain_mut.

nft::MintNftEvent has copy, drop

Fields:

Name Type Description
nft_id object::ID

ID of the Nft that was minted

nft_type ascii::String

Type name of Nft<C> one-time witness C

Intended to allow users to filter by collections of interest.

logical_owner address

Assigned address which owns the NFT

Event signalling that an Nft was minted

nft::ChangeLogicalOwnerEvent has copy, drop

Fields:

Name Type Description
nft_id object::ID

ID of the Nft that had its logical owner changed

old_logical_owner address

The address of the previous logical owner

new_logical_owner address

The address of the new logical owner

nft_type ascii::String

The TypeName string of the inner C generic of Nft<C>.

Methods

public fun new<C, W>(
    _witness: &W,
    name: string::String,
    url: url::Url,
    owner: address,
    ctx: &mut tx_context::TxContext,
): nft::Nft<C>

Create a new Nft using MintCap

Requires witness of collection contract as this function should only be used by functions defined within that contract due to the potential to violate correctness guarantees in other parts of the codebase.

Usage

struct Witness has drop {}
struct SUIMARINES has drop {}

fun init(witness: SUIMARINES, ctx: &mut TxContext) {
    let nft = nft::new(&Witness {}, tx_context::sender(ctx), ctx);
}

public fun from_mint_cap<C>(
    _mint_cap: &mint_cap::MintCap<C>,
    name: string::String,
    url: url::Url,
    ctx: &mut tx_context::TxContext,
): nft::Nft<C>

Create a new Nft using MintCap

Contrary to minting NFTs using new, the logical owner is set to the transaction sender as MintCap does not have the ability to add domains to NFTs not belonging to the transaction sender.

public fun from_regulated<C>(
    mint_cap: &mut mint_cap::RegulatedMintCap<C>,
    name: string::String,
    url: url::Url,
    ctx: &mut tx_context::TxContext,
): nft::Nft<C>

Create a new Nft using RegulatedMintCap

RegulatedMintCap may only be created by supply_domain::delegate_regulated.

Contrary to minting NFTs using new, the logical owner is set to the transaction sender as RegulatedMintCap does not have the ability to add domains to NFTs not belonging to the transaction sender.

See new for usage information.

Panics

Panics if supply is exceeded.

public fun from_unregulated<C>(
    _mint_cap: &mint_cap::UnregulatedMintCap<C>,
    name: string::String,
    url: url::Url,
    ctx: &mut tx_context::TxContext,
): nft::Nft<C>

Create a new Nft using UnregulatedMintCap

UnregulatedMintCap may only be created by supply_domain::delegate_unregulated.

Contrary to minting NFTs using new, the logical owner is set to the transaction sender as RegulatedMintCap does not have the ability to add domains to NFTs not belonging to the transaction sender.

See new for usage information.

public fun has_domain<C, D: store>(
    nft: &nft::Nft<C>,
): bool

Check whether Nft has a domain of type D

public fun borrow_domain<C, D: store>(
    nft: &nft::Nft<C>,
): &D

Borrow domain of type D from Nft

Panics

Panics if domain of type D is not present on the Nft

public fun borrow_domain_mut<C, D: store, W: drop>(
    _witness: W,
    nft: &mut nft::Nft<C>,
): &mut D

Mutably borrow domain of type D from Nft

Guarantees that domain D can only be mutated by the module that instantiated it. In other words, witness W must be defined in the same module as domain D.

Usage

module nft_protocol::display {
    struct SUIMARINES has drop {}
    struct Witness has drop {}

    struct DisplayDomain {
        id: UID,
        name: string::String,
    } has key, store

    public fun domain_mut(nft: &mut Nft<C>): &mut DisplayDomain {
        let domain: &mut DisplayDomain =
            collection::borrow_domain_mut(Witness {}, collection);
    }
}

Panics

Panics when module attempts to mutably borrow a domain it did not define itself or if domain of type D is not present on the Nft.

The module that actually added the domain to the Nft is not affected, in effect, this means that you can register OriginByte standard domains but OriginByte still controls access through any mutating methods it exposes.

module nft_protocol::fake_display {
    use nft_protocol::display::DisplayDomain;

    struct SUIMARINES has drop {}
    struct Witness has drop {}

    public fun domain_mut<C>(nft: &mut Nft<C>): &mut DisplayDomain {
        // Call to `borrow_domain_mut` will panic due to `Witness` not originating from `nft_protocol::display`.
        let domain: &mut DisplayDomain =
            collection::borrow_domain_mut(Witness {}, collection);
    }
}

public fun add_domain<C, W, D: store>(
    witness: &W,
    nft: &mut nft::Nft<C>,
    domain: D,
)

Adds domain of type D to Nft

Helper method that can be simply used without knowing what a delegated witness is.

Panics

Panics if domain D already exists.

public fun add_domain_delegated<C, D: store>(
    _witness: witness::Witness<C>,
    nft: &mut nft::Nft<C>,
    domain: D,
)

Adds domain of type D to Nft

Panics

Panics if domain D already exists.

public fun add_domain_with_mint_cap<C, D: store>(
    _mint_cap: &mint_cap::MintCap<C>,
    nft: &mut nft::Nft<C>,
    domain: D,
    ctx: &mut tx_context::TxContext,
)

Adds domain of type D to Nft

Same as add_domain but uses MintCap to authenticate the operation.

Requires that transaction sender is the logical owner of the NFT. Prevents entities delegated the sole right ot mint NFTs from registering arbitrary domains on existing NFTs.

Panics

Panics transaction sender is not logical owner or if domain D already exists.

public fun add_domain_with_regulated<C, D: store>(
    _mint_cap: &mint_cap::RegulatedMintCap<C>,
    nft: &mut nft::Nft<C>,
    domain: D,
    ctx: &mut tx_context::TxContext,
)

Adds domain of type D to Nft

Same as add_domain but uses RegulatedMintCap to authenticate the operation.

Requires that transaction sender is the logical owner of the NFT. Prevents entities delegated the sole right ot mint NFTs from registering arbitrary domains on existing NFTs.

Panics

Panics transaction sender is not logical owner or if domain D already exists.

public fun add_domain_with_unregulated<C, D: store>(
    _mint_cap: &mint_cap::UnregulatedMintCap<C>,
    nft: &mut nft::Nft<C>,
    domain: D,
    ctx: &mut tx_context::TxContext,
)

Adds domain of type D to Nft

Same as add_domain but uses UnregulatedMintCap to authenticate the operation.

Requires that transaction sender is the logical owner of the NFT. Prevents entities delegated the sole right ot mint NFTs from registering arbitrary domains on existing NFTs.

Panics

Panics transaction sender is not logical owner or if domain D already exists.

public fun remove_domain<C, W: drop, D: store>(
    _witness: W,
    nft: &mut nft::Nft<C>,
): D

Removes domain of type D from Nft

Panics

Panics when module attempts to remove a domain it did not define itself or if domain of type D is not present on the Nft. See borrow_domain_mut.

Usage

let display_domain: DisplayDomain = nft::remove_domain(Witness {}, &mut nft);

public entry fun burn<C>(nft: nft::Nft<C>)

Burns an Nft

Panics

Panics if any domains are still registered on the Nft.

public fun name<C>(nft: &nft::Nft<C>): 
    &string::String

Returns Nft name

public fun url<C>(nft: &nft::Nft<C>): &url::Url

Returns Nft name

public fun set_name<C>(
    _witness: witness::Witness<C>,
    nft: &mut nft::Nft<C>,
    name: string::String,
)

Sets Nft static name

Caution when changing properties of loose NFTs as the changes will not be propagated to the template.

public fun set_url<C>(
    _witness: witness::Witness<C>,
    nft: &mut nft::Nft<C>,
    url: url::Url,
)

Sets Nft static URL

Caution when changing properties of loose NFTs as the changes will not be propagated to the template.

public fun logical_owner<C>(nft: &nft::Nft<C>): 
    address

Returns the logical owner of the Nft

public fun transfer<C, Auth: drop>(
    nft: nft::Nft<C>,
    recipient: address,
    authority: Auth,
    allowlist: &transfer_allowlist::Allowlist,
)

Transfer the Nft to recipient while changing the logical_owner

Requires that Auth is registered as an authority on Allowlist.

Panics

Panics if authority token, Auth, or collection was not defined on Allowlist.

public fun change_logical_owner<C, Auth: drop>(
    nft: &mut nft::Nft<C>,
    recipient: address,
    _authority: Auth,
    allowlist: &transfer_allowlist::Allowlist,
)

Change the logical_owner of the Nft to recipient

Creator can allow certain contracts to change the logical owner of an NFT.

This function is a no-op if the logical_owner is already recipient.

Panics

Panics if authority token, Auth, or collection was not defined on Allowlist.

public fun assert_domain<C, D: store>(
    nft: &nft::Nft<C>,
)

Assert that domain, D, exists on Nft

Panics

Panics if domain, D, does not exist on Nft.

public fun assert_no_domain<C, D: store>(
    nft: &nft::Nft<C>,
)

Assert that domain, D, does not exist on Nft

Panics

Panics if domain, D, exists on Nft.

public fun assert_logical_owner<C>(
    nft: &nft::Nft<C>,
    ctx: &mut tx_context::TxContext,
)

Asserts that transaction sender is the logical owner of the Nft

Panics

Panics if transaction sender is not logical owner.