Smart Contract
AeraNFT
A.30cf5dcf6ea8d379.AeraNFT
1import NonFungibleToken from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import FungibleToken from 0xf233dcee88fe0abe
5import FindViews from 0x097bafa4e0b48eef
6
7
8access(all)
9contract AeraNFT: NonFungibleToken{
10
11 access(all) entitlement Owner
12
13 access(all)
14 var totalSupply: UInt64
15
16 access(all)
17 event ContractInitialized()
18
19 access(all)
20 event Withdraw(id: UInt64, from: Address?)
21
22 access(all)
23 event Deposit(id: UInt64, to: Address?)
24
25 access(all)
26 event Minted(id: UInt64, address: Address)
27
28 access(all)
29 event Burned(id: UInt64, from: Address?, playId: UInt64, edition: UInt64)
30
31 access(all)
32 let CollectionStoragePath: StoragePath
33
34 access(all)
35 let CollectionPublicPath: PublicPath
36
37 access(all)
38 let CollectionPrivatePath: PrivatePath
39
40 access(all)
41 resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver{
42 access(all)
43 let id: UInt64
44
45 access(all)
46 var nounce: UInt64
47
48 access(all)
49 let play: Play
50
51 access(all)
52 let edition: UInt64
53
54 access(all)
55 let badges:{ UInt64: Badge}
56
57 init(play: Play, edition: UInt64){
58 self.nounce = 0
59 self.id = self.uuid
60 self.play = play
61 self.edition = edition
62 self.badges ={}
63 }
64
65 access(account)
66 fun addBadge(_ badge: Badge){
67 self.badges[badge.id] = badge
68 }
69
70 access(all)
71 view fun getViews(): [Type]{
72 let views = [Type<MetadataViews.Display>(), Type<License>(), Type<MetadataViews.Editions>(), Type<MetadataViews.Medias>(), Type<MetadataViews.Rarity>(), Type<MetadataViews.NFTCollectionData>(), Type<MetadataViews.NFTCollectionDisplay>(), Type<MetadataViews.Traits>(), Type<MetadataViews.ExternalURL>(), Type<MetadataViews.Royalties>(), Type<Play>()]
73
74 return views
75 }
76
77 access(all)
78 view fun isSoulBound(): Bool{
79 return self.badges[1] != nil && (self.badges[1]!).name == "soulbound"
80 }
81
82 access(all)
83 fun resolveView(_ view: Type): AnyStruct?{
84 let play = self.play
85 switch view {
86 case Type<FindViews.SoulBound>():
87 if self.isSoulBound(){
88 return FindViews.SoulBound("This NFT cannot be traded, it is soulbound")
89 }
90 return nil
91 case Type<Play>():
92 return play
93 case Type<License>():
94 if let licence = play.getLicenseID(){
95 return AeraNFT.getLicense(licence)!
96 } else{
97 return nil
98 }
99 case Type<MetadataViews.NFTCollectionData>():
100 return MetadataViews.NFTCollectionData(storagePath: AeraNFT.CollectionStoragePath, publicPath: AeraNFT.CollectionPublicPath, publicCollection: Type<&AeraNFT.Collection>(), publicLinkedType: Type<&AeraNFT.Collection>(), createEmptyCollectionFunction: fun (): @{NonFungibleToken.Collection}{
101 return <-AeraNFT.createEmptyCollection(nftType: Type<@AeraNFT.Collection>())
102 })
103 case Type<MetadataViews.NFTCollectionDisplay>():
104 let externalURL = MetadataViews.ExternalURL("http://aera.onefootbal.com")
105 let squareImage = MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://miro.medium.com/fit/c/176/176/1*hzfP51MATg3et5vghYy1uQ.png"), mediaType: "image/png")
106 let bannerImage = MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://bafybeiaaf7bfbppep5ahb2m75xlmxyj76hxo3oh5dcl4prxeskruwpe6c4.ipfs.nftstorage.link/"), mediaType: "image/png")
107 let socialMap:{ String: MetadataViews.ExternalURL} ={ "twitter": MetadataViews.ExternalURL("https://twitter.com/aera_football"), "discord": MetadataViews.ExternalURL("https://discord.gg/aera"), "instagram": MetadataViews.ExternalURL("https://www.instagram.com/aera_football/")}
108 return MetadataViews.NFTCollectionDisplay(name: "Aera", description: "Aera by OneFootball", externalURL: externalURL, squareImage: squareImage, bannerImage: bannerImage, socials: socialMap)
109 case Type<MetadataViews.Display>():
110 return play.asDisplay()
111 case Type<MetadataViews.Medias>():
112 return play.getMedias()
113 case Type<MetadataViews.Editions>():
114 return MetadataViews.Editions([MetadataViews.Edition(name: "play", number: self.edition, max: play.maxSerial)])
115 case Type<MetadataViews.Rarity>():
116 var rarity: UFix64 = 0.0
117 switch play.rarity{
118 case "Common":
119 rarity = 1.0
120 case "Rare":
121 rarity = 2.0
122 case "Epic":
123 rarity = 3.0
124 case "Legendary":
125 rarity = 4.0
126 }
127 return MetadataViews.Rarity(score: rarity, max: nil, description: play.rarity)
128 case Type<MetadataViews.Traits>():
129 let traits = play.getTraits()
130 for badgeID in self.badges.keys{
131 let badge = self.badges[badgeID]!
132 let value = badge.name!
133 traits.append(MetadataViews.Trait(name: "badge_".concat(badge.name!), value: value, displayType: "String", rarity: badge.rarity))
134 }
135 return MetadataViews.Traits(traits)
136 case Type<MetadataViews.Royalties>():
137 var address = AeraNFT.account.address
138 if address == 0x46625f59708ec2f8{
139 //testnet merchant address
140 address = 0x4ff956c78244911b
141 } else if address == 0x30cf5dcf6ea8d379{
142 //mainnet merchant address
143 address = 0xa9277dcbec7769df
144 }
145 let ducReceiver = getAccount(address).capabilities.get<&{FungibleToken.Receiver}>(/public/dapperUtilityCoinReceiver)
146 return MetadataViews.Royalties([MetadataViews.Royalty(receiver: ducReceiver!, cut: 0.06, description: "onefootball largest of 6% or 0.65")])
147
148 }
149 return nil
150 }
151
152 access(contract)
153 fun increaseNounce(){
154 self.nounce = self.nounce + 1
155 }
156
157 access(all)
158 fun createEmptyCollection(): @{NonFungibleToken.Collection}{
159 return <-create Collection()
160 }
161 }
162
163 access(all)
164 struct Badge{
165 access(all)
166 let id: UInt64
167
168 access(all)
169 let name: String?
170
171 access(all)
172 let description: String?
173
174 access(all)
175 let rarity: MetadataViews.Rarity?
176
177 init(id: UInt64, name: String?, description: String?, rarity: MetadataViews.Rarity?){
178 self.id = id
179 self.name = name
180 self.description = description
181 self.rarity = rarity
182 }
183 }
184
185 access(all)
186 resource interface CollectionPublic{
187 access(account)
188 fun addBadge(id: UInt64, badge: Badge)
189
190 access(all)
191 fun hasNFT(_ id: UInt64): Bool
192 }
193
194 access(all)
195 resource Collection: NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.Collection, NonFungibleToken.CollectionPublic, ViewResolver.ResolverCollection, CollectionPublic{
196 // dictionary of NFT conforming tokens
197 // NFT is a resource type with an `UInt64` ID field
198 access(all)
199 var ownedNFTs: @{UInt64:{ NonFungibleToken.NFT}}
200
201 init(){
202 self.ownedNFTs <-{}
203 }
204
205 access(all)
206 fun hasNFT(_ id: UInt64): Bool{
207 return self.ownedNFTs[id] != nil
208 }
209
210 // withdraw removes an NFT from the collection and moves it to the caller
211 access(NonFungibleToken.Withdraw)
212 fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT}{
213 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
214 emit Withdraw(id: token.id, from: self.owner?.address)
215 return <-token
216 }
217
218 // withdraw removes an NFT from the collection and moves it to the caller
219 access(Owner)
220 fun burn(_ id: UInt64){
221 let token <- self.withdraw(withdrawID: id) as! @NFT
222 emit Burned(id: token.id, from: self.owner?.address, playId: token.play.id, edition: token.edition)
223 destroy <-token
224 }
225
226 // deposit takes a NFT and adds it to the collections dictionary
227 // and adds the ID to the id array
228 access(all)
229 fun deposit(token: @{NonFungibleToken.NFT}): Void{
230 let token <- token as! @NFT
231 let id: UInt64 = token.id
232 token.increaseNounce()
233 // add the new token to the dictionary which removes the old one
234 let oldToken <- self.ownedNFTs[id] <- token
235 emit Deposit(id: id, to: self.owner?.address)
236 destroy oldToken
237 }
238
239 // getIDs returns an array of the IDs that are in the collection
240 access(all)
241 view fun getIDs(): [UInt64]{
242 return self.ownedNFTs.keys
243 }
244
245 // borrowNFT gets a reference to an NFT in the collection
246 // so that the caller can read its metadata and call its methods
247 access(all)
248 view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}?{
249 return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
250 }
251
252 access(all)
253 view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}?{
254 let nft = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
255 let aera = nft as! &NFT
256 return aera as &{ViewResolver.Resolver}
257 }
258
259 access(account)
260 fun addBadge(id: UInt64, badge: Badge){
261 let nft = (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
262 let aera = nft as! &NFT
263 aera.addBadge(badge)
264 }
265
266 access(all)
267 view fun getSupportedNFTTypes():{ Type: Bool}{
268 panic("implement me")
269 }
270
271 access(all)
272 view fun isSupportedNFTType(type: Type): Bool{
273 panic("implement me")
274 }
275
276 access(all)
277 fun createEmptyCollection(): @{NonFungibleToken.Collection}{
278 return <-create Collection()
279 }
280 }
281
282 // public function that anyone can call to create a new empty collection
283 access(all)
284 fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection}{
285 return <-create Collection()
286 }
287
288 // mintNFT mints a new NFT with a new ID
289 // and deposit it in the recipients collection using their collection reference
290 //The distinction between sending in a reference and sending in a capability is that when you send in a reference it cannot be stored. So it can only be used in this method
291 //while a capability can be stored and used later. So in this case using a reference is the right choice, but it needs to be owned so that you can have a good event
292 access(account)
293 fun mintNFT(recipient: &{NonFungibleToken.Receiver}, edition: UInt64, play: Play, badges: [Badge]){
294 pre{
295 recipient.owner != nil:
296 "Recipients NFT collection is not owned"
297 }
298 AeraNFT.totalSupply = AeraNFT.totalSupply + 1
299 // create a new NFT
300 var newNFT <- create NFT(play: play, edition: edition)
301 for badge in badges{
302 newNFT.addBadge(badge)
303 }
304 recipient.deposit(token: <-newNFT)
305 }
306
307 access(all)
308 struct Game{
309 access(all)
310 let id: UInt64
311
312 access(all)
313 let homeTeamName: String
314
315 access(all)
316 let awayTeamName: String
317
318 access(all)
319 let derbyID: String
320
321 access(all)
322 let competition: String
323
324 access(all)
325 let season: String
326
327 access(all)
328 let date: UFix64
329
330 access(all)
331 let matchday: UInt64
332
333 access(all)
334 let highlightedTeam: String
335
336 access(all)
337 let homeScore: UInt64
338
339 access(all)
340 let awayScore: UInt64
341
342 access(all)
343 let metadata:{ String: String}
344
345 init(id: UInt64, homeTeamName: String, awayTeamName: String, derbyID: String, competition: String, season: String, date: UFix64, matchday: UInt64, highlightedTeam: String, homeScore: UInt64, awayScore: UInt64, metadata:{ String: String}){
346 self.id = id
347 self.homeTeamName = homeTeamName
348 self.awayTeamName = awayTeamName
349 self.derbyID = derbyID
350 self.competition = competition
351 self.season = season
352 self.date = date
353 self.matchday = matchday
354 self.highlightedTeam = highlightedTeam
355 self.homeScore = homeScore
356 self.awayScore = awayScore
357 self.metadata = metadata
358 }
359
360 access(all)
361 fun getTraits(): [MetadataViews.Trait]{
362 var winner = "tie"
363 if self.homeScore > self.awayScore{
364 winner = "home"
365 } else if self.homeScore < self.awayScore{
366 winner = "away"
367 }
368 let views = [MetadataViews.Trait(name: "home_team", value: self.homeTeamName, displayType: "String", rarity: nil), MetadataViews.Trait(name: "away_team", value: self.awayTeamName, displayType: "String", rarity: nil), MetadataViews.Trait(name: "competition", value: self.competition, displayType: "String", rarity: nil), MetadataViews.Trait(name: "season", value: self.season, displayType: "String", rarity: nil), MetadataViews.Trait(name: "match_date", value: self.date, displayType: "Date", rarity: nil), MetadataViews.Trait(name: "match_day", value: self.matchday, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "home_score", value: self.homeScore, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "away_score", value: self.awayScore, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "score", value: self.homeScore.toString().concat("-").concat(self.awayScore.toString()), displayType: "String", rarity: nil), MetadataViews.Trait(name: "winner", value: winner, displayType: "String", rarity: nil)]
369 if self.derbyID != "-" && self.derbyID != ""{
370 views.append(MetadataViews.Trait(name: "derby_id", value: self.derbyID, displayType: "String", rarity: nil))
371 }
372 return views
373 }
374 }
375
376 access(self)
377 let games:{ UInt64: Game}
378
379 access(account)
380 fun addGame(_ game: Game){
381 self.games[game.id] = game
382 }
383
384 access(all)
385 fun getGames():{ UInt64: Game}{
386 return self.games
387 }
388
389 access(all)
390 fun getGame(_ id: UInt64): Game?{
391 return self.games[id]
392 }
393
394 access(all)
395 struct License{
396 access(all)
397 let id: UInt64
398
399 access(all)
400 let note: String
401
402 access(all)
403 let copyright: String
404
405 init(id: UInt64, note: String, copyright: String){
406 self.id = id
407 self.note = note
408 self.copyright = copyright
409 }
410 }
411
412 access(self)
413 let licenses:{ UInt64: License}
414
415 access(account)
416 fun addLicense(_ license: License){
417 self.licenses[license.id] = license
418 }
419
420 access(all)
421 fun getLicenses():{ UInt64: License}{
422 return self.licenses
423 }
424
425 access(all)
426 fun getLicense(_ id: UInt64): License?{
427 return self.licenses[id]
428 }
429
430 /// A struct to hold information about a play
431 access(all)
432 struct Play{
433 access(all)
434 let id: UInt64
435
436 access(all)
437 let gameID: UInt64
438
439 access(all)
440 let playersInvolved:{ String: UInt64}
441
442 access(all)
443 let title: String
444
445 access(all)
446 let description: String
447
448 //this is the thumbnail
449 access(all)
450 let imageIpfsHash: String
451
452 access(all)
453 let videoIpfsHash: String
454
455 //these are images
456 access(all)
457 let thumbnailsIpfsHash: [String]
458
459 access(all)
460 let type: String
461
462 access(all)
463 let rarity: String
464
465 access(all)
466 let maxSerial: UInt64
467
468 access(all)
469 let period: String
470
471 access(all)
472 let date: UFix64
473
474 access(all)
475 let time: UInt64
476
477 access(all)
478 let homeScore: UInt64
479
480 access(all)
481 let awayScore: UInt64
482
483 init(id: UInt64, gameID: UInt64, playersInvolved:{ String: UInt64}, title: String, description: String, imageIpfsHash: String, videoIpfsHash: String, thumbnailsIpfsHash: [String], type: String, rarity: String, maxSerial: UInt64, period: String, date: UFix64, time: UInt64, homeScore: UInt64, awayScore: UInt64){
484 self.id = id
485 self.gameID = gameID
486 self.playersInvolved = playersInvolved
487 self.title = title
488 self.description = description
489 self.imageIpfsHash = imageIpfsHash
490 self.videoIpfsHash = videoIpfsHash
491 self.thumbnailsIpfsHash = thumbnailsIpfsHash
492 self.type = type
493 self.rarity = rarity
494 self.maxSerial = maxSerial
495 self.period = period
496 self.date = date
497 self.time = time
498 self.homeScore = homeScore
499 self.awayScore = awayScore
500 }
501
502 access(all)
503 fun getLicenseID(): UInt64?{
504 let playId = self.id
505 if let licence = self.playersInvolved["license"]{
506 //There was a typo in mint so we fix it here
507 if playId == 338{
508 return 2
509 } else if playId == 342{
510 return 1
511 } else{
512 return licence
513 }
514 }
515 return nil
516 }
517
518 access(all)
519 fun getTraits(): [MetadataViews.Trait]{
520 let traits = [MetadataViews.Trait(name: "play_id", value: self.id, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "play_period", value: self.period, displayType: "String", rarity: nil), MetadataViews.Trait(name: "play_time", value: self.time, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "play_home_score", value: self.homeScore, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "play_away_score", value: self.awayScore, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "play_score", value: self.homeScore.toString().concat("-").concat(self.awayScore.toString()), displayType: "String", rarity: nil), MetadataViews.Trait(name: "play_type", value: self.type, displayType: "String", rarity: nil)]
521 let game = AeraNFT.getGame(self.gameID)!
522 if let ht = self.playersInvolved["highlightedTeam"]{
523 var highlightedTeam = game.homeTeamName
524 if ht == 2{
525 highlightedTeam = game.awayTeamName
526 }
527 traits.append(MetadataViews.Trait(name: "highlighted_team", value: highlightedTeam, displayType: "String", rarity: nil))
528 }
529 if let pt = self.playersInvolved["play_type"]{
530 var playType = "player"
531 if pt == 2{
532 playType = "team"
533 } else if pt == 3{
534 playType = "reward"
535 }
536 traits.append(MetadataViews.Trait(name: "play_entity", value: playType, displayType: "String", rarity: nil))
537 }
538 traits.appendAll(game.getTraits())
539 for role in self.playersInvolved.keys{
540 if role == "highlightedTeam" || role == "license" || role == "play_type"{
541 continue
542 }
543 let player = AeraNFT.getPlayer(self.playersInvolved[role]!)!
544 var prefix = role
545 traits.appendAll(player.getTraits(prefix))
546 }
547 if let licence = self.getLicenseID(){
548 let l = AeraNFT.getLicense(licence)!
549 traits.append(MetadataViews.Trait(name: "copyright", value: l.copyright, displayType: "String", rarity: nil))
550 }
551 return traits
552 }
553
554 access(all)
555 fun getMetadata(_ field: String): AnyStruct?{
556 if let metadata = AeraNFT.getPlayMetadata(self.id){
557 return metadata.metadata[field]
558 }
559 return nil
560 }
561
562 access(all)
563 fun getMedias(): MetadataViews.Medias{
564 let imageFile = MetadataViews.IPFSFile(cid: self.imageIpfsHash, path: nil)
565 let medias = [self.getVideo(), MetadataViews.Media(file: imageFile, mediaType: "image/png")]
566 for hash in self.thumbnailsIpfsHash{
567 let file = MetadataViews.IPFSFile(cid: hash, path: nil)
568 medias.append(MetadataViews.Media(file: file, mediaType: "image/png"))
569 }
570 return MetadataViews.Medias(medias)
571 }
572
573 access(all)
574 fun asDisplay(): MetadataViews.Display{
575 let imageFile = MetadataViews.IPFSFile(cid: self.imageIpfsHash, path: nil)
576 return MetadataViews.Display(name: self.title, description: self.description, thumbnail: imageFile)
577 }
578
579 access(all)
580 fun getVideo(): MetadataViews.Media{
581 let file = MetadataViews.IPFSFile(cid: self.videoIpfsHash, path: nil)
582 return MetadataViews.Media(file: file, mediaType: self.getVideoMediaType())
583 }
584
585 access(all)
586 fun getVideoMediaType(): String{
587 if let videoMediaType = self.getMetadata("videoMediaType"){
588 return videoMediaType as! String
589 }
590 return "video/mp4"
591 }
592 }
593
594 access(all)
595 struct PlayMetadata{
596 access(all)
597 let id: UInt64
598
599 access(all)
600 let metadata:{ String: String}
601
602 init(id: UInt64, metadata:{ String: String}){
603 self.id = id
604 self.metadata = metadata
605 }
606 }
607
608 access(self)
609 let playMetadata:{ UInt64: PlayMetadata}
610
611 access(account)
612 fun addPlayMetadata(_ play: PlayMetadata){
613 self.playMetadata[play.id] = play
614 }
615
616 access(all)
617 fun getAllPlayMetadata():{ UInt64: PlayMetadata}{
618 return self.playMetadata
619 }
620
621 access(all)
622 fun getPlayMetadata(_ id: UInt64): PlayMetadata?{
623 return self.playMetadata[id]
624 }
625
626 /// Players store information about a player that can change and is therefore not stored in the NFT itself
627 /// can be mutated from Admin
628 access(all)
629 struct Player{
630 access(all)
631 let id: UInt64
632
633 access(all)
634 let jerseyname: String
635
636 access(all)
637 let position: String
638
639 access(all)
640 let number: UInt64
641
642 access(all)
643 let nationality: String
644
645 access(all)
646 let birthday: String
647
648 access(all)
649 let metadata:{ String: String}
650
651 init(id: UInt64, jerseyname: String, position: String, number: UInt64, nationality: String, birthday: String, metadata:{ String: String}){
652 self.id = id
653 self.jerseyname = jerseyname
654 self.position = position
655 self.number = number
656 self.nationality = nationality
657 self.birthday = birthday
658 self.metadata = metadata
659 }
660
661 access(all)
662 fun getTraits(_ role: String): [MetadataViews.Trait]{
663 return [MetadataViews.Trait(name: "player_".concat(role).concat("_jersey"), value: self.jerseyname, displayType: "String", rarity: nil), MetadataViews.Trait(name: "player_".concat(role).concat("_position"), value: self.position, displayType: "String", rarity: nil), MetadataViews.Trait(name: "player_".concat(role).concat("_number"), value: self.number, displayType: "Number", rarity: nil), MetadataViews.Trait(name: "player_".concat(role).concat("_nationality"), value: self.nationality, displayType: "String", rarity: nil), MetadataViews.Trait(name: "player_".concat(role).concat("_birthday"), value: self.birthday, displayType: "String", rarity: nil)]
664 }
665 }
666
667 access(self)
668 let players:{ UInt64: Player}
669
670 access(account)
671 fun addPlayer(_ player: Player){
672 self.players[player.id] = player
673 }
674
675 access(all)
676 fun getPlayers():{ UInt64: Player}{
677 return self.players
678 }
679
680 access(all)
681 fun getPlayer(_ id: UInt64): Player?{
682 return self.players[id]
683 }
684
685 access(all)
686 fun resolveLicence(_ viewResolver: &{ViewResolver.Resolver}): License?{
687 if let view = viewResolver.resolveView(Type<License>()){
688 if let v = view as? License{
689 return v
690 }
691 }
692 return nil
693 }
694
695 access(all)
696 struct Challenge{
697 access(all)
698 var completed: Bool
699
700 access(all)
701 let playIds: [UInt64]
702
703 access(all)
704 let numberOfPlaysToComplete: Int
705
706 access(all)
707 let qualification:{ UInt64: UInt64}
708
709 init(playIds: [UInt64], numberOfPlaysToComplete: Int){
710 self.playIds = playIds
711 self.numberOfPlaysToComplete = numberOfPlaysToComplete
712 self.qualification ={}
713 self.completed = false
714 }
715
716 access(all)
717 fun checkPlay(playId: UInt64, id: UInt64){
718 if self.playIds.contains(playId) && self.qualification[playId] == nil{
719 self.qualification[playId] = id
720 }
721 self.completed = self.qualification.length >= self.numberOfPlaysToComplete
722 }
723 }
724
725 access(all) view fun getContractViews(resourceType: Type?): [Type] {
726 return [
727 Type<MetadataViews.NFTCollectionData>(),
728 Type<MetadataViews.NFTCollectionDisplay>()
729 ]
730 }
731
732 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
733 switch viewType {
734 case Type<MetadataViews.NFTCollectionData>():
735 return MetadataViews.NFTCollectionData(storagePath: AeraNFT.CollectionStoragePath, publicPath: AeraNFT.CollectionPublicPath, publicCollection: Type<&AeraNFT.Collection>(), publicLinkedType: Type<&AeraNFT.Collection>(), createEmptyCollectionFunction: fun (): @{NonFungibleToken.Collection}{
736 return <-AeraNFT.createEmptyCollection(nftType: Type<@AeraNFT.Collection>())
737 })
738 case Type<MetadataViews.NFTCollectionDisplay>():
739 let externalURL = MetadataViews.ExternalURL("http://aera.onefootbal.com")
740 let squareImage = MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://miro.medium.com/fit/c/176/176/1*hzfP51MATg3et5vghYy1uQ.png"), mediaType: "image/png")
741 let bannerImage = MetadataViews.Media(file: MetadataViews.HTTPFile(url: "https://bafybeiaaf7bfbppep5ahb2m75xlmxyj76hxo3oh5dcl4prxeskruwpe6c4.ipfs.nftstorage.link/"), mediaType: "image/png")
742 let socialMap:{ String: MetadataViews.ExternalURL} ={ "twitter": MetadataViews.ExternalURL("https://twitter.com/aera_football"), "discord": MetadataViews.ExternalURL("https://discord.gg/aera"), "instagram": MetadataViews.ExternalURL("https://www.instagram.com/aera_football/")}
743 return MetadataViews.NFTCollectionDisplay(name: "Aera", description: "Aera by OneFootball", externalURL: externalURL, squareImage: squareImage, bannerImage: bannerImage, socials: socialMap)
744
745 }
746 return nil
747 }
748
749
750 init(){
751 self.players ={}
752 self.games ={}
753 self.playMetadata ={}
754 self.licenses ={}
755 // Initialize the total supply
756 self.totalSupply = 0
757
758 // Set the named paths
759 self.CollectionStoragePath = /storage/aeraNFTs
760 self.CollectionPublicPath = /public/aeraNFTs
761 self.CollectionPrivatePath = /private/aeraNFTs
762 emit ContractInitialized()
763 }
764}
765
766