🎰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
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)
Calls
ctx.sender()
to identify the address minting the NFT.Constructs an
NFT
object with:id
: a fresh object created viaobject::new(ctx)
name
: converted fromvector<u8>
tostring::String
metadata
: likewise convertedurl
: built from raw bytes (url::new_unsafe_from_bytes
)merkleroot
: converted tostring::String
so it’s stored on-chain.
Emits an
NFTMinted
event with:object_id
: the newly minted NFT’s object IDcreator
: the minter’s addressname
: the NFT’s human-readable name
Transfers ownership of the
nft
object to the minter (sender
) usingtransfer::public_transfer
.
transfer
A basic transfer function allowing the current owner to send the NFT to another address. It simply callstransfer::public_transfer
to move theNFT
object torecipient
.
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
Takes a
name
(for identification) and the transaction contextctx
.Creates a new
Allowlist
object with:id
: generated viaobject::new(ctx)
list
: an initially emptyvector<string::String>
that will hold blob IDsname
: the provided identifier (e.g., “Summer 2025 Collection”)
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 newAllowlist
.
Calls
transfer::share_object(allowlist)
so theAllowlist
object becomes globally accessible.Returns the
Cap
, which can be used to callpublish
later.
create_allowlist_entry
(entry function) A convenience wrapper that callscreate_allowlist(name, ctx)
and then immediately transfers the resultingCap
toctx.sender()
. This is useful in CLI scripts: the caller ends up owning theCap
to manage that allowlist.publish
Takes a mutable reference to an existing
Allowlist
(&mut Allowlist
), aCap
, and ablob_id
string.Asserts that
cap.allowlist_id
matchesobject::id(allowlist)
—that is, the caller really holds the capability for that allowlist (otherwise it aborts withEInvalidCap
).Calls
df::add(&mut allowlist.id, blob_id, MARKER)
to appendblob_id
into theAllowlist.list
. Here,df::add
is a helper that associates the new blob ID under a special “MARKER” field on theallowlist.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
Structid: 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
Creates a shared, singleton
Marketplace
object with:id
: new object created viaobject::new(ctx)
blobs
: initialized as an emptyvector
.
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 freshMarketplace
(with its ownUID
and emptyblobs
). It does not automatically share it—caller can share or transfer as needed.add_blob
Accepts a mutable reference to a
Marketplace
(registry: &mut Marketplace
) and a new blob ID as raw bytes (new_blob: vector<u8>
).Converts
new_blob
intostring::String
viastring::utf8(new_blob)
.Appends it to
registry.blobs
usingpush_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 fullvector<string::String>
of blob IDs stored in the givenMarketplace
object. Front-end applications callget_blobs
to enumerate all available NFTs and render their previews/metadata.
Last updated