Smart Contract

Gamisodes

A.09e04bdbcccde6ca.Gamisodes

Deployed

3d ago
Feb 25, 2026, 07:54:26 AM UTC

Dependents

5 imports
1/*
2Gamisodes
3
4This is the contract for Gamisodes NFTs!
5
6This was implemented using Niftory interfaces. For full details on how this
7contract functions, please see the Niftory and NFTRegistry contracts.
8
9*/
10
11import NonFungibleToken from 0x1d7e57aa55817448
12import MetadataViews from 0x1d7e57aa55817448
13import ViewResolver from 0x1d7e57aa55817448
14
15import MutableMetadata from 0x7ec1f607f0872a9e
16import MutableMetadataTemplate from 0x7ec1f607f0872a9e
17import MutableMetadataSet from 0x7ec1f607f0872a9e
18import MutableMetadataSetManager from 0x7ec1f607f0872a9e
19import MetadataViewsManager from 0x7ec1f607f0872a9e
20
21import NiftoryNonFungibleToken from 0x7ec1f607f0872a9e
22import NiftoryNFTRegistry from 0x7ec1f607f0872a9e
23
24import NiftoryMetadataViewsResolvers from 0x7ec1f607f0872a9e
25import NiftoryNonFungibleTokenProxy from 0x7ec1f607f0872a9e
26
27pub contract Gamisodes: NonFungibleToken, ViewResolver {
28
29  // ========================================================================
30  // Constants
31  // ========================================================================
32
33  // Suggested paths where collection could be stored
34  pub let COLLECTION_PRIVATE_PATH: PrivatePath
35  pub let COLLECTION_PUBLIC_PATH: PublicPath
36  pub let COLLECTION_STORAGE_PATH: StoragePath
37
38  // Accessor token to be used with NiftoryNFTRegistry to retrieve
39  // meta-information about this NFT project
40  pub let REGISTRY_ADDRESS: Address
41  pub let REGISTRY_BRAND: String
42
43  // ========================================================================
44  // Attributes
45  // ========================================================================
46
47  // Arbitrary metadata for this NFT contract
48  pub var metadata: AnyStruct?
49
50  // Number of NFTs created
51  pub var totalSupply: UInt64
52
53  // ========================================================================
54  // Contract Events
55  // ========================================================================
56
57  // This contract was initialized
58  pub event ContractInitialized()
59
60  // A withdrawal of NFT `id` has occurred from the `from` Address
61  pub event Withdraw(id: UInt64, from: Address?)
62
63  // A deposit of an NFT `id` has occurred to the `to` Address
64  pub event Deposit(id: UInt64, to: Address?)
65
66  ///////////////////////////////////////////////////////////////////////////
67
68  // Contract metadata was modified
69  pub event ContractMetadataUpdated()
70
71  // Metadata Views Manager was locked
72  pub event MetadataViewsManagerLocked()
73
74  // Metadata Views Resolver was added
75  pub event MetadataViewsResolverAdded(type: Type)
76
77  // Metadata Views Resolver was removed
78  pub event MetadataViewsResolverRemoved(type: Type)
79
80  // Set Manager Name or Description updated
81  pub event SetManagerMetadataUpdated()
82
83  // Set added to Set Manager
84  pub event SetAddedToSetManager(setID: Int)
85
86  ///////////////////////////////////////////////////////////////////////////
87
88  // Set `setId` was locked (no new templates can be added)
89  pub event SetLocked(setId: Int)
90
91  // The metadata for Set `setId` was locked and cannot be modified
92  pub event SetMetadataLocked(setId: Int)
93
94  // Set `setId` was modified
95  pub event SetMetadataModified(setId: Int)
96
97  // A new Template `templateId` was added to Set `setId`
98  pub event TemplateAddedToSet(setId: Int, templateId: Int)
99
100  ///////////////////////////////////////////////////////////////////////////
101
102  // Template `templateId` was locked in Set `setId`, which disables minting
103  pub event TemplateLocked(setId: Int, templateId: Int)
104
105  // Template `templateId` of Set `setId` had it's maxMint set to `maxMint`
106  pub event TemplateMaxMintSet(setId: Int, templateId: Int, maxMint: UInt64)
107
108  // Template `templateId` of Set `setId` has minted NFT with serial `serial`
109  pub event NFTMinted(id: UInt64, setId: Int, templateId: Int, serial: UInt64)
110
111  ///////////////////////////////////////////////////////////////////////////
112
113  // The metadata for NFT/Template `templateId` of Set `setId` was locked
114  pub event NFTMetadataLocked(setId: Int, templateId: Int)
115
116  // The metadata for NFT/Template `templateId` of Set `setId` was modified
117  pub event NFTMetadataModified(setId: Int, templateId: Int)
118
119  ///////////////////////////////////////////////////////////////////////////
120
121  // NFT `serial` from Template `templateId` of Set `setId` was burned
122  pub event NFTBurned(setId: Int, templateId: Int, serial: UInt64)
123
124  // ========================================================================
125  // NFT
126  // ========================================================================
127
128  pub resource NFT:
129    NonFungibleToken.INFT,
130    MetadataViews.Resolver,
131    NiftoryNonFungibleToken.NFTPublic
132  {
133    pub let id: UInt64
134    pub let setId: Int
135    pub let templateId: Int
136    pub let serial: UInt64
137
138    pub fun contract(): &{NiftoryNonFungibleToken.ManagerPublic} {
139      return Gamisodes.contract()
140    }
141
142    pub fun set(): &MutableMetadataSet.Set{MutableMetadataSet.Public} {
143      return self
144        .contract()
145        .getSetManagerPublic()
146        .getSet(self.setId)
147    }
148
149    pub fun metadata(): &MutableMetadata.Metadata{MutableMetadata.Public} {
150      return self
151        .set()
152        .getTemplate(self.templateId)
153        .metadata()
154    }
155
156    pub fun getViews(): [Type] {
157      return self
158        .contract()
159        .getMetadataViewsManagerPublic()
160        .getViews()
161    }
162
163    pub fun resolveView(_ view: Type): AnyStruct? {
164      let nftRef = &self as &{NiftoryNonFungibleToken.NFTPublic}
165      return self
166        .contract()
167        .getMetadataViewsManagerPublic()
168        .resolveView(view: view, nftRef: nftRef)
169    }
170
171    init(setId: Int, templateId: Int, serial: UInt64) {
172      self.id = Gamisodes.totalSupply
173      Gamisodes.totalSupply =
174        Gamisodes.totalSupply + 1
175      self.setId = setId
176      self.templateId = templateId
177      self.serial = serial
178    }
179
180    destroy() {
181      emit NFTBurned(
182        setId: self.setId,
183        templateId: self.templateId,
184        serial: self.serial
185      )
186    }
187  }
188
189  // ========================================================================
190  // Collection
191  // ========================================================================
192
193  pub resource Collection:
194    NonFungibleToken.Provider,
195    NonFungibleToken.Receiver,
196    NonFungibleToken.CollectionPublic,
197    MetadataViews.ResolverCollection,
198    NiftoryNonFungibleToken.CollectionPublic,
199    NiftoryNonFungibleToken.CollectionPrivate
200  {
201    pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
202
203    pub fun contract(): &{NiftoryNonFungibleToken.ManagerPublic} {
204      return Gamisodes.contract()
205    }
206
207    pub fun getIDs(): [UInt64] {
208      return self.ownedNFTs.keys
209    }
210
211    pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
212      pre {
213        self.ownedNFTs[id] != nil : "NFT "
214          .concat(id.toString())
215          .concat(" does not exist in collection.")
216      }
217      return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
218    }
219
220    pub fun borrow(id: UInt64): &NFT{NiftoryNonFungibleToken.NFTPublic} {
221      pre {
222        self.ownedNFTs[id] != nil : "NFT does not exist in collection."
223      }
224      let nftRef = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
225      let fullNft = nftRef as! &NFT
226      return fullNft
227    }
228
229    pub fun borrowViewResolver(id: UInt64): &{MetadataViews.Resolver} {
230      pre {
231        self.ownedNFTs[id] != nil : "NFT does not exist in collection."
232      }
233      let nftRef = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
234      let fullNft = nftRef as! &NFT
235      return fullNft
236    }
237
238    pub fun deposit(token: @NonFungibleToken.NFT) {
239      let token <- token as! @Gamisodes.NFT
240      let id: UInt64 = token.id
241      let oldToken <- self.ownedNFTs[id] <- token
242      emit Deposit(id: id, to: self.owner?.address)
243      destroy oldToken
244    }
245
246    pub fun depositBulk(tokens: @[NonFungibleToken.NFT]) {
247      while tokens.length > 0 {
248        let token <- tokens.removeLast() as! @Gamisodes.NFT
249        self.deposit(token: <-token)
250      }
251      destroy tokens
252    }
253
254    pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
255      pre {
256        self.ownedNFTs[withdrawID] != nil
257          : "NFT "
258            .concat(withdrawID.toString())
259            .concat(" does not exist in collection.")
260      }
261      let token <-self.ownedNFTs.remove(key: withdrawID)!
262      emit Withdraw(id: token.id, from: self.owner?.address)
263      return <-token
264    }
265
266    pub fun withdrawBulk(withdrawIDs: [UInt64]): @[NonFungibleToken.NFT] {
267      let tokens: @[NonFungibleToken.NFT] <- []
268      while withdrawIDs.length > 0 {
269        tokens.append(<- self.withdraw(withdrawID: withdrawIDs.removeLast()))
270      }
271      return <-tokens
272    }
273
274    init() {
275      self.ownedNFTs <- {}
276    }
277
278    destroy() {
279      destroy self.ownedNFTs
280    }
281  }
282
283  pub fun createEmptyCollection(): @Collection {
284    return <-create Collection()
285  }
286
287  // ========================================================================
288  // Manager
289  // ========================================================================
290
291  pub resource Manager:
292    NiftoryNonFungibleToken.ManagerPublic,
293    NiftoryNonFungibleToken.ManagerPrivate
294  {
295    // ========================================================================
296    // Public
297    // ========================================================================
298
299    pub fun metadata(): AnyStruct? {
300      return Gamisodes.metadata
301    }
302
303    pub fun getSetManagerPublic():
304      &MutableMetadataSetManager.Manager{MutableMetadataSetManager.Public}
305    {
306      return NiftoryNFTRegistry
307        .getSetManagerPublic(
308          Gamisodes.REGISTRY_ADDRESS,
309          Gamisodes.REGISTRY_BRAND
310        )
311    }
312
313    pub fun getMetadataViewsManagerPublic():
314      &MetadataViewsManager.Manager{MetadataViewsManager.Public}
315    {
316      return NiftoryNFTRegistry
317        .getMetadataViewsManagerPublic(
318          Gamisodes.REGISTRY_ADDRESS,
319          Gamisodes.REGISTRY_BRAND
320        )
321    }
322
323    pub fun getNFTCollectionData(): MetadataViews.NFTCollectionData {
324      return NiftoryNFTRegistry
325        .buildNFTCollectionData(
326          Gamisodes.REGISTRY_ADDRESS,
327          Gamisodes.REGISTRY_BRAND,
328          (fun (): @NonFungibleToken.Collection {
329            return <-Gamisodes.createEmptyCollection()
330          })
331        )
332    }
333
334    // ========================================================================
335    // Contract metadata
336    // ========================================================================
337
338    pub fun modifyContractMetadata(): auth &AnyStruct {
339      emit ContractMetadataUpdated()
340      let maybeMetadata = Gamisodes.metadata
341      if maybeMetadata == nil {
342        let blankMetadata: {String: String} = {}
343        Gamisodes.metadata = blankMetadata
344      }
345      return (&Gamisodes.metadata as auth &AnyStruct?)!
346    }
347
348    pub fun replaceContractMetadata(_ metadata: AnyStruct?) {
349      emit ContractMetadataUpdated()
350      Gamisodes.metadata = metadata
351    }
352
353    // ========================================================================
354    // Metadata Views Manager
355    // ========================================================================
356
357    access(self) fun _getMetadataViewsManagerPrivate():
358      &MetadataViewsManager.Manager{MetadataViewsManager.Private}
359    {
360      let record =
361        NiftoryNFTRegistry.getRegistryRecord(
362          Gamisodes.REGISTRY_ADDRESS,
363          Gamisodes.REGISTRY_BRAND
364        )
365      let manager =
366        Gamisodes.account
367          .getCapability<&MetadataViewsManager.Manager{MetadataViewsManager.Private}>(
368            record.metadataViewsManager.paths.private
369          ).borrow()!
370      return manager
371    }
372
373    pub fun lockMetadataViewsManager() {
374      self._getMetadataViewsManagerPrivate().lock()
375      emit MetadataViewsManagerLocked()
376    }
377
378    pub fun setMetadataViewsResolver(
379      _ resolver: AnyStruct{MetadataViewsManager.Resolver}
380    ) {
381      self._getMetadataViewsManagerPrivate().addResolver(resolver)
382      emit MetadataViewsResolverAdded(type: resolver.type)
383    }
384
385    pub fun removeMetadataViewsResolver(_ type: Type) {
386      self._getMetadataViewsManagerPrivate().removeResolver(type)
387      emit MetadataViewsResolverRemoved(type: type)
388    }
389
390    // ========================================================================
391    // Set Manager
392    // ========================================================================
393
394    access(self) fun _getSetManagerPrivate():
395      &MutableMetadataSetManager.Manager{MutableMetadataSetManager.Public, MutableMetadataSetManager.Private}
396    {
397      let record =
398        NiftoryNFTRegistry.getRegistryRecord(
399          Gamisodes.REGISTRY_ADDRESS,
400          Gamisodes.REGISTRY_BRAND
401        )
402      let setManager =
403        Gamisodes.account
404          .getCapability<&MutableMetadataSetManager.Manager{MutableMetadataSetManager.Public, MutableMetadataSetManager.Private}>(
405            record.setManager.paths.private
406          ).borrow()!
407      return setManager
408    }
409
410    pub fun setMetadataManagerName(_ name: String) {
411      self._getSetManagerPrivate().setName(name)
412      emit SetManagerMetadataUpdated()
413    }
414
415    pub fun setMetadataManagerDescription(_ description: String) {
416      self._getSetManagerPrivate().setDescription(description)
417      emit SetManagerMetadataUpdated()
418    }
419
420    pub fun addSet(_ set: @MutableMetadataSet.Set) {
421      let setManager = self._getSetManagerPrivate()
422      let setId = setManager.numSets()
423      setManager.addSet(<-set)
424      emit SetAddedToSetManager(setID: setId)
425    }
426
427    // ========================================================================
428    // Set
429    // ========================================================================
430
431    access(self) fun _getSetMutable(_ setId: Int):
432      &MutableMetadataSet.Set{MutableMetadataSet.Private,
433        MutableMetadataSet.Public} {
434      return self._getSetManagerPrivate().getSetMutable(setId)
435    }
436
437    pub fun lockSet(setId: Int) {
438      self._getSetMutable(setId).lock()
439      emit SetLocked(setId: setId)
440    }
441
442    pub fun lockSetMetadata(setId: Int) {
443      self._getSetMutable(setId).metadataMutable().lock()
444      emit SetMetadataLocked(setId: setId)
445    }
446
447    pub fun modifySetMetadata(setId: Int): auth &AnyStruct {
448      emit SetMetadataModified(setId: setId)
449      return self._getSetMutable(setId).metadataMutable().getMutable()
450    }
451
452    pub fun replaceSetMetadata(setId: Int, new: AnyStruct) {
453      self._getSetMutable(setId).metadataMutable().replace(new)
454      emit SetMetadataModified(setId: setId)
455    }
456
457    pub fun addTemplate(
458      setId: Int,
459      template: @MutableMetadataTemplate.Template
460    ) {
461      let set = self._getSetMutable(setId)
462      let templateId = set.numTemplates()
463      set.addTemplate(<-template)
464      emit TemplateAddedToSet(setId: setId, templateId: templateId)
465    }
466
467    // ========================================================================
468    // Minting
469    // ========================================================================
470
471    access(self) fun _getTemplateMutable(_ setId: Int, _ templateId: Int):
472      &MutableMetadataTemplate.Template{MutableMetadataTemplate.Public,
473        MutableMetadataTemplate.Private} {
474      return self._getSetMutable(setId).getTemplateMutable(templateId)
475    }
476
477    pub fun lockTemplate(setId: Int, templateId: Int) {
478      self._getTemplateMutable(setId, templateId).lock()
479      emit TemplateLocked(setId: setId, templateId: templateId)
480    }
481
482    pub fun setTemplateMaxMint(setId: Int, templateId: Int, max: UInt64) {
483      self._getTemplateMutable(setId, templateId).setMaxMint(max)
484      emit TemplateMaxMintSet(
485        setId: setId,
486        templateId: templateId,
487        maxMint: max
488      )
489    }
490
491    pub fun mint(setId: Int, templateId: Int): @NonFungibleToken.NFT {
492      let template = self._getTemplateMutable(setId, templateId)
493      template.registerMint()
494      let serial = template.minted()
495      let nft <-create NFT(
496        setId: setId,
497        templateId: templateId,
498        serial: serial
499      )
500      emit NFTMinted(
501        id: nft.id,
502        setId: setId,
503        templateId: templateId,
504        serial: serial
505      )
506      return <-nft
507    }
508
509    pub fun mintBulk(
510      setId: Int,
511      templateId: Int,
512      numToMint: UInt64,
513    ): @[NonFungibleToken.NFT] {
514      pre {
515        numToMint > 0: "Must mint at least one NFT"
516      }
517      let template = self._getTemplateMutable(setId, templateId)
518      let nfts: @[NonFungibleToken.NFT] <- []
519      var leftToMint = numToMint
520      while leftToMint > 0 {
521        template.registerMint()
522        let serial = template.minted()
523        let nft <-create NFT(
524          setId: setId,
525          templateId: templateId,
526          serial: serial
527        )
528        emit NFTMinted(
529          id: nft.id,
530          setId: setId,
531          templateId: templateId,
532          serial: serial
533        )
534        nfts.append(<-nft)
535        leftToMint = leftToMint - 1
536      }
537      return <-nfts
538    }
539
540    // ========================================================================
541    // NFT metadata
542    // ========================================================================
543
544    access(self) fun _getNFTMetadata(_ setId: Int, _ templateId: Int):
545      &MutableMetadata.Metadata{MutableMetadata.Public,
546        MutableMetadata.Private
547      } {
548        return self._getTemplateMutable(setId, templateId).metadataMutable()
549    }
550
551    pub fun lockNFTMetadata(setId: Int, templateId: Int) {
552      self._getNFTMetadata(setId, templateId).lock()
553      emit NFTMetadataLocked(setId: setId, templateId: templateId)
554    }
555
556    pub fun modifyNFTMetadata(setId: Int, templateId: Int): auth &AnyStruct {
557      emit NFTMetadataModified(setId: setId, templateId: templateId)
558      return self._getNFTMetadata(setId, templateId).getMutable()
559    }
560
561    pub fun replaceNFTMetadata(setId: Int, templateId: Int, new: AnyStruct) {
562      self._getNFTMetadata(setId, templateId).replace(new)
563      emit NFTMetadataModified(setId: setId, templateId: templateId)
564    }
565  }
566
567  // ========================================================================
568  // Contract functions
569  // ========================================================================
570
571  pub fun contract(): &{NiftoryNonFungibleToken.ManagerPublic} {
572    return NiftoryNFTRegistry
573      .getNFTManagerPublic(
574        Gamisodes.REGISTRY_ADDRESS,
575        Gamisodes.REGISTRY_BRAND
576      )
577  }
578
579  pub fun getViews(): [Type] {
580    let possibleViews = [
581      Type<MetadataViews.NFTCollectionDisplay>(),
582      Type<MetadataViews.ExternalURL>()
583    ]
584    let views: [Type] = [Type<MetadataViews.NFTCollectionData>()]
585
586    let viewManager = self.contract().getMetadataViewsManagerPublic()
587    for view in possibleViews {
588      if viewManager.inspectView(view: view) != nil {
589        views.append(view)
590      }
591    }
592    return views
593  }
594
595  pub fun resolveView(_ view: Type): AnyStruct? {
596    let viewManager = self.contract().getMetadataViewsManagerPublic()
597    switch view {
598
599      case Type<MetadataViews.NFTCollectionData>():
600        return self.contract().getNFTCollectionData()
601
602      case Type<MetadataViews.NFTCollectionDisplay>():
603        let maybeView = viewManager.inspectView(
604          view: Type<MetadataViews.NFTCollectionDisplay>()
605        )
606        if maybeView == nil {
607          return nil
608        }
609        let view = maybeView!
610
611        if view.isInstance(
612          Type<NiftoryMetadataViewsResolvers.NFTCollectionDisplayResolver>()
613        ) {
614          let resolver = view as! NiftoryMetadataViewsResolvers.NFTCollectionDisplayResolver
615
616          // External URL
617          let externalURL = MetadataViews.ExternalURL(url:
618            NiftoryMetadataViewsResolvers._prefixUri(
619              allowedPrefixes:
620                NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
621              default: resolver.defaultExternalURLPrefix,
622              uri: resolver.defaultExternalURL
623            )
624          )
625
626          // Square image
627          let squareImageURL = NiftoryMetadataViewsResolvers._prefixUri(
628            allowedPrefixes:
629              NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
630            default: resolver.defaultSquareImagePrefix,
631            uri: resolver.defaultSquareImage
632          )
633          let squareImageMediaType = resolver.defaultSquareImageMediaType
634          let squareImage = MetadataViews.Media(
635            file: MetadataViews.HTTPFile(url: squareImageURL),
636            mediaType: squareImageMediaType
637          )
638
639          // Banner image
640          let bannerImageURL = NiftoryMetadataViewsResolvers._prefixUri(
641            allowedPrefixes:
642              NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
643            default: resolver.defaultBannerImagePrefix,
644            uri: resolver.defaultBannerImage
645          )
646          let bannerImageMediaType = resolver.defaultBannerImageMediaType
647          let bannerImage = MetadataViews.Media(
648            file: MetadataViews.HTTPFile(
649              url: bannerImageURL
650            ),
651            mediaType: bannerImageMediaType
652          )
653
654          return MetadataViews.NFTCollectionDisplay(
655            name: resolver.defaultName,
656            description: resolver.defaultDescription,
657            externalURL: externalURL,
658            squareImage: squareImage,
659            bannerImage: bannerImage,
660            socials: {}
661
662          )
663        }
664
665        if view.isInstance(
666          Type<NiftoryMetadataViewsResolvers.NFTCollectionDisplayResolverWithIpfsGateway>()
667        ) {
668          let resolver = view as! NiftoryMetadataViewsResolvers.NFTCollectionDisplayResolverWithIpfsGateway
669
670          // External URL
671          let externalURL = MetadataViews.ExternalURL(url:
672            NiftoryMetadataViewsResolvers._prefixUri(
673              allowedPrefixes:
674                NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
675              default: resolver.defaultExternalURLPrefix,
676              uri: resolver.defaultExternalURL
677            )
678          )
679
680          // Square image
681          let squareImageURL = NiftoryMetadataViewsResolvers._useIpfsGateway(
682            ipfsGateway: resolver.ipfsGateway,
683            uri: NiftoryMetadataViewsResolvers._prefixUri(
684              allowedPrefixes:
685                NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
686              default: resolver.defaultSquareImagePrefix,
687              uri: resolver.defaultSquareImage
688            )
689        )
690          let squareImageMediaType = resolver.defaultSquareImageMediaType
691          let squareImage = MetadataViews.Media(
692            file: MetadataViews.HTTPFile(url: squareImageURL),
693            mediaType: squareImageMediaType
694          )
695
696          // Banner image
697          let bannerImageURL = NiftoryMetadataViewsResolvers._useIpfsGateway(
698            ipfsGateway: resolver.ipfsGateway,
699            uri: NiftoryMetadataViewsResolvers._prefixUri(
700              allowedPrefixes:
701                NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
702              default: resolver.defaultBannerImagePrefix,
703              uri: resolver.defaultBannerImage
704            )
705          )
706          let bannerImageMediaType = resolver.defaultBannerImageMediaType
707          let bannerImage = MetadataViews.Media(
708            file: MetadataViews.HTTPFile(
709              url: bannerImageURL
710            ),
711            mediaType: bannerImageMediaType
712          )
713
714          return MetadataViews.NFTCollectionDisplay(
715            name: resolver.defaultName,
716            description: resolver.defaultDescription,
717            externalURL: externalURL,
718            squareImage: squareImage,
719            bannerImage: bannerImage,
720            socials: {}
721          )
722        }
723
724        return nil
725
726      case Type<MetadataViews.ExternalURL>():
727        let maybeView = viewManager.inspectView(
728          view: Type<MetadataViews.ExternalURL>()
729        )
730        if maybeView == nil {
731          return nil
732        }
733        let view = maybeView!
734
735        if view.isInstance(
736          Type<NiftoryMetadataViewsResolvers.ExternalURLResolver>()
737        ) {
738          let resolver = view as! NiftoryMetadataViewsResolvers.ExternalURLResolver
739          return MetadataViews.ExternalURL(url:
740            NiftoryMetadataViewsResolvers._prefixUri(
741              allowedPrefixes:
742                NiftoryMetadataViewsResolvers.DEFAULT_ALLOWED_URI_PREFIXES(),
743              default: resolver.defaultPrefix,
744              uri: resolver.defaultURL
745            )
746          )
747        }
748
749        return nil
750      }
751      return nil
752
753  }
754
755  // ========================================================================
756  // Init
757  // ========================================================================
758
759  init(
760    nftManagerProxy: &{
761      NiftoryNonFungibleTokenProxy.Public,
762      NiftoryNonFungibleTokenProxy.Private
763    }
764  ) {
765
766    let record = NiftoryNFTRegistry.generateRecord(
767      account: self.account.address,
768      project: "cl9bquwn300010hkzt0td7pec_Gamisodes"
769    )
770
771    self.REGISTRY_ADDRESS = 0x32d62d5c43ad1038
772    self.REGISTRY_BRAND = "cl9bquwn300010hkzt0td7pec_Gamisodes"
773
774    self.COLLECTION_PUBLIC_PATH = record.collectionPaths.public
775    self.COLLECTION_PRIVATE_PATH = record.collectionPaths.private
776    self.COLLECTION_STORAGE_PATH = record.collectionPaths.storage
777
778    // No metadata to start with
779    self.metadata = nil
780
781    // Initialize the total supply to 0.
782    self.totalSupply = 0
783
784    // The Manager for this NFT
785    //
786    // NFT Manager storage
787    let nftManager <- create Manager()
788
789    // Save a MutableSetManager to this contract's storage, as the source of
790    // this NFT contract's metadata.
791    //
792    // MutableMetadataSetManager storage
793    self
794      .account
795      .save<@MutableMetadataSetManager.Manager>(
796        <-MutableMetadataSetManager.create(
797          name: "Gamisodes",
798          description: "The set manager for Gamisodes."
799        ),
800        to: record.setManager.paths.storage
801      )
802
803    // MutableMetadataSetManager public
804    self
805      .account
806      .link<&MutableMetadataSetManager.Manager{MutableMetadataSetManager.Public}>(
807        record.setManager.paths.public,
808        target: record.setManager.paths.storage
809      )
810
811    // MutableMetadataSetManager private
812    self
813      .account
814      .link<&
815        MutableMetadataSetManager.Manager{MutableMetadataSetManager.Public,
816        MutableMetadataSetManager.Private
817      }>(
818        record.setManager.paths.private,
819        target: record.setManager.paths.storage
820      )
821
822    // Save a MetadataViewsManager to this contract's storage, which will
823    // allow observers to inspect standardized metadata through any of its
824    // configured MetadataViews resolvers.
825    //
826    // MetadataViewsManager storage
827    self
828      .account
829      .save<@MetadataViewsManager.Manager>(
830        <-MetadataViewsManager.create(),
831        to: record.metadataViewsManager.paths.storage
832      )
833
834    // MetadataViewsManager public
835    self
836      .account
837      .link<&MetadataViewsManager.Manager{MetadataViewsManager.Public}>(
838        record.metadataViewsManager.paths.public,
839        target: record.metadataViewsManager.paths.storage
840      )
841
842    // MetadataViewsManager private
843    self
844      .account
845      .link<&
846        MetadataViewsManager.Manager{MetadataViewsManager.Private,
847        MetadataViewsManager.Public
848      }>(
849        record.metadataViewsManager.paths.private,
850        target: record.metadataViewsManager.paths.storage
851      )
852
853    let contractName = "Gamisodes"
854
855    // Royalties
856    let royaltiesResolver = NiftoryMetadataViewsResolvers.RoyaltiesResolver(
857        royalties: MetadataViews.Royalties([])
858    )
859    nftManager.setMetadataViewsResolver(royaltiesResolver)
860
861    // Collection Data
862    let collectionDataResolver
863        = NiftoryMetadataViewsResolvers.NFTCollectionDataResolver()
864    nftManager.setMetadataViewsResolver(collectionDataResolver)
865
866    // Display
867    let displayResolver = NiftoryMetadataViewsResolvers.DisplayResolver(
868        "title",
869        contractName.concat("NFT"),
870        "description",
871        contractName.concat(" NFT"),
872        "mediaUrl",
873        "ipfs://",
874        "ipfs://bafybeig6la3me5x3veull7jzxmwle4sfuaguou2is3o3z44ayhe7ihlqpa/NiftoryBanner.png"
875    )
876    nftManager.setMetadataViewsResolver(displayResolver)
877
878    // Collection Display
879    let collectionResolver = NiftoryMetadataViewsResolvers.NFTCollectionDisplayResolver(
880        "title",
881        contractName,
882        "description",
883        contractName.concat(" Collection"),
884        "domainUrl",
885        "https://",
886        "https://niftory.com",
887        "squareImage",
888        "ipfs://",
889        "ipfs://bafybeihc76uodw2at2xi2l5jydpvscj5ophfpqgblbrmsfpeffhcmgdtl4/squareImage.png",
890        "squareImageMediaType",
891        "image/png",
892        "bannerImage",
893        "ipfs://",
894        "ipfs://bafybeig6la3me5x3veull7jzxmwle4sfuaguou2is3o3z44ayhe7ihlqpa/NiftoryBanner.png",
895        "bannerImageMediaType",
896        "image/png",
897        []
898    )
899    nftManager.setMetadataViewsResolver(collectionResolver)
900
901    // ExternalURL
902    let externalURLResolver = NiftoryMetadataViewsResolvers.ExternalURLResolver(
903        "domainUrl",
904        "https://",
905        "https://niftory.com"
906    )
907    nftManager.setMetadataViewsResolver(externalURLResolver)
908
909    // Save NFT Manager
910    self
911      .account
912      .save<@Manager>(
913        <-nftManager,
914        to: record.nftManager.paths.storage
915      )
916
917    // NFT Manager public
918    self
919      .account
920      .link<&{NiftoryNonFungibleToken.ManagerPublic}>(
921        record.nftManager.paths.public,
922        target: record.nftManager.paths.storage
923      )
924
925    // NFT Manager private
926    self
927      .account
928      .link<&
929        Manager{NiftoryNonFungibleToken.ManagerPublic,
930        NiftoryNonFungibleToken.ManagerPrivate
931      }>(
932        record.nftManager.paths.private,
933        target: record.nftManager.paths.storage
934      )
935
936      nftManagerProxy.add(
937        registryAddress: self.REGISTRY_ADDRESS,
938        brand: self.REGISTRY_BRAND,
939        cap: self.account
940              .getCapability<&{
941                NiftoryNonFungibleToken.ManagerPrivate,
942                NiftoryNonFungibleToken.ManagerPublic
943              }>(
944                record.nftManager.paths.private
945              )
946      )
947  }
948}