@flowtyio/flow-contracts 0.1.0-beta.8 → 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/TokenForwarding.cdc +19 -11
- 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
|
@@ -22,36 +22,39 @@ import "NonFungibleToken"
|
|
|
22
22
|
import "MetadataViews"
|
|
23
23
|
import "FungibleToken"
|
|
24
24
|
import "FlowToken"
|
|
25
|
-
import "FindViews"
|
|
25
|
+
// import "FindViews"
|
|
26
26
|
import "ViewResolver"
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
access(all) contract FLOAT: NonFungibleToken, ViewResolver {
|
|
29
|
+
|
|
30
|
+
access(all) entitlement EventOwner
|
|
31
|
+
access(all) entitlement EventsOwner
|
|
29
32
|
|
|
30
33
|
/***********************************************/
|
|
31
34
|
/******************** PATHS ********************/
|
|
32
35
|
/***********************************************/
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
access(all) let FLOATCollectionStoragePath: StoragePath
|
|
38
|
+
access(all) let FLOATCollectionPublicPath: PublicPath
|
|
39
|
+
access(all) let FLOATEventsStoragePath: StoragePath
|
|
40
|
+
access(all) let FLOATEventsPublicPath: PublicPath
|
|
41
|
+
access(all) let FLOATEventsPrivatePath: PrivatePath
|
|
39
42
|
|
|
40
43
|
/************************************************/
|
|
41
44
|
/******************** EVENTS ********************/
|
|
42
45
|
/************************************************/
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
access(all) event ContractInitialized()
|
|
48
|
+
access(all) event FLOATMinted(id: UInt64, eventHost: Address, eventId: UInt64, eventImage: String, recipient: Address, serial: UInt64)
|
|
49
|
+
access(all) event FLOATClaimed(id: UInt64, eventHost: Address, eventId: UInt64, eventImage: String, eventName: String, recipient: Address, serial: UInt64)
|
|
50
|
+
access(all) event FLOATDestroyed(id: UInt64, eventHost: Address, eventId: UInt64, eventImage: String, serial: UInt64)
|
|
51
|
+
access(all) event FLOATTransferred(id: UInt64, eventHost: Address, eventId: UInt64, newOwner: Address?, serial: UInt64)
|
|
52
|
+
access(all) event FLOATPurchased(id: UInt64, eventHost: Address, eventId: UInt64, recipient: Address, serial: UInt64)
|
|
53
|
+
access(all) event FLOATEventCreated(eventId: UInt64, description: String, host: Address, image: String, name: String, url: String)
|
|
54
|
+
access(all) event FLOATEventDestroyed(eventId: UInt64, host: Address, name: String)
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
access(all) event Deposit(id: UInt64, to: Address?)
|
|
57
|
+
access(all) event Withdraw(id: UInt64, from: Address?)
|
|
55
58
|
|
|
56
59
|
/***********************************************/
|
|
57
60
|
/******************** STATE ********************/
|
|
@@ -59,10 +62,10 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
59
62
|
|
|
60
63
|
// The total amount of FLOATs that have ever been
|
|
61
64
|
// created (does not go down when a FLOAT is destroyed)
|
|
62
|
-
|
|
65
|
+
access(all) var totalSupply: UInt64
|
|
63
66
|
// The total amount of FLOATEvents that have ever been
|
|
64
67
|
// created (does not go down when a FLOATEvent is destroyed)
|
|
65
|
-
|
|
68
|
+
access(all) var totalFLOATEvents: UInt64
|
|
66
69
|
|
|
67
70
|
/***********************************************/
|
|
68
71
|
/**************** FUNCTIONALITY ****************/
|
|
@@ -70,10 +73,10 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
70
73
|
|
|
71
74
|
// A helpful wrapper to contain an address,
|
|
72
75
|
// the id of a FLOAT, and its serial
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
access(all) struct TokenIdentifier {
|
|
77
|
+
access(all) let id: UInt64
|
|
78
|
+
access(all) let address: Address
|
|
79
|
+
access(all) let serial: UInt64
|
|
77
80
|
|
|
78
81
|
init(_id: UInt64, _address: Address, _serial: UInt64) {
|
|
79
82
|
self.id = _id
|
|
@@ -82,9 +85,9 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
access(all) struct TokenInfo {
|
|
89
|
+
access(all) let path: PublicPath
|
|
90
|
+
access(all) let price: UFix64
|
|
88
91
|
|
|
89
92
|
init(_path: PublicPath, _price: UFix64) {
|
|
90
93
|
self.path = _path
|
|
@@ -93,50 +96,54 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
// Represents a FLOAT
|
|
96
|
-
|
|
99
|
+
access(all) resource NFT: NonFungibleToken.NFT {
|
|
97
100
|
// The `uuid` of this resource
|
|
98
|
-
|
|
101
|
+
access(all) let id: UInt64
|
|
99
102
|
|
|
100
103
|
// Some of these are also duplicated on the event,
|
|
101
104
|
// but it's necessary to put them here as well
|
|
102
105
|
// in case the FLOATEvent host deletes the event
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
access(all) let dateReceived: UFix64
|
|
107
|
+
access(all) let eventDescription: String
|
|
108
|
+
access(all) let eventHost: Address
|
|
109
|
+
access(all) let eventId: UInt64
|
|
110
|
+
access(all) let eventImage: String
|
|
111
|
+
access(all) let eventName: String
|
|
112
|
+
access(all) let originalRecipient: Address
|
|
113
|
+
access(all) let serial: UInt64
|
|
111
114
|
|
|
112
115
|
// A capability that points to the FLOATEvents this FLOAT is from.
|
|
113
116
|
// There is a chance the event host unlinks their event from
|
|
114
117
|
// the public, in which case it's impossible to know details
|
|
115
118
|
// about the event. Which is fine, since we store the
|
|
116
119
|
// crucial data to know about the FLOAT in the FLOAT itself.
|
|
117
|
-
|
|
120
|
+
access(all) let eventsCap: Capability<&FLOATEvents>
|
|
121
|
+
|
|
122
|
+
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
|
|
123
|
+
return <- FLOAT.createEmptyCollection(nftType: Type<@FLOAT.NFT>())
|
|
124
|
+
}
|
|
118
125
|
|
|
119
126
|
// Helper function to get the metadata of the event
|
|
120
127
|
// this FLOAT is from.
|
|
121
|
-
|
|
122
|
-
if let events: &FLOATEvents
|
|
128
|
+
access(all) fun getEventRef(): &FLOATEvent? {
|
|
129
|
+
if let events: &FLOATEvents = self.eventsCap.borrow() {
|
|
123
130
|
return events.borrowPublicEventRef(eventId: self.eventId)
|
|
124
131
|
}
|
|
125
132
|
return nil
|
|
126
133
|
}
|
|
127
134
|
|
|
128
|
-
|
|
129
|
-
if let
|
|
130
|
-
return
|
|
135
|
+
access(all) fun getExtraMetadata(): {String: AnyStruct} {
|
|
136
|
+
if let eventRef: &FLOATEvent = self.getEventRef() {
|
|
137
|
+
return eventRef.getExtraFloatMetadata(serial: self.serial)
|
|
131
138
|
}
|
|
132
139
|
return {}
|
|
133
140
|
}
|
|
134
141
|
|
|
135
|
-
|
|
142
|
+
access(all) fun getSpecificExtraMetadata(key: String): AnyStruct? {
|
|
136
143
|
return self.getExtraMetadata()[key]
|
|
137
144
|
}
|
|
138
145
|
|
|
139
|
-
|
|
146
|
+
access(all) fun getImage(): String {
|
|
140
147
|
if let extraEventMetadata: {String: AnyStruct} = self.getEventRef()?.getExtraMetadata() {
|
|
141
148
|
if FLOAT.extraMetadataToStrOpt(extraEventMetadata, "visibilityMode") == "picture" {
|
|
142
149
|
return self.eventImage
|
|
@@ -157,7 +164,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
// This is for the MetdataStandard
|
|
160
|
-
|
|
167
|
+
access(all) view fun getViews(): [Type] {
|
|
161
168
|
let supportedViews = [
|
|
162
169
|
Type<MetadataViews.Display>(),
|
|
163
170
|
Type<MetadataViews.Royalties>(),
|
|
@@ -169,15 +176,15 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
169
176
|
Type<TokenIdentifier>()
|
|
170
177
|
]
|
|
171
178
|
|
|
172
|
-
if self.getEventRef()?.transferrable == false {
|
|
173
|
-
|
|
174
|
-
}
|
|
179
|
+
// if self.getEventRef()?.transferrable == false {
|
|
180
|
+
// supportedViews.append(Type<FindViews.SoulBound>())
|
|
181
|
+
// }
|
|
175
182
|
|
|
176
183
|
return supportedViews
|
|
177
184
|
}
|
|
178
185
|
|
|
179
186
|
// This is for the MetdataStandard
|
|
180
|
-
|
|
187
|
+
access(all) fun resolveView(_ view: Type): AnyStruct? {
|
|
181
188
|
switch view {
|
|
182
189
|
case Type<MetadataViews.Display>():
|
|
183
190
|
return MetadataViews.Display(
|
|
@@ -188,7 +195,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
188
195
|
case Type<MetadataViews.Royalties>():
|
|
189
196
|
return MetadataViews.Royalties([
|
|
190
197
|
MetadataViews.Royalty(
|
|
191
|
-
|
|
198
|
+
receiver: getAccount(0x5643fd47a29770e7).capabilities.get<&{FungibleToken.Receiver}>(/public/flowTokenReceiver),
|
|
192
199
|
cut: 0.05, // 5% royalty on secondary sales
|
|
193
200
|
description: "Emerald City DAO receives a 5% royalty from secondary sales because this NFT was created using FLOAT (https://floats.city/), a proof of attendance platform created by Emerald City DAO."
|
|
194
201
|
)
|
|
@@ -196,9 +203,9 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
196
203
|
case Type<MetadataViews.ExternalURL>():
|
|
197
204
|
return MetadataViews.ExternalURL("https://floats.city/".concat(self.owner!.address.toString()).concat("/float/").concat(self.id.toString()))
|
|
198
205
|
case Type<MetadataViews.NFTCollectionData>():
|
|
199
|
-
return FLOAT.
|
|
206
|
+
return FLOAT.resolveContractView(resourceType: Type<@FLOAT.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
|
|
200
207
|
case Type<MetadataViews.NFTCollectionDisplay>():
|
|
201
|
-
return FLOAT.
|
|
208
|
+
return FLOAT.resolveContractView(resourceType: Type<@FLOAT.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
|
|
202
209
|
case Type<MetadataViews.Serial>():
|
|
203
210
|
return MetadataViews.Serial(
|
|
204
211
|
self.serial
|
|
@@ -209,24 +216,37 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
209
216
|
_address: self.owner!.address,
|
|
210
217
|
_serial: self.serial
|
|
211
218
|
)
|
|
212
|
-
case Type<FindViews.SoulBound>():
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
+
// case Type<FindViews.SoulBound>():
|
|
220
|
+
// if self.getEventRef()?.transferrable == false {
|
|
221
|
+
// return FindViews.SoulBound(
|
|
222
|
+
// "This FLOAT is soulbound because the event host toggled off transferring."
|
|
223
|
+
// )
|
|
224
|
+
// }
|
|
225
|
+
// return nil
|
|
219
226
|
case Type<MetadataViews.Traits>():
|
|
220
227
|
let traitsView: MetadataViews.Traits = MetadataViews.dictToTraits(dict: self.getExtraMetadata(), excludedNames: nil)
|
|
221
228
|
|
|
222
|
-
if let eventRef: &FLOATEvent
|
|
229
|
+
if let eventRef: &FLOATEvent = self.getEventRef() {
|
|
223
230
|
let eventExtraMetadata: {String: AnyStruct} = eventRef.getExtraMetadata()
|
|
224
231
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
232
|
+
// certificate type doesn't apply if it's a picture FLOAT
|
|
233
|
+
if FLOAT.extraMetadataToStrOpt(eventExtraMetadata, "visibilityMode") == "certificate" {
|
|
234
|
+
let certificateType: MetadataViews.Trait = MetadataViews.Trait(name: "certificateType", value: eventExtraMetadata["certificateType"], displayType: nil, rarity: nil)
|
|
235
|
+
traitsView.addTrait(certificateType)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let serial: MetadataViews.Trait = MetadataViews.Trait(name: "serial", value: self.serial, displayType: nil, rarity: nil)
|
|
239
|
+
traitsView.addTrait(serial)
|
|
240
|
+
let originalRecipient: MetadataViews.Trait = MetadataViews.Trait(name: "originalRecipient", value: self.originalRecipient, displayType: nil, rarity: nil)
|
|
241
|
+
traitsView.addTrait(originalRecipient)
|
|
242
|
+
let eventCreator: MetadataViews.Trait = MetadataViews.Trait(name: "eventCreator", value: self.eventHost, displayType: nil, rarity: nil)
|
|
243
|
+
traitsView.addTrait(eventCreator)
|
|
228
244
|
let eventType: MetadataViews.Trait = MetadataViews.Trait(name: "eventType", value: eventExtraMetadata["eventType"], displayType: nil, rarity: nil)
|
|
229
245
|
traitsView.addTrait(eventType)
|
|
246
|
+
let dateReceived: MetadataViews.Trait = MetadataViews.Trait(name: "dateMinted", value: self.dateReceived, displayType: "Date", rarity: nil)
|
|
247
|
+
traitsView.addTrait(dateReceived)
|
|
248
|
+
let eventId: MetadataViews.Trait = MetadataViews.Trait(name: "eventId", value: self.eventId, displayType: nil, rarity: nil)
|
|
249
|
+
traitsView.addTrait(eventId)
|
|
230
250
|
}
|
|
231
251
|
|
|
232
252
|
return traitsView
|
|
@@ -247,8 +267,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
247
267
|
self.serial = _serial
|
|
248
268
|
|
|
249
269
|
// Stores a capability to the FLOATEvents of its creator
|
|
250
|
-
self.eventsCap = getAccount(_eventHost)
|
|
251
|
-
.getCapability<&FLOATEvents{FLOATEventsPublic, MetadataViews.ResolverCollection}>(FLOAT.FLOATEventsPublicPath)
|
|
270
|
+
self.eventsCap = getAccount(_eventHost).capabilities.get<&FLOATEvents>(FLOAT.FLOATEventsPublicPath)
|
|
252
271
|
|
|
253
272
|
emit FLOATMinted(
|
|
254
273
|
id: self.id,
|
|
@@ -262,33 +281,22 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
262
281
|
FLOAT.totalSupply = FLOAT.totalSupply + 1
|
|
263
282
|
}
|
|
264
283
|
|
|
265
|
-
destroy() {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// A public interface for people to call into our Collection
|
|
277
|
-
pub resource interface CollectionPublic {
|
|
278
|
-
pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
|
|
279
|
-
pub fun borrowFLOAT(id: UInt64): &NFT?
|
|
280
|
-
pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver}
|
|
281
|
-
pub fun deposit(token: @NonFungibleToken.NFT)
|
|
282
|
-
pub fun getIDs(): [UInt64]
|
|
283
|
-
pub fun getAllIDs(): [UInt64]
|
|
284
|
-
pub fun ownedIdsFromEvent(eventId: UInt64): [UInt64]
|
|
284
|
+
// destroy() {
|
|
285
|
+
// emit FLOATDestroyed(
|
|
286
|
+
// id: self.id,
|
|
287
|
+
// eventHost: self.eventHost,
|
|
288
|
+
// eventId: self.eventId,
|
|
289
|
+
// eventImage: self.eventImage,
|
|
290
|
+
// serial: self.serial
|
|
291
|
+
// )
|
|
292
|
+
// }
|
|
285
293
|
}
|
|
286
294
|
|
|
287
295
|
// A Collection that holds all of the users FLOATs.
|
|
288
296
|
// Withdrawing is not allowed. You can only transfer.
|
|
289
|
-
|
|
297
|
+
access(all) resource Collection: NonFungibleToken.Collection {
|
|
290
298
|
// Maps a FLOAT id to the FLOAT itself
|
|
291
|
-
|
|
299
|
+
access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
|
|
292
300
|
// Maps an eventId to the ids of FLOATs that
|
|
293
301
|
// this user owns from that event. It's possible
|
|
294
302
|
// for it to be out of sync until June 2022 spork,
|
|
@@ -296,7 +304,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
296
304
|
access(self) var events: {UInt64: {UInt64: Bool}}
|
|
297
305
|
|
|
298
306
|
// Deposits a FLOAT to the collection
|
|
299
|
-
|
|
307
|
+
access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
|
|
300
308
|
let nft <- token as! @NFT
|
|
301
309
|
let id = nft.id
|
|
302
310
|
let eventId = nft.eventId
|
|
@@ -309,12 +317,12 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
309
317
|
self.events[eventId]!.insert(key: id, true)
|
|
310
318
|
}
|
|
311
319
|
|
|
312
|
-
emit Deposit(id: id, to: self.owner
|
|
313
|
-
emit FLOATTransferred(id: id, eventHost: nft.eventHost, eventId: nft.eventId, newOwner: self.owner
|
|
320
|
+
emit Deposit(id: id, to: self.owner?.address)
|
|
321
|
+
emit FLOATTransferred(id: id, eventHost: nft.eventHost, eventId: nft.eventId, newOwner: self.owner?.address, serial: nft.serial)
|
|
314
322
|
self.ownedNFTs[id] <-! nft
|
|
315
323
|
}
|
|
316
324
|
|
|
317
|
-
|
|
325
|
+
access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
|
|
318
326
|
let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("You do not own this FLOAT in your collection")
|
|
319
327
|
let nft <- token as! @NFT
|
|
320
328
|
|
|
@@ -326,19 +334,19 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
326
334
|
// FLOAT to be transferrable. Secondary marketplaces will use this
|
|
327
335
|
// withdraw function, so if the FLOAT is not transferrable,
|
|
328
336
|
// you can't sell it there.
|
|
329
|
-
if let floatEvent: &FLOATEvent
|
|
337
|
+
if let floatEvent: &FLOATEvent = nft.getEventRef() {
|
|
330
338
|
assert(
|
|
331
339
|
floatEvent.transferrable,
|
|
332
340
|
message: "This FLOAT is not transferrable."
|
|
333
341
|
)
|
|
334
342
|
}
|
|
335
343
|
|
|
336
|
-
emit Withdraw(id: withdrawID, from: self.owner
|
|
344
|
+
emit Withdraw(id: withdrawID, from: self.owner?.address)
|
|
337
345
|
emit FLOATTransferred(id: withdrawID, eventHost: nft.eventHost, eventId: nft.eventId, newOwner: nil, serial: nft.serial)
|
|
338
346
|
return <- nft
|
|
339
347
|
}
|
|
340
348
|
|
|
341
|
-
|
|
349
|
+
access(NonFungibleToken.Update) fun delete(id: UInt64) {
|
|
342
350
|
let token <- self.ownedNFTs.remove(key: id) ?? panic("You do not own this FLOAT in your collection")
|
|
343
351
|
let nft <- token as! @NFT
|
|
344
352
|
|
|
@@ -351,19 +359,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
351
359
|
|
|
352
360
|
// Only returns the FLOATs for which we can still
|
|
353
361
|
// access data about their event.
|
|
354
|
-
|
|
355
|
-
let ids: [UInt64] = []
|
|
356
|
-
for key in self.ownedNFTs.keys {
|
|
357
|
-
let nftRef = self.borrowFLOAT(id: key)!
|
|
358
|
-
if nftRef.eventsCap.check() {
|
|
359
|
-
ids.append(key)
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
return ids
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Returns all the FLOATs ids
|
|
366
|
-
pub fun getAllIDs(): [UInt64] {
|
|
362
|
+
access(all) view fun getIDs(): [UInt64] {
|
|
367
363
|
return self.ownedNFTs.keys
|
|
368
364
|
}
|
|
369
365
|
|
|
@@ -375,7 +371,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
375
371
|
// from `ownedNFTs` (not possible after June 2022 spork),
|
|
376
372
|
// but this makes sure the returned
|
|
377
373
|
// ids are all actually owned by this account.
|
|
378
|
-
|
|
374
|
+
access(all) fun ownedIdsFromEvent(eventId: UInt64): [UInt64] {
|
|
379
375
|
let answer: [UInt64] = []
|
|
380
376
|
if let idsInEvent = self.events[eventId]?.keys {
|
|
381
377
|
for id in idsInEvent {
|
|
@@ -387,32 +383,53 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
387
383
|
return answer
|
|
388
384
|
}
|
|
389
385
|
|
|
390
|
-
|
|
391
|
-
return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)
|
|
386
|
+
access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
|
|
387
|
+
return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
access(all) view fun getLength(): Int {
|
|
391
|
+
return self.ownedNFTs.keys.length
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
|
|
395
|
+
access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
|
|
396
|
+
let supportedTypes: {Type: Bool} = {}
|
|
397
|
+
supportedTypes[Type<@FLOAT.NFT>()] = true
|
|
398
|
+
return supportedTypes
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/// Returns whether or not the given type is accepted by the collection
|
|
402
|
+
/// A collection that can accept any type should just return true by default
|
|
403
|
+
access(all) view fun isSupportedNFTType(type: Type): Bool {
|
|
404
|
+
if type == Type<@FLOAT.NFT>() {
|
|
405
|
+
return true
|
|
406
|
+
} else {
|
|
407
|
+
return false
|
|
408
|
+
}
|
|
392
409
|
}
|
|
393
410
|
|
|
394
|
-
|
|
395
|
-
if self.ownedNFTs[id]
|
|
396
|
-
|
|
397
|
-
return ref as! &NFT
|
|
411
|
+
access(all) fun borrowFLOAT(id: UInt64): &NFT? {
|
|
412
|
+
if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
|
|
413
|
+
return nft as! &NFT
|
|
398
414
|
}
|
|
399
415
|
return nil
|
|
400
416
|
}
|
|
401
417
|
|
|
402
|
-
|
|
403
|
-
let
|
|
404
|
-
|
|
405
|
-
|
|
418
|
+
access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
|
|
419
|
+
if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
|
|
420
|
+
return nft as &{ViewResolver.Resolver}
|
|
421
|
+
}
|
|
422
|
+
return nil
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
|
|
426
|
+
return <- FLOAT.createEmptyCollection(nftType: Type<@FLOAT.NFT>())
|
|
406
427
|
}
|
|
407
428
|
|
|
408
429
|
init() {
|
|
409
430
|
self.ownedNFTs <- {}
|
|
410
431
|
self.events = {}
|
|
411
432
|
}
|
|
412
|
-
|
|
413
|
-
destroy() {
|
|
414
|
-
destroy self.ownedNFTs
|
|
415
|
-
}
|
|
416
433
|
}
|
|
417
434
|
|
|
418
435
|
// An interface that every "verifier" must implement.
|
|
@@ -420,7 +437,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
420
437
|
// for example, a "time limit," or a "limited" number of
|
|
421
438
|
// FLOATs that can be claimed.
|
|
422
439
|
// All the current verifiers can be seen inside FLOATVerifiers.cdc
|
|
423
|
-
|
|
440
|
+
access(all) struct interface IVerifier {
|
|
424
441
|
// A function every verifier must implement.
|
|
425
442
|
// Will have `assert`s in it to make sure
|
|
426
443
|
// the user fits some criteria.
|
|
@@ -428,60 +445,60 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
428
445
|
}
|
|
429
446
|
|
|
430
447
|
// A public interface to read the FLOATEvent
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
448
|
+
access(all) resource interface FLOATEventPublic {
|
|
449
|
+
access(all) var claimable: Bool
|
|
450
|
+
access(all) let dateCreated: UFix64
|
|
451
|
+
access(all) let description: String
|
|
452
|
+
access(all) let eventId: UInt64
|
|
453
|
+
access(all) let host: Address
|
|
454
|
+
access(all) let image: String
|
|
455
|
+
access(all) let name: String
|
|
456
|
+
access(all) var totalSupply: UInt64
|
|
457
|
+
access(all) var transferrable: Bool
|
|
458
|
+
access(all) let url: String
|
|
459
|
+
|
|
460
|
+
access(all) fun claim(recipient: &Collection, params: {String: AnyStruct})
|
|
461
|
+
access(all) fun purchase(recipient: &Collection, params: {String: AnyStruct}, payment: @{FungibleToken.Vault})
|
|
462
|
+
|
|
463
|
+
access(all) fun getExtraMetadata(): {String: AnyStruct}
|
|
464
|
+
access(all) fun getSpecificExtraMetadata(key: String): AnyStruct?
|
|
465
|
+
access(all) fun getVerifiers(): {String: [{IVerifier}]}
|
|
466
|
+
access(all) fun getPrices(): {String: TokenInfo}?
|
|
467
|
+
access(all) fun getExtraFloatMetadata(serial: UInt64): {String: AnyStruct}
|
|
468
|
+
access(all) fun getSpecificExtraFloatMetadata(serial: UInt64, key: String): AnyStruct?
|
|
469
|
+
access(all) fun getClaims(): {UInt64: TokenIdentifier}
|
|
470
|
+
access(all) fun getSerialsUserClaimed(address: Address): [UInt64]
|
|
471
|
+
access(all) fun userHasClaimed(address: Address): Bool
|
|
472
|
+
access(all) fun userCanMint(address: Address): Bool
|
|
456
473
|
}
|
|
457
474
|
|
|
458
475
|
//
|
|
459
476
|
// FLOATEvent
|
|
460
477
|
//
|
|
461
|
-
|
|
478
|
+
access(all) resource FLOATEvent {
|
|
462
479
|
// Whether or not users can claim from our event (can be toggled
|
|
463
480
|
// at any time)
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
481
|
+
access(all) var claimable: Bool
|
|
482
|
+
access(all) let dateCreated: UFix64
|
|
483
|
+
access(all) let description: String
|
|
467
484
|
// This is equal to this resource's uuid
|
|
468
|
-
|
|
485
|
+
access(all) let eventId: UInt64
|
|
469
486
|
// Who created this FLOAT Event
|
|
470
|
-
|
|
487
|
+
access(all) let host: Address
|
|
471
488
|
// The image of the FLOAT Event
|
|
472
|
-
|
|
489
|
+
access(all) let image: String
|
|
473
490
|
// The name of the FLOAT Event
|
|
474
|
-
|
|
491
|
+
access(all) let name: String
|
|
475
492
|
// The total number of FLOATs that have been
|
|
476
493
|
// minted from this event
|
|
477
|
-
|
|
494
|
+
access(all) var totalSupply: UInt64
|
|
478
495
|
// Whether or not the FLOATs that users own
|
|
479
496
|
// from this event can be transferred on the
|
|
480
497
|
// FLOAT platform itself (transferring allowed
|
|
481
498
|
// elsewhere)
|
|
482
|
-
|
|
499
|
+
access(all) var transferrable: Bool
|
|
483
500
|
// A url of where the event took place
|
|
484
|
-
|
|
501
|
+
access(all) let url: String
|
|
485
502
|
// A list of verifiers this FLOAT Event contains.
|
|
486
503
|
// Will be used every time someone "claims" a FLOAT
|
|
487
504
|
// to see if they pass the requirements
|
|
@@ -499,19 +516,19 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
499
516
|
access(self) var groups: {String: Bool}
|
|
500
517
|
|
|
501
518
|
// Type: Admin Toggle
|
|
502
|
-
|
|
519
|
+
access(EventOwner) fun toggleClaimable(): Bool {
|
|
503
520
|
self.claimable = !self.claimable
|
|
504
521
|
return self.claimable
|
|
505
522
|
}
|
|
506
523
|
|
|
507
524
|
// Type: Admin Toggle
|
|
508
|
-
|
|
525
|
+
access(EventOwner) fun toggleTransferrable(): Bool {
|
|
509
526
|
self.transferrable = !self.transferrable
|
|
510
527
|
return self.transferrable
|
|
511
528
|
}
|
|
512
529
|
|
|
513
530
|
// Type: Admin Toggle
|
|
514
|
-
|
|
531
|
+
access(EventOwner) fun toggleVisibilityMode() {
|
|
515
532
|
if let currentVisibilityMode: String = FLOAT.extraMetadataToStrOpt(self.getExtraMetadata(), "visibilityMode") {
|
|
516
533
|
if currentVisibilityMode == "certificate" {
|
|
517
534
|
self.extraMetadata["visibilityMode"] = "picture"
|
|
@@ -529,11 +546,12 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
529
546
|
let userClaims: {Address: [UInt64]} = {}
|
|
530
547
|
self.extraMetadata["userClaims"] = userClaims
|
|
531
548
|
}
|
|
532
|
-
let e = (&self.extraMetadata["userClaims"] as auth &AnyStruct?)!
|
|
533
|
-
let claims = e as! &{Address: [UInt64]}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
549
|
+
let e = (&self.extraMetadata["userClaims"] as auth(Mutate) &AnyStruct?)!
|
|
550
|
+
let claims = e as! auth(Mutate) &{Address: [UInt64]}
|
|
551
|
+
let claimsByAddress = claims[address] as! auth(Mutate) &[UInt64]?
|
|
552
|
+
|
|
553
|
+
if let specificUserClaims: auth(Mutate) &[UInt64] = claimsByAddress {
|
|
554
|
+
specificUserClaims.append(serial)
|
|
537
555
|
} else {
|
|
538
556
|
claims[address] = [serial]
|
|
539
557
|
}
|
|
@@ -545,8 +563,8 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
545
563
|
let extraFloatMetadatas: {UInt64: AnyStruct} = {}
|
|
546
564
|
self.extraMetadata["extraFloatMetadatas"] = extraFloatMetadatas
|
|
547
565
|
}
|
|
548
|
-
let e = (&self.extraMetadata["extraFloatMetadatas"] as auth
|
|
549
|
-
let extraFloatMetadatas = e as! &{UInt64: AnyStruct}
|
|
566
|
+
let e = (&self.extraMetadata["extraFloatMetadatas"] as auth(Mutate)&AnyStruct?)!
|
|
567
|
+
let extraFloatMetadatas = e as! auth(Mutate) &{UInt64: AnyStruct}
|
|
550
568
|
extraFloatMetadatas[serial] = metadata
|
|
551
569
|
}
|
|
552
570
|
|
|
@@ -556,22 +574,22 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
556
574
|
let extraFloatMetadatas: {UInt64: AnyStruct} = {}
|
|
557
575
|
self.extraMetadata["extraFloatMetadatas"] = extraFloatMetadatas
|
|
558
576
|
}
|
|
559
|
-
let e = (&self.extraMetadata["extraFloatMetadatas"] as auth &AnyStruct?)!
|
|
560
|
-
let extraFloatMetadatas = e as! &{UInt64: AnyStruct}
|
|
577
|
+
let e = (&self.extraMetadata["extraFloatMetadatas"] as auth(Mutate) &AnyStruct?)!
|
|
578
|
+
let extraFloatMetadatas = e as! auth(Mutate) &{UInt64: AnyStruct}
|
|
561
579
|
|
|
562
580
|
if extraFloatMetadatas[serial] == nil {
|
|
563
581
|
let extraFloatMetadata: {String: AnyStruct} = {}
|
|
564
582
|
extraFloatMetadatas[serial] = extraFloatMetadata
|
|
565
583
|
}
|
|
566
584
|
|
|
567
|
-
let f = (
|
|
568
|
-
let extraFloatMetadata = e as! &{String: AnyStruct}
|
|
585
|
+
let f = (extraFloatMetadatas[serial] as! auth(Mutate) &AnyStruct?)!
|
|
586
|
+
let extraFloatMetadata = e as! auth(Mutate) &{String: AnyStruct}
|
|
569
587
|
extraFloatMetadata[key] = value
|
|
570
588
|
}
|
|
571
589
|
|
|
572
590
|
// Type: Getter
|
|
573
591
|
// Description: Get extra metadata on a specific FLOAT from this event
|
|
574
|
-
|
|
592
|
+
access(all) view fun getExtraFloatMetadata(serial: UInt64): {String: AnyStruct} {
|
|
575
593
|
if self.extraMetadata["extraFloatMetadatas"] != nil {
|
|
576
594
|
if let e: {UInt64: AnyStruct} = self.extraMetadata["extraFloatMetadatas"]! as? {UInt64: AnyStruct} {
|
|
577
595
|
if e[serial] != nil {
|
|
@@ -586,13 +604,13 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
586
604
|
|
|
587
605
|
// Type: Getter
|
|
588
606
|
// Description: Get specific extra metadata on a specific FLOAT from this event
|
|
589
|
-
|
|
607
|
+
access(all) view fun getSpecificExtraFloatMetadata(serial: UInt64, key: String): AnyStruct? {
|
|
590
608
|
return self.getExtraFloatMetadata(serial: serial)[key]
|
|
591
609
|
}
|
|
592
610
|
|
|
593
611
|
// Type: Getter
|
|
594
612
|
// Description: Returns claim info of all the serials
|
|
595
|
-
|
|
613
|
+
access(all) view fun getClaims(): {UInt64: TokenIdentifier} {
|
|
596
614
|
return self.currentHolders
|
|
597
615
|
}
|
|
598
616
|
|
|
@@ -600,14 +618,14 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
600
618
|
// Description: Will return an array of all the serials a user claimed.
|
|
601
619
|
// Most of the time this will be a maximum length of 1 because most
|
|
602
620
|
// events only allow 1 claim per user.
|
|
603
|
-
|
|
621
|
+
access(all) view fun getSerialsUserClaimed(address: Address): [UInt64] {
|
|
604
622
|
var serials: [UInt64] = []
|
|
605
623
|
if let userClaims: {Address: [UInt64]} = self.getSpecificExtraMetadata(key: "userClaims") as! {Address: [UInt64]}? {
|
|
606
624
|
serials = userClaims[address] ?? []
|
|
607
625
|
}
|
|
608
626
|
// take into account claims during FLOATv1
|
|
609
627
|
if let oldClaim: TokenIdentifier = self.claimed[address] {
|
|
610
|
-
serials.
|
|
628
|
+
serials = serials.concat([oldClaim.serial])
|
|
611
629
|
}
|
|
612
630
|
return serials
|
|
613
631
|
}
|
|
@@ -615,37 +633,37 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
615
633
|
// Type: Getter
|
|
616
634
|
// Description: Returns true if the user has either claimed
|
|
617
635
|
// or been minted at least one float from this event
|
|
618
|
-
|
|
636
|
+
access(all) view fun userHasClaimed(address: Address): Bool {
|
|
619
637
|
return self.getSerialsUserClaimed(address: address).length >= 1
|
|
620
638
|
}
|
|
621
639
|
|
|
622
640
|
// Type: Getter
|
|
623
641
|
// Description: Get extra metadata on this event
|
|
624
|
-
|
|
642
|
+
access(all) view fun getExtraMetadata(): {String: AnyStruct} {
|
|
625
643
|
return self.extraMetadata
|
|
626
644
|
}
|
|
627
645
|
|
|
628
646
|
// Type: Getter
|
|
629
647
|
// Description: Get specific extra metadata on this event
|
|
630
|
-
|
|
648
|
+
access(all) view fun getSpecificExtraMetadata(key: String): AnyStruct? {
|
|
631
649
|
return self.extraMetadata[key]
|
|
632
650
|
}
|
|
633
651
|
|
|
634
652
|
// Type: Getter
|
|
635
653
|
// Description: Checks if a user can mint a new FLOAT from this event
|
|
636
|
-
|
|
654
|
+
access(all) view fun userCanMint(address: Address): Bool {
|
|
637
655
|
if let allows: Bool = self.getSpecificExtraMetadata(key: "allowMultipleClaim") as! Bool? {
|
|
638
656
|
if allows || self.getSerialsUserClaimed(address: address).length == 0 {
|
|
639
657
|
return true
|
|
640
658
|
}
|
|
641
659
|
}
|
|
642
|
-
return
|
|
660
|
+
return !self.userHasClaimed(address: address)
|
|
643
661
|
}
|
|
644
662
|
|
|
645
663
|
// Type: Getter
|
|
646
664
|
// Description: Gets all the verifiers that will be used
|
|
647
665
|
// for claiming
|
|
648
|
-
|
|
666
|
+
access(all) view fun getVerifiers(): {String: [{IVerifier}]} {
|
|
649
667
|
return self.verifiers
|
|
650
668
|
}
|
|
651
669
|
|
|
@@ -653,13 +671,13 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
653
671
|
// Description: Returns a dictionary whose key is a token identifier
|
|
654
672
|
// and value is the path to that token and price of the FLOAT in that
|
|
655
673
|
// currency
|
|
656
|
-
|
|
674
|
+
access(all) view fun getPrices(): {String: TokenInfo}? {
|
|
657
675
|
return self.extraMetadata["prices"] as! {String: TokenInfo}?
|
|
658
676
|
}
|
|
659
677
|
|
|
660
678
|
// Type: Getter
|
|
661
679
|
// Description: For MetadataViews
|
|
662
|
-
|
|
680
|
+
access(all) view fun getViews(): [Type] {
|
|
663
681
|
return [
|
|
664
682
|
Type<MetadataViews.Display>()
|
|
665
683
|
]
|
|
@@ -667,7 +685,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
667
685
|
|
|
668
686
|
// Type: Getter
|
|
669
687
|
// Description: For MetadataViews
|
|
670
|
-
|
|
688
|
+
access(all) view fun resolveView(_ view: Type): AnyStruct? {
|
|
671
689
|
switch view {
|
|
672
690
|
case Type<MetadataViews.Display>():
|
|
673
691
|
return MetadataViews.Display(
|
|
@@ -685,7 +703,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
685
703
|
// If the event owner directly mints to a user, it does not
|
|
686
704
|
// run the verifiers on the user. It bypasses all of them.
|
|
687
705
|
// Return the id of the FLOAT it minted.
|
|
688
|
-
|
|
706
|
+
access(EventOwner) fun mint(recipient: &Collection, optExtraFloatMetadata: {String: AnyStruct}?): UInt64 {
|
|
689
707
|
pre {
|
|
690
708
|
self.userCanMint(address: recipient.owner!.address): "Only 1 FLOAT allowed per user, and this user already claimed their FLOAT!"
|
|
691
709
|
}
|
|
@@ -724,7 +742,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
724
742
|
// Description: Will get run by the public, so verifies
|
|
725
743
|
// the user can mint
|
|
726
744
|
access(self) fun verifyAndMint(recipient: &Collection, params: {String: AnyStruct}): UInt64 {
|
|
727
|
-
params["event"] = &self as &FLOATEvent
|
|
745
|
+
params["event"] = &self as &FLOATEvent
|
|
728
746
|
params["claimee"] = recipient.owner!.address
|
|
729
747
|
|
|
730
748
|
// Runs a loop over all the verifiers that this FLOAT Events
|
|
@@ -734,7 +752,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
734
752
|
let typedModules = (&self.verifiers[identifier] as &[{IVerifier}]?)!
|
|
735
753
|
var i = 0
|
|
736
754
|
while i < typedModules.length {
|
|
737
|
-
let verifier =
|
|
755
|
+
let verifier = typedModules[i]
|
|
738
756
|
verifier.verify(params)
|
|
739
757
|
i = i + 1
|
|
740
758
|
}
|
|
@@ -768,7 +786,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
768
786
|
// For example, the FLOAT platform allows event hosts
|
|
769
787
|
// to specify a secret phrase. That secret phrase will
|
|
770
788
|
// be passed in the `params`.
|
|
771
|
-
|
|
789
|
+
access(all) fun claim(recipient: &Collection, params: {String: AnyStruct}) {
|
|
772
790
|
pre {
|
|
773
791
|
self.getPrices() == nil:
|
|
774
792
|
"You need to purchase this FLOAT."
|
|
@@ -779,7 +797,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
779
797
|
self.verifyAndMint(recipient: recipient, params: params)
|
|
780
798
|
}
|
|
781
799
|
|
|
782
|
-
|
|
800
|
+
access(all) fun purchase(recipient: &Collection, params: {String: AnyStruct}, payment: @{FungibleToken.Vault}) {
|
|
783
801
|
pre {
|
|
784
802
|
self.getPrices() != nil:
|
|
785
803
|
"Don't call this function. The FLOAT is free. Call the claim function instead."
|
|
@@ -795,8 +813,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
795
813
|
let paymentType: String = payment.getType().identifier
|
|
796
814
|
let tokenInfo: TokenInfo = self.getPrices()![paymentType]!
|
|
797
815
|
|
|
798
|
-
let EventHostVault = getAccount(self.host).
|
|
799
|
-
.borrow<&{FungibleToken.Receiver}>()
|
|
816
|
+
let EventHostVault = getAccount(self.host).capabilities.borrow<&{FungibleToken.Receiver}>(tokenInfo.path)
|
|
800
817
|
?? panic("Could not borrow the &{FungibleToken.Receiver} from the event host.")
|
|
801
818
|
|
|
802
819
|
assert(
|
|
@@ -804,8 +821,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
804
821
|
message: "The event host's path is not associated with the intended token."
|
|
805
822
|
)
|
|
806
823
|
|
|
807
|
-
let EmeraldCityVault = getAccount(emeraldCityTreasury).
|
|
808
|
-
.borrow<&{FungibleToken.Receiver}>()
|
|
824
|
+
let EmeraldCityVault = getAccount(emeraldCityTreasury).capabilities.borrow<&{FungibleToken.Receiver}>(tokenInfo.path)
|
|
809
825
|
?? panic("Could not borrow the &{FungibleToken.Receiver} from Emerald City's Vault.")
|
|
810
826
|
|
|
811
827
|
assert(
|
|
@@ -854,17 +870,17 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
854
870
|
emit FLOATEventCreated(eventId: self.eventId, description: self.description, host: self.host, image: self.image, name: self.name, url: self.url)
|
|
855
871
|
}
|
|
856
872
|
|
|
857
|
-
destroy() {
|
|
858
|
-
|
|
859
|
-
}
|
|
873
|
+
// destroy() {
|
|
874
|
+
// emit FLOATEventDestroyed(eventId: self.eventId, host: self.host, name: self.name)
|
|
875
|
+
// }
|
|
860
876
|
}
|
|
861
877
|
|
|
862
878
|
// DEPRECATED
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
879
|
+
access(all) resource Group {
|
|
880
|
+
access(all) let id: UInt64
|
|
881
|
+
access(all) let name: String
|
|
882
|
+
access(all) let image: String
|
|
883
|
+
access(all) let description: String
|
|
868
884
|
access(self) var events: {UInt64: Bool}
|
|
869
885
|
init() {
|
|
870
886
|
self.id = 0
|
|
@@ -878,16 +894,9 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
878
894
|
//
|
|
879
895
|
// FLOATEvents
|
|
880
896
|
//
|
|
881
|
-
pub resource interface FLOATEventsPublic {
|
|
882
|
-
// Public Getters
|
|
883
|
-
pub fun borrowPublicEventRef(eventId: UInt64): &FLOATEvent{FLOATEventPublic}?
|
|
884
|
-
pub fun getAllEvents(): {UInt64: String}
|
|
885
|
-
pub fun getIDs(): [UInt64]
|
|
886
|
-
pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver}
|
|
887
|
-
}
|
|
888
897
|
|
|
889
898
|
// A "Collection" of FLOAT Events
|
|
890
|
-
|
|
899
|
+
access(all) resource FLOATEvents {
|
|
891
900
|
// All the FLOAT Events this collection stores
|
|
892
901
|
access(self) var events: @{UInt64: FLOATEvent}
|
|
893
902
|
// DEPRECATED
|
|
@@ -913,7 +922,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
913
922
|
// certificateImage: Must either be nil or a String type
|
|
914
923
|
// backImage: The IPFS CID of what will display on the back of your FLOAT. Must either be nil or a String type
|
|
915
924
|
// eventType: Must either be nil or a String type
|
|
916
|
-
|
|
925
|
+
access(EventsOwner) fun createEvent(
|
|
917
926
|
claimable: Bool,
|
|
918
927
|
description: String,
|
|
919
928
|
image: String,
|
|
@@ -938,7 +947,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
938
947
|
|
|
939
948
|
let typedVerifiers: {String: [{IVerifier}]} = {}
|
|
940
949
|
for verifier in verifiers {
|
|
941
|
-
let identifier = verifier.getType().identifier
|
|
950
|
+
let identifier: String = verifier.getType().identifier
|
|
942
951
|
if typedVerifiers[identifier] == nil {
|
|
943
952
|
typedVerifiers[identifier] = [verifier]
|
|
944
953
|
} else {
|
|
@@ -961,35 +970,35 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
961
970
|
_url: url,
|
|
962
971
|
_verifiers: typedVerifiers
|
|
963
972
|
)
|
|
964
|
-
let eventId = FLOATEvent.eventId
|
|
973
|
+
let eventId: UInt64 = FLOATEvent.eventId
|
|
965
974
|
self.events[eventId] <-! FLOATEvent
|
|
966
975
|
|
|
967
976
|
return eventId
|
|
968
977
|
}
|
|
969
978
|
|
|
970
979
|
// Deletes an event.
|
|
971
|
-
|
|
980
|
+
access(EventsOwner) fun deleteEvent(eventId: UInt64) {
|
|
972
981
|
let eventRef = self.borrowEventRef(eventId: eventId) ?? panic("This FLOAT does not exist.")
|
|
973
982
|
destroy self.events.remove(key: eventId)
|
|
974
983
|
}
|
|
975
984
|
|
|
976
|
-
|
|
977
|
-
return &self.events[eventId]
|
|
985
|
+
access(EventsOwner) fun borrowEventRef(eventId: UInt64): auth(EventOwner) &FLOATEvent? {
|
|
986
|
+
return &self.events[eventId]
|
|
978
987
|
}
|
|
979
988
|
|
|
980
989
|
// Get a public reference to the FLOATEvent
|
|
981
990
|
// so you can call some helpful getters
|
|
982
|
-
|
|
983
|
-
return &self.events[eventId] as &FLOATEvent
|
|
991
|
+
access(all) fun borrowPublicEventRef(eventId: UInt64): &FLOATEvent? {
|
|
992
|
+
return &self.events[eventId] as &FLOATEvent?
|
|
984
993
|
}
|
|
985
994
|
|
|
986
|
-
|
|
995
|
+
access(all) fun getIDs(): [UInt64] {
|
|
987
996
|
return self.events.keys
|
|
988
997
|
}
|
|
989
998
|
|
|
990
999
|
// Maps the eventId to the name of that
|
|
991
1000
|
// event. Just a kind helper.
|
|
992
|
-
|
|
1001
|
+
access(all) fun getAllEvents(): {UInt64: String} {
|
|
993
1002
|
let answer: {UInt64: String} = {}
|
|
994
1003
|
for id in self.events.keys {
|
|
995
1004
|
let ref = (&self.events[id] as &FLOATEvent?)!
|
|
@@ -998,32 +1007,23 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
998
1007
|
return answer
|
|
999
1008
|
}
|
|
1000
1009
|
|
|
1001
|
-
pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver} {
|
|
1002
|
-
return (&self.events[id] as &{MetadataViews.Resolver}?)!
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
1010
|
init() {
|
|
1006
1011
|
self.events <- {}
|
|
1007
1012
|
self.groups <- {}
|
|
1008
1013
|
}
|
|
1009
|
-
|
|
1010
|
-
destroy() {
|
|
1011
|
-
destroy self.events
|
|
1012
|
-
destroy self.groups
|
|
1013
|
-
}
|
|
1014
1014
|
}
|
|
1015
1015
|
|
|
1016
|
-
|
|
1016
|
+
access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
|
|
1017
1017
|
return <- create Collection()
|
|
1018
1018
|
}
|
|
1019
1019
|
|
|
1020
|
-
|
|
1020
|
+
access(all) fun createEmptyFLOATEventCollection(): @FLOATEvents {
|
|
1021
1021
|
return <- create FLOATEvents()
|
|
1022
1022
|
}
|
|
1023
1023
|
|
|
1024
1024
|
// A function to validate expected FLOAT metadata that must be in a
|
|
1025
1025
|
// certain format as to not cause aborts during expected casting
|
|
1026
|
-
|
|
1026
|
+
access(all) fun validateExtraFloatMetadata(data: {String: AnyStruct}): Bool {
|
|
1027
1027
|
if data.containsKey("medalType") {
|
|
1028
1028
|
let medalType: String? = FLOAT.extraMetadataToStrOpt(data, "medalType")
|
|
1029
1029
|
if medalType == nil || (medalType != "gold" && medalType != "silver" && medalType != "bronze" && medalType != "participation") {
|
|
@@ -1044,7 +1044,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1044
1044
|
// So we force unwrap due to the dictionary, then unwrap the value within.
|
|
1045
1045
|
// It will never abort because we have checked for nil above, which checks
|
|
1046
1046
|
// for both types of nil.
|
|
1047
|
-
|
|
1047
|
+
access(all) fun extraMetadataToStrOpt(_ dict: {String: AnyStruct}, _ key: String): String? {
|
|
1048
1048
|
// `dict[key] == nil` means:
|
|
1049
1049
|
// 1. the key doesn't exist
|
|
1050
1050
|
// 2. the value for the key is nil
|
|
@@ -1059,7 +1059,7 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1059
1059
|
/// @return An array of Types defining the implemented views. This value will be used by
|
|
1060
1060
|
/// developers to know which parameter to pass to the resolveView() method.
|
|
1061
1061
|
///
|
|
1062
|
-
|
|
1062
|
+
access(all) fun getViews(): [Type] {
|
|
1063
1063
|
return [
|
|
1064
1064
|
Type<MetadataViews.NFTCollectionData>(),
|
|
1065
1065
|
Type<MetadataViews.NFTCollectionDisplay>()
|
|
@@ -1071,18 +1071,16 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1071
1071
|
/// @param view: The Type of the desired view.
|
|
1072
1072
|
/// @return A structure representing the requested view.
|
|
1073
1073
|
///
|
|
1074
|
-
|
|
1075
|
-
switch
|
|
1074
|
+
access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
|
|
1075
|
+
switch viewType {
|
|
1076
1076
|
case Type<MetadataViews.NFTCollectionData>():
|
|
1077
1077
|
return MetadataViews.NFTCollectionData(
|
|
1078
1078
|
storagePath: FLOAT.FLOATCollectionStoragePath,
|
|
1079
1079
|
publicPath: FLOAT.FLOATCollectionPublicPath,
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
|
|
1085
|
-
return <- FLOAT.createEmptyCollection()
|
|
1080
|
+
publicCollection: Type<&Collection>(),
|
|
1081
|
+
publicLinkedType: Type<&Collection>(),
|
|
1082
|
+
createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
|
|
1083
|
+
return <- FLOAT.createEmptyCollection(nftType: Type<@FLOAT.NFT>())
|
|
1086
1084
|
})
|
|
1087
1085
|
)
|
|
1088
1086
|
case Type<MetadataViews.NFTCollectionDisplay>():
|
|
@@ -1113,6 +1111,13 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1113
1111
|
return nil
|
|
1114
1112
|
}
|
|
1115
1113
|
|
|
1114
|
+
access(all) view fun getContractViews(resourceType: Type?): [Type] {
|
|
1115
|
+
return [
|
|
1116
|
+
Type<MetadataViews.NFTCollectionData>(),
|
|
1117
|
+
Type<MetadataViews.NFTCollectionDisplay>()
|
|
1118
|
+
]
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1116
1121
|
init() {
|
|
1117
1122
|
self.totalSupply = 0
|
|
1118
1123
|
self.totalFLOATEvents = 0
|
|
@@ -1126,19 +1131,19 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1126
1131
|
|
|
1127
1132
|
// delete later
|
|
1128
1133
|
|
|
1129
|
-
if self.account.borrow<&FLOAT.Collection>(from: FLOAT.FLOATCollectionStoragePath) == nil {
|
|
1130
|
-
self.account.save(<-
|
|
1131
|
-
self.account.
|
|
1132
|
-
|
|
1134
|
+
if self.account.storage.borrow<&FLOAT.Collection>(from: FLOAT.FLOATCollectionStoragePath) == nil {
|
|
1135
|
+
self.account.storage.save(<- create Collection(), to: FLOAT.FLOATCollectionStoragePath)
|
|
1136
|
+
let collectionCap = self.account.capabilities.storage.issue<&FLOAT.Collection>(FLOAT.FLOATCollectionStoragePath)
|
|
1137
|
+
self.account.capabilities.publish(collectionCap, at: FLOAT.FLOATCollectionPublicPath)
|
|
1133
1138
|
}
|
|
1134
1139
|
|
|
1135
|
-
if self.account.borrow<&FLOAT.FLOATEvents>(from: FLOAT.FLOATEventsStoragePath) == nil {
|
|
1136
|
-
self.account.save(<- FLOAT.createEmptyFLOATEventCollection(), to: FLOAT.FLOATEventsStoragePath)
|
|
1137
|
-
self.account.
|
|
1138
|
-
|
|
1140
|
+
if self.account.storage.borrow<&FLOAT.FLOATEvents>(from: FLOAT.FLOATEventsStoragePath) == nil {
|
|
1141
|
+
self.account.storage.save(<- FLOAT.createEmptyFLOATEventCollection(), to: FLOAT.FLOATEventsStoragePath)
|
|
1142
|
+
let eventsCap = self.account.capabilities.storage.issue<&FLOAT.FLOATEvents>(FLOAT.FLOATEventsStoragePath)
|
|
1143
|
+
self.account.capabilities.publish(eventsCap, at: FLOAT.FLOATEventsPublicPath)
|
|
1139
1144
|
}
|
|
1140
1145
|
|
|
1141
|
-
let FLOATEvents = self.account.borrow
|
|
1146
|
+
let FLOATEvents = self.account.storage.borrow<auth(EventsOwner) &FLOAT.FLOATEvents>(from: FLOAT.FLOATEventsStoragePath)
|
|
1142
1147
|
?? panic("Could not borrow the FLOATEvents from the signer.")
|
|
1143
1148
|
|
|
1144
1149
|
var verifiers: [{FLOAT.IVerifier}] = []
|
|
@@ -1158,4 +1163,4 @@ pub contract FLOAT: NonFungibleToken, ViewResolver {
|
|
|
1158
1163
|
FLOATEvents.createEvent(claimable: true, description: "Test description for a Discord meeting. This is soooo fun! Woohoo!", image: "bafybeifpsnwb2vkz4p6nxhgsbwgyslmlfd7jyicx5ukbj3tp7qsz7myzrq", name: "Discord Meeting", transferrable: true, url: "", verifiers: verifiers, allowMultipleClaim: false, certificateType: "ticket", visibilityMode: "picture", extraMetadata: extraMetadata)
|
|
1159
1164
|
}
|
|
1160
1165
|
}
|
|
1161
|
-
|
|
1166
|
+
|