@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.
- package/README.md +1 -1
- package/contracts/Burner.cdc +44 -0
- package/contracts/FlowStorageFees.cdc +15 -15
- package/contracts/FlowToken.cdc +29 -78
- package/contracts/FungibleToken.cdc +80 -53
- package/contracts/FungibleTokenMetadataViews.cdc +13 -25
- package/contracts/FungibleTokenSwitchboard.cdc +360 -0
- package/contracts/MetadataViews.cdc +107 -50
- package/contracts/NonFungibleToken.cdc +110 -60
- package/contracts/TokenForwarding.cdc +19 -11
- package/contracts/ViewResolver.cdc +20 -16
- package/contracts/capability-cache/CapabilityCache.cdc +97 -0
- package/contracts/dapper/DapperUtilityCoin.cdc +106 -39
- package/contracts/dapper/FlowUtilityToken.cdc +107 -40
- 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 +18 -21
- package/contracts/example/ExampleToken.cdc +68 -1
- package/contracts/find/FindViews.cdc +357 -353
- package/contracts/flow-utils/AddressUtils.cdc +20 -23
- package/contracts/flow-utils/ArrayUtils.cdc +10 -11
- package/contracts/flow-utils/ScopedFTProviders.cdc +27 -19
- package/contracts/flow-utils/ScopedNFTProviders.cdc +31 -26
- package/contracts/flow-utils/StringUtils.cdc +24 -37
- package/contracts/flowty-drops/ContractManager.cdc +47 -0
- package/contracts/flowty-drops/DropFactory.cdc +75 -0
- package/contracts/flowty-drops/DropTypes.cdc +278 -0
- package/contracts/flowty-drops/FlowtyAddressVerifiers.cdc +64 -0
- package/contracts/flowty-drops/FlowtyDrops.cdc +431 -0
- package/contracts/flowty-drops/FlowtyPricers.cdc +48 -0
- package/contracts/flowty-drops/FlowtySwitchers.cdc +113 -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 +58 -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 +119 -0
- package/contracts/flowty-drops/nft/OpenEditionNFT.cdc +41 -0
- package/contracts/flowty-drops/nft/OpenEditionTemplate.cdc +52 -0
- package/contracts/flowty-drops/nft/UniversalCollection.cdc +23 -0
- package/contracts/fungible-token-router/FungibleTokenRouter.cdc +105 -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 +29 -25
- package/contracts/nft-catalog/NFTCatalog.cdc +60 -64
- package/contracts/nft-catalog/NFTCatalogAdmin.cdc +28 -27
- package/flow.json +189 -5
- package/package.json +1 -1
- 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
|
+
}
|