From 8e4f566d96f23f858c52d73c660688201e19eb26 Mon Sep 17 00:00:00 2001 From: Austin Kline Date: Wed, 6 Sep 2023 09:24:29 -0700 Subject: [PATCH] Extend AccountPublic to allow retrieval of Factory and Filter capabilities (#153) Without this, it's very difficult to detect whether a certain capability is allowed to be retrieved unless you run scripts manually. With helper methods like this (I'm sure others will be needed), you can borrow and return details of the filter/factory yourself and then process them offline --- contracts/HybridCustody.cdc | 14 ++++++++++++++ .../can_get_child_factory_and_filter_caps.cdc | 19 +++++++++++++++++++ test/HybridCustody_tests.cdc | 8 ++++++++ 3 files changed, 41 insertions(+) create mode 100644 scripts/test/can_get_child_factory_and_filter_caps.cdc diff --git a/contracts/HybridCustody.cdc b/contracts/HybridCustody.cdc index 3d4f960..5d526e2 100644 --- a/contracts/HybridCustody.cdc +++ b/contracts/HybridCustody.cdc @@ -198,6 +198,8 @@ pub contract HybridCustody { pub fun getPublicCapability(path: PublicPath, type: Type): Capability? pub fun getPublicCapFromDelegator(type: Type): Capability? pub fun getAddress(): Address + pub fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}? + pub fun getCapabilityFilter(): &{CapabilityFilter.Filter}? } /// Methods accessible to the designated parent of a ChildAccount @@ -716,6 +718,18 @@ pub contract HybridCustody { self.resources <- {} } + /// Returns a capability to this child account's CapabilityFilter + /// + pub fun getCapabilityFilter(): &{CapabilityFilter.Filter}? { + return self.filter.check() ? self.filter.borrow() : nil + } + + /// Returns a capability to this child account's CapabilityFactory + /// + pub fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}? { + return self.factory.check() ? self.factory.borrow() : nil + } + destroy () { destroy <- self.resources } diff --git a/scripts/test/can_get_child_factory_and_filter_caps.cdc b/scripts/test/can_get_child_factory_and_filter_caps.cdc new file mode 100644 index 0000000..f4b28c4 --- /dev/null +++ b/scripts/test/can_get_child_factory_and_filter_caps.cdc @@ -0,0 +1,19 @@ +import "HybridCustody" + +// @addr - The address of the child account +// @parent - The parent account that this child is assigned to +pub fun main(addr: Address, parent: Address): Bool { + let identifier = HybridCustody.getChildAccountIdentifier(parent) + let path = PrivatePath(identifier: identifier) ?? panic("invalid public path identifier for parent address") + + let acctPublic = getAuthAccount(addr).getCapability<&HybridCustody.ChildAccount{HybridCustody.AccountPublic}>(path) + .borrow() ?? panic("account public not found") + + let factory = acctPublic.getCapabilityFactoryManager() + assert(factory != nil, message: "capability factory is not valid") + + let filter = acctPublic.getCapabilityFilter() + assert(filter != nil, message: "capability filter is not valid") + + return true +} \ No newline at end of file diff --git a/test/HybridCustody_tests.cdc b/test/HybridCustody_tests.cdc index a485a53..520f0fc 100644 --- a/test/HybridCustody_tests.cdc +++ b/test/HybridCustody_tests.cdc @@ -797,6 +797,14 @@ pub fun testRemoveParent() { txExecutor("hybrid-custody/remove_parent_from_child.cdc", [child], [parent.address], nil, nil) } +pub fun testGetChildAccountCapabilityFilterAndFactory() { + let child = blockchain.createAccount() + let parent = blockchain.createAccount() + + setupChildAndParent_FilterKindAll(child: child, parent: parent) + scriptExecutor("test/can_get_child_factory_and_filter_caps.cdc", [child.address, parent.address]) +} + // --------------- End Test Cases ---------------