@flowtyio/flow-contracts 0.1.0-beta.3 → 0.1.0-beta.30

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.
Files changed (67) hide show
  1. package/README.md +1 -1
  2. package/contracts/Burner.cdc +44 -0
  3. package/contracts/FlowStorageFees.cdc +15 -15
  4. package/contracts/FlowToken.cdc +29 -78
  5. package/contracts/FungibleToken.cdc +80 -53
  6. package/contracts/FungibleTokenMetadataViews.cdc +13 -25
  7. package/contracts/FungibleTokenSwitchboard.cdc +360 -0
  8. package/contracts/MetadataViews.cdc +107 -50
  9. package/contracts/NonFungibleToken.cdc +110 -60
  10. package/contracts/TokenForwarding.cdc +19 -11
  11. package/contracts/ViewResolver.cdc +20 -16
  12. package/contracts/capability-cache/CapabilityCache.cdc +97 -0
  13. package/contracts/dapper/DapperUtilityCoin.cdc +106 -39
  14. package/contracts/dapper/FlowUtilityToken.cdc +107 -40
  15. package/contracts/dapper/TopShot.cdc +323 -259
  16. package/contracts/dapper/TopShotLocking.cdc +41 -15
  17. package/contracts/dapper/offers/DapperOffersV2.cdc +46 -43
  18. package/contracts/dapper/offers/OffersV2.cdc +40 -56
  19. package/contracts/dapper/offers/Resolver.cdc +20 -13
  20. package/contracts/emerald-city/FLOAT.cdc +259 -254
  21. package/contracts/example/ExampleNFT.cdc +18 -21
  22. package/contracts/example/ExampleToken.cdc +68 -1
  23. package/contracts/find/FindViews.cdc +357 -353
  24. package/contracts/flow-utils/AddressUtils.cdc +20 -23
  25. package/contracts/flow-utils/ArrayUtils.cdc +10 -11
  26. package/contracts/flow-utils/ScopedFTProviders.cdc +27 -19
  27. package/contracts/flow-utils/ScopedNFTProviders.cdc +31 -26
  28. package/contracts/flow-utils/StringUtils.cdc +24 -37
  29. package/contracts/flowty-drops/ContractManager.cdc +47 -0
  30. package/contracts/flowty-drops/DropFactory.cdc +75 -0
  31. package/contracts/flowty-drops/DropTypes.cdc +278 -0
  32. package/contracts/flowty-drops/FlowtyAddressVerifiers.cdc +64 -0
  33. package/contracts/flowty-drops/FlowtyDrops.cdc +431 -0
  34. package/contracts/flowty-drops/FlowtyPricers.cdc +48 -0
  35. package/contracts/flowty-drops/FlowtySwitchers.cdc +113 -0
  36. package/contracts/flowty-drops/initializers/ContractBorrower.cdc +14 -0
  37. package/contracts/flowty-drops/initializers/ContractInitializer.cdc +7 -0
  38. package/contracts/flowty-drops/initializers/OpenEditionInitializer.cdc +58 -0
  39. package/contracts/flowty-drops/nft/BaseCollection.cdc +97 -0
  40. package/contracts/flowty-drops/nft/BaseNFT.cdc +107 -0
  41. package/contracts/flowty-drops/nft/ContractFactory.cdc +13 -0
  42. package/contracts/flowty-drops/nft/ContractFactoryTemplate.cdc +48 -0
  43. package/contracts/flowty-drops/nft/NFTMetadata.cdc +119 -0
  44. package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +41 -0
  45. package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +52 -0
  46. package/contracts/flowty-drops/nft/UniversalCollection.cdc +23 -0
  47. package/contracts/fungible-token-router/FungibleTokenRouter.cdc +105 -0
  48. package/contracts/hybrid-custody/CapabilityDelegator.cdc +28 -26
  49. package/contracts/hybrid-custody/CapabilityFactory.cdc +20 -18
  50. package/contracts/hybrid-custody/CapabilityFilter.cdc +41 -24
  51. package/contracts/hybrid-custody/HybridCustody.cdc +303 -242
  52. package/contracts/hybrid-custody/factories/FTAllFactory.cdc +16 -4
  53. package/contracts/hybrid-custody/factories/FTBalanceFactory.cdc +16 -4
  54. package/contracts/hybrid-custody/factories/FTProviderFactory.cdc +17 -5
  55. package/contracts/hybrid-custody/factories/FTReceiverBalanceFactory.cdc +16 -4
  56. package/contracts/hybrid-custody/factories/FTReceiverFactory.cdc +16 -4
  57. package/contracts/hybrid-custody/factories/FTVaultFactory.cdc +46 -0
  58. package/contracts/hybrid-custody/factories/NFTCollectionFactory.cdc +45 -0
  59. package/contracts/hybrid-custody/factories/NFTCollectionPublicFactory.cdc +16 -4
  60. package/contracts/hybrid-custody/factories/NFTProviderAndCollectionFactory.cdc +22 -0
  61. package/contracts/hybrid-custody/factories/NFTProviderFactory.cdc +16 -4
  62. package/contracts/lost-and-found/LostAndFound.cdc +29 -25
  63. package/contracts/nft-catalog/NFTCatalog.cdc +60 -64
  64. package/contracts/nft-catalog/NFTCatalogAdmin.cdc +28 -27
  65. package/flow.json +189 -5
  66. package/package.json +1 -1
  67. package/contracts/hybrid-custody/factories/NFTProviderAndCollectionPublicFactory.cdc +0 -10
@@ -16,29 +16,37 @@ their tokens to.
16
16
 
17
17
  import "FungibleToken"
18
18
 
19
- pub contract TokenForwarding {
19
+ access(all) contract TokenForwarding {
20
20
 
21
21
  // Event that is emitted when tokens are deposited to the target receiver
22
- pub event ForwardedDeposit(amount: UFix64, from: Address?)
22
+ access(all) event ForwardedDeposit(amount: UFix64, from: Address?)
23
23
 
24
- pub resource interface ForwarderPublic {
25
- pub fun check(): Bool
26
- pub fun safeBorrow(): &{FungibleToken.Receiver}?
24
+ access(all) resource interface ForwarderPublic {
25
+ access(all) fun check(): Bool
26
+ access(all) fun safeBorrow(): &{FungibleToken.Receiver}?
27
27
  }
28
28
 
29
- pub resource Forwarder: FungibleToken.Receiver, ForwarderPublic {
29
+ access(all) resource Forwarder: FungibleToken.Receiver, ForwarderPublic {
30
30
 
31
31
  // This is where the deposited tokens will be sent.
32
32
  // The type indicates that it is a reference to a receiver
33
33
  //
34
34
  access(self) var recipient: Capability
35
35
 
36
+ access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
37
+ return {}
38
+ }
39
+
40
+ access(all) view fun isSupportedVaultType(type: Type): Bool {
41
+ return true
42
+ }
43
+
36
44
  // deposit
37
45
  //
38
46
  // Function that takes a Vault object as an argument and forwards
39
47
  // it to the recipient's Vault using the stored reference
40
48
  //
41
- pub fun deposit(from: @FungibleToken.Vault) {
49
+ access(all) fun deposit(from: @{FungibleToken.Vault}) {
42
50
  let receiverRef = self.recipient.borrow<&{FungibleToken.Receiver}>()!
43
51
 
44
52
  let balance = from.balance
@@ -48,17 +56,17 @@ pub contract TokenForwarding {
48
56
  emit ForwardedDeposit(amount: balance, from: self.owner?.address)
49
57
  }
50
58
 
51
- pub fun check(): Bool {
59
+ access(all) fun check(): Bool {
52
60
  return self.recipient.check<&{FungibleToken.Receiver}>()
53
61
  }
54
62
 
55
- pub fun safeBorrow(): &{FungibleToken.Receiver}? {
63
+ access(all) fun safeBorrow(): &{FungibleToken.Receiver}? {
56
64
  return self.recipient.borrow<&{FungibleToken.Receiver}>()
57
65
  }
58
66
 
59
67
  // changeRecipient changes the recipient of the forwarder to the provided recipient
60
68
  //
61
- pub fun changeRecipient(_ newRecipient: Capability) {
69
+ access(all) fun changeRecipient(_ newRecipient: Capability) {
62
70
  pre {
63
71
  newRecipient.borrow<&{FungibleToken.Receiver}>() != nil: "Could not borrow Receiver reference from the Capability"
64
72
  }
@@ -75,7 +83,7 @@ pub contract TokenForwarding {
75
83
 
76
84
  // createNewForwarder creates a new Forwarder reference with the provided recipient
77
85
  //
78
- pub fun createNewForwarder(recipient: Capability): @Forwarder {
86
+ access(all) fun createNewForwarder(recipient: Capability): @Forwarder {
79
87
  return <-create Forwarder(recipient: recipient)
80
88
  }
81
89
  }
@@ -1,43 +1,47 @@
1
- // Taken from the NFT Metadata standard, this contract exposes an interface to let
1
+ // Taken from the NFT Metadata standard, this contract exposes an interface to let
2
2
  // anyone borrow a contract and resolve views on it.
3
3
  //
4
4
  // This will allow you to obtain information about a contract without necessarily knowing anything about it.
5
5
  // All you need is its address and name and you're good to go!
6
6
  access(all) contract interface ViewResolver {
7
7
 
8
- /// Function that returns all the Metadata Views implemented by the resolving contract
8
+ /// Function that returns all the Metadata Views implemented by the resolving contract.
9
+ /// Some contracts may have multiple resource types that support metadata views
10
+ /// so there there is an optional parameter for specify which resource type the caller
11
+ /// is looking for views for.
12
+ /// Some contract-level views may be type-agnostic. In that case, the contract
13
+ /// should return the same views regardless of what type is passed in.
9
14
  ///
15
+ /// @param resourceType: An optional resource type to return views for
10
16
  /// @return An array of Types defining the implemented views. This value will be used by
11
17
  /// developers to know which parameter to pass to the resolveView() method.
12
18
  ///
13
- access(all) view fun getViews(): [Type] {
14
- return []
15
- }
19
+ access(all) view fun getContractViews(resourceType: Type?): [Type]
16
20
 
17
21
  /// Function that resolves a metadata view for this token.
22
+ /// Some contracts may have multiple resource types that support metadata views
23
+ /// so there there is an optional parameter for specify which resource type the caller
24
+ /// is looking for views for.
25
+ /// Some contract-level views may be type-agnostic. In that case, the contract
26
+ /// should return the same views regardless of what type is passed in.
18
27
  ///
28
+ /// @param resourceType: An optional resource type to return views for
19
29
  /// @param view: The Type of the desired view.
20
30
  /// @return A structure representing the requested view.
21
31
  ///
22
- access(all) fun resolveView(_ view: Type): AnyStruct? {
23
- return nil
24
- }
32
+ access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct?
25
33
 
26
- /// Provides access to a set of metadata views. A struct or
27
- /// resource (e.g. an NFT) can implement this interface to provide access to
34
+ /// Provides access to a set of metadata views. A struct or
35
+ /// resource (e.g. an NFT) can implement this interface to provide access to
28
36
  /// the views that it supports.
29
37
  ///
30
38
  access(all) resource interface Resolver {
31
39
 
32
40
  /// Same as getViews above, but on a specific NFT instead of a contract
33
- access(all) view fun getViews(): [Type] {
34
- return []
35
- }
41
+ access(all) view fun getViews(): [Type]
36
42
 
37
43
  /// Same as resolveView above, but on a specific NFT instead of a contract
38
- access(all) fun resolveView(_ view: Type): AnyStruct? {
39
- return nil
40
- }
44
+ access(all) fun resolveView(_ view: Type): AnyStruct?
41
45
  }
42
46
 
43
47
  /// A group of view resolvers indexed by ID.
@@ -0,0 +1,97 @@
1
+ /*
2
+ https://github.com/Flowtyio/capability-cache
3
+
4
+ CapabilityCache helps manage capabilities which are issued but are not in public paths.
5
+ Rather than looping through all capabilities under a storage path and finding one that
6
+ matches the Capability type you want, the cache can be used to retrieve them
7
+ */
8
+ access(all) contract CapabilityCache {
9
+
10
+ access(all) let basePathIdentifier: String
11
+
12
+ access(all) event CapabilityAdded(owner: Address?, cacheUuid: UInt64, namespace: String, resourceType: Type, capabilityType: Type, capabilityID: UInt64)
13
+ access(all) event CapabilityRemoved(owner: Address?, cacheUuid: UInt64, namespace: String, resourceType: Type, capabilityType: Type, capabilityID: UInt64)
14
+
15
+ // Add to a namespace
16
+ access(all) entitlement Add
17
+
18
+ // Remove from a namespace
19
+ access(all) entitlement Delete
20
+
21
+ // Retrieve a cap from the namespace
22
+ access(all) entitlement Get
23
+
24
+ // Resource that manages capabilities for a provided namespace. Only one capability is permitted per type.
25
+ access(all) resource Cache {
26
+ // A dictionary of resourceType -> CapabilityType -> Capability
27
+ // For example, one might store a Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Collection}> for the @TopShot.NFT resource.
28
+ // Note that the resource type is not necessarily the type that the borrowed capability is an instance of. This is because some resource definitions
29
+ // might be reused.
30
+ access(self) let caps: {Type: {Type: Capability}}
31
+
32
+ // who is this capability cache maintained by? e.g. flowty, dapper, find?
33
+ access(all) let namespace: String
34
+
35
+ // Remove a capability, if it exists,
36
+ access(Delete) fun removeCapabilityByType(resourceType: Type, capabilityType: Type): Capability? {
37
+ if let ref = &self.caps[resourceType] as auth(Mutate) &{Type: Capability}? {
38
+ let cap = ref.remove(key: capabilityType)
39
+ if cap != nil {
40
+ emit CapabilityRemoved(owner: self.owner?.address, cacheUuid: self.uuid, namespace: self.namespace, resourceType: resourceType, capabilityType: capabilityType, capabilityID: cap!.id)
41
+ }
42
+ }
43
+
44
+ return nil
45
+ }
46
+
47
+ // Adds a capability to the cache. If there is already an entry for the given type,
48
+ // it will be returned
49
+ access(Add) fun addCapability(resourceType: Type, cap: Capability): Capability? {
50
+ pre {
51
+ cap.id != 0: "cannot add a capability with id 0"
52
+ }
53
+
54
+ let capType = cap.getType()
55
+ emit CapabilityAdded(owner: self.owner?.address, cacheUuid: self.uuid, namespace: self.namespace, resourceType: resourceType, capabilityType: capType, capabilityID: cap.id)
56
+ if let ref = &self.caps[resourceType] as auth(Mutate) &{Type: Capability}? {
57
+ return ref.insert(key: capType, cap)
58
+ }
59
+
60
+ self.caps[resourceType] = {
61
+ capType: cap
62
+ }
63
+
64
+ return nil
65
+ }
66
+
67
+ // Retrieve a capability key'd by a given type.
68
+ access(Get) fun getCapabilityByType(resourceType: Type, capabilityType: Type): Capability? {
69
+ if let tmp = self.caps[resourceType] {
70
+ return tmp[capabilityType]
71
+ }
72
+
73
+ return nil
74
+ }
75
+
76
+ init(namespace: String) {
77
+ self.caps = {}
78
+
79
+ self.namespace = namespace
80
+ }
81
+ }
82
+
83
+ // There is no uniform storage path for the Capability Cache. Instead, each platform which issues capabilities
84
+ // should manage their own cache, and can generate the storage path to store it in with this helper method
85
+ access(all) fun getPathForCache(_ namespace: String): StoragePath {
86
+ return StoragePath(identifier: self.basePathIdentifier.concat(namespace))
87
+ ?? panic("invalid namespace value")
88
+ }
89
+
90
+ access(all) fun createCache(namespace: String): @Cache {
91
+ return <- create Cache(namespace: namespace)
92
+ }
93
+
94
+ init() {
95
+ self.basePathIdentifier = "CapabilityCache_".concat(self.account.address.toString()).concat("_")
96
+ }
97
+ }
@@ -1,30 +1,32 @@
1
1
  import "FungibleToken"
2
+ import "MetadataViews"
3
+ import "FungibleTokenMetadataViews"
2
4
 
3
- pub contract DapperUtilityCoin: FungibleToken {
5
+ access(all) contract DapperUtilityCoin: FungibleToken {
4
6
 
5
7
  // Total supply of DapperUtilityCoins in existence
6
- pub var totalSupply: UFix64
8
+ access(all) var totalSupply: UFix64
7
9
 
8
10
  // Event that is emitted when the contract is created
9
- pub event TokensInitialized(initialSupply: UFix64)
11
+ access(all) event TokensInitialized(initialSupply: UFix64)
10
12
 
11
13
  // Event that is emitted when tokens are withdrawn from a Vault
12
- pub event TokensWithdrawn(amount: UFix64, from: Address?)
14
+ access(all) event TokensWithdrawn(amount: UFix64, from: Address?)
13
15
 
14
16
  // Event that is emitted when tokens are deposited to a Vault
15
- pub event TokensDeposited(amount: UFix64, to: Address?)
17
+ access(all) event TokensDeposited(amount: UFix64, to: Address?)
16
18
 
17
19
  // Event that is emitted when new tokens are minted
18
- pub event TokensMinted(amount: UFix64)
20
+ access(all) event TokensMinted(amount: UFix64)
19
21
 
20
22
  // Event that is emitted when tokens are destroyed
21
- pub event TokensBurned(amount: UFix64)
23
+ access(all) event TokensBurned(amount: UFix64)
22
24
 
23
25
  // Event that is emitted when a new minter resource is created
24
- pub event MinterCreated(allowedAmount: UFix64)
26
+ access(all) event MinterCreated(allowedAmount: UFix64)
25
27
 
26
28
  // Event that is emitted when a new burner resource is created
27
- pub event BurnerCreated()
29
+ access(all) event BurnerCreated()
28
30
 
29
31
  // Vault
30
32
  //
@@ -38,10 +40,10 @@ pub contract DapperUtilityCoin: FungibleToken {
38
40
  // out of thin air. A special Minter resource needs to be defined to mint
39
41
  // new tokens.
40
42
  //
41
- pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance {
43
+ access(all) resource Vault: FungibleToken.Vault {
42
44
 
43
45
  // holds the balance of a users tokens
44
- pub var balance: UFix64
46
+ access(all) var balance: UFix64
45
47
 
46
48
  // initialize the balance at resource creation time
47
49
  init(balance: UFix64) {
@@ -57,7 +59,7 @@ pub contract DapperUtilityCoin: FungibleToken {
57
59
  // created Vault to the context that called so it can be deposited
58
60
  // elsewhere.
59
61
  //
60
- pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
62
+ access(FungibleToken.Withdraw) fun withdraw(amount: UFix64): @{FungibleToken.Vault} {
61
63
  self.balance = self.balance - amount
62
64
  emit TokensWithdrawn(amount: amount, from: self.owner?.address)
63
65
  return <-create Vault(balance: amount)
@@ -70,7 +72,7 @@ pub contract DapperUtilityCoin: FungibleToken {
70
72
  // It is allowed to destroy the sent Vault because the Vault
71
73
  // was a temporary holder of the tokens. The Vault's balance has
72
74
  // been consumed and therefore can be destroyed.
73
- pub fun deposit(from: @FungibleToken.Vault) {
75
+ access(all) fun deposit(from: @{FungibleToken.Vault}) {
74
76
  let vault <- from as! @DapperUtilityCoin.Vault
75
77
  self.balance = self.balance + vault.balance
76
78
  emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
@@ -78,9 +80,33 @@ pub contract DapperUtilityCoin: FungibleToken {
78
80
  destroy vault
79
81
  }
80
82
 
81
- destroy() {
83
+ access(all) view fun isAvailableToWithdraw(amount: UFix64): Bool {
84
+ return self.balance >= amount
85
+ }
86
+
87
+ access(all) view fun getSupportedVaultTypes(): {Type: Bool} {
88
+ return {Type<@Vault>(): true}
89
+ }
90
+
91
+ access(all) view fun isSupportedVaultType(type: Type): Bool {
92
+ return type == Type<@Vault>()
93
+ }
94
+
95
+ access(contract) fun burnCallback() {
82
96
  DapperUtilityCoin.totalSupply = DapperUtilityCoin.totalSupply - self.balance
83
97
  }
98
+
99
+ access(all) fun createEmptyVault(): @{FungibleToken.Vault} {
100
+ return <- create Vault(balance: 0.0)
101
+ }
102
+
103
+ access(all) view fun getViews(): [Type]{
104
+ return DapperUtilityCoin.getContractViews(resourceType: nil)
105
+ }
106
+
107
+ access(all) fun resolveView(_ view: Type): AnyStruct? {
108
+ return DapperUtilityCoin.resolveContractView(resourceType: nil, viewType: view)
109
+ }
84
110
  }
85
111
 
86
112
  // createEmptyVault
@@ -90,16 +116,16 @@ pub contract DapperUtilityCoin: FungibleToken {
90
116
  // and store the returned Vault in their storage in order to allow their
91
117
  // account to be able to receive deposits of this token type.
92
118
  //
93
- pub fun createEmptyVault(): @FungibleToken.Vault {
119
+ access(all) fun createEmptyVault(vaultType: Type): @{FungibleToken.Vault} {
94
120
  return <-create Vault(balance: 0.0)
95
121
  }
96
122
 
97
- pub resource Administrator {
123
+ access(all) resource Administrator {
98
124
  // createNewMinter
99
125
  //
100
126
  // Function that creates and returns a new minter resource
101
127
  //
102
- pub fun createNewMinter(allowedAmount: UFix64): @Minter {
128
+ access(all) fun createNewMinter(allowedAmount: UFix64): @Minter {
103
129
  emit MinterCreated(allowedAmount: allowedAmount)
104
130
  return <-create Minter(allowedAmount: allowedAmount)
105
131
  }
@@ -108,7 +134,7 @@ pub contract DapperUtilityCoin: FungibleToken {
108
134
  //
109
135
  // Function that creates and returns a new burner resource
110
136
  //
111
- pub fun createNewBurner(): @Burner {
137
+ access(all) fun createNewBurner(): @Burner {
112
138
  emit BurnerCreated()
113
139
  return <-create Burner()
114
140
  }
@@ -118,19 +144,19 @@ pub contract DapperUtilityCoin: FungibleToken {
118
144
  //
119
145
  // Resource object that token admin accounts can hold to mint new tokens.
120
146
  //
121
- pub resource Minter {
147
+ access(all) resource Minter {
122
148
 
123
149
  // the amount of tokens that the minter is allowed to mint
124
- pub var allowedAmount: UFix64
150
+ access(all) var allowedAmount: UFix64
125
151
 
126
152
  // mintTokens
127
153
  //
128
154
  // Function that mints new tokens, adds them to the total supply,
129
155
  // and returns them to the calling context.
130
156
  //
131
- pub fun mintTokens(amount: UFix64): @DapperUtilityCoin.Vault {
157
+ access(all) fun mintTokens(amount: UFix64): @DapperUtilityCoin.Vault {
132
158
  pre {
133
- amount > UFix64(0): "Amount minted must be greater than zero"
159
+ amount > 0.0: "Amount minted must be greater than zero"
134
160
  amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
135
161
  }
136
162
  DapperUtilityCoin.totalSupply = DapperUtilityCoin.totalSupply + amount
@@ -148,7 +174,7 @@ pub contract DapperUtilityCoin: FungibleToken {
148
174
  //
149
175
  // Resource object that token admin accounts can hold to burn tokens.
150
176
  //
151
- pub resource Burner {
177
+ access(all) resource Burner {
152
178
 
153
179
  // burnTokens
154
180
  //
@@ -157,7 +183,7 @@ pub contract DapperUtilityCoin: FungibleToken {
157
183
  // Note: the burned tokens are automatically subtracted from the
158
184
  // total supply in the Vault destructor.
159
185
  //
160
- pub fun burnTokens(from: @FungibleToken.Vault) {
186
+ access(all) fun burnTokens(from: @{FungibleToken.Vault}) {
161
187
  let vault <- from as! @DapperUtilityCoin.Vault
162
188
  let amount = vault.balance
163
189
  destroy vault
@@ -165,6 +191,57 @@ pub contract DapperUtilityCoin: FungibleToken {
165
191
  }
166
192
  }
167
193
 
194
+ access(all) view fun getContractViews(resourceType: Type?): [Type] {
195
+ return [Type<FungibleTokenMetadataViews.FTView>(),
196
+ Type<FungibleTokenMetadataViews.FTDisplay>(),
197
+ Type<FungibleTokenMetadataViews.FTVaultData>(),
198
+ Type<FungibleTokenMetadataViews.TotalSupply>()]
199
+ }
200
+
201
+ access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
202
+ switch viewType {
203
+ case Type<FungibleTokenMetadataViews.FTView>():
204
+ return FungibleTokenMetadataViews.FTView(
205
+ ftDisplay: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTDisplay>()) as! FungibleTokenMetadataViews.FTDisplay?,
206
+ ftVaultData: self.resolveContractView(resourceType: nil, viewType: Type<FungibleTokenMetadataViews.FTVaultData>()) as! FungibleTokenMetadataViews.FTVaultData?
207
+ )
208
+ case Type<FungibleTokenMetadataViews.FTDisplay>():
209
+ let media = MetadataViews.Media(
210
+ file: MetadataViews.HTTPFile(
211
+ url: "https://meetdapper.com/"
212
+ ),
213
+ mediaType: "image/svg+xml"
214
+ )
215
+ let medias = MetadataViews.Medias([media])
216
+ return FungibleTokenMetadataViews.FTDisplay(
217
+ name: "Dapper Utility Coin",
218
+ symbol: "DUC",
219
+ description: "",
220
+ externalURL: MetadataViews.ExternalURL("https://meetdapper.com/"),
221
+ logos: medias,
222
+ socials: {
223
+ "twitter": MetadataViews.ExternalURL("https://twitter.com/hellodapper")
224
+ }
225
+ )
226
+ case Type<FungibleTokenMetadataViews.FTVaultData>():
227
+ let vaultRef = DapperUtilityCoin.account.storage.borrow<auth(FungibleToken.Withdraw) &DapperUtilityCoin.Vault>(from: /storage/dapperUtilityCoinVault)
228
+ ?? panic("Could not borrow reference to the contract's Vault!")
229
+ return FungibleTokenMetadataViews.FTVaultData(
230
+ storagePath: /storage/dapperUtilityCoinVault,
231
+ receiverPath: /public/exampleTokenReceiver,
232
+ metadataPath: /public/dapperUtilityCoinBalance,
233
+ receiverLinkedType: Type<&{FungibleToken.Receiver, FungibleToken.Vault}>(),
234
+ metadataLinkedType: Type<&{FungibleToken.Balance, FungibleToken.Vault}>(),
235
+ createEmptyVaultFunction: (fun (): @{FungibleToken.Vault} {
236
+ return <-vaultRef.createEmptyVault()
237
+ })
238
+ )
239
+ case Type<FungibleTokenMetadataViews.TotalSupply>():
240
+ return FungibleTokenMetadataViews.TotalSupply(totalSupply: DapperUtilityCoin.totalSupply)
241
+ }
242
+ return nil
243
+ }
244
+
168
245
  init() {
169
246
  // we're using a high value as the balance here to make it look like we've got a ton of money,
170
247
  // just in case some contract manually checks that our balance is sufficient to pay for stuff
@@ -172,26 +249,16 @@ pub contract DapperUtilityCoin: FungibleToken {
172
249
 
173
250
  let admin <- create Administrator()
174
251
  let minter <- admin.createNewMinter(allowedAmount: self.totalSupply)
175
- self.account.save(<-admin, to: /storage/dapperUtilityCoinAdmin)
252
+ self.account.storage.save(<-admin, to: /storage/dapperUtilityCoinAdmin)
176
253
 
177
254
  // mint tokens
178
255
  let tokenVault <- minter.mintTokens(amount: self.totalSupply)
179
- self.account.save(<-tokenVault, to: /storage/dapperUtilityCoinVault)
256
+ self.account.storage.save(<-tokenVault, to: /storage/dapperUtilityCoinVault)
180
257
  destroy minter
181
258
 
182
- // Create a public capability to the stored Vault that only exposes
183
- // the balance field through the Balance interface
184
- self.account.link<&DapperUtilityCoin.Vault{FungibleToken.Balance}>(
185
- /public/dapperUtilityCoinBalance,
186
- target: /storage/dapperUtilityCoinVault
187
- )
188
-
189
- // Create a public capability to the stored Vault that only exposes
190
- // the deposit method through the Receiver interface
191
- self.account.link<&{FungibleToken.Receiver}>(
192
- /public/dapperUtilityCoinReceiver,
193
- target: /storage/dapperUtilityCoinVault
194
- )
259
+ let cap = self.account.capabilities.storage.issue<&DapperUtilityCoin.Vault>(/storage/dapperUtilityCoinVault)
260
+ self.account.capabilities.publish(cap, at: /public/dapperUtilityCoinBalance)
261
+ self.account.capabilities.publish(cap, at: /public/dapperUtilityCoinReceiver)
195
262
 
196
263
  // Emit an event that shows that the contract was initialized
197
264
  emit TokensInitialized(initialSupply: self.totalSupply)