🎰Contracts

Contracts of SuiShadow

PackageId : 0x576ce6f9227b55f93844988881ecb53c74c8ffcbd5e7ecf6be8624d2ebd47f25
// This is the Package named nftverifier and has all of the contracts of SuiShadow . 

There are 3 main Contracts NFT , Allowlist and MarketPlace .


The NFT contract handles minting and transferring NFTs, and stores each token’s Merkle root on-chain. Below are the key functions:

#[allow(lint(self_transfer))]
/// Create a new devnet_nft
public fun mint_to_sender(
    name: vector<u8>,
    metadata: vector<u8>,
    url: vector<u8>,    
    merkleroot: vector<u8>,
    ctx: &mut TxContext,
) {
    let sender = ctx.sender();
    let nft = NFT {
        id: object::new(ctx),
        name: string::utf8(name),
        metadata: string::utf8(metadata),
        url: url::new_unsafe_from_bytes(url),
        merkleroot: string::utf8(merkleroot),
    };

    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: NFT, recipient: address, _: &mut TxContext) {
    transfer::public_transfer(nft, recipient)
}
  • mint_to_sender

    1. Reads four inputs:

      • name: the NFT’s name (as UTF-8 bytes)

      • metadata: arbitrary metadata (UTF-8)

      • url: a pointer to an off-chain preview or data blob (raw bytes)

      • merkleroot: the 32-byte SHA-256 Merkle root of all encrypted tiles (UTF-8)

    2. Calls ctx.sender() to identify the address minting the NFT.

    3. Constructs an NFT object with:

      • id: a fresh object created via object::new(ctx)

      • name: converted from vector<u8> to string::String

      • metadata: likewise converted

      • url: built from raw bytes (url::new_unsafe_from_bytes)

      • merkleroot: converted to string::String so it’s stored on-chain.

    4. Emits an NFTMinted event with:

      • object_id: the newly minted NFT’s object ID

      • creator: the minter’s address

      • name: the NFT’s human-readable name

    5. Transfers ownership of the nft object to the minter (sender) using transfer::public_transfer.

  • transfer A basic transfer function allowing the current owner to send the NFT to another address. It simply calls transfer::public_transfer to move the NFT object to recipient.


Allowlist Contract

The Allowlist contract tracks which addresses are permitted to decrypt encrypted data via Sui Seal. Once a buyer pays for an NFT, their address is added here, and they receive the encrypted blob IDs they can decrypt.

public fun create_allowlist(name: String, ctx: &mut TxContext): Cap {
    let allowlist = Allowlist {
        id: object::new(ctx),
        list: vector::empty(),
        name: name,
    };
    let cap = Cap {
        id: object::new(ctx),
        allowlist_id: object::id(&allowlist),
    };
    transfer::share_object(allowlist);
    cap
}

// convenience function to create a allowlist and send it back to sender (simpler ptb for cli)
entry fun create_allowlist_entry(name: String, ctx: &mut TxContext) {
    transfer::transfer(create_allowlist(name, ctx), ctx.sender());
}

public fun publish(allowlist: &mut Allowlist, cap: &Cap, blob_id: String) {
    assert!(cap.allowlist_id == object::id(allowlist), EInvalidCap);
    df::add(&mut allowlist.id, blob_id, MARKER);
}
  • create_allowlist

    1. Takes a name (for identification) and the transaction context ctx.

    2. Creates a new Allowlist object with:

      • id: generated via object::new(ctx)

      • list: an initially empty vector<string::String> that will hold blob IDs

      • name: the provided identifier (e.g., “Summer 2025 Collection”)

    3. Creates a Cap object, which is a capability allowing only the holder to add entries to this allowlist:

      • id: its own fresh object ID (object::new(ctx))

      • allowlist_id: the object ID of the new Allowlist.

    4. Calls transfer::share_object(allowlist) so the Allowlist object becomes globally accessible.

    5. Returns the Cap, which can be used to call publish later.

  • create_allowlist_entry (entry function) A convenience wrapper that calls create_allowlist(name, ctx) and then immediately transfers the resulting Cap to ctx.sender(). This is useful in CLI scripts: the caller ends up owning the Cap to manage that allowlist.

  • publish

    1. Takes a mutable reference to an existing Allowlist (&mut Allowlist), a Cap, and a blob_id string.

    2. Asserts that cap.allowlist_id matches object::id(allowlist)—that is, the caller really holds the capability for that allowlist (otherwise it aborts with EInvalidCap).

    3. Calls df::add(&mut allowlist.id, blob_id, MARKER) to append blob_id into the Allowlist.list. Here, df::add is a helper that associates the new blob ID under a special “MARKER” field on the allowlist.id object. In practice, blob_id represents the Walrus content address that the allowed user can now decrypt via Sui Seal.


Marketplace Contract

The Marketplace contract maintains a shared list of all NFTs (by their Walrus blob IDs and metadata) so that anyone can browse the public collection without requiring centralized servers.

public struct Marketplace has key, store {
    id: UID,
    blobs: vector<string::String>,
}

// Initialize and share the marketplace
fun init(ctx: &mut TxContext) {
    let marketplace = Marketplace {
        id: object::new(ctx),
        blobs: empty()
    };
    transfer::share_object(marketplace);
}

// Create a new marketplace (if you need multiple instances)
public fun create_marketplace(ctx: &mut TxContext): Marketplace {
    Marketplace {
        id: object::new(ctx),
        blobs: empty()
    }
}

// Add a blob ID to the marketplace
public fun add_blob(registry: &mut Marketplace, new_blob: vector<u8>) {
    push_back<string::String>(&mut registry.blobs, string::utf8(new_blob));
}

// Get all blob IDs from the marketplace
public fun get_blobs(registry: &Marketplace): vector<string::String> {
    registry.blobs
}
  • Marketplace Struct

    • id: UID A unique object identifier for this marketplace instance.

    • blobs: vector<string::String> A dynamic list of Walrus blob IDs (each pointing to an encrypted payload or metadata) that represent the entire collection visible in the storefront.

  • init

    1. Creates a shared, singleton Marketplace object with:

      • id: new object created via object::new(ctx)

      • blobs: initialized as an empty vector.

    2. Calls transfer::share_object(marketplace) to make this shared marketplace accessible to all users on-chain.

  • create_marketplace If you want to run multiple, separate storefronts (e.g., per artist or per sub-collection), this function instantiates a fresh Marketplace (with its own UID and empty blobs). It does not automatically share it—caller can share or transfer as needed.

  • add_blob

    1. Accepts a mutable reference to a Marketplace (registry: &mut Marketplace) and a new blob ID as raw bytes (new_blob: vector<u8>).

    2. Converts new_blob into string::String via string::utf8(new_blob).

    3. Appends it to registry.blobs using push_back. This is how each newly minted NFT’s Walrus blob ID (or metadata blob) becomes visible in the public marketplace.

  • get_blobs A read-only accessor that returns the full vector<string::String> of blob IDs stored in the given Marketplace object. Front-end applications call get_blobs to enumerate all available NFTs and render their previews/metadata.

Last updated