@flowtyio/flow-contracts 0.1.0-beta.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/contracts/FungibleTokenSwitchboard.cdc +360 -0
- package/contracts/MetadataViews.cdc +79 -6
- package/contracts/NonFungibleToken.cdc +17 -10
- package/contracts/capability-cache/CapabilityCache.cdc +97 -0
- package/contracts/dapper/TopShot.cdc +323 -259
- package/contracts/dapper/TopShotLocking.cdc +41 -15
- package/contracts/dapper/offers/DapperOffersV2.cdc +46 -43
- package/contracts/dapper/offers/OffersV2.cdc +40 -56
- package/contracts/dapper/offers/Resolver.cdc +20 -13
- package/contracts/emerald-city/FLOAT.cdc +259 -254
- package/contracts/example/ExampleNFT.cdc +2 -2
- package/contracts/find/FindViews.cdc +357 -353
- package/contracts/flow-utils/ScopedFTProviders.cdc +5 -2
- package/contracts/flow-utils/ScopedNFTProviders.cdc +6 -2
- package/contracts/flowty-drops/ContractManager.cdc +73 -0
- package/contracts/flowty-drops/DropFactory.cdc +75 -0
- package/contracts/flowty-drops/DropTypes.cdc +282 -0
- package/contracts/flowty-drops/FlowtyActiveCheckers.cdc +113 -0
- package/contracts/flowty-drops/FlowtyAddressVerifiers.cdc +64 -0
- package/contracts/flowty-drops/FlowtyDrops.cdc +461 -0
- package/contracts/flowty-drops/FlowtyPricers.cdc +48 -0
- package/contracts/flowty-drops/initializers/ContractBorrower.cdc +14 -0
- package/contracts/flowty-drops/initializers/ContractInitializer.cdc +7 -0
- package/contracts/flowty-drops/initializers/OpenEditionInitializer.cdc +57 -0
- package/contracts/flowty-drops/nft/BaseCollection.cdc +97 -0
- package/contracts/flowty-drops/nft/BaseNFT.cdc +107 -0
- package/contracts/flowty-drops/nft/ContractFactory.cdc +13 -0
- package/contracts/flowty-drops/nft/ContractFactoryTemplate.cdc +48 -0
- package/contracts/flowty-drops/nft/NFTMetadata.cdc +140 -0
- package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +42 -0
- package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +54 -0
- package/contracts/flowty-drops/nft/UniversalCollection.cdc +29 -0
- package/contracts/fungible-token-router/FungibleTokenRouter.cdc +103 -0
- package/contracts/hybrid-custody/CapabilityDelegator.cdc +28 -26
- package/contracts/hybrid-custody/CapabilityFactory.cdc +20 -18
- package/contracts/hybrid-custody/CapabilityFilter.cdc +41 -24
- package/contracts/hybrid-custody/HybridCustody.cdc +303 -242
- package/contracts/hybrid-custody/factories/FTAllFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTBalanceFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTProviderFactory.cdc +17 -5
- package/contracts/hybrid-custody/factories/FTReceiverBalanceFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTReceiverFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/FTVaultFactory.cdc +46 -0
- package/contracts/hybrid-custody/factories/NFTCollectionFactory.cdc +45 -0
- package/contracts/hybrid-custody/factories/NFTCollectionPublicFactory.cdc +16 -4
- package/contracts/hybrid-custody/factories/NFTProviderAndCollectionFactory.cdc +22 -0
- package/contracts/hybrid-custody/factories/NFTProviderFactory.cdc +16 -4
- package/contracts/lost-and-found/LostAndFound.cdc +21 -17
- package/flow.json +181 -7
- package/package.json +1 -1
- package/contracts/hybrid-custody/factories/NFTProviderAndCollectionPublicFactory.cdc +0 -10
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Third-party imports
|
|
2
2
|
import "MetadataViews"
|
|
3
|
+
import "ViewResolver"
|
|
4
|
+
import "Burner"
|
|
3
5
|
|
|
4
6
|
// HC-owned imports
|
|
5
7
|
import "CapabilityFactory"
|
|
@@ -27,39 +29,37 @@ import "CapabilityFilter"
|
|
|
27
29
|
///
|
|
28
30
|
/// Repo reference: https://github.com/onflow/hybrid-custody
|
|
29
31
|
///
|
|
30
|
-
|
|
32
|
+
access(all) contract HybridCustody {
|
|
33
|
+
access(all) entitlement Owner
|
|
34
|
+
access(all) entitlement Child
|
|
35
|
+
access(all) entitlement Manage
|
|
31
36
|
|
|
32
37
|
/* --- Canonical Paths --- */
|
|
33
38
|
//
|
|
34
39
|
// Note: Paths for ChildAccount & Delegator are derived from the parent's address
|
|
35
40
|
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pub let OwnedAccountPrivatePath: PrivatePath
|
|
41
|
+
access(all) let OwnedAccountStoragePath: StoragePath
|
|
42
|
+
access(all) let OwnedAccountPublicPath: PublicPath
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
pub let ManagerPrivatePath: PrivatePath
|
|
43
|
-
|
|
44
|
-
pub let LinkedAccountPrivatePath: PrivatePath
|
|
45
|
-
pub let BorrowableAccountPrivatePath: PrivatePath
|
|
44
|
+
access(all) let ManagerStoragePath: StoragePath
|
|
45
|
+
access(all) let ManagerPublicPath: PublicPath
|
|
46
46
|
|
|
47
47
|
/* --- Events --- */
|
|
48
48
|
//
|
|
49
49
|
/// Manager creation event
|
|
50
|
-
|
|
50
|
+
access(all) event CreatedManager(id: UInt64)
|
|
51
51
|
/// OwnedAccount creation event
|
|
52
|
-
|
|
52
|
+
access(all) event CreatedOwnedAccount(id: UInt64, child: Address)
|
|
53
53
|
/// ChildAccount added/removed from Manager
|
|
54
54
|
/// active : added to Manager
|
|
55
55
|
/// !active : removed from Manager
|
|
56
|
-
|
|
56
|
+
access(all) event AccountUpdated(id: UInt64?, child: Address, parent: Address?, active: Bool)
|
|
57
57
|
/// OwnedAccount added/removed or sealed
|
|
58
58
|
/// active && owner != nil : added to Manager
|
|
59
59
|
/// !active && owner == nil : removed from Manager
|
|
60
|
-
|
|
60
|
+
access(all) event OwnershipUpdated(id: UInt64, child: Address, previousOwner: Address?, owner: Address?, active: Bool)
|
|
61
61
|
/// ChildAccount ready to be redeemed by emitted pendingParent
|
|
62
|
-
|
|
62
|
+
access(all) event ChildAccountPublished(
|
|
63
63
|
ownedAcctID: UInt64,
|
|
64
64
|
childAcctID: UInt64,
|
|
65
65
|
capDelegatorID: UInt64,
|
|
@@ -70,49 +70,52 @@ pub contract HybridCustody {
|
|
|
70
70
|
pendingParent: Address
|
|
71
71
|
)
|
|
72
72
|
/// OwnedAccount granted ownership to a new address, publishing a Capability for the pendingOwner
|
|
73
|
-
|
|
73
|
+
access(all) event OwnershipGranted(ownedAcctID: UInt64, child: Address, previousOwner: Address?, pendingOwner: Address)
|
|
74
74
|
/// Account has been sealed - keys revoked, new AuthAccount Capability generated
|
|
75
|
-
|
|
75
|
+
access(all) event AccountSealed(id: UInt64, address: Address, parents: [Address])
|
|
76
76
|
|
|
77
77
|
/// An OwnedAccount shares the BorrowableAccount capability to itelf with ChildAccount resources
|
|
78
78
|
///
|
|
79
|
-
|
|
80
|
-
access(contract) fun
|
|
81
|
-
|
|
79
|
+
access(all) resource interface BorrowableAccount {
|
|
80
|
+
access(contract) view fun _borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account
|
|
81
|
+
access(all) view fun check(): Bool
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/// Public methods anyone can call on an OwnedAccount
|
|
85
85
|
///
|
|
86
|
-
|
|
86
|
+
access(all) resource interface OwnedAccountPublic {
|
|
87
87
|
/// Returns the addresses of all parent accounts
|
|
88
|
-
|
|
88
|
+
access(all) view fun getParentAddresses(): [Address]
|
|
89
89
|
|
|
90
90
|
/// Returns associated parent addresses and their redeemed status - true if redeemed, false if pending
|
|
91
|
-
|
|
91
|
+
access(all) view fun getParentStatuses(): {Address: Bool}
|
|
92
92
|
|
|
93
93
|
/// Returns true if the given address is a parent of this child and has redeemed it. Returns false if the given
|
|
94
94
|
/// address is a parent of this child and has NOT redeemed it. Returns nil if the given address it not a parent
|
|
95
95
|
/// of this child account.
|
|
96
|
-
|
|
96
|
+
access(all) view fun getRedeemedStatus(addr: Address): Bool?
|
|
97
97
|
|
|
98
98
|
/// A callback function to mark a parent as redeemed on the child account.
|
|
99
99
|
access(contract) fun setRedeemed(_ addr: Address)
|
|
100
|
+
|
|
101
|
+
/// A helper function to find what controller Id to ask for if you are looking for a specific type of capability
|
|
102
|
+
access(all) view fun getControllerIDForType(type: Type, forPath: StoragePath): UInt64?
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
/// Private interface accessible to the owner of the OwnedAccount
|
|
103
106
|
///
|
|
104
|
-
|
|
107
|
+
access(all) resource interface OwnedAccountPrivate {
|
|
105
108
|
/// Deletes the ChildAccount resource being used to share access to this OwnedAccount with the supplied parent
|
|
106
109
|
/// address, and unlinks the paths it was using to reach the underlying account.
|
|
107
|
-
|
|
110
|
+
access(Owner) fun removeParent(parent: Address): Bool
|
|
108
111
|
|
|
109
112
|
/// Sets up a new ChildAccount resource for the given parentAddress to redeem. This child account uses the
|
|
110
113
|
/// supplied factory and filter to manage what can be obtained from the child account, and a new
|
|
111
114
|
/// CapabilityDelegator resource is created for the sharing of one-off capabilities. Each of these pieces of
|
|
112
115
|
/// access control are managed through the child account.
|
|
113
|
-
|
|
116
|
+
access(Owner) fun publishToParent(
|
|
114
117
|
parentAddress: Address,
|
|
115
|
-
factory: Capability<&CapabilityFactory.Manager
|
|
118
|
+
factory: Capability<&CapabilityFactory.Manager>,
|
|
116
119
|
filter: Capability<&{CapabilityFilter.Filter}>
|
|
117
120
|
) {
|
|
118
121
|
pre {
|
|
@@ -124,7 +127,7 @@ pub contract HybridCustody {
|
|
|
124
127
|
/// Passes ownership of this child account to the given address. Once executed, all active keys on the child
|
|
125
128
|
/// account will be revoked, and the active AuthAccount Capability being used by to obtain capabilities will be
|
|
126
129
|
/// rotated, preventing anyone without the newly generated Capability from gaining access to the account.
|
|
127
|
-
|
|
130
|
+
access(Owner) fun giveOwnership(to: Address)
|
|
128
131
|
|
|
129
132
|
/// Revokes all keys on an account, unlinks all currently active AuthAccount capabilities, then makes a new one
|
|
130
133
|
/// and replaces the OwnedAccount's underlying AuthAccount Capability with the new one to ensure that all
|
|
@@ -132,20 +135,20 @@ pub contract HybridCustody {
|
|
|
132
135
|
/// Unless this method is executed via the giveOwnership function, this will leave an account **without** an
|
|
133
136
|
/// owner.
|
|
134
137
|
/// USE WITH EXTREME CAUTION.
|
|
135
|
-
|
|
138
|
+
access(Owner) fun seal()
|
|
136
139
|
|
|
137
140
|
// setCapabilityFactoryForParent
|
|
138
141
|
// Override the existing CapabilityFactory Capability for a given parent. This will allow the owner of the
|
|
139
142
|
// account to start managing their own factory of capabilities to be able to retrieve
|
|
140
|
-
|
|
143
|
+
access(Owner) fun setCapabilityFactoryForParent(parent: Address, cap: Capability<&CapabilityFactory.Manager>) {
|
|
141
144
|
pre {
|
|
142
145
|
cap.check(): "Invalid CapabilityFactory.Getter Capability provided"
|
|
143
146
|
}
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
/// Override the existing CapabilityFilter Capability for a given parent. This will allow the owner of the
|
|
147
|
-
/// account to start managing their own filter for retrieving Capabilities
|
|
148
|
-
|
|
150
|
+
/// account to start managing their own filter for retrieving Capabilities
|
|
151
|
+
access(Owner) fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) {
|
|
149
152
|
pre {
|
|
150
153
|
cap.check(): "Invalid CapabilityFilter Capability provided"
|
|
151
154
|
}
|
|
@@ -153,66 +156,67 @@ pub contract HybridCustody {
|
|
|
153
156
|
|
|
154
157
|
/// Adds a capability to a parent's managed @ChildAccount resource. The Capability can be made public,
|
|
155
158
|
/// permitting anyone to borrow it.
|
|
156
|
-
|
|
159
|
+
access(Owner) fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) {
|
|
157
160
|
pre {
|
|
158
161
|
cap.check<&AnyResource>(): "Invalid Capability provided"
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
164
|
|
|
162
165
|
/// Removes a Capability from the CapabilityDelegator used by the specified parent address
|
|
163
|
-
|
|
166
|
+
access(Owner) fun removeCapabilityFromDelegator(parent: Address, cap: Capability)
|
|
164
167
|
|
|
165
168
|
/// Returns the address of this OwnedAccount
|
|
166
|
-
|
|
169
|
+
access(all) view fun getAddress(): Address
|
|
167
170
|
|
|
168
171
|
/// Checks if this OwnedAccount is a child of the specified address
|
|
169
|
-
|
|
172
|
+
access(all) view fun isChildOf(_ addr: Address): Bool
|
|
170
173
|
|
|
171
174
|
/// Returns all addresses which are parents of this OwnedAccount
|
|
172
|
-
|
|
175
|
+
access(all) view fun getParentAddresses(): [Address]
|
|
173
176
|
|
|
174
177
|
/// Borrows this OwnedAccount's AuthAccount Capability
|
|
175
|
-
|
|
178
|
+
access(Owner) view fun borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account
|
|
176
179
|
|
|
177
180
|
/// Returns the current owner of this account, if there is one
|
|
178
|
-
|
|
181
|
+
access(all) view fun getOwner(): Address?
|
|
179
182
|
|
|
180
183
|
/// Returns the pending owner of this account, if there is one
|
|
181
|
-
|
|
184
|
+
access(all) view fun getPendingOwner(): Address?
|
|
182
185
|
|
|
183
186
|
/// A callback which is invoked when a parent redeems an owned account
|
|
184
187
|
access(contract) fun setOwnerCallback(_ addr: Address)
|
|
185
188
|
|
|
186
189
|
/// Destroys all outstanding AuthAccount capabilities on this owned account, and creates a new one for the
|
|
187
190
|
/// OwnedAccount to use
|
|
188
|
-
|
|
191
|
+
access(Owner) fun rotateAuthAccount()
|
|
189
192
|
|
|
190
193
|
/// Revokes all keys on this account
|
|
191
|
-
|
|
194
|
+
access(Owner) fun revokeAllKeys()
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
/// Public methods exposed on a ChildAccount resource. OwnedAccountPublic will share some methods here, but isn't
|
|
195
198
|
/// necessarily the same.
|
|
196
199
|
///
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
200
|
+
access(all) resource interface AccountPublic {
|
|
201
|
+
access(all) view fun getPublicCapability(path: PublicPath, type: Type): Capability?
|
|
202
|
+
access(all) view fun getPublicCapFromDelegator(type: Type): Capability?
|
|
203
|
+
access(all) view fun getAddress(): Address
|
|
204
|
+
access(all) view fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}?
|
|
205
|
+
access(all) view fun getCapabilityFilter(): &{CapabilityFilter.Filter}?
|
|
206
|
+
access(all) view fun getControllerIDForType(type: Type, forPath: StoragePath): UInt64?
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
/// Methods accessible to the designated parent of a ChildAccount
|
|
204
210
|
///
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
access(all) resource interface AccountPrivate {
|
|
212
|
+
access(Child) view fun getCapability(controllerID: UInt64, type: Type): Capability? {
|
|
207
213
|
post {
|
|
208
214
|
result == nil || [true, nil].contains(self.getManagerCapabilityFilter()?.allowed(cap: result!)):
|
|
209
215
|
"Capability is not allowed by this account's Parent"
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
pub fun getPublicCapFromDelegator(type: Type): Capability?
|
|
215
|
-
pub fun getPrivateCapFromDelegator(type: Type): Capability? {
|
|
218
|
+
access(all) view fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}?
|
|
219
|
+
access(Child) view fun getPrivateCapFromDelegator(type: Type): Capability? {
|
|
216
220
|
post {
|
|
217
221
|
result == nil || [true, nil].contains(self.getManagerCapabilityFilter()?.allowed(cap: result!)):
|
|
218
222
|
"Capability is not allowed by this account's Parent"
|
|
@@ -229,14 +233,14 @@ pub contract HybridCustody {
|
|
|
229
233
|
|
|
230
234
|
/// Entry point for a parent to obtain, maintain and access Capabilities or perform other actions on child accounts
|
|
231
235
|
///
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
access(all) resource interface ManagerPrivate {
|
|
237
|
+
access(Manage) fun addAccount(cap: Capability<auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}>)
|
|
238
|
+
access(Manage) fun borrowAccount(addr: Address): auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}?
|
|
239
|
+
access(Manage) fun removeChild(addr: Address)
|
|
240
|
+
access(Manage) fun addOwnedAccount(cap: Capability<auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}>)
|
|
241
|
+
access(Manage) fun borrowOwnedAccount(addr: Address): auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}?
|
|
242
|
+
access(Manage) fun removeOwned(addr: Address)
|
|
243
|
+
access(Manage) fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) {
|
|
240
244
|
pre {
|
|
241
245
|
cap == nil || cap!.check(): "Invalid Manager Capability Filter"
|
|
242
246
|
}
|
|
@@ -245,39 +249,40 @@ pub contract HybridCustody {
|
|
|
245
249
|
|
|
246
250
|
/// Functions anyone can call on a manager to get information about an account such as What child accounts it has
|
|
247
251
|
/// Functions anyone can call on a manager to get information about an account such as what child accounts it has
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
252
|
+
access(all) resource interface ManagerPublic {
|
|
253
|
+
access(all) view fun borrowAccountPublic(addr: Address): &{AccountPublic, ViewResolver.Resolver}?
|
|
254
|
+
access(all) view fun getChildAddresses(): [Address]
|
|
255
|
+
access(all) view fun getOwnedAddresses(): [Address]
|
|
256
|
+
access(all) view fun getChildAccountDisplay(address: Address): MetadataViews.Display?
|
|
253
257
|
access(contract) fun removeParentCallback(child: Address)
|
|
254
258
|
}
|
|
255
259
|
|
|
256
260
|
/// A resource for an account which fills the Parent role of the Child-Parent account management Model. A Manager
|
|
257
261
|
/// can redeem or remove child accounts, and obtain any capabilities exposed by the child account to them.
|
|
258
262
|
///
|
|
259
|
-
|
|
263
|
+
access(all) resource Manager: ManagerPrivate, ManagerPublic, ViewResolver.Resolver, Burner.Burnable {
|
|
264
|
+
access(all) event ResourceDestroyed(uuid: UInt64 = self.uuid)
|
|
260
265
|
|
|
261
266
|
/// Mapping of restricted access child account Capabilities indexed by their address
|
|
262
|
-
|
|
267
|
+
access(self) let childAccounts: {Address: Capability<auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}>}
|
|
263
268
|
/// Mapping of unrestricted owned account Capabilities indexed by their address
|
|
264
|
-
|
|
269
|
+
access(self) let ownedAccounts: {Address: Capability<auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}>}
|
|
265
270
|
|
|
266
271
|
/// A bucket of structs so that the Manager resource can be easily extended with new functionality.
|
|
267
|
-
|
|
272
|
+
access(self) let data: {String: AnyStruct}
|
|
268
273
|
/// A bucket of resources so that the Manager resource can be easily extended with new functionality.
|
|
269
|
-
|
|
274
|
+
access(self) let resources: @{String: AnyResource}
|
|
270
275
|
|
|
271
276
|
/// An optional filter to gate what capabilities are permitted to be returned from a child account For example,
|
|
272
277
|
/// Dapper Wallet parent account's should not be able to retrieve any FungibleToken Provider capabilities.
|
|
273
|
-
|
|
278
|
+
access(self) var filter: Capability<&{CapabilityFilter.Filter}>?
|
|
274
279
|
|
|
275
280
|
// display metadata for a child account exists on its parent
|
|
276
|
-
|
|
281
|
+
access(self) let childAccountDisplays: {Address: MetadataViews.Display}
|
|
277
282
|
|
|
278
283
|
/// Sets the Display on the ChildAccount. If nil, the display is removed.
|
|
279
284
|
///
|
|
280
|
-
|
|
285
|
+
access(Manage) fun setChildAccountDisplay(address: Address, _ d: MetadataViews.Display?) {
|
|
281
286
|
pre {
|
|
282
287
|
self.childAccounts[address] != nil: "There is no child account with this address"
|
|
283
288
|
}
|
|
@@ -293,7 +298,7 @@ pub contract HybridCustody {
|
|
|
293
298
|
/// Adds a ChildAccount Capability to this Manager. If a default Filter is set in the manager, it will also be
|
|
294
299
|
/// added to the ChildAccount
|
|
295
300
|
///
|
|
296
|
-
|
|
301
|
+
access(Manage) fun addAccount(cap: Capability<auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}>) {
|
|
297
302
|
pre {
|
|
298
303
|
self.childAccounts[cap.address] == nil: "There is already a child account with this address"
|
|
299
304
|
}
|
|
@@ -311,17 +316,17 @@ pub contract HybridCustody {
|
|
|
311
316
|
|
|
312
317
|
/// Sets the default Filter Capability for this Manager. Does not propagate to child accounts.
|
|
313
318
|
///
|
|
314
|
-
|
|
319
|
+
access(Manage) fun setDefaultManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?) {
|
|
315
320
|
pre {
|
|
316
321
|
cap == nil || cap!.check(): "supplied capability must be nil or check must pass"
|
|
317
322
|
}
|
|
318
323
|
|
|
319
324
|
self.filter = cap
|
|
320
325
|
}
|
|
321
|
-
|
|
326
|
+
|
|
322
327
|
/// Sets the Filter Capability for this Manager, propagating to the specified child account
|
|
323
328
|
///
|
|
324
|
-
|
|
329
|
+
access(Manage) fun setManagerCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>?, childAddress: Address) {
|
|
325
330
|
let acct = self.borrowAccount(addr: childAddress)
|
|
326
331
|
?? panic("child account not found")
|
|
327
332
|
|
|
@@ -331,7 +336,7 @@ pub contract HybridCustody {
|
|
|
331
336
|
/// Removes specified child account from the Manager's child accounts. Callbacks to the child account remove
|
|
332
337
|
/// any associated resources and Capabilities
|
|
333
338
|
///
|
|
334
|
-
|
|
339
|
+
access(Manage) fun removeChild(addr: Address) {
|
|
335
340
|
let cap = self.childAccounts.remove(key: addr)
|
|
336
341
|
?? panic("child account not found")
|
|
337
342
|
|
|
@@ -347,9 +352,11 @@ pub contract HybridCustody {
|
|
|
347
352
|
// Get the child account id before removing capability
|
|
348
353
|
let id: UInt64 = acct.uuid
|
|
349
354
|
|
|
350
|
-
|
|
355
|
+
if self.owner != nil {
|
|
356
|
+
acct.parentRemoveChildCallback(parent: self.owner!.address)
|
|
357
|
+
}
|
|
351
358
|
|
|
352
|
-
emit AccountUpdated(id: id, child: cap.address, parent: self.owner
|
|
359
|
+
emit AccountUpdated(id: id, child: cap.address, parent: self.owner?.address, active: false)
|
|
353
360
|
}
|
|
354
361
|
|
|
355
362
|
/// Contract callback that removes a child account from the Manager's child accounts in the event a child
|
|
@@ -363,7 +370,7 @@ pub contract HybridCustody {
|
|
|
363
370
|
/// Adds an owned account to the Manager's list of owned accounts, setting the Manager account as the owner of
|
|
364
371
|
/// the given account
|
|
365
372
|
///
|
|
366
|
-
|
|
373
|
+
access(Manage) fun addOwnedAccount(cap: Capability<auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}>) {
|
|
367
374
|
pre {
|
|
368
375
|
self.ownedAccounts[cap.address] == nil: "There is already an owned account with this address"
|
|
369
376
|
}
|
|
@@ -384,7 +391,7 @@ pub contract HybridCustody {
|
|
|
384
391
|
|
|
385
392
|
/// Returns a reference to a child account
|
|
386
393
|
///
|
|
387
|
-
|
|
394
|
+
access(Manage) fun borrowAccount(addr: Address): auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}? {
|
|
388
395
|
let cap = self.childAccounts[addr]
|
|
389
396
|
if cap == nil {
|
|
390
397
|
return nil
|
|
@@ -395,7 +402,7 @@ pub contract HybridCustody {
|
|
|
395
402
|
|
|
396
403
|
/// Returns a reference to a child account's public AccountPublic interface
|
|
397
404
|
///
|
|
398
|
-
|
|
405
|
+
access(all) view fun borrowAccountPublic(addr: Address): &{AccountPublic, ViewResolver.Resolver}? {
|
|
399
406
|
let cap = self.childAccounts[addr]
|
|
400
407
|
if cap == nil {
|
|
401
408
|
return nil
|
|
@@ -406,7 +413,7 @@ pub contract HybridCustody {
|
|
|
406
413
|
|
|
407
414
|
/// Returns a reference to an owned account
|
|
408
415
|
///
|
|
409
|
-
|
|
416
|
+
access(Manage) view fun borrowOwnedAccount(addr: Address): auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}? {
|
|
410
417
|
if let cap = self.ownedAccounts[addr] {
|
|
411
418
|
return cap.borrow()
|
|
412
419
|
}
|
|
@@ -417,7 +424,7 @@ pub contract HybridCustody {
|
|
|
417
424
|
/// Removes specified child account from the Manager's child accounts. Callbacks to the child account remove
|
|
418
425
|
/// any associated resources and Capabilities
|
|
419
426
|
///
|
|
420
|
-
|
|
427
|
+
access(Manage) fun removeOwned(addr: Address) {
|
|
421
428
|
if let acct = self.ownedAccounts.remove(key: addr) {
|
|
422
429
|
if acct.check() {
|
|
423
430
|
acct.borrow()!.seal()
|
|
@@ -437,7 +444,7 @@ pub contract HybridCustody {
|
|
|
437
444
|
/// mechanism intended to easily transfer 'root' access on this account to another account and an attempt to
|
|
438
445
|
/// minimize access vectors.
|
|
439
446
|
///
|
|
440
|
-
|
|
447
|
+
access(Manage) fun giveOwnership(addr: Address, to: Address) {
|
|
441
448
|
let acct = self.ownedAccounts.remove(key: addr)
|
|
442
449
|
?? panic("account not found")
|
|
443
450
|
|
|
@@ -446,31 +453,31 @@ pub contract HybridCustody {
|
|
|
446
453
|
|
|
447
454
|
/// Returns an array of child account addresses
|
|
448
455
|
///
|
|
449
|
-
|
|
456
|
+
access(all) view fun getChildAddresses(): [Address] {
|
|
450
457
|
return self.childAccounts.keys
|
|
451
458
|
}
|
|
452
459
|
|
|
453
460
|
/// Returns an array of owned account addresses
|
|
454
461
|
///
|
|
455
|
-
|
|
462
|
+
access(all) view fun getOwnedAddresses(): [Address] {
|
|
456
463
|
return self.ownedAccounts.keys
|
|
457
464
|
}
|
|
458
465
|
|
|
459
466
|
/// Retrieves the parent-defined display for the given child account
|
|
460
467
|
///
|
|
461
|
-
|
|
468
|
+
access(all) view fun getChildAccountDisplay(address: Address): MetadataViews.Display? {
|
|
462
469
|
return self.childAccountDisplays[address]
|
|
463
470
|
}
|
|
464
471
|
|
|
465
472
|
/// Returns the types of supported views - none at this time
|
|
466
473
|
///
|
|
467
|
-
|
|
474
|
+
access(all) view fun getViews(): [Type] {
|
|
468
475
|
return []
|
|
469
476
|
}
|
|
470
477
|
|
|
471
478
|
/// Resolves the given view if supported - none at this time
|
|
472
479
|
///
|
|
473
|
-
|
|
480
|
+
access(all) view fun resolveView(_ view: Type): AnyStruct? {
|
|
474
481
|
return nil
|
|
475
482
|
}
|
|
476
483
|
|
|
@@ -487,8 +494,19 @@ pub contract HybridCustody {
|
|
|
487
494
|
self.resources <- {}
|
|
488
495
|
}
|
|
489
496
|
|
|
490
|
-
|
|
491
|
-
|
|
497
|
+
// When a manager resource is destroyed, attempt to remove this parent from every
|
|
498
|
+
// child account it currently has
|
|
499
|
+
//
|
|
500
|
+
// Destruction will fail if there are any owned account to prevent loss of access to an account
|
|
501
|
+
access(contract) fun burnCallback() {
|
|
502
|
+
pre {
|
|
503
|
+
// Prevent accidental burning of a resource that has ownership of other accounts
|
|
504
|
+
self.ownedAccounts.length == 0: "cannot destroy a manager with owned accounts"
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
for c in self.childAccounts.keys {
|
|
508
|
+
self.removeChild(addr: c)
|
|
509
|
+
}
|
|
492
510
|
}
|
|
493
511
|
}
|
|
494
512
|
|
|
@@ -501,27 +519,29 @@ pub contract HybridCustody {
|
|
|
501
519
|
/// able to manage all ChildAccount resources it shares, without worrying about whether the upstream parent can do
|
|
502
520
|
/// anything to prevent it.
|
|
503
521
|
///
|
|
504
|
-
|
|
522
|
+
access(all) resource ChildAccount: AccountPrivate, AccountPublic, ViewResolver.Resolver, Burner.Burnable {
|
|
523
|
+
access(all) event ResourceDestroyed(uuid: UInt64 = self.uuid, address: Address = self.childCap.address, parent: Address = self.parent)
|
|
524
|
+
|
|
505
525
|
/// A Capability providing access to the underlying child account
|
|
506
|
-
access(self) let childCap: Capability<&{BorrowableAccount, OwnedAccountPublic,
|
|
526
|
+
access(self) let childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}>
|
|
507
527
|
|
|
508
528
|
/// The CapabilityFactory Manager is a ChildAccount's way of limiting what types can be asked for by its parent
|
|
509
529
|
/// account. The CapabilityFactory returns Capabilities which can be casted to their appropriate types once
|
|
510
530
|
/// obtained, but only if the child account has configured their factory to allow it. For instance, a
|
|
511
531
|
/// ChildAccount might choose to expose NonFungibleToken.Provider, but not FungibleToken.Provider
|
|
512
|
-
|
|
532
|
+
access(self) var factory: Capability<&CapabilityFactory.Manager>
|
|
513
533
|
|
|
514
534
|
/// The CapabilityFilter is a restriction put at the front of obtaining any non-public Capability. Some wallets
|
|
515
535
|
/// might want to give access to NonFungibleToken.Provider, but only to **some** of the collections it manages,
|
|
516
536
|
/// not all of them.
|
|
517
|
-
|
|
537
|
+
access(self) var filter: Capability<&{CapabilityFilter.Filter}>
|
|
518
538
|
|
|
519
539
|
/// The CapabilityDelegator is a way to share one-off capabilities from the child account. These capabilities
|
|
520
540
|
/// can be public OR private and are separate from the factory which returns a capability at a given path as a
|
|
521
541
|
/// certain type. When using the CapabilityDelegator, you do not have the ability to specify which path a
|
|
522
542
|
/// capability came from. For instance, Dapper Wallet might choose to expose a Capability to their Full TopShot
|
|
523
543
|
/// collection, but only to the path that the collection exists in.
|
|
524
|
-
|
|
544
|
+
access(self) let delegator: Capability<auth(CapabilityDelegator.Get) &CapabilityDelegator.Delegator>
|
|
525
545
|
|
|
526
546
|
/// managerCapabilityFilter is a component optionally given to a child account when a manager redeems it. If
|
|
527
547
|
/// this filter is not nil, any Capability returned through the `getCapability` function checks that the
|
|
@@ -536,11 +556,11 @@ pub contract HybridCustody {
|
|
|
536
556
|
|
|
537
557
|
/// ChildAccount resources have a 1:1 association with parent accounts, the named parent Address here is the
|
|
538
558
|
/// one with a Capability on this resource.
|
|
539
|
-
|
|
559
|
+
access(all) let parent: Address
|
|
540
560
|
|
|
541
561
|
/// Returns the Address of the underlying child account
|
|
542
562
|
///
|
|
543
|
-
|
|
563
|
+
access(all) view fun getAddress(): Address {
|
|
544
564
|
return self.childCap.address
|
|
545
565
|
}
|
|
546
566
|
|
|
@@ -560,24 +580,24 @@ pub contract HybridCustody {
|
|
|
560
580
|
|
|
561
581
|
/// Sets the CapabiltyFactory.Manager Capability
|
|
562
582
|
///
|
|
563
|
-
|
|
583
|
+
access(contract) fun setCapabilityFactory(cap: Capability<&CapabilityFactory.Manager>) {
|
|
564
584
|
self.factory = cap
|
|
565
585
|
}
|
|
566
586
|
|
|
567
587
|
/// Sets the Filter Capability as the one provided
|
|
568
588
|
///
|
|
569
|
-
|
|
589
|
+
access(contract) fun setCapabilityFilter(cap: Capability<&{CapabilityFilter.Filter}>) {
|
|
570
590
|
self.filter = cap
|
|
571
591
|
}
|
|
572
592
|
|
|
573
|
-
/// The main function to a child account's capabilities from a parent account. When a
|
|
574
|
-
/// the
|
|
575
|
-
/// ensure that borrowing is permitted.
|
|
593
|
+
/// The main function to a child account's capabilities from a parent account. When getting a capability, the CapabilityFilter will be borrowed and
|
|
594
|
+
/// the Capability being returned will be checked against it to
|
|
595
|
+
/// ensure that borrowing is permitted. If not allowed, nil is returned.
|
|
576
596
|
/// Also know that this method retrieves Capabilities via the CapabilityFactory path. To retrieve arbitrary
|
|
577
597
|
/// Capabilities, see `getPrivateCapFromDelegator()` and `getPublicCapFromDelegator()` which use the
|
|
578
598
|
/// `Delegator` retrieval path.
|
|
579
599
|
///
|
|
580
|
-
|
|
600
|
+
access(Child) view fun getCapability(controllerID: UInt64, type: Type): Capability? {
|
|
581
601
|
let child = self.childCap.borrow() ?? panic("failed to borrow child account")
|
|
582
602
|
|
|
583
603
|
let f = self.factory.borrow()!.getFactory(type)
|
|
@@ -585,12 +605,17 @@ pub contract HybridCustody {
|
|
|
585
605
|
return nil
|
|
586
606
|
}
|
|
587
607
|
|
|
588
|
-
let acct = child.
|
|
608
|
+
let acct = child._borrowAccount()
|
|
609
|
+
let tmp = f!.getCapability(acct: acct, controllerID: controllerID)
|
|
610
|
+
if tmp == nil {
|
|
611
|
+
return nil
|
|
612
|
+
}
|
|
589
613
|
|
|
590
|
-
let cap =
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
614
|
+
let cap = tmp!
|
|
615
|
+
// Check that private capabilities are allowed by either internal or manager filter (if assigned)
|
|
616
|
+
// If not allowed, return nil
|
|
617
|
+
if self.filter.borrow()!.allowed(cap: cap) == false || (self.getManagerCapabilityFilter()?.allowed(cap: cap) ?? true) == false {
|
|
618
|
+
return nil
|
|
594
619
|
}
|
|
595
620
|
|
|
596
621
|
return cap
|
|
@@ -599,7 +624,7 @@ pub contract HybridCustody {
|
|
|
599
624
|
/// Retrieves a private Capability from the Delegator or nil none is found of the given type. Useful for
|
|
600
625
|
/// arbitrary Capability retrieval
|
|
601
626
|
///
|
|
602
|
-
|
|
627
|
+
access(Child) view fun getPrivateCapFromDelegator(type: Type): Capability? {
|
|
603
628
|
if let d = self.delegator.borrow() {
|
|
604
629
|
return d.getPrivateCapability(type)
|
|
605
630
|
}
|
|
@@ -610,7 +635,7 @@ pub contract HybridCustody {
|
|
|
610
635
|
/// Retrieves a public Capability from the Delegator or nil none is found of the given type. Useful for
|
|
611
636
|
/// arbitrary Capability retrieval
|
|
612
637
|
///
|
|
613
|
-
|
|
638
|
+
access(all) view fun getPublicCapFromDelegator(type: Type): Capability? {
|
|
614
639
|
if let d = self.delegator.borrow() {
|
|
615
640
|
return d.getPublicCapability(type)
|
|
616
641
|
}
|
|
@@ -620,37 +645,43 @@ pub contract HybridCustody {
|
|
|
620
645
|
/// Enables retrieval of public Capabilities of the given type from the specified path or nil if none is found.
|
|
621
646
|
/// Callers should be aware this method uses the `CapabilityFactory` retrieval path.
|
|
622
647
|
///
|
|
623
|
-
|
|
624
|
-
|
|
648
|
+
access(all) view fun getPublicCapability(path: PublicPath, type: Type): Capability? {
|
|
649
|
+
let child = self.childCap.borrow() ?? panic("failed to borrow child account")
|
|
650
|
+
|
|
651
|
+
let f = self.factory.borrow()!.getFactory(type)
|
|
652
|
+
if f == nil {
|
|
653
|
+
return nil
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
let acct = child._borrowAccount()
|
|
657
|
+
return f!.getPublicCapability(acct: acct, path: path)
|
|
625
658
|
}
|
|
626
659
|
|
|
627
660
|
/// Returns a reference to the stored managerCapabilityFilter if one exists
|
|
628
661
|
///
|
|
629
|
-
|
|
662
|
+
access(all) view fun getManagerCapabilityFilter(): &{CapabilityFilter.Filter}? {
|
|
630
663
|
return self.managerCapabilityFilter != nil ? self.managerCapabilityFilter!.borrow() : nil
|
|
631
664
|
}
|
|
632
665
|
|
|
633
666
|
/// Sets the child account as redeemed by the given Address
|
|
634
667
|
///
|
|
635
668
|
access(contract) fun setRedeemed(_ addr: Address) {
|
|
636
|
-
let acct = self.childCap.borrow()!.
|
|
637
|
-
|
|
638
|
-
o.setRedeemed(addr)
|
|
639
|
-
}
|
|
669
|
+
let acct = self.childCap.borrow()!._borrowAccount()
|
|
670
|
+
acct.storage.borrow<&OwnedAccount>(from: HybridCustody.OwnedAccountStoragePath)?.setRedeemed(addr)
|
|
640
671
|
}
|
|
641
672
|
|
|
642
673
|
/// Returns a reference to the stored delegator, generally used for arbitrary Capability retrieval
|
|
643
674
|
///
|
|
644
|
-
|
|
675
|
+
access(Owner) fun borrowCapabilityDelegator(): auth(CapabilityDelegator.Get) &CapabilityDelegator.Delegator? {
|
|
645
676
|
let path = HybridCustody.getCapabilityDelegatorIdentifier(self.parent)
|
|
646
|
-
return self.childCap.borrow()!.
|
|
677
|
+
return self.childCap.borrow()!._borrowAccount().storage.borrow<auth(CapabilityDelegator.Get) &CapabilityDelegator.Delegator>(
|
|
647
678
|
from: StoragePath(identifier: path)!
|
|
648
679
|
)
|
|
649
680
|
}
|
|
650
681
|
|
|
651
682
|
/// Returns a list of supported metadata views
|
|
652
683
|
///
|
|
653
|
-
|
|
684
|
+
access(all) view fun getViews(): [Type] {
|
|
654
685
|
return [
|
|
655
686
|
Type<MetadataViews.Display>()
|
|
656
687
|
]
|
|
@@ -658,17 +689,22 @@ pub contract HybridCustody {
|
|
|
658
689
|
|
|
659
690
|
/// Resolves a view of the given type if supported
|
|
660
691
|
///
|
|
661
|
-
|
|
692
|
+
access(all) fun resolveView(_ view: Type): AnyStruct? {
|
|
662
693
|
switch view {
|
|
663
694
|
case Type<MetadataViews.Display>():
|
|
664
695
|
let childAddress = self.getAddress()
|
|
665
|
-
let
|
|
696
|
+
let tmp = getAccount(self.parent).capabilities.get<&{HybridCustody.ManagerPublic}>(HybridCustody.ManagerPublicPath)
|
|
697
|
+
if tmp == nil {
|
|
698
|
+
return nil
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
let manager = tmp!
|
|
666
702
|
|
|
667
703
|
if !manager.check() {
|
|
668
704
|
return nil
|
|
669
705
|
}
|
|
670
706
|
|
|
671
|
-
return manager
|
|
707
|
+
return manager.borrow()!.getChildAccountDisplay(address: childAddress)
|
|
672
708
|
}
|
|
673
709
|
return nil
|
|
674
710
|
}
|
|
@@ -681,22 +717,22 @@ pub contract HybridCustody {
|
|
|
681
717
|
return
|
|
682
718
|
}
|
|
683
719
|
|
|
684
|
-
let child: &
|
|
720
|
+
let child: &{HybridCustody.BorrowableAccount} = self.childCap.borrow()!
|
|
685
721
|
if !child.check() {
|
|
686
722
|
return
|
|
687
723
|
}
|
|
688
724
|
|
|
689
|
-
let acct = child.
|
|
690
|
-
if let ownedAcct = acct.borrow
|
|
725
|
+
let acct = child._borrowAccount()
|
|
726
|
+
if let ownedAcct = acct.storage.borrow<auth(Owner) &OwnedAccount>(from: HybridCustody.OwnedAccountStoragePath) {
|
|
691
727
|
ownedAcct.removeParent(parent: parent)
|
|
692
728
|
}
|
|
693
729
|
}
|
|
694
730
|
|
|
695
731
|
init(
|
|
696
|
-
_ childCap: Capability<&{BorrowableAccount, OwnedAccountPublic,
|
|
697
|
-
_ factory: Capability<&CapabilityFactory.Manager
|
|
732
|
+
_ childCap: Capability<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}>,
|
|
733
|
+
_ factory: Capability<&CapabilityFactory.Manager>,
|
|
698
734
|
_ filter: Capability<&{CapabilityFilter.Filter}>,
|
|
699
|
-
_ delegator: Capability
|
|
735
|
+
_ delegator: Capability<auth(CapabilityDelegator.Get) &CapabilityDelegator.Delegator>,
|
|
700
736
|
_ parent: Address
|
|
701
737
|
) {
|
|
702
738
|
pre {
|
|
@@ -716,8 +752,30 @@ pub contract HybridCustody {
|
|
|
716
752
|
self.resources <- {}
|
|
717
753
|
}
|
|
718
754
|
|
|
719
|
-
|
|
720
|
-
|
|
755
|
+
/// Returns a capability to this child account's CapabilityFilter
|
|
756
|
+
///
|
|
757
|
+
access(all) view fun getCapabilityFilter(): &{CapabilityFilter.Filter}? {
|
|
758
|
+
return self.filter.check() ? self.filter.borrow() : nil
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/// Returns a capability to this child account's CapabilityFactory
|
|
762
|
+
///
|
|
763
|
+
access(all) view fun getCapabilityFactoryManager(): &{CapabilityFactory.Getter}? {
|
|
764
|
+
return self.factory.check() ? self.factory.borrow() : nil
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
access(all) view fun getControllerIDForType(type: Type, forPath: StoragePath): UInt64? {
|
|
768
|
+
let child = self.childCap.borrow()
|
|
769
|
+
if child == nil {
|
|
770
|
+
return nil
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
return child!.getControllerIDForType(type: type, forPath: forPath)
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// When a ChildAccount is destroyed, attempt to remove it from the parent account as well
|
|
777
|
+
access(contract) fun burnCallback() {
|
|
778
|
+
self.parentRemoveChildCallback(parent: self.parent)
|
|
721
779
|
}
|
|
722
780
|
}
|
|
723
781
|
|
|
@@ -730,18 +788,19 @@ pub contract HybridCustody {
|
|
|
730
788
|
/// accounts would still exist, allowing a form of Hybrid Custody which has no true owner over an account, but
|
|
731
789
|
/// shared partial ownership.
|
|
732
790
|
///
|
|
733
|
-
|
|
791
|
+
access(all) resource OwnedAccount: OwnedAccountPrivate, BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver, Burner.Burnable {
|
|
792
|
+
access(all) event ResourceDestroyed(uuid: UInt64 = self.uuid, addr: Address = self.acct.address)
|
|
734
793
|
/// Capability on the underlying account object
|
|
735
|
-
access(self) var acct: Capability
|
|
794
|
+
access(self) var acct: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>
|
|
736
795
|
|
|
737
796
|
/// Mapping of current and pending parents, true and false respectively
|
|
738
|
-
|
|
797
|
+
access(all) let parents: {Address: Bool}
|
|
739
798
|
/// Address of the pending owner, if one exists
|
|
740
|
-
|
|
799
|
+
access(all) var pendingOwner: Address?
|
|
741
800
|
/// Address of the current owner, if one exists
|
|
742
|
-
|
|
801
|
+
access(all) var acctOwner: Address?
|
|
743
802
|
/// Owned status of this account
|
|
744
|
-
|
|
803
|
+
access(all) var currentlyOwned: Bool
|
|
745
804
|
|
|
746
805
|
/// A bucket of structs so that the OwnedAccount resource can be easily extended with new functionality.
|
|
747
806
|
access(self) let data: {String: AnyStruct}
|
|
@@ -792,12 +851,12 @@ pub contract HybridCustody {
|
|
|
792
851
|
/// 4. Publish the newly made private link to the designated parent's inbox for them to claim on their @Manager
|
|
793
852
|
/// resource.
|
|
794
853
|
///
|
|
795
|
-
|
|
854
|
+
access(Owner) fun publishToParent(
|
|
796
855
|
parentAddress: Address,
|
|
797
|
-
factory: Capability<&CapabilityFactory.Manager
|
|
856
|
+
factory: Capability<&CapabilityFactory.Manager>,
|
|
798
857
|
filter: Capability<&{CapabilityFilter.Filter}>
|
|
799
858
|
) {
|
|
800
|
-
pre{
|
|
859
|
+
pre {
|
|
801
860
|
self.parents[parentAddress] == nil: "Address pending or already redeemed as parent"
|
|
802
861
|
}
|
|
803
862
|
let capDelegatorIdentifier = HybridCustody.getCapabilityDelegatorIdentifier(parentAddress)
|
|
@@ -808,41 +867,30 @@ pub contract HybridCustody {
|
|
|
808
867
|
let capDelegatorStorage = StoragePath(identifier: capDelegatorIdentifier)!
|
|
809
868
|
let acct = self.borrowAccount()
|
|
810
869
|
|
|
811
|
-
assert(acct.borrow<&AnyResource>(from: capDelegatorStorage) == nil, message: "conflicting resource found in capability delegator storage slot for parentAddress")
|
|
812
|
-
assert(acct.borrow<&AnyResource>(from: childAccountStorage) == nil, message: "conflicting resource found in child account storage slot for parentAddress")
|
|
870
|
+
assert(acct.storage.borrow<&AnyResource>(from: capDelegatorStorage) == nil, message: "conflicting resource found in capability delegator storage slot for parentAddress")
|
|
871
|
+
assert(acct.storage.borrow<&AnyResource>(from: childAccountStorage) == nil, message: "conflicting resource found in child account storage slot for parentAddress")
|
|
813
872
|
|
|
814
|
-
if acct.borrow<&CapabilityDelegator.Delegator>(from: capDelegatorStorage) == nil {
|
|
873
|
+
if acct.storage.borrow<&CapabilityDelegator.Delegator>(from: capDelegatorStorage) == nil {
|
|
815
874
|
let delegator <- CapabilityDelegator.createDelegator()
|
|
816
|
-
acct.save(<-delegator, to: capDelegatorStorage)
|
|
875
|
+
acct.storage.save(<-delegator, to: capDelegatorStorage)
|
|
817
876
|
}
|
|
818
877
|
|
|
819
878
|
let capDelegatorPublic = PublicPath(identifier: capDelegatorIdentifier)!
|
|
820
|
-
let capDelegatorPrivate = PrivatePath(identifier: capDelegatorIdentifier)!
|
|
821
879
|
|
|
822
|
-
acct.
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
)
|
|
826
|
-
acct.link<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}>(
|
|
827
|
-
capDelegatorPrivate,
|
|
828
|
-
target: capDelegatorStorage
|
|
829
|
-
)
|
|
830
|
-
let delegator = acct.getCapability<&CapabilityDelegator.Delegator{CapabilityDelegator.GetterPublic, CapabilityDelegator.GetterPrivate}>(
|
|
831
|
-
capDelegatorPrivate
|
|
832
|
-
)
|
|
880
|
+
let pubCap = acct.capabilities.storage.issue<&{CapabilityDelegator.GetterPublic}>(capDelegatorStorage)
|
|
881
|
+
acct.capabilities.publish(pubCap, at: capDelegatorPublic)
|
|
882
|
+
|
|
883
|
+
let delegator = acct.capabilities.storage.issue<auth(CapabilityDelegator.Get) &CapabilityDelegator.Delegator>(capDelegatorStorage)
|
|
833
884
|
assert(delegator.check(), message: "failed to setup capability delegator for parent address")
|
|
834
885
|
|
|
835
|
-
let borrowableCap = self.borrowAccount().
|
|
836
|
-
HybridCustody.
|
|
886
|
+
let borrowableCap = self.borrowAccount().capabilities.storage.issue<&{BorrowableAccount, OwnedAccountPublic, ViewResolver.Resolver}>(
|
|
887
|
+
HybridCustody.OwnedAccountStoragePath
|
|
837
888
|
)
|
|
838
|
-
let childAcct <- create ChildAccount(borrowableCap, factory, filter, delegator, parentAddress)
|
|
839
889
|
|
|
840
|
-
let
|
|
890
|
+
let childAcct <- create ChildAccount(borrowableCap, factory, filter, delegator, parentAddress)
|
|
841
891
|
|
|
842
|
-
acct.save(<-childAcct, to: childAccountStorage)
|
|
843
|
-
acct.
|
|
844
|
-
|
|
845
|
-
let delegatorCap = acct.getCapability<&ChildAccount{AccountPrivate, AccountPublic, MetadataViews.Resolver}>(childAccountPrivatePath)
|
|
892
|
+
acct.storage.save(<-childAcct, to: childAccountStorage)
|
|
893
|
+
let delegatorCap = acct.capabilities.storage.issue<auth(Child) &{AccountPrivate, AccountPublic, ViewResolver.Resolver}>(childAccountStorage)
|
|
846
894
|
assert(delegatorCap.check(), message: "Delegator capability check failed")
|
|
847
895
|
|
|
848
896
|
acct.inbox.publish(delegatorCap, name: identifier, recipient: parentAddress)
|
|
@@ -862,38 +910,43 @@ pub contract HybridCustody {
|
|
|
862
910
|
|
|
863
911
|
/// Checks the validity of the encapsulated account Capability
|
|
864
912
|
///
|
|
865
|
-
|
|
913
|
+
access(all) view fun check(): Bool {
|
|
866
914
|
return self.acct.check()
|
|
867
915
|
}
|
|
868
916
|
|
|
869
917
|
/// Returns a reference to the encapsulated account object
|
|
870
918
|
///
|
|
871
|
-
|
|
872
|
-
return self.acct.borrow()
|
|
919
|
+
access(Owner) view fun borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account {
|
|
920
|
+
return self.acct.borrow() ?? panic("unable to borrow Account Capability")
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// Used internally so that child account resources are able to borrow their underlying Account reference
|
|
924
|
+
access(contract) view fun _borrowAccount(): auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account {
|
|
925
|
+
return self.borrowAccount()
|
|
873
926
|
}
|
|
874
927
|
|
|
875
928
|
/// Returns the addresses of all associated parents pending and active
|
|
876
929
|
///
|
|
877
|
-
|
|
930
|
+
access(all) view fun getParentAddresses(): [Address] {
|
|
878
931
|
return self.parents.keys
|
|
879
932
|
}
|
|
880
933
|
|
|
881
934
|
/// Returns whether the given address is a parent of this account
|
|
882
935
|
///
|
|
883
|
-
|
|
936
|
+
access(all) view fun isChildOf(_ addr: Address): Bool {
|
|
884
937
|
return self.parents[addr] != nil
|
|
885
938
|
}
|
|
886
939
|
|
|
887
940
|
/// Returns nil if the given address is not a parent, false if the parent has not redeemed the child account
|
|
888
941
|
/// yet, and true if they have
|
|
889
942
|
///
|
|
890
|
-
|
|
943
|
+
access(all) view fun getRedeemedStatus(addr: Address): Bool? {
|
|
891
944
|
return self.parents[addr]
|
|
892
945
|
}
|
|
893
946
|
|
|
894
947
|
/// Returns associated parent addresses and their redeemed status
|
|
895
948
|
///
|
|
896
|
-
|
|
949
|
+
access(all) view fun getParentStatuses(): {Address: Bool} {
|
|
897
950
|
return self.parents
|
|
898
951
|
}
|
|
899
952
|
|
|
@@ -901,29 +954,37 @@ pub contract HybridCustody {
|
|
|
901
954
|
/// configured for the provided parent address. Once done, the parent will not have any valid capabilities with
|
|
902
955
|
/// which to access the child account.
|
|
903
956
|
///
|
|
904
|
-
|
|
957
|
+
access(Owner) fun removeParent(parent: Address): Bool {
|
|
905
958
|
if self.parents[parent] == nil {
|
|
906
959
|
return false
|
|
907
960
|
}
|
|
961
|
+
|
|
908
962
|
let identifier = HybridCustody.getChildAccountIdentifier(parent)
|
|
909
963
|
let capDelegatorIdentifier = HybridCustody.getCapabilityDelegatorIdentifier(parent)
|
|
910
964
|
|
|
911
965
|
let acct = self.borrowAccount()
|
|
912
|
-
acct.unlink(PrivatePath(identifier: identifier)!)
|
|
913
|
-
acct.unlink(PublicPath(identifier: identifier)!)
|
|
914
966
|
|
|
915
|
-
|
|
916
|
-
|
|
967
|
+
// get all controllers which target this storage path
|
|
968
|
+
let storagePath = StoragePath(identifier: identifier)!
|
|
969
|
+
let childAccountControllers = acct.capabilities.storage.getControllers(forPath: storagePath)
|
|
970
|
+
for c in childAccountControllers {
|
|
971
|
+
c.delete()
|
|
972
|
+
}
|
|
973
|
+
Burner.burn(<- acct.storage.load<@AnyResource>(from: storagePath))
|
|
917
974
|
|
|
918
|
-
|
|
919
|
-
|
|
975
|
+
let delegatorStoragePath = StoragePath(identifier: capDelegatorIdentifier)!
|
|
976
|
+
let delegatorControllers = acct.capabilities.storage.getControllers(forPath: delegatorStoragePath)
|
|
977
|
+
for c in delegatorControllers {
|
|
978
|
+
c.delete()
|
|
979
|
+
}
|
|
980
|
+
Burner.burn(<- acct.storage.load<@AnyResource>(from: delegatorStoragePath))
|
|
920
981
|
|
|
921
982
|
self.parents.remove(key: parent)
|
|
922
983
|
emit AccountUpdated(id: self.uuid, child: self.acct.address, parent: parent, active: false)
|
|
923
984
|
|
|
924
|
-
let parentManager = getAccount(parent).
|
|
985
|
+
let parentManager = getAccount(parent).capabilities.get<&{ManagerPublic}>(HybridCustody.ManagerPublicPath)
|
|
925
986
|
if parentManager.check() {
|
|
926
|
-
parentManager.borrow()?.removeParentCallback(child:
|
|
987
|
+
parentManager.borrow()?.removeParentCallback(child: acct.address)
|
|
927
988
|
}
|
|
928
989
|
|
|
929
990
|
return true
|
|
@@ -931,21 +992,21 @@ pub contract HybridCustody {
|
|
|
931
992
|
|
|
932
993
|
/// Returns the address of the encapsulated account
|
|
933
994
|
///
|
|
934
|
-
|
|
995
|
+
access(all) view fun getAddress(): Address {
|
|
935
996
|
return self.acct.address
|
|
936
997
|
}
|
|
937
998
|
|
|
938
999
|
/// Returns the address of the pending owner if one is assigned. Pending owners are assigned when ownership has
|
|
939
1000
|
/// been granted, but has not yet been redeemed.
|
|
940
1001
|
///
|
|
941
|
-
|
|
1002
|
+
access(all) view fun getPendingOwner(): Address? {
|
|
942
1003
|
return self.pendingOwner
|
|
943
1004
|
}
|
|
944
1005
|
|
|
945
1006
|
/// Returns the address of the current owner if one is assigned. Current owners are assigned when ownership has
|
|
946
1007
|
/// been redeemed.
|
|
947
1008
|
///
|
|
948
|
-
|
|
1009
|
+
access(all) view fun getOwner(): Address? {
|
|
949
1010
|
if !self.currentlyOwned {
|
|
950
1011
|
return nil
|
|
951
1012
|
}
|
|
@@ -961,22 +1022,17 @@ pub contract HybridCustody {
|
|
|
961
1022
|
/// mechanism intended to easily transfer 'root' access on this account to another account and an attempt to
|
|
962
1023
|
/// minimize access vectors.
|
|
963
1024
|
///
|
|
964
|
-
|
|
1025
|
+
access(Owner) fun giveOwnership(to: Address) {
|
|
965
1026
|
self.seal()
|
|
966
1027
|
|
|
967
1028
|
let acct = self.borrowAccount()
|
|
968
|
-
|
|
969
|
-
if self.acctOwner != nil {
|
|
970
|
-
acct.unlink(
|
|
971
|
-
PrivatePath(identifier: HybridCustody.getOwnerIdentifier(self.acctOwner!))!
|
|
972
|
-
)
|
|
973
|
-
}
|
|
1029
|
+
|
|
974
1030
|
// Link a Capability for the new owner, retrieve & publish
|
|
975
1031
|
let identifier = HybridCustody.getOwnerIdentifier(to)
|
|
976
|
-
let cap = acct.
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1032
|
+
let cap = acct.capabilities.storage.issue<auth(Owner) &{OwnedAccountPrivate, OwnedAccountPublic, ViewResolver.Resolver}>(HybridCustody.OwnedAccountStoragePath)
|
|
1033
|
+
|
|
1034
|
+
// make sure we can borrow the newly issued owned account
|
|
1035
|
+
cap.borrow()?.borrowAccount() ?? panic("can not borrow the Hybrid Custody Owned Account")
|
|
980
1036
|
|
|
981
1037
|
acct.inbox.publish(cap, name: identifier, recipient: to)
|
|
982
1038
|
|
|
@@ -988,7 +1044,7 @@ pub contract HybridCustody {
|
|
|
988
1044
|
|
|
989
1045
|
/// Revokes all keys on the underlying account
|
|
990
1046
|
///
|
|
991
|
-
|
|
1047
|
+
access(Owner) fun revokeAllKeys() {
|
|
992
1048
|
let acct = self.borrowAccount()
|
|
993
1049
|
|
|
994
1050
|
// Revoke all keys
|
|
@@ -1007,33 +1063,25 @@ pub contract HybridCustody {
|
|
|
1007
1063
|
/// assumes ownership of an account to guarantee that the previous owner doesn't maintain admin access to the
|
|
1008
1064
|
/// account via other AuthAccount Capabilities.
|
|
1009
1065
|
///
|
|
1010
|
-
|
|
1066
|
+
access(Owner) fun rotateAuthAccount() {
|
|
1011
1067
|
let acct = self.borrowAccount()
|
|
1012
1068
|
|
|
1013
1069
|
// Find all active AuthAccount capabilities so they can be removed after we make the new auth account cap
|
|
1014
|
-
let
|
|
1015
|
-
acct.forEachPrivate(fun (path: PrivatePath, type: Type): Bool {
|
|
1016
|
-
if type.identifier == "Capability<&AuthAccount>" {
|
|
1017
|
-
pathsToUnlink.append(path)
|
|
1018
|
-
}
|
|
1019
|
-
return true
|
|
1020
|
-
})
|
|
1070
|
+
let controllersToDestroy = acct.capabilities.account.getControllers()
|
|
1021
1071
|
|
|
1022
1072
|
// Link a new AuthAccount Capability
|
|
1023
|
-
|
|
1024
|
-
// capability to this path before it is made, thus maintaining ownership despite making it look like they
|
|
1025
|
-
// gave it away. Until capability controllers, this method should not be fully trusted.
|
|
1026
|
-
let authAcctPath = "HybridCustodyRelinquished".concat(HybridCustody.account.address.toString()).concat(getCurrentBlock().height.toString())
|
|
1027
|
-
let acctCap = acct.linkAccount(PrivatePath(identifier: authAcctPath)!)!
|
|
1073
|
+
let acctCap = acct.capabilities.account.issue<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>()
|
|
1028
1074
|
|
|
1029
1075
|
self.acct = acctCap
|
|
1030
1076
|
let newAcct = self.acct.borrow()!
|
|
1031
1077
|
|
|
1032
1078
|
// cleanup, remove all previously found paths. We had to do it in this order because we will be unlinking
|
|
1033
1079
|
// the existing path which will cause a deference issue with the originally borrowed auth account
|
|
1034
|
-
for
|
|
1035
|
-
newAcct.
|
|
1080
|
+
for con in controllersToDestroy {
|
|
1081
|
+
newAcct.capabilities.account.getController(byCapabilityID: con.capabilityID)?.delete()
|
|
1036
1082
|
}
|
|
1083
|
+
|
|
1084
|
+
assert(self.acct.check(), message: "new auth account capability is not valid")
|
|
1037
1085
|
}
|
|
1038
1086
|
|
|
1039
1087
|
/// Revokes all keys on an account, unlinks all currently active AuthAccount capabilities, then makes a new one
|
|
@@ -1043,7 +1091,7 @@ pub contract HybridCustody {
|
|
|
1043
1091
|
///
|
|
1044
1092
|
/// USE WITH EXTREME CAUTION.
|
|
1045
1093
|
///
|
|
1046
|
-
|
|
1094
|
+
access(Owner) fun seal() {
|
|
1047
1095
|
self.rotateAuthAccount()
|
|
1048
1096
|
self.revokeAllKeys() // There needs to be a path to giving ownership that doesn't revoke keys
|
|
1049
1097
|
emit AccountSealed(id: self.uuid, address: self.acct.address, parents: self.parents.keys)
|
|
@@ -1052,16 +1100,16 @@ pub contract HybridCustody {
|
|
|
1052
1100
|
|
|
1053
1101
|
/// Retrieves a reference to the ChildAccount associated with the given parent account if one exists.
|
|
1054
1102
|
///
|
|
1055
|
-
|
|
1103
|
+
access(Owner) fun borrowChildAccount(parent: Address): auth(Child) &ChildAccount? {
|
|
1056
1104
|
let identifier = HybridCustody.getChildAccountIdentifier(parent)
|
|
1057
|
-
return self.borrowAccount().borrow
|
|
1105
|
+
return self.borrowAccount().storage.borrow<auth(Child) &ChildAccount>(from: StoragePath(identifier: identifier)!)
|
|
1058
1106
|
}
|
|
1059
1107
|
|
|
1060
1108
|
/// Sets the CapabilityFactory Manager for the specified parent in the associated ChildAccount.
|
|
1061
1109
|
///
|
|
1062
|
-
|
|
1110
|
+
access(Owner) fun setCapabilityFactoryForParent(
|
|
1063
1111
|
parent: Address,
|
|
1064
|
-
cap: Capability<&CapabilityFactory.Manager
|
|
1112
|
+
cap: Capability<&CapabilityFactory.Manager>
|
|
1065
1113
|
) {
|
|
1066
1114
|
let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address")
|
|
1067
1115
|
p.setCapabilityFactory(cap: cap)
|
|
@@ -1069,21 +1117,21 @@ pub contract HybridCustody {
|
|
|
1069
1117
|
|
|
1070
1118
|
/// Sets the Filter for the specified parent in the associated ChildAccount.
|
|
1071
1119
|
///
|
|
1072
|
-
|
|
1120
|
+
access(Owner) fun setCapabilityFilterForParent(parent: Address, cap: Capability<&{CapabilityFilter.Filter}>) {
|
|
1073
1121
|
let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address")
|
|
1074
1122
|
p.setCapabilityFilter(cap: cap)
|
|
1075
1123
|
}
|
|
1076
1124
|
|
|
1077
1125
|
/// Retrieves a reference to the Delegator associated with the given parent account if one exists.
|
|
1078
1126
|
///
|
|
1079
|
-
|
|
1127
|
+
access(Owner) fun borrowCapabilityDelegatorForParent(parent: Address): auth(CapabilityDelegator.Get, CapabilityDelegator.Add, CapabilityDelegator.Delete) &CapabilityDelegator.Delegator? {
|
|
1080
1128
|
let identifier = HybridCustody.getCapabilityDelegatorIdentifier(parent)
|
|
1081
|
-
return self.borrowAccount().borrow
|
|
1129
|
+
return self.borrowAccount().storage.borrow<auth(CapabilityDelegator.Get, CapabilityDelegator.Add, CapabilityDelegator.Delete) &CapabilityDelegator.Delegator>(from: StoragePath(identifier: identifier)!)
|
|
1082
1130
|
}
|
|
1083
1131
|
|
|
1084
1132
|
/// Adds the provided Capability to the Delegator associated with the given parent account.
|
|
1085
1133
|
///
|
|
1086
|
-
|
|
1134
|
+
access(Owner) fun addCapabilityToDelegator(parent: Address, cap: Capability, isPublic: Bool) {
|
|
1087
1135
|
let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address")
|
|
1088
1136
|
let delegator = self.borrowCapabilityDelegatorForParent(parent: parent)
|
|
1089
1137
|
?? panic("could not borrow capability delegator resource for parent address")
|
|
@@ -1092,20 +1140,20 @@ pub contract HybridCustody {
|
|
|
1092
1140
|
|
|
1093
1141
|
/// Removes the provided Capability from the Delegator associated with the given parent account.
|
|
1094
1142
|
///
|
|
1095
|
-
|
|
1143
|
+
access(Owner) fun removeCapabilityFromDelegator(parent: Address, cap: Capability) {
|
|
1096
1144
|
let p = self.borrowChildAccount(parent: parent) ?? panic("could not find parent address")
|
|
1097
1145
|
let delegator = self.borrowCapabilityDelegatorForParent(parent: parent)
|
|
1098
1146
|
?? panic("could not borrow capability delegator resource for parent address")
|
|
1099
1147
|
delegator.removeCapability(cap: cap)
|
|
1100
1148
|
}
|
|
1101
1149
|
|
|
1102
|
-
|
|
1150
|
+
access(all) view fun getViews(): [Type] {
|
|
1103
1151
|
return [
|
|
1104
1152
|
Type<MetadataViews.Display>()
|
|
1105
1153
|
]
|
|
1106
1154
|
}
|
|
1107
1155
|
|
|
1108
|
-
|
|
1156
|
+
access(all) fun resolveView(_ view: Type): AnyStruct? {
|
|
1109
1157
|
switch view {
|
|
1110
1158
|
case Type<MetadataViews.Display>():
|
|
1111
1159
|
return self.display
|
|
@@ -1115,12 +1163,27 @@ pub contract HybridCustody {
|
|
|
1115
1163
|
|
|
1116
1164
|
/// Sets this OwnedAccount's display to the one provided
|
|
1117
1165
|
///
|
|
1118
|
-
|
|
1166
|
+
access(Owner) fun setDisplay(_ d: MetadataViews.Display) {
|
|
1119
1167
|
self.display = d
|
|
1120
1168
|
}
|
|
1121
1169
|
|
|
1170
|
+
access(all) view fun getControllerIDForType(type: Type, forPath: StoragePath): UInt64? {
|
|
1171
|
+
let acct = self.acct.borrow()
|
|
1172
|
+
if acct == nil {
|
|
1173
|
+
return nil
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
for c in acct!.capabilities.storage.getControllers(forPath: forPath) {
|
|
1177
|
+
if c.borrowType.isSubtype(of: type) {
|
|
1178
|
+
return c.capabilityID
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
return nil
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1122
1185
|
init(
|
|
1123
|
-
_ acct: Capability
|
|
1186
|
+
_ acct: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>
|
|
1124
1187
|
) {
|
|
1125
1188
|
self.acct = acct
|
|
1126
1189
|
|
|
@@ -1134,36 +1197,39 @@ pub contract HybridCustody {
|
|
|
1134
1197
|
self.display = nil
|
|
1135
1198
|
}
|
|
1136
1199
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1200
|
+
// When an OwnedAccount is destroyed, remove it from every configured parent account
|
|
1201
|
+
access(contract) fun burnCallback() {
|
|
1202
|
+
for p in self.parents.keys {
|
|
1203
|
+
self.removeParent(parent: p)
|
|
1204
|
+
}
|
|
1139
1205
|
}
|
|
1140
1206
|
}
|
|
1141
1207
|
|
|
1142
1208
|
/// Utility function to get the path identifier for a parent address when interacting with a ChildAccount and its
|
|
1143
1209
|
/// parents
|
|
1144
1210
|
///
|
|
1145
|
-
|
|
1211
|
+
access(all) view fun getChildAccountIdentifier(_ addr: Address): String {
|
|
1146
1212
|
return "ChildAccount_".concat(addr.toString())
|
|
1147
1213
|
}
|
|
1148
1214
|
|
|
1149
1215
|
/// Utility function to get the path identifier for a parent address when interacting with a Delegator and its
|
|
1150
1216
|
/// parents
|
|
1151
1217
|
///
|
|
1152
|
-
|
|
1218
|
+
access(all) view fun getCapabilityDelegatorIdentifier(_ addr: Address): String {
|
|
1153
1219
|
return "ChildCapabilityDelegator_".concat(addr.toString())
|
|
1154
1220
|
}
|
|
1155
1221
|
|
|
1156
1222
|
/// Utility function to get the path identifier for a parent address when interacting with an OwnedAccount and its
|
|
1157
1223
|
/// owners
|
|
1158
1224
|
///
|
|
1159
|
-
|
|
1225
|
+
access(all) view fun getOwnerIdentifier(_ addr: Address): String {
|
|
1160
1226
|
return "HybridCustodyOwnedAccount_".concat(HybridCustody.account.address.toString()).concat(addr.toString())
|
|
1161
1227
|
}
|
|
1162
1228
|
|
|
1163
1229
|
/// Returns an OwnedAccount wrapping the provided AuthAccount Capability.
|
|
1164
1230
|
///
|
|
1165
|
-
|
|
1166
|
-
acct: Capability
|
|
1231
|
+
access(all) fun createOwnedAccount(
|
|
1232
|
+
acct: Capability<auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account>
|
|
1167
1233
|
): @OwnedAccount {
|
|
1168
1234
|
pre {
|
|
1169
1235
|
acct.check(): "invalid auth account capability"
|
|
@@ -1176,7 +1242,7 @@ pub contract HybridCustody {
|
|
|
1176
1242
|
|
|
1177
1243
|
/// Returns a new Manager with the provided Filter as default (if not nil).
|
|
1178
1244
|
///
|
|
1179
|
-
|
|
1245
|
+
access(all) fun createManager(filter: Capability<&{CapabilityFilter.Filter}>?): @Manager {
|
|
1180
1246
|
pre {
|
|
1181
1247
|
filter == nil || filter!.check(): "Invalid CapabilityFilter Filter capability provided"
|
|
1182
1248
|
}
|
|
@@ -1188,15 +1254,10 @@ pub contract HybridCustody {
|
|
|
1188
1254
|
init() {
|
|
1189
1255
|
let identifier = "HybridCustodyChild_".concat(self.account.address.toString())
|
|
1190
1256
|
self.OwnedAccountStoragePath = StoragePath(identifier: identifier)!
|
|
1191
|
-
self.OwnedAccountPrivatePath = PrivatePath(identifier: identifier)!
|
|
1192
1257
|
self.OwnedAccountPublicPath = PublicPath(identifier: identifier)!
|
|
1193
1258
|
|
|
1194
|
-
self.LinkedAccountPrivatePath = PrivatePath(identifier: "LinkedAccountPrivatePath_".concat(identifier))!
|
|
1195
|
-
self.BorrowableAccountPrivatePath = PrivatePath(identifier: "BorrowableAccountPrivatePath_".concat(identifier))!
|
|
1196
|
-
|
|
1197
1259
|
let managerIdentifier = "HybridCustodyManager_".concat(self.account.address.toString())
|
|
1198
1260
|
self.ManagerStoragePath = StoragePath(identifier: managerIdentifier)!
|
|
1199
1261
|
self.ManagerPublicPath = PublicPath(identifier: managerIdentifier)!
|
|
1200
|
-
self.ManagerPrivatePath = PrivatePath(identifier: managerIdentifier)!
|
|
1201
1262
|
}
|
|
1202
|
-
}
|
|
1263
|
+
}
|