Smart Contract
MotoGPCardMetadata
A.a49cc0ee46c54bfb.MotoGPCardMetadata
1import FungibleToken from 0xf233dcee88fe0abe
2import NonFungibleToken from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import MotoGPAdmin from 0xa49cc0ee46c54bfb
5import ContractVersion from 0xb223b2bfe4b8ffb5
6import MotoGPRegistry from 0xa49cc0ee46c54bfb
7
8
9// Contract to hold Metadata for MotoGPCards. Metadata is accessed using the Card's cardID (not the Card's id)
10//
11pub contract MotoGPCardMetadata: ContractVersion {
12
13 pub fun getVersion():String {
14 return "1.0.4"
15 }
16
17 //////////////////////////////////
18 // MotoGPCard MetadataViews implementation
19 //////////////////////////////////
20
21 pub struct Rider {
22 pub let name: String
23 pub let bike: String
24 pub let team: String
25 pub let number: String
26 init(name: String, bike: String, team: String, number: String) {
27 self.name = name
28 self.bike = bike
29 self.team = team
30 self.number = number
31 }
32 }
33
34 pub struct Riders {
35 pub let riders: [Rider]
36 init(riders: [Rider]) {
37 self.riders = riders
38 }
39 }
40
41 // The getRider method is the equivalent of the MetadataViews.get{ViewName} methods
42 // to get the custom Riders view by supplying a card reference as argument
43 //
44 pub fun getRiders(_ viewResolver: &{MetadataViews.Resolver}): Riders? {
45 if let view = viewResolver.resolveView(Type<Riders>()) {
46 if let v = view as? Riders {
47 return v
48 }
49 }
50 return nil
51 }
52
53 access(contract) fun resolveDisplayView(cardID: UInt64): MetadataViews.Display {
54 let metadata = self.metadatas[cardID]!
55 return MetadataViews.Display(
56 name: metadata.name,
57 description: metadata.description,
58 thumbnail: MetadataViews.HTTPFile(url: metadata.imageUrl)
59 )
60 }
61
62 access(contract) fun resolveRoyaltiesView(): MetadataViews.Royalties {
63 var royaltyList: [MetadataViews.Royalty] = []
64 let capability = getAccount(MotoGPRegistry.get(key: "motogp-royalty-receiver")! as! Address).getCapability<&{FungibleToken.Receiver}>(MetadataViews.getRoyaltyReceiverPublicPath())
65 let royalty:MetadataViews.Royalty = MetadataViews.Royalty(
66 receiver: capability,
67 cut: 0.075,
68 description: "Creator royalty"
69 )
70 royaltyList.append(royalty)
71 return MetadataViews.Royalties(royaltyList)
72 }
73
74 access(contract) fun resolveExternalURLView(id: UInt64): MetadataViews.ExternalURL {
75 return MetadataViews.ExternalURL("https://motogp-ignition.com/nft/card/".concat(id.toString()))
76 }
77
78 access(contract) fun resolveNFTCollectionDisplayView(): MetadataViews.NFTCollectionDisplay {
79 let socials:{String: MetadataViews.ExternalURL} = {}
80 socials.insert(key: "twitter", MetadataViews.ExternalURL("https://twitter.com/MotoGPIgnition"))
81
82 let squareMedia = MetadataViews.Media(
83 file: MetadataViews.HTTPFile(url: "https://assets.motogp-ignition.com/MGPI-card-Square.jpg"),
84 mediaType: "image/jpeg"
85 )
86 let bannerMedia = MetadataViews.Media(
87 file: MetadataViews.HTTPFile(url: "https://assets.motogp-ignition.com/MGPI-card-Banner.jpg"),
88 mediaType: "image/jpeg"
89 )
90 return MetadataViews.NFTCollectionDisplay(
91 name: "MotoGPCard",
92 description: "MotoGP Ignition is an NFT collection for MotoGP enthusiasts",
93 externalURL: MetadataViews.ExternalURL("https://motogp-ignition.com"),
94 squareImage: squareMedia,
95 bannerImage: bannerMedia,
96 socials: socials
97 )
98 }
99
100 access(contract) fun resolveMediasView(cardID: UInt64): MetadataViews.Medias {
101 let metadata = self.metadatas[cardID]!
102 var imageUrl:String = metadata.imageUrl
103 var videoUrl:String = metadata.data["videoUrl"]!
104 var thumbnailVideoUrl:String = metadata.data["thumbnailVideoUrl"]!
105 let medias:[MetadataViews.Media] = []
106 medias.append(MetadataViews.Media(file: MetadataViews.HTTPFile(url: imageUrl), mediaType: "image/png"))
107 medias.append(MetadataViews.Media(file: MetadataViews.HTTPFile(url: videoUrl), mediaType: "video/mp4"))
108 medias.append(MetadataViews.Media(file: MetadataViews.HTTPFile(url: thumbnailVideoUrl), mediaType: "video/mp4"))
109 return MetadataViews.Medias(medias)
110 }
111
112 access(contract) fun resolveTraitsView(cardID: UInt64): MetadataViews.Traits {
113 let metadata = self.metadatas[cardID]!
114 let traits = MetadataViews.Traits([])
115 for key in metadata.data.keys {
116 if key != "id" && key != "name" && key != "description" && key != "imageUrl" && key != "videoUrl" && key != "thumbnailVideoUrl" {
117 let trait = MetadataViews.Trait(name: key, value: metadata.data[key], nil, nil)
118 traits.addTrait(trait)
119 }
120 }
121 return traits
122 }
123
124 access(contract) fun resolveRidersView(cardID: UInt64): Riders {
125 let riders:[Rider] = []
126 let metadata = self.metadatas[cardID]!
127 var riderIndex = 1
128 for key in metadata.data.keys {
129 let riderKey = "rider_".concat(riderIndex.toString())
130 let riderName = metadata.data[riderKey]
131 if riderName == nil {
132 break
133 } else {
134 let riderBike = metadata.data[riderKey.concat("_bike")] ?? ""
135 let riderTeam = metadata.data[riderKey.concat("_team")] ?? ""
136 let riderNumber = metadata.data[riderKey.concat("_number")] ?? ""
137 riders.append(Rider(name: riderName!, bike: riderBike, team: riderTeam, number: riderNumber));
138 riderIndex = riderIndex + 1
139 }
140 }
141 return Riders(riders: riders)
142 }
143
144 pub fun resolveView(
145 view: Type,
146 id: UInt64,
147 cardID: UInt64,
148 serial: UInt64,
149 publicCollectionType: Type,
150 publicLinkedType: Type,
151 providerLinkedType: Type,
152 createEmptyCollectionFunction: ((): @NonFungibleToken.Collection)
153 ): AnyStruct? {
154
155 switch view {
156
157 case Type<MotoGPCardMetadata.Riders>():
158 return self.resolveRidersView(cardID: cardID)
159
160 case Type<MetadataViews.Traits>():
161 return self.resolveTraitsView(cardID: cardID)
162
163 case Type<MetadataViews.Display>():
164 return self.resolveDisplayView(cardID: cardID)
165
166 case Type<MetadataViews.Royalties>():
167 return self.resolveRoyaltiesView()
168
169 case Type<MetadataViews.ExternalURL>():
170 return self.resolveExternalURLView(id: id)
171
172 case Type<MetadataViews.Medias>():
173 return self.resolveMediasView(cardID: cardID)
174
175 case Type<MetadataViews.NFTCollectionDisplay>():
176 return self.resolveNFTCollectionDisplayView()
177
178 case Type<MetadataViews.NFTCollectionData>():
179 return MetadataViews.NFTCollectionData(
180 storagePath: StoragePath(identifier: "motogpCardCollection")!,
181 publicPath: PublicPath(identifier: "motogpCardCollection")!,
182 providerPath: PrivatePath(identifier: "motogpCardCollection")!,
183 publicCollection: publicCollectionType,
184 publicLinkedType: publicLinkedType,
185 providerLinkedType: providerLinkedType,
186 createEmptyCollectionFunction: createEmptyCollectionFunction
187 )
188
189 }
190 return nil
191 }
192
193
194 /////////////////////////////////////////////////////////////////////////////////
195 // MotoGPCard Legacy Metadata Implementation (kept for compatibility purposes)
196 ////////////////////////////////////////////////////////////////////////////////
197
198
199 pub struct Metadata {
200 pub let cardID: UInt64
201 pub let name: String
202 pub let description: String
203 pub let imageUrl: String
204 // data contains all 'other' metadata fields, e.g. videoUrl, team, etc
205 //
206 pub let data: {String: String}
207 init(_cardID:UInt64, _name:String, _description:String, _imageUrl:String, _data:{String:String}){
208 pre {
209 !_data.containsKey("name") : "data dictionary contains 'name' key"
210 !_data.containsKey("description") : "data dictionary contains 'description' key"
211 !_data.containsKey("imageUrl") : "data dictionary contains 'imageUrl' key"
212 }
213 self.cardID = _cardID
214 self.name = _name
215 self.description = _description
216 self.imageUrl = _imageUrl
217 self.data = _data
218 }
219 }
220
221 //Dictionary to hold all metadata with cardID as key
222 //
223 access(self) let metadatas: {UInt64: MotoGPCardMetadata.Metadata}
224
225 // Get all metadatas
226 //
227 pub fun getMetadatas(): {UInt64: MotoGPCardMetadata.Metadata} {
228 return self.metadatas
229 }
230
231 pub fun getMetadatasCount(): UInt64 {
232 return UInt64(self.metadatas.length)
233 }
234
235 //Get metadata for a specific cardID
236 //
237 pub fun getMetadataForCardID(cardID: UInt64): MotoGPCardMetadata.Metadata? {
238 return self.metadatas[cardID]
239 }
240
241 //Access to set metadata is controlled using an Admin reference as argument
242 //
243 pub fun setMetadata(adminRef: &MotoGPAdmin.Admin, cardID: UInt64, name:String, description:String, imageUrl:String, data:{String: String}) {
244 pre {
245 adminRef != nil: "adminRef is nil"
246 }
247 let metadata = Metadata(_cardID:cardID, _name:name, _description:description, _imageUrl:imageUrl, _data:data)
248 self.metadatas[cardID] = metadata
249 }
250
251 //Remove metadata by cardID
252 //
253 pub fun removeMetadata(adminRef: &MotoGPAdmin.Admin, cardID: UInt64) {
254 pre {
255 adminRef != nil: "adminRef is nil"
256 }
257 self.metadatas.remove(key: cardID)
258 }
259
260 init(){
261 self.metadatas = {}
262 }
263
264}
265