Smart Contract
NFTMetadata
A.befbaccb5032a457.NFTMetadata
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3
4access(all) contract NFTMetadata {
5 access(all) entitlement Owner
6
7 access(all) event MetadataFrozen(uuid: UInt64, owner: Address?)
8
9 access(all) struct CollectionInfo {
10 access(all) var collectionDisplay: MetadataViews.NFTCollectionDisplay
11
12 access(all) let data: {String: AnyStruct}
13
14 access(all) fun getDisplay(): MetadataViews.NFTCollectionDisplay {
15 return self.collectionDisplay
16 }
17
18 init(collectionDisplay: MetadataViews.NFTCollectionDisplay) {
19 self.collectionDisplay = collectionDisplay
20
21 self.data = {}
22 }
23 }
24
25 access(all) struct Metadata {
26 // these are used to create the display metadata view so that we can concatenate
27 // the id onto it.
28 access(all) let name: String
29 access(all) let description: String
30 access(all) let thumbnail: {MetadataViews.File}
31
32 access(all) let traits: MetadataViews.Traits?
33 access(all) let editions: MetadataViews.Editions?
34 access(all) let externalURL: MetadataViews.ExternalURL?
35 access(all) let royalties: MetadataViews.Royalties?
36
37 access(all) let data: {String: AnyStruct}
38
39 access(all) fun getThumbnail(): {MetadataViews.File} {
40 return self.thumbnail
41 }
42
43 access(all) fun getTraits(): MetadataViews.Traits? {
44 return self.traits
45 }
46
47 access(all) fun getEditions(): MetadataViews.Editions? {
48 return self.editions
49 }
50
51 access(all) fun getExternalURL(): MetadataViews.ExternalURL? {
52 return self.externalURL
53 }
54
55 access(all) fun getRoyalties(): MetadataViews.Royalties? {
56 return self.royalties
57 }
58
59 init(
60 name: String,
61 description: String,
62 thumbnail: {MetadataViews.File},
63 traits: MetadataViews.Traits?,
64 editions: MetadataViews.Editions?,
65 externalURL: MetadataViews.ExternalURL?,
66 royalties: MetadataViews.Royalties?,
67 data: {String: AnyStruct}
68 ) {
69 self.name = name
70 self.description = description
71 self.thumbnail = thumbnail
72
73 self.traits = traits
74 self.editions = editions
75 self.externalURL = externalURL
76 self.royalties = royalties
77
78 self.data = {}
79 }
80 }
81
82 access(all) resource Container {
83 access(all) var collectionInfo: CollectionInfo
84 access(all) let metadata: {UInt64: Metadata}
85 access(all) var frozen: Bool
86
87 access(all) let data: {String: AnyStruct}
88 access(all) let resources: @{String: AnyResource}
89
90 access(all) fun borrowMetadata(id: UInt64): &Metadata? {
91 return &self.metadata[id]
92 }
93
94 access(Owner) fun addMetadata(id: UInt64, data: Metadata) {
95 pre {
96 self.metadata[id] == nil: "id already has metadata assigned"
97 !self.frozen: "metadata is frozen and cannot be updated"
98 }
99
100 self.metadata[id] = data
101 }
102
103 access(Owner) fun freeze() {
104 self.frozen = true
105 emit MetadataFrozen(uuid: self.uuid, owner: self.owner?.address)
106 }
107
108 init(collectionInfo: CollectionInfo) {
109 self.collectionInfo = collectionInfo
110 self.metadata = {}
111 self.frozen = false
112
113 self.data = {}
114 self.resources <- {}
115 }
116 }
117
118 access(all) struct InitializedCaps {
119 access(all) let pubCap: Capability<&Container>
120 access(all) let ownerCap: Capability<auth(Owner) &Container>
121
122 access(all) let data: {String: AnyStruct}
123
124 init(pubCap: Capability<&Container>, ownerCap: Capability<auth(Owner) &Container>) {
125 self.pubCap = pubCap
126 self.ownerCap = ownerCap
127
128 self.data = {}
129 }
130 }
131
132 access(all) fun createContainer(collectionInfo: CollectionInfo): @Container {
133 return <- create Container(collectionInfo: collectionInfo)
134 }
135
136 access(all) fun initialize(acct: auth(Storage, Capabilities) &Account, collectionInfo: CollectionInfo, nftType: Type): InitializedCaps {
137 let storagePath = self.getCollectionStoragePath(type: nftType)
138 let container <- self.createContainer(collectionInfo: collectionInfo)
139 acct.storage.save(<-container, to: storagePath)
140 let pubCap = acct.capabilities.storage.issue<&Container>(storagePath)
141 let ownerCap = acct.capabilities.storage.issue<auth(Owner) &Container>(storagePath)
142 return InitializedCaps(pubCap: pubCap, ownerCap: ownerCap)
143 }
144
145 access(all) struct UriFile: MetadataViews.File {
146 access(self) let url: String
147
148 access(all) view fun uri(): String {
149 return self.url
150 }
151
152 init(_ url: String) {
153 self.url = url
154 }
155 }
156
157 access(all) fun getCollectionStoragePath(type: Type): StoragePath {
158 let segments = type.identifier.split(separator: ".")
159 return StoragePath(identifier: "NFTMetadataContainer_".concat(segments[2]).concat("_").concat(segments[1]))!
160 }
161}