From acaa263335ceaa3a3709bcd4a9c67b81aee2f336 Mon Sep 17 00:00:00 2001 From: Austin Kline Date: Sun, 31 Mar 2024 19:54:07 -0700 Subject: [PATCH] address all contract errors/warnings --- contracts/HybridCustody.cdc | 459 ++++++++++++++++++------------------ 1 file changed, 229 insertions(+), 230 deletions(-) diff --git a/contracts/HybridCustody.cdc b/contracts/HybridCustody.cdc index 1c5795d..6ff01b6 100644 --- a/contracts/HybridCustody.cdc +++ b/contracts/HybridCustody.cdc @@ -1,5 +1,6 @@ // Third-party imports import "MetadataViews" +import "ViewResolver" // HC-owned imports import "CapabilityFactory" @@ -27,39 +28,42 @@ import "CapabilityFilter" /// /// Repo reference: https://github.com/onflow/hybrid-custody /// -pub contract HybridCustody { +access(all) contract HybridCustody { + + access(all) entitlement Restricted + access(all) entitlement Owner /* --- Canonical Paths --- */ // // Note: Paths for ChildAccount & Delegator are derived from the parent's address // - pub let OwnedAccountStoragePath: StoragePath - pub let OwnedAccountPublicPath: PublicPath - pub let OwnedAccountPrivatePath: PrivatePath + access(all) let OwnedAccountStoragePath: StoragePath + access(all) let OwnedAccountPublicPath: PublicPath + access(all) let OwnedAccountPrivatePath: PrivatePath - pub let ManagerStoragePath: StoragePath - pub let ManagerPublicPath: PublicPath - pub let ManagerPrivatePath: PrivatePath + access(all) let ManagerStoragePath: StoragePath + access(all) let ManagerPublicPath: PublicPath + access(all) let ManagerPrivatePath: PrivatePath - pub let LinkedAccountPrivatePath: PrivatePath - pub let BorrowableAccountPrivatePath: PrivatePath + access(all) let LinkedAccountPrivatePath: PrivatePath + access(all) let BorrowableAccountPrivatePath: PrivatePath /* --- Events --- */ // /// Manager creation event - pub event CreatedManager(id: UInt64) + access(all) event CreatedManager(id: UInt64) /// OwnedAccount creation event - pub event CreatedOwnedAccount(id: UInt64, child: Address) + access(all) event CreatedOwnedAccount(id: UInt64, child: Address) /// ChildAccount added/removed from Manager /// active : added to Manager /// !active : removed from Manager - pub event AccountUpdated(id: UInt64?, child: Address, parent: Address, active: Bool) + access(all) event AccountUpdated(id: UInt64?, child: Address, parent: Address, active: Bool) /// OwnedAccount added/removed or sealed /// active && owner != nil : added to Manager /// !active && owner == nil : removed from Manager - pub event OwnershipUpdated(id: UInt64, child: Address, previousOwner: Address?, owner: Address?, active: Bool) + access(all) event OwnershipUpdated(id: UInt64, child: Address, previousOwner: Address?, owner: Address?, active: Bool) /// ChildAccount ready to be redeemed by emitted pendingParent - pub event ChildAccountPublished( + access(all) event ChildAccountPublished( ownedAcctID: UInt64, childAcctID: UInt64, capDelegatorID: UInt64, @@ -70,30 +74,30 @@ pub contract HybridCustody { pendingParent: Address ) /// OwnedAccount granted ownership to a new address, publishing a Capability for the pendingOwner - pub event OwnershipGranted(ownedAcctID: UInt64, child: Address, previousOwner: Address?, pendingOwner: Address) + access(all) event OwnershipGranted(ownedAcctID: UInt64, child: Address, previousOwner: Address?, pendingOwner: Address) /// Account has been sealed - keys revoked, new AuthAccount Capability generated - pub event AccountSealed(id: UInt64, address: Address, parents: [Address]) + access(all) event AccountSealed(id: UInt64, address: Address, parents: [Address]) /// An OwnedAccount shares the BorrowableAccount capability to itelf with ChildAccount resources /// - pub resource interface BorrowableAccount { - access(contract) fun borrowAccount(): &AuthAccount - pub fun check(): Bool + access(all) resource interface BorrowableAccount { + access(contract) view fun borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account + access(all) view fun check(): Bool } /// Public methods anyone can call on an OwnedAccount /// - pub resource interface OwnedAccountPublic { + access(all) resource interface OwnedAccountPublic { /// Returns the addresses of all parent accounts - pub fun getParentAddresses(): [Address] + access(all) view fun getParentAddresses(): [Address] /// Returns associated parent addresses and their redeemed status - true if redeemed, false if pending - pub fun getParentStatuses(): {Address: Bool} + access(all) view fun getParentStatuses(): {Address: Bool} /// Returns true if the given address is a parent of this child and has redeemed it. Returns false if the given /// address is a parent of this child and has NOT redeemed it. Returns nil if the given address it not a parent /// of this child account. - pub fun getRedeemedStatus(addr: Address): Bool? + access(all) view fun getRedeemedStatus(addr: Address): Bool? /// A callback function to mark a parent as redeemed on the child account. access(contract) fun setRedeemed(_ addr: Address) @@ -101,18 +105,18 @@ pub contract HybridCustody { /// Private interface accessible to the owner of the OwnedAccount /// - pub resource interface OwnedAccountPrivate { + access(all) resource interface OwnedAccountPrivate { /// Deletes the ChildAccount resource being used to share access to this OwnedAccount with the supplied parent /// address, and unlinks the paths it was using to reach the underlying account. - pub fun removeParent(parent: Address): Bool + access(Restricted) fun removeParent(parent: Address): Bool /// Sets up a new ChildAccount resource for the given parentAddress to redeem. This child account uses the /// supplied factory and filter to manage what can be obtained from the child account, and a new /// CapabilityDelegator resource is created for the sharing of one-off capabilities. Each of these pieces of /// access control are managed through the child account. - pub fun publishToParent( + access(Restricted) fun publishToParent( parentAddress: Address, - factory: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>, + factory: Capability<&{CapabilityFactory.Getter}>, filter: Capability<&{CapabilityFilter.Filter}> ) { pre { @@ -124,7 +128,7 @@ pub contract HybridCustody { /// Passes ownership of this child account to the given address. Once executed, all active keys on the child /// account will be revoked, and the active AuthAccount Capability being used by to obtain capabilities will be /// rotated, preventing anyone without the newly generated Capability from gaining access to the account. - pub fun giveOwnership(to: Address) + access(Owner) fun giveOwnership(to: Address) /// Revokes all keys on an account, unlinks all currently active AuthAccount capabilities, then makes a new one /// and replaces the OwnedAccount's underlying AuthAccount Capability with the new one to ensure that all @@ -132,12 +136,12 @@ pub contract HybridCustody { /// Unless this method is executed via the giveOwnership function, this will leave an account **without** an /// owner. /// USE WITH EXTREME CAUTION. - pub fun seal() + access(Owner) fun seal() // setCapabilityFactoryForParent // Override the existing CapabilityFactory Capability for a given parent. This will allow the owner of the // account to start managing their own factory of capabilities to be able to retrieve - pub fun setCapabilityFactoryForParent(parent: Address, cap: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>) { + access(Restricted) fun setCapabilityFactoryForParent(parent: Address, cap: Capability<&{CapabilityFactory.Getter}>) { pre { cap.check(): "Invalid CapabilityFactory.Getter Capability provided" } @@ -145,7 +149,7 @@ pub contract HybridCustody { /// Override the existing CapabilityFilter Capability for a given parent. This will allow the owner of the /// account to start managing their own filter for retrieving Capabilities on Private Paths - pub fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) { + access(Restricted) fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) { pre { cap.check(): "Invalid CapabilityFilter Capability provided" } @@ -153,68 +157,67 @@ pub contract HybridCustody { /// Adds a capability to a parent's managed @ChildAccount resource. The Capability can be made public, /// permitting anyone to borrow it. - pub fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) { + access(Restricted) fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) { pre { cap.check<&AnyResource>(): "Invalid Capability provided" } } /// Removes a Capability from the CapabilityDelegator used by the specified parent address - pub fun removeCapabilityFromDelegator(parent: Address, cap: Capability) + access(Restricted) fun removeCapabilityFromDelegator(parent: Address, cap: Capability) /// Returns the address of this OwnedAccount - pub fun getAddress(): Address + access(all) view fun getAddress(): Address /// Checks if this OwnedAccount is a child of the specified address - pub fun isChildOf(_ addr: Address): Bool + access(all) view fun isChildOf(_ addr: Address): Bool /// Returns all addresses which are parents of this OwnedAccount - pub fun getParentAddresses(): [Address] + access(all) view fun getParentAddresses(): [Address] /// Borrows this OwnedAccount's AuthAccount Capability - pub fun borrowAccount(): &AuthAccount? + access(contract) view fun borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account /// Returns the current owner of this account, if there is one - pub fun getOwner(): Address? + access(all) view fun getOwner(): Address? /// Returns the pending owner of this account, if there is one - pub fun getPendingOwner(): Address? + access(all) view fun getPendingOwner(): Address? /// A callback which is invoked when a parent redeems an owned account access(contract) fun setOwnerCallback(_ addr: Address) /// Destroys all outstanding AuthAccount capabilities on this owned account, and creates a new one for the /// OwnedAccount to use - pub fun rotateAuthAccount() + access(Owner) fun rotateAuthAccount() /// Revokes all keys on this account - pub fun revokeAllKeys() + access(Owner) fun revokeAllKeys() } /// Public methods exposed on a ChildAccount resource. OwnedAccountPublic will share some methods here, but isn't /// necessarily the same. /// - pub resource interface AccountPublic { - 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}? + access(all) resource interface AccountPublic { + // TODO: This has been disabled because you cannot get a capability without providing a type T anymore in Cadence 1.0 + // access(all) view fun getPublicCapability(path: PublicPath, type: Type): Capability? + access(all) view fun getPublicCapFromDelegator(type: Type): Capability? + access(all) view fun getAddress(): Address + access(all) view fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}? + access(all) view fun getCapabilityFilter(): &{CapabilityFilter.Filter}? } /// Methods accessible to the designated parent of a ChildAccount /// - pub resource interface AccountPrivate { - pub fun getCapability(path: CapabilityPath, type: Type): Capability? { + access(all) resource interface AccountPrivate { + access(Capabilities) view fun getCapability(controllerID: UInt64, type: Type): Capability? { post { result == nil || [true, nil].contains(self.getManagerCapabilityFilter()?.allowed(cap: result!)): "Capability is not allowed by this account's Parent" } } - pub fun getPublicCapability(path: PublicPath, type: Type): Capability? - pub fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}? - pub fun getPublicCapFromDelegator(type: Type): Capability? - pub fun getPrivateCapFromDelegator(type: Type): Capability? { + access(all) view fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}? + access(Capabilities) view fun getPrivateCapFromDelegator(type: Type): Capability? { post { result == nil || [true, nil].contains(self.getManagerCapabilityFilter()?.allowed(cap: result!)): "Capability is not allowed by this account's Parent" @@ -231,14 +234,14 @@ pub contract HybridCustody { /// Entry point for a parent to obtain, maintain and access Capabilities or perform other actions on child accounts /// - pub resource interface ManagerPrivate { - pub fun addAccount(cap: Capability<&{AccountPrivate, AccountPublic, MetadataViews.Resolver}>) - pub fun borrowAccount(addr: Address): &{AccountPrivate, AccountPublic, MetadataViews.Resolver}? - pub fun removeChild(addr: Address) - pub fun addOwnedAccount(cap: Capability<&{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}>) - pub fun borrowOwnedAccount(addr: Address): &{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}? - pub fun removeOwned(addr: Address) - pub fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) { + access(all) resource interface ManagerPrivate { + access(Restricted) fun addAccount(cap: Capability<&{AccountPrivate, AccountPublic, ViewResolver.Resolver}>) + access(Restricted) fun borrowAccount(addr: Address): &{AccountPrivate, AccountPublic, ViewResolver.Resolver}? + access(Restricted) fun removeChild(addr: Address) + access(Owner) fun addOwnedAccount(cap: Capability) + access(Restricted) fun borrowOwnedAccount(addr: Address): &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}? + access(Restricted) fun removeOwned(addr: Address) + access(Restricted) fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) { pre { cap == nil || cap!.check(): "Invalid Manager Capability Filter" } @@ -247,39 +250,39 @@ pub contract HybridCustody { /// Functions anyone can call on a manager to get information about an account such as What child accounts it has /// Functions anyone can call on a manager to get information about an account such as what child accounts it has - pub resource interface ManagerPublic { - pub fun borrowAccountPublic(addr: Address): &{AccountPublic, MetadataViews.Resolver}? - pub fun getChildAddresses(): [Address] - pub fun getOwnedAddresses(): [Address] - pub fun getChildAccountDisplay(address: Address): MetadataViews.Display? + access(all) resource interface ManagerPublic { + access(all) fun borrowAccountPublic(addr: Address): &{AccountPublic, ViewResolver.Resolver}? + access(all) fun getChildAddresses(): [Address] + access(all) fun getOwnedAddresses(): [Address] + access(all) fun getChildAccountDisplay(address: Address): MetadataViews.Display? access(contract) fun removeParentCallback(child: Address) } /// A resource for an account which fills the Parent role of the Child-Parent account management Model. A Manager /// can redeem or remove child accounts, and obtain any capabilities exposed by the child account to them. /// - pub resource Manager: ManagerPrivate, ManagerPublic, MetadataViews.Resolver { + access(all) resource Manager: ManagerPrivate, ManagerPublic, ViewResolver.Resolver { /// Mapping of restricted access child account Capabilities indexed by their address - pub let childAccounts: {Address: Capability<&{AccountPrivate, AccountPublic, MetadataViews.Resolver}>} + access(self) let childAccounts: {Address: Capability<&{AccountPrivate, AccountPublic, ViewResolver.Resolver}>} /// Mapping of unrestricted owned account Capabilities indexed by their address - pub let ownedAccounts: {Address: Capability<&{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}>} + access(self) let ownedAccounts: {Address: Capability} /// A bucket of structs so that the Manager resource can be easily extended with new functionality. - pub let data: {String: AnyStruct} + access(self) let data: {String: AnyStruct} /// A bucket of resources so that the Manager resource can be easily extended with new functionality. - pub let resources: @{String: AnyResource} + access(self) let resources: @{String: AnyResource} /// An optional filter to gate what capabilities are permitted to be returned from a child account For example, /// Dapper Wallet parent account's should not be able to retrieve any FungibleToken Provider capabilities. - pub var filter: Capability<&{CapabilityFilter.Filter}>? + access(self) var filter: Capability<&{CapabilityFilter.Filter}>? // display metadata for a child account exists on its parent - pub let childAccountDisplays: {Address: MetadataViews.Display} + access(self) let childAccountDisplays: {Address: MetadataViews.Display} /// Sets the Display on the ChildAccount. If nil, the display is removed. /// - pub fun setChildAccountDisplay(address: Address, _ d: MetadataViews.Display?) { + access(Restricted) fun setChildAccountDisplay(address: Address, _ d: MetadataViews.Display?) { pre { self.childAccounts[address] != nil: "There is no child account with this address" } @@ -295,7 +298,7 @@ pub contract HybridCustody { /// Adds a ChildAccount Capability to this Manager. If a default Filter is set in the manager, it will also be /// added to the ChildAccount /// - pub fun addAccount(cap: Capability<&{AccountPrivate, AccountPublic, MetadataViews.Resolver}>) { + access(Restricted) fun addAccount(cap: Capability<&{AccountPrivate, AccountPublic, ViewResolver.Resolver}>) { pre { self.childAccounts[cap.address] == nil: "There is already a child account with this address" } @@ -313,7 +316,7 @@ pub contract HybridCustody { /// Sets the default Filter Capability for this Manager. Does not propagate to child accounts. /// - pub fun setDefaultManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?) { + access(Restricted) fun setDefaultManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?) { pre { cap == nil || cap!.check(): "supplied capability must be nil or check must pass" } @@ -323,7 +326,7 @@ pub contract HybridCustody { /// Sets the Filter Capability for this Manager, propagating to the specified child account /// - pub fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) { + access(Restricted) fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) { let acct = self.borrowAccount(addr: childAddress) ?? panic("child account not found") @@ -333,7 +336,7 @@ pub contract HybridCustody { /// Removes specified child account from the Manager's child accounts. Callbacks to the child account remove /// any associated resources and Capabilities /// - pub fun removeChild(addr: Address) { + access(Restricted) fun removeChild(addr: Address) { let cap = self.childAccounts.remove(key: addr) ?? panic("child account not found") @@ -365,7 +368,7 @@ pub contract HybridCustody { /// Adds an owned account to the Manager's list of owned accounts, setting the Manager account as the owner of /// the given account /// - pub fun addOwnedAccount(cap: Capability<&{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}>) { + access(Owner) fun addOwnedAccount(cap: Capability) { pre { self.ownedAccounts[cap.address] == nil: "There is already an owned account with this address" } @@ -386,7 +389,7 @@ pub contract HybridCustody { /// Returns a reference to a child account /// - pub fun borrowAccount(addr: Address): &{AccountPrivate, AccountPublic, MetadataViews.Resolver}? { + access(Restricted) fun borrowAccount(addr: Address): &{AccountPrivate, AccountPublic, ViewResolver.Resolver}? { let cap = self.childAccounts[addr] if cap == nil { return nil @@ -397,7 +400,7 @@ pub contract HybridCustody { /// Returns a reference to a child account's public AccountPublic interface /// - pub fun borrowAccountPublic(addr: Address): &{AccountPublic, MetadataViews.Resolver}? { + access(all) fun borrowAccountPublic(addr: Address): &{AccountPublic, ViewResolver.Resolver}? { let cap = self.childAccounts[addr] if cap == nil { return nil @@ -408,7 +411,7 @@ pub contract HybridCustody { /// Returns a reference to an owned account /// - pub fun borrowOwnedAccount(addr: Address): &{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}? { + access(Restricted) fun borrowOwnedAccount(addr: Address): &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}? { if let cap = self.ownedAccounts[addr] { return cap.borrow() } @@ -419,7 +422,7 @@ pub contract HybridCustody { /// Removes specified child account from the Manager's child accounts. Callbacks to the child account remove /// any associated resources and Capabilities /// - pub fun removeOwned(addr: Address) { + access(Restricted) fun removeOwned(addr: Address) { if let acct = self.ownedAccounts.remove(key: addr) { if acct.check() { acct.borrow()!.seal() @@ -439,7 +442,7 @@ pub contract HybridCustody { /// mechanism intended to easily transfer 'root' access on this account to another account and an attempt to /// minimize access vectors. /// - pub fun giveOwnership(addr: Address, to: Address) { + access(Owner) fun giveOwnership(addr: Address, to: Address) { let acct = self.ownedAccounts.remove(key: addr) ?? panic("account not found") @@ -448,31 +451,31 @@ pub contract HybridCustody { /// Returns an array of child account addresses /// - pub fun getChildAddresses(): [Address] { + access(all) view fun getChildAddresses(): [Address] { return self.childAccounts.keys } /// Returns an array of owned account addresses /// - pub fun getOwnedAddresses(): [Address] { + access(all) view fun getOwnedAddresses(): [Address] { return self.ownedAccounts.keys } /// Retrieves the parent-defined display for the given child account /// - pub fun getChildAccountDisplay(address: Address): MetadataViews.Display? { + access(all) view fun getChildAccountDisplay(address: Address): MetadataViews.Display? { return self.childAccountDisplays[address] } /// Returns the types of supported views - none at this time /// - pub fun getViews(): [Type] { + access(all) view fun getViews(): [Type] { return [] } /// Resolves the given view if supported - none at this time /// - pub fun resolveView(_ view: Type): AnyStruct? { + access(all) view fun resolveView(_ view: Type): AnyStruct? { return nil } @@ -489,9 +492,10 @@ pub contract HybridCustody { self.resources <- {} } - destroy () { - destroy self.resources - } + // TODO: burnCallback and ResourceDestroyed event + // destroy () { + // destroy self.resources + // } } /// The ChildAccount resource sits between a child account and a parent and is stored on the same account as the @@ -503,27 +507,27 @@ pub contract HybridCustody { /// able to manage all ChildAccount resources it shares, without worrying about whether the upstream parent can do /// anything to prevent it. /// - pub resource ChildAccount: AccountPrivate, AccountPublic, MetadataViews.Resolver { + access(all) resource ChildAccount: AccountPrivate, AccountPublic, ViewResolver.Resolver { /// A Capability providing access to the underlying child account - access(self) let childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, MetadataViews.Resolver}> + access(self) let childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}> /// The CapabilityFactory Manager is a ChildAccount's way of limiting what types can be asked for by its parent /// account. The CapabilityFactory returns Capabilities which can be casted to their appropriate types once /// obtained, but only if the child account has configured their factory to allow it. For instance, a /// ChildAccount might choose to expose NonFungibleToken.Provider, but not FungibleToken.Provider - pub var factory: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}> + access(self) var factory: Capability<&{CapabilityFactory.Getter}> /// The CapabilityFilter is a restriction put at the front of obtaining any non-public Capability. Some wallets /// might want to give access to NonFungibleToken.Provider, but only to **some** of the collections it manages, /// not all of them. - pub var filter: Capability<&{CapabilityFilter.Filter}> + access(self) var filter: Capability<&{CapabilityFilter.Filter}> /// The CapabilityDelegator is a way to share one-off capabilities from the child account. These capabilities /// can be public OR private and are separate from the factory which returns a capability at a given path as a /// certain type. When using the CapabilityDelegator, you do not have the ability to specify which path a /// capability came from. For instance, Dapper Wallet might choose to expose a Capability to their Full TopShot /// collection, but only to the path that the collection exists in. - pub let delegator: Capability<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}> + access(self) let delegator: Capability /// managerCapabilityFilter is a component optionally given to a child account when a manager redeems it. If /// this filter is not nil, any Capability returned through the `getCapability` function checks that the @@ -538,11 +542,11 @@ pub contract HybridCustody { /// ChildAccount resources have a 1:1 association with parent accounts, the named parent Address here is the /// one with a Capability on this resource. - pub let parent: Address + access(all) let parent: Address /// Returns the Address of the underlying child account /// - pub fun getAddress(): Address { + access(all) view fun getAddress(): Address { return self.childCap.address } @@ -562,13 +566,13 @@ pub contract HybridCustody { /// Sets the CapabiltyFactory.Manager Capability /// - pub fun setCapabilityFactory(cap: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>) { + access(Restricted) fun setCapabilityFactory(cap: Capability<&{CapabilityFactory.Getter}>) { self.factory = cap } /// Sets the Filter Capability as the one provided /// - pub fun setCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>) { + access(Restricted) fun setCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>) { self.filter = cap } @@ -579,7 +583,7 @@ pub contract HybridCustody { /// Capabilities, see `getPrivateCapFromDelegator()` and `getPublicCapFromDelegator()` which use the /// `Delegator` retrieval path. /// - pub fun getCapability(path: CapabilityPath, type: Type): Capability? { + access(Capabilities) view fun getCapability(controllerID: UInt64, type: Type): Capability? { let child = self.childCap.borrow() ?? panic("failed to borrow child account") let f = self.factory.borrow()!.getFactory(type) @@ -588,14 +592,15 @@ pub contract HybridCustody { } let acct = child.borrowAccount() - let cap = f!.getCapability(acct: acct, path: path) + let tmp = f!.getCapability(acct: acct, controllerID: controllerID) + if tmp == nil { + return nil + } + let cap = tmp! // Check that private capabilities are allowed by either internal or manager filter (if assigned) // If not allowed, return nil - if path.getType() == Type() && ( - self.filter.borrow()!.allowed(cap: cap) == false || - (self.getManagerCapabilityFilter()?.allowed(cap: cap) ?? true) == false - ) { + if self.filter.borrow()!.allowed(cap: cap) == false || (self.getManagerCapabilityFilter()?.allowed(cap: cap) ?? true) == false { return nil } @@ -605,7 +610,7 @@ pub contract HybridCustody { /// Retrieves a private Capability from the Delegator or nil none is found of the given type. Useful for /// arbitrary Capability retrieval /// - pub fun getPrivateCapFromDelegator(type: Type): Capability? { + access(Capabilities) view fun getPrivateCapFromDelegator(type: Type): Capability? { if let d = self.delegator.borrow() { return d.getPrivateCapability(type) } @@ -616,23 +621,25 @@ pub contract HybridCustody { /// Retrieves a public Capability from the Delegator or nil none is found of the given type. Useful for /// arbitrary Capability retrieval /// - pub fun getPublicCapFromDelegator(type: Type): Capability? { + access(all) view fun getPublicCapFromDelegator(type: Type): Capability? { if let d = self.delegator.borrow() { return d.getPublicCapability(type) } return nil } + /// TODO: This has been disabled because you cannot get a capability without providing a type T anymore in Cadence 1.0 + // /// Enables retrieval of public Capabilities of the given type from the specified path or nil if none is found. /// Callers should be aware this method uses the `CapabilityFactory` retrieval path. /// - pub fun getPublicCapability(path: PublicPath, type: Type): Capability? { - return self.getCapability(path: path, type: type) - } + // access(all) view fun getPublicCapability(path: PublicPath, type: Type): Capability? { + // return self.getCapability(path: path, type: type) + // } /// Returns a reference to the stored managerCapabilityFilter if one exists /// - pub fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}? { + access(all) view fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}? { return self.managerCapabilityFilter != nil ? self.managerCapabilityFilter!.borrow() : nil } @@ -640,23 +647,23 @@ pub contract HybridCustody { /// access(contract) fun setRedeemed(_ addr: Address) { let acct = self.childCap.borrow()!.borrowAccount() - if let o = acct.borrow<&OwnedAccount>(from: HybridCustody.OwnedAccountStoragePath) { + if let o = acct.storage.borrow<&OwnedAccount>(from: HybridCustody.OwnedAccountStoragePath) { o.setRedeemed(addr) } } /// Returns a reference to the stored delegator, generally used for arbitrary Capability retrieval /// - pub fun borrowCapabilityDelegator(): &CapabilityDelegator.Delegator? { + access(Restricted) fun borrowCapabilityDelegator(): &CapabilityDelegator.Delegator? { let path = HybridCustody.getCapabilityDelegatorIdentifier(self.parent) - return self.childCap.borrow()!.borrowAccount().borrow<&CapabilityDelegator.Delegator>( + return self.childCap.borrow()!.borrowAccount().storage.borrow<&CapabilityDelegator.Delegator>( from: StoragePath(identifier: path)! ) } /// Returns a list of supported metadata views /// - pub fun getViews(): [Type] { + access(all) view fun getViews(): [Type] { return [ Type() ] @@ -664,17 +671,22 @@ pub contract HybridCustody { /// Resolves a view of the given type if supported /// - pub fun resolveView(_ view: Type): AnyStruct? { + access(all) fun resolveView(_ view: Type): AnyStruct? { switch view { case Type(): let childAddress = self.getAddress() - let manager = getAccount(self.parent).getCapability<&HybridCustody.Manager{HybridCustody.ManagerPublic}>(HybridCustody.ManagerPublicPath) + let tmp = getAccount(self.parent).capabilities.get<&{HybridCustody.ManagerPublic}>(HybridCustody.ManagerPublicPath) + if tmp == nil { + return nil + } + + let manager = tmp! if !manager.check() { return nil } - return manager!.borrow()!.getChildAccountDisplay(address: childAddress) + return manager.borrow()!.getChildAccountDisplay(address: childAddress) } return nil } @@ -687,22 +699,22 @@ pub contract HybridCustody { return } - let child: &AnyResource{HybridCustody.BorrowableAccount} = self.childCap.borrow()! + let child: &{HybridCustody.BorrowableAccount} = self.childCap.borrow()! if !child.check() { return } let acct = child.borrowAccount() - if let ownedAcct = acct.borrow<&OwnedAccount>(from: HybridCustody.OwnedAccountStoragePath) { + if let ownedAcct = acct.storage.borrow(from: HybridCustody.OwnedAccountStoragePath) { ownedAcct.removeParent(parent: parent) } } init( - _ childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, MetadataViews.Resolver}>, - _ factory: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>, + _ childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}>, + _ factory: Capability<&{CapabilityFactory.Getter}>, _ filter: Capability<&{CapabilityFilter.Filter}>, - _ delegator: Capability<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}>, + _ delegator: Capability, _ parent: Address ) { pre { @@ -724,19 +736,20 @@ pub contract HybridCustody { /// Returns a capability to this child account's CapabilityFilter /// - pub fun getCapabilityFilter(): &{CapabilityFilter.Filter}? { + access(all) view 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}? { + access(all) view fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}? { return self.factory.check() ? self.factory.borrow() : nil } - destroy () { - destroy <- self.resources - } + // TODO: burnCallback and ResourceDestoryed event + // destroy () { + // destroy <- self.resources + // } } /// A resource which sits on the account it manages to make it easier for apps to configure the behavior they want @@ -748,18 +761,18 @@ pub contract HybridCustody { /// accounts would still exist, allowing a form of Hybrid Custody which has no true owner over an account, but /// shared partial ownership. /// - pub resource OwnedAccount: OwnedAccountPrivate, BorrowableAccount, OwnedAccountPublic, MetadataViews.Resolver { + access(all) resource OwnedAccount: OwnedAccountPrivate, BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver { /// Capability on the underlying account object - access(self) var acct: Capability<&AuthAccount> + access(self) var acct: Capability /// Mapping of current and pending parents, true and false respectively - pub let parents: {Address: Bool} + access(all) let parents: {Address: Bool} /// Address of the pending owner, if one exists - pub var pendingOwner: Address? + access(all) var pendingOwner: Address? /// Address of the current owner, if one exists - pub var acctOwner: Address? + access(all) var acctOwner: Address? /// Owned status of this account - pub var currentlyOwned: Bool + access(all) var currentlyOwned: Bool /// A bucket of structs so that the OwnedAccount resource can be easily extended with new functionality. access(self) let data: {String: AnyStruct} @@ -810,12 +823,12 @@ pub contract HybridCustody { /// 4. Publish the newly made private link to the designated parent's inbox for them to claim on their @Manager /// resource. /// - pub fun publishToParent( + access(Restricted) fun publishToParent( parentAddress: Address, - factory: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}>, + factory: Capability<&{CapabilityFactory.Getter}>, filter: Capability<&{CapabilityFilter.Filter}> ) { - pre{ + pre { self.parents[parentAddress] == nil: "Address pending or already redeemed as parent" } let capDelegatorIdentifier = HybridCustody.getCapabilityDelegatorIdentifier(parentAddress) @@ -826,41 +839,32 @@ pub contract HybridCustody { let capDelegatorStorage = StoragePath(identifier: capDelegatorIdentifier)! let acct = self.borrowAccount() - assert(acct.borrow<&AnyResource>(from: capDelegatorStorage) == nil, message: "conflicting resource found in capability delegator storage slot for parentAddress") - assert(acct.borrow<&AnyResource>(from: childAccountStorage) == nil, message: "conflicting resource found in child account storage slot for parentAddress") + assert(acct.storage.borrow<&AnyResource>(from: capDelegatorStorage) == nil, message: "conflicting resource found in capability delegator storage slot for parentAddress") + assert(acct.storage.borrow<&AnyResource>(from: childAccountStorage) == nil, message: "conflicting resource found in child account storage slot for parentAddress") - if acct.borrow<&CapabilityDelegator.Delegator>(from: capDelegatorStorage) == nil { + if acct.storage.borrow<&CapabilityDelegator.Delegator>(from: capDelegatorStorage) == nil { let delegator <- CapabilityDelegator.createDelegator() - acct.save(<-delegator, to: capDelegatorStorage) + acct.storage.save(<-delegator, to: capDelegatorStorage) } let capDelegatorPublic = PublicPath(identifier: capDelegatorIdentifier)! - let capDelegatorPrivate = PrivatePath(identifier: capDelegatorIdentifier)! + // let capDelegatorPrivate = PrivatePath(identifier: capDelegatorIdentifier)! - acct.link<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic}>( - capDelegatorPublic, - target: capDelegatorStorage - ) - acct.link<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}>( - capDelegatorPrivate, - target: capDelegatorStorage - ) - let delegator = acct.getCapability<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}>( - capDelegatorPrivate - ) + let pubCap = acct.capabilities.storage.issue<&{CapabilityDelegator.GetterPublic}>(capDelegatorStorage) + acct.capabilities.publish(pubCap, at: capDelegatorPublic) + + let delegator = acct.capabilities.storage.issue(capDelegatorStorage) assert(delegator.check(), message: "failed to setup capability delegator for parent address") - let borrowableCap = self.borrowAccount().getCapability<&{BorrowableAccount, OwnedAccountPublic, MetadataViews.Resolver}>( - HybridCustody.OwnedAccountPrivatePath + let borrowableCap = self.borrowAccount().capabilities.storage.issue<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}>( + HybridCustody.OwnedAccountStoragePath ) - let childAcct <- create ChildAccount(borrowableCap, factory, filter, delegator, parentAddress) + let childAcct <- create ChildAccount(borrowableCap, factory, filter, delegator, parentAddress) let childAccountPrivatePath = PrivatePath(identifier: identifier)! - acct.save(<-childAcct, to: childAccountStorage) - acct.link<&ChildAccount{AccountPrivate, AccountPublic, MetadataViews.Resolver}>(childAccountPrivatePath, target: childAccountStorage) - - let delegatorCap = acct.getCapability<&ChildAccount{AccountPrivate, AccountPublic, MetadataViews.Resolver}>(childAccountPrivatePath) + acct.storage.save(<-childAcct, to: childAccountStorage) + let delegatorCap = acct.capabilities.storage.issue<&{AccountPrivate, AccountPublic, ViewResolver.Resolver}>(childAccountStorage) assert(delegatorCap.check(), message: "Delegator capability check failed") acct.inbox.publish(delegatorCap, name: identifier, recipient: parentAddress) @@ -880,38 +884,38 @@ pub contract HybridCustody { /// Checks the validity of the encapsulated account Capability /// - pub fun check(): Bool { + access(all) view fun check(): Bool { return self.acct.check() } /// Returns a reference to the encapsulated account object /// - pub fun borrowAccount(): &AuthAccount { + access(contract) view fun borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account { return self.acct.borrow()! } /// Returns the addresses of all associated parents pending and active /// - pub fun getParentAddresses(): [Address] { + access(all) view fun getParentAddresses(): [Address] { return self.parents.keys } /// Returns whether the given address is a parent of this account /// - pub fun isChildOf(_ addr: Address): Bool { + access(all) view fun isChildOf(_ addr: Address): Bool { return self.parents[addr] != nil } /// Returns nil if the given address is not a parent, false if the parent has not redeemed the child account /// yet, and true if they have /// - pub fun getRedeemedStatus(addr: Address): Bool? { + access(all) view fun getRedeemedStatus(addr: Address): Bool? { return self.parents[addr] } /// Returns associated parent addresses and their redeemed status /// - pub fun getParentStatuses(): {Address: Bool} { + access(all) view fun getParentStatuses(): {Address: Bool} { return self.parents } @@ -919,7 +923,7 @@ pub contract HybridCustody { /// configured for the provided parent address. Once done, the parent will not have any valid capabilities with /// which to access the child account. /// - pub fun removeParent(parent: Address): Bool { + access(Restricted) fun removeParent(parent: Address): Bool { if self.parents[parent] == nil { return false } @@ -927,21 +931,28 @@ pub contract HybridCustody { let capDelegatorIdentifier = HybridCustody.getCapabilityDelegatorIdentifier(parent) let acct = self.borrowAccount() - acct.unlink(PrivatePath(identifier: identifier)!) - acct.unlink(PublicPath(identifier: identifier)!) - acct.unlink(PrivatePath(identifier: capDelegatorIdentifier)!) - acct.unlink(PublicPath(identifier: capDelegatorIdentifier)!) + // get all controllers which target this storage path + let storagePath = StoragePath(identifier: identifier)! + let childAccountControllers = acct.capabilities.storage.getControllers(forPath: storagePath) + for c in childAccountControllers { + c.delete() + } + destroy <- acct.storage.load<@AnyResource>(from: storagePath) - destroy <- acct.load<@AnyResource>(from: StoragePath(identifier: identifier)!) - destroy <- acct.load<@AnyResource>(from: StoragePath(identifier: capDelegatorIdentifier)!) + let delegatorStoragePath = StoragePath(identifier: capDelegatorIdentifier)! + let delegatorControllers = acct.capabilities.storage.getControllers(forPath: delegatorStoragePath) + for c in delegatorControllers { + c.delete() + } + destroy <- acct.storage.load<@AnyResource>(from: delegatorStoragePath) self.parents.remove(key: parent) emit AccountUpdated(id: self.uuid, child: self.acct.address, parent: parent, active: false) - let parentManager = getAccount(parent).getCapability<&Manager{ManagerPublic}>(HybridCustody.ManagerPublicPath) - if parentManager.check() { - parentManager.borrow()?.removeParentCallback(child: self.owner!.address) + let parentManager = getAccount(parent).capabilities.get<&{ManagerPublic}>(HybridCustody.ManagerPublicPath) + if parentManager?.check() == true { + parentManager!.borrow()?.removeParentCallback(child: self.owner!.address) } return true @@ -949,21 +960,21 @@ pub contract HybridCustody { /// Returns the address of the encapsulated account /// - pub fun getAddress(): Address { + access(all) view fun getAddress(): Address { return self.acct.address } /// Returns the address of the pending owner if one is assigned. Pending owners are assigned when ownership has /// been granted, but has not yet been redeemed. /// - pub fun getPendingOwner(): Address? { + access(all) view fun getPendingOwner(): Address? { return self.pendingOwner } /// Returns the address of the current owner if one is assigned. Current owners are assigned when ownership has /// been redeemed. /// - pub fun getOwner(): Address? { + access(all) view fun getOwner(): Address? { if !self.currentlyOwned { return nil } @@ -979,23 +990,19 @@ pub contract HybridCustody { /// mechanism intended to easily transfer 'root' access on this account to another account and an attempt to /// minimize access vectors. /// - pub fun giveOwnership(to: Address) { + access(Owner) fun giveOwnership(to: Address) { self.seal() let acct = self.borrowAccount() // Unlink existing owner's Capability if owner exists if self.acctOwner != nil { - acct.unlink( - PrivatePath(identifier: HybridCustody.getOwnerIdentifier(self.acctOwner!))! - ) + acct.capabilities.account.getController(byCapabilityID: self.acct.id)?.delete() } + + // Link a Capability for the new owner, retrieve & publish let identifier = HybridCustody.getOwnerIdentifier(to) - let cap = acct.link<&{OwnedAccountPrivate, OwnedAccountPublic, MetadataViews.Resolver}>( - PrivatePath(identifier: identifier)!, - target: HybridCustody.OwnedAccountStoragePath - ) ?? panic("failed to link child account capability") - + let cap = acct.capabilities.storage.issue<&{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}>(HybridCustody.OwnedAccountStoragePath) acct.inbox.publish(cap, name: identifier, recipient: to) self.pendingOwner = to @@ -1006,7 +1013,7 @@ pub contract HybridCustody { /// Revokes all keys on the underlying account /// - pub fun revokeAllKeys() { + access(Owner) fun revokeAllKeys() { let acct = self.borrowAccount() // Revoke all keys @@ -1025,35 +1032,26 @@ pub contract HybridCustody { /// assumes ownership of an account to guarantee that the previous owner doesn't maintain admin access to the /// account via other AuthAccount Capabilities. /// - pub fun rotateAuthAccount() { + access(Owner) fun rotateAuthAccount() { let acct = self.borrowAccount() // Find all active AuthAccount capabilities so they can be removed after we make the new auth account cap - let pathsToUnlink: [PrivatePath] = [] - acct.forEachPrivate(fun (path: PrivatePath, type: Type): Bool { - if type.identifier == "Capability<&AuthAccount>" { - pathsToUnlink.append(path) - } + let idsToDestroy: [UInt64] = [] + acct.capabilities.account.forEachController(fun(con: &AccountCapabilityController): Bool { + idsToDestroy.append(con.capabilityID) return true }) // Link a new AuthAccount Capability - // NOTE: This path cannot be sufficiently randomly generated, an app calling this function could build a - // capability to this path before it is made, thus maintaining ownership despite making it look like they - // gave it away. Until capability controllers, this method should not be fully trusted. - let authAcctPath = "HybridCustodyRelinquished_" - .concat(HybridCustody.account.address.toString()) - .concat(getCurrentBlock().height.toString()) - .concat(unsafeRandom().toString()) // ensure that the path is different from the previous one - let acctCap = acct.linkAccount(PrivatePath(identifier: authAcctPath)!)! + let acctCap = acct.capabilities.account.issue() self.acct = acctCap let newAcct = self.acct.borrow()! // cleanup, remove all previously found paths. We had to do it in this order because we will be unlinking // the existing path which will cause a deference issue with the originally borrowed auth account - for p in pathsToUnlink { - newAcct.unlink(p) + for id in idsToDestroy { + newAcct.capabilities.account.getController(byCapabilityID: id)?.delete() } } @@ -1064,7 +1062,7 @@ pub contract HybridCustody { /// /// USE WITH EXTREME CAUTION. /// - pub fun seal() { + access(Owner) fun seal() { self.rotateAuthAccount() self.revokeAllKeys() // There needs to be a path to giving ownership that doesn't revoke keys emit AccountSealed(id: self.uuid, address: self.acct.address, parents: self.parents.keys) @@ -1073,16 +1071,16 @@ pub contract HybridCustody { /// Retrieves a reference to the ChildAccount associated with the given parent account if one exists. /// - pub fun borrowChildAccount(parent: Address): &ChildAccount? { + access(Restricted) fun borrowChildAccount(parent: Address): auth(Restricted) &ChildAccount? { let identifier = HybridCustody.getChildAccountIdentifier(parent) - return self.borrowAccount().borrow<&ChildAccount>(from: StoragePath(identifier: identifier)!) + return self.borrowAccount().storage.borrow(from: StoragePath(identifier: identifier)!) } /// Sets the CapabilityFactory Manager for the specified parent in the associated ChildAccount. /// - pub fun setCapabilityFactoryForParent( + access(Restricted) fun setCapabilityFactoryForParent( parent: Address, - cap: Capability<&CapabilityFactory.Manager{CapabilityFactory.Getter}> + cap: Capability<&{CapabilityFactory.Getter}> ) { let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address") p.setCapabilityFactory(cap: cap) @@ -1090,21 +1088,21 @@ pub contract HybridCustody { /// Sets the Filter for the specified parent in the associated ChildAccount. /// - pub fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) { + access(Restricted) fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) { let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address") p.setCapabilityFilter(cap: cap) } /// Retrieves a reference to the Delegator associated with the given parent account if one exists. /// - pub fun borrowCapabilityDelegatorForParent(parent: Address): &CapabilityDelegator.Delegator? { + access(Restricted) fun borrowCapabilityDelegatorForParent(parent: Address): auth(Mutate) &CapabilityDelegator.Delegator? { let identifier = HybridCustody.getCapabilityDelegatorIdentifier(parent) - return self.borrowAccount().borrow<&CapabilityDelegator.Delegator>(from: StoragePath(identifier: identifier)!) + return self.borrowAccount().storage.borrow(from: StoragePath(identifier: identifier)!) } /// Adds the provided Capability to the Delegator associated with the given parent account. /// - pub fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) { + access(Restricted) fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) { let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address") let delegator = self.borrowCapabilityDelegatorForParent(parent: parent) ?? panic("could not borrow capability delegator resource for parent address") @@ -1113,20 +1111,20 @@ pub contract HybridCustody { /// Removes the provided Capability from the Delegator associated with the given parent account. /// - pub fun removeCapabilityFromDelegator(parent: Address, cap: Capability) { + access(Restricted) fun removeCapabilityFromDelegator(parent: Address, cap: Capability) { let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address") let delegator = self.borrowCapabilityDelegatorForParent(parent: parent) ?? panic("could not borrow capability delegator resource for parent address") delegator.removeCapability(cap: cap) } - pub fun getViews(): [Type] { + access(all) view fun getViews(): [Type] { return [ Type() ] } - pub fun resolveView(_ view: Type): AnyStruct? { + access(all) fun resolveView(_ view: Type): AnyStruct? { switch view { case Type(): return self.display @@ -1136,12 +1134,12 @@ pub contract HybridCustody { /// Sets this OwnedAccount's display to the one provided /// - pub fun setDisplay(_ d: MetadataViews.Display) { + access(Restricted) fun setDisplay(_ d: MetadataViews.Display) { self.display = d } init( - _ acct: Capability<&AuthAccount> + _ acct: Capability ) { self.acct = acct @@ -1155,36 +1153,37 @@ pub contract HybridCustody { self.display = nil } - destroy () { - destroy <- self.resources - } + // TODO: Use the burner interface + // destroy () { + // destroy <- self.resources + // } } /// Utility function to get the path identifier for a parent address when interacting with a ChildAccount and its /// parents /// - pub fun getChildAccountIdentifier(_ addr: Address): String { + access(all) view fun getChildAccountIdentifier(_ addr: Address): String { return "ChildAccount_".concat(addr.toString()) } /// Utility function to get the path identifier for a parent address when interacting with a Delegator and its /// parents /// - pub fun getCapabilityDelegatorIdentifier(_ addr: Address): String { + access(all) view fun getCapabilityDelegatorIdentifier(_ addr: Address): String { return "ChildCapabilityDelegator_".concat(addr.toString()) } /// Utility function to get the path identifier for a parent address when interacting with an OwnedAccount and its /// owners /// - pub fun getOwnerIdentifier(_ addr: Address): String { + access(all) view fun getOwnerIdentifier(_ addr: Address): String { return "HybridCustodyOwnedAccount_".concat(HybridCustody.account.address.toString()).concat(addr.toString()) } /// Returns an OwnedAccount wrapping the provided AuthAccount Capability. /// - pub fun createOwnedAccount( - acct: Capability<&AuthAccount> + access(all) fun createOwnedAccount( + acct: Capability ): @OwnedAccount { pre { acct.check(): "invalid auth account capability" @@ -1197,7 +1196,7 @@ pub contract HybridCustody { /// Returns a new Manager with the provided Filter as default (if not nil). /// - pub fun createManager(filter: Capability<&{CapabilityFilter.Filter}>?): @Manager { + access(all) fun createManager(filter: Capability<&{CapabilityFilter.Filter}>?): @Manager { pre { filter == nil || filter!.check(): "Invalid CapabilityFilter Filter capability provided" }