diff --git a/aptos-move/framework/aptos-token-objects/doc/overview.md b/aptos-move/framework/aptos-token-objects/doc/overview.md index 58a452350877e..aacb913656b59 100644 --- a/aptos-move/framework/aptos-token-objects/doc/overview.md +++ b/aptos-move/framework/aptos-token-objects/doc/overview.md @@ -12,10 +12,10 @@ This is the reference documentation of the Supra Token Objects framework. ## Index -- [`0x4::aptos_token`](aptos_token.md#0x4_aptos_token) - [`0x4::collection`](collection.md#0x4_collection) - [`0x4::property_map`](property_map.md#0x4_property_map) - [`0x4::royalty`](royalty.md#0x4_royalty) +- [`0x4::supra_token`](supra_token.md#0x4_supra_token) - [`0x4::token`](token.md#0x4_token) diff --git a/aptos-move/framework/aptos-token-objects/doc/supra_token.md b/aptos-move/framework/aptos-token-objects/doc/supra_token.md new file mode 100644 index 0000000000000..7d491d834b299 --- /dev/null +++ b/aptos-move/framework/aptos-token-objects/doc/supra_token.md @@ -0,0 +1,1703 @@ + + + +# Module `0x4::supra_token` + +This defines a minimally viable token for no-code solutions akin to the original token at +0x3::token module. +The key features are: +* Base token and collection features +* Creator definable mutability for tokens +* Creator-based freezing of tokens +* Standard object-based transfer and events +* Metadata property type + + +- [Resource `AptosCollection`](#0x4_supra_token_AptosCollection) +- [Resource `AptosToken`](#0x4_supra_token_AptosToken) +- [Constants](#@Constants_0) +- [Function `create_collection`](#0x4_supra_token_create_collection) +- [Function `create_collection_object`](#0x4_supra_token_create_collection_object) +- [Function `mint`](#0x4_supra_token_mint) +- [Function `mint_token_object`](#0x4_supra_token_mint_token_object) +- [Function `mint_soul_bound`](#0x4_supra_token_mint_soul_bound) +- [Function `mint_soul_bound_token_object`](#0x4_supra_token_mint_soul_bound_token_object) +- [Function `mint_internal`](#0x4_supra_token_mint_internal) +- [Function `borrow`](#0x4_supra_token_borrow) +- [Function `are_properties_mutable`](#0x4_supra_token_are_properties_mutable) +- [Function `is_burnable`](#0x4_supra_token_is_burnable) +- [Function `is_freezable_by_creator`](#0x4_supra_token_is_freezable_by_creator) +- [Function `is_mutable_description`](#0x4_supra_token_is_mutable_description) +- [Function `is_mutable_name`](#0x4_supra_token_is_mutable_name) +- [Function `is_mutable_uri`](#0x4_supra_token_is_mutable_uri) +- [Function `authorized_borrow`](#0x4_supra_token_authorized_borrow) +- [Function `burn`](#0x4_supra_token_burn) +- [Function `freeze_transfer`](#0x4_supra_token_freeze_transfer) +- [Function `unfreeze_transfer`](#0x4_supra_token_unfreeze_transfer) +- [Function `set_description`](#0x4_supra_token_set_description) +- [Function `set_name`](#0x4_supra_token_set_name) +- [Function `set_uri`](#0x4_supra_token_set_uri) +- [Function `add_property`](#0x4_supra_token_add_property) +- [Function `add_typed_property`](#0x4_supra_token_add_typed_property) +- [Function `remove_property`](#0x4_supra_token_remove_property) +- [Function `update_property`](#0x4_supra_token_update_property) +- [Function `update_typed_property`](#0x4_supra_token_update_typed_property) +- [Function `collection_object`](#0x4_supra_token_collection_object) +- [Function `borrow_collection`](#0x4_supra_token_borrow_collection) +- [Function `is_mutable_collection_description`](#0x4_supra_token_is_mutable_collection_description) +- [Function `is_mutable_collection_royalty`](#0x4_supra_token_is_mutable_collection_royalty) +- [Function `is_mutable_collection_uri`](#0x4_supra_token_is_mutable_collection_uri) +- [Function `is_mutable_collection_token_description`](#0x4_supra_token_is_mutable_collection_token_description) +- [Function `is_mutable_collection_token_name`](#0x4_supra_token_is_mutable_collection_token_name) +- [Function `is_mutable_collection_token_uri`](#0x4_supra_token_is_mutable_collection_token_uri) +- [Function `is_mutable_collection_token_properties`](#0x4_supra_token_is_mutable_collection_token_properties) +- [Function `are_collection_tokens_burnable`](#0x4_supra_token_are_collection_tokens_burnable) +- [Function `are_collection_tokens_freezable`](#0x4_supra_token_are_collection_tokens_freezable) +- [Function `authorized_borrow_collection`](#0x4_supra_token_authorized_borrow_collection) +- [Function `set_collection_description`](#0x4_supra_token_set_collection_description) +- [Function `set_collection_royalties`](#0x4_supra_token_set_collection_royalties) +- [Function `set_collection_royalties_call`](#0x4_supra_token_set_collection_royalties_call) +- [Function `set_collection_uri`](#0x4_supra_token_set_collection_uri) + + +
use 0x1::error;
+use 0x1::object;
+use 0x1::option;
+use 0x1::signer;
+use 0x1::string;
+use 0x4::collection;
+use 0x4::property_map;
+use 0x4::royalty;
+use 0x4::token;
+
+ + + + + +## Resource `AptosCollection` + +Storage state for managing the no-code Collection. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct AptosCollection has key
+
+ + + +
+Fields + + +
+
+mutator_ref: option::Option<collection::MutatorRef> +
+
+ Used to mutate collection fields +
+
+royalty_mutator_ref: option::Option<royalty::MutatorRef> +
+
+ Used to mutate royalties +
+
+mutable_description: bool +
+
+ Determines if the creator can mutate the collection's description +
+
+mutable_uri: bool +
+
+ Determines if the creator can mutate the collection's uri +
+
+mutable_token_description: bool +
+
+ Determines if the creator can mutate token descriptions +
+
+mutable_token_name: bool +
+
+ Determines if the creator can mutate token names +
+
+mutable_token_properties: bool +
+
+ Determines if the creator can mutate token properties +
+
+mutable_token_uri: bool +
+
+ Determines if the creator can mutate token uris +
+
+tokens_burnable_by_creator: bool +
+
+ Determines if the creator can burn tokens +
+
+tokens_freezable_by_creator: bool +
+
+ Determines if the creator can freeze tokens +
+
+ + +
+ + + +## Resource `AptosToken` + +Storage state for managing the no-code Token. + + +
#[resource_group_member(#[group = 0x1::object::ObjectGroup])]
+struct AptosToken has key
+
+ + + +
+Fields + + +
+
+burn_ref: option::Option<token::BurnRef> +
+
+ Used to burn. +
+
+transfer_ref: option::Option<object::TransferRef> +
+
+ Used to control freeze. +
+
+mutator_ref: option::Option<token::MutatorRef> +
+
+ Used to mutate fields +
+
+property_mutator_ref: property_map::MutatorRef +
+
+ Used to mutate properties +
+
+ + +
+ + + +## Constants + + + + +The collection does not exist + + +
const ECOLLECTION_DOES_NOT_EXIST: u64 = 1;
+
+ + + + + +The field being changed is not mutable + + +
const EFIELD_NOT_MUTABLE: u64 = 4;
+
+ + + + + +The provided signer is not the creator + + +
const ENOT_CREATOR: u64 = 3;
+
+ + + + + +The token does not exist + + +
const ETOKEN_DOES_NOT_EXIST: u64 = 2;
+
+ + + + + +The property map being mutated is not mutable + + +
const EPROPERTIES_NOT_MUTABLE: u64 = 6;
+
+ + + + + +The token being burned is not burnable + + +
const ETOKEN_NOT_BURNABLE: u64 = 5;
+
+ + + + + +## Function `create_collection` + +Create a new collection + + +
public entry fun create_collection(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_token_description: bool, mutable_token_name: bool, mutable_token_properties: bool, mutable_token_uri: bool, tokens_burnable_by_creator: bool, tokens_freezable_by_creator: bool, royalty_numerator: u64, royalty_denominator: u64)
+
+ + + +
+Implementation + + +
public entry fun create_collection(
+    creator: &signer,
+    description: String,
+    max_supply: u64,
+    name: String,
+    uri: String,
+    mutable_description: bool,
+    mutable_royalty: bool,
+    mutable_uri: bool,
+    mutable_token_description: bool,
+    mutable_token_name: bool,
+    mutable_token_properties: bool,
+    mutable_token_uri: bool,
+    tokens_burnable_by_creator: bool,
+    tokens_freezable_by_creator: bool,
+    royalty_numerator: u64,
+    royalty_denominator: u64,
+) {
+    create_collection_object(
+        creator,
+        description,
+        max_supply,
+        name,
+        uri,
+        mutable_description,
+        mutable_royalty,
+        mutable_uri,
+        mutable_token_description,
+        mutable_token_name,
+        mutable_token_properties,
+        mutable_token_uri,
+        tokens_burnable_by_creator,
+        tokens_freezable_by_creator,
+        royalty_numerator,
+        royalty_denominator
+    );
+}
+
+ + + +
+ + + +## Function `create_collection_object` + + + +
public fun create_collection_object(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_token_description: bool, mutable_token_name: bool, mutable_token_properties: bool, mutable_token_uri: bool, tokens_burnable_by_creator: bool, tokens_freezable_by_creator: bool, royalty_numerator: u64, royalty_denominator: u64): object::Object<supra_token::AptosCollection>
+
+ + + +
+Implementation + + +
public fun create_collection_object(
+    creator: &signer,
+    description: String,
+    max_supply: u64,
+    name: String,
+    uri: String,
+    mutable_description: bool,
+    mutable_royalty: bool,
+    mutable_uri: bool,
+    mutable_token_description: bool,
+    mutable_token_name: bool,
+    mutable_token_properties: bool,
+    mutable_token_uri: bool,
+    tokens_burnable_by_creator: bool,
+    tokens_freezable_by_creator: bool,
+    royalty_numerator: u64,
+    royalty_denominator: u64,
+): Object<AptosCollection> {
+    let creator_addr = signer::address_of(creator);
+    let royalty = royalty::create(royalty_numerator, royalty_denominator, creator_addr);
+    let constructor_ref = collection::create_fixed_collection(
+        creator,
+        description,
+        max_supply,
+        name,
+        option::some(royalty),
+        uri,
+    );
+
+    let object_signer = object::generate_signer(&constructor_ref);
+    let mutator_ref = if (mutable_description || mutable_uri) {
+        option::some(collection::generate_mutator_ref(&constructor_ref))
+    } else {
+        option::none()
+    };
+
+    let royalty_mutator_ref = if (mutable_royalty) {
+        option::some(royalty::generate_mutator_ref(object::generate_extend_ref(&constructor_ref)))
+    } else {
+        option::none()
+    };
+
+    let aptos_collection = AptosCollection {
+        mutator_ref,
+        royalty_mutator_ref,
+        mutable_description,
+        mutable_uri,
+        mutable_token_description,
+        mutable_token_name,
+        mutable_token_properties,
+        mutable_token_uri,
+        tokens_burnable_by_creator,
+        tokens_freezable_by_creator,
+    };
+    move_to(&object_signer, aptos_collection);
+    object::object_from_constructor_ref(&constructor_ref)
+}
+
+ + + +
+ + + +## Function `mint` + +With an existing collection, directly mint a viable token into the creators account. + + +
public entry fun mint(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>)
+
+ + + +
+Implementation + + +
public entry fun mint(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+) acquires AptosCollection, AptosToken {
+    mint_token_object(creator, collection, description, name, uri, property_keys, property_types, property_values);
+}
+
+ + + +
+ + + +## Function `mint_token_object` + +Mint a token into an existing collection, and retrieve the object / address of the token. + + +
public fun mint_token_object(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>): object::Object<supra_token::AptosToken>
+
+ + + +
+Implementation + + +
public fun mint_token_object(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+): Object<AptosToken> acquires AptosCollection, AptosToken {
+    let constructor_ref = mint_internal(
+        creator,
+        collection,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+    );
+
+    let collection = collection_object(creator, &collection);
+
+    // If tokens are freezable, add a transfer ref to be able to freeze transfers
+    let freezable_by_creator = are_collection_tokens_freezable(collection);
+    if (freezable_by_creator) {
+        let aptos_token_addr = object::address_from_constructor_ref(&constructor_ref);
+        let aptos_token = borrow_global_mut<AptosToken>(aptos_token_addr);
+        let transfer_ref = object::generate_transfer_ref(&constructor_ref);
+        option::fill(&mut aptos_token.transfer_ref, transfer_ref);
+    };
+
+    object::object_from_constructor_ref(&constructor_ref)
+}
+
+ + + +
+ + + +## Function `mint_soul_bound` + +With an existing collection, directly mint a soul bound token into the recipient's account. + + +
public entry fun mint_soul_bound(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>, soul_bound_to: address)
+
+ + + +
+Implementation + + +
public entry fun mint_soul_bound(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+    soul_bound_to: address,
+) acquires AptosCollection {
+    mint_soul_bound_token_object(
+        creator,
+        collection,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+        soul_bound_to
+    );
+}
+
+ + + +
+ + + +## Function `mint_soul_bound_token_object` + +With an existing collection, directly mint a soul bound token into the recipient's account. + + +
public fun mint_soul_bound_token_object(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>, soul_bound_to: address): object::Object<supra_token::AptosToken>
+
+ + + +
+Implementation + + +
public fun mint_soul_bound_token_object(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+    soul_bound_to: address,
+): Object<AptosToken> acquires AptosCollection {
+    let constructor_ref = mint_internal(
+        creator,
+        collection,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+    );
+
+    let transfer_ref = object::generate_transfer_ref(&constructor_ref);
+    let linear_transfer_ref = object::generate_linear_transfer_ref(&transfer_ref);
+    object::transfer_with_ref(linear_transfer_ref, soul_bound_to);
+    object::disable_ungated_transfer(&transfer_ref);
+
+    object::object_from_constructor_ref(&constructor_ref)
+}
+
+ + + +
+ + + +## Function `mint_internal` + + + +
fun mint_internal(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>): object::ConstructorRef
+
+ + + +
+Implementation + + +
fun mint_internal(
+    creator: &signer,
+    collection: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: vector<String>,
+    property_types: vector<String>,
+    property_values: vector<vector<u8>>,
+): ConstructorRef acquires AptosCollection {
+    let constructor_ref = token::create(creator, collection, description, name, option::none(), uri);
+
+    let object_signer = object::generate_signer(&constructor_ref);
+
+    let collection_obj = collection_object(creator, &collection);
+    let collection = borrow_collection(&collection_obj);
+
+    let mutator_ref = if (
+        collection.mutable_token_description
+            || collection.mutable_token_name
+            || collection.mutable_token_uri
+    ) {
+        option::some(token::generate_mutator_ref(&constructor_ref))
+    } else {
+        option::none()
+    };
+
+    let burn_ref = if (collection.tokens_burnable_by_creator) {
+        option::some(token::generate_burn_ref(&constructor_ref))
+    } else {
+        option::none()
+    };
+
+    let aptos_token = AptosToken {
+        burn_ref,
+        transfer_ref: option::none(),
+        mutator_ref,
+        property_mutator_ref: property_map::generate_mutator_ref(&constructor_ref),
+    };
+    move_to(&object_signer, aptos_token);
+
+    let properties = property_map::prepare_input(property_keys, property_types, property_values);
+    property_map::init(&constructor_ref, properties);
+
+    constructor_ref
+}
+
+ + + +
+ + + +## Function `borrow` + + + +
fun borrow<T: key>(token: &object::Object<T>): &supra_token::AptosToken
+
+ + + +
+Implementation + + +
inline fun borrow<T: key>(token: &Object<T>): &AptosToken {
+    let token_address = object::object_address(token);
+    assert!(
+        exists<AptosToken>(token_address),
+        error::not_found(ETOKEN_DOES_NOT_EXIST),
+    );
+    borrow_global<AptosToken>(token_address)
+}
+
+ + + +
+ + + +## Function `are_properties_mutable` + + + +
#[view]
+public fun are_properties_mutable<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun are_properties_mutable<T: key>(token: Object<T>): bool acquires AptosCollection {
+    let collection = token::collection_object(token);
+    borrow_collection(&collection).mutable_token_properties
+}
+
+ + + +
+ + + +## Function `is_burnable` + + + +
#[view]
+public fun is_burnable<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_burnable<T: key>(token: Object<T>): bool acquires AptosToken {
+    option::is_some(&borrow(&token).burn_ref)
+}
+
+ + + +
+ + + +## Function `is_freezable_by_creator` + + + +
#[view]
+public fun is_freezable_by_creator<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_freezable_by_creator<T: key>(token: Object<T>): bool acquires AptosCollection {
+    are_collection_tokens_freezable(token::collection_object(token))
+}
+
+ + + +
+ + + +## Function `is_mutable_description` + + + +
#[view]
+public fun is_mutable_description<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_description<T: key>(token: Object<T>): bool acquires AptosCollection {
+    is_mutable_collection_token_description(token::collection_object(token))
+}
+
+ + + +
+ + + +## Function `is_mutable_name` + + + +
#[view]
+public fun is_mutable_name<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_name<T: key>(token: Object<T>): bool acquires AptosCollection {
+    is_mutable_collection_token_name(token::collection_object(token))
+}
+
+ + + +
+ + + +## Function `is_mutable_uri` + + + +
#[view]
+public fun is_mutable_uri<T: key>(token: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_uri<T: key>(token: Object<T>): bool acquires AptosCollection {
+    is_mutable_collection_token_uri(token::collection_object(token))
+}
+
+ + + +
+ + + +## Function `authorized_borrow` + + + +
fun authorized_borrow<T: key>(token: &object::Object<T>, creator: &signer): &supra_token::AptosToken
+
+ + + +
+Implementation + + +
inline fun authorized_borrow<T: key>(token: &Object<T>, creator: &signer): &AptosToken {
+    let token_address = object::object_address(token);
+    assert!(
+        exists<AptosToken>(token_address),
+        error::not_found(ETOKEN_DOES_NOT_EXIST),
+    );
+
+    assert!(
+        token::creator(*token) == signer::address_of(creator),
+        error::permission_denied(ENOT_CREATOR),
+    );
+    borrow_global<AptosToken>(token_address)
+}
+
+ + + +
+ + + +## Function `burn` + + + +
public entry fun burn<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public entry fun burn<T: key>(creator: &signer, token: Object<T>) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        option::is_some(&aptos_token.burn_ref),
+        error::permission_denied(ETOKEN_NOT_BURNABLE),
+    );
+    move aptos_token;
+    let aptos_token = move_from<AptosToken>(object::object_address(&token));
+    let AptosToken {
+        burn_ref,
+        transfer_ref: _,
+        mutator_ref: _,
+        property_mutator_ref,
+    } = aptos_token;
+    property_map::burn(property_mutator_ref);
+    token::burn(option::extract(&mut burn_ref));
+}
+
+ + + +
+ + + +## Function `freeze_transfer` + + + +
public entry fun freeze_transfer<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public entry fun freeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_collection_tokens_freezable(token::collection_object(token))
+            && option::is_some(&aptos_token.transfer_ref),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    object::disable_ungated_transfer(option::borrow(&aptos_token.transfer_ref));
+}
+
+ + + +
+ + + +## Function `unfreeze_transfer` + + + +
public entry fun unfreeze_transfer<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public entry fun unfreeze_transfer<T: key>(
+    creator: &signer,
+    token: Object<T>
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_collection_tokens_freezable(token::collection_object(token))
+            && option::is_some(&aptos_token.transfer_ref),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    object::enable_ungated_transfer(option::borrow(&aptos_token.transfer_ref));
+}
+
+ + + +
+ + + +## Function `set_description` + + + +
public entry fun set_description<T: key>(creator: &signer, token: object::Object<T>, description: string::String)
+
+ + + +
+Implementation + + +
public entry fun set_description<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    description: String,
+) acquires AptosCollection, AptosToken {
+    assert!(
+        is_mutable_description(token),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    let aptos_token = authorized_borrow(&token, creator);
+    token::set_description(option::borrow(&aptos_token.mutator_ref), description);
+}
+
+ + + +
+ + + +## Function `set_name` + + + +
public entry fun set_name<T: key>(creator: &signer, token: object::Object<T>, name: string::String)
+
+ + + +
+Implementation + + +
public entry fun set_name<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    name: String,
+) acquires AptosCollection, AptosToken {
+    assert!(
+        is_mutable_name(token),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    let aptos_token = authorized_borrow(&token, creator);
+    token::set_name(option::borrow(&aptos_token.mutator_ref), name);
+}
+
+ + + +
+ + + +## Function `set_uri` + + + +
public entry fun set_uri<T: key>(creator: &signer, token: object::Object<T>, uri: string::String)
+
+ + + +
+Implementation + + +
public entry fun set_uri<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    uri: String,
+) acquires AptosCollection, AptosToken {
+    assert!(
+        is_mutable_uri(token),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    let aptos_token = authorized_borrow(&token, creator);
+    token::set_uri(option::borrow(&aptos_token.mutator_ref), uri);
+}
+
+ + + +
+ + + +## Function `add_property` + + + +
public entry fun add_property<T: key>(creator: &signer, token: object::Object<T>, key: string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
public entry fun add_property<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_properties_mutable(token),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::add(&aptos_token.property_mutator_ref, key, type, value);
+}
+
+ + + +
+ + + +## Function `add_typed_property` + + + +
public entry fun add_typed_property<T: key, V: drop>(creator: &signer, token: object::Object<T>, key: string::String, value: V)
+
+ + + +
+Implementation + + +
public entry fun add_typed_property<T: key, V: drop>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    value: V,
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_properties_mutable(token),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::add_typed(&aptos_token.property_mutator_ref, key, value);
+}
+
+ + + +
+ + + +## Function `remove_property` + + + +
public entry fun remove_property<T: key>(creator: &signer, token: object::Object<T>, key: string::String)
+
+ + + +
+Implementation + + +
public entry fun remove_property<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_properties_mutable(token),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::remove(&aptos_token.property_mutator_ref, &key);
+}
+
+ + + +
+ + + +## Function `update_property` + + + +
public entry fun update_property<T: key>(creator: &signer, token: object::Object<T>, key: string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
public entry fun update_property<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_properties_mutable(token),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::update(&aptos_token.property_mutator_ref, &key, type, value);
+}
+
+ + + +
+ + + +## Function `update_typed_property` + + + +
public entry fun update_typed_property<T: key, V: drop>(creator: &signer, token: object::Object<T>, key: string::String, value: V)
+
+ + + +
+Implementation + + +
public entry fun update_typed_property<T: key, V: drop>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    value: V,
+) acquires AptosCollection, AptosToken {
+    let aptos_token = authorized_borrow(&token, creator);
+    assert!(
+        are_properties_mutable(token),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::update_typed(&aptos_token.property_mutator_ref, &key, value);
+}
+
+ + + +
+ + + +## Function `collection_object` + + + +
fun collection_object(creator: &signer, name: &string::String): object::Object<supra_token::AptosCollection>
+
+ + + +
+Implementation + + +
inline fun collection_object(creator: &signer, name: &String): Object<AptosCollection> {
+    let collection_addr = collection::create_collection_address(&signer::address_of(creator), name);
+    object::address_to_object<AptosCollection>(collection_addr)
+}
+
+ + + +
+ + + +## Function `borrow_collection` + + + +
fun borrow_collection<T: key>(token: &object::Object<T>): &supra_token::AptosCollection
+
+ + + +
+Implementation + + +
inline fun borrow_collection<T: key>(token: &Object<T>): &AptosCollection {
+    let collection_address = object::object_address(token);
+    assert!(
+        exists<AptosCollection>(collection_address),
+        error::not_found(ECOLLECTION_DOES_NOT_EXIST),
+    );
+    borrow_global<AptosCollection>(collection_address)
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_description` + + + +
public fun is_mutable_collection_description<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_description<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_description
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_royalty` + + + +
public fun is_mutable_collection_royalty<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_royalty<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    option::is_some(&borrow_collection(&collection).royalty_mutator_ref)
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_uri` + + + +
public fun is_mutable_collection_uri<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_uri<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_uri
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_token_description` + + + +
public fun is_mutable_collection_token_description<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_token_description<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_token_description
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_token_name` + + + +
public fun is_mutable_collection_token_name<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_token_name<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_token_name
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_token_uri` + + + +
public fun is_mutable_collection_token_uri<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_token_uri<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_token_uri
+}
+
+ + + +
+ + + +## Function `is_mutable_collection_token_properties` + + + +
public fun is_mutable_collection_token_properties<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun is_mutable_collection_token_properties<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).mutable_token_properties
+}
+
+ + + +
+ + + +## Function `are_collection_tokens_burnable` + + + +
public fun are_collection_tokens_burnable<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun are_collection_tokens_burnable<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).tokens_burnable_by_creator
+}
+
+ + + +
+ + + +## Function `are_collection_tokens_freezable` + + + +
public fun are_collection_tokens_freezable<T: key>(collection: object::Object<T>): bool
+
+ + + +
+Implementation + + +
public fun are_collection_tokens_freezable<T: key>(
+    collection: Object<T>,
+): bool acquires AptosCollection {
+    borrow_collection(&collection).tokens_freezable_by_creator
+}
+
+ + + +
+ + + +## Function `authorized_borrow_collection` + + + +
fun authorized_borrow_collection<T: key>(collection: &object::Object<T>, creator: &signer): &supra_token::AptosCollection
+
+ + + +
+Implementation + + +
inline fun authorized_borrow_collection<T: key>(collection: &Object<T>, creator: &signer): &AptosCollection {
+    let collection_address = object::object_address(collection);
+    assert!(
+        exists<AptosCollection>(collection_address),
+        error::not_found(ECOLLECTION_DOES_NOT_EXIST),
+    );
+    assert!(
+        collection::creator(*collection) == signer::address_of(creator),
+        error::permission_denied(ENOT_CREATOR),
+    );
+    borrow_global<AptosCollection>(collection_address)
+}
+
+ + + +
+ + + +## Function `set_collection_description` + + + +
public entry fun set_collection_description<T: key>(creator: &signer, collection: object::Object<T>, description: string::String)
+
+ + + +
+Implementation + + +
public entry fun set_collection_description<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    description: String,
+) acquires AptosCollection {
+    let aptos_collection = authorized_borrow_collection(&collection, creator);
+    assert!(
+        aptos_collection.mutable_description,
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    collection::set_description(option::borrow(&aptos_collection.mutator_ref), description);
+}
+
+ + + +
+ + + +## Function `set_collection_royalties` + + + +
public fun set_collection_royalties<T: key>(creator: &signer, collection: object::Object<T>, royalty: royalty::Royalty)
+
+ + + +
+Implementation + + +
public fun set_collection_royalties<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    royalty: royalty::Royalty,
+) acquires AptosCollection {
+    let aptos_collection = authorized_borrow_collection(&collection, creator);
+    assert!(
+        option::is_some(&aptos_collection.royalty_mutator_ref),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    royalty::update(option::borrow(&aptos_collection.royalty_mutator_ref), royalty);
+}
+
+ + + +
+ + + +## Function `set_collection_royalties_call` + + + +
entry fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty_numerator: u64, royalty_denominator: u64, payee_address: address)
+
+ + + +
+Implementation + + +
entry fun set_collection_royalties_call<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    royalty_numerator: u64,
+    royalty_denominator: u64,
+    payee_address: address,
+) acquires AptosCollection {
+    let royalty = royalty::create(royalty_numerator, royalty_denominator, payee_address);
+    set_collection_royalties(creator, collection, royalty);
+}
+
+ + + +
+ + + +## Function `set_collection_uri` + + + +
public entry fun set_collection_uri<T: key>(creator: &signer, collection: object::Object<T>, uri: string::String)
+
+ + + +
+Implementation + + +
public entry fun set_collection_uri<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    uri: String,
+) acquires AptosCollection {
+    let aptos_collection = authorized_borrow_collection(&collection, creator);
+    assert!(
+        aptos_collection.mutable_uri,
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    collection::set_uri(option::borrow(&aptos_collection.mutator_ref), uri);
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-token-objects/sources/aptos_token.move b/aptos-move/framework/aptos-token-objects/sources/supra_token.move similarity index 99% rename from aptos-move/framework/aptos-token-objects/sources/aptos_token.move rename to aptos-move/framework/aptos-token-objects/sources/supra_token.move index 87468a90e0943..b07f91f0b17bc 100644 --- a/aptos-move/framework/aptos-token-objects/sources/aptos_token.move +++ b/aptos-move/framework/aptos-token-objects/sources/supra_token.move @@ -6,7 +6,7 @@ /// * Creator-based freezing of tokens /// * Standard object-based transfer and events /// * Metadata property type -module aptos_token_objects::aptos_token { +module aptos_token_objects::supra_token { use std::error; use std::option::{Self, Option}; use std::string::String; diff --git a/aptos-move/framework/cached-packages/src/aptos_token_objects_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_token_objects_sdk_builder.rs index 92b35f81cebc9..0b1638be38f78 100644 --- a/aptos-move/framework/cached-packages/src/aptos_token_objects_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_token_objects_sdk_builder.rs @@ -38,7 +38,7 @@ type Bytes = Vec; #[cfg_attr(feature = "fuzzing", proptest(no_params))] pub enum EntryFunctionCall { /// Create a new collection - AptosTokenCreateCollection { + SupraTokenCreateCollection { description: Vec, max_supply: u64, name: Vec, @@ -57,7 +57,7 @@ pub enum EntryFunctionCall { }, /// With an existing collection, directly mint a viable token into the creators account. - AptosTokenMint { + SupraTokenMint { collection: Vec, description: Vec, name: Vec, @@ -68,7 +68,7 @@ pub enum EntryFunctionCall { }, /// With an existing collection, directly mint a soul bound token into the recipient's account. - AptosTokenMintSoulBound { + SupraTokenMintSoulBound { collection: Vec, description: Vec, name: Vec, @@ -85,7 +85,7 @@ impl EntryFunctionCall { pub fn encode(self) -> TransactionPayload { use EntryFunctionCall::*; match self { - AptosTokenCreateCollection { + SupraTokenCreateCollection { description, max_supply, name, @@ -101,7 +101,7 @@ impl EntryFunctionCall { tokens_freezable_by_creator, royalty_numerator, royalty_denominator, - } => aptos_token_create_collection( + } => supra_token_create_collection( description, max_supply, name, @@ -118,7 +118,7 @@ impl EntryFunctionCall { royalty_numerator, royalty_denominator, ), - AptosTokenMint { + SupraTokenMint { collection, description, name, @@ -126,7 +126,7 @@ impl EntryFunctionCall { property_keys, property_types, property_values, - } => aptos_token_mint( + } => supra_token_mint( collection, description, name, @@ -135,7 +135,7 @@ impl EntryFunctionCall { property_types, property_values, ), - AptosTokenMintSoulBound { + SupraTokenMintSoulBound { collection, description, name, @@ -144,7 +144,7 @@ impl EntryFunctionCall { property_types, property_values, soul_bound_to, - } => aptos_token_mint_soul_bound( + } => supra_token_mint_soul_bound( collection, description, name, @@ -175,7 +175,7 @@ impl EntryFunctionCall { } /// Create a new collection -pub fn aptos_token_create_collection( +pub fn supra_token_create_collection( description: Vec, max_supply: u64, name: Vec, @@ -198,7 +198,7 @@ pub fn aptos_token_create_collection( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ]), - ident_str!("aptos_token").to_owned(), + ident_str!("supra_token").to_owned(), ), ident_str!("create_collection").to_owned(), vec![], @@ -223,7 +223,7 @@ pub fn aptos_token_create_collection( } /// With an existing collection, directly mint a viable token into the creators account. -pub fn aptos_token_mint( +pub fn supra_token_mint( collection: Vec, description: Vec, name: Vec, @@ -238,7 +238,7 @@ pub fn aptos_token_mint( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ]), - ident_str!("aptos_token").to_owned(), + ident_str!("supra_token").to_owned(), ), ident_str!("mint").to_owned(), vec![], @@ -255,7 +255,7 @@ pub fn aptos_token_mint( } /// With an existing collection, directly mint a soul bound token into the recipient's account. -pub fn aptos_token_mint_soul_bound( +pub fn supra_token_mint_soul_bound( collection: Vec, description: Vec, name: Vec, @@ -271,7 +271,7 @@ pub fn aptos_token_mint_soul_bound( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ]), - ident_str!("aptos_token").to_owned(), + ident_str!("supra_token").to_owned(), ), ident_str!("mint_soul_bound").to_owned(), vec![], @@ -289,11 +289,11 @@ pub fn aptos_token_mint_soul_bound( } mod decoder { use super::*; - pub fn aptos_token_create_collection( + pub fn supra_token_create_collection( payload: &TransactionPayload, ) -> Option { if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::AptosTokenCreateCollection { + Some(EntryFunctionCall::SupraTokenCreateCollection { description: bcs::from_bytes(script.args().get(0)?).ok()?, max_supply: bcs::from_bytes(script.args().get(1)?).ok()?, name: bcs::from_bytes(script.args().get(2)?).ok()?, @@ -315,9 +315,9 @@ mod decoder { } } - pub fn aptos_token_mint(payload: &TransactionPayload) -> Option { + pub fn supra_token_mint(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::AptosTokenMint { + Some(EntryFunctionCall::SupraTokenMint { collection: bcs::from_bytes(script.args().get(0)?).ok()?, description: bcs::from_bytes(script.args().get(1)?).ok()?, name: bcs::from_bytes(script.args().get(2)?).ok()?, @@ -331,9 +331,9 @@ mod decoder { } } - pub fn aptos_token_mint_soul_bound(payload: &TransactionPayload) -> Option { + pub fn supra_token_mint_soul_bound(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::AptosTokenMintSoulBound { + Some(EntryFunctionCall::SupraTokenMintSoulBound { collection: bcs::from_bytes(script.args().get(0)?).ok()?, description: bcs::from_bytes(script.args().get(1)?).ok()?, name: bcs::from_bytes(script.args().get(2)?).ok()?, @@ -362,16 +362,16 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy, Object) { let collection_name = string::utf8(b"collection_name"); - let collection_object = aptos_token::create_collection_object( + let collection_object = supra_token::create_collection_object( seller, string::utf8(b"collection description"), 2, @@ -86,7 +86,7 @@ module marketplace::test_utils { 100, ); - let aptos_token = aptos_token::mint_token_object( + let supra_token = supra_token::mint_token_object( seller, collection_name, string::utf8(b"description"), @@ -96,7 +96,7 @@ module marketplace::test_utils { vector::empty(), vector::empty(), ); - (object::convert(collection_object), object::convert(aptos_token)) + (object::convert(collection_object), object::convert(supra_token)) } public fun mint_tokenv2_with_collection_royalty( @@ -106,7 +106,7 @@ module marketplace::test_utils { ): (Object, Object) { let collection_name = string::utf8(b"collection_name"); - let collection_object = aptos_token::create_collection_object( + let collection_object = supra_token::create_collection_object( seller, string::utf8(b"collection description"), 2, @@ -125,7 +125,7 @@ module marketplace::test_utils { royalty_denominator, ); - let aptos_token = aptos_token::mint_token_object( + let supra_token = supra_token::mint_token_object( seller, collection_name, string::utf8(b"description"), @@ -135,7 +135,7 @@ module marketplace::test_utils { vector::empty(), vector::empty(), ); - (object::convert(collection_object), object::convert(aptos_token)) + (object::convert(collection_object), object::convert(supra_token)) } public fun mint_tokenv2(seller: &signer): Object { @@ -146,7 +146,7 @@ module marketplace::test_utils { public fun mint_tokenv2_additional(seller: &signer): Object { let collection_name = string::utf8(b"collection_name"); - let aptos_token = aptos_token::mint_token_object( + let supra_token = supra_token::mint_token_object( seller, collection_name, string::utf8(b"description"), @@ -156,7 +156,7 @@ module marketplace::test_utils { vector::empty(), vector::empty(), ); - object::convert(aptos_token) + object::convert(supra_token) } public fun mint_tokenv1(seller: &signer): tokenv1::TokenId {