diff --git a/aptos-move/framework/aptos-framework/doc/object.md b/aptos-move/framework/aptos-framework/doc/object.md index e3c6f2f70ece32..48279c737cf736 100644 --- a/aptos-move/framework/aptos-framework/doc/object.md +++ b/aptos-move/framework/aptos-framework/doc/object.md @@ -91,6 +91,7 @@ make it so that a reference to a global object can be returned from a function. - [Function `owns`](#0x1_object_owns) - [Function `root_owner`](#0x1_object_root_owner) - [Function `grant_permission`](#0x1_object_grant_permission) +- [Function `grant_permission_with_transfer_ref`](#0x1_object_grant_permission_with_transfer_ref) - [Specification](#@Specification_1) - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) @@ -2407,6 +2408,7 @@ to determine the identity of the starting point of ownership. ## Function `grant_permission` +Master signer offers a transfer permission of an object to a permissioned signer.
public fun grant_permission<T>(master: &signer, permissioned_signer: &signer, object: object::Object<T>)
@@ -2433,6 +2435,37 @@ to determine the identity of the starting point of ownership.
 
 
 
+
+
+
+
+## Function `grant_permission_with_transfer_ref`
+
+Grant a transfer permission to the permissioned signer using TransferRef.
+
+
+
public fun grant_permission_with_transfer_ref(permissioned_signer: &signer, ref: &object::TransferRef)
+
+ + + +
+Implementation + + +
public fun grant_permission_with_transfer_ref(
+    permissioned_signer: &signer,
+    ref: &TransferRef,
+) {
+    permissioned_signer::grant_unlimited_with_permissioned_signer(
+        permissioned_signer,
+        TransferPermission { object: ref.self }
+    )
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-framework/doc/permissioned_signer.md b/aptos-move/framework/aptos-framework/doc/permissioned_signer.md index 222793271ad35e..9fb317115c7f3b 100644 --- a/aptos-move/framework/aptos-framework/doc/permissioned_signer.md +++ b/aptos-move/framework/aptos-framework/doc/permissioned_signer.md @@ -49,6 +49,7 @@ for blind signing. - [Function `insert_or`](#0x1_permissioned_signer_insert_or) - [Function `authorize_increase`](#0x1_permissioned_signer_authorize_increase) - [Function `authorize_unlimited`](#0x1_permissioned_signer_authorize_unlimited) +- [Function `grant_unlimited_with_permissioned_signer`](#0x1_permissioned_signer_grant_unlimited_with_permissioned_signer) - [Function `increase_limit`](#0x1_permissioned_signer_increase_limit) - [Function `check_permission_exists`](#0x1_permissioned_signer_check_permission_exists) - [Function `check_permission_capacity_above`](#0x1_permissioned_signer_check_permission_capacity_above) @@ -1286,6 +1287,44 @@ Unlimited permission can be consumed however many times. + + + + +## Function `grant_unlimited_with_permissioned_signer` + +Grant an unlimited permission to a permissioned signer **without** master signer's approvoal. + + +
public(friend) fun grant_unlimited_with_permissioned_signer<PermKey: copy, drop, store>(permissioned: &signer, perm: PermKey)
+
+ + + +
+Implementation + + +
public(package) fun grant_unlimited_with_permissioned_signer<PermKey: copy + drop + store>(
+    permissioned: &signer,
+    perm: PermKey
+) acquires PermissionStorage {
+    if(!is_permissioned_signer(permissioned)) {
+        return;
+    };
+    insert_or(
+        permissioned,
+        perm,
+        |stored_permission| {
+            *stored_permission = StoredPermission::Unlimited;
+        },
+        StoredPermission::Unlimited,
+    )
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-framework/sources/object.move b/aptos-move/framework/aptos-framework/sources/object.move index 7f94c73b2ac903..09e724318e9422 100644 --- a/aptos-move/framework/aptos-framework/sources/object.move +++ b/aptos-move/framework/aptos-framework/sources/object.move @@ -713,6 +713,7 @@ module aptos_framework::object { obj_owner } + /// Master signer offers a transfer permission of an object to a permissioned signer. public fun grant_permission( master: &signer, permissioned_signer: &signer, @@ -725,6 +726,17 @@ module aptos_framework::object { ) } + /// Grant a transfer permission to the permissioned signer using TransferRef. + public fun grant_permission_with_transfer_ref( + permissioned_signer: &signer, + ref: &TransferRef, + ) { + permissioned_signer::grant_unlimited_with_permissioned_signer( + permissioned_signer, + TransferPermission { object: ref.self } + ) + } + #[test_only] use std::option::{Self, Option}; @@ -1163,4 +1175,25 @@ module aptos_framework::object { permissioned_signer::destroy_permissioned_handle(creator_permission_handle); } + + #[test(creator = @0x123)] + fun test_create_and_transfer( + creator: &signer, + ) acquires ObjectCore { + let aptos_framework = account::create_signer_for_test(@0x1); + timestamp::set_time_has_started_for_testing(&aptos_framework); + + let (_, hero) = create_hero(creator); + let (weapon_ref, weapon) = create_weapon(creator); + let t_ref = generate_transfer_ref(&weapon_ref); + + // Create a permissioned signer + let creator_permission_handle = permissioned_signer::create_permissioned_handle(creator); + let creator_permission_signer = permissioned_signer::signer_from_permissioned_handle(&creator_permission_handle); + + grant_permission_with_transfer_ref(&creator_permission_signer, &t_ref); + transfer_to_object(&creator_permission_signer, weapon, hero); + + permissioned_signer::destroy_permissioned_handle(creator_permission_handle); + } } diff --git a/aptos-move/framework/aptos-framework/sources/permissioned_signer.move b/aptos-move/framework/aptos-framework/sources/permissioned_signer.move index 194baab8530529..8e752e723138d5 100644 --- a/aptos-move/framework/aptos-framework/sources/permissioned_signer.move +++ b/aptos-move/framework/aptos-framework/sources/permissioned_signer.move @@ -509,6 +509,24 @@ module aptos_framework::permissioned_signer { ) } + /// Grant an unlimited permission to a permissioned signer **without** master signer's approvoal. + public(package) fun grant_unlimited_with_permissioned_signer( + permissioned: &signer, + perm: PermKey + ) acquires PermissionStorage { + if(!is_permissioned_signer(permissioned)) { + return; + }; + insert_or( + permissioned, + perm, + |stored_permission| { + *stored_permission = StoredPermission::Unlimited; + }, + StoredPermission::Unlimited, + ) + } + /// Increase the `capacity` of a permissioned signer **without** master signer's approvoal. /// /// The caller of the module will need to make sure the witness type `PermKey` can only be