Smart Contract

TouchstoneGalacticGourmet

A.c4b1f4387748f389.TouchstoneGalacticGourmet

Deployed

1d ago
Feb 26, 2026, 11:04:48 PM UTC

Dependents

0 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448 
3import FungibleToken from 0xf233dcee88fe0abe
4import FlowToken from 0x1654653399040a61
5import ViewResolver from 0x1d7e57aa55817448
6
7// CREATED BY: Touchstone (https://touchstone.city/), a platform crafted by your best friends at Emerald City DAO (https://ecdao.org/).
8// STATEMENT: This contract promises to keep the 5% royalty off of primary sales and 2.5% off of secondary sales to Emerald City DAO or risk permanent suspension from participation in the DAO and its tools.
9
10// import "NonFungibleToken"
11// import "MetadataViews"
12// import "FungibleToken"
13// import "FlowToken" 
14// import "ViewResolver"
15
16// import "MintVerifiers"  
17// import "FUSD"
18// import "EmeraldPass"
19
20
21access(all) contract TouchstoneGalacticGourmet: NonFungibleToken {
22
23	// Collection Information
24	access(self) let collectionInfo: {String: AnyStruct}
25
26	// Contract Information
27	access(all) var nextEditionId: UInt64
28	access(all) var nextMetadataId: UInt64
29	access(all) var totalSupply: UInt64
30
31	// Events
32	access(all) event ContractInitialized()
33	access(all) event Withdraw(id: UInt64, from: Address?)
34	access(all) event Deposit(id: UInt64, to: Address?)
35	access(all) event TouchstonePurchase(id: UInt64, recipient: Address, metadataId: UInt64, name: String, description: String, image: MetadataViews.IPFSFile, price: UFix64)
36	access(all) event Minted(id: UInt64, recipient: Address, metadataId: UInt64)
37	access(all) event MintBatch(metadataIds: [UInt64], recipients: [Address])
38
39	// Paths
40	access(all) let CollectionStoragePath: StoragePath
41	access(all) let CollectionPublicPath: PublicPath
42	access(all) let CollectionPrivatePath: PrivatePath
43	access(all) let AdministratorStoragePath: StoragePath
44
45	// Maps metadataId of NFT to NFTMetadata
46	access(account) let metadatas: {UInt64: NFTMetadata}
47
48	// Maps the metadataId of an NFT to the primary buyer
49	access(account) let primaryBuyers: {Address: {UInt64: [UInt64]}}
50
51	access(account) let nftStorage: @{Address: {UInt64: NFT}}
52
53	access(all) struct NFTMetadata {
54		access(all) let metadataId: UInt64
55		access(all) let name: String
56		access(all) let description: String 
57		// The main image of the NFT
58		access(all) let image: MetadataViews.IPFSFile
59		// An optional thumbnail that can go along with it
60		// for easier loading
61		access(all) let thumbnail: MetadataViews.IPFSFile?
62		// If price is nil, defaults to the collection price
63		access(all) let price: UFix64?
64		access(all) var extra: {String: AnyStruct}
65		access(all) let supply: UInt64
66		access(all) let purchasers: {UInt64: Address}
67
68		access(account) fun purchased(serial: UInt64, buyer: Address) {
69			self.purchasers[serial] = buyer
70		}
71
72		init(_name: String, _description: String, _image: MetadataViews.IPFSFile, _thumbnail: MetadataViews.IPFSFile?, _price: UFix64?, _extra: {String: AnyStruct}, _supply: UInt64) {
73			self.metadataId = TouchstoneGalacticGourmet.nextMetadataId
74			self.name = _name
75			self.description = _description
76			self.image = _image
77			self.thumbnail = _thumbnail
78			self.price = _price
79			self.extra = _extra
80			self.supply = _supply
81			self.purchasers = {}
82		}
83	}
84
85	access(all) resource NFT: NonFungibleToken.NFT, ViewResolver.Resolver {
86		// The 'id' is the same as the 'uuid'
87		access(all) let id: UInt64
88		// The 'metadataId' is what maps this NFT to its 'NFTMetadata'
89		access(all) let metadataId: UInt64
90		access(all) let serial: UInt64
91
92		access(all) fun getMetadata(): NFTMetadata {
93			return TouchstoneGalacticGourmet.getNFTMetadata(self.metadataId)!
94		}
95
96		access(all) view fun getViews(): [Type] {
97			return [
98				Type<MetadataViews.Display>(),
99				Type<MetadataViews.ExternalURL>(),
100				Type<MetadataViews.NFTCollectionData>(),
101				Type<MetadataViews.NFTCollectionDisplay>(),
102				Type<MetadataViews.Royalties>(),
103				Type<MetadataViews.Serial>(),
104				Type<MetadataViews.Traits>(),
105				Type<MetadataViews.NFTView>()
106			]
107		}
108
109		access(all) fun resolveView(_ view: Type): AnyStruct? {
110			switch view {
111				case Type<MetadataViews.Display>():
112					let metadata = self.getMetadata()
113					return MetadataViews.Display(
114						name: metadata.name,
115						description: metadata.description,
116						thumbnail: metadata.thumbnail ?? metadata.image
117					)
118				case Type<MetadataViews.NFTCollectionData>():
119					return MetadataViews.NFTCollectionData(
120						storagePath: TouchstoneGalacticGourmet.CollectionStoragePath,
121						publicPath: TouchstoneGalacticGourmet.CollectionPublicPath,
122						publicCollection: Type<&Collection>(),
123						publicLinkedType: Type<&Collection>(),
124						createEmptyCollectionFunction: (fun (): @{NonFungibleToken.Collection} {
125								return <- TouchstoneGalacticGourmet.createEmptyCollection(nftType: Type<@TouchstoneGalacticGourmet.NFT>())
126						})
127					)
128				case Type<MetadataViews.ExternalURL>():
129          return MetadataViews.ExternalURL("https://touchstone.city/discover/".concat(self.owner!.address.toString()).concat("/TouchstoneGalacticGourmet"))
130				case Type<MetadataViews.NFTCollectionDisplay>():
131					let squareMedia = MetadataViews.Media(
132						file: TouchstoneGalacticGourmet.getCollectionAttribute(key: "image") as! MetadataViews.IPFSFile,
133						mediaType: "image"
134					)
135
136					// If a banner image exists, use it
137					// Otherwise, default to the main square image
138					var bannerMedia: MetadataViews.Media? = nil
139					if let bannerImage = TouchstoneGalacticGourmet.getOptionalCollectionAttribute(key: "bannerImage") as! MetadataViews.IPFSFile? {
140						bannerMedia = MetadataViews.Media(
141							file: bannerImage,
142							mediaType: "image"
143						)
144					}
145					return MetadataViews.NFTCollectionDisplay(
146						name: TouchstoneGalacticGourmet.getCollectionAttribute(key: "name") as! String,
147						description: TouchstoneGalacticGourmet.getCollectionAttribute(key: "description") as! String,
148						externalURL: MetadataViews.ExternalURL("https://touchstone.city/discover/".concat(self.owner!.address.toString()).concat("/TouchstoneGalacticGourmet")),
149						squareImage: squareMedia,
150						bannerImage: bannerMedia ?? squareMedia,
151						socials: TouchstoneGalacticGourmet.getCollectionAttribute(key: "socials") as! {String: MetadataViews.ExternalURL}
152					)
153				case Type<MetadataViews.Royalties>():
154					return MetadataViews.Royalties([
155						// This is for Emerald City in favor of producing Touchstone, a free platform for our users. Failure to keep this in the contract may result in permanent suspension from Emerald City.
156						MetadataViews.Royalty(
157							receiver: getAccount(0x5643fd47a29770e7).capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver),
158							cut: 0.025, // 2.5% royalty on secondary sales
159							description: "Emerald City DAO receives a 2.5% royalty from secondary sales because this collection was created using Touchstone (https://touchstone.city/), a tool for creating your own NFT collections, crafted by Emerald City DAO."
160						)
161					])
162				case Type<MetadataViews.Serial>():
163					return MetadataViews.Serial(
164						self.serial
165					)
166				case Type<MetadataViews.Traits>():
167					return MetadataViews.dictToTraits(dict: self.getMetadata().extra, excludedNames: nil)
168				case Type<MetadataViews.NFTView>():
169					return MetadataViews.NFTView(
170						id: self.id,
171						uuid: self.uuid,
172						display: self.resolveView(Type<MetadataViews.Display>()) as! MetadataViews.Display?,
173						externalURL: self.resolveView(Type<MetadataViews.ExternalURL>()) as! MetadataViews.ExternalURL?,
174						collectionData: self.resolveView(Type<MetadataViews.NFTCollectionData>()) as! MetadataViews.NFTCollectionData?,
175						collectionDisplay: self.resolveView(Type<MetadataViews.NFTCollectionDisplay>()) as! MetadataViews.NFTCollectionDisplay?,
176						royalties: self.resolveView(Type<MetadataViews.Royalties>()) as! MetadataViews.Royalties?,
177						traits: self.resolveView(Type<MetadataViews.Traits>()) as! MetadataViews.Traits?
178					)
179			}
180			return nil
181		}
182
183
184		init(_metadataId: UInt64, _serial: UInt64, _recipient: Address) {
185			pre {
186				TouchstoneGalacticGourmet.metadatas[_metadataId] != nil:
187					"This NFT does not exist yet."
188				_serial < TouchstoneGalacticGourmet.getNFTMetadata(_metadataId)!.supply:
189					"This serial does not exist for this metadataId."
190				!TouchstoneGalacticGourmet.getNFTMetadata(_metadataId)!.purchasers.containsKey(_serial):
191					"This serial has already been purchased."
192			}
193			self.id = self.uuid
194			self.metadataId = _metadataId
195			self.serial = _serial
196
197			// Update the buyers list so we keep track of who is purchasing
198			// if let buyersRef: auth(Mutate) &{UInt64: [UInt64]} = &TouchstoneGalacticGourmet.primaryBuyers[_recipient] {
199			// 	if let metadataIdMap: &[UInt64] = buyersRef[_metadataId] {
200			// 		metadataIdMap.append(_serial)
201			// 	} else {
202			// 		buyersRef[_metadataId] = [_serial]
203			// 	}
204			// } else {
205			// 	TouchstoneGalacticGourmet.primaryBuyers[_recipient] = {_metadataId: [_serial]}
206			// }
207
208			// Update who bought this serial inside NFTMetadata so it cannot be purchased again.
209			let metadataRef = (&TouchstoneGalacticGourmet.metadatas[_metadataId] as &NFTMetadata?)!
210			metadataRef.purchased(serial: _serial, buyer: _recipient)
211
212			TouchstoneGalacticGourmet.totalSupply = TouchstoneGalacticGourmet.totalSupply + 1
213			emit Minted(id: self.id, recipient: _recipient, metadataId: _metadataId)
214		}
215
216		access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
217            return <- TouchstoneGalacticGourmet.createEmptyCollection(nftType: Type<@TouchstoneGalacticGourmet.NFT>())
218        }
219	}
220
221	access(all) resource Collection: NonFungibleToken.Collection, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, ViewResolver.ResolverCollection {
222		// dictionary of NFT conforming tokens
223		// NFT is a resource type with an 'UInt64' ID field
224        access(all) var ownedNFTs: @{UInt64: {NonFungibleToken.NFT}}
225
226		// withdraw removes an NFT from the collection and moves it to the caller
227		access(NonFungibleToken.Withdraw) fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT} {        
228			let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
229
230			emit Withdraw(id: token.id, from: self.owner?.address)
231
232			return <-token
233		}
234
235		// deposit takes a NFT and adds it to the collections dictionary
236		// and adds the ID to the id array
237		access(all) fun deposit(token: @{NonFungibleToken.NFT}) {
238            let token: @TouchstoneGalacticGourmet.NFT <- token as! @TouchstoneGalacticGourmet.NFT
239
240            let id: UInt64 = token.id
241
242            // add the new token to the dictionary which removes the old one
243            let oldToken: @{NonFungibleToken.NFT}? <- self.ownedNFTs[id] <- token
244
245            emit Deposit(id: id, to: self.owner?.address)
246
247            destroy oldToken
248        }
249
250		// getIDs returns an array of the IDs that are in the collection
251		access(all) view fun getIDs(): [UInt64] {
252			return self.ownedNFTs.keys
253		}
254
255		access(all) view fun getLength(): Int {
256            return self.ownedNFTs.length
257        }
258
259        access(all) fun forEachID(_ f: fun (UInt64): Bool): Void {}
260
261        /// getSupportedNFTTypes returns a list of NFT types that this receiver accepts
262        access(all) view fun getSupportedNFTTypes(): {Type: Bool} {
263            let supportedTypes: {Type: Bool} = {}
264            supportedTypes[Type<@TouchstoneGalacticGourmet.NFT>()] = true
265            return supportedTypes
266        }
267
268        /// Returns whether or not the given type is accepted by the collection
269        /// A collection that can accept any type should just return true by default
270        access(all) view fun isSupportedNFTType(type: Type): Bool {
271            return type == Type<@TouchstoneGalacticGourmet.NFT>()
272        }
273
274		// borrowNFT gets a reference to an NFT in the collection
275		// so that the caller can read its metadata and call its methods
276		access(all) view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}? {
277            return (&self.ownedNFTs[id])
278        }
279
280		access(all) view fun borrowViewResolver(id: UInt64): &{ViewResolver.Resolver}? {
281          pre {
282            self.ownedNFTs[id] != nil : "NFT not in collection"
283          }
284          let nft: &{NonFungibleToken.NFT} = (&self.ownedNFTs[id])!
285          let tokenRef = nft as! &TouchstoneGalacticGourmet.NFT
286          return tokenRef
287        }
288
289		access(all) fun claim() {
290			if let storage: auth(Remove, Mutate) &{UInt64: TouchstoneGalacticGourmet.NFT} = &TouchstoneGalacticGourmet.nftStorage[self.owner!.address] {
291				for id in storage.keys {
292					self.deposit(token: <- storage.remove(key: id)!)
293				}
294			}
295		}
296		
297		access(all) fun createEmptyCollection(): @{NonFungibleToken.Collection} {
298            return <- TouchstoneGalacticGourmet.createEmptyCollection(nftType: Type<@TouchstoneGalacticGourmet.NFT>())
299        }
300
301		init () {
302			self.ownedNFTs <- {}
303		}
304	}
305
306	// A function to mint NFTs. 
307	// You can only call this function if minting
308	// is currently active.
309	access(all) fun mintNFT(metadataId: UInt64, recipient: &{NonFungibleToken.Receiver}, payment: @FlowToken.Vault, serial: UInt64): UInt64 {
310		pre {
311			self.canMint(): "Minting is currently closed by the Administrator!"
312			payment.balance == self.getPriceOfNFT(metadataId): 
313				"Payment does not match the price. You passed in ".concat(payment.balance.toString()).concat(" but this NFT costs ").concat(self.getPriceOfNFT(metadataId)!.toString())
314		}
315		let price: UFix64 = self.getPriceOfNFT(metadataId)!
316
317		// Confirm recipient passes all verifiers
318		// for verifier in self.getMintVerifiers() {
319		// 	let params = {"minter": recipient.owner!.address}
320		// 	if let error = verifier.verify(params) {
321		// 		panic(error)
322		// 	}
323		// }
324
325		// Handle Emerald City DAO royalty (5%)
326		let EmeraldCityTreasury: &FlowToken.Vault = getAccount(0x5643fd47a29770e7).capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver)
327								.borrow()!
328		let emeraldCityCut: UFix64 = 0.05 * price
329
330		// Handle royalty to user that was configured upon creation
331		if let royalty = TouchstoneGalacticGourmet.getOptionalCollectionAttribute(key: "royalty") as! MetadataViews.Royalty? {
332			royalty.receiver.borrow()!.deposit(from: <- payment.withdraw(amount: price * royalty.cut))
333		}
334
335		EmeraldCityTreasury.deposit(from: <- payment.withdraw(amount: emeraldCityCut))
336
337		// Give the rest to the collection owner
338		let paymentRecipient = self.account.capabilities.get<&FlowToken.Vault>(/public/flowTokenReceiver)
339								.borrow()!
340		paymentRecipient.deposit(from: <- payment)
341
342		// Mint the nft 
343		let nft <- create NFT(_metadataId: metadataId, _serial: serial, _recipient: recipient.owner!.address)
344		let nftId: UInt64 = nft.id
345		let metadata = self.getNFTMetadata(metadataId)!
346		self.collectionInfo["profit"] = (self.getCollectionAttribute(key: "profit") as! UFix64) + price
347
348		// Emit event
349		emit TouchstonePurchase(id: nftId, recipient: recipient.owner!.address, metadataId: metadataId, name: metadata.name, description: metadata.description, image: metadata.image, price: price)
350		
351		// Deposit nft
352		recipient.deposit(token: <- nft)
353
354		return nftId
355	}
356
357	access(all) resource Administrator {
358		access(all) fun createNFTMetadata(name: String, description: String, imagePath: String, thumbnailPath: String?, ipfsCID: String, price: UFix64?, extra: {String: AnyStruct}, supply: UInt64) {
359			TouchstoneGalacticGourmet.metadatas[TouchstoneGalacticGourmet.nextMetadataId] = NFTMetadata(
360				_name: name,
361				_description: description,
362				_image: MetadataViews.IPFSFile(
363					cid: ipfsCID,
364					path: imagePath
365				),
366				_thumbnail: thumbnailPath == nil ? nil : MetadataViews.IPFSFile(cid: ipfsCID, path: thumbnailPath),
367				_price: price,
368				_extra: extra,
369				_supply: supply
370			)
371			TouchstoneGalacticGourmet.nextMetadataId = TouchstoneGalacticGourmet.nextMetadataId + 1
372		}
373
374		// mintNFT mints a new NFT and deposits 
375		// it in the recipients collection
376		access(all) fun mintNFT(metadataId: UInt64, serial: UInt64, recipient: Address) {
377			pre {
378				// EmeraldPass.isActive(user: TouchstoneGalacticGourmet.account.address): "You must have an active Emerald Pass subscription to airdrop NFTs. You can purchase Emerald Pass at https://pass.ecdao.org/"
379			}
380			let nft <- create NFT(_metadataId: metadataId, _serial: serial, _recipient: recipient)
381			if let recipientCollection = getAccount(recipient).capabilities.get<&TouchstoneGalacticGourmet.Collection>(TouchstoneGalacticGourmet.CollectionPublicPath).borrow() {
382				recipientCollection.deposit(token: <- nft)
383			} else {
384				if let storage: auth(Mutate) &{UInt64: TouchstoneGalacticGourmet.NFT} = &TouchstoneGalacticGourmet.nftStorage[recipient]  {
385					storage[nft.id] <-! nft
386				} else {
387					TouchstoneGalacticGourmet.nftStorage[recipient] <-! {nft.id: <- nft}
388				}
389			}
390		}
391
392		access(all) fun mintBatch(metadataIds: [UInt64], serials: [UInt64], recipients: [Address]) {
393			pre {
394				metadataIds.length == recipients.length: "You need to pass in an equal number of metadataIds and recipients."
395			}
396			var i = 0
397			while i < metadataIds.length {
398				self.mintNFT(metadataId: metadataIds[i], serial: serials[i], recipient: recipients[i])
399				i = i + 1
400			}
401
402			emit MintBatch(metadataIds: metadataIds, recipients: recipients)
403		}
404
405		// create a new Administrator resource
406		access(all) fun createAdmin(): @Administrator {
407			return <- create Administrator()
408		}
409
410		// change piece of collection info
411		access(all) fun changeField(key: String, value: AnyStruct) {
412			TouchstoneGalacticGourmet.collectionInfo[key] = value
413		}
414	}
415
416	// public function that anyone can call to create a new empty collection
417	access(all) fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection} {
418        return <- create Collection()
419    }
420
421	// Get information about a NFTMetadata
422	access(all) view fun getNFTMetadata(_ metadataId: UInt64): NFTMetadata? {
423		return self.metadatas[metadataId]
424	}
425
426	access(all) view fun getNFTMetadatas(): {UInt64: NFTMetadata} {
427		return self.metadatas
428	}
429
430	access(all) view fun getPrimaryBuyers(): {Address: {UInt64: [UInt64]}} {
431		return self.primaryBuyers
432	}
433
434	access(all) view fun getCollectionInfo(): {String: AnyStruct} {
435		let collectionInfo = self.collectionInfo
436		collectionInfo["metadatas"] = self.metadatas
437		collectionInfo["primaryBuyers"] = self.primaryBuyers
438		collectionInfo["totalSupply"] = self.totalSupply
439		collectionInfo["nextMetadataId"] = self.nextMetadataId
440		collectionInfo["version"] = 1
441		return collectionInfo
442	}
443
444	access(all) view fun getCollectionAttribute(key: String): AnyStruct {
445		return self.collectionInfo[key] ?? panic(key.concat(" is not an attribute in this collection."))
446	}
447
448	access(all) view fun getOptionalCollectionAttribute(key: String): AnyStruct? {
449		return self.collectionInfo[key]
450	}
451
452	// access(all) fun getMintVerifiers(): [{MintVerifiers.IVerifier}] {
453	// 	return self.getCollectionAttribute(key: "mintVerifiers") as! [{MintVerifiers.IVerifier}]
454	// }
455
456	access(all) view fun canMint(): Bool {
457		return self.getCollectionAttribute(key: "minting") as! Bool
458	}
459
460	// Returns nil if an NFT with this metadataId doesn't exist
461	access(all) view fun getPriceOfNFT(_ metadataId: UInt64): UFix64? {
462		if let metadata: TouchstoneGalacticGourmet.NFTMetadata = self.getNFTMetadata(metadataId) {
463			let defaultPrice: UFix64 = self.getCollectionAttribute(key: "price") as! UFix64
464			if self.getCollectionAttribute(key: "lotteryBuying") as! Bool {
465				return defaultPrice
466			}
467			return metadata.price ?? defaultPrice
468		}
469		// If the metadataId doesn't exist
470		return nil
471	}
472
473	// Returns an mapping of id to NFTMetadata
474	// for the NFTs a user can claim
475	access(all) view fun getClaimableNFTs(user: Address): {UInt64: NFTMetadata} {
476		let answer: {UInt64: NFTMetadata} = {}
477		if let storage = &TouchstoneGalacticGourmet.nftStorage[user] as &{UInt64: NFT}? {
478			for id in storage.keys {
479				let nftRef = (storage[id])!
480				answer[id] = self.getNFTMetadata(nftRef.metadataId)
481			}
482		}
483		return answer
484	}
485
486	access(all) view fun getContractViews(resourceType: Type?): [Type] {
487		return [
488			Type<MetadataViews.NFTCollectionData>()
489		]
490	}
491
492	access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
493		return nil
494	}
495
496	init(
497		_name: String, 
498		_description: String, 
499		_imagePath: String, 
500		_bannerImagePath: String?,
501		_minting: Bool, 
502		_royalty: MetadataViews.Royalty?,
503		_defaultPrice: UFix64,
504		_paymentType: String,
505		_ipfsCID: String,
506		_lotteryBuying: Bool,
507		_socials: {String: MetadataViews.ExternalURL}
508		// _mintVerifiers: [{MintVerifiers.IVerifier}]
509	) {
510		// Collection Info
511		self.collectionInfo = {}
512		self.collectionInfo["name"] = _name
513		self.collectionInfo["description"] = _description
514		self.collectionInfo["image"] = MetadataViews.IPFSFile(
515			cid: _ipfsCID,
516			path: _imagePath
517		)
518		if let bannerImagePath = _bannerImagePath {
519			self.collectionInfo["bannerImage"] = MetadataViews.IPFSFile(
520				cid: _ipfsCID,
521				path: _bannerImagePath
522			)
523		}
524		self.collectionInfo["ipfsCID"] = _ipfsCID
525		self.collectionInfo["socials"] = _socials
526		self.collectionInfo["minting"] = _minting
527		self.collectionInfo["lotteryBuying"] = _lotteryBuying
528		if let royalty = _royalty {
529			assert(royalty.receiver.check(), message: "The passed in royalty receiver is not valid. The royalty account must set up the intended payment token.")
530			assert(royalty.cut <= 0.95, message: "The royalty cut cannot be bigger than 95% because 5% goes to Emerald City treasury for primary sales.")
531			self.collectionInfo["royalty"] = royalty
532		}
533		self.collectionInfo["price"] = _defaultPrice
534		self.collectionInfo["paymentType"] = _paymentType
535		self.collectionInfo["dateCreated"] = getCurrentBlock().timestamp
536		// self.collectionInfo["mintVerifiers"] = _mintVerifiers
537		self.collectionInfo["profit"] = 0.0
538
539		self.nextEditionId = 0
540		self.nextMetadataId = 0
541		self.totalSupply = 0
542		self.metadatas = {}
543		self.primaryBuyers = {}
544		self.nftStorage <- {}
545
546		// Set the named paths
547		// We include the user's address in the paths.
548		// This is to prevent clashing with existing 
549		// Collection paths in the ecosystem.
550		self.CollectionStoragePath = /storage/TouchstoneGalacticGourmetCollection_0xc4b1f4387748f389
551		self.CollectionPublicPath = /public/TouchstoneGalacticGourmetCollection_0xc4b1f4387748f389
552		self.CollectionPrivatePath = /private/TouchstoneGalacticGourmetCollection_0xc4b1f4387748f389
553		self.AdministratorStoragePath = /storage/TouchstoneGalacticGourmetAdministrator_0xc4b1f4387748f389
554
555		// Create a Collection resource and save it to storage
556		let collection <- create Collection()
557		self.account.storage.save(<- collection, to: self.CollectionStoragePath)
558
559		// create a public capability for the collectio
560		let cap = self.account.capabilities.storage.issue<&Collection>(self.CollectionStoragePath)
561        self.account.capabilities.publish(cap, at: self.CollectionPublicPath)
562
563
564		// Create a Administrator resource and save it to storage
565		let administrator <- create Administrator()
566		self.account.storage.save(<- administrator, to: self.AdministratorStoragePath)
567
568		emit ContractInitialized()
569	}
570}
571