diff --git a/api/src/tests/objects.rs b/api/src/tests/objects.rs
index 8caae930b669d..74e589f1e5070 100644
--- a/api/src/tests/objects.rs
+++ b/api/src/tests/objects.rs
@@ -37,7 +37,7 @@ async fn test_gen_object() {
     let collection_addr = account_address::create_collection_address(user_addr, "Hero Quest!");
     let token_addr = account_address::create_token_address(user_addr, "Hero Quest!", "Wukong");
     let object_resource = "0x1::object::ObjectCore";
-    let token_resource = format!("0x{}::token::Token", user_addr);
+    let token_resource = "0x4::token::Token";
     let hero_resource = format!("0x{}::hero::Hero", user_addr);
 
     let collection0 = context.gen_all_resources(&collection_addr).await;
@@ -56,7 +56,7 @@ async fn test_gen_object() {
     let hero = context.gen_all_resources(&token_addr).await;
     let hero_map = to_object(hero);
     assert!(hero_map.contains_key(object_resource));
-    assert!(hero_map.contains_key(&token_resource));
+    assert!(hero_map.contains_key(token_resource));
     assert!(hero_map.contains_key(&hero_resource));
     let owner: AccountAddress = hero_map[object_resource]["owner"]
         .as_str()
diff --git a/aptos-move/aptos-release-builder/data/release.yaml b/aptos-move/aptos-release-builder/data/release.yaml
index cd956ac7baf75..4b0112c574ede 100644
--- a/aptos-move/aptos-release-builder/data/release.yaml
+++ b/aptos-move/aptos-release-builder/data/release.yaml
@@ -20,6 +20,7 @@ update_sequence:
         - multisig_accounts
         - delegation_pools
         - ed25519_pubkey_validate_return_false_wrong_length
+        - struct_constructors
       disabled: []
   - Consensus:
       V1:
diff --git a/aptos-move/aptos-release-builder/src/components/framework.rs b/aptos-move/aptos-release-builder/src/components/framework.rs
index e923005c08b0f..81d721d78c7e9 100644
--- a/aptos-move/aptos-release-builder/src/components/framework.rs
+++ b/aptos-move/aptos-release-builder/src/components/framework.rs
@@ -30,6 +30,7 @@ pub fn generate_upgrade_proposals(
         ("0x1", "aptos-move/framework/aptos-stdlib"),
         ("0x1", "aptos-move/framework/aptos-framework"),
         ("0x3", "aptos-move/framework/aptos-token"),
+        ("0x4", "aptos-move/framework/aptos-token-objects"),
     ];
 
     let mut result: Vec<(String, String)> = vec![];
diff --git a/aptos-move/e2e-move-tests/src/harness.rs b/aptos-move/e2e-move-tests/src/harness.rs
index 42cb2009fb2a4..c17e42f9b58c8 100644
--- a/aptos-move/e2e-move-tests/src/harness.rs
+++ b/aptos-move/e2e-move-tests/src/harness.rs
@@ -615,3 +615,18 @@ macro_rules! assert_vm_status {
         );
     }};
 }
+
+#[macro_export]
+macro_rules! assert_move_abort {
+    ($s:expr, $c:ident) => {{
+        use aptos_types::transaction::*;
+        assert!(match $s {
+            TransactionStatus::Keep(ExecutionStatus::MoveAbort {
+                location: _,
+                code: _,
+                info,
+            }) => info == $c,
+            _ => false,
+        });
+    }};
+}
diff --git a/aptos-move/e2e-move-tests/src/tests/string_args.rs b/aptos-move/e2e-move-tests/src/tests/string_args.rs
index e7d7b15177b32..0910f2cf82aec 100644
--- a/aptos-move/e2e-move-tests/src/tests/string_args.rs
+++ b/aptos-move/e2e-move-tests/src/tests/string_args.rs
@@ -1,8 +1,11 @@
 // Copyright © Aptos Foundation
 // SPDX-License-Identifier: Apache-2.0
 
-use crate::{assert_success, assert_vm_status, tests::common, MoveHarness};
-use aptos_types::account_address::AccountAddress;
+use crate::{assert_move_abort, assert_success, assert_vm_status, tests::common, MoveHarness};
+use aptos_types::{
+    account_address::AccountAddress,
+    transaction::{AbortInfo, TransactionStatus},
+};
 use move_core_types::{
     identifier::Identifier,
     language_storage::{StructTag, TypeTag},
@@ -62,11 +65,27 @@ fn success_generic(ty_args: Vec<TypeTag>, tests: Vec<(&str, Vec<(Vec<Vec<u8>>, &
     }
 }
 
-fn fail(tests: Vec<(&str, Vec<Vec<u8>>, StatusCode)>) {
+fn deserialization_failure() -> impl Fn(TransactionStatus) {
+    let status_code = StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT;
+    move |txn_status| assert_vm_status!(txn_status, status_code)
+}
+
+fn abort_info() -> impl Fn(TransactionStatus) {
+    let abort_info = Some(AbortInfo {
+        reason_name: "EINVALID_UTF8".to_string(),
+        description: "An invalid UTF8 encoding.".to_string(),
+    });
+    move |txn_status| assert_move_abort!(txn_status, abort_info)
+}
+
+fn fail(tests: Vec<(&str, Vec<Vec<u8>>, impl Fn(TransactionStatus))>) {
     fail_generic(vec![], tests)
 }
 
-fn fail_generic(ty_args: Vec<TypeTag>, tests: Vec<(&str, Vec<Vec<u8>>, StatusCode)>) {
+fn fail_generic(
+    ty_args: Vec<TypeTag>,
+    tests: Vec<(&str, Vec<Vec<u8>>, impl Fn(TransactionStatus))>,
+) {
     let mut h = MoveHarness::new();
 
     // Load the code
@@ -81,7 +100,7 @@ fn fail_generic(ty_args: Vec<TypeTag>, tests: Vec<(&str, Vec<Vec<u8>>, StatusCod
     for (entry, args, err) in tests {
         // Now send hi transaction, after that resource should exist and carry value
         let status = h.run_entry_function(&acc, str::parse(entry).unwrap(), ty_args.clone(), args);
-        assert_vm_status!(status, err);
+        err(status);
     }
 }
 
@@ -289,38 +308,22 @@ fn string_args_bad_utf8() {
 
     // simple strings
     let args = vec![bcs::to_bytes(&vec![0xF0u8, 0x28u8, 0x8Cu8, 0xBCu8]).unwrap()];
-    tests.push((
-        "0xcafe::test::hi",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::hi", args, abort_info()));
 
     let args = vec![bcs::to_bytes(&vec![0xC3u8, 0x28u8]).unwrap()];
-    tests.push((
-        "0xcafe::test::hi",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::hi", args, abort_info()));
 
     // vector of strings
     let bad = vec![0xC3u8, 0x28u8];
     let s_vec = vec![&bad[..], "hello".as_bytes(), "world".as_bytes()];
     let i = 0u64;
     let args = vec![bcs::to_bytes(&s_vec).unwrap(), bcs::to_bytes(&i).unwrap()];
-    tests.push((
-        "0xcafe::test::str_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec", args, abort_info()));
 
     let bad = vec![0xC3u8, 0x28u8];
     let s_vec = vec![&bad[..], "hello".as_bytes(), "world".as_bytes()];
     let args = vec![bcs::to_bytes(&s_vec).unwrap(), bcs::to_bytes(&i).unwrap()];
-    tests.push((
-        "0xcafe::test::str_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec", args, abort_info()));
 
     // vector of vector of strings
     let i = 0u64;
@@ -345,11 +348,7 @@ fn string_args_bad_utf8() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, abort_info()));
 
     let bad = vec![0xF0u8, 0x28u8, 0x8Cu8, 0x28u8];
     let s_vec = vec![
@@ -370,11 +369,7 @@ fn string_args_bad_utf8() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, abort_info()));
 
     let bad = vec![0x60u8, 0xFFu8];
     let s_vec = vec![
@@ -395,11 +390,7 @@ fn string_args_bad_utf8() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, abort_info()));
 
     fail(tests);
 }
@@ -421,7 +412,7 @@ fn string_args_chopped() {
         fail(vec![(
             "0xcafe::test::str_vec",
             args,
-            StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
+            deserialization_failure(),
         )]);
         i /= 2;
     }
@@ -437,20 +428,12 @@ fn string_args_bad_length() {
     // length over max size
     let mut args = bcs::to_bytes(&vec![0x30u8; 100000]).unwrap();
     args.truncate(20);
-    tests.push((
-        "0xcafe::test::hi",
-        vec![args],
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::hi", vec![args], deserialization_failure()));
 
     // length in size but input chopped
     let mut args = bcs::to_bytes(&vec![0x30u8; 30000]).unwrap();
     args.truncate(300);
-    tests.push((
-        "0xcafe::test::hi",
-        vec![args],
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::hi", vec![args], deserialization_failure()));
 
     // vector of strings
 
@@ -461,11 +444,7 @@ fn string_args_bad_length() {
     bcs_vec.truncate(200);
     let i = 0u64;
     let args = vec![bcs_vec, bcs::to_bytes(&i).unwrap()];
-    tests.push((
-        "0xcafe::test::str_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec", args, deserialization_failure()));
 
     // length over max size after 2 big-ish strings
     let bad = vec![0x30u8; 100000];
@@ -474,11 +453,7 @@ fn string_args_bad_length() {
     let mut bcs_vec = bcs::to_bytes(&s_vec).unwrap();
     bcs_vec.truncate(30000);
     let args = vec![bcs_vec, bcs::to_bytes(&i).unwrap()];
-    tests.push((
-        "0xcafe::test::str_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec", args, deserialization_failure()));
 
     // length in size but input chopped
     let big = vec![0x30u8; 10000];
@@ -486,11 +461,7 @@ fn string_args_bad_length() {
     let mut bcs_vec = bcs::to_bytes(&s_vec).unwrap();
     bcs_vec.truncate(20000);
     let args = vec![bcs_vec, bcs::to_bytes(&i).unwrap()];
-    tests.push((
-        "0xcafe::test::str_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec", args, deserialization_failure()));
 
     // vector of vector of strings
 
@@ -518,11 +489,7 @@ fn string_args_bad_length() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, deserialization_failure()));
 
     let bad = vec![0x30u8; 10000];
     let s_vec = vec![
@@ -545,11 +512,7 @@ fn string_args_bad_length() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, deserialization_failure()));
 
     let bad = vec![0x30u8; 100000];
     let s_vec = vec![
@@ -572,11 +535,7 @@ fn string_args_bad_length() {
         bcs::to_bytes(&i).unwrap(),
         bcs::to_bytes(&j).unwrap(),
     ];
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, deserialization_failure()));
 
     // length over max size with 0 length strings
     let s_vec = vec![vec!["".as_bytes(); 3]; 100000];
@@ -603,11 +562,7 @@ fn string_args_bad_length() {
         bcs::to_bytes(&j).unwrap(),
     ];
 
-    tests.push((
-        "0xcafe::test::str_vec_vec",
-        args,
-        StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT,
-    ));
+    tests.push(("0xcafe::test::str_vec_vec", args, deserialization_failure()));
 
     fail(tests);
 }
diff --git a/aptos-move/e2e-move-tests/src/tests/token_objects.rs b/aptos-move/e2e-move-tests/src/tests/token_objects.rs
index bdd7881ba089b..7899b52858797 100644
--- a/aptos-move/e2e-move-tests/src/tests/token_objects.rs
+++ b/aptos-move/e2e-move-tests/src/tests/token_objects.rs
@@ -69,7 +69,7 @@ fn test_basic_token() {
         type_params: vec![],
     };
     let token_obj_tag = StructTag {
-        address: addr,
+        address: AccountAddress::from_hex_literal("0x4").unwrap(),
         module: Identifier::new("token").unwrap(),
         name: Identifier::new("Token").unwrap(),
         type_params: vec![],
diff --git a/aptos-move/framework/aptos-token-objects/Move.toml b/aptos-move/framework/aptos-token-objects/Move.toml
new file mode 100644
index 0000000000000..c60f18f8d8f40
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/Move.toml
@@ -0,0 +1,13 @@
+[package]
+name = "AptosTokenObjects"
+version = "1.0.0"
+
+[addresses]
+std = "0x1"
+aptos_std = "0x1"
+aptos_framework = "0x1"
+aptos_token_objects = "0x4"
+
+[dependencies]
+MoveStdlib = { local = "../move-stdlib" }
+AptosFramework = { local = "../aptos-framework"}
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..f4eb9a1f870cd
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/aptos_token.md
@@ -0,0 +1,1397 @@
+
+<a name="0x4_aptos_token"></a>
+
+# 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 `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_royalties_call`](#0x4_aptos_token_set_collection_royalties_call)
+-  [Function `set_collection_uri`](#0x4_aptos_token_set_collection_uri)
+
+
+<pre><code><b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
+<b>use</b> <a href="../../aptos-framework/doc/object.md#0x1_object">0x1::object</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">0x1::signer</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">0x1::string</a>;
+<b>use</b> <a href="collection.md#0x4_collection">0x4::collection</a>;
+<b>use</b> <a href="property_map.md#0x4_property_map">0x4::property_map</a>;
+<b>use</b> <a href="royalty.md#0x4_royalty">0x4::royalty</a>;
+<b>use</b> <a href="token.md#0x4_token">0x4::token</a>;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_AptosCollection"></a>
+
+## Resource `AptosCollection`
+
+Storage state for managing the no-code Collection.
+
+
+<pre><code><b>struct</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> <b>has</b> key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>mutator_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="collection.md#0x4_collection_MutatorRef">collection::MutatorRef</a>&gt;</code>
+</dt>
+<dd>
+ Used to mutate collection fields
+</dd>
+<dt>
+<code>royalty_mutator_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_MutatorRef">royalty::MutatorRef</a>&gt;</code>
+</dt>
+<dd>
+ Used to mutate royalties
+</dd>
+<dt>
+<code>mutable_description: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate the collection's description
+</dd>
+<dt>
+<code>mutable_uri: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate the collection's uri
+</dd>
+<dt>
+<code>mutable_token_description: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate token descriptions
+</dd>
+<dt>
+<code>mutable_token_name: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate token names
+</dd>
+<dt>
+<code>mutable_token_properties: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate token properties
+</dd>
+<dt>
+<code>mutable_token_uri: bool</code>
+</dt>
+<dd>
+ Determines if the creator can mutate token uris
+</dd>
+<dt>
+<code>tokens_burnable_by_creator: bool</code>
+</dt>
+<dd>
+ Determines if the creator can burn tokens
+</dd>
+<dt>
+<code>tokens_freezable_by_creator: bool</code>
+</dt>
+<dd>
+ Determines if the creator can freeze tokens
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_aptos_token_AptosToken"></a>
+
+## Resource `AptosToken`
+
+Storage state for managing the no-code Token.
+
+
+<pre><code><b>struct</b> <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> <b>has</b> key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>burn_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="token.md#0x4_token_BurnRef">token::BurnRef</a>&gt;</code>
+</dt>
+<dd>
+ Used to burn.
+</dd>
+<dt>
+<code>transfer_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="../../aptos-framework/doc/object.md#0x1_object_TransferRef">object::TransferRef</a>&gt;</code>
+</dt>
+<dd>
+ Used to control freeze.
+</dd>
+<dt>
+<code>mutator_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="token.md#0x4_token_MutatorRef">token::MutatorRef</a>&gt;</code>
+</dt>
+<dd>
+ Used to mutate fields
+</dd>
+<dt>
+<code>property_mutator_ref: <a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a></code>
+</dt>
+<dd>
+ Used to mutate properties
+</dd>
+</dl>
+
+
+</details>
+
+<a name="@Constants_0"></a>
+
+## Constants
+
+
+<a name="0x4_aptos_token_ECOLLECTION_DOES_NOT_EXIST"></a>
+
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_ECOLLECTION_DOES_NOT_EXIST">ECOLLECTION_DOES_NOT_EXIST</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_EFIELD_NOT_MUTABLE"></a>
+
+Attempted to mutate an immutable field
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>: u64 = 3;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_ENOT_CREATOR"></a>
+
+The provided signer is not the creator
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_ENOT_CREATOR">ENOT_CREATOR</a>: u64 = 2;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_ETOKEN_DOES_NOT_EXIST"></a>
+
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_ETOKEN_DOES_NOT_EXIST">ETOKEN_DOES_NOT_EXIST</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_EPROPERTIES_NOT_MUTABLE"></a>
+
+Attempted to mutate a property map that is not mutable
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>: u64 = 5;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_ETOKEN_NOT_BURNABLE"></a>
+
+Attempted to burn a non-burnable token
+
+
+<pre><code><b>const</b> <a href="aptos_token.md#0x4_aptos_token_ETOKEN_NOT_BURNABLE">ETOKEN_NOT_BURNABLE</a>: u64 = 4;
+</code></pre>
+
+
+
+<a name="0x4_aptos_token_create_collection"></a>
+
+## Function `create_collection`
+
+Create a new collection
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_create_collection">create_collection</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, max_supply: u64, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, 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)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_create_collection">create_collection</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    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,
+) {
+    <b>let</b> creator_addr = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator);
+    <b>let</b> <a href="royalty.md#0x4_royalty">royalty</a> = <a href="royalty.md#0x4_royalty_create">royalty::create</a>(royalty_numerator, royalty_denominator, creator_addr);
+    <b>let</b> constructor_ref = <a href="collection.md#0x4_collection_create_fixed_collection">collection::create_fixed_collection</a>(
+        creator,
+        description,
+        max_supply,
+        name,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="royalty.md#0x4_royalty">royalty</a>),
+        uri,
+    );
+
+    <b>let</b> object_signer = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer">object::generate_signer</a>(&constructor_ref);
+    <b>let</b> mutator_ref = <b>if</b> (mutable_description || mutable_uri) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="collection.md#0x4_collection_generate_mutator_ref">collection::generate_mutator_ref</a>(&constructor_ref))
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    };
+
+    <b>let</b> royalty_mutator_ref = <b>if</b> (mutable_royalty) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="royalty.md#0x4_royalty_generate_mutator_ref">royalty::generate_mutator_ref</a>(<a href="../../aptos-framework/doc/object.md#0x1_object_generate_extend_ref">object::generate_extend_ref</a>(&constructor_ref)))
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    };
+
+    <b>let</b> aptos_collection = <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+        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,
+    };
+    <b>move_to</b>(&object_signer, aptos_collection);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_mint"></a>
+
+## Function `mint`
+
+With an existing collection, directly mint a viable token into the creators account.
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint">mint</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint">mint</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> constructor_ref = <a href="aptos_token.md#0x4_aptos_token_mint_internal">mint_internal</a>(
+        creator,
+        <a href="collection.md#0x4_collection">collection</a>,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+    );
+
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = collection_object(creator, &<a href="collection.md#0x4_collection">collection</a>);
+    <b>let</b> freezable_by_creator = <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>(<a href="collection.md#0x4_collection">collection</a>);
+    <b>if</b> (!freezable_by_creator) {
+        <b>return</b>
+    };
+
+    <b>let</b> aptos_token_addr = <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_constructor_ref">object::address_from_constructor_ref</a>(&constructor_ref);
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = <b>borrow_global_mut</b>&lt;<a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a>&gt;(aptos_token_addr);
+    <b>let</b> transfer_ref = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_transfer_ref">object::generate_transfer_ref</a>(&constructor_ref);
+    <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_fill">option::fill</a>(&<b>mut</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.transfer_ref, transfer_ref);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_mint_soul_bound"></a>
+
+## Function `mint_soul_bound`
+
+With an existing collection, directly mint a soul bound token into the recipient's account.
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint_soul_bound">mint_soul_bound</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;, soul_bound_to: <b>address</b>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint_soul_bound">mint_soul_bound</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;,
+    soul_bound_to: <b>address</b>,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> constructor_ref = <a href="aptos_token.md#0x4_aptos_token_mint_internal">mint_internal</a>(
+        creator,
+        <a href="collection.md#0x4_collection">collection</a>,
+        description,
+        name,
+        uri,
+        property_keys,
+        property_types,
+        property_values,
+    );
+
+    <b>let</b> transfer_ref = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_transfer_ref">object::generate_transfer_ref</a>(&constructor_ref);
+    <b>let</b> linear_transfer_ref = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_linear_transfer_ref">object::generate_linear_transfer_ref</a>(&transfer_ref);
+    <a href="../../aptos-framework/doc/object.md#0x1_object_transfer_with_ref">object::transfer_with_ref</a>(linear_transfer_ref, soul_bound_to);
+    <a href="../../aptos-framework/doc/object.md#0x1_object_disable_ungated_transfer">object::disable_ungated_transfer</a>(&transfer_ref);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_mint_internal"></a>
+
+## Function `mint_internal`
+
+
+
+<pre><code><b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint_internal">mint_internal</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;): <a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>fun</b> <a href="aptos_token.md#0x4_aptos_token_mint_internal">mint_internal</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: String,
+    description: String,
+    name: String,
+    uri: String,
+    property_keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    property_values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;,
+): ConstructorRef <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> constructor_ref = <a href="token.md#0x4_token_create">token::create</a>(
+        creator,
+        <a href="collection.md#0x4_collection">collection</a>,
+        description,
+        name,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(),
+        uri,
+    );
+
+    <b>let</b> object_signer = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer">object::generate_signer</a>(&constructor_ref);
+
+    <b>let</b> collection_obj = collection_object(creator, &<a href="collection.md#0x4_collection">collection</a>);
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = borrow_collection(&collection_obj);
+
+    <b>let</b> mutator_ref = <b>if</b> (
+        <a href="collection.md#0x4_collection">collection</a>.mutable_token_description
+        || <a href="collection.md#0x4_collection">collection</a>.mutable_token_name
+        || <a href="collection.md#0x4_collection">collection</a>.mutable_token_uri
+    ) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="token.md#0x4_token_generate_mutator_ref">token::generate_mutator_ref</a>(&constructor_ref))
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    };
+
+    <b>let</b> burn_ref = <b>if</b> (<a href="collection.md#0x4_collection">collection</a>.tokens_burnable_by_creator) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(<a href="token.md#0x4_token_generate_burn_ref">token::generate_burn_ref</a>(&constructor_ref))
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    };
+
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+        burn_ref,
+        transfer_ref: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(),
+        mutator_ref,
+        property_mutator_ref: <a href="property_map.md#0x4_property_map_generate_mutator_ref">property_map::generate_mutator_ref</a>(&constructor_ref),
+    };
+    <b>move_to</b>(&object_signer, <a href="aptos_token.md#0x4_aptos_token">aptos_token</a>);
+
+    <b>let</b> properties = <a href="property_map.md#0x4_property_map_prepare_input">property_map::prepare_input</a>(property_keys, property_types, property_values);
+    <a href="property_map.md#0x4_property_map_init">property_map::init</a>(&constructor_ref, properties);
+
+    constructor_ref
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_are_properties_mutable"></a>
+
+## Function `are_properties_mutable`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = <a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>);
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_token_properties
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_burnable"></a>
+
+## Function `is_burnable`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_burnable">is_burnable</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_burnable">is_burnable</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&borrow(&<a href="token.md#0x4_token">token</a>).burn_ref)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_freezable_by_creator"></a>
+
+## Function `is_freezable_by_creator`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_freezable_by_creator">is_freezable_by_creator</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_freezable_by_creator">is_freezable_by_creator</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_description"></a>
+
+## Function `is_mutable_description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_description">is_mutable_description</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_description">is_mutable_description</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_description">is_mutable_collection_token_description</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_name"></a>
+
+## Function `is_mutable_name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_name">is_mutable_name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_name">is_mutable_name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_name">is_mutable_collection_token_name</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_uri"></a>
+
+## Function `is_mutable_uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_uri">is_mutable_uri</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_uri">is_mutable_uri</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_uri">is_mutable_collection_token_uri</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_burn"></a>
+
+## Function `burn`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_burn">burn</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_burn">burn</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.burn_ref),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_ETOKEN_NOT_BURNABLE">ETOKEN_NOT_BURNABLE</a>),
+    );
+    <b>move</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a>;
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = <b>move_from</b>&lt;<a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(&<a href="token.md#0x4_token">token</a>));
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+        burn_ref,
+        transfer_ref: _,
+        mutator_ref: _,
+        property_mutator_ref,
+    } = <a href="aptos_token.md#0x4_aptos_token">aptos_token</a>;
+    <a href="property_map.md#0x4_property_map_burn">property_map::burn</a>(property_mutator_ref);
+    <a href="token.md#0x4_token_burn">token::burn</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_extract">option::extract</a>(&<b>mut</b> burn_ref));
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_freeze_transfer"></a>
+
+## Function `freeze_transfer`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_freeze_transfer">freeze_transfer</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_freeze_transfer">freeze_transfer</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+            && <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.transfer_ref),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <a href="../../aptos-framework/doc/object.md#0x1_object_disable_ungated_transfer">object::disable_ungated_transfer</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.transfer_ref));
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_unfreeze_transfer"></a>
+
+## Function `unfreeze_transfer`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_unfreeze_transfer">unfreeze_transfer</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_unfreeze_transfer">unfreeze_transfer</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>(<a href="token.md#0x4_token_collection_object">token::collection_object</a>(<a href="token.md#0x4_token">token</a>))
+            && <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.transfer_ref),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <a href="../../aptos-framework/doc/object.md#0x1_object_enable_ungated_transfer">object::enable_ungated_transfer</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.transfer_ref));
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_description"></a>
+
+## Function `set_description`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_description">set_description</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_description">set_description</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    description: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_is_mutable_description">is_mutable_description</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <a href="token.md#0x4_token_set_description">token::set_description</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.mutator_ref), description);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_name"></a>
+
+## Function `set_name`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_name">set_name</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_name">set_name</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    name: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_is_mutable_name">is_mutable_name</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <a href="token.md#0x4_token_set_name">token::set_name</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.mutator_ref), name);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_uri"></a>
+
+## Function `set_uri`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_uri">set_uri</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_uri">set_uri</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    uri: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_is_mutable_uri">is_mutable_uri</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <a href="token.md#0x4_token_set_uri">token::set_uri</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.mutator_ref), uri);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_add_property"></a>
+
+## Function `add_property`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_add_property">add_property</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_add_property">add_property</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    key: String,
+    type: String,
+    value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>),
+    );
+
+    <a href="property_map.md#0x4_property_map_add">property_map::add</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.property_mutator_ref, key, type, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_add_typed_property"></a>
+
+## Function `add_typed_property`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_add_typed_property">add_typed_property</a>&lt;T: key, V: drop&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: V)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_add_typed_property">add_typed_property</a>&lt;T: key, V: drop&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    key: String,
+    value: V,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>),
+    );
+
+    <a href="property_map.md#0x4_property_map_add_typed">property_map::add_typed</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.property_mutator_ref, key, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_remove_property"></a>
+
+## Function `remove_property`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_remove_property">remove_property</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_remove_property">remove_property</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    key: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>),
+    );
+
+    <a href="property_map.md#0x4_property_map_remove">property_map::remove</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.property_mutator_ref, &key);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_update_property"></a>
+
+## Function `update_property`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_update_property">update_property</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_update_property">update_property</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    key: String,
+    type: String,
+    value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>),
+    );
+
+    <a href="property_map.md#0x4_property_map_update">property_map::update</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.property_mutator_ref, &key, type, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_update_typed_property"></a>
+
+## Function `update_typed_property`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_update_typed_property">update_typed_property</a>&lt;T: key, V: drop&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: V)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_update_typed_property">update_typed_property</a>&lt;T: key, V: drop&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="token.md#0x4_token">token</a>: Object&lt;T&gt;,
+    key: String,
+    value: V,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a>, <a href="aptos_token.md#0x4_aptos_token_AptosToken">AptosToken</a> {
+    <b>let</b> <a href="aptos_token.md#0x4_aptos_token">aptos_token</a> = authorized_borrow(&<a href="token.md#0x4_token">token</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="aptos_token.md#0x4_aptos_token_are_properties_mutable">are_properties_mutable</a>(<a href="token.md#0x4_token">token</a>),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EPROPERTIES_NOT_MUTABLE">EPROPERTIES_NOT_MUTABLE</a>),
+    );
+
+    <a href="property_map.md#0x4_property_map_update_typed">property_map::update_typed</a>(&<a href="aptos_token.md#0x4_aptos_token">aptos_token</a>.property_mutator_ref, &key, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_description"></a>
+
+## Function `is_mutable_collection_description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_description">is_mutable_collection_description</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_description">is_mutable_collection_description</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_description
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_royalty"></a>
+
+## Function `is_mutable_collection_royalty`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_royalty">is_mutable_collection_royalty</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_royalty">is_mutable_collection_royalty</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).royalty_mutator_ref)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_uri"></a>
+
+## Function `is_mutable_collection_uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_uri">is_mutable_collection_uri</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_uri">is_mutable_collection_uri</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_uri
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_token_description"></a>
+
+## Function `is_mutable_collection_token_description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_description">is_mutable_collection_token_description</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_description">is_mutable_collection_token_description</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_token_description
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_token_name"></a>
+
+## Function `is_mutable_collection_token_name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_name">is_mutable_collection_token_name</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_name">is_mutable_collection_token_name</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_token_name
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_token_uri"></a>
+
+## Function `is_mutable_collection_token_uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_uri">is_mutable_collection_token_uri</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_uri">is_mutable_collection_token_uri</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_token_uri
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_is_mutable_collection_token_properties"></a>
+
+## Function `is_mutable_collection_token_properties`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_properties">is_mutable_collection_token_properties</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_is_mutable_collection_token_properties">is_mutable_collection_token_properties</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).mutable_token_properties
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_are_collection_tokens_burnable"></a>
+
+## Function `are_collection_tokens_burnable`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_burnable">are_collection_tokens_burnable</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_burnable">are_collection_tokens_burnable</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).tokens_burnable_by_creator
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_are_collection_tokens_freezable"></a>
+
+## Function `are_collection_tokens_freezable`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_are_collection_tokens_freezable">are_collection_tokens_freezable</a>&lt;T: key&gt;(
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+): bool <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    borrow_collection(&<a href="collection.md#0x4_collection">collection</a>).tokens_freezable_by_creator
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_collection_description"></a>
+
+## Function `set_collection_description`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_description">set_collection_description</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_description">set_collection_description</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+    description: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> aptos_collection = authorized_borrow_collection(&<a href="collection.md#0x4_collection">collection</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        aptos_collection.mutable_description,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <a href="collection.md#0x4_collection_set_description">collection::set_description</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&aptos_collection.mutator_ref), description);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_collection_royalties"></a>
+
+## Function `set_collection_royalties`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_royalties">set_collection_royalties</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_royalties">set_collection_royalties</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+    <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> aptos_collection = authorized_borrow_collection(&<a href="collection.md#0x4_collection">collection</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&aptos_collection.royalty_mutator_ref),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <a href="royalty.md#0x4_royalty_update">royalty::update</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&aptos_collection.royalty_mutator_ref), <a href="royalty.md#0x4_royalty">royalty</a>);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_collection_royalties_call"></a>
+
+## Function `set_collection_royalties_call`
+
+
+
+<pre><code>entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_royalties_call">set_collection_royalties_call</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, royalty_numerator: u64, royalty_denominator: u64, payee_address: <b>address</b>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code>entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_royalties_call">set_collection_royalties_call</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+    royalty_numerator: u64,
+    royalty_denominator: u64,
+    payee_address: <b>address</b>,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> <a href="royalty.md#0x4_royalty">royalty</a> = <a href="royalty.md#0x4_royalty_create">royalty::create</a>(royalty_numerator, royalty_denominator, payee_address);
+    <a href="aptos_token.md#0x4_aptos_token_set_collection_royalties">set_collection_royalties</a>(creator, <a href="collection.md#0x4_collection">collection</a>, <a href="royalty.md#0x4_royalty">royalty</a>);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_aptos_token_set_collection_uri"></a>
+
+## Function `set_collection_uri`
+
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_uri">set_collection_uri</a>&lt;T: key&gt;(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> entry <b>fun</b> <a href="aptos_token.md#0x4_aptos_token_set_collection_uri">set_collection_uri</a>&lt;T: key&gt;(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    <a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;,
+    uri: String,
+) <b>acquires</b> <a href="aptos_token.md#0x4_aptos_token_AptosCollection">AptosCollection</a> {
+    <b>let</b> aptos_collection = authorized_borrow_collection(&<a href="collection.md#0x4_collection">collection</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator));
+    <b>assert</b>!(
+        aptos_collection.mutable_uri,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="aptos_token.md#0x4_aptos_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>),
+    );
+    <a href="collection.md#0x4_collection_set_uri">collection::set_uri</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&aptos_collection.mutator_ref), uri);
+}
+</code></pre>
+
+
+
+</details>
+
+
+[move-book]: https://move-language.github.io/move/introduction.html
diff --git a/aptos-move/framework/aptos-token-objects/doc/collection.md b/aptos-move/framework/aptos-token-objects/doc/collection.md
new file mode 100644
index 0000000000000..dbe52641b6cd7
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/collection.md
@@ -0,0 +1,658 @@
+
+<a name="0x4_collection"></a>
+
+# Module `0x4::collection`
+
+This defines an object-based Collection. A collection acts as a set organizer for a group of
+tokens. This includes aspects such as a general description, project URI, name, and may contain
+other useful generalizations across this set of tokens.
+
+Being built upon objects enables collections to be relatively flexible. As core primitives it
+supports:
+* Common fields: name, uri, description, creator
+* MutatorRef leaving mutability configuration to a higher level component
+* Addressed by a global identifier of creator's address and collection name, thus collections
+cannot be deleted as a restriction of the object model.
+* Optional support for collection-wide royalties
+* Optional support for tracking of supply
+
+This collection does not directly support:
+* Events on mint or burn -- that's left to the collection creator.
+
+TODO:
+* Consider supporting changing the name of the collection with the MutatorRef. This would
+require adding the field original_name.
+* Consider supporting changing the aspects of supply with the MutatorRef.
+* Add aggregator support when added to framework
+* Update Object<T> to be viable input as a transaction arg and then update all readers as view.
+
+
+-  [Resource `Collection`](#0x4_collection_Collection)
+-  [Struct `MutatorRef`](#0x4_collection_MutatorRef)
+-  [Struct `MutationEvent`](#0x4_collection_MutationEvent)
+-  [Resource `FixedSupply`](#0x4_collection_FixedSupply)
+-  [Constants](#@Constants_0)
+-  [Function `create_fixed_collection`](#0x4_collection_create_fixed_collection)
+-  [Function `create_untracked_collection`](#0x4_collection_create_untracked_collection)
+-  [Function `create_collection_address`](#0x4_collection_create_collection_address)
+-  [Function `create_collection_seed`](#0x4_collection_create_collection_seed)
+-  [Function `increment_supply`](#0x4_collection_increment_supply)
+-  [Function `decrement_supply`](#0x4_collection_decrement_supply)
+-  [Function `generate_mutator_ref`](#0x4_collection_generate_mutator_ref)
+-  [Function `count`](#0x4_collection_count)
+-  [Function `creator`](#0x4_collection_creator)
+-  [Function `description`](#0x4_collection_description)
+-  [Function `name`](#0x4_collection_name)
+-  [Function `uri`](#0x4_collection_uri)
+-  [Function `set_description`](#0x4_collection_set_description)
+-  [Function `set_uri`](#0x4_collection_set_uri)
+
+
+<pre><code><b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
+<b>use</b> <a href="../../aptos-framework/doc/event.md#0x1_event">0x1::event</a>;
+<b>use</b> <a href="../../aptos-framework/doc/object.md#0x1_object">0x1::object</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">0x1::signer</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">0x1::string</a>;
+<b>use</b> <a href="royalty.md#0x4_royalty">0x4::royalty</a>;
+</code></pre>
+
+
+
+<a name="0x4_collection_Collection"></a>
+
+## Resource `Collection`
+
+Represents the common fields for a collection.
+
+
+<pre><code><b>struct</b> <a href="collection.md#0x4_collection_Collection">Collection</a> <b>has</b> key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>creator: <b>address</b></code>
+</dt>
+<dd>
+ The creator of this collection.
+</dd>
+<dt>
+<code>description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ A brief description of the collection.
+</dd>
+<dt>
+<code>name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ An optional categorization of similar token.
+</dd>
+<dt>
+<code>uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ The Uniform Resource Identifier (uri) pointing to the JSON file stored in off-chain
+ storage; the URL length will likely need a maximum any suggestions?
+</dd>
+<dt>
+<code>mutation_events: <a href="../../aptos-framework/doc/event.md#0x1_event_EventHandle">event::EventHandle</a>&lt;<a href="collection.md#0x4_collection_MutationEvent">collection::MutationEvent</a>&gt;</code>
+</dt>
+<dd>
+ Emitted upon any mutation of the collection.
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_collection_MutatorRef"></a>
+
+## Struct `MutatorRef`
+
+This enables mutating description and URI by higher level services.
+
+
+<pre><code><b>struct</b> <a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>self: <b>address</b></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_collection_MutationEvent"></a>
+
+## Struct `MutationEvent`
+
+Contains the mutated fields name. This makes the life of indexers easier, so that they can
+directly understand the behavior in a writeset.
+
+
+<pre><code><b>struct</b> <a href="collection.md#0x4_collection_MutationEvent">MutationEvent</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_collection_FixedSupply"></a>
+
+## Resource `FixedSupply`
+
+Fixed supply tracker, this is useful for ensuring that a limited number of tokens are minted.
+
+
+<pre><code><b>struct</b> <a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a> <b>has</b> key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>current_supply: u64</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>max_supply: u64</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>total_minted: u64</code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="@Constants_0"></a>
+
+## Constants
+
+
+<a name="0x4_collection_ECOLLECTION_DOES_NOT_EXIST"></a>
+
+The collection does not exist
+
+
+<pre><code><b>const</b> <a href="collection.md#0x4_collection_ECOLLECTION_DOES_NOT_EXIST">ECOLLECTION_DOES_NOT_EXIST</a>: u64 = 2;
+</code></pre>
+
+
+
+<a name="0x4_collection_EEXCEEDS_MAX_SUPPLY"></a>
+
+The collections supply is at its maximum amount
+
+
+<pre><code><b>const</b> <a href="collection.md#0x4_collection_EEXCEEDS_MAX_SUPPLY">EEXCEEDS_MAX_SUPPLY</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_collection_create_fixed_collection"></a>
+
+## Function `create_fixed_collection`
+
+Creates a fixed-sized collection, or a collection that supports a fixed amount of tokens.
+This is useful to create a guaranteed, limited supply on-chain digital asset. For example,
+a collection 1111 vicious vipers. Note, creating restrictions such as upward limits results
+in data structures that prevent Aptos from parallelizing mints of this collection type.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_fixed_collection">create_fixed_collection</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, max_supply: u64, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>&gt;, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_fixed_collection">create_fixed_collection</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    description: String,
+    max_supply: u64,
+    name: String,
+    <a href="royalty.md#0x4_royalty">royalty</a>: Option&lt;Royalty&gt;,
+    uri: String,
+): ConstructorRef {
+    <b>let</b> supply = <a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a> {
+        current_supply: 0,
+        max_supply,
+        total_minted: 0,
+    };
+
+    create_collection_internal(
+        creator,
+        description,
+        name,
+        <a href="royalty.md#0x4_royalty">royalty</a>,
+        uri,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(supply),
+    )
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_create_untracked_collection"></a>
+
+## Function `create_untracked_collection`
+
+Creates an untracked collection, or a collection that supports an arbitrary amount of
+tokens. This is useful for mass airdrops that fully leverage Aptos parallelization.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_untracked_collection">create_untracked_collection</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>&gt;, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_untracked_collection">create_untracked_collection</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    description: String,
+    name: String,
+    <a href="royalty.md#0x4_royalty">royalty</a>: Option&lt;Royalty&gt;,
+    uri: String,
+): ConstructorRef {
+    create_collection_internal&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(
+        creator,
+        description,
+        name,
+        <a href="royalty.md#0x4_royalty">royalty</a>,
+        uri,
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(),
+    )
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_create_collection_address"></a>
+
+## Function `create_collection_address`
+
+Generates the collections address based upon the creators address and the collection's name
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_collection_address">create_collection_address</a>(creator: &<b>address</b>, name: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_collection_address">create_collection_address</a>(creator: &<b>address</b>, name: &String): <b>address</b> {
+    <a href="../../aptos-framework/doc/object.md#0x1_object_create_object_address">object::create_object_address</a>(creator, <a href="collection.md#0x4_collection_create_collection_seed">create_collection_seed</a>(name))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_create_collection_seed"></a>
+
+## Function `create_collection_seed`
+
+Named objects are derived from a seed, the collection's seed is its name.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_collection_seed">create_collection_seed</a>(name: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_create_collection_seed">create_collection_seed</a>(name: &String): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
+    *<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_bytes">string::bytes</a>(name)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_increment_supply"></a>
+
+## Function `increment_supply`
+
+Called by token on mint to increment supply if there's an appropriate Supply struct.
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="collection.md#0x4_collection_increment_supply">increment_supply</a>(<a href="collection.md#0x4_collection">collection</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;<a href="collection.md#0x4_collection_Collection">collection::Collection</a>&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="collection.md#0x4_collection_increment_supply">increment_supply</a>(
+    <a href="collection.md#0x4_collection">collection</a>: &Object&lt;<a href="collection.md#0x4_collection_Collection">Collection</a>&gt;,
+): Option&lt;u64&gt; <b>acquires</b> <a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a> {
+    <b>let</b> collection_addr = <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="collection.md#0x4_collection">collection</a>);
+    <b>if</b> (<b>exists</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_addr)) {
+        <b>let</b> supply = <b>borrow_global_mut</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_addr);
+        supply.current_supply = supply.current_supply + 1;
+        supply.total_minted = supply.total_minted + 1;
+        <b>assert</b>!(
+            supply.current_supply &lt;= supply.max_supply,
+            <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="collection.md#0x4_collection_EEXCEEDS_MAX_SUPPLY">EEXCEEDS_MAX_SUPPLY</a>),
+        );
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(supply.total_minted)
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_decrement_supply"></a>
+
+## Function `decrement_supply`
+
+Called by token on burn to decrement supply if there's an appropriate Supply struct.
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="collection.md#0x4_collection_decrement_supply">decrement_supply</a>(<a href="collection.md#0x4_collection">collection</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;<a href="collection.md#0x4_collection_Collection">collection::Collection</a>&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="collection.md#0x4_collection_decrement_supply">decrement_supply</a>(<a href="collection.md#0x4_collection">collection</a>: &Object&lt;<a href="collection.md#0x4_collection_Collection">Collection</a>&gt;) <b>acquires</b> <a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a> {
+    <b>let</b> collection_addr = <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="collection.md#0x4_collection">collection</a>);
+    <b>if</b> (<b>exists</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_addr)) {
+        <b>let</b> supply = <b>borrow_global_mut</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_addr);
+        supply.current_supply = supply.current_supply - 1;
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_generate_mutator_ref"></a>
+
+## Function `generate_mutator_ref`
+
+Creates a MutatorRef, which gates the ability to mutate any fields that support mutation.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_generate_mutator_ref">generate_mutator_ref</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>): <a href="collection.md#0x4_collection_MutatorRef">collection::MutatorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_generate_mutator_ref">generate_mutator_ref</a>(ref: &ConstructorRef): <a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a> {
+    <b>let</b> <a href="../../aptos-framework/doc/object.md#0x1_object">object</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_object_from_constructor_ref">object::object_from_constructor_ref</a>&lt;<a href="collection.md#0x4_collection_Collection">Collection</a>&gt;(ref);
+    <a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a> { self: <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(&<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>) }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_count"></a>
+
+## Function `count`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_count">count</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;u64&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_count">count</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;): Option&lt;u64&gt; <b>acquires</b> <a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a> {
+    <b>let</b> collection_address = <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(&<a href="collection.md#0x4_collection">collection</a>);
+    <b>assert</b>!(
+        <b>exists</b>&lt;<a href="collection.md#0x4_collection_Collection">Collection</a>&gt;(collection_address),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="collection.md#0x4_collection_ECOLLECTION_DOES_NOT_EXIST">ECOLLECTION_DOES_NOT_EXIST</a>),
+    );
+
+    <b>if</b> (<b>exists</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_address)) {
+        <b>let</b> supply = <b>borrow_global_mut</b>&lt;<a href="collection.md#0x4_collection_FixedSupply">FixedSupply</a>&gt;(collection_address);
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(supply.current_supply)
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_creator"></a>
+
+## Function `creator`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_creator">creator</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_creator">creator</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;): <b>address</b> <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    borrow(&<a href="collection.md#0x4_collection">collection</a>).creator
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_description"></a>
+
+## Function `description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_description">description</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_description">description</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    borrow(&<a href="collection.md#0x4_collection">collection</a>).description
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_name"></a>
+
+## Function `name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_name">name</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_name">name</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    borrow(&<a href="collection.md#0x4_collection">collection</a>).name
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_uri"></a>
+
+## Function `uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_uri">uri</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_uri">uri</a>&lt;T: key&gt;(<a href="collection.md#0x4_collection">collection</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    borrow(&<a href="collection.md#0x4_collection">collection</a>).uri
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_set_description"></a>
+
+## Function `set_description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_description">set_description</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">collection::MutatorRef</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_description">set_description</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a>, description: String) <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = borrow_mut(mutator_ref);
+    <a href="collection.md#0x4_collection">collection</a>.description = description;
+    <a href="../../aptos-framework/doc/event.md#0x1_event_emit_event">event::emit_event</a>(
+        &<b>mut</b> <a href="collection.md#0x4_collection">collection</a>.mutation_events,
+        <a href="collection.md#0x4_collection_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_utf8">string::utf8</a>(b"description") },
+    );
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_collection_set_uri"></a>
+
+## Function `set_uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_uri">set_uri</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">collection::MutatorRef</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection_set_uri">set_uri</a>(mutator_ref: &<a href="collection.md#0x4_collection_MutatorRef">MutatorRef</a>, uri: String) <b>acquires</b> <a href="collection.md#0x4_collection_Collection">Collection</a> {
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = borrow_mut(mutator_ref);
+    <a href="collection.md#0x4_collection">collection</a>.uri = uri;
+    <a href="../../aptos-framework/doc/event.md#0x1_event_emit_event">event::emit_event</a>(
+        &<b>mut</b> <a href="collection.md#0x4_collection">collection</a>.mutation_events,
+        <a href="collection.md#0x4_collection_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_utf8">string::utf8</a>(b"uri") },
+    );
+}
+</code></pre>
+
+
+
+</details>
+
+
+[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
new file mode 100644
index 0000000000000..95871073813d9
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/overview.md
@@ -0,0 +1,22 @@
+
+<a name="@Aptos_Token_Framework_0"></a>
+
+# Aptos Token Framework
+
+
+This is the reference documentation of the Aptos Token Objects framework.
+
+
+<a name="@Index_1"></a>
+
+## 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::token`](token.md#0x4_token)
+
+
+[move-book]: https://move-language.github.io/move/introduction.html
diff --git a/aptos-move/framework/aptos-token-objects/doc/property_map.md b/aptos-move/framework/aptos-token-objects/doc/property_map.md
new file mode 100644
index 0000000000000..8ab1b5390cb44
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/property_map.md
@@ -0,0 +1,978 @@
+
+<a name="0x4_property_map"></a>
+
+# Module `0x4::property_map`
+
+PropertyMap provides generic metadata support for AptosToken. It is a  specialization of
+SimpleMap that enforces strict typing with minimal storage use by using constant u64 to
+represent types and storing values in bcs format.
+
+
+-  [Resource `PropertyMap`](#0x4_property_map_PropertyMap)
+-  [Struct `PropertyValue`](#0x4_property_map_PropertyValue)
+-  [Struct `MutatorRef`](#0x4_property_map_MutatorRef)
+-  [Constants](#@Constants_0)
+-  [Function `init`](#0x4_property_map_init)
+-  [Function `burn`](#0x4_property_map_burn)
+-  [Function `prepare_input`](#0x4_property_map_prepare_input)
+-  [Function `generate_mutator_ref`](#0x4_property_map_generate_mutator_ref)
+-  [Function `contains_key`](#0x4_property_map_contains_key)
+-  [Function `length`](#0x4_property_map_length)
+-  [Function `read`](#0x4_property_map_read)
+-  [Function `read_bool`](#0x4_property_map_read_bool)
+-  [Function `read_u8`](#0x4_property_map_read_u8)
+-  [Function `read_u16`](#0x4_property_map_read_u16)
+-  [Function `read_u32`](#0x4_property_map_read_u32)
+-  [Function `read_u64`](#0x4_property_map_read_u64)
+-  [Function `read_u128`](#0x4_property_map_read_u128)
+-  [Function `read_u256`](#0x4_property_map_read_u256)
+-  [Function `read_address`](#0x4_property_map_read_address)
+-  [Function `read_bytes`](#0x4_property_map_read_bytes)
+-  [Function `read_string`](#0x4_property_map_read_string)
+-  [Function `add`](#0x4_property_map_add)
+-  [Function `add_typed`](#0x4_property_map_add_typed)
+-  [Function `add_internal`](#0x4_property_map_add_internal)
+-  [Function `update`](#0x4_property_map_update)
+-  [Function `update_typed`](#0x4_property_map_update_typed)
+-  [Function `update_internal`](#0x4_property_map_update_internal)
+-  [Function `remove`](#0x4_property_map_remove)
+
+
+<pre><code><b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/bcs.md#0x1_bcs">0x1::bcs</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs">0x1::from_bcs</a>;
+<b>use</b> <a href="../../aptos-framework/doc/object.md#0x1_object">0x1::object</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map">0x1::simple_map</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">0x1::string</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/doc/type_info.md#0x1_type_info">0x1::type_info</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">0x1::vector</a>;
+</code></pre>
+
+
+
+<a name="0x4_property_map_PropertyMap"></a>
+
+## Resource `PropertyMap`
+
+
+
+<pre><code><b>struct</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> <b>has</b> drop, key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>inner: <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_SimpleMap">simple_map::SimpleMap</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, <a href="property_map.md#0x4_property_map_PropertyValue">property_map::PropertyValue</a>&gt;</code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_property_map_PropertyValue"></a>
+
+## Struct `PropertyValue`
+
+
+
+<pre><code><b>struct</b> <a href="property_map.md#0x4_property_map_PropertyValue">PropertyValue</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>type: u8</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;</code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_property_map_MutatorRef"></a>
+
+## Struct `MutatorRef`
+
+
+
+<pre><code><b>struct</b> <a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>self: <b>address</b></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="@Constants_0"></a>
+
+## Constants
+
+
+<a name="0x4_property_map_ETYPE_MISMATCH"></a>
+
+Property type does not match
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_ETYPE_MISMATCH">ETYPE_MISMATCH</a>: u64 = 5;
+</code></pre>
+
+
+
+<a name="0x4_property_map_ADDRESS"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_ADDRESS">ADDRESS</a>: u8 = 7;
+</code></pre>
+
+
+
+<a name="0x4_property_map_BOOL"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_BOOL">BOOL</a>: u8 = 0;
+</code></pre>
+
+
+
+<a name="0x4_property_map_BYTE_VECTOR"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_BYTE_VECTOR">BYTE_VECTOR</a>: u8 = 8;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EKEY_AREADY_EXIST_IN_PROPERTY_MAP"></a>
+
+The property key already exists
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EKEY_AREADY_EXIST_IN_PROPERTY_MAP">EKEY_AREADY_EXIST_IN_PROPERTY_MAP</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EKEY_TYPE_COUNT_MISMATCH"></a>
+
+Property key and type count do not match
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EKEY_TYPE_COUNT_MISMATCH">EKEY_TYPE_COUNT_MISMATCH</a>: u64 = 4;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EKEY_VALUE_COUNT_MISMATCH"></a>
+
+Property key and value counts do not match
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EKEY_VALUE_COUNT_MISMATCH">EKEY_VALUE_COUNT_MISMATCH</a>: u64 = 3;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST"></a>
+
+The property map does not exist within global storage
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>: u64 = 7;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EPROPERTY_MAP_NAME_TOO_LONG"></a>
+
+The name (key) of the property is too long
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EPROPERTY_MAP_NAME_TOO_LONG">EPROPERTY_MAP_NAME_TOO_LONG</a>: u64 = 6;
+</code></pre>
+
+
+
+<a name="0x4_property_map_EPROPERTY_NUMBER_EXCEEDS_LIMIT"></a>
+
+The number of property exceeds the limit
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_EPROPERTY_NUMBER_EXCEEDS_LIMIT">EPROPERTY_NUMBER_EXCEEDS_LIMIT</a>: u64 = 2;
+</code></pre>
+
+
+
+<a name="0x4_property_map_ETYPE_INVALID"></a>
+
+Invalid type specified
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_ETYPE_INVALID">ETYPE_INVALID</a>: u64 = 8;
+</code></pre>
+
+
+
+<a name="0x4_property_map_MAX_PROPERTY_MAP_SIZE"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_MAX_PROPERTY_MAP_SIZE">MAX_PROPERTY_MAP_SIZE</a>: u64 = 1000;
+</code></pre>
+
+
+
+<a name="0x4_property_map_MAX_PROPERTY_NAME_LENGTH"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_MAX_PROPERTY_NAME_LENGTH">MAX_PROPERTY_NAME_LENGTH</a>: u64 = 128;
+</code></pre>
+
+
+
+<a name="0x4_property_map_STRING"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_STRING">STRING</a>: u8 = 9;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U128"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U128">U128</a>: u8 = 5;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U16"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U16">U16</a>: u8 = 2;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U256"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U256">U256</a>: u8 = 6;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U32"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U32">U32</a>: u8 = 3;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U64"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U64">U64</a>: u8 = 4;
+</code></pre>
+
+
+
+<a name="0x4_property_map_U8"></a>
+
+
+
+<pre><code><b>const</b> <a href="property_map.md#0x4_property_map_U8">U8</a>: u8 = 1;
+</code></pre>
+
+
+
+<a name="0x4_property_map_init"></a>
+
+## Function `init`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_init">init</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>, container: <a href="property_map.md#0x4_property_map_PropertyMap">property_map::PropertyMap</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_init">init</a>(ref: &ConstructorRef, container: <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>) {
+    <b>let</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer">object::generate_signer</a>(ref);
+    <b>move_to</b>(&<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, container);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_burn"></a>
+
+## Function `burn`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_burn">burn</a>(ref: <a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_burn">burn</a>(ref: <a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>move_from</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_prepare_input"></a>
+
+## Function `prepare_input`
+
+Helper for external entry functions to produce a valid container for property values.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_prepare_input">prepare_input</a>(keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;, values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;): <a href="property_map.md#0x4_property_map_PropertyMap">property_map::PropertyMap</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_prepare_input">prepare_input</a>(
+    keys: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    types: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;String&gt;,
+    values: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;,
+): <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> length = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&keys);
+    <b>assert</b>!(<a href="property_map.md#0x4_property_map_length">length</a> &lt;= <a href="property_map.md#0x4_property_map_MAX_PROPERTY_MAP_SIZE">MAX_PROPERTY_MAP_SIZE</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_NUMBER_EXCEEDS_LIMIT">EPROPERTY_NUMBER_EXCEEDS_LIMIT</a>));
+    <b>assert</b>!(length == <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&values), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="property_map.md#0x4_property_map_EKEY_VALUE_COUNT_MISMATCH">EKEY_VALUE_COUNT_MISMATCH</a>));
+    <b>assert</b>!(length == <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_length">vector::length</a>(&types), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="property_map.md#0x4_property_map_EKEY_TYPE_COUNT_MISMATCH">EKEY_TYPE_COUNT_MISMATCH</a>));
+
+    <b>let</b> container = <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_create">simple_map::create</a>&lt;String, <a href="property_map.md#0x4_property_map_PropertyValue">PropertyValue</a>&gt;();
+    <b>while</b> (!<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_is_empty">vector::is_empty</a>(&keys)) {
+        <b>let</b> key = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_pop_back">vector::pop_back</a>(&<b>mut</b> keys);
+        <b>assert</b>!(
+            <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_length">string::length</a>(&key) &lt;= <a href="property_map.md#0x4_property_map_MAX_PROPERTY_NAME_LENGTH">MAX_PROPERTY_NAME_LENGTH</a>,
+            <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_NAME_TOO_LONG">EPROPERTY_MAP_NAME_TOO_LONG</a>),
+        );
+
+        <b>let</b> value = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_pop_back">vector::pop_back</a>(&<b>mut</b> values);
+        <b>let</b> type = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_pop_back">vector::pop_back</a>(&<b>mut</b> types);
+
+        <b>let</b> new_type = to_internal_type(type);
+        validate_type(new_type, value);
+
+        <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_add">simple_map::add</a>(&<b>mut</b> container, key, <a href="property_map.md#0x4_property_map_PropertyValue">PropertyValue</a> { value, type: new_type });
+    };
+
+    <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> { inner: container }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_generate_mutator_ref"></a>
+
+## Function `generate_mutator_ref`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_generate_mutator_ref">generate_mutator_ref</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>): <a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_generate_mutator_ref">generate_mutator_ref</a>(ref: &ConstructorRef): <a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a> {
+    <a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a> { self: <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_constructor_ref">object::address_from_constructor_ref</a>(ref) }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_contains_key"></a>
+
+## Function `contains_key`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_contains_key">contains_key</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_contains_key">contains_key</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): bool <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(
+        <b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>)),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>),
+    );
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>));
+    <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_contains_key">simple_map::contains_key</a>(&<a href="property_map.md#0x4_property_map">property_map</a>.inner, key)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_length"></a>
+
+## Function `length`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_length">length</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): u64
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_length">length</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;): u64 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(
+        <b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>)),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>),
+    );
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>));
+    <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_length">simple_map::length</a>(&<a href="property_map.md#0x4_property_map">property_map</a>.inner)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read"></a>
+
+## Function `read`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read">read</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read">read</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): (String, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(
+        <b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>)),
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>),
+    );
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>));
+    <b>let</b> property_value = <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_borrow">simple_map::borrow</a>(&<a href="property_map.md#0x4_property_map">property_map</a>.inner, key);
+    <b>let</b> new_type = to_external_type(property_value.type);
+    (new_type, property_value.value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_bool"></a>
+
+## Function `read_bool`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_bool">read_bool</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_bool">read_bool</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): bool <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, bool&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_bool">from_bcs::to_bool</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u8"></a>
+
+## Function `read_u8`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u8">read_u8</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u8
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u8">read_u8</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u8 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u8&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u8">from_bcs::to_u8</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u16"></a>
+
+## Function `read_u16`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u16">read_u16</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u16
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u16">read_u16</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u16 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u16&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u16">from_bcs::to_u16</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u32"></a>
+
+## Function `read_u32`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u32">read_u32</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u32
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u32">read_u32</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u32 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u32&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u32">from_bcs::to_u32</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u64"></a>
+
+## Function `read_u64`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u64">read_u64</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u64
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u64">read_u64</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u64 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u64&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u64">from_bcs::to_u64</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u128"></a>
+
+## Function `read_u128`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u128">read_u128</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u128
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u128">read_u128</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u128 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u128&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u128">from_bcs::to_u128</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_u256"></a>
+
+## Function `read_u256`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u256">read_u256</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): u256
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_u256">read_u256</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): u256 <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, u256&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_u256">from_bcs::to_u256</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_address"></a>
+
+## Function `read_address`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_address">read_address</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_address">read_address</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): <b>address</b> <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, <b>address</b>&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_address">from_bcs::to_address</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_bytes"></a>
+
+## Function `read_bytes`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_bytes">read_bytes</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_bytes">read_bytes</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;<b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_bytes">from_bcs::to_bytes</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_read_string"></a>
+
+## Function `read_string`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_string">read_string</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &<a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_read_string">read_string</a>&lt;T: key&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>: &Object&lt;T&gt;, key: &String): String <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> value = read_typed&lt;T, String&gt;(<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>, key);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/from_bcs.md#0x1_from_bcs_to_string">from_bcs::to_string</a>(value)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_add"></a>
+
+## Function `add`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_add">add</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_add">add</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: String, type: String, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> new_type = to_internal_type(type);
+    validate_type(new_type, value);
+    <a href="property_map.md#0x4_property_map_add_internal">add_internal</a>(ref, key, new_type, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_add_typed"></a>
+
+## Function `add_typed`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_add_typed">add_typed</a>&lt;T: drop&gt;(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: T)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_add_typed">add_typed</a>&lt;T: drop&gt;(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: String, value: T) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> type = type_info_to_internal_type&lt;T&gt;();
+    <a href="property_map.md#0x4_property_map_add_internal">add_internal</a>(ref, key, type, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/bcs.md#0x1_bcs_to_bytes">bcs::to_bytes</a>(&value));
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_add_internal"></a>
+
+## Function `add_internal`
+
+
+
+<pre><code><b>fun</b> <a href="property_map.md#0x4_property_map_add_internal">add_internal</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: u8, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>fun</b> <a href="property_map.md#0x4_property_map_add_internal">add_internal</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: String, type: u8, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(<b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>));
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global_mut</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_add">simple_map::add</a>(&<b>mut</b> <a href="property_map.md#0x4_property_map">property_map</a>.inner, key, <a href="property_map.md#0x4_property_map_PropertyValue">PropertyValue</a> { type, value });
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_update"></a>
+
+## Function `update`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <b>update</b>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <b>update</b>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: &String, type: String, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> new_type = to_internal_type(type);
+    validate_type(new_type, value);
+    <a href="property_map.md#0x4_property_map_update_internal">update_internal</a>(ref, key, new_type, value);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_update_typed"></a>
+
+## Function `update_typed`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_update_typed">update_typed</a>&lt;T: drop&gt;(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, value: T)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_update_typed">update_typed</a>&lt;T: drop&gt;(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: &String, value: T) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>let</b> type = type_info_to_internal_type&lt;T&gt;();
+    <a href="property_map.md#0x4_property_map_update_internal">update_internal</a>(ref, key, type, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/bcs.md#0x1_bcs_to_bytes">bcs::to_bytes</a>(&value));
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_update_internal"></a>
+
+## Function `update_internal`
+
+
+
+<pre><code><b>fun</b> <a href="property_map.md#0x4_property_map_update_internal">update_internal</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, type: u8, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>fun</b> <a href="property_map.md#0x4_property_map_update_internal">update_internal</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: &String, type: u8, value: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(<b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>));
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global_mut</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self);
+    <b>let</b> old_value = <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_borrow_mut">simple_map::borrow_mut</a>(&<b>mut</b> <a href="property_map.md#0x4_property_map">property_map</a>.inner, key);
+    *old_value = <a href="property_map.md#0x4_property_map_PropertyValue">PropertyValue</a> { type, value };
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_property_map_remove"></a>
+
+## Function `remove`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_remove">remove</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">property_map::MutatorRef</a>, key: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="property_map.md#0x4_property_map_remove">remove</a>(ref: &<a href="property_map.md#0x4_property_map_MutatorRef">MutatorRef</a>, key: &String) <b>acquires</b> <a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a> {
+    <b>assert</b>!(<b>exists</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="property_map.md#0x4_property_map_EPROPERTY_MAP_DOES_NOT_EXIST">EPROPERTY_MAP_DOES_NOT_EXIST</a>));
+    <b>let</b> <a href="property_map.md#0x4_property_map">property_map</a> = <b>borrow_global_mut</b>&lt;<a href="property_map.md#0x4_property_map_PropertyMap">PropertyMap</a>&gt;(ref.self);
+    <a href="../../aptos-framework/../aptos-stdlib/doc/simple_map.md#0x1_simple_map_remove">simple_map::remove</a>(&<b>mut</b> <a href="property_map.md#0x4_property_map">property_map</a>.inner, key);
+}
+</code></pre>
+
+
+
+</details>
+
+
+[move-book]: https://move-language.github.io/move/introduction.html
diff --git a/aptos-move/framework/aptos-token-objects/doc/royalty.md b/aptos-move/framework/aptos-token-objects/doc/royalty.md
new file mode 100644
index 0000000000000..0736f4d912b38
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/royalty.md
@@ -0,0 +1,393 @@
+
+<a name="0x4_royalty"></a>
+
+# Module `0x4::royalty`
+
+This defines an object-based Royalty. The royalty can be applied to either a collection or a
+token. Applications should read the royalty from the token, as it will read the appropriate
+royalty.
+
+
+-  [Resource `Royalty`](#0x4_royalty_Royalty)
+-  [Struct `MutatorRef`](#0x4_royalty_MutatorRef)
+-  [Constants](#@Constants_0)
+-  [Function `init`](#0x4_royalty_init)
+-  [Function `update`](#0x4_royalty_update)
+-  [Function `create`](#0x4_royalty_create)
+-  [Function `generate_mutator_ref`](#0x4_royalty_generate_mutator_ref)
+-  [Function `exists_at`](#0x4_royalty_exists_at)
+-  [Function `delete`](#0x4_royalty_delete)
+-  [Function `get`](#0x4_royalty_get)
+-  [Function `denominator`](#0x4_royalty_denominator)
+-  [Function `numerator`](#0x4_royalty_numerator)
+-  [Function `payee_address`](#0x4_royalty_payee_address)
+
+
+<pre><code><b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
+<b>use</b> <a href="../../aptos-framework/doc/object.md#0x1_object">0x1::object</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
+</code></pre>
+
+
+
+<a name="0x4_royalty_Royalty"></a>
+
+## Resource `Royalty`
+
+The royalty of a token within this collection -- this optional
+
+
+<pre><code><b>struct</b> <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> <b>has</b> <b>copy</b>, drop, key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>numerator: u64</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>denominator: u64</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>payee_address: <b>address</b></code>
+</dt>
+<dd>
+ The recipient of royalty payments. See the <code>shared_account</code> for how to handle multiple
+ creators.
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_royalty_MutatorRef"></a>
+
+## Struct `MutatorRef`
+
+This enables creating or overwriting a MutatorRef.
+
+
+<pre><code><b>struct</b> <a href="royalty.md#0x4_royalty_MutatorRef">MutatorRef</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>inner: <a href="../../aptos-framework/doc/object.md#0x1_object_ExtendRef">object::ExtendRef</a></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="@Constants_0"></a>
+
+## Constants
+
+
+<a name="0x4_royalty_EROYALTY_DENOMINATOR_IS_ZERO"></a>
+
+
+
+<pre><code><b>const</b> <a href="royalty.md#0x4_royalty_EROYALTY_DENOMINATOR_IS_ZERO">EROYALTY_DENOMINATOR_IS_ZERO</a>: u64 = 2;
+</code></pre>
+
+
+
+<a name="0x4_royalty_EROYALTY_DOES_NOT_EXIST"></a>
+
+
+
+<pre><code><b>const</b> <a href="royalty.md#0x4_royalty_EROYALTY_DOES_NOT_EXIST">EROYALTY_DOES_NOT_EXIST</a>: u64 = 3;
+</code></pre>
+
+
+
+<a name="0x4_royalty_EROYALTY_EXCEEDS_MAXIMUM"></a>
+
+
+
+<pre><code><b>const</b> <a href="royalty.md#0x4_royalty_EROYALTY_EXCEEDS_MAXIMUM">EROYALTY_EXCEEDS_MAXIMUM</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_royalty_init"></a>
+
+## Function `init`
+
+Add a royalty, given a ConstructorRef.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_init">init</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_init">init</a>(ref: &ConstructorRef, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">Royalty</a>) {
+    <b>let</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer">object::generate_signer</a>(ref);
+    <b>move_to</b>(&<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="royalty.md#0x4_royalty">royalty</a>);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_update"></a>
+
+## Function `update`
+
+Set the royalty if it does not exist, replace it otherwise.
+
+
+<pre><code><b>public</b> <b>fun</b> <b>update</b>(mutator_ref: &<a href="royalty.md#0x4_royalty_MutatorRef">royalty::MutatorRef</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <b>update</b>(mutator_ref: &<a href="royalty.md#0x4_royalty_MutatorRef">MutatorRef</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="royalty.md#0x4_royalty_Royalty">Royalty</a>) <b>acquires</b> <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> {
+    <b>let</b> addr = <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_extend_ref">object::address_from_extend_ref</a>(&mutator_ref.inner);
+    <b>if</b> (<b>exists</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(addr)) {
+        <b>move_from</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(addr);
+    };
+
+    <b>let</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer_for_extending">object::generate_signer_for_extending</a>(&mutator_ref.inner);
+    <b>move_to</b>(&<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="royalty.md#0x4_royalty">royalty</a>);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_create"></a>
+
+## Function `create`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_create">create</a>(numerator: u64, denominator: u64, payee_address: <b>address</b>): <a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_create">create</a>(numerator: u64, denominator: u64, payee_address: <b>address</b>): <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> {
+    <b>assert</b>!(denominator != 0, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="royalty.md#0x4_royalty_EROYALTY_DENOMINATOR_IS_ZERO">EROYALTY_DENOMINATOR_IS_ZERO</a>));
+    <b>assert</b>!(<a href="royalty.md#0x4_royalty_numerator">numerator</a> &lt;= denominator, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_out_of_range">error::out_of_range</a>(<a href="royalty.md#0x4_royalty_EROYALTY_EXCEEDS_MAXIMUM">EROYALTY_EXCEEDS_MAXIMUM</a>));
+
+    <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> { numerator, denominator, payee_address }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_generate_mutator_ref"></a>
+
+## Function `generate_mutator_ref`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_generate_mutator_ref">generate_mutator_ref</a>(ref: <a href="../../aptos-framework/doc/object.md#0x1_object_ExtendRef">object::ExtendRef</a>): <a href="royalty.md#0x4_royalty_MutatorRef">royalty::MutatorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_generate_mutator_ref">generate_mutator_ref</a>(ref: ExtendRef): <a href="royalty.md#0x4_royalty_MutatorRef">MutatorRef</a> {
+    <a href="royalty.md#0x4_royalty_MutatorRef">MutatorRef</a> { inner: ref }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_exists_at"></a>
+
+## Function `exists_at`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_exists_at">exists_at</a>(addr: <b>address</b>): bool
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_exists_at">exists_at</a>(addr: <b>address</b>): bool {
+    <b>exists</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(addr)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_delete"></a>
+
+## Function `delete`
+
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="royalty.md#0x4_royalty_delete">delete</a>(addr: <b>address</b>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="royalty.md#0x4_royalty_delete">delete</a>(addr: <b>address</b>) <b>acquires</b> <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> {
+    <b>assert</b>!(<b>exists</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(addr), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_not_found">error::not_found</a>(<a href="royalty.md#0x4_royalty_EROYALTY_DOES_NOT_EXIST">EROYALTY_DOES_NOT_EXIST</a>));
+    <b>move_from</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(addr);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_get"></a>
+
+## Function `get`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_get">get</a>&lt;T: key&gt;(maybe_royalty: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_get">get</a>&lt;T: key&gt;(maybe_royalty: Object&lt;T&gt;): Option&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt; <b>acquires</b> <a href="royalty.md#0x4_royalty_Royalty">Royalty</a> {
+    <b>let</b> obj_addr = <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(&maybe_royalty);
+    <b>if</b> (<b>exists</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(obj_addr)) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(*<b>borrow_global</b>&lt;<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>&gt;(obj_addr))
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>()
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_denominator"></a>
+
+## Function `denominator`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_denominator">denominator</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>): u64
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_denominator">denominator</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>): u64 {
+    <a href="royalty.md#0x4_royalty">royalty</a>.denominator
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_numerator"></a>
+
+## Function `numerator`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_numerator">numerator</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>): u64
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_numerator">numerator</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>): u64 {
+    <a href="royalty.md#0x4_royalty">royalty</a>.numerator
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_royalty_payee_address"></a>
+
+## Function `payee_address`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_payee_address">payee_address</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty_payee_address">payee_address</a>(<a href="royalty.md#0x4_royalty">royalty</a>: &<a href="royalty.md#0x4_royalty_Royalty">Royalty</a>): <b>address</b> {
+    <a href="royalty.md#0x4_royalty">royalty</a>.payee_address
+}
+</code></pre>
+
+
+
+</details>
+
+
+[move-book]: https://move-language.github.io/move/introduction.html
diff --git a/aptos-move/framework/aptos-token-objects/doc/token.md b/aptos-move/framework/aptos-token-objects/doc/token.md
new file mode 100644
index 0000000000000..bc204c4349caf
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc/token.md
@@ -0,0 +1,790 @@
+
+<a name="0x4_token"></a>
+
+# Module `0x4::token`
+
+This defines an object-based Token. The key differentiating features from the Aptos standard
+token are:
+* Decouple token ownership from token data.
+* Explicit data model for token metadata via adjacent resources
+* Extensible framework for tokens
+
+TODO:
+* Update Object<T> to be a viable input as a transaction arg and then update all readers as view.
+
+
+-  [Resource `Token`](#0x4_token_Token)
+-  [Struct `BurnRef`](#0x4_token_BurnRef)
+-  [Struct `MutatorRef`](#0x4_token_MutatorRef)
+-  [Struct `MutationEvent`](#0x4_token_MutationEvent)
+-  [Constants](#@Constants_0)
+-  [Function `create`](#0x4_token_create)
+-  [Function `create_token_address`](#0x4_token_create_token_address)
+-  [Function `create_token_seed`](#0x4_token_create_token_seed)
+-  [Function `generate_mutator_ref`](#0x4_token_generate_mutator_ref)
+-  [Function `generate_burn_ref`](#0x4_token_generate_burn_ref)
+-  [Function `address_from_burn_ref`](#0x4_token_address_from_burn_ref)
+-  [Function `creator`](#0x4_token_creator)
+-  [Function `collection`](#0x4_token_collection)
+-  [Function `collection_object`](#0x4_token_collection_object)
+-  [Function `creation_name`](#0x4_token_creation_name)
+-  [Function `description`](#0x4_token_description)
+-  [Function `name`](#0x4_token_name)
+-  [Function `uri`](#0x4_token_uri)
+-  [Function `royalty`](#0x4_token_royalty)
+-  [Function `burn`](#0x4_token_burn)
+-  [Function `set_description`](#0x4_token_set_description)
+-  [Function `set_name`](#0x4_token_set_name)
+-  [Function `set_uri`](#0x4_token_set_uri)
+
+
+<pre><code><b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
+<b>use</b> <a href="../../aptos-framework/doc/event.md#0x1_event">0x1::event</a>;
+<b>use</b> <a href="../../aptos-framework/doc/object.md#0x1_object">0x1::object</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option">0x1::option</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">0x1::signer</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">0x1::string</a>;
+<b>use</b> <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">0x1::vector</a>;
+<b>use</b> <a href="collection.md#0x4_collection">0x4::collection</a>;
+<b>use</b> <a href="royalty.md#0x4_royalty">0x4::royalty</a>;
+</code></pre>
+
+
+
+<a name="0x4_token_Token"></a>
+
+## Resource `Token`
+
+Represents the common fields to all tokens.
+
+
+<pre><code><b>struct</b> <a href="token.md#0x4_token_Token">Token</a> <b>has</b> key
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code><a href="collection.md#0x4_collection">collection</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;<a href="collection.md#0x4_collection_Collection">collection::Collection</a>&gt;</code>
+</dt>
+<dd>
+ The collection from which this token resides.
+</dd>
+<dt>
+<code>collection_id: u64</code>
+</dt>
+<dd>
+ Unique identifier within the collection, optional, 0 means unassigned
+</dd>
+<dt>
+<code>description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ A brief description of the token.
+</dd>
+<dt>
+<code>name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ The name of the token, which should be unique within the collection; the length of name
+ should be smaller than 128, characters, eg: "Aptos Animal #1234"
+</dd>
+<dt>
+<code>creation_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>&gt;</code>
+</dt>
+<dd>
+ The creation name of the token. Since tokens are created with the name as part of the
+ object id generation.
+</dd>
+<dt>
+<code>uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+ The Uniform Resource Identifier (uri) pointing to the JSON file stored in off-chain
+ storage; the URL length will likely need a maximum any suggestions?
+</dd>
+<dt>
+<code>mutation_events: <a href="../../aptos-framework/doc/event.md#0x1_event_EventHandle">event::EventHandle</a>&lt;<a href="token.md#0x4_token_MutationEvent">token::MutationEvent</a>&gt;</code>
+</dt>
+<dd>
+ Emitted upon any mutation of the token.
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_token_BurnRef"></a>
+
+## Struct `BurnRef`
+
+This enables burning an NFT, if possible, it will also delete the object. Note, the data
+in inner and self occupies 32-bytes each, rather than have both, this data structure makes
+a small optimization to support either and take a fixed amount of 34-bytes.
+
+
+<pre><code><b>struct</b> <a href="token.md#0x4_token_BurnRef">BurnRef</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>inner: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="../../aptos-framework/doc/object.md#0x1_object_DeleteRef">object::DeleteRef</a>&gt;</code>
+</dt>
+<dd>
+
+</dd>
+<dt>
+<code>self: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<b>address</b>&gt;</code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_token_MutatorRef"></a>
+
+## Struct `MutatorRef`
+
+This enables mutating descritpion and URI by higher level services.
+
+
+<pre><code><b>struct</b> <a href="token.md#0x4_token_MutatorRef">MutatorRef</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>self: <b>address</b></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="0x4_token_MutationEvent"></a>
+
+## Struct `MutationEvent`
+
+Contains the mutated fields name. This makes the life of indexers easier, so that they can
+directly understand the behavior in a writeset.
+
+
+<pre><code><b>struct</b> <a href="token.md#0x4_token_MutationEvent">MutationEvent</a> <b>has</b> drop, store
+</code></pre>
+
+
+
+<details>
+<summary>Fields</summary>
+
+
+<dl>
+<dt>
+<code>mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a></code>
+</dt>
+<dd>
+
+</dd>
+</dl>
+
+
+</details>
+
+<a name="@Constants_0"></a>
+
+## Constants
+
+
+<a name="0x4_token_EFIELD_NOT_MUTABLE"></a>
+
+Attempted to mutate an immutable field
+
+
+<pre><code><b>const</b> <a href="token.md#0x4_token_EFIELD_NOT_MUTABLE">EFIELD_NOT_MUTABLE</a>: u64 = 3;
+</code></pre>
+
+
+
+<a name="0x4_token_ENOT_CREATOR"></a>
+
+The provided signer is not the creator
+
+
+<pre><code><b>const</b> <a href="token.md#0x4_token_ENOT_CREATOR">ENOT_CREATOR</a>: u64 = 2;
+</code></pre>
+
+
+
+<a name="0x4_token_ETOKEN_DOES_NOT_EXIST"></a>
+
+
+
+<pre><code><b>const</b> <a href="token.md#0x4_token_ETOKEN_DOES_NOT_EXIST">ETOKEN_DOES_NOT_EXIST</a>: u64 = 1;
+</code></pre>
+
+
+
+<a name="0x4_token_create"></a>
+
+## Function `create`
+
+Creates a new token object and returns the ConstructorRef for additional specialization.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create">create</a>(creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, collection_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, <a href="royalty.md#0x4_royalty">royalty</a>: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>&gt;, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create">create</a>(
+    creator: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
+    collection_name: String,
+    description: String,
+    name: String,
+    <a href="royalty.md#0x4_royalty">royalty</a>: Option&lt;Royalty&gt;,
+    uri: String,
+): ConstructorRef {
+    <b>let</b> creator_address = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(creator);
+    <b>let</b> seed = <a href="token.md#0x4_token_create_token_seed">create_token_seed</a>(&collection_name, &name);
+
+    <b>let</b> collection_addr = <a href="collection.md#0x4_collection_create_collection_address">collection::create_collection_address</a>(&creator_address, &collection_name);
+    <b>let</b> <a href="collection.md#0x4_collection">collection</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_address_to_object">object::address_to_object</a>&lt;Collection&gt;(collection_addr);
+    <b>let</b> id = <a href="collection.md#0x4_collection_increment_supply">collection::increment_supply</a>(&<a href="collection.md#0x4_collection">collection</a>);
+
+    <b>let</b> constructor_ref = <a href="../../aptos-framework/doc/object.md#0x1_object_create_named_object">object::create_named_object</a>(creator, seed);
+    <b>let</b> object_signer = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_signer">object::generate_signer</a>(&constructor_ref);
+
+    <b>let</b> <a href="token.md#0x4_token">token</a> = <a href="token.md#0x4_token_Token">Token</a> {
+        <a href="collection.md#0x4_collection">collection</a>,
+        collection_id: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_get_with_default">option::get_with_default</a>(&<b>mut</b> id, 0),
+        description,
+        name,
+        creation_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(),
+        uri,
+        mutation_events: <a href="../../aptos-framework/doc/object.md#0x1_object_new_event_handle">object::new_event_handle</a>(&object_signer),
+    };
+    <b>move_to</b>(&object_signer, <a href="token.md#0x4_token">token</a>);
+
+    <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="royalty.md#0x4_royalty">royalty</a>)) {
+        <a href="royalty.md#0x4_royalty_init">royalty::init</a>(&constructor_ref, <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_extract">option::extract</a>(&<b>mut</b> <a href="royalty.md#0x4_royalty">royalty</a>))
+    };
+    constructor_ref
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_create_token_address"></a>
+
+## Function `create_token_address`
+
+Generates the collections address based upon the creators address and the collection's name
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create_token_address">create_token_address</a>(creator: &<b>address</b>, <a href="collection.md#0x4_collection">collection</a>: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create_token_address">create_token_address</a>(creator: &<b>address</b>, <a href="collection.md#0x4_collection">collection</a>: &String, name: &String): <b>address</b> {
+    <a href="../../aptos-framework/doc/object.md#0x1_object_create_object_address">object::create_object_address</a>(creator, <a href="token.md#0x4_token_create_token_seed">create_token_seed</a>(<a href="collection.md#0x4_collection">collection</a>, name))
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_create_token_seed"></a>
+
+## Function `create_token_seed`
+
+Named objects are derived from a seed, the collection's seed is its name.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create_token_seed">create_token_seed</a>(<a href="collection.md#0x4_collection">collection</a>: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>, name: &<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_create_token_seed">create_token_seed</a>(<a href="collection.md#0x4_collection">collection</a>: &String, name: &String): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
+    <b>let</b> seed = *<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_bytes">string::bytes</a>(<a href="collection.md#0x4_collection">collection</a>);
+    <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_append">vector::append</a>(&<b>mut</b> seed, b"::");
+    <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector_append">vector::append</a>(&<b>mut</b> seed, *<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_bytes">string::bytes</a>(name));
+    seed
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_generate_mutator_ref"></a>
+
+## Function `generate_mutator_ref`
+
+Creates a MutatorRef, which gates the ability to mutate any fields that support mutation.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_generate_mutator_ref">generate_mutator_ref</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>): <a href="token.md#0x4_token_MutatorRef">token::MutatorRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_generate_mutator_ref">generate_mutator_ref</a>(ref: &ConstructorRef): <a href="token.md#0x4_token_MutatorRef">MutatorRef</a> {
+    <b>let</b> <a href="../../aptos-framework/doc/object.md#0x1_object">object</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_object_from_constructor_ref">object::object_from_constructor_ref</a>&lt;<a href="token.md#0x4_token_Token">Token</a>&gt;(ref);
+    <a href="token.md#0x4_token_MutatorRef">MutatorRef</a> { self: <a href="../../aptos-framework/doc/object.md#0x1_object_object_address">object::object_address</a>(&<a href="../../aptos-framework/doc/object.md#0x1_object">object</a>) }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_generate_burn_ref"></a>
+
+## Function `generate_burn_ref`
+
+Creates a BurnRef, which gates the ability to burn the given token.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_generate_burn_ref">generate_burn_ref</a>(ref: &<a href="../../aptos-framework/doc/object.md#0x1_object_ConstructorRef">object::ConstructorRef</a>): <a href="token.md#0x4_token_BurnRef">token::BurnRef</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_generate_burn_ref">generate_burn_ref</a>(ref: &ConstructorRef): <a href="token.md#0x4_token_BurnRef">BurnRef</a> {
+    <b>let</b> (inner, self) = <b>if</b> (<a href="../../aptos-framework/doc/object.md#0x1_object_can_generate_delete_ref">object::can_generate_delete_ref</a>(ref)) {
+        <b>let</b> delete_ref = <a href="../../aptos-framework/doc/object.md#0x1_object_generate_delete_ref">object::generate_delete_ref</a>(ref);
+        (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(delete_ref), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>())
+    } <b>else</b> {
+        <b>let</b> addr = <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_constructor_ref">object::address_from_constructor_ref</a>(ref);
+        (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_none">option::none</a>(), <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_some">option::some</a>(addr))
+    };
+    <a href="token.md#0x4_token_BurnRef">BurnRef</a> { self, inner }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_address_from_burn_ref"></a>
+
+## Function `address_from_burn_ref`
+
+Extracts the tokens address from a BurnRef.
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_address_from_burn_ref">address_from_burn_ref</a>(ref: &<a href="token.md#0x4_token_BurnRef">token::BurnRef</a>): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_address_from_burn_ref">address_from_burn_ref</a>(ref: &<a href="token.md#0x4_token_BurnRef">BurnRef</a>): <b>address</b> {
+    <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&ref.inner)) {
+        <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_delete_ref">object::address_from_delete_ref</a>(<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&ref.inner))
+    } <b>else</b> {
+        *<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&ref.self)
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_creator"></a>
+
+## Function `creator`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_creator">creator</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <b>address</b>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_creator">creator</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): <b>address</b> <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <a href="collection.md#0x4_collection_creator">collection::creator</a>(borrow(&<a href="token.md#0x4_token">token</a>).<a href="collection.md#0x4_collection">collection</a>)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_collection"></a>
+
+## Function `collection`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection">collection</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="collection.md#0x4_collection">collection</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <a href="collection.md#0x4_collection_name">collection::name</a>(borrow(&<a href="token.md#0x4_token">token</a>).<a href="collection.md#0x4_collection">collection</a>)
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_collection_object"></a>
+
+## Function `collection_object`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_collection_object">collection_object</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;<a href="collection.md#0x4_collection_Collection">collection::Collection</a>&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_collection_object">collection_object</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): Object&lt;Collection&gt; <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    borrow(&<a href="token.md#0x4_token">token</a>).<a href="collection.md#0x4_collection">collection</a>
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_creation_name"></a>
+
+## Function `creation_name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_creation_name">creation_name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_creation_name">creation_name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <b>let</b> <a href="token.md#0x4_token">token</a> = borrow(&<a href="token.md#0x4_token">token</a>);
+    <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="token.md#0x4_token">token</a>.creation_name)) {
+        *<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_borrow">option::borrow</a>(&<a href="token.md#0x4_token">token</a>.creation_name)
+    } <b>else</b> {
+        <a href="token.md#0x4_token">token</a>.name
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_description"></a>
+
+## Function `description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_description">description</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_description">description</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    borrow(&<a href="token.md#0x4_token">token</a>).description
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_name"></a>
+
+## Function `name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_name">name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_name">name</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    borrow(&<a href="token.md#0x4_token">token</a>).name
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_uri"></a>
+
+## Function `uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_uri">uri</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_uri">uri</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): String <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    borrow(&<a href="token.md#0x4_token">token</a>).uri
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_royalty"></a>
+
+## Function `royalty`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty">royalty</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: <a href="../../aptos-framework/doc/object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_Option">option::Option</a>&lt;<a href="royalty.md#0x4_royalty_Royalty">royalty::Royalty</a>&gt;
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="royalty.md#0x4_royalty">royalty</a>&lt;T: key&gt;(<a href="token.md#0x4_token">token</a>: Object&lt;T&gt;): Option&lt;Royalty&gt; <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    borrow(&<a href="token.md#0x4_token">token</a>);
+    <b>let</b> <a href="royalty.md#0x4_royalty">royalty</a> = <a href="royalty.md#0x4_royalty_get">royalty::get</a>(<a href="token.md#0x4_token">token</a>);
+    <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&<a href="royalty.md#0x4_royalty">royalty</a>)) {
+        <a href="royalty.md#0x4_royalty">royalty</a>
+    } <b>else</b> {
+        <b>let</b> creator = <a href="token.md#0x4_token_creator">creator</a>(<a href="token.md#0x4_token">token</a>);
+        <b>let</b> collection_name = <a href="collection.md#0x4_collection">collection</a>(<a href="token.md#0x4_token">token</a>);
+        <b>let</b> collection_address = <a href="collection.md#0x4_collection_create_collection_address">collection::create_collection_address</a>(&creator, &collection_name);
+        <b>let</b> <a href="collection.md#0x4_collection">collection</a> = <a href="../../aptos-framework/doc/object.md#0x1_object_address_to_object">object::address_to_object</a>&lt;<a href="collection.md#0x4_collection_Collection">collection::Collection</a>&gt;(collection_address);
+        <a href="royalty.md#0x4_royalty_get">royalty::get</a>(<a href="collection.md#0x4_collection">collection</a>)
+    }
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_burn"></a>
+
+## Function `burn`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_burn">burn</a>(burn_ref: <a href="token.md#0x4_token_BurnRef">token::BurnRef</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_burn">burn</a>(burn_ref: <a href="token.md#0x4_token_BurnRef">BurnRef</a>) <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <b>let</b> addr = <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_some">option::is_some</a>(&burn_ref.inner)) {
+        <b>let</b> delete_ref = <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_extract">option::extract</a>(&<b>mut</b> burn_ref.inner);
+        <b>let</b> addr = <a href="../../aptos-framework/doc/object.md#0x1_object_address_from_delete_ref">object::address_from_delete_ref</a>(&delete_ref);
+        <a href="../../aptos-framework/doc/object.md#0x1_object_delete">object::delete</a>(delete_ref);
+        addr
+    } <b>else</b> {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_extract">option::extract</a>(&<b>mut</b> burn_ref.self)
+    };
+
+    <b>if</b> (<a href="royalty.md#0x4_royalty_exists_at">royalty::exists_at</a>(addr)) {
+        <a href="royalty.md#0x4_royalty_delete">royalty::delete</a>(addr)
+    };
+
+    <b>let</b> <a href="token.md#0x4_token_Token">Token</a> {
+        <a href="collection.md#0x4_collection">collection</a>,
+        collection_id: _,
+        description: _,
+        name: _,
+        creation_name: _,
+        uri: _,
+        mutation_events,
+    } = <b>move_from</b>&lt;<a href="token.md#0x4_token_Token">Token</a>&gt;(addr);
+
+    <a href="../../aptos-framework/doc/event.md#0x1_event_destroy_handle">event::destroy_handle</a>(mutation_events);
+    <a href="collection.md#0x4_collection_decrement_supply">collection::decrement_supply</a>(&<a href="collection.md#0x4_collection">collection</a>);
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_set_description"></a>
+
+## Function `set_description`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_description">set_description</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">token::MutatorRef</a>, description: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_description">set_description</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">MutatorRef</a>, description: String) <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <b>let</b> <a href="token.md#0x4_token">token</a> = borrow_mut(mutator_ref);
+    <a href="token.md#0x4_token">token</a>.description = description;
+    <a href="../../aptos-framework/doc/event.md#0x1_event_emit_event">event::emit_event</a>(
+        &<b>mut</b> <a href="token.md#0x4_token">token</a>.mutation_events,
+        <a href="token.md#0x4_token_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_utf8">string::utf8</a>(b"description") },
+    );
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_set_name"></a>
+
+## Function `set_name`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_name">set_name</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">token::MutatorRef</a>, name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_name">set_name</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">MutatorRef</a>, name: String) <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <b>let</b> <a href="token.md#0x4_token">token</a> = borrow_mut(mutator_ref);
+    <b>if</b> (<a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_is_none">option::is_none</a>(&<a href="token.md#0x4_token">token</a>.creation_name)) {
+        <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/option.md#0x1_option_fill">option::fill</a>(&<b>mut</b> <a href="token.md#0x4_token">token</a>.creation_name, <a href="token.md#0x4_token">token</a>.name)
+    };
+    <a href="token.md#0x4_token">token</a>.name = name;
+    <a href="../../aptos-framework/doc/event.md#0x1_event_emit_event">event::emit_event</a>(
+        &<b>mut</b> <a href="token.md#0x4_token">token</a>.mutation_events,
+        <a href="token.md#0x4_token_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_utf8">string::utf8</a>(b"name") },
+    );
+}
+</code></pre>
+
+
+
+</details>
+
+<a name="0x4_token_set_uri"></a>
+
+## Function `set_uri`
+
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_uri">set_uri</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">token::MutatorRef</a>, uri: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_String">string::String</a>)
+</code></pre>
+
+
+
+<details>
+<summary>Implementation</summary>
+
+
+<pre><code><b>public</b> <b>fun</b> <a href="token.md#0x4_token_set_uri">set_uri</a>(mutator_ref: &<a href="token.md#0x4_token_MutatorRef">MutatorRef</a>, uri: String) <b>acquires</b> <a href="token.md#0x4_token_Token">Token</a> {
+    <b>let</b> <a href="token.md#0x4_token">token</a> = borrow_mut(mutator_ref);
+    <a href="token.md#0x4_token">token</a>.uri = uri;
+    <a href="../../aptos-framework/doc/event.md#0x1_event_emit_event">event::emit_event</a>(
+        &<b>mut</b> <a href="token.md#0x4_token">token</a>.mutation_events,
+        <a href="token.md#0x4_token_MutationEvent">MutationEvent</a> { mutated_field_name: <a href="../../aptos-framework/../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string_utf8">string::utf8</a>(b"uri") },
+    );
+}
+</code></pre>
+
+
+
+</details>
+
+
+[move-book]: https://move-language.github.io/move/introduction.html
diff --git a/aptos-move/framework/aptos-token-objects/doc_template/overview.md b/aptos-move/framework/aptos-token-objects/doc_template/overview.md
new file mode 100644
index 0000000000000..006db85f6117a
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc_template/overview.md
@@ -0,0 +1,7 @@
+# Aptos Token Framework
+
+This is the reference documentation of the Aptos Token Objects framework.
+
+## Index
+
+> {{move-index}}
diff --git a/aptos-move/framework/aptos-token-objects/doc_template/references.md b/aptos-move/framework/aptos-token-objects/doc_template/references.md
new file mode 100644
index 0000000000000..147a67c84546c
--- /dev/null
+++ b/aptos-move/framework/aptos-token-objects/doc_template/references.md
@@ -0,0 +1 @@
+[move-book]: https://move-language.github.io/move/introduction.html
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 79%
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 09af3360cbc2f..92813f439f5c4 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;
@@ -14,10 +14,10 @@ module token_objects::aptos_token {
 
     use aptos_framework::object::{Self, ConstructorRef, Object};
 
-    use token_objects::collection;
-    use token_objects::property_map;
-    use token_objects::royalty;
-    use token_objects::token;
+    use aptos_token_objects::collection;
+    use aptos_token_objects::property_map;
+    use aptos_token_objects::royalty;
+    use aptos_token_objects::token;
 
     // The token does not exist
     const ETOKEN_DOES_NOT_EXIST: u64 = 1;
@@ -67,7 +67,7 @@ module token_objects::aptos_token {
         /// Used to mutate fields
         mutator_ref: Option<token::MutatorRef>,
         /// Used to mutate properties
-        property_mutator_ref: Option<property_map::MutatorRef>,
+        property_mutator_ref: property_map::MutatorRef,
     }
 
     /// Create a new collection
@@ -231,17 +231,11 @@ module token_objects::aptos_token {
             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,
+            property_mutator_ref: property_map::generate_mutator_ref(&constructor_ref),
         };
         move_to(&object_signer, aptos_token);
 
@@ -262,26 +256,33 @@ module token_objects::aptos_token {
         borrow_global<AptosToken>(token_address)
     }
 
-    public fun are_properties_mutable<T: key>(token: Object<T>): bool acquires AptosToken {
-        option::is_some(&borrow(&token).property_mutator_ref)
+    #[view]
+    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
     }
 
+    #[view]
     public fun is_burnable<T: key>(token: Object<T>): bool acquires AptosToken {
         option::is_some(&borrow(&token).burn_ref)
     }
 
+    #[view]
     public fun is_freezable_by_creator<T: key>(token: Object<T>): bool acquires AptosCollection {
         are_collection_tokens_freezable(token::collection_object(token))
     }
 
+    #[view]
     public fun is_mutable_description<T: key>(token: Object<T>): bool acquires AptosCollection {
         is_mutable_collection_token_description(token::collection_object(token))
     }
 
+    #[view]
     public fun is_mutable_name<T: key>(token: Object<T>): bool acquires AptosCollection {
         is_mutable_collection_token_name(token::collection_object(token))
     }
 
+    #[view]
     public fun is_mutable_uri<T: key>(token: Object<T>): bool acquires AptosCollection {
         is_mutable_collection_token_uri(token::collection_object(token))
     }
@@ -302,7 +303,7 @@ module token_objects::aptos_token {
         borrow_global<AptosToken>(token_address)
     }
 
-    public fun burn<T: key>(creator: &signer, token: Object<T>) acquires AptosToken {
+    public entry 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),
@@ -314,30 +315,33 @@ module token_objects::aptos_token {
             burn_ref,
             transfer_ref: _,
             mutator_ref: _,
-            property_mutator_ref: _,
+            property_mutator_ref,
         } = aptos_token;
+        property_map::burn(property_mutator_ref);
         token::burn(option::extract(&mut burn_ref));
     }
 
-    public fun freeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+    public entry fun freeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+        let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            are_collection_tokens_freezable(token::collection_object(token)),
+            are_collection_tokens_freezable(token::collection_object(token))
+                && option::is_some(&aptos_token.transfer_ref),
             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));
     }
 
-    public fun unfreeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+    public entry fun unfreeze_transfer<T: key>(creator: &signer, token: Object<T>) acquires AptosCollection, AptosToken {
+        let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            are_collection_tokens_freezable(token::collection_object(token)),
+            are_collection_tokens_freezable(token::collection_object(token))
+                && option::is_some(&aptos_token.transfer_ref),
             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));
     }
 
-    public fun set_description<T: key>(
+    public entry fun set_description<T: key>(
         creator: &signer,
         token: Object<T>,
         description: String,
@@ -350,7 +354,7 @@ module token_objects::aptos_token {
         token::set_description(option::borrow(&aptos_token.mutator_ref), description);
     }
 
-    public fun set_name<T: key>(
+    public entry fun set_name<T: key>(
         creator: &signer,
         token: Object<T>,
         name: String,
@@ -363,7 +367,7 @@ module token_objects::aptos_token {
         token::set_name(option::borrow(&aptos_token.mutator_ref), name);
     }
 
-    public fun set_uri<T: key>(
+    public entry fun set_uri<T: key>(
         creator: &signer,
         token: Object<T>,
         uri: String,
@@ -376,212 +380,89 @@ module token_objects::aptos_token {
         token::set_uri(option::borrow(&aptos_token.mutator_ref), uri);
     }
 
-    public fun add_property<T: key>(
+    public entry fun add_property<T: key>(
         creator: &signer,
         token: Object<T>,
         key: String,
         type: String,
         value: vector<u8>,
-    ) acquires AptosToken {
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            option::is_some(&aptos_token.property_mutator_ref),
+            are_properties_mutable(token),
             error::permission_denied(EPROPERTIES_NOT_MUTABLE),
         );
 
-        property_map::add(
-            option::borrow(&aptos_token.property_mutator_ref),
-            key,
-            type,
-            value,
-        );
+        property_map::add(&aptos_token.property_mutator_ref, key, type, value);
     }
 
-    public fun add_typed_property<T: key, V: drop>(
+    public entry fun add_typed_property<T: key, V: drop>(
         creator: &signer,
         token: Object<T>,
         key: String,
         value: V,
-    ) acquires AptosToken {
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            option::is_some(&aptos_token.property_mutator_ref),
+            are_properties_mutable(token),
             error::permission_denied(EPROPERTIES_NOT_MUTABLE),
         );
 
-        property_map::add_typed(
-            option::borrow(&aptos_token.property_mutator_ref),
-            key,
-            value,
-        );
+        property_map::add_typed(&aptos_token.property_mutator_ref, key, value);
     }
 
-    public fun remove_property<T: key>(creator: &signer, token: Object<T>, key: &String) acquires AptosToken {
+    public entry fun remove_property<T: key>(
+        creator: &signer,
+        token: Object<T>,
+        key: String,
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            option::is_some(&aptos_token.property_mutator_ref),
+            are_properties_mutable(token),
             error::permission_denied(EPROPERTIES_NOT_MUTABLE),
         );
 
-        property_map::remove(option::borrow(&aptos_token.property_mutator_ref), key);
+        property_map::remove(&aptos_token.property_mutator_ref, &key);
     }
 
-    public fun update_property<T: key>(
+    public entry fun update_property<T: key>(
         creator: &signer,
         token: Object<T>,
-        key: &String,
+        key: String,
         type: String,
         value: vector<u8>,
-    ) acquires AptosToken {
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            option::is_some(&aptos_token.property_mutator_ref),
+            are_properties_mutable(token),
             error::permission_denied(EPROPERTIES_NOT_MUTABLE),
         );
 
-        property_map::update(
-            option::borrow(&aptos_token.property_mutator_ref),
-            key,
-            type,
-            value,
-        );
+        property_map::update(&aptos_token.property_mutator_ref, &key, type, value);
     }
 
-    public fun update_typed_property<T: key, V: drop>(
+    public entry fun update_typed_property<T: key, V: drop>(
         creator: &signer,
         token: Object<T>,
-        key: &String,
+        key: String,
         value: V,
-    ) acquires AptosToken {
+    ) acquires AptosCollection, AptosToken {
         let aptos_token = authorized_borrow(&token, signer::address_of(creator));
         assert!(
-            option::is_some(&aptos_token.property_mutator_ref),
+            are_properties_mutable(token),
             error::permission_denied(EPROPERTIES_NOT_MUTABLE),
         );
 
-        property_map::update_typed(
-            option::borrow(&aptos_token.property_mutator_ref),
-            key,
-            value,
-        );
-    }
-
-    // Token entry functions
-
-    inline fun token_object(creator: &signer, collection: &String, name: &String): Object<AptosToken> {
-        let token_addr = token::create_token_address(&signer::address_of(creator), collection, name);
-        object::address_to_object<AptosToken>(token_addr)
-    }
-
-    entry fun burn_call(
-        creator: &signer,
-        collection: String,
-        name: String,
-    ) acquires AptosToken {
-        burn(creator, token_object(creator, &collection, &name));
-    }
-
-    entry fun freeze_transfer_call(
-        creator: &signer,
-        collection: String,
-        name: String,
-    ) acquires AptosCollection, AptosToken {
-        freeze_transfer(creator, token_object(creator, &collection, &name));
-    }
-
-    entry fun unfreeze_transfer_call(
-        creator: &signer,
-        collection: String,
-        name: String,
-    ) acquires AptosCollection, AptosToken {
-        unfreeze_transfer(creator, token_object(creator, &collection, &name));
-    }
-
-    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);
-    }
-
-    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);
-    }
-
-    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);
+        property_map::update_typed(&aptos_token.property_mutator_ref, &key, value);
     }
 
-    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);
-    }
-
-    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);
-    }
-
-    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);
-    }
-
-    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);
-    }
+    // Collection accessors
 
-    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);
+    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)
     }
 
-    // Collection accessors
-
     inline fun borrow_collection<T: key>(token: &Object<T>): &AptosCollection {
         let collection_address = object::object_address(token);
         assert!(
@@ -660,7 +541,7 @@ module token_objects::aptos_token {
         borrow_global<AptosCollection>(collection_address)
     }
 
-    public fun set_collection_description<T: key>(
+    public entry fun set_collection_description<T: key>(
         creator: &signer,
         collection: Object<T>,
         description: String,
@@ -686,55 +567,39 @@ module token_objects::aptos_token {
         royalty::update(option::borrow(&aptos_collection.royalty_mutator_ref), royalty);
     }
 
-    public fun set_collection_uri<T: key>(
+    entry fun set_collection_royalties_call<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);
-    }
-
-    // Collection entry functions
-
-    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)
-    }
-
-    entry fun set_collection_description_call(
-        creator: &signer,
-        collection: String,
-        description: String,
-    ) acquires AptosCollection {
-        set_collection_description(creator, collection_object(creator, &collection), description);
-    }
-
-    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);
+        set_collection_royalties(creator, collection, royalty);
     }
 
-    entry fun set_collection_uri_call(
+    public entry fun set_collection_uri<T: key>(
         creator: &signer,
-        collection: String,
+        collection: Object<T>,
         uri: String,
     ) acquires AptosCollection {
-        set_collection_uri(creator, collection_object(creator, &collection), uri);
+        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);
     }
 
     // Tests
 
+    #[test_only]
+    inline fun token_object(creator: &signer, collection: &String, name: &String): Object<AptosToken> {
+        let token_addr = token::create_token_address(&signer::address_of(creator), collection, name);
+        object::address_to_object<AptosToken>(token_addr)
+    }
+
+
     #[test_only]
     use std::string;
 
@@ -787,7 +652,7 @@ module token_objects::aptos_token {
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        freeze_transfer_call(creator, collection_name, token_name);
+        freeze_transfer(creator, token);
         object::transfer(creator, token, @0x345);
     }
 
@@ -798,8 +663,8 @@ module token_objects::aptos_token {
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        freeze_transfer_call(creator, collection_name, token_name);
-        unfreeze_transfer_call(creator, collection_name, token_name);
+        freeze_transfer(creator, token);
+        unfreeze_transfer(creator, token);
         object::transfer(creator, token, @0x345);
     }
 
@@ -822,7 +687,7 @@ module token_objects::aptos_token {
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        freeze_transfer_call(creator, collection_name, token_name);
+        freeze_transfer(creator, token);
         unfreeze_transfer(another, token);
     }
 
@@ -836,7 +701,7 @@ module token_objects::aptos_token {
 
         let description = string::utf8(b"not");
         assert!(token::description(token) != description, 0);
-        set_description_call(creator, collection_name, token_name, description);
+        set_description(creator, token, description);
         assert!(token::description(token) == description, 1);
     }
 
@@ -847,9 +712,9 @@ module token_objects::aptos_token {
         let token_name = string::utf8(b"token name");
 
         create_collection_helper(creator, collection_name, false);
-        mint_helper(creator, collection_name, token_name);
+        let token = mint_helper(creator, collection_name, token_name);
 
-        set_description_call(creator, collection_name, token_name, string::utf8(b""));
+        set_description(creator, token, string::utf8(b""));
     }
 
     #[test(creator = @0x123, noncreator = @0x456)]
@@ -878,7 +743,7 @@ module token_objects::aptos_token {
 
         let name = string::utf8(b"not");
         assert!(token::name(token) != name, 0);
-        set_name_call(creator, collection_name, token_name, name);
+        set_name(creator, token, name);
         assert!(token::name(token) == name, 1);
     }
 
@@ -889,9 +754,9 @@ module token_objects::aptos_token {
         let token_name = string::utf8(b"token name");
 
         create_collection_helper(creator, collection_name, false);
-        mint_helper(creator, collection_name, token_name);
+        let token = mint_helper(creator, collection_name, token_name);
 
-        set_name_call(creator, collection_name, token_name, string::utf8(b""));
+        set_name(creator, token, string::utf8(b""));
     }
 
     #[test(creator = @0x123, noncreator = @0x456)]
@@ -920,7 +785,7 @@ module token_objects::aptos_token {
 
         let uri = string::utf8(b"not");
         assert!(token::uri(token) != uri, 0);
-        set_uri_call(creator, collection_name, token_name, uri);
+        set_uri(creator, token, uri);
         assert!(token::uri(token) == uri, 1);
     }
 
@@ -931,9 +796,9 @@ module token_objects::aptos_token {
         let token_name = string::utf8(b"token name");
 
         create_collection_helper(creator, collection_name, false);
-        mint_helper(creator, collection_name, token_name);
+        let token = mint_helper(creator, collection_name, token_name);
 
-        set_uri_call(creator, collection_name, token_name, string::utf8(b""));
+        set_uri(creator, token, string::utf8(b""));
     }
 
     #[test(creator = @0x123, noncreator = @0x456)]
@@ -953,7 +818,7 @@ module token_objects::aptos_token {
     }
 
     #[test(creator = @0x123)]
-    entry fun test_burnable(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_burnable(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
 
@@ -968,7 +833,7 @@ module token_objects::aptos_token {
 
     #[test(creator = @0x123)]
     #[expected_failure(abort_code = 0x50004, location = Self)]
-    entry fun test_not_burnable(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_not_burnable(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
 
@@ -980,7 +845,7 @@ module token_objects::aptos_token {
 
     #[test(creator = @0x123, noncreator = @0x456)]
     #[expected_failure(abort_code = 0x50002, location = Self)]
-    entry fun test_burn_non_creator(
+    fun test_burn_non_creator(
         creator: &signer,
         noncreator: &signer,
     ) acquires AptosCollection, AptosToken {
@@ -999,7 +864,7 @@ module token_objects::aptos_token {
         let collection = create_collection_helper(creator, collection_name, true);
         let value = string::utf8(b"not");
         assert!(collection::description(collection) != value, 0);
-        set_collection_description_call(creator, collection_name, value);
+        set_collection_description(creator, collection, value);
         assert!(collection::description(collection) == value, 1);
     }
 
@@ -1007,8 +872,8 @@ module token_objects::aptos_token {
     #[expected_failure(abort_code = 0x50003, location = Self)]
     fun test_set_immutable_collection_description(creator: &signer) acquires AptosCollection {
         let collection_name = string::utf8(b"collection name");
-        create_collection_helper(creator, collection_name, false);
-        set_collection_description_call(creator, collection_name, string::utf8(b""));
+        let collection = create_collection_helper(creator, collection_name, false);
+        set_collection_description(creator, collection, string::utf8(b""));
     }
 
     #[test(creator = @0x123, noncreator = @0x456)]
@@ -1028,7 +893,7 @@ module token_objects::aptos_token {
         let collection = create_collection_helper(creator, collection_name, true);
         let value = string::utf8(b"not");
         assert!(collection::uri(collection) != value, 0);
-        set_collection_uri_call(creator, collection_name, value);
+        set_collection_uri(creator, collection, value);
         assert!(collection::uri(collection) == value, 1);
     }
 
@@ -1036,8 +901,8 @@ module token_objects::aptos_token {
     #[expected_failure(abort_code = 0x50003, location = Self)]
     fun test_set_immutable_collection_uri(creator: &signer) acquires AptosCollection {
         let collection_name = string::utf8(b"collection name");
-        create_collection_helper(creator, collection_name, false);
-        set_collection_uri_call(creator, collection_name, string::utf8(b""));
+        let collection = create_collection_helper(creator, collection_name, false);
+        set_collection_uri(creator, collection, string::utf8(b""));
     }
 
     #[test(creator = @0x123, noncreator = @0x456)]
@@ -1052,7 +917,7 @@ module token_objects::aptos_token {
     }
 
     #[test(creator = @0x123)]
-    entry fun test_property_add(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_property_add(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
         let property_name = string::utf8(b"u8");
@@ -1060,26 +925,26 @@ module token_objects::aptos_token {
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        add_property_call(creator, collection_name, token_name, property_name, property_type, vector [ 0x08 ]);
+        add_property(creator, token, property_name, property_type, vector [ 0x08 ]);
 
         assert!(property_map::read_u8(&token, &property_name) == 0x8, 0);
     }
 
     #[test(creator = @0x123)]
-    entry fun test_property_typed_add(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_property_typed_add(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
         let property_name = string::utf8(b"u8");
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        add_typed_property_call<u8>(creator, collection_name, token_name, property_name, 0x8);
+        add_typed_property<AptosToken, u8>(creator, token, property_name, 0x8);
 
         assert!(property_map::read_u8(&token, &property_name) == 0x8, 0);
     }
 
     #[test(creator = @0x123)]
-    entry fun test_property_update(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_property_update(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
         let property_name = string::utf8(b"bool");
@@ -1087,45 +952,45 @@ module token_objects::aptos_token {
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        update_property_call(creator, collection_name, token_name, property_name, property_type, vector [ 0x00 ]);
+        update_property(creator, token, property_name, property_type, vector [ 0x00 ]);
 
         assert!(!property_map::read_bool(&token, &property_name), 0);
     }
 
     #[test(creator = @0x123)]
-    entry fun test_property_update_typed(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_property_update_typed(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
         let property_name = string::utf8(b"bool");
 
         create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
-        update_typed_property_call<bool>(creator, collection_name, token_name, property_name, false);
+        update_typed_property<AptosToken, bool>(creator, token, property_name, false);
 
         assert!(!property_map::read_bool(&token, &property_name), 0);
     }
 
     #[test(creator = @0x123)]
-    entry fun test_property_remove(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_property_remove(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
         let property_name = string::utf8(b"bool");
 
         create_collection_helper(creator, collection_name, true);
-        mint_helper(creator, collection_name, token_name);
-        remove_property_call(creator, collection_name, token_name, property_name);
+        let token = mint_helper(creator, collection_name, token_name);
+        remove_property(creator, token, property_name);
     }
 
     #[test(creator = @0x123)]
-    entry fun test_royalties(creator: &signer) acquires AptosCollection, AptosToken {
+    fun test_royalties(creator: &signer) acquires AptosCollection, AptosToken {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
 
-        create_collection_helper(creator, collection_name, true);
+        let collection = create_collection_helper(creator, collection_name, true);
         let token = mint_helper(creator, collection_name, token_name);
 
         let royalty_before = option::extract(&mut token::royalty(token));
-        set_collection_royalties_call(creator, collection_name, 2, 3, @0x444);
+        set_collection_royalties_call(creator, collection, 2, 3, @0x444);
         let royalty_after = option::extract(&mut token::royalty(token));
         assert!(royalty_before != royalty_after, 0);
     }
diff --git a/aptos-move/move-examples/token_objects/sources/collection.move b/aptos-move/framework/aptos-token-objects/sources/collection.move
similarity index 89%
rename from aptos-move/move-examples/token_objects/sources/collection.move
rename to aptos-move/framework/aptos-token-objects/sources/collection.move
index 2303659b6e86f..994f6eda46287 100644
--- a/aptos-move/move-examples/token_objects/sources/collection.move
+++ b/aptos-move/framework/aptos-token-objects/sources/collection.move
@@ -20,7 +20,7 @@
 /// * Consider supporting changing the aspects of supply with the MutatorRef.
 /// * Add aggregator support when added to framework
 /// * Update Object<T> to be viable input as a transaction arg and then update all readers as view.
-module token_objects::collection {
+module aptos_token_objects::collection {
     use std::error;
     use std::option::{Self, Option};
     use std::signer;
@@ -29,9 +29,9 @@ module token_objects::collection {
     use aptos_framework::event;
     use aptos_framework::object::{Self, ConstructorRef, Object};
 
-    use token_objects::royalty::{Self, Royalty};
+    use aptos_token_objects::royalty::{Self, Royalty};
 
-    friend token_objects::token;
+    friend aptos_token_objects::token;
 
     /// The collections supply is at its maximum amount
     const EEXCEEDS_MAX_SUPPLY: u64 = 1;
@@ -54,17 +54,17 @@ module token_objects::collection {
         mutation_events: event::EventHandle<MutationEvent>,
     }
 
+    /// This enables mutating description and URI by higher level services.
+    struct MutatorRef has drop, store {
+        self: address,
+    }
+
     /// Contains the mutated fields name. This makes the life of indexers easier, so that they can
     /// directly understand the behavior in a writeset.
     struct MutationEvent has drop, store {
         mutated_field_name: String,
     }
 
-    /// This enables mutating description and URI by higher level services.
-    struct MutatorRef has drop, store {
-        self: address,
-    }
-
     #[resource_group_member(group = aptos_framework::object::ObjectGroup)]
     /// Fixed supply tracker, this is useful for ensuring that a limited number of tokens are minted.
     struct FixedSupply has key {
@@ -151,6 +151,9 @@ module token_objects::collection {
             royalty::init(&constructor_ref, option::extract(&mut royalty))
         };
 
+        let transfer_ref = object::generate_transfer_ref(&constructor_ref);
+        object::disable_ungated_transfer(&transfer_ref);
+
         constructor_ref
     }
 
@@ -192,48 +195,6 @@ module token_objects::collection {
         }
     }
 
-    /// Entry function for creating a collection
-    public entry fun create_collection(
-        creator: &signer,
-        description: String,
-        name: String,
-        uri: String,
-        max_supply: u64,
-        enable_royalty: bool,
-        royalty_numerator: u64,
-        royalty_denominator: u64,
-        royalty_payee_address: address,
-    ) {
-        let royalty = if (enable_royalty) {
-            option::some(royalty::create(
-                royalty_numerator,
-                royalty_denominator,
-                royalty_payee_address,
-            ))
-        } else {
-            option::none()
-        };
-
-        if (max_supply == 0) {
-            create_untracked_collection(
-                creator,
-                description,
-                name,
-                royalty,
-                uri,
-            )
-        } else {
-            create_fixed_collection(
-                creator,
-                description,
-                max_supply,
-                name,
-                royalty,
-                uri,
-            )
-        };
-    }
-
     /// Creates a MutatorRef, which gates the ability to mutate any fields that support mutation.
     public fun generate_mutator_ref(ref: &ConstructorRef): MutatorRef {
         let object = object::object_from_constructor_ref<Collection>(ref);
@@ -292,10 +253,7 @@ module token_objects::collection {
         borrow_global_mut<Collection>(mutator_ref.self)
     }
 
-    public fun set_description(
-        mutator_ref: &MutatorRef,
-        description: String,
-    ) acquires Collection {
+    public fun set_description(mutator_ref: &MutatorRef, description: String) acquires Collection {
         let collection = borrow_mut(mutator_ref);
         collection.description = description;
         event::emit_event(
@@ -304,10 +262,7 @@ module token_objects::collection {
         );
     }
 
-    public fun set_uri(
-        mutator_ref: &MutatorRef,
-        uri: String,
-    ) acquires Collection {
+    public fun set_uri(mutator_ref: &MutatorRef, uri: String) acquires Collection {
         let collection = borrow_mut(mutator_ref);
         collection.uri = uri;
         event::emit_event(
@@ -319,6 +274,7 @@ module token_objects::collection {
     // Tests
 
     #[test(creator = @0x123, trader = @0x456)]
+    #[expected_failure(abort_code = 0x50003, location = aptos_framework::object)]
     entry fun test_create_and_transfer(creator: &signer, trader: &signer) {
         let creator_address = signer::address_of(creator);
         let collection_name = string::utf8(b"collection name");
@@ -329,7 +285,6 @@ module token_objects::collection {
         );
         assert!(object::owner(collection) == creator_address, 1);
         object::transfer(creator, collection, signer::address_of(trader));
-        assert!(object::owner(collection) == signer::address_of(trader), 1);
     }
 
     #[test(creator = @0x123)]
diff --git a/aptos-move/move-examples/token_objects/sources/property_map.move b/aptos-move/framework/aptos-token-objects/sources/property_map.move
similarity index 98%
rename from aptos-move/move-examples/token_objects/sources/property_map.move
rename to aptos-move/framework/aptos-token-objects/sources/property_map.move
index e5d34812f9a94..e9d0950983c27 100644
--- a/aptos-move/move-examples/token_objects/sources/property_map.move
+++ b/aptos-move/framework/aptos-token-objects/sources/property_map.move
@@ -1,7 +1,7 @@
 /// PropertyMap provides generic metadata support for AptosToken. It is a  specialization of
 /// SimpleMap that enforces strict typing with minimal storage use by using constant u64 to
 /// represent types and storing values in bcs format.
-module token_objects::property_map {
+module aptos_token_objects::property_map {
     use std::bcs;
     use std::vector;
     use std::error;
@@ -35,6 +35,7 @@ module token_objects::property_map {
     const MAX_PROPERTY_MAP_SIZE: u64 = 1000;
     const MAX_PROPERTY_NAME_LENGTH: u64 = 128;
 
+    // PropertyValue::type
     const BOOL: u8 = 0;
     const U8: u8 = 1;
     const U16: u8 = 2;
@@ -49,7 +50,7 @@ module token_objects::property_map {
     // Structs
 
     #[resource_group_member(group = aptos_framework::object::ObjectGroup)]
-    struct PropertyMap has key {
+    struct PropertyMap has drop, key {
         inner: SimpleMap<String, PropertyValue>,
     }
 
@@ -67,6 +68,10 @@ module token_objects::property_map {
         move_to(&signer, container);
     }
 
+    public fun burn(ref: MutatorRef) acquires PropertyMap {
+        move_from<PropertyMap>(ref.self);
+    }
+
     /// Helper for external entry functions to produce a valid container for property values.
     public fun prepare_input(
         keys: vector<String>,
@@ -242,7 +247,7 @@ module token_objects::property_map {
         let (type, value) = read(object, key);
         assert!(
             type == type_info::type_name<V>(),
-            error::invalid_argument(ETYPE_INVALID),
+            error::invalid_argument(ETYPE_MISMATCH),
         );
         value
     }
@@ -580,7 +585,7 @@ module token_objects::property_map {
     }
 
     #[test(creator = @0x123)]
-    #[expected_failure(abort_code = 0x10008, location = Self)]
+    #[expected_failure(abort_code = 0x10005, location = Self)]
     fun test_invalid_read(creator: &signer) acquires PropertyMap {
         let constructor_ref = object::create_named_object(creator, b"");
         let object = object::object_from_constructor_ref<object::ObjectCore>(&constructor_ref);
diff --git a/aptos-move/move-examples/token_objects/sources/royalty.move b/aptos-move/framework/aptos-token-objects/sources/royalty.move
similarity index 97%
rename from aptos-move/move-examples/token_objects/sources/royalty.move
rename to aptos-move/framework/aptos-token-objects/sources/royalty.move
index 5d1c47b0c4273..e27be8ad59483 100644
--- a/aptos-move/move-examples/token_objects/sources/royalty.move
+++ b/aptos-move/framework/aptos-token-objects/sources/royalty.move
@@ -1,13 +1,13 @@
 /// This defines an object-based Royalty. The royalty can be applied to either a collection or a
 /// token. Applications should read the royalty from the token, as it will read the appropriate
 /// royalty.
-module token_objects::royalty {
+module aptos_token_objects::royalty {
     use std::error;
     use std::option::{Self, Option};
 
     use aptos_framework::object::{Self, ConstructorRef, ExtendRef, Object};
 
-    friend token_objects::token;
+    friend aptos_token_objects::token;
 
     // Enforce that the royalty is between 0 and 1
     const EROYALTY_EXCEEDS_MAXIMUM: u64 = 1;
@@ -26,6 +26,7 @@ module token_objects::royalty {
         payee_address: address,
     }
 
+    /// This enables creating or overwriting a MutatorRef.
     struct MutatorRef has drop, store {
         inner: ExtendRef,
     }
diff --git a/aptos-move/move-examples/token_objects/sources/token.move b/aptos-move/framework/aptos-token-objects/sources/token.move
similarity index 95%
rename from aptos-move/move-examples/token_objects/sources/token.move
rename to aptos-move/framework/aptos-token-objects/sources/token.move
index 98398a318b026..1b4be5d1b27f7 100644
--- a/aptos-move/move-examples/token_objects/sources/token.move
+++ b/aptos-move/framework/aptos-token-objects/sources/token.move
@@ -6,7 +6,7 @@
 ///
 /// TODO:
 /// * Update Object<T> to be a viable input as a transaction arg and then update all readers as view.
-module token_objects::token {
+module aptos_token_objects::token {
     use std::error;
     use std::option::{Self, Option};
     use std::string::{Self, String};
@@ -16,8 +16,8 @@ module token_objects::token {
     use aptos_framework::event;
     use aptos_framework::object::{Self, ConstructorRef, Object};
 
-    use token_objects::collection::{Self, Collection};
-    use token_objects::royalty::{Self, Royalty};
+    use aptos_token_objects::collection::{Self, Collection};
+    use aptos_token_objects::royalty::{Self, Royalty};
 
     // The token does not exist
     const ETOKEN_DOES_NOT_EXIST: u64 = 1;
@@ -56,17 +56,17 @@ module token_objects::token {
         self: Option<address>,
     }
 
+    /// This enables mutating descritpion and URI by higher level services.
+    struct MutatorRef has drop, store {
+        self: address,
+    }
+
     /// Contains the mutated fields name. This makes the life of indexers easier, so that they can
     /// directly understand the behavior in a writeset.
     struct MutationEvent has drop, store {
         mutated_field_name: String,
     }
 
-    /// This enables mutating descritpion and URI by higher level services.
-    struct MutatorRef has drop, store {
-        self: address,
-    }
-
     /// Creates a new token object and returns the ConstructorRef for additional specialization.
     public fun create(
         creator: &signer,
@@ -239,10 +239,7 @@ module token_objects::token {
         collection::decrement_supply(&collection);
     }
 
-    public fun set_description(
-        mutator_ref: &MutatorRef,
-        description: String,
-    ) acquires Token {
+    public fun set_description(mutator_ref: &MutatorRef, description: String) acquires Token {
         let token = borrow_mut(mutator_ref);
         token.description = description;
         event::emit_event(
@@ -251,10 +248,7 @@ module token_objects::token {
         );
     }
 
-    public fun set_name(
-        mutator_ref: &MutatorRef,
-        name: String,
-    ) acquires Token {
+    public fun set_name(mutator_ref: &MutatorRef, name: String) acquires Token {
         let token = borrow_mut(mutator_ref);
         if (option::is_none(&token.creation_name)) {
             option::fill(&mut token.creation_name, token.name)
@@ -266,10 +260,7 @@ module token_objects::token {
         );
     }
 
-    public fun set_uri(
-        mutator_ref: &MutatorRef,
-        uri: String,
-    ) acquires Token {
+    public fun set_uri(mutator_ref: &MutatorRef, uri: String) acquires Token {
         let token = borrow_mut(mutator_ref);
         token.uri = uri;
         event::emit_event(
@@ -302,16 +293,15 @@ module token_objects::token {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
 
-        collection::create_collection(
+        let creator_address = signer::address_of(creator);
+        let expected_royalty = royalty::create(10, 1000, creator_address);
+        collection::create_fixed_collection(
             creator,
             string::utf8(b"collection description"),
+            5,
             collection_name,
+            option::some(expected_royalty),
             string::utf8(b"collection uri"),
-            5,
-            true,
-            10,
-            1000,
-            signer::address_of(creator),
         );
 
         create(
@@ -323,10 +313,8 @@ module token_objects::token {
             string::utf8(b"token uri"),
         );
 
-        let creator_address = signer::address_of(creator);
         let token_addr = create_token_address(&creator_address, &collection_name, &token_name);
         let token = object::address_to_object<Token>(token_addr);
-        let expected_royalty = royalty::create(10, 1000, creator_address);
         assert!(option::some(expected_royalty) == royalty(token), 0);
     }
 
@@ -359,7 +347,7 @@ module token_objects::token {
     }
 
     #[test(creator = @0x123)]
-    #[expected_failure(abort_code = 0x20001, location = token_objects::collection)]
+    #[expected_failure(abort_code = 0x20001, location = aptos_token_objects::collection)]
     fun test_too_many_tokens(creator: &signer) {
         let collection_name = string::utf8(b"collection name");
         let token_name = string::utf8(b"token name");
@@ -484,16 +472,13 @@ module token_objects::token {
 
     #[test_only]
     fun create_collection_helper(creator: &signer, collection_name: String, max_supply: u64) {
-        collection::create_collection(
+        collection::create_fixed_collection(
             creator,
             string::utf8(b"collection description"),
+            max_supply,
             collection_name,
+            option::none(),
             string::utf8(b"collection uri"),
-            max_supply,
-            false,
-            0,
-            0,
-            signer::address_of(creator),
         );
     }
 
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
new file mode 100644
index 0000000000000..ee0982cfbf492
--- /dev/null
+++ b/aptos-move/framework/cached-packages/src/aptos_token_objects_sdk_builder.rs
@@ -0,0 +1,374 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+// This file was generated. Do not modify!
+//
+// To update this code, run: `cargo run --release -p framework`.
+
+// Conversion library between a structured representation of a Move script call (`ScriptCall`) and the
+// standard BCS-compatible representation used in Aptos transactions (`Script`).
+//
+// This code was generated by compiling known Script interfaces ("ABIs") with the tool `aptos-sdk-builder`.
+
+#![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},
+};
+
+type Bytes = Vec<u8>;
+
+/// Structured representation of a call into a known Move entry function.
+/// ```ignore
+/// impl EntryFunctionCall {
+///     pub fn encode(self) -> TransactionPayload { .. }
+///     pub fn decode(&TransactionPayload) -> Option<EntryFunctionCall> { .. }
+/// }
+/// ```
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[cfg_attr(feature = "fuzzing", derive(proptest_derive::Arbitrary))]
+#[cfg_attr(feature = "fuzzing", proptest(no_params))]
+pub enum EntryFunctionCall {
+    /// Create a new collection
+    AptosTokenCreateCollection {
+        description: Vec<u8>,
+        max_supply: u64,
+        name: Vec<u8>,
+        uri: Vec<u8>,
+        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,
+    },
+
+    /// With an existing collection, directly mint a viable token into the creators account.
+    AptosTokenMint {
+        collection: Vec<u8>,
+        description: Vec<u8>,
+        name: Vec<u8>,
+        uri: Vec<u8>,
+        property_keys: Vec<Vec<u8>>,
+        property_types: Vec<Vec<u8>>,
+        property_values: Vec<Vec<u8>>,
+    },
+
+    /// With an existing collection, directly mint a soul bound token into the recipient's account.
+    AptosTokenMintSoulBound {
+        collection: Vec<u8>,
+        description: Vec<u8>,
+        name: Vec<u8>,
+        uri: Vec<u8>,
+        property_keys: Vec<Vec<u8>>,
+        property_types: Vec<Vec<u8>>,
+        property_values: Vec<Vec<u8>>,
+        soul_bound_to: AccountAddress,
+    },
+}
+
+impl EntryFunctionCall {
+    /// Build an Aptos `TransactionPayload` from a structured object `EntryFunctionCall`.
+    pub fn encode(self) -> TransactionPayload {
+        use EntryFunctionCall::*;
+        match self {
+            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,
+            ),
+            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,
+            ),
+        }
+    }
+
+    /// Try to recognize an Aptos `TransactionPayload` and convert it into a structured object `EntryFunctionCall`.
+    pub fn decode(payload: &TransactionPayload) -> Option<EntryFunctionCall> {
+        if let TransactionPayload::EntryFunction(script) = payload {
+            match SCRIPT_FUNCTION_DECODER_MAP.get(&format!(
+                "{}_{}",
+                script.module().name(),
+                script.function()
+            )) {
+                Some(decoder) => decoder(payload),
+                None => None,
+            }
+        } else {
+            None
+        }
+    }
+}
+
+/// Create a new collection
+pub fn aptos_token_create_collection(
+    description: Vec<u8>,
+    max_supply: u64,
+    name: Vec<u8>,
+    uri: Vec<u8>,
+    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(),
+        ],
+    ))
+}
+
+/// With an existing collection, directly mint a viable token into the creators account.
+pub fn aptos_token_mint(
+    collection: Vec<u8>,
+    description: Vec<u8>,
+    name: Vec<u8>,
+    uri: Vec<u8>,
+    property_keys: Vec<Vec<u8>>,
+    property_types: Vec<Vec<u8>>,
+    property_values: Vec<Vec<u8>>,
+) -> 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<u8>,
+    description: Vec<u8>,
+    name: Vec<u8>,
+    uri: Vec<u8>,
+    property_keys: Vec<Vec<u8>>,
+    property_types: Vec<Vec<u8>>,
+    property_values: Vec<Vec<u8>>,
+    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(),
+        ],
+    ))
+}
+mod decoder {
+    use super::*;
+    pub fn aptos_token_create_collection(
+        payload: &TransactionPayload,
+    ) -> Option<EntryFunctionCall> {
+        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_mint(payload: &TransactionPayload) -> Option<EntryFunctionCall> {
+        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<EntryFunctionCall> {
+        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
+        }
+    }
+}
+
+type EntryFunctionDecoderMap = std::collections::HashMap<
+    String,
+    Box<
+        dyn Fn(&TransactionPayload) -> Option<EntryFunctionCall>
+            + std::marker::Sync
+            + std::marker::Send,
+    >,
+>;
+
+static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy<EntryFunctionDecoderMap> =
+    once_cell::sync::Lazy::new(|| {
+        let mut map: EntryFunctionDecoderMap = std::collections::HashMap::new();
+        map.insert(
+            "aptos_token_create_collection".to_string(),
+            Box::new(decoder::aptos_token_create_collection),
+        );
+        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
+    });
diff --git a/aptos-move/framework/src/aptos.rs b/aptos-move/framework/src/aptos.rs
index 90616474e195e..845756d18fd24 100644
--- a/aptos-move/framework/src/aptos.rs
+++ b/aptos-move/framework/src/aptos.rs
@@ -67,6 +67,10 @@ impl ReleaseTarget {
                 "aptos-token",
                 Some("cached-packages/src/aptos_token_sdk_builder.rs"),
             ),
+            (
+                "aptos-token-objects",
+                Some("cached-packages/src/aptos_token_objects_sdk_builder.rs"),
+            ),
         ];
         // Currently we don't have experimental packages only included in particular targets.
         result
@@ -168,12 +172,14 @@ static NAMED_ADDRESSES: Lazy<BTreeMap<String, NumericalAddress>> = Lazy::new(||
     let mut result = BTreeMap::new();
     let zero = NumericalAddress::parse_str("0x0").unwrap();
     let one = NumericalAddress::parse_str("0x1").unwrap();
-    let two = NumericalAddress::parse_str("0x2").unwrap();
+    let three = NumericalAddress::parse_str("0x3").unwrap();
+    let four = NumericalAddress::parse_str("0x4").unwrap();
     let resources = NumericalAddress::parse_str("0xA550C18").unwrap();
     result.insert("std".to_owned(), one);
     result.insert("aptos_std".to_owned(), one);
     result.insert("aptos_framework".to_owned(), one);
-    result.insert("aptos_token".to_owned(), two);
+    result.insert("aptos_token".to_owned(), three);
+    result.insert("aptos_token_objects".to_owned(), four);
     result.insert("core_resources".to_owned(), resources);
     result.insert("vm_reserved".to_owned(), zero);
     result
diff --git a/aptos-move/framework/tests/move_unit_test.rs b/aptos-move/framework/tests/move_unit_test.rs
index c8583531a88e0..f71d3b633e81c 100644
--- a/aptos-move/framework/tests/move_unit_test.rs
+++ b/aptos-move/framework/tests/move_unit_test.rs
@@ -66,3 +66,8 @@ fn move_stdlib_unit_tests() {
 fn move_token_unit_tests() {
     run_tests_for_pkg("aptos-token");
 }
+
+#[test]
+fn move_token_objects_unit_tests() {
+    run_tests_for_pkg("aptos-token-objects");
+}
diff --git a/aptos-move/move-examples/token_objects/Move.toml b/aptos-move/move-examples/token_objects/Move.toml
index 37d121899a9ad..b816afb63d495 100644
--- a/aptos-move/move-examples/token_objects/Move.toml
+++ b/aptos-move/move-examples/token_objects/Move.toml
@@ -7,3 +7,4 @@ token_objects = "_"
 
 [dependencies]
 AptosFramework = { local = "../../framework/aptos-framework" }
+AptosTokenObjects = { local = "../../framework/aptos-token-objects" }
diff --git a/aptos-move/move-examples/token_objects/sources/hero.move b/aptos-move/move-examples/token_objects/sources/hero.move
index 5484ed4eebc16..b5f639a447550 100644
--- a/aptos-move/move-examples/token_objects/sources/hero.move
+++ b/aptos-move/move-examples/token_objects/sources/hero.move
@@ -6,8 +6,8 @@ module token_objects::hero {
 
     use aptos_framework::object::{Self, ConstructorRef, Object};
 
-    use token_objects::collection;
-    use token_objects::token;
+    use aptos_token_objects::collection;
+    use aptos_token_objects::token;
 
     const ENOT_A_HERO: u64 = 1;
     const ENOT_A_WEAPON: u64 = 2;
diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs
index 32dce2d4ee25b..518a90db83f4f 100644
--- a/aptos-move/vm-genesis/src/lib.rs
+++ b/aptos-move/vm-genesis/src/lib.rs
@@ -420,6 +420,7 @@ pub fn default_features() -> Vec<FeatureFlag> {
         FeatureFlag::MULTISIG_ACCOUNTS,
         FeatureFlag::DELEGATION_POOLS,
         FeatureFlag::ED25519_PUBKEY_VALIDATE_RETURN_FALSE_WRONG_LENGTH,
+        FeatureFlag::STRUCT_CONSTRUCTORS,
     ]
 }
 
diff --git a/developer-docs-site/docs/guides/aptos-name-service-connector.md b/developer-docs-site/docs/guides/aptos-name-service-connector.md
index cfe8d679207d7..5489a28956594 100644
--- a/developer-docs-site/docs/guides/aptos-name-service-connector.md
+++ b/developer-docs-site/docs/guides/aptos-name-service-connector.md
@@ -70,7 +70,7 @@ The `AptosNamesConnector` component supports both mainnet and testnet. To connec
 
 ## Example
 The following example shows how to use the `AptosNamesConnector` component in a React application:
-<last image>
+<last image />
 
 
 - Add a ‘claim name’ button to any page in your application. This allows your users to directly create an Aptos name, giving them a human-readable .apt name for their Aptos wallet address. You can customize the look of the button to suit your application. Here is an example on the profile page of an NFT marketplace.
diff --git a/ecosystem/python/sdk/aptos_sdk/account_address.py b/ecosystem/python/sdk/aptos_sdk/account_address.py
index 4ca2049f52239..db49df3675d36 100644
--- a/ecosystem/python/sdk/aptos_sdk/account_address.py
+++ b/ecosystem/python/sdk/aptos_sdk/account_address.py
@@ -4,12 +4,20 @@
 from __future__ import annotations
 
 import hashlib
-from typing import List
+import unittest
 
 from . import ed25519
 from .bcs import Deserializer, Serializer
 
 
+class AuthKeyScheme:
+    Ed25519: bytes = b"\x00"
+    MultiEd25519: bytes = b"\x01"
+    DeriveObjectAddressFromGuid: bytes = b"\xFD"
+    DeriveObjectAddressFromSeed: bytes = b"\xFE"
+    DeriveResourceAccountAddress: bytes = b"\xFF"
+
+
 class AccountAddress:
     address: bytes
     LENGTH: int = 32
@@ -47,15 +55,48 @@ def from_hex(address: str) -> AccountAddress:
     @staticmethod
     def from_key(key: ed25519.PublicKey) -> AccountAddress:
         hasher = hashlib.sha3_256()
-        hasher.update(key.key.encode() + b"\x00")
+        hasher.update(key.key.encode())
+        hasher.update(AuthKeyScheme.Ed25519)
+        return AccountAddress(hasher.digest())
+
+    @staticmethod
+    def from_multi_ed25519(keys: ed25519.MultiPublicKey) -> AccountAddress:
+        hasher = hashlib.sha3_256()
+        hasher.update(keys.to_bytes())
+        hasher.update(AuthKeyScheme.MultiEd25519)
+        return AccountAddress(hasher.digest())
+
+    @staticmethod
+    def for_resource_account(creator: AccountAddress, seed: bytes) -> AccountAddress:
+        hasher = hashlib.sha3_256()
+        hasher.update(creator.address)
+        hasher.update(seed)
+        hasher.update(AuthKeyScheme.DeriveResourceAccountAddress)
         return AccountAddress(hasher.digest())
 
     @staticmethod
-    def from_multisig_schema(
-        keys: List[ed25519.PublicKey], threshold: int
+    def for_named_object(creator: AccountAddress, seed: bytes) -> AccountAddress:
+        hasher = hashlib.sha3_256()
+        hasher.update(creator.address)
+        hasher.update(seed)
+        hasher.update(AuthKeyScheme.DeriveObjectAddressFromSeed)
+        return AccountAddress(hasher.digest())
+
+    @staticmethod
+    def for_named_token(
+        creator: AccountAddress, collection_name: str, token_name: str
     ) -> AccountAddress:
-        multisig_public_key = ed25519.MultiEd25519PublicKey(keys, threshold)
-        return AccountAddress(multisig_public_key.auth_key())
+        collection_bytes = collection_name.encode()
+        token_bytes = token_name.encode()
+        return AccountAddress.for_named_object(
+            creator, collection_bytes + b"::" + token_bytes
+        )
+
+    @staticmethod
+    def for_named_collection(
+        creator: AccountAddress, collection_name: str
+    ) -> AccountAddress:
+        return AccountAddress.for_named_object(creator, collection_name.encode())
 
     @staticmethod
     def deserialize(deserializer: Deserializer) -> AccountAddress:
@@ -63,3 +104,56 @@ def deserialize(deserializer: Deserializer) -> AccountAddress:
 
     def serialize(self, serializer: Serializer):
         serializer.fixed_bytes(self.address)
+
+
+class Test(unittest.TestCase):
+    def test_multi_ed25519(self):
+        private_key_1 = ed25519.PrivateKey.from_hex(
+            "4e5e3be60f4bbd5e98d086d932f3ce779ff4b58da99bf9e5241ae1212a29e5fe"
+        )
+        private_key_2 = ed25519.PrivateKey.from_hex(
+            "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901"
+        )
+        multisig_public_key = ed25519.MultiPublicKey(
+            [private_key_1.public_key(), private_key_2.public_key()], 1
+        )
+
+        expected = AccountAddress.from_hex(
+            "835bb8c5ee481062946b18bbb3b42a40b998d6bf5316ca63834c959dc739acf0"
+        )
+        actual = AccountAddress.from_multi_ed25519(multisig_public_key)
+        self.assertEqual(actual, expected)
+
+    def test_resource_account(self):
+        base_address = AccountAddress.from_hex("b0b")
+        expected = AccountAddress.from_hex(
+            "ee89f8c763c27f9d942d496c1a0dcf32d5eacfe78416f9486b8db66155b163b0"
+        )
+        actual = AccountAddress.for_resource_account(base_address, b"\x0b\x00\x0b")
+        self.assertEqual(actual, expected)
+
+    def test_named_object(self):
+        base_address = AccountAddress.from_hex("b0b")
+        expected = AccountAddress.from_hex(
+            "f417184602a828a3819edf5e36285ebef5e4db1ba36270be580d6fd2d7bcc321"
+        )
+        actual = AccountAddress.for_named_object(base_address, b"bob's collection")
+        self.assertEqual(actual, expected)
+
+    def test_collection(self):
+        base_address = AccountAddress.from_hex("b0b")
+        expected = AccountAddress.from_hex(
+            "f417184602a828a3819edf5e36285ebef5e4db1ba36270be580d6fd2d7bcc321"
+        )
+        actual = AccountAddress.for_named_collection(base_address, "bob's collection")
+        self.assertEqual(actual, expected)
+
+    def test_token(self):
+        base_address = AccountAddress.from_hex("b0b")
+        expected = AccountAddress.from_hex(
+            "e20d1f22a5400ba7be0f515b7cbd00edc42dbcc31acc01e31128b2b5ddb3c56e"
+        )
+        actual = AccountAddress.for_named_token(
+            base_address, "bob's collection", "bob's token"
+        )
+        self.assertEqual(actual, expected)
diff --git a/ecosystem/python/sdk/aptos_sdk/aptos_token_client.py b/ecosystem/python/sdk/aptos_sdk/aptos_token_client.py
new file mode 100644
index 0000000000000..0efb0036acb26
--- /dev/null
+++ b/ecosystem/python/sdk/aptos_sdk/aptos_token_client.py
@@ -0,0 +1,574 @@
+# Copyright © Aptos Foundation
+# SPDX-License-Identifier: Apache-2.0
+
+from __future__ import annotations
+
+from typing import Any, List, Optional, Tuple
+
+from .account import Account
+from .account_address import AccountAddress
+from .async_client import RestClient
+from .bcs import Deserializer, Serializer
+from .transactions import (EntryFunction, TransactionArgument,
+                           TransactionPayload)
+from .type_tag import StructTag, TypeTag
+
+
+class Object:
+
+    allow_ungated_transfer: bool
+    owner: AccountAddress
+
+    struct_tag: str = "0x1::object::ObjectCore"
+
+    def __init__(self, allow_ungated_transfer, owner):
+        self.allow_ungated_transfer = allow_ungated_transfer
+        self.owner = owner
+
+    @staticmethod
+    def parse(resource: dict[str, Any]) -> Object:
+        return Object(
+            resource["allow_ungated_transfer"],
+            AccountAddress.from_hex(resource["owner"]),
+        )
+
+    def __str__(self) -> str:
+        return f"Object[allow_ungated_transfer: {self.allow_ungated_transfer}, owner: {self.owner}]"
+
+
+class Collection:
+
+    creator: AccountAddress
+    description: str
+    name: str
+    uri: str
+
+    struct_tag: str = "0x4::collection::Collection"
+
+    def __init__(self, creator, description, name, uri):
+        self.creator = creator
+        self.description = description
+        self.name = name
+        self.uri = uri
+
+    def __str__(self) -> str:
+        return f"AccountAddress[creator: {self.creator}, description: {self.description}, name: {self.name}, ur: {self.uri}]"
+
+    @staticmethod
+    def parse(resource: dict[str, Any]) -> Collection:
+        return Collection(
+            AccountAddress.from_hex(resource["creator"]),
+            resource["description"],
+            resource["name"],
+            resource["uri"],
+        )
+
+
+class Royalty:
+
+    numerator: int
+    denominator: int
+    payee_address: AccountAddress
+
+    struct_tag: str = "0x4::royalty::Royalty"
+
+    def __init__(self, numerator, denominator, payee_address):
+        self.numerator = numerator
+        self.denominator = denominator
+        self.payee_address = payee_address
+
+    def __str__(self) -> str:
+        return f"Royalty[numerator: {self.numerator}, denominator: {self.denominator}, payee_address: {self.payee_address}]"
+
+    @staticmethod
+    def parse(resource: dict[str, Any]) -> Royalty:
+        return Royalty(
+            resource["numerator"],
+            resource["denominator"],
+            AccountAddress.from_hex(resource["payee_address"]),
+        )
+
+
+class Token:
+
+    collection: AccountAddress
+    collection_id: int
+    creation_name: Optional[str]
+    description: str
+    name: str
+    uri: str
+
+    struct_tag: str = "0x4::token::Token"
+
+    def __init__(
+        self,
+        collection: AccountAddress,
+        collection_id: int,
+        creation_name: Optional[str],
+        description: str,
+        name: str,
+        uri: str,
+    ):
+        self.collection = collection
+        self.collection_id = collection_id
+        self.creation_name = creation_name
+        self.description = description
+        self.name = name
+        self.uri = uri
+
+    def __str__(self) -> str:
+        return f"Token[collection: {self.collection}, collection_id: {self.collection_id}, creation_name: {self.creation_name}, description: {self.description}, name: {self.name}, uri: {self.uri}]"
+
+    @staticmethod
+    def parse(resource: dict[str, Any]):
+        return Token(
+            AccountAddress.from_hex(resource["collection"]["inner"]),
+            int(resource["collection_id"]),
+            resource["creation_name"]["vec"][0]
+            if len(resource["creation_name"]["vec"]) == 1
+            else None,
+            resource["description"],
+            resource["name"],
+            resource["uri"],
+        )
+
+
+class InvalidPropertyType(Exception):
+    """Invalid property type"""
+
+    property_type: Any
+
+    def __init__(self, property_type: Any):
+        message = f"Unknown property type: {property_type}"
+        super().__init__(message)
+        self.property_type = property_type
+
+
+class Property:
+
+    name: str
+    property_type: str
+    value: Any
+
+    BOOL: int = 0
+    U8: int = 1
+    U16: int = 2
+    U32: int = 3
+    U64: int = 4
+    U128: int = 5
+    U256: int = 6
+    ADDRESS: int = 7
+    BYTE_VECTOR: int = 8
+    STRING: int = 9
+
+    def __init__(self, name: str, property_type: str, value: Any):
+        self.name = name
+        self.property_type = property_type
+        self.value = value
+
+    def __str__(self) -> str:
+        return f"Property[{self.name}, {self.property_type}, {self.value}]"
+
+    def serialize_value(self) -> bytes:
+        ser = Serializer()
+        if self.property_type == "bool":
+            Serializer.bool(ser, self.value)
+        elif self.property_type == "u8":
+            Serializer.u8(ser, self.value)
+        elif self.property_type == "u16":
+            Serializer.u16(ser, self.value)
+        elif self.property_type == "u32":
+            Serializer.u32(ser, self.value)
+        elif self.property_type == "u64":
+            Serializer.u64(ser, self.value)
+        elif self.property_type == "u128":
+            Serializer.u128(ser, self.value)
+        elif self.property_type == "u256":
+            Serializer.u256(ser, self.value)
+        elif self.property_type == "address":
+            Serializer.struct(ser, self.value)
+        elif self.property_type == "0x1::string::String":
+            Serializer.str(ser, self.value)
+        elif self.property_type == "vector<u8>":
+            Serializer.to_bytes(ser, self.value)
+        else:
+            raise InvalidPropertyType(self.property_type)
+        return ser.output()
+
+    def to_transaction_arguments(self) -> List[TransactionArgument]:
+        return [
+            TransactionArgument(self.name, Serializer.str),
+            TransactionArgument(self.property_type, Serializer.str),
+            TransactionArgument(self.serialize_value(), Serializer.to_bytes),
+        ]
+
+    @staticmethod
+    def parse(name: str, property_type: int, value: bytes) -> Property:
+        deserializer = Deserializer(value)
+
+        if property_type == Property.BOOL:
+            return Property(name, "bool", deserializer.bool())
+        elif property_type == Property.U8:
+            return Property(name, "u8", deserializer.u8())
+        elif property_type == Property.U16:
+            return Property(name, "u16", deserializer.u16())
+        elif property_type == Property.U32:
+            return Property(name, "u32", deserializer.u32())
+        elif property_type == Property.U64:
+            return Property(name, "u64", deserializer.u64())
+        elif property_type == Property.U128:
+            return Property(name, "u128", deserializer.u128())
+        elif property_type == Property.U256:
+            return Property(name, "u256", deserializer.u256())
+        elif property_type == Property.ADDRESS:
+            return Property(name, "address", AccountAddress.deserialize(deserializer))
+        elif property_type == Property.STRING:
+            return Property(name, "0x1::string::String", deserializer.str())
+        elif property_type == Property.BYTE_VECTOR:
+            return Property(name, "vector<u8>", deserializer.to_bytes())
+        raise InvalidPropertyType(property_type)
+
+    @staticmethod
+    def bool(name: str, value: bool) -> Property:
+        return Property(name, "bool", value)
+
+    @staticmethod
+    def u8(name: str, value: int) -> Property:
+        return Property(name, "u8", value)
+
+    @staticmethod
+    def u16(name: str, value: int) -> Property:
+        return Property(name, "u16", value)
+
+    @staticmethod
+    def u32(name: str, value: int) -> Property:
+        return Property(name, "u32", value)
+
+    @staticmethod
+    def u64(name: str, value: int) -> Property:
+        return Property(name, "u64", value)
+
+    @staticmethod
+    def u128(name: str, value: int) -> Property:
+        return Property(name, "u128", value)
+
+    @staticmethod
+    def u256(name: str, value: int) -> Property:
+        return Property(name, "u256", value)
+
+    @staticmethod
+    def string(name: str, value: str) -> Property:
+        return Property(name, "0x1::string::String", value)
+
+    @staticmethod
+    def bytes(name: str, value: bytes) -> Property:
+        return Property(name, "vector<u8>", value)
+
+
+class PropertyMap:
+
+    properties: List[Property]
+
+    struct_tag: str = "0x4::property_map::PropertyMap"
+
+    def __init__(self, properties: List[Property]):
+        self.properties = properties
+
+    def __str__(self) -> str:
+        response = "PropertyMap["
+        for prop in self.properties:
+            response += f"{prop}, "
+        if len(self.properties) > 0:
+            response = response[:-2]
+        response += "]"
+        return response
+
+    def to_tuple(self) -> Tuple[List[str], List[str], List[bytes]]:
+        names = []
+        types = []
+        values = []
+
+        for prop in self.properties:
+            names.append(prop.name)
+            types.append(prop.property_type)
+            values.append(prop.serialize_value())
+
+        return (names, types, values)
+
+    @staticmethod
+    def parse(resource: dict[str, Any]) -> PropertyMap:
+        props = resource["inner"]["data"]
+        properties = []
+        for prop in props:
+            properties.append(
+                Property.parse(
+                    prop["key"],
+                    prop["value"]["type"],
+                    bytes.fromhex(prop["value"]["value"][2:]),
+                )
+            )
+
+        return PropertyMap(properties)
+
+
+class ReadObject:
+    resource_map: dict[str, Any] = {
+        Collection.struct_tag: Collection,
+        Object.struct_tag: Object,
+        PropertyMap.struct_tag: PropertyMap,
+        Royalty.struct_tag: Royalty,
+        Token.struct_tag: Token,
+    }
+
+    resources: dict[Any, Any]
+
+    def __init__(self, resources: dict[Any, Any]):
+        self.resources = resources
+
+    def __str__(self) -> str:
+        response = "ReadObject"
+        for (resource_obj, value) in self.resources.items():
+            response += f"\n\t{resource_obj.struct_tag}: {value}"
+
+        return response
+
+
+class AptosTokenClient:
+    """A wrapper around reading and mutating AptosTokens also known as Token Objects"""
+
+    client: RestClient
+
+    def __init__(self, client: RestClient):
+        self.client = client
+
+    async def read_object(self, address: AccountAddress) -> ReadObject:
+        resources = {}
+
+        read_resources = await self.client.account_resources(address)
+        for resource in read_resources:
+            if resource["type"] in ReadObject.resource_map:
+                resource_obj = ReadObject.resource_map[resource["type"]]
+                resources[resource_obj] = resource_obj.parse(resource["data"])
+        return ReadObject(resources)
+
+    async def create_collection(
+        self,
+        creator: Account,
+        description: str,
+        max_supply: int,
+        name: str,
+        uri: str,
+        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: int,
+        royalty_denominator: int,
+    ) -> str:
+        transaction_arguments = [
+            TransactionArgument(description, Serializer.str),
+            TransactionArgument(max_supply, Serializer.u64),
+            TransactionArgument(name, Serializer.str),
+            TransactionArgument(uri, Serializer.str),
+            TransactionArgument(mutable_description, Serializer.bool),
+            TransactionArgument(mutable_royalty, Serializer.bool),
+            TransactionArgument(mutable_uri, Serializer.bool),
+            TransactionArgument(mutable_token_description, Serializer.bool),
+            TransactionArgument(mutable_token_name, Serializer.bool),
+            TransactionArgument(mutable_token_properties, Serializer.bool),
+            TransactionArgument(mutable_token_uri, Serializer.bool),
+            TransactionArgument(tokens_burnable_by_creator, Serializer.bool),
+            TransactionArgument(tokens_freezable_by_creator, Serializer.bool),
+            TransactionArgument(royalty_numerator, Serializer.u64),
+            TransactionArgument(royalty_denominator, Serializer.u64),
+        ]
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "create_collection",
+            [],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def mint_token(
+        self,
+        creator: Account,
+        collection: str,
+        description: str,
+        name: str,
+        uri: str,
+        properties: PropertyMap,
+    ) -> str:
+        (property_names, property_types, property_values) = properties.to_tuple()
+        transaction_arguments = [
+            TransactionArgument(collection, Serializer.str),
+            TransactionArgument(description, Serializer.str),
+            TransactionArgument(name, Serializer.str),
+            TransactionArgument(uri, Serializer.str),
+            TransactionArgument(
+                property_names, Serializer.sequence_serializer(Serializer.str)
+            ),
+            TransactionArgument(
+                property_types, Serializer.sequence_serializer(Serializer.str)
+            ),
+            TransactionArgument(
+                property_values, Serializer.sequence_serializer(Serializer.to_bytes)
+            ),
+        ]
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "mint",
+            [],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def mint_soul_bound_token(
+        self,
+        creator: Account,
+        collection: str,
+        description: str,
+        name: str,
+        uri: str,
+        properties: PropertyMap,
+        soul_bound_to: AccountAddress,
+    ):
+        (property_names, property_types, property_values) = properties.to_tuple()
+        transaction_arguments = [
+            TransactionArgument(collection, Serializer.str),
+            TransactionArgument(description, Serializer.str),
+            TransactionArgument(name, Serializer.str),
+            TransactionArgument(uri, Serializer.str),
+            TransactionArgument(
+                property_names, Serializer.sequence_serializer(Serializer.str)
+            ),
+            TransactionArgument(
+                property_types, Serializer.sequence_serializer(Serializer.str)
+            ),
+            TransactionArgument(
+                property_values, Serializer.sequence_serializer(Serializer.to_bytes)
+            ),
+            TransactionArgument(soul_bound_to, Serializer.struct),
+        ]
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "mint_soul_bound",
+            [],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def burn_token(self, creator: Account, token: AccountAddress) -> str:
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "burn",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            [TransactionArgument(token, Serializer.struct)],
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def freeze_token(self, creator: Account, token: AccountAddress) -> str:
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "freeze_transfer",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            [TransactionArgument(token, Serializer.struct)],
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def unfreeze_token(self, creator: Account, token: AccountAddress) -> str:
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "unfreeze_transfer",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            [TransactionArgument(token, Serializer.struct)],
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def add_token_property(
+        self, creator: Account, token: AccountAddress, prop: Property
+    ) -> str:
+        transaction_arguments = [TransactionArgument(token, Serializer.struct)]
+        transaction_arguments.extend(prop.to_transaction_arguments())
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "add_property",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def remove_token_property(
+        self, creator: Account, token: AccountAddress, name: str
+    ) -> str:
+        transaction_arguments = [
+            TransactionArgument(token, Serializer.struct),
+            TransactionArgument(name, Serializer.str),
+        ]
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "remove_property",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
+
+    async def update_token_property(
+        self, creator: Account, token: AccountAddress, prop: Property
+    ) -> str:
+        transaction_arguments = [TransactionArgument(token, Serializer.struct)]
+        transaction_arguments.extend(prop.to_transaction_arguments())
+
+        payload = EntryFunction.natural(
+            "0x4::aptos_token",
+            "update_property",
+            [TypeTag(StructTag.from_str("0x4::token::Token"))],
+            transaction_arguments,
+        )
+
+        signed_transaction = await self.client.create_bcs_signed_transaction(
+            creator, TransactionPayload(payload)
+        )
+        return await self.client.submit_bcs_transaction(signed_transaction)
diff --git a/ecosystem/python/sdk/aptos_sdk/async_client.py b/ecosystem/python/sdk/aptos_sdk/async_client.py
index 6850307c18a6b..81d0c770baa3b 100644
--- a/ecosystem/python/sdk/aptos_sdk/async_client.py
+++ b/ecosystem/python/sdk/aptos_sdk/async_client.py
@@ -116,6 +116,23 @@ async def account_resource(
             raise ApiError(f"{response.text} - {account_address}", response.status_code)
         return response.json()
 
+    async def account_resources(
+        self,
+        account_address: AccountAddress,
+        ledger_version: int = None,
+    ) -> List[Dict[str, Any]]:
+        if not ledger_version:
+            request = f"{self.base_url}/accounts/{account_address}/resources"
+        else:
+            request = f"{self.base_url}/accounts/{account_address}/resources?ledger_version={ledger_version}"
+
+        response = await self.client.get(request)
+        if response.status_code == 404:
+            raise AccountNotFound(f"{account_address}", account_address)
+        if response.status_code >= 400:
+            raise ApiError(f"{response.text} - {account_address}", response.status_code)
+        return response.json()
+
     async def get_table_item(
         self,
         handle: str,
@@ -729,15 +746,30 @@ async def fund_account(self, address: str, amount: int):
 class ApiError(Exception):
     """The API returned a non-success status code, e.g., >= 400"""
 
+    status_code: int
+
     def __init__(self, message: str, status_code: int):
         # Call the base class constructor with the parameters it needs
         super().__init__(message)
         self.status_code = status_code
 
 
+class AccountNotFound(Exception):
+    """The account was not found"""
+
+    account: AccountAddress
+
+    def __init__(self, message: str, account: AccountAddress):
+        # Call the base class constructor with the parameters it needs
+        super().__init__(message)
+        self.account = account
+
+
 class ResourceNotFound(Exception):
     """The underlying resource was not found"""
 
+    resource: str
+
     def __init__(self, message: str, resource: str):
         # Call the base class constructor with the parameters it needs
         super().__init__(message)
diff --git a/ecosystem/python/sdk/aptos_sdk/authenticator.py b/ecosystem/python/sdk/aptos_sdk/authenticator.py
index ca83870ce0677..89998eb1e1c13 100644
--- a/ecosystem/python/sdk/aptos_sdk/authenticator.py
+++ b/ecosystem/python/sdk/aptos_sdk/authenticator.py
@@ -146,8 +146,8 @@ def serialize(self, serializer: Serializer):
 
 
 class MultiEd25519Authenticator:
-    public_key: ed25519.MultiEd25519PublicKey
-    signature: ed25519.MultiEd25519Signature
+    public_key: ed25519.MultiPublicKey
+    signature: ed25519.MultiSignature
 
     def __init__(self, public_key, signature):
         self.public_key = public_key
diff --git a/ecosystem/python/sdk/aptos_sdk/ed25519.py b/ecosystem/python/sdk/aptos_sdk/ed25519.py
index c8fa3dd346439..2d3bc0e552cda 100644
--- a/ecosystem/python/sdk/aptos_sdk/ed25519.py
+++ b/ecosystem/python/sdk/aptos_sdk/ed25519.py
@@ -3,7 +3,6 @@
 
 from __future__ import annotations
 
-import hashlib
 import unittest
 from typing import List, Tuple
 
@@ -94,7 +93,7 @@ def serialize(self, serializer: Serializer):
         serializer.to_bytes(self.key.encode())
 
 
-class MultiEd25519PublicKey:
+class MultiPublicKey:
     keys: List[PublicKey]
     threshold: int
 
@@ -116,11 +115,6 @@ def __init__(self, keys: List[PublicKey], threshold: int, checked=True):
     def __str__(self) -> str:
         return f"{self.threshold}-of-{len(self.keys)} Multi-Ed25519 public key"
 
-    def auth_key(self) -> bytes:
-        hasher = hashlib.sha3_256()
-        hasher.update(self.to_bytes() + b"\x01")
-        return hasher.digest()
-
     def to_bytes(self) -> bytes:
         concatenated_keys = bytes()
         for key in self.keys:
@@ -128,11 +122,11 @@ def to_bytes(self) -> bytes:
         return concatenated_keys + bytes([self.threshold])
 
     @staticmethod
-    def from_bytes(key: bytes) -> MultiEd25519PublicKey:
+    def from_bytes(key: bytes) -> MultiPublicKey:
         # Get key count and threshold limits.
-        min_keys = MultiEd25519PublicKey.MIN_KEYS
-        max_keys = MultiEd25519PublicKey.MAX_KEYS
-        min_threshold = MultiEd25519PublicKey.MIN_THRESHOLD
+        min_keys = MultiPublicKey.MIN_KEYS
+        max_keys = MultiPublicKey.MAX_KEYS
+        min_threshold = MultiPublicKey.MIN_THRESHOLD
         # Get number of signers.
         n_signers = int(len(key) / PublicKey.LENGTH)
         assert (
@@ -149,7 +143,7 @@ def from_bytes(key: bytes) -> MultiEd25519PublicKey:
             start_byte = i * PublicKey.LENGTH
             end_byte = (i + 1) * PublicKey.LENGTH
             keys.append(PublicKey(VerifyKey(key[start_byte:end_byte])))
-        return MultiEd25519PublicKey(keys, threshold)
+        return MultiPublicKey(keys, threshold)
 
     def serialize(self, serializer: Serializer):
         serializer.to_bytes(self.to_bytes())
@@ -186,13 +180,13 @@ def serialize(self, serializer: Serializer):
         serializer.to_bytes(self.signature)
 
 
-class MultiEd25519Signature:
+class MultiSignature:
     signatures: List[Signature]
     bitmap: bytes
 
     def __init__(
         self,
-        public_key: MultiEd25519PublicKey,
+        public_key: MultiPublicKey,
         signatures_map: List[Tuple[PublicKey, Signature]],
     ):
         self.signatures = list()
@@ -261,16 +255,9 @@ def test_multisig(self):
             "1e70e49b78f976644e2c51754a2f049d3ff041869c669523ba95b172c7329901"
         )
         # Generate multisig public key with threshold of 1.
-        multisig_public_key = MultiEd25519PublicKey(
+        multisig_public_key = MultiPublicKey(
             [private_key_1.public_key(), private_key_2.public_key()], 1
         )
-        # Check expected authentication key.
-        expected_authentication_key = (
-            "835bb8c5ee481062946b18bbb3b42a40b998d6bf5316ca63834c959dc739acf0"
-        )
-        self.assertEqual(
-            multisig_public_key.auth_key().hex(), expected_authentication_key
-        )
         # Get public key BCS representation.
         serializer = Serializer()
         multisig_public_key.serialize(serializer)
@@ -284,7 +271,7 @@ def test_multisig(self):
         # Get public key bytes representation.
         public_key_bytes = multisig_public_key.to_bytes()
         # Convert back to multisig class instance from bytes.
-        multisig_public_key = MultiEd25519PublicKey.from_bytes(public_key_bytes)
+        multisig_public_key = MultiPublicKey.from_bytes(public_key_bytes)
         # Get public key BCS representation.
         serializer = Serializer()
         multisig_public_key.serialize(serializer)
@@ -294,7 +281,7 @@ def test_multisig(self):
         # Have one signer sign arbitrary message.
         signature = private_key_2.sign(b"multisig")
         # Compose multisig signature.
-        multisig_signature = MultiEd25519Signature(
+        multisig_signature = MultiSignature(
             multisig_public_key, [(private_key_2.public_key(), signature)]
         )
         # Get signature BCS representation.
@@ -312,46 +299,43 @@ def test_multisig(self):
     def test_multisig_range_checks(self):
         # Generate public keys.
         keys = [
-            PrivateKey.random().public_key()
-            for x in range(MultiEd25519PublicKey.MAX_KEYS + 1)
+            PrivateKey.random().public_key() for x in range(MultiPublicKey.MAX_KEYS + 1)
         ]
         # Verify failure for initializing multisig instance with too few keys.
         with self.assertRaisesRegex(AssertionError, "Must have between 2 and 32 keys."):
-            MultiEd25519PublicKey([keys[0]], 1)
+            MultiPublicKey([keys[0]], 1)
         # Verify failure for initializing multisig instance with too many keys.
         with self.assertRaisesRegex(AssertionError, "Must have between 2 and 32 keys."):
-            MultiEd25519PublicKey(keys, 1)
+            MultiPublicKey(keys, 1)
         # Verify failure for initializing multisig instance with small threshold.
         with self.assertRaisesRegex(
             AssertionError, "Threshold must be between 1 and 4."
         ):
-            MultiEd25519PublicKey(keys[0:4], 0)
+            MultiPublicKey(keys[0:4], 0)
         # Verify failure for initializing multisig instance with large threshold.
         with self.assertRaisesRegex(
             AssertionError, "Threshold must be between 1 and 4."
         ):
-            MultiEd25519PublicKey(keys[0:4], 5)
+            MultiPublicKey(keys[0:4], 5)
         # Verify failure for initializing from bytes with too few keys.
         with self.assertRaisesRegex(AssertionError, "Must have between 2 and 32 keys."):
-            MultiEd25519PublicKey.from_bytes(
-                MultiEd25519PublicKey([keys[0]], 1, checked=False).to_bytes()
+            MultiPublicKey.from_bytes(
+                MultiPublicKey([keys[0]], 1, checked=False).to_bytes()
             )
         # Verify failure for initializing from bytes with too many keys.
         with self.assertRaisesRegex(AssertionError, "Must have between 2 and 32 keys."):
-            MultiEd25519PublicKey.from_bytes(
-                MultiEd25519PublicKey(keys, 1, checked=False).to_bytes()
-            )
+            MultiPublicKey.from_bytes(MultiPublicKey(keys, 1, checked=False).to_bytes())
         # Verify failure for initializing from bytes with small threshold.
         with self.assertRaisesRegex(
             AssertionError, "Threshold must be between 1 and 4."
         ):
-            MultiEd25519PublicKey.from_bytes(
-                MultiEd25519PublicKey(keys[0:4], 0, checked=False).to_bytes()
+            MultiPublicKey.from_bytes(
+                MultiPublicKey(keys[0:4], 0, checked=False).to_bytes()
             )
         # Verify failure for initializing from bytes with large threshold.
         with self.assertRaisesRegex(
             AssertionError, "Threshold must be between 1 and 4."
         ):
-            MultiEd25519PublicKey.from_bytes(
-                MultiEd25519PublicKey(keys[0:4], 5, checked=False).to_bytes()
+            MultiPublicKey.from_bytes(
+                MultiPublicKey(keys[0:4], 5, checked=False).to_bytes()
             )
diff --git a/ecosystem/python/sdk/examples/async-aptos-token.py b/ecosystem/python/sdk/examples/async-aptos-token.py
new file mode 100644
index 0000000000000..78cb3bf532f5a
--- /dev/null
+++ b/ecosystem/python/sdk/examples/async-aptos-token.py
@@ -0,0 +1,116 @@
+# Copyright © Aptos Foundation
+# SPDX-License-Identifier: Apache-2.0
+
+import asyncio
+
+from aptos_sdk.account import Account
+from aptos_sdk.account_address import AccountAddress
+from aptos_sdk.aptos_token_client import (AptosTokenClient, Property,
+                                          PropertyMap)
+from aptos_sdk.async_client import FaucetClient, RestClient
+
+from .common import FAUCET_URL, NODE_URL
+
+
+async def main():
+    rest_client = RestClient(NODE_URL)
+    faucet_client = FaucetClient(FAUCET_URL, rest_client)
+    token_client = AptosTokenClient(rest_client)
+    alice = Account.generate()
+    bob = Account.generate()
+
+    collection_name = "Alice's"
+    token_name = "Alice's first token"
+
+    print("\n=== Addresses ===")
+    print(f"Alice: {alice.address()}")
+    print(f"Bob: {bob.address()}")
+
+    bob_fund = faucet_client.fund_account(alice.address(), 100_000_000)
+    alice_fund = faucet_client.fund_account(bob.address(), 100_000_000)
+    await asyncio.gather(*[bob_fund, alice_fund])
+
+    print("\n=== Initial Coin Balances ===")
+    alice_balance = rest_client.account_balance(alice.address())
+    bob_balance = rest_client.account_balance(bob.address())
+    [alice_balance, bob_balance] = await asyncio.gather(*[alice_balance, bob_balance])
+    print(f"Alice: {alice_balance}")
+    print(f"Bob: {bob_balance}")
+
+    print("\n=== Creating Collection and Token ===")
+
+    txn_hash = await token_client.create_collection(
+        alice,
+        "Alice's simple collection",
+        1,
+        collection_name,
+        "https://aptos.dev",
+        True,
+        True,
+        True,
+        True,
+        True,
+        True,
+        True,
+        True,
+        True,
+        0,
+        1,
+    )
+    await rest_client.wait_for_transaction(txn_hash)
+
+    txn_hash = await token_client.mint_token(
+        alice,
+        collection_name,
+        "Alice's simple token",
+        token_name,
+        "https://aptos.dev/img/nyan.jpeg",
+        PropertyMap([Property.string("string", "string value")]),
+    )
+    await rest_client.wait_for_transaction(txn_hash)
+
+    collection_addr = AccountAddress.for_named_collection(
+        alice.address(), collection_name
+    )
+    token_addr = AccountAddress.for_named_token(
+        alice.address(), collection_name, token_name
+    )
+    """
+    alice_address = AccountAddress.from_hex("0xa018017dc40fd081d2001acdb2660058ed2011f2790a42c2a40bab99909fbde5")
+    collection_addr = AccountAddress.for_named_collection(alice_address, collection_name)
+    token_addr = AccountAddress.for_named_token(alice_address, collection_name, token_name)
+    """
+
+    collection_data = await token_client.read_object(collection_addr)
+    print(f"Alice's collection: {collection_data}")
+    token_data = await token_client.read_object(token_addr)
+    print(f"Alice's token: {token_data}")
+
+    txn_hash = await token_client.add_token_property(
+        alice, token_addr, Property.bool("test", False)
+    )
+    await rest_client.wait_for_transaction(txn_hash)
+    token_data = await token_client.read_object(token_addr)
+    print(f"Alice's token: {token_data}")
+    txn_hash = await token_client.remove_token_property(alice, token_addr, "string")
+    await rest_client.wait_for_transaction(txn_hash)
+    token_data = await token_client.read_object(token_addr)
+    print(f"Alice's token: {token_data}")
+    txn_hash = await token_client.update_token_property(
+        alice, token_addr, Property.bool("test", True)
+    )
+    await rest_client.wait_for_transaction(txn_hash)
+    token_data = await token_client.read_object(token_addr)
+    print(f"Alice's token: {token_data}")
+    txn_hash = await token_client.add_token_property(
+        alice, token_addr, Property.bytes("bytes", b"\x00\x01")
+    )
+    await rest_client.wait_for_transaction(txn_hash)
+    token_data = await token_client.read_object(token_addr)
+    print(f"Alice's token: {token_data}")
+
+    await rest_client.close()
+
+
+if __name__ == "__main__":
+    asyncio.run(main())
diff --git a/ecosystem/python/sdk/examples/multisig.py b/ecosystem/python/sdk/examples/multisig.py
index 953fcf3acc6a0..e5d4b78032b74 100644
--- a/ecosystem/python/sdk/examples/multisig.py
+++ b/ecosystem/python/sdk/examples/multisig.py
@@ -6,7 +6,7 @@
 from aptos_sdk.authenticator import Authenticator, MultiEd25519Authenticator
 from aptos_sdk.bcs import Serializer
 from aptos_sdk.client import FaucetClient, RestClient
-from aptos_sdk.ed25519 import MultiEd25519PublicKey, MultiEd25519Signature
+from aptos_sdk.ed25519 import MultiPublicKey, MultiSignature
 from aptos_sdk.transactions import (EntryFunction, RawTransaction, Script,
                                     ScriptArgument, SignedTransaction,
                                     TransactionArgument, TransactionPayload)
@@ -49,7 +49,7 @@ def wait():
     # :!:>section_2
     threshold = 2
 
-    multisig_public_key = MultiEd25519PublicKey(
+    multisig_public_key = MultiPublicKey(
         [alice.public_key(), bob.public_key(), chad.public_key()], threshold
     )
 
@@ -129,7 +129,7 @@ def wait():
         (bob.public_key(), bob_signature),
     ]
 
-    multisig_signature = MultiEd25519Signature(multisig_public_key, sig_map)
+    multisig_signature = MultiSignature(multisig_public_key, sig_map)
 
     authenticator = Authenticator(
         MultiEd25519Authenticator(multisig_public_key, multisig_signature)
@@ -197,7 +197,7 @@ def wait():
 
     cap_rotate_key = deedee.sign(rotation_proof_challenge_bcs).data()
 
-    cap_update_table = MultiEd25519Signature(
+    cap_update_table = MultiSignature(
         multisig_public_key,
         [
             (bob.public_key(), bob.sign(rotation_proof_challenge_bcs)),
@@ -309,7 +309,7 @@ def wait():
         (chad.public_key(), chad_signature),
     ]
 
-    multisig_signature = MultiEd25519Signature(multisig_public_key, sig_map)
+    multisig_signature = MultiSignature(multisig_public_key, sig_map)
 
     authenticator = Authenticator(
         MultiEd25519Authenticator(multisig_public_key, multisig_signature)
@@ -392,7 +392,7 @@ def wait():
         (chad.public_key(), chad_signature),
     ]
 
-    multisig_signature = MultiEd25519Signature(multisig_public_key, sig_map)
+    multisig_signature = MultiSignature(multisig_public_key, sig_map)
 
     authenticator = Authenticator(
         MultiEd25519Authenticator(multisig_public_key, multisig_signature)
@@ -449,7 +449,7 @@ def wait():
         (bob.public_key(), bob_signature),
     ]
 
-    multisig_signature = MultiEd25519Signature(multisig_public_key, sig_map)
+    multisig_signature = MultiSignature(multisig_public_key, sig_map)
 
     authenticator = Authenticator(
         MultiEd25519Authenticator(multisig_public_key, multisig_signature)
diff --git a/third_party/move/move-prover/move-abigen/src/abigen.rs b/third_party/move/move-prover/move-abigen/src/abigen.rs
index eca389e87fa0f..d36d41a16c9ed 100644
--- a/third_party/move/move-prover/move-abigen/src/abigen.rs
+++ b/third_party/move/move-prover/move-abigen/src/abigen.rs
@@ -286,25 +286,27 @@ impl<'env> Abigen<'env> {
                 TypeTag::Vector(Box::new(tag))
             },
             Struct(module_id, struct_id, vec_type) => {
-                let expect_msg = format!("type {:?} is not allowed in scription function", ty0);
                 let struct_module_env = module_env.env.get_module(*module_id);
                 let abilities = struct_module_env.get_struct(*struct_id).get_abilities();
                 if abilities.has_ability(Ability::Copy) && !abilities.has_ability(Ability::Key) {
+                    let mut type_params = vec![];
+                    for e in vec_type {
+                        let type_param = match Self::get_type_tag(e, module_env)? {
+                            Some(type_param) => type_param,
+                            None => return Ok(None),
+                        };
+                        type_params.push(type_param);
+                    }
                     TypeTag::Struct(Box::new(StructTag {
                         address: *struct_module_env.self_address(),
                         module: struct_module_env.get_identifier(),
                         name: struct_module_env
                             .get_struct(*struct_id)
                             .get_identifier()
-                            .unwrap_or_else(|| panic!("{}", expect_msg)),
-                        type_params: vec_type
-                            .iter()
-                            .map(|e| {
-                                Self::get_type_tag(e, module_env)
-                                    .unwrap_or_else(|_| panic!("{}", expect_msg))
-                            })
-                            .map(|e| e.unwrap_or_else(|| panic!("{}", expect_msg)))
-                            .collect(),
+                            .unwrap_or_else(|| {
+                                panic!("type {:?} is not allowed in entry function", ty0)
+                            }),
+                        type_params,
                     }))
                 } else {
                     return Ok(None);
diff --git a/types/src/account_address.rs b/types/src/account_address.rs
index 3ff3b6004e8f5..599708507db75 100644
--- a/types/src/account_address.rs
+++ b/types/src/account_address.rs
@@ -284,6 +284,13 @@ mod test {
             "{:?}",
             super::create_token_address(address, "bob's collection", "bob's token")
         );
-        // println!("{:?}", create_object_address(address, guid);
+        println!(
+            "{:?}",
+            super::create_collection_address(address, "bob's collection")
+        );
+        println!(
+            "{:?}",
+            super::create_resource_address(address, &[0x0B, 0x00, 0x0B])
+        );
     }
 }