@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
@@ -0,0 +1,75 @@
1
+ import "FungibleToken"
2
+ import "MetadataViews"
3
+
4
+ import "FlowtyDrops"
5
+ import "FlowtySwitchers"
6
+ import "FlowtyAddressVerifiers"
7
+ import "FlowtyPricers"
8
+
9
+ /*
10
+ The DropFactory is a contract that helps create common types of drops
11
+ */
12
+ access(all) contract DropFactory {
13
+ access(all) fun createEndlessOpenEditionDrop(
14
+ price: UFix64,
15
+ paymentTokenType: Type,
16
+ dropDisplay: MetadataViews.Display,
17
+ minterCap: Capability<&{FlowtyDrops.Minter}>,
18
+ nftTypeIdentifier: String
19
+ ): @FlowtyDrops.Drop {
20
+ pre {
21
+ paymentTokenType.isSubtype(of: Type<@{FungibleToken.Vault}>()): "paymentTokenType must be a FungibleToken"
22
+ }
23
+
24
+ // This drop is always on and never ends.
25
+ let switcher = FlowtySwitchers.AlwaysOn()
26
+
27
+ // All addresses are allowed to participate
28
+ let addressVerifier = FlowtyAddressVerifiers.AllowAll(maxPerMint: 10)
29
+
30
+ // The cost of each mint is the same, and only permits one token type as payment
31
+ let pricer = FlowtyPricers.FlatPrice(price: price, paymentTokenType: paymentTokenType)
32
+
33
+ let phaseDetails = FlowtyDrops.PhaseDetails(switcher: switcher, display: nil, pricer: pricer, addressVerifier: addressVerifier)
34
+ let phase <- FlowtyDrops.createPhase(details: phaseDetails)
35
+
36
+
37
+ let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
38
+ let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05, nftType: nftTypeIdentifier)
39
+ let drop <- FlowtyDrops.createDrop(details: dropDetails, minterCap: minterCap, phases: <- [<-phase])
40
+
41
+ return <- drop
42
+ }
43
+
44
+ access(all) fun createTimeBasedOpenEditionDrop(
45
+ price: UFix64,
46
+ paymentTokenType: Type,
47
+ dropDisplay: MetadataViews.Display,
48
+ minterCap: Capability<&{FlowtyDrops.Minter}>,
49
+ startUnix: UInt64?,
50
+ endUnix: UInt64?,
51
+ nftTypeIdentifier: String
52
+ ): @FlowtyDrops.Drop {
53
+ pre {
54
+ paymentTokenType.isSubtype(of: Type<@{FungibleToken.Vault}>()): "paymentTokenType must be a FungibleToken"
55
+ }
56
+
57
+ // This switcher turns on at a set unix timestamp (or is on by default if nil), and ends at the specified end date if provided
58
+ let switcher = FlowtySwitchers.TimestampSwitch(start: startUnix, end: endUnix)
59
+
60
+ // All addresses are allowed to participate
61
+ let addressVerifier = FlowtyAddressVerifiers.AllowAll(maxPerMint: 10)
62
+
63
+ // The cost of each mint is the same, and only permits one token type as payment
64
+ let pricer = FlowtyPricers.FlatPrice(price: price, paymentTokenType: paymentTokenType)
65
+
66
+ let phaseDetails = FlowtyDrops.PhaseDetails(switcher: switcher, display: nil, pricer: pricer, addressVerifier: addressVerifier)
67
+ let phase <- FlowtyDrops.createPhase(details: phaseDetails)
68
+
69
+ let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
70
+ let dropDetails = FlowtyDrops.DropDetails(display: dropDisplay, medias: nil, commissionRate: 0.05, nftType: nftTypeIdentifier)
71
+ let drop <- FlowtyDrops.createDrop(details: dropDetails, minterCap: minterCap, phases: <- [<-phase])
72
+
73
+ return <- drop
74
+ }
75
+ }
@@ -0,0 +1,278 @@
1
+ import "FlowtyDrops"
2
+ import "MetadataViews"
3
+ import "ViewResolver"
4
+ import "AddressUtils"
5
+
6
+ access(all) contract DropTypes {
7
+ access(all) struct Display {
8
+ access(all) let name: String
9
+ access(all) let description: String
10
+ access(all) let url: String
11
+
12
+ init(_ display: MetadataViews.Display) {
13
+ self.name = display.name
14
+ self.description = display.description
15
+ self.url = display.thumbnail.uri()
16
+ }
17
+ }
18
+
19
+ access(all) struct Media {
20
+ access(all) let url: String
21
+ access(all) let mediaType: String
22
+
23
+ init(_ media: MetadataViews.Media) {
24
+ self.url = media.file.uri()
25
+ self.mediaType = media.mediaType
26
+ }
27
+ }
28
+
29
+ access(all) struct DropSummary {
30
+ access(all) let id: UInt64
31
+ access(all) let display: Display
32
+ access(all) let medias: [Media]
33
+ access(all) let totalMinted: Int
34
+ access(all) let minterCount: Int
35
+ access(all) let commissionRate: UFix64
36
+ access(all) let nftType: String
37
+
38
+ access(all) let address: Address?
39
+ access(all) let mintedByAddress: Int?
40
+
41
+ access(all) let phases: [PhaseSummary]
42
+
43
+ access(all) let blockTimestamp: UInt64
44
+ access(all) let blockHeight: UInt64
45
+
46
+ init(
47
+ id: UInt64,
48
+ display: MetadataViews.Display,
49
+ medias: MetadataViews.Medias?,
50
+ totalMinted: Int,
51
+ minterCount: Int,
52
+ mintedByAddress: Int?,
53
+ commissionRate: UFix64,
54
+ nftType: Type,
55
+ address: Address?,
56
+ phases: [PhaseSummary]
57
+ ) {
58
+ self.id = id
59
+ self.display = Display(display)
60
+
61
+ self.medias = []
62
+ for m in medias?.items ?? [] {
63
+ self.medias.append(Media(m))
64
+ }
65
+
66
+
67
+ self.totalMinted = totalMinted
68
+ self.commissionRate = commissionRate
69
+ self.minterCount = minterCount
70
+ self.mintedByAddress = mintedByAddress
71
+ self.nftType = nftType.identifier
72
+ self.address = address
73
+ self.phases = phases
74
+
75
+ let b = getCurrentBlock()
76
+ self.blockHeight = b.height
77
+ self.blockTimestamp = UInt64(b.timestamp)
78
+ }
79
+ }
80
+
81
+ access(all) struct Quote {
82
+ access(all) let price: UFix64
83
+ access(all) let quantity: Int
84
+ access(all) let paymentIdentifier: String
85
+ access(all) let minter: Address?
86
+
87
+ init(price: UFix64, quantity: Int, paymentIdentifier: String, minter: Address?) {
88
+ self.price = price
89
+ self.quantity = quantity
90
+ self.paymentIdentifier = paymentIdentifier
91
+ self.minter = minter
92
+ }
93
+ }
94
+
95
+ access(all) struct PhaseSummary {
96
+ access(all) let id: UInt64
97
+ access(all) let index: Int
98
+
99
+ access(all) let switcherType: String
100
+ access(all) let pricerType: String
101
+ access(all) let addressVerifierType: String
102
+
103
+ access(all) let hasStarted: Bool
104
+ access(all) let hasEnded: Bool
105
+ access(all) let start: UInt64?
106
+ access(all) let end: UInt64?
107
+
108
+ access(all) let paymentTypes: [String]
109
+
110
+ access(all) let address: Address?
111
+ access(all) let remainingForAddress: Int?
112
+
113
+ access(all) let quote: Quote?
114
+
115
+ init(
116
+ index: Int,
117
+ phase: &{FlowtyDrops.PhasePublic},
118
+ address: Address?,
119
+ totalMinted: Int?,
120
+ minter: Address?,
121
+ quantity: Int?,
122
+ paymentIdentifier: String?
123
+ ) {
124
+ self.index = index
125
+ self.id = phase.uuid
126
+
127
+ let d = phase.getDetails()
128
+ self.switcherType = d.switcher.getType().identifier
129
+ self.pricerType = d.pricer.getType().identifier
130
+ self.addressVerifierType = d.addressVerifier.getType().identifier
131
+
132
+ self.hasStarted = d.switcher.hasStarted()
133
+ self.hasEnded = d.switcher.hasEnded()
134
+ self.start = d.switcher.getStart()
135
+ self.end = d.switcher.getEnd()
136
+
137
+ self.paymentTypes = []
138
+ for pt in d.pricer.getPaymentTypes() {
139
+ self.paymentTypes.append(pt.identifier)
140
+ }
141
+
142
+ if let addr = address {
143
+ self.address = address
144
+ self.remainingForAddress = d.addressVerifier.remainingForAddress(addr: addr, totalMinted: totalMinted ?? 0)
145
+ } else {
146
+ self.address = nil
147
+ self.remainingForAddress = nil
148
+ }
149
+
150
+ if paymentIdentifier != nil && quantity != nil {
151
+ let price = d.pricer.getPrice(num: quantity!, paymentTokenType: CompositeType(paymentIdentifier!)!, minter: minter)
152
+
153
+ self.quote = Quote(price: price, quantity: quantity!, paymentIdentifier: paymentIdentifier!, minter: minter)
154
+ } else {
155
+ self.quote = nil
156
+ }
157
+ }
158
+ }
159
+
160
+ access(all) fun getDropSummary(nftTypeIdentifier: String, dropID: UInt64, minter: Address?, quantity: Int?, paymentIdentifier: String?): DropSummary? {
161
+ let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
162
+ let segments = nftTypeIdentifier.split(separator: ".")
163
+ let contractAddress = AddressUtils.parseAddress(nftType)!
164
+ let contractName = segments[2]
165
+
166
+ let resolver = getAccount(contractAddress).contracts.borrow<&{ViewResolver}>(name: contractName)
167
+ if resolver == nil {
168
+ return nil
169
+ }
170
+
171
+ let dropResolver = resolver!.resolveContractView(resourceType: nftType, viewType: Type<FlowtyDrops.DropResolver>()) as! FlowtyDrops.DropResolver?
172
+ if dropResolver == nil {
173
+ return nil
174
+ }
175
+
176
+ let container = dropResolver!.borrowContainer()
177
+ if container == nil {
178
+ return nil
179
+ }
180
+
181
+ let drop = container!.borrowDropPublic(id: dropID)
182
+ if drop == nil {
183
+ return nil
184
+ }
185
+
186
+ let dropDetails = drop!.getDetails()
187
+
188
+ let phaseSummaries: [PhaseSummary] = []
189
+ for index, phase in drop!.borrowAllPhases() {
190
+ let summary = PhaseSummary(
191
+ index: index,
192
+ phase: phase,
193
+ address: minter,
194
+ totalMinted: minter != nil ? dropDetails.minters[minter!] : nil,
195
+ minter: minter,
196
+ quantity: quantity,
197
+ paymentIdentifier: paymentIdentifier
198
+ )
199
+ phaseSummaries.append(summary)
200
+ }
201
+
202
+ let dropSummary = DropSummary(
203
+ id: drop!.uuid,
204
+ display: dropDetails.display,
205
+ medias: dropDetails.medias,
206
+ totalMinted: dropDetails.totalMinted,
207
+ minterCount: dropDetails.minters.keys.length,
208
+ mintedByAddress: minter != nil ? dropDetails.minters[minter!] : nil,
209
+ commissionRate: dropDetails.commissionRate,
210
+ nftType: CompositeType(dropDetails.nftType)!,
211
+ address: minter,
212
+ phases: phaseSummaries
213
+ )
214
+
215
+ return dropSummary
216
+ }
217
+
218
+ access(all) fun getAllDropSummaries(nftTypeIdentifier: String, minter: Address?, quantity: Int?, paymentIdentifier: String?): [DropSummary] {
219
+ let nftType = CompositeType(nftTypeIdentifier) ?? panic("invalid nft type identifier")
220
+ let segments = nftTypeIdentifier.split(separator: ".")
221
+ let contractAddress = AddressUtils.parseAddress(nftType)!
222
+ let contractName = segments[2]
223
+
224
+ let resolver = getAccount(contractAddress).contracts.borrow<&{ViewResolver}>(name: contractName)
225
+ if resolver == nil {
226
+ return []
227
+ }
228
+
229
+ let dropResolver = resolver!.resolveContractView(resourceType: nftType, viewType: Type<FlowtyDrops.DropResolver>()) as! FlowtyDrops.DropResolver?
230
+ if dropResolver == nil {
231
+ return []
232
+ }
233
+
234
+ let container = dropResolver!.borrowContainer()
235
+ if container == nil {
236
+ return []
237
+ }
238
+
239
+ let summaries: [DropSummary] = []
240
+ for id in container!.getIDs() {
241
+ let drop = container!.borrowDropPublic(id: id)
242
+ if drop == nil {
243
+ continue
244
+ }
245
+
246
+ let dropDetails = drop!.getDetails()
247
+
248
+ let phaseSummaries: [PhaseSummary] = []
249
+ for index, phase in drop!.borrowAllPhases() {
250
+ let summary = PhaseSummary(
251
+ index: index,
252
+ phase: phase,
253
+ address: minter,
254
+ totalMinted: minter != nil ? dropDetails.minters[minter!] : nil,
255
+ minter: minter,
256
+ quantity: quantity,
257
+ paymentIdentifier: paymentIdentifier
258
+ )
259
+ phaseSummaries.append(summary)
260
+ }
261
+
262
+ summaries.append(DropSummary(
263
+ id: drop!.uuid,
264
+ display: dropDetails.display,
265
+ medias: dropDetails.medias,
266
+ totalMinted: dropDetails.totalMinted,
267
+ minterCount: dropDetails.minters.keys.length,
268
+ mintedByAddress: minter != nil ? dropDetails.minters[minter!] : nil,
269
+ commissionRate: dropDetails.commissionRate,
270
+ nftType: CompositeType(dropDetails.nftType)!,
271
+ address: minter,
272
+ phases: phaseSummaries
273
+ ))
274
+ }
275
+
276
+ return summaries
277
+ }
278
+ }
@@ -0,0 +1,64 @@
1
+ import "FlowtyDrops"
2
+
3
+ /*
4
+ This contract contains implementations of the FlowtyDrops.AddressVerifier struct interface
5
+ */
6
+ access(all) contract FlowtyAddressVerifiers {
7
+ /*
8
+ The AllowAll AddressVerifier allows any address to mint without any verification
9
+ */
10
+ access(all) struct AllowAll: FlowtyDrops.AddressVerifier {
11
+ access(all) var maxPerMint: Int
12
+
13
+ access(all) view fun canMint(addr: Address, num: Int, totalMinted: Int, data: {String: AnyStruct}): Bool {
14
+ return num <= self.maxPerMint
15
+ }
16
+
17
+ access(Mutate) fun setMaxPerMint(_ value: Int) {
18
+ self.maxPerMint = value
19
+ }
20
+
21
+ init(maxPerMint: Int) {
22
+ pre {
23
+ maxPerMint > 0: "maxPerMint must be greater than 0"
24
+ }
25
+
26
+ self.maxPerMint = maxPerMint
27
+ }
28
+ }
29
+
30
+ /*
31
+ The AllowList Verifier only lets a configured set of addresses participate in a drop phase. The number
32
+ of mints per address is specified to allow more granular control of what each address is permitted to do.
33
+ */
34
+ access(all) struct AllowList: FlowtyDrops.AddressVerifier {
35
+ access(self) let allowedAddresses: {Address: Int}
36
+
37
+ access(all) view fun canMint(addr: Address, num: Int, totalMinted: Int, data: {String: AnyStruct}): Bool {
38
+ if let allowedMints = self.allowedAddresses[addr] {
39
+ return allowedMints >= num + totalMinted
40
+ }
41
+
42
+ return false
43
+ }
44
+
45
+ access(all) view fun remainingForAddress(addr: Address, totalMinted: Int): Int? {
46
+ if let allowedMints = self.allowedAddresses[addr] {
47
+ return allowedMints - totalMinted
48
+ }
49
+ return nil
50
+ }
51
+
52
+ access(Mutate) fun setAddress(addr: Address, value: Int) {
53
+ self.allowedAddresses[addr] = value
54
+ }
55
+
56
+ access(Mutate) fun removeAddress(addr: Address) {
57
+ self.allowedAddresses.remove(key: addr)
58
+ }
59
+
60
+ init(allowedAddresses: {Address: Int}) {
61
+ self.allowedAddresses = allowedAddresses
62
+ }
63
+ }
64
+ }