From e009be79074ab0d92a25fb85b6ff78ae3462fe06 Mon Sep 17 00:00:00 2001 From: David Wolinsky Date: Sat, 18 Mar 2023 15:23:30 -0700 Subject: [PATCH] [framework] move aptos-token into aptos-token-object --- .../aptos-token-objects/doc/aptos_token.md | 1809 +++++++++++++++++ .../aptos-token-objects/doc/overview.md | 1 + .../sources/aptos_token.move | 2 +- .../src/aptos_token_objects_sdk_builder.rs | 694 ++++++- 4 files changed, 2408 insertions(+), 98 deletions(-) create mode 100644 aptos-move/framework/aptos-token-objects/doc/aptos_token.md rename aptos-move/{move-examples/token_objects => framework/aptos-token-objects}/sources/aptos_token.move (99%) diff --git a/aptos-move/framework/aptos-token-objects/doc/aptos_token.md b/aptos-move/framework/aptos-token-objects/doc/aptos_token.md new file mode 100644 index 0000000000000..eb434cd319cb3 --- /dev/null +++ b/aptos-move/framework/aptos-token-objects/doc/aptos_token.md @@ -0,0 +1,1809 @@ + + + +# Module `0x4::aptos_token` + +This defines a minimally viable token for no-code solutions akin the 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_aptos_token_AptosCollection) +- [Resource `AptosToken`](#0x4_aptos_token_AptosToken) +- [Constants](#@Constants_0) +- [Function `create_collection`](#0x4_aptos_token_create_collection) +- [Function `mint`](#0x4_aptos_token_mint) +- [Function `mint_soul_bound`](#0x4_aptos_token_mint_soul_bound) +- [Function `mint_internal`](#0x4_aptos_token_mint_internal) +- [Function `are_properties_mutable`](#0x4_aptos_token_are_properties_mutable) +- [Function `is_burnable`](#0x4_aptos_token_is_burnable) +- [Function `is_freezable_by_creator`](#0x4_aptos_token_is_freezable_by_creator) +- [Function `is_mutable_description`](#0x4_aptos_token_is_mutable_description) +- [Function `is_mutable_name`](#0x4_aptos_token_is_mutable_name) +- [Function `is_mutable_uri`](#0x4_aptos_token_is_mutable_uri) +- [Function `burn`](#0x4_aptos_token_burn) +- [Function `freeze_transfer`](#0x4_aptos_token_freeze_transfer) +- [Function `unfreeze_transfer`](#0x4_aptos_token_unfreeze_transfer) +- [Function `set_description`](#0x4_aptos_token_set_description) +- [Function `set_name`](#0x4_aptos_token_set_name) +- [Function `set_uri`](#0x4_aptos_token_set_uri) +- [Function `add_property`](#0x4_aptos_token_add_property) +- [Function `add_typed_property`](#0x4_aptos_token_add_typed_property) +- [Function `remove_property`](#0x4_aptos_token_remove_property) +- [Function `update_property`](#0x4_aptos_token_update_property) +- [Function `update_typed_property`](#0x4_aptos_token_update_typed_property) +- [Function `burn_call`](#0x4_aptos_token_burn_call) +- [Function `freeze_transfer_call`](#0x4_aptos_token_freeze_transfer_call) +- [Function `unfreeze_transfer_call`](#0x4_aptos_token_unfreeze_transfer_call) +- [Function `set_description_call`](#0x4_aptos_token_set_description_call) +- [Function `set_name_call`](#0x4_aptos_token_set_name_call) +- [Function `set_uri_call`](#0x4_aptos_token_set_uri_call) +- [Function `add_property_call`](#0x4_aptos_token_add_property_call) +- [Function `add_typed_property_call`](#0x4_aptos_token_add_typed_property_call) +- [Function `remove_property_call`](#0x4_aptos_token_remove_property_call) +- [Function `update_property_call`](#0x4_aptos_token_update_property_call) +- [Function `update_typed_property_call`](#0x4_aptos_token_update_typed_property_call) +- [Function `is_mutable_collection_description`](#0x4_aptos_token_is_mutable_collection_description) +- [Function `is_mutable_collection_royalty`](#0x4_aptos_token_is_mutable_collection_royalty) +- [Function `is_mutable_collection_uri`](#0x4_aptos_token_is_mutable_collection_uri) +- [Function `is_mutable_collection_token_description`](#0x4_aptos_token_is_mutable_collection_token_description) +- [Function `is_mutable_collection_token_name`](#0x4_aptos_token_is_mutable_collection_token_name) +- [Function `is_mutable_collection_token_uri`](#0x4_aptos_token_is_mutable_collection_token_uri) +- [Function `is_mutable_collection_token_properties`](#0x4_aptos_token_is_mutable_collection_token_properties) +- [Function `are_collection_tokens_burnable`](#0x4_aptos_token_are_collection_tokens_burnable) +- [Function `are_collection_tokens_freezable`](#0x4_aptos_token_are_collection_tokens_freezable) +- [Function `set_collection_description`](#0x4_aptos_token_set_collection_description) +- [Function `set_collection_royalties`](#0x4_aptos_token_set_collection_royalties) +- [Function `set_collection_uri`](#0x4_aptos_token_set_collection_uri) +- [Function `set_collection_description_call`](#0x4_aptos_token_set_collection_description_call) +- [Function `set_collection_royalties_call`](#0x4_aptos_token_set_collection_royalties_call) +- [Function `set_collection_uri_call`](#0x4_aptos_token_set_collection_uri_call) + + +
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. + + +
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. + + +
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: option::Option<property_map::MutatorRef> +
+
+ Used to mutate properties +
+
+ + +
+ + + +## Constants + + + + + + +
const ECOLLECTION_DOES_NOT_EXIST: u64 = 1;
+
+ + + + + +Attempted to mutate an immutable field + + +
const EFIELD_NOT_MUTABLE: u64 = 3;
+
+ + + + + +The provided signer is not the creator + + +
const ENOT_CREATOR: u64 = 2;
+
+ + + + + + + +
const ETOKEN_DOES_NOT_EXIST: u64 = 1;
+
+ + + + + +Attempted to mutate a property map that is not mutable + + +
const EPROPERTIES_NOT_MUTABLE: u64 = 5;
+
+ + + + + +Attempted to burn a non-burnable token + + +
const ETOKEN_NOT_BURNABLE: u64 = 4;
+
+ + + + + +## 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,
+) {
+    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);
+}
+
+ + + +
+ + + +## 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 {
+    let constructor_ref = mint_internal(
+        creator,
+        collection,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+    );
+
+    let collection = collection_object(creator, &collection);
+    let freezable_by_creator = are_collection_tokens_freezable(collection);
+    if (!freezable_by_creator) {
+        return
+    };
+
+    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);
+}
+
+ + + +
+ + + +## 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 {
+    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);
+}
+
+ + + +
+ + + +## 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 property_mutator_ref = if (collection.mutable_token_properties) {
+        option::some(property_map::generate_mutator_ref(&constructor_ref))
+    } else {
+        option::none()
+    };
+
+    let aptos_token = AptosToken {
+        burn_ref,
+        transfer_ref: option::none(),
+        mutator_ref,
+        property_mutator_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 `are_properties_mutable` + + + +
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 AptosToken {
+    option::is_some(&borrow(&token).property_mutator_ref)
+}
+
+ + + +
+ + + +## Function `is_burnable` + + + +
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` + + + +
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` + + + +
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` + + + +
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` + + + +
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 `burn` + + + +
public fun burn<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public fun burn<T: key>(creator: &signer, token: Object<T>) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(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;
+    token::burn(option::extract(&mut burn_ref));
+}
+
+ + + +
+ + + +## Function `freeze_transfer` + + + +
public fun freeze_transfer<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public fun freeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+    assert!(
+        are_collection_tokens_freezable(token::collection_object(token)),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    object::disable_ungated_transfer(option::borrow(&aptos_token.transfer_ref));
+}
+
+ + + +
+ + + +## Function `unfreeze_transfer` + + + +
public fun unfreeze_transfer<T: key>(creator: &signer, token: object::Object<T>)
+
+ + + +
+Implementation + + +
public fun unfreeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+    assert!(
+        are_collection_tokens_freezable(token::collection_object(token)),
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    object::enable_ungated_transfer(option::borrow(&aptos_token.transfer_ref));
+}
+
+ + + +
+ + + +## Function `set_description` + + + +
public fun set_description<T: key>(creator: &signer, token: object::Object<T>, description: string::String)
+
+ + + +
+Implementation + + +
public 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, signer::address_of(creator));
+    token::set_description(option::borrow(&aptos_token.mutator_ref), description);
+}
+
+ + + +
+ + + +## Function `set_name` + + + +
public fun set_name<T: key>(creator: &signer, token: object::Object<T>, name: string::String)
+
+ + + +
+Implementation + + +
public 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, signer::address_of(creator));
+    token::set_name(option::borrow(&aptos_token.mutator_ref), name);
+}
+
+ + + +
+ + + +## Function `set_uri` + + + +
public fun set_uri<T: key>(creator: &signer, token: object::Object<T>, uri: string::String)
+
+ + + +
+Implementation + + +
public 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, signer::address_of(creator));
+    token::set_uri(option::borrow(&aptos_token.mutator_ref), uri);
+}
+
+ + + +
+ + + +## Function `add_property` + + + +
public fun add_property<T: key>(creator: &signer, token: object::Object<T>, key: string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
public fun add_property<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    assert!(
+        option::is_some(&aptos_token.property_mutator_ref),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::add(
+        option::borrow(&aptos_token.property_mutator_ref),
+        key,
+        type,
+        value,
+    );
+}
+
+ + + +
+ + + +## Function `add_typed_property` + + + +
public fun add_typed_property<T: key, V: drop>(creator: &signer, token: object::Object<T>, key: string::String, value: V)
+
+ + + +
+Implementation + + +
public fun add_typed_property<T: key, V: drop>(
+    creator: &signer,
+    token: Object<T>,
+    key: String,
+    value: V,
+) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    assert!(
+        option::is_some(&aptos_token.property_mutator_ref),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::add_typed(
+        option::borrow(&aptos_token.property_mutator_ref),
+        key,
+        value,
+    );
+}
+
+ + + +
+ + + +## Function `remove_property` + + + +
public fun remove_property<T: key>(creator: &signer, token: object::Object<T>, key: &string::String)
+
+ + + +
+Implementation + + +
public fun remove_property<T: key>(creator: &signer, token: Object<T>, key: &String) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    assert!(
+        option::is_some(&aptos_token.property_mutator_ref),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::remove(option::borrow(&aptos_token.property_mutator_ref), key);
+}
+
+ + + +
+ + + +## Function `update_property` + + + +
public fun update_property<T: key>(creator: &signer, token: object::Object<T>, key: &string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
public fun update_property<T: key>(
+    creator: &signer,
+    token: Object<T>,
+    key: &String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    assert!(
+        option::is_some(&aptos_token.property_mutator_ref),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::update(
+        option::borrow(&aptos_token.property_mutator_ref),
+        key,
+        type,
+        value,
+    );
+}
+
+ + + +
+ + + +## Function `update_typed_property` + + + +
public fun update_typed_property<T: key, V: drop>(creator: &signer, token: object::Object<T>, key: &string::String, value: V)
+
+ + + +
+Implementation + + +
public fun update_typed_property<T: key, V: drop>(
+    creator: &signer,
+    token: Object<T>,
+    key: &String,
+    value: V,
+) acquires AptosToken {
+    let aptos_token = authorized_borrow(&token, signer::address_of(creator));
+    assert!(
+        option::is_some(&aptos_token.property_mutator_ref),
+        error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+    );
+
+    property_map::update_typed(
+        option::borrow(&aptos_token.property_mutator_ref),
+        key,
+        value,
+    );
+}
+
+ + + +
+ + + +## Function `burn_call` + + + +
entry fun burn_call(creator: &signer, collection: string::String, name: string::String)
+
+ + + +
+Implementation + + +
entry fun burn_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+) acquires AptosToken {
+    burn(creator, token_object(creator, &collection, &name));
+}
+
+ + + +
+ + + +## Function `freeze_transfer_call` + + + +
entry fun freeze_transfer_call(creator: &signer, collection: string::String, name: string::String)
+
+ + + +
+Implementation + + +
entry fun freeze_transfer_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+) acquires AptosCollection, AptosToken {
+    freeze_transfer(creator, token_object(creator, &collection, &name));
+}
+
+ + + +
+ + + +## Function `unfreeze_transfer_call` + + + +
entry fun unfreeze_transfer_call(creator: &signer, collection: string::String, name: string::String)
+
+ + + +
+Implementation + + +
entry fun unfreeze_transfer_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+) acquires AptosCollection, AptosToken {
+    unfreeze_transfer(creator, token_object(creator, &collection, &name));
+}
+
+ + + +
+ + + +## Function `set_description_call` + + + +
entry fun set_description_call(creator: &signer, collection: string::String, name: string::String, description: string::String)
+
+ + + +
+Implementation + + +
entry fun set_description_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+    description: String,
+) acquires AptosCollection, AptosToken {
+    set_description(creator, token_object(creator, &collection, &name), description);
+}
+
+ + + +
+ + + +## Function `set_name_call` + + + +
entry fun set_name_call(creator: &signer, collection: string::String, original_name: string::String, new_name: string::String)
+
+ + + +
+Implementation + + +
entry fun set_name_call(
+    creator: &signer,
+    collection: String,
+    original_name: String,
+    new_name: String,
+) acquires AptosCollection, AptosToken {
+    set_name(creator, token_object(creator, &collection, &original_name), new_name);
+}
+
+ + + +
+ + + +## Function `set_uri_call` + + + +
entry fun set_uri_call(creator: &signer, collection: string::String, name: string::String, uri: string::String)
+
+ + + +
+Implementation + + +
entry fun set_uri_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+    uri: String,
+) acquires AptosCollection, AptosToken {
+    set_uri(creator, token_object(creator, &collection, &name), uri);
+}
+
+ + + +
+ + + +## Function `add_property_call` + + + +
entry fun add_property_call(creator: &signer, collection: string::String, name: string::String, key: string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
entry fun add_property_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+    key: String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosToken {
+    let token = token_object(creator, &collection, &name);
+    add_property(creator, token, key, type, value);
+}
+
+ + + +
+ + + +## Function `add_typed_property_call` + + + +
entry fun add_typed_property_call<T: drop>(creator: &signer, collection: string::String, name: string::String, key: string::String, value: T)
+
+ + + +
+Implementation + + +
entry fun add_typed_property_call<T: drop>(
+    creator: &signer,
+    collection: String,
+    name: String,
+    key: String,
+    value: T,
+) acquires AptosToken {
+    let token = token_object(creator, &collection, &name);
+    add_typed_property(creator, token, key, value);
+}
+
+ + + +
+ + + +## Function `remove_property_call` + + + +
entry fun remove_property_call(creator: &signer, collection: string::String, name: string::String, key: string::String)
+
+ + + +
+Implementation + + +
entry fun remove_property_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+    key: String,
+) acquires AptosToken {
+    let token = token_object(creator, &collection, &name);
+    remove_property(creator, token, &key);
+}
+
+ + + +
+ + + +## Function `update_property_call` + + + +
entry fun update_property_call(creator: &signer, collection: string::String, name: string::String, key: string::String, type: string::String, value: vector<u8>)
+
+ + + +
+Implementation + + +
entry fun update_property_call(
+    creator: &signer,
+    collection: String,
+    name: String,
+    key: String,
+    type: String,
+    value: vector<u8>,
+) acquires AptosToken {
+    let token = token_object(creator, &collection, &name);
+    update_property(creator, token, &key, type, value);
+}
+
+ + + +
+ + + +## Function `update_typed_property_call` + + + +
entry fun update_typed_property_call<T: drop>(creator: &signer, collection: string::String, name: string::String, key: string::String, value: T)
+
+ + + +
+Implementation + + +
entry fun update_typed_property_call<T: drop>(
+    creator: &signer,
+    collection: String,
+    name: String,
+    key: String,
+    value: T,
+) acquires AptosToken {
+    let token = token_object(creator, &collection, &name);
+    update_typed_property(creator, token, &key, value);
+}
+
+ + + +
+ + + +## 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 `set_collection_description` + + + +
public fun set_collection_description<T: key>(creator: &signer, collection: object::Object<T>, description: string::String)
+
+ + + +
+Implementation + + +
public fun set_collection_description<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    description: String,
+) acquires AptosCollection {
+    let aptos_collection = authorized_borrow_collection(&collection, signer::address_of(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, signer::address_of(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_uri` + + + +
public fun set_collection_uri<T: key>(creator: &signer, collection: object::Object<T>, uri: string::String)
+
+ + + +
+Implementation + + +
public fun set_collection_uri<T: key>(
+    creator: &signer,
+    collection: Object<T>,
+    uri: String,
+) acquires AptosCollection {
+    let aptos_collection = authorized_borrow_collection(&collection, signer::address_of(creator));
+    assert!(
+        aptos_collection.mutable_uri,
+        error::permission_denied(EFIELD_NOT_MUTABLE),
+    );
+    collection::set_uri(option::borrow(&aptos_collection.mutator_ref), uri);
+}
+
+ + + +
+ + + +## Function `set_collection_description_call` + + + +
entry fun set_collection_description_call(creator: &signer, collection: string::String, description: string::String)
+
+ + + +
+Implementation + + +
entry fun set_collection_description_call(
+    creator: &signer,
+    collection: String,
+    description: String,
+) acquires AptosCollection {
+    set_collection_description(creator, collection_object(creator, &collection), description);
+}
+
+ + + +
+ + + +## Function `set_collection_royalties_call` + + + +
entry fun set_collection_royalties_call(creator: &signer, collection: string::String, royalty_numerator: u64, royalty_denominator: u64, payee_address: address)
+
+ + + +
+Implementation + + +
entry fun set_collection_royalties_call(
+    creator: &signer,
+    collection: String,
+    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_object(creator, &collection), royalty);
+}
+
+ + + +
+ + + +## Function `set_collection_uri_call` + + + +
entry fun set_collection_uri_call(creator: &signer, collection: string::String, uri: string::String)
+
+ + + +
+Implementation + + +
entry fun set_collection_uri_call(
+    creator: &signer,
+    collection: String,
+    uri: String,
+) acquires AptosCollection {
+    set_collection_uri(creator, collection_object(creator, &collection), uri);
+}
+
+ + + +
+ + +[move-book]: https://move-language.github.io/move/introduction.html diff --git a/aptos-move/framework/aptos-token-objects/doc/overview.md b/aptos-move/framework/aptos-token-objects/doc/overview.md index e1059dfd43fc9..95871073813d9 100644 --- a/aptos-move/framework/aptos-token-objects/doc/overview.md +++ b/aptos-move/framework/aptos-token-objects/doc/overview.md @@ -12,6 +12,7 @@ This is the reference documentation of the Aptos 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) diff --git a/aptos-move/move-examples/token_objects/sources/aptos_token.move b/aptos-move/framework/aptos-token-objects/sources/aptos_token.move similarity index 99% rename from aptos-move/move-examples/token_objects/sources/aptos_token.move rename to aptos-move/framework/aptos-token-objects/sources/aptos_token.move index e70104f9e6612..5c70cc0c27504 100644 --- a/aptos-move/move-examples/token_objects/sources/aptos_token.move +++ b/aptos-move/framework/aptos-token-objects/sources/aptos_token.move @@ -6,7 +6,7 @@ /// * Creator-based freezing of tokens /// * Standard object-based transfer and events /// * Metadata property type -module token_objects::aptos_token { +module aptos_token_objects::aptos_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 f53563a36a420..6de4f579e6676 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 @@ -1,3 +1,4 @@ + // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 @@ -12,17 +13,14 @@ #![allow(dead_code)] #![allow(unused_imports)] -use aptos_types::{ - account_address::AccountAddress, - transaction::{EntryFunction, TransactionPayload}, -}; -use move_core_types::{ - ident_str, - language_storage::{ModuleId, TypeTag}, -}; +use aptos_types::account_address::{AccountAddress}; +use aptos_types::transaction::{TransactionPayload, EntryFunction}; +use move_core_types::{ident_str}; +use move_core_types::language_storage::{ModuleId, TypeTag}; type Bytes = Vec; + /// Structured representation of a call into a known Move entry function. /// ```ignore /// impl EntryFunctionCall { @@ -34,6 +32,133 @@ type Bytes = Vec; #[cfg_attr(feature = "fuzzing", derive(proptest_derive::Arbitrary))] #[cfg_attr(feature = "fuzzing", proptest(no_params))] pub enum EntryFunctionCall { + + + AptosTokenAddPropertyCall { + collection: Vec, + name: Vec, + key: Vec, + type: Vec, + value: Vec, + }, + + + AptosTokenBurnCall { + collection: Vec, + name: Vec, + }, + + /// Create a new collection + AptosTokenCreateCollection { + description: Vec, + max_supply: u64, + name: Vec, + uri: Vec, + 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, + }, + + + AptosTokenFreezeTransferCall { + collection: Vec, + name: Vec, + }, + + /// With an existing collection, directly mint a viable token into the creators account. + AptosTokenMint { + collection: Vec, + description: Vec, + name: Vec, + uri: Vec, + property_keys: Vec>, + property_types: Vec>, + property_values: Vec>, + }, + + /// With an existing collection, directly mint a soul bound token into the recipient's account. + AptosTokenMintSoulBound { + collection: Vec, + description: Vec, + name: Vec, + uri: Vec, + property_keys: Vec>, + property_types: Vec>, + property_values: Vec>, + soul_bound_to: AccountAddress, + }, + + + AptosTokenRemovePropertyCall { + collection: Vec, + name: Vec, + key: Vec, + }, + + + AptosTokenSetCollectionDescriptionCall { + collection: Vec, + description: Vec, + }, + + + AptosTokenSetCollectionRoyaltiesCall { + collection: Vec, + royalty_numerator: u64, + royalty_denominator: u64, + payee_address: AccountAddress, + }, + + + AptosTokenSetCollectionUriCall { + collection: Vec, + uri: Vec, + }, + + + AptosTokenSetDescriptionCall { + collection: Vec, + name: Vec, + description: Vec, + }, + + + AptosTokenSetNameCall { + collection: Vec, + original_name: Vec, + new_name: Vec, + }, + + + AptosTokenSetUriCall { + collection: Vec, + name: Vec, + uri: Vec, + }, + + + AptosTokenUnfreezeTransferCall { + collection: Vec, + name: Vec, + }, + + + AptosTokenUpdatePropertyCall { + collection: Vec, + name: Vec, + key: Vec, + type: Vec, + value: Vec, + }, + /// Entry function for creating a collection CollectionCreateCollection { description: Vec, @@ -47,41 +172,37 @@ pub enum EntryFunctionCall { }, } + impl EntryFunctionCall { + /// Build an Aptos `TransactionPayload` from a structured object `EntryFunctionCall`. pub fn encode(self) -> TransactionPayload { use EntryFunctionCall::*; match self { - CollectionCreateCollection { - description, - name, - uri, - max_supply, - enable_royalty, - royalty_numerator, - royalty_denominator, - royalty_payee_address, - } => collection_create_collection( - description, - name, - uri, - max_supply, - enable_royalty, - royalty_numerator, - royalty_denominator, - royalty_payee_address, - ), + AptosTokenAddPropertyCall{collection, name, key, type, value} => aptos_token_add_property_call(collection, name, key, type, value), + AptosTokenBurnCall{collection, name} => aptos_token_burn_call(collection, name), + AptosTokenCreateCollection{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} => aptos_token_create_collection(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), + AptosTokenFreezeTransferCall{collection, name} => aptos_token_freeze_transfer_call(collection, name), + AptosTokenMint{collection, description, name, uri, property_keys, property_types, property_values} => aptos_token_mint(collection, description, name, uri, property_keys, property_types, property_values), + AptosTokenMintSoulBound{collection, description, name, uri, property_keys, property_types, property_values, soul_bound_to} => aptos_token_mint_soul_bound(collection, description, name, uri, property_keys, property_types, property_values, soul_bound_to), + AptosTokenRemovePropertyCall{collection, name, key} => aptos_token_remove_property_call(collection, name, key), + AptosTokenSetCollectionDescriptionCall{collection, description} => aptos_token_set_collection_description_call(collection, description), + AptosTokenSetCollectionRoyaltiesCall{collection, royalty_numerator, royalty_denominator, payee_address} => aptos_token_set_collection_royalties_call(collection, royalty_numerator, royalty_denominator, payee_address), + AptosTokenSetCollectionUriCall{collection, uri} => aptos_token_set_collection_uri_call(collection, uri), + AptosTokenSetDescriptionCall{collection, name, description} => aptos_token_set_description_call(collection, name, description), + AptosTokenSetNameCall{collection, original_name, new_name} => aptos_token_set_name_call(collection, original_name, new_name), + AptosTokenSetUriCall{collection, name, uri} => aptos_token_set_uri_call(collection, name, uri), + AptosTokenUnfreezeTransferCall{collection, name} => aptos_token_unfreeze_transfer_call(collection, name), + AptosTokenUpdatePropertyCall{collection, name, key, type, value} => aptos_token_update_property_call(collection, name, key, type, value), + CollectionCreateCollection{description, name, uri, max_supply, enable_royalty, royalty_numerator, royalty_denominator, royalty_payee_address} => collection_create_collection(description, name, uri, max_supply, enable_royalty, royalty_numerator, royalty_denominator, royalty_payee_address), } } + /// Try to recognize an Aptos `TransactionPayload` and convert it into a structured object `EntryFunctionCall`. pub fn decode(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { - match SCRIPT_FUNCTION_DECODER_MAP.get(&format!( - "{}_{}", - script.module().name(), - script.function() - )) { + match SCRIPT_FUNCTION_DECODER_MAP.get(&format!("{}_{}", script.module().name(), script.function())) { Some(decoder) => decoder(payload), None => None, } @@ -89,76 +210,455 @@ impl EntryFunctionCall { None } } + +} + + +pub fn aptos_token_add_property_call(collection: Vec, name: Vec, key: Vec, type: Vec, value: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("add_property_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&key).unwrap(), bcs::to_bytes(&type).unwrap(), bcs::to_bytes(&value).unwrap()], + )) +} + + +pub fn aptos_token_burn_call(collection: Vec, name: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("burn_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap()], + )) +} + +/// Create a new collection +pub fn aptos_token_create_collection(description: Vec, max_supply: u64, name: Vec, uri: Vec, 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) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("create_collection").to_owned(), + vec![], + vec![bcs::to_bytes(&description).unwrap(), bcs::to_bytes(&max_supply).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&uri).unwrap(), bcs::to_bytes(&mutable_description).unwrap(), bcs::to_bytes(&mutable_royalty).unwrap(), bcs::to_bytes(&mutable_uri).unwrap(), bcs::to_bytes(&mutable_token_description).unwrap(), bcs::to_bytes(&mutable_token_name).unwrap(), bcs::to_bytes(&mutable_token_properties).unwrap(), bcs::to_bytes(&mutable_token_uri).unwrap(), bcs::to_bytes(&tokens_burnable_by_creator).unwrap(), bcs::to_bytes(&tokens_freezable_by_creator).unwrap(), bcs::to_bytes(&royalty_numerator).unwrap(), bcs::to_bytes(&royalty_denominator).unwrap()], + )) +} + + +pub fn aptos_token_freeze_transfer_call(collection: Vec, name: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("freeze_transfer_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap()], + )) +} + +/// With an existing collection, directly mint a viable token into the creators account. +pub fn aptos_token_mint(collection: Vec, description: Vec, name: Vec, uri: Vec, property_keys: Vec>, property_types: Vec>, property_values: Vec>) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("mint").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&description).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&uri).unwrap(), bcs::to_bytes(&property_keys).unwrap(), bcs::to_bytes(&property_types).unwrap(), bcs::to_bytes(&property_values).unwrap()], + )) +} + +/// With an existing collection, directly mint a soul bound token into the recipient's account. +pub fn aptos_token_mint_soul_bound(collection: Vec, description: Vec, name: Vec, uri: Vec, property_keys: Vec>, property_types: Vec>, property_values: Vec>, soul_bound_to: AccountAddress) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("mint_soul_bound").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&description).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&uri).unwrap(), bcs::to_bytes(&property_keys).unwrap(), bcs::to_bytes(&property_types).unwrap(), bcs::to_bytes(&property_values).unwrap(), bcs::to_bytes(&soul_bound_to).unwrap()], + )) +} + + +pub fn aptos_token_remove_property_call(collection: Vec, name: Vec, key: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("remove_property_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&key).unwrap()], + )) +} + + +pub fn aptos_token_set_collection_description_call(collection: Vec, description: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_collection_description_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&description).unwrap()], + )) +} + + +pub fn aptos_token_set_collection_royalties_call(collection: Vec, royalty_numerator: u64, royalty_denominator: u64, payee_address: AccountAddress) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_collection_royalties_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&royalty_numerator).unwrap(), bcs::to_bytes(&royalty_denominator).unwrap(), bcs::to_bytes(&payee_address).unwrap()], + )) +} + + +pub fn aptos_token_set_collection_uri_call(collection: Vec, uri: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_collection_uri_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&uri).unwrap()], + )) +} + + +pub fn aptos_token_set_description_call(collection: Vec, name: Vec, description: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_description_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&description).unwrap()], + )) +} + + +pub fn aptos_token_set_name_call(collection: Vec, original_name: Vec, new_name: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_name_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&original_name).unwrap(), bcs::to_bytes(&new_name).unwrap()], + )) +} + + +pub fn aptos_token_set_uri_call(collection: Vec, name: Vec, uri: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("set_uri_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&uri).unwrap()], + )) +} + + +pub fn aptos_token_unfreeze_transfer_call(collection: Vec, name: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("unfreeze_transfer_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap()], + )) +} + + +pub fn aptos_token_update_property_call(collection: Vec, name: Vec, key: Vec, type: Vec, value: Vec) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("update_property_call").to_owned(), + vec![], + vec![bcs::to_bytes(&collection).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&key).unwrap(), bcs::to_bytes(&type).unwrap(), bcs::to_bytes(&value).unwrap()], + )) } /// Entry function for creating a collection -pub fn collection_create_collection( - description: Vec, - name: Vec, - uri: Vec, - max_supply: u64, - enable_royalty: bool, - royalty_numerator: u64, - royalty_denominator: u64, - royalty_payee_address: AccountAddress, -) -> TransactionPayload { - TransactionPayload::EntryFunction(EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 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!("collection").to_owned(), - ), +pub fn collection_create_collection(description: Vec, name: Vec, uri: Vec, max_supply: u64, enable_royalty: bool, royalty_numerator: u64, royalty_denominator: u64, royalty_payee_address: AccountAddress) -> TransactionPayload { + TransactionPayload::EntryFunction(EntryFunction::new( + ModuleId::new( + AccountAddress::new([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!("collection").to_owned(), + ), ident_str!("create_collection").to_owned(), vec![], - vec![ - bcs::to_bytes(&description).unwrap(), - bcs::to_bytes(&name).unwrap(), - bcs::to_bytes(&uri).unwrap(), - bcs::to_bytes(&max_supply).unwrap(), - bcs::to_bytes(&enable_royalty).unwrap(), - bcs::to_bytes(&royalty_numerator).unwrap(), - bcs::to_bytes(&royalty_denominator).unwrap(), - bcs::to_bytes(&royalty_payee_address).unwrap(), - ], - )) -} -mod decoder { - use super::*; - pub fn collection_create_collection(payload: &TransactionPayload) -> Option { - if let TransactionPayload::EntryFunction(script) = payload { - Some(EntryFunctionCall::CollectionCreateCollection { - description: bcs::from_bytes(script.args().get(0)?).ok()?, - name: bcs::from_bytes(script.args().get(1)?).ok()?, - uri: bcs::from_bytes(script.args().get(2)?).ok()?, - max_supply: bcs::from_bytes(script.args().get(3)?).ok()?, - enable_royalty: bcs::from_bytes(script.args().get(4)?).ok()?, - royalty_numerator: bcs::from_bytes(script.args().get(5)?).ok()?, - royalty_denominator: bcs::from_bytes(script.args().get(6)?).ok()?, - royalty_payee_address: bcs::from_bytes(script.args().get(7)?).ok()?, - }) - } else { - None - } + vec![bcs::to_bytes(&description).unwrap(), bcs::to_bytes(&name).unwrap(), bcs::to_bytes(&uri).unwrap(), bcs::to_bytes(&max_supply).unwrap(), bcs::to_bytes(&enable_royalty).unwrap(), bcs::to_bytes(&royalty_numerator).unwrap(), bcs::to_bytes(&royalty_denominator).unwrap(), bcs::to_bytes(&royalty_payee_address).unwrap()], + )) +} +mod decoder { use super::*; +pub fn aptos_token_add_property_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenAddPropertyCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + key : bcs::from_bytes(script.args().get(2)?).ok()?, + type : bcs::from_bytes(script.args().get(3)?).ok()?, + value : bcs::from_bytes(script.args().get(4)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_burn_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenBurnCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_create_collection(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenCreateCollection { + 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()?, + uri : bcs::from_bytes(script.args().get(3)?).ok()?, + mutable_description : bcs::from_bytes(script.args().get(4)?).ok()?, + mutable_royalty : bcs::from_bytes(script.args().get(5)?).ok()?, + mutable_uri : bcs::from_bytes(script.args().get(6)?).ok()?, + mutable_token_description : bcs::from_bytes(script.args().get(7)?).ok()?, + mutable_token_name : bcs::from_bytes(script.args().get(8)?).ok()?, + mutable_token_properties : bcs::from_bytes(script.args().get(9)?).ok()?, + mutable_token_uri : bcs::from_bytes(script.args().get(10)?).ok()?, + tokens_burnable_by_creator : bcs::from_bytes(script.args().get(11)?).ok()?, + tokens_freezable_by_creator : bcs::from_bytes(script.args().get(12)?).ok()?, + royalty_numerator : bcs::from_bytes(script.args().get(13)?).ok()?, + royalty_denominator : bcs::from_bytes(script.args().get(14)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_freeze_transfer_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenFreezeTransferCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_mint(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenMint { + 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()?, + uri : bcs::from_bytes(script.args().get(3)?).ok()?, + property_keys : bcs::from_bytes(script.args().get(4)?).ok()?, + property_types : bcs::from_bytes(script.args().get(5)?).ok()?, + property_values : bcs::from_bytes(script.args().get(6)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_mint_soul_bound(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenMintSoulBound { + 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()?, + uri : bcs::from_bytes(script.args().get(3)?).ok()?, + property_keys : bcs::from_bytes(script.args().get(4)?).ok()?, + property_types : bcs::from_bytes(script.args().get(5)?).ok()?, + property_values : bcs::from_bytes(script.args().get(6)?).ok()?, + soul_bound_to : bcs::from_bytes(script.args().get(7)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_remove_property_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenRemovePropertyCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + key : bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None } } -type EntryFunctionDecoderMap = std::collections::HashMap< - String, - Box< - dyn Fn(&TransactionPayload) -> Option - + std::marker::Sync - + std::marker::Send, - >, ->; - -static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy = - once_cell::sync::Lazy::new(|| { - let mut map: EntryFunctionDecoderMap = std::collections::HashMap::new(); - map.insert( - "collection_create_collection".to_string(), - Box::new(decoder::collection_create_collection), - ); - map - }); +pub fn aptos_token_set_collection_description_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetCollectionDescriptionCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + description : bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_set_collection_royalties_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetCollectionRoyaltiesCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + royalty_numerator : bcs::from_bytes(script.args().get(1)?).ok()?, + royalty_denominator : bcs::from_bytes(script.args().get(2)?).ok()?, + payee_address : bcs::from_bytes(script.args().get(3)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_set_collection_uri_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetCollectionUriCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + uri : bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_set_description_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetDescriptionCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + description : bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_set_name_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetNameCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + original_name : bcs::from_bytes(script.args().get(1)?).ok()?, + new_name : bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_set_uri_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenSetUriCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + uri : bcs::from_bytes(script.args().get(2)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_unfreeze_transfer_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenUnfreezeTransferCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } +} + +pub fn aptos_token_update_property_call(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::AptosTokenUpdatePropertyCall { + collection : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + key : bcs::from_bytes(script.args().get(2)?).ok()?, + type : bcs::from_bytes(script.args().get(3)?).ok()?, + value : bcs::from_bytes(script.args().get(4)?).ok()?, + }) + } else { + None + } +} + +pub fn collection_create_collection(payload: &TransactionPayload) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::CollectionCreateCollection { + description : bcs::from_bytes(script.args().get(0)?).ok()?, + name : bcs::from_bytes(script.args().get(1)?).ok()?, + uri : bcs::from_bytes(script.args().get(2)?).ok()?, + max_supply : bcs::from_bytes(script.args().get(3)?).ok()?, + enable_royalty : bcs::from_bytes(script.args().get(4)?).ok()?, + royalty_numerator : bcs::from_bytes(script.args().get(5)?).ok()?, + royalty_denominator : bcs::from_bytes(script.args().get(6)?).ok()?, + royalty_payee_address : bcs::from_bytes(script.args().get(7)?).ok()?, + }) + } else { + None + } +} +} + +type EntryFunctionDecoderMap = std::collections::HashMap Option + std::marker::Sync + std::marker::Send>>; + +static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| { + let mut map : EntryFunctionDecoderMap = std::collections::HashMap::new(); + map.insert("aptos_token_add_property_call".to_string(), Box::new(decoder::aptos_token_add_property_call)); + map.insert("aptos_token_burn_call".to_string(), Box::new(decoder::aptos_token_burn_call)); + map.insert("aptos_token_create_collection".to_string(), Box::new(decoder::aptos_token_create_collection)); + map.insert("aptos_token_freeze_transfer_call".to_string(), Box::new(decoder::aptos_token_freeze_transfer_call)); + map.insert("aptos_token_mint".to_string(), Box::new(decoder::aptos_token_mint)); + map.insert("aptos_token_mint_soul_bound".to_string(), Box::new(decoder::aptos_token_mint_soul_bound)); + map.insert("aptos_token_remove_property_call".to_string(), Box::new(decoder::aptos_token_remove_property_call)); + map.insert("aptos_token_set_collection_description_call".to_string(), Box::new(decoder::aptos_token_set_collection_description_call)); + map.insert("aptos_token_set_collection_royalties_call".to_string(), Box::new(decoder::aptos_token_set_collection_royalties_call)); + map.insert("aptos_token_set_collection_uri_call".to_string(), Box::new(decoder::aptos_token_set_collection_uri_call)); + map.insert("aptos_token_set_description_call".to_string(), Box::new(decoder::aptos_token_set_description_call)); + map.insert("aptos_token_set_name_call".to_string(), Box::new(decoder::aptos_token_set_name_call)); + map.insert("aptos_token_set_uri_call".to_string(), Box::new(decoder::aptos_token_set_uri_call)); + map.insert("aptos_token_unfreeze_transfer_call".to_string(), Box::new(decoder::aptos_token_unfreeze_transfer_call)); + map.insert("aptos_token_update_property_call".to_string(), Box::new(decoder::aptos_token_update_property_call)); + map.insert("collection_create_collection".to_string(), Box::new(decoder::collection_create_collection)); + map +});