0x0::transfer_allowlist

Allowlists NFT transfers.

This module is a set of functions for implementing and managing a allowlist for NFT (non-fungible token) transfers. The allowlist is used to authorize which contracts are allowed to transfer NFTs of a particular collection. The module includes functions for creating and managing the allowlist, adding and removing collections from the allowlist, and checking whether a contract is authorized to transfer a particular NFT. The module uses generics and reflection to allow for flexibility in implementing and managing the allowlist.

Three generics at play:

  1. Admin (allowlist witness) enables any organization to start their own allowlist and manage it according to their own rules;
  2. CW (collection witness) enpowers creators to add or remove their collections to allowlists;
  3. Auth (3rd party witness) is used to authorize contracts via their witness types. If e.g. an orderbook trading contract wants to be included in a allowlist, the allowlist admin adds the stringified version of their witness type. The OB then uses this witness type to authorize transfers.

Structs

transfer_allowlist::Allowlist has store, key

Fields:

Name Type Description
id object::UID
admin_witness type_name::TypeName

We don't store it as generic because then it has to be propagated around and it's very unergonomic.

collections vec_set::VecSet<type_name::TypeName>

Which collections does this allowlist apply to?

We use reflection to avoid generics.

authorities option::Option<vec_set::VecSet<type_name::TypeName>>

If None, then there's no allowlist and everyone is allowed.

Otherwise we use a witness pattern but store the witness object as the output of type_name::get.

transfer_allowlist::CollectionControlCap<C> has store, key

Fields:

Name Type Description
id object::UID

Gives the collection admin a capability to insert and remove their collection from a allowlist.

To create this cap, the contract which defines the collection generic must call create_collection_cap with a witness that belongs to the same contract as the generic C. Additionally, the witness type must be called Witness.

Methods

public fun create<Admin>(
    _witness: &Admin,
    ctx: &mut tx_context::TxContext,
): transfer_allowlist::Allowlist

Creates a new Allowlist

public fun init_allowlist<Admin>(
    witness: &Admin,
    ctx: &mut tx_context::TxContext,
)

Creates and shares a new Allowlist

public fun create_collection_cap<C>(
    _witness: witness::Witness<C>,
    ctx: &mut tx_context::TxContext,
): transfer_allowlist::CollectionControlCap<C>

See the docs for struct CollectionControlCap.

public fun insert_collection<C, Admin>(
    _allowlist_witness: &Admin,
    _collection_witness: witness::Witness<C>,
    list: &mut transfer_allowlist::Allowlist,
)

public fun insert_collection_with_cap<C, Admin>(
    _allowlist_witness: &Admin,
    _authority: &transfer_allowlist::CollectionControlCap<C>,
    list: &mut transfer_allowlist::Allowlist,
)

To add a collection to the list, we need a confirmation by both the allowlist authority and the collection creator via witness pattern.

If the allowlist authority wants to enable any creator to add their collection to the allowlist, they can reexport this function in their module without the witness protection. However, we opt for witness collection to give the allowlist owner a way to combat spam.

public entry fun remove_itself<C>(
    _authority: &transfer_allowlist::CollectionControlCap<C>,
    list: &mut transfer_allowlist::Allowlist,
)

Any collection is allowed to remove itself from any allowlist at any time.

It's always the creator's right to decide at any point what authorities can transfer NFTs of that collection.

public fun remove_collection<Admin: drop, C>(
    _allowlist_witness: Admin,
    list: &mut transfer_allowlist::Allowlist,
)

The allowlist owner can remove any collection at any point.

public fun clear_collections<Admin: drop>(
    _allowlist_witness: Admin,
    list: &mut transfer_allowlist::Allowlist,
)

Removes all collections from this list.

public fun insert_authority<Admin: drop, Auth>(
    _allowlist_witness: Admin,
    list: &mut transfer_allowlist::Allowlist,
)

To insert a new authority into a list we need confirmation by the allowlist authority (via witness.)

public fun remove_authority<Admin: drop, Auth>(
    _allowlist_witness: Admin,
    list: &mut transfer_allowlist::Allowlist,
)

The allowlist authority (via witness) can at any point remove any authority from their list.

public fun can_be_transferred<C, Auth>(
    allowlist: &transfer_allowlist::Allowlist,
): bool

Checks whether given authority witness is in the allowlist, and also whether given collection witness (C) is in the allowlist.

public fun contains_collection<C>(
    allowlist: &transfer_allowlist::Allowlist,
): bool

Returns whether Allowlist contains collection C

public fun contains_authority<Auth>(
    allowlist: &transfer_allowlist::Allowlist,
): bool

Returns whether Allowlist contains authority Auth

public fun requires_authority(
    allowlist: &transfer_allowlist::Allowlist,
): bool

Returns whether Allowlist requires an authority to transfer

public fun assert_collection<C>(
    allowlist: &transfer_allowlist::Allowlist,
)

Assert that Nft<C> may be transferred using this Allowlist

Panics

Panics if Nft<C> may not be transferred.

public fun assert_authority<Auth>(
    allowlist: &transfer_allowlist::Allowlist,
)

Assert that Auth may be used to transfer using this Allowlist

Panics

Panics if Nft<C> may not be transferred.

public fun assert_transferable<C, Auth>(
    allowlist: &transfer_allowlist::Allowlist,
)

Assert that Nft<C> is transferrable and Auth may be used to transfer using this Allowlist.

Panics

Panics if neither Nft<C> is not transferrable or Auth is not a valid authority.