Smart Contract

TouchstonePartyFlavorz

A.c4b1f4387748f389.TouchstonePartyFlavorz

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