Smart Contract
MatrixWorldVoucher
A.0d77ec47bbad8ef6.MatrixWorldVoucher
1import NonFungibleToken from 0x1d7e57aa55817448
2import ViewResolver from 0x1d7e57aa55817448
3import MetadataViews from 0x1d7e57aa55817448
4import FungibleToken from 0xf233dcee88fe0abe
5
6access(all) contract MatrixWorldVoucher: NonFungibleToken {
7 access(all) event ContractInitialized()
8 access(all) event Withdraw(id: UInt64, from: Address?)
9 access(all) event Deposit(id: UInt64, to: Address?)
10 access(all) event Minted(id: UInt64, name: String, description:String, animationUrl:String, hash: String, type: String)
11
12 access(all) let CollectionStoragePath: StoragePath
13 access(all) let CollectionPublicPath: PublicPath
14 access(all) let MinterStoragePath: StoragePath
15
16 access(all) var totalSupply: UInt64
17 access(self) var nftHashes: {String: Bool}
18
19 access(all) fun isHashExists(hash: String): Bool {
20 return self.nftHashes[hash] ?? false
21 }
22
23 access(all) resource interface NFTPublic {
24 access(all) let id: UInt64
25 access(all) let metadata: Metadata
26 }
27
28 access(all) struct Metadata {
29 access(all) let name: String
30 access(all) let description: String
31 access(all) let animationUrl: String
32 access(all) let hash: String
33 access(all) let type: String
34
35 init(name: String, description: String, animationUrl: String, hash: String, type: String) {
36 self.name = name
37 self.description = description
38 self.animationUrl = animationUrl
39 self.hash = hash
40 self.type = type
41 }
42 }
43
44 access(all) resource NFT: NonFungibleToken.NFT, NFTPublic {
45 access(all) let id: UInt64
46 access(all) let metadata: Metadata
47 init(initID: UInt64,metadata: Metadata) {
48 self.id = initID
49 self.metadata = metadata
50 }
51
52 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
53 return <- create Collection()
54 }
55
56 access(all) view fun getViews(): [Type] {
57 return [
58 Type<MetadataViews.Display>(),
59 Type<MetadataViews.ExternalURL>(),
60 Type<MetadataViews.Serial>(),
61 Type<MetadataViews.NFTCollectionData>(),
62 Type<MetadataViews.NFTCollectionDisplay>(),
63 Type<MetadataViews.EVMBridgedMetadata>(),
64 Type<MetadataViews.Royalties>()
65 ]
66 }
67
68 access(all) fun resolveView(_ view: Type): AnyStruct? {
69 switch view {
70 case Type<MetadataViews.Display>():
71 return MetadataViews.Display(
72 name: self.metadata.name,
73 description: self.metadata.description,
74 thumbnail: MetadataViews.HTTPFile(
75 url:"https://assets.matrixworld.org/land/flow/thumbnails/".concat(self.id.toString().concat(".png"))
76 )
77 )
78 case Type<MetadataViews.Royalties>():
79 return MetadataViews.Royalties([])
80 case Type<MetadataViews.Serial>():
81 return MetadataViews.Serial(self.id)
82 case Type<MetadataViews.ExternalURL>():
83 return MetadataViews.ExternalURL("https://api.matrixworld.org/land/api/v1/land/metadata/estate/flow/".concat(self.id.toString()))
84 case Type<MetadataViews.NFTCollectionData>():
85 return MatrixWorldVoucher.resolveContractView(resourceType: Type<@MatrixWorldVoucher.NFT>(), viewType: Type<MetadataViews.NFTCollectionData>())
86 case Type<MetadataViews.NFTCollectionDisplay>():
87 return MatrixWorldVoucher.resolveContractView(resourceType: Type<@MatrixWorldVoucher.NFT>(), viewType: Type<MetadataViews.NFTCollectionDisplay>())
88 case Type<MetadataViews.EVMBridgedMetadata>():
89 let baseURI = "https://api.matrixworld.org/land/api/v1/land/metadata/estate/flow/"
90 let uriValue = self.id.toString()
91 return MetadataViews.EVMBridgedMetadata(
92 name: "MatrixWorldLandVoucher",
93 symbol: "MWLV",
94 uri: MetadataViews.URI(
95 baseURI: baseURI, // defining baseURI results in a concatenation of baseURI and value
96 value: uriValue
97 )
98 )
99
100 }
101 return nil
102 }
103 }
104
105
106
107 access(all) resource interface MatrixWorldVoucherCollectionPublic {}
108
109 access(all) resource Collection: MatrixWorldVoucherCollectionPublic, NonFungibleToken.Collection {
110 access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
111
112 init () {
113 self.ownedNFTs <- {}
114 }
115
116 /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
117 access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
118 let supportedTypes: {Type: Bool} = {}
119 supportedTypes[Type<@MatrixWorldVoucher.NFT>()] = true
120 return supportedTypes
121 }
122
123 /// Returns whether or not the given type is accepted by the collection
124 /// A collection that can accept any type should just return true by default
125 access(all) view fun isSupportedNFTType(type: Type): Bool {
126 return type == Type<@MatrixWorldVoucher.NFT>()
127 }
128
129 access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {
130 let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
131
132 emit Withdraw(id: token.id, from: self.owner?.address)
133
134 return <-token
135 }
136
137 access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
138 let token <- token as! @MatrixWorldVoucher.NFT
139
140 let id: UInt64 = token.id
141
142 let oldToken <- self.ownedNFTs[id] <- token
143
144 emit Deposit(id: id, to: self.owner?.address)
145
146 destroy oldToken
147 }
148
149
150 access(all) view fun getIDs(): [UInt64] {
151 return self.ownedNFTs.keys
152 }
153
154 /// Gets the amount of NFTs stored in the collection
155 access(all) view fun getLength(): Int {
156 return self.ownedNFTs.length
157 }
158
159 access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
160 return &self.ownedNFTs[id]
161 }
162
163 /// Borrow the view resolver for the specified NFT ID
164 access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
165 if let nft = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}? {
166 return nft as &{ViewResolver.Resolver}
167 }
168 return nil
169 }
170
171 access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
172 return <- create Collection()
173 }
174
175 }
176
177
178 access(all) view fun getContractViews(resourceType: Type?): [Type] {
179 return [
180 Type<MetadataViews.NFTCollectionData>(),
181 Type<MetadataViews.NFTCollectionDisplay>(),
182 Type<MetadataViews.EVMBridgedMetadata>()
183 ]
184 }
185
186 access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
187 return <- create Collection()
188 }
189
190 access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
191 switch viewType {
192 case Type<MetadataViews.NFTCollectionData>():
193 let collectionsData = MetadataViews.NFTCollectionData(
194 storagePath: self.CollectionStoragePath,
195 publicPath: self.CollectionPublicPath,
196 publicCollection: Type<&MatrixWorldVoucher.Collection>(),
197 publicLinkedType: Type<&MatrixWorldVoucher.Collection>(),
198 createEmptyCollectionFunction: (fun(): @{NonFungibleToken.Collection} {
199 return <-MatrixWorldVoucher.createEmptyCollection(nftType: Type<@MatrixWorldVoucher.NFT>())
200 })
201 )
202 return collectionsData
203 case Type<MetadataViews.NFTCollectionDisplay>():
204 let squareMedia= MetadataViews.Media(
205 file: MetadataViews.HTTPFile(
206 url: "https://world3.ai/assets/WORLD3Logo_black.png"
207 ),
208 mediaType: "image/png"
209 )
210 let bannerMedia= MetadataViews.Media(
211 file: MetadataViews.HTTPFile(
212 url: "https://world3.ai/assets/Matrixworld_poster.png"
213 ),
214 mediaType: "image/png"
215 )
216 return MetadataViews.NFTCollectionDisplay(
217 name: "WORLD3 Land Voucher",
218 description: "WORLD3 Land Voucher is a collection of NFTs that represent the ownership of a piece of land in the WORLD3 Metaverse. Each NFT is unique and can be used to claim the ownership of a specific piece of land in the WORLD3 Space.",
219 externalURL: MetadataViews.ExternalURL("https://world3.ai/"),
220 squareImage: squareMedia,
221 bannerImage: bannerMedia,
222 socials: {
223 "twitter": MetadataViews.ExternalURL("https://x.com/WORLD3_AI")
224 }
225 )
226 case Type<MetadataViews.EVMBridgedMetadata>():
227 let baseURI = "https://api.matrixworld.org/land/api/v1/land/metadata/estate/flow/"
228 return MetadataViews.EVMBridgedMetadata(
229 name: "MatrixWorldLandVoucher",
230 symbol: "MWLV",
231 uri: MetadataViews.URI(
232 baseURI: baseURI,
233 value: ""
234 )
235 )
236 default:
237 return nil
238 }
239 }
240
241
242 access(all) struct NftData {
243 access(all) let metadata: MatrixWorldVoucher.Metadata
244 access(all) let id: UInt64
245 init(metadata: MatrixWorldVoucher.Metadata, id: UInt64) {
246 self.metadata = metadata
247 self.id = id
248 }
249 }
250
251 access(all) resource NFTMinter {
252 access(all) fun mintNFT(
253 recipient: &{NonFungibleToken.CollectionPublic},
254 name: String,
255 description: String,
256 animationUrl: String,
257 hash: String,
258 type: String) {
259 assert(!MatrixWorldVoucher.nftHashes.containsKey(hash), message: "Duplicate voucher hash")
260 recipient.deposit(token: <-create MatrixWorldVoucher.NFT(
261 initID: MatrixWorldVoucher.totalSupply,
262 metadata: Metadata(
263 name: name,
264 description:description,
265 animationUrl: animationUrl,
266 hash: hash,
267 type: type
268 )))
269
270 MatrixWorldVoucher.totalSupply = MatrixWorldVoucher.totalSupply + 1
271 MatrixWorldVoucher.nftHashes[hash] = true;
272 }
273 }
274
275 init() {
276 self.CollectionStoragePath = /storage/MatrixWorldVoucherCollection
277 self.CollectionPublicPath = /public/MatrixWorldVoucherCollection
278 self.MinterStoragePath = /storage/MatrixWorldVoucherMinter
279
280 self.totalSupply = 0
281 self.nftHashes = {}
282
283 let minter <- create NFTMinter()
284 self.account.storage.save(<-minter, to: self.MinterStoragePath)
285
286 emit ContractInitialized()
287 }
288}
289