Smart Contract

TheFabricantMarketplaceHelper

A.7752ea736384322f.TheFabricantMarketplaceHelper

Deployed

3h ago
Feb 28, 2026, 08:14:46 PM UTC

Dependents

0 imports
1/*
2	Description: The Marketplace Helper Contract for TheFabricant NFTs
3   
4	the purpose of this contract is to enforce the SaleCut array when a listing is created or an offer is made for a nft
5	the main problem with the marketplace contract is the SaleCut is made during the transaction, and not enforced in the contract
6	currently only enforces ItemNFT and TheFabricantS1ItemNFT nfts
7	uses FlowToken as payment method
8*/
9
10import NonFungibleToken from 0x1d7e57aa55817448
11
12import FungibleToken from 0xf233dcee88fe0abe
13
14import FlowToken from 0x1654653399040a61
15
16import GarmentNFT from 0xfc91de5e6566cc7c
17
18import MaterialNFT from 0xfc91de5e6566cc7c
19
20import ItemNFT from 0xfc91de5e6566cc7c
21
22import TheFabricantS1GarmentNFT from 0x09e03b1f871b3513
23
24import TheFabricantS1MaterialNFT from 0x09e03b1f871b3513
25
26import TheFabricantS1ItemNFT from 0x09e03b1f871b3513
27
28import TheFabricantS2GarmentNFT from 0x7752ea736384322f
29
30import TheFabricantS2MaterialNFT from 0x7752ea736384322f
31
32import TheFabricantS2ItemNFT from 0x7752ea736384322f
33
34import TheFabricantMarketplace from 0x09e03b1f871b3513
35
36import MetadataViews from 0x1d7e57aa55817448
37
38import TheFabricantXXories from 0x7752ea736384322f
39
40import TheFabricantNFTStandard from 0x7752ea736384322f
41
42import TheFabricantNFTStandardV2 from 0x7752ea736384322f
43
44import TheFabricantKapers from 0x7752ea736384322f
45
46access(all)
47contract TheFabricantMarketplaceHelper{ 
48	
49	// events emitted when an nft is listed or an offer is made for an nft
50	access(all)
51	event S0ItemListed(
52		name: String,
53		mainImage: String,
54		images: [
55			String
56		],
57		listingID: String,
58		nftType: Type,
59		nftID: UInt64,
60		ftVaultType: Type,
61		price: UFix64,
62		seller: Address?,
63		season: String
64	)
65	
66	access(all)
67	event S1ItemListed(
68		name: String,
69		mainImage: String,
70		images: [
71			String
72		],
73		listingID: String,
74		nftType: Type,
75		nftID: UInt64,
76		ftVaultType: Type,
77		price: UFix64,
78		seller: Address?,
79		season: String
80	)
81	
82	access(all)
83	event S2ItemListed(
84		name: String,
85		mainImage: String,
86		images: [
87			String
88		],
89		listingID: String,
90		nftType: Type,
91		nftID: UInt64,
92		ftVaultType: Type,
93		price: UFix64,
94		seller: Address?,
95		season: String,
96		edition: String?
97	)
98	
99	access(all)
100	event XXoryListed(
101		name: String,
102		mainImage: String,
103		images: [
104			String
105		],
106		listingID: String,
107		nftType: Type,
108		nftID: UInt64,
109		ftVaultType: Type,
110		price: UFix64,
111		seller: Address?,
112		season: String,
113		edition: String?
114	)
115	
116	access(all)
117	event CATListed(
118		name: String,
119		mainImage: String,
120		images: [
121			String
122		],
123		listingID: String,
124		nftType: Type,
125		nftID: UInt64,
126		ftVaultType: Type,
127		price: UFix64,
128		seller: Address?,
129		season: String,
130		edition: String?
131	)
132	
133	access(all)
134	event TFNFTListed(
135		name: String,
136		mainImage: String,
137		images: [
138			String
139		],
140		listingID: String,
141		nftType: Type,
142		nftID: UInt64,
143		ftVaultType: Type,
144		price: UFix64,
145		seller: Address?,
146		season: String,
147		edition: String?
148	)
149	
150	access(all)
151	event AccessPassListed(
152		listingID: String,
153		nftType: Type,
154		nftID: UInt64,
155		serial: UInt64,
156		ftVaultType: Type,
157		price: UFix64,
158		seller: Address?,
159		variant: String,
160		promotionId: UInt64,
161		promotionHost: Address,
162		accessUnits: UInt8,
163		initialAccessUnits: UInt8,
164		season: String
165	)
166	
167	access(all)
168	event S0ItemOfferMade(
169		offerID: String,
170		nftType: Type,
171		nftID: UInt64,
172		ftVaultType: Type,
173		price: UFix64,
174		offerer: Address?,
175		initialNFTOwner: Address,
176		season: String
177	)
178	
179	access(all)
180	event S1ItemOfferMade(
181		offerID: String,
182		nftType: Type,
183		nftID: UInt64,
184		ftVaultType: Type,
185		price: UFix64,
186		offerer: Address?,
187		initialNFTOwner: Address,
188		season: String
189	)
190	
191	access(all)
192	event S2ItemOfferMade(
193		offerID: String,
194		nftType: Type,
195		nftID: UInt64,
196		ftVaultType: Type,
197		price: UFix64,
198		offerer: Address?,
199		initialNFTOwner: Address,
200		season: String,
201		edition: String?
202	)
203	
204	access(all)
205	event AccessPassOfferMade(
206		offerID: String,
207		nftType: Type,
208		nftID: UInt64,
209		ftVaultType: Type,
210		price: UFix64,
211		offerer: Address?,
212		initialNFTOwner: Address,
213		season: String
214	)
215	
216	access(all)
217	let AdminStoragePath: StoragePath
218	
219	// dictionary of name of royalty recipient to their salecut amounts
220	access(self)
221	var saleCuts:{ String: SaleCutValues}
222	
223	access(all)
224	struct SaleCutValues{ 
225		access(all)
226		var initialAmount: UFix64
227		
228		access(all)
229		var amount: UFix64
230		
231		init(initialAmount: UFix64, amount: UFix64){ 
232			self.initialAmount = initialAmount
233			self.amount = amount
234		}
235	}
236	
237	// list an s0Item from ItemNFT contract, calling TheFabricantMarketplace's Listings' createListing function
238	access(all)
239	fun s0ListItem(
240		itemRef: &ItemNFT.NFT,
241		listingRef: &TheFabricantMarketplace.Listings,
242		nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
243		nftType: Type,
244		nftID: UInt64,
245		paymentCapability: Capability<&{FungibleToken.Receiver}>,
246		salePaymentVaultType: Type,
247		price: UFix64
248	){ 
249		
250		//get the flowToken capabilities for each component of the item (garment, item, material)
251		let itemCap =
252			getAccount(itemRef.royaltyVault.address).capabilities.get<&FlowToken.Vault>(
253				/public/flowTokenReceiver
254			)
255		let itemDataID = itemRef.item.itemDataID
256		let itemData = ItemNFT.getItemData(id: itemDataID)
257		let itemName = itemRef.name
258		let mainImage = itemData.mainImage
259		var images: [String] = itemData.images
260		let garmentCap =
261			getAccount((itemRef.borrowGarment()!).royaltyVault.address).capabilities.get<
262				&FlowToken.Vault
263			>(/public/flowTokenReceiver)
264		let materialCap =
265			getAccount((itemRef.borrowMaterial()!).royaltyVault.address).capabilities.get<
266				&FlowToken.Vault
267			>(/public/flowTokenReceiver)
268		
269		// initialize sale cuts for item, garment, material and contract
270		let saleCutArray: [TheFabricantMarketplace.SaleCut] =
271			[
272				TheFabricantMarketplace.SaleCut(
273					name: "Season 0 Item Creator",
274					receiver: itemCap,
275					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["item"]!).initialAmount,
276					amount: (TheFabricantMarketplaceHelper.saleCuts["item"]!).amount
277				),
278				TheFabricantMarketplace.SaleCut(
279					name: "Season 0 Garment Creator",
280					receiver: garmentCap,
281					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["garment"]!)
282						.initialAmount,
283					amount: (TheFabricantMarketplaceHelper.saleCuts["garment"]!).amount
284				),
285				TheFabricantMarketplace.SaleCut(
286					name: "Season 0 Material Creator",
287					receiver: materialCap,
288					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["material"]!)
289						.initialAmount,
290					amount: (TheFabricantMarketplaceHelper.saleCuts["material"]!).amount
291				),
292				TheFabricantMarketplace.SaleCut(
293					name: "Channel Fee Royalty",
294					receiver: TheFabricantMarketplace.getChannelFeeCap()!,
295					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
296						.initialAmount,
297					amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
298				)
299			]
300		let listingID =
301			listingRef.createListing(
302				nftProviderCapability: nftProviderCapability,
303				nftType: nftType,
304				nftID: nftID,
305				paymentCapability: paymentCapability,
306				salePaymentVaultType: salePaymentVaultType,
307				price: price,
308				saleCuts: saleCutArray
309			)
310		emit S0ItemListed(
311			name: itemName,
312			mainImage: mainImage,
313			images: images,
314			listingID: listingID,
315			nftType: nftType,
316			nftID: nftID,
317			ftVaultType: salePaymentVaultType,
318			price: price,
319			seller: listingRef.owner?.address,
320			season: "0"
321		)
322	}
323	
324	// make an offer for an s0Item from ItemNFT contract, calling TheFabricantMarketplace's Offers' makeOffer function
325	access(all)
326	fun s0ItemMakeOffer(
327		initialNFTOwner: Address,
328		itemRef: &ItemNFT.NFT,
329		offerRef: &TheFabricantMarketplace.Offers,
330		ftProviderCapability: Capability<auth(FungibleToken.Withdraw)&{FungibleToken.Provider, FungibleToken.Balance}>,
331		nftType: Type,
332		nftID: UInt64,
333		nftReceiver: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
334		offerPaymentVaultType: Type,
335		price: UFix64
336	){ 
337		
338		// get the flowToken capabilities for each component of the item (garment, item, material)
339		let itemCap =
340			getAccount(itemRef.royaltyVault.address).capabilities.get<&FlowToken.Vault>(
341				/public/flowTokenReceiver
342			)
343		let garmentCap =
344			getAccount((itemRef.borrowGarment()!).royaltyVault.address).capabilities.get<
345				&FlowToken.Vault
346			>(/public/flowTokenReceiver)
347		let materialCap =
348			getAccount((itemRef.borrowMaterial()!).royaltyVault.address).capabilities.get<
349				&FlowToken.Vault
350			>(/public/flowTokenReceiver)
351		
352		// initialize sale cuts for item, garment, material and channelFee
353		let saleCutArray: [TheFabricantMarketplace.SaleCut] =
354			[
355				TheFabricantMarketplace.SaleCut(
356					name: "Season 0 Item Creator",
357					receiver: itemCap,
358					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["item"]!).initialAmount,
359					amount: (TheFabricantMarketplaceHelper.saleCuts["item"]!).amount
360				),
361				TheFabricantMarketplace.SaleCut(
362					name: "Season 0 Garment Creator",
363					receiver: garmentCap,
364					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["garment"]!)
365						.initialAmount,
366					amount: (TheFabricantMarketplaceHelper.saleCuts["garment"]!).amount
367				),
368				TheFabricantMarketplace.SaleCut(
369					name: "Season 0 Material Creator",
370					receiver: materialCap,
371					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["material"]!)
372						.initialAmount,
373					amount: (TheFabricantMarketplaceHelper.saleCuts["material"]!).amount
374				),
375				TheFabricantMarketplace.SaleCut(
376					name: "Channel Fee Royalty",
377					receiver: TheFabricantMarketplace.getChannelFeeCap()!,
378					initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
379						.initialAmount,
380					amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
381				)
382			]
383		let offerID =
384			offerRef.makeOffer(
385				initialNFTOwner: initialNFTOwner,
386				ftProviderCapability: ftProviderCapability,
387				offerPaymentVaultType: offerPaymentVaultType,
388				nftType: nftType,
389				nftID: nftID,
390				nftReceiverCapability: nftReceiver,
391				price: price,
392				saleCuts: saleCutArray
393			)
394		emit S0ItemOfferMade(
395			offerID: offerID,
396			nftType: nftType,
397			nftID: nftID,
398			ftVaultType: offerPaymentVaultType,
399			price: price,
400			offerer: offerRef.owner?.address,
401			initialNFTOwner: initialNFTOwner,
402			season: "0"
403		)
404	}
405	
406	// list an s1Item from TheFabricantS1ItemNFT contract, calling TheFabricantMarketplace's Listings' createListing function
407	access(all)
408	fun s1ListItem(
409		itemRef: &TheFabricantS1ItemNFT.NFT,
410		listingRef: &TheFabricantMarketplace.Listings,
411		nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
412		nftType: Type,
413		nftID: UInt64,
414		paymentCapability: Capability<&{FungibleToken.Receiver}>,
415		salePaymentVaultType: Type,
416		price: UFix64
417	){ 
418		
419		// get the flowToken capabilities for each component of the item (garment, item, material)
420		let itemCap =
421			getAccount(itemRef.royaltyVault.wallet.address).capabilities.get<&FlowToken.Vault>(
422				/public/flowTokenReceiver
423			)
424		let itemDataID = itemRef.item.itemDataID
425		let itemData = TheFabricantS1ItemNFT.getItemData(id: itemDataID)
426		let itemMetadata = itemData.getMetadata()
427		let itemName = itemRef.name
428		let mainImage = (itemMetadata["itemImage"]!).metadataValue
429		var images: [String] = []
430		let itemImage2 = (itemMetadata["itemImage2"]!).metadataValue
431		let itemImage3 = (itemMetadata["itemImage3"]!).metadataValue
432		let itemImage4 = (itemMetadata["itemImage4"]!).metadataValue
433		images = images.concat([itemImage2, itemImage3, itemImage4])
434		let garmentData = (itemRef.borrowGarment()!).garment.garmentDataID
435		let garmentRoyalties = TheFabricantS1GarmentNFT.getGarmentData(id: garmentData).getRoyalty()
436		let materialData = (itemRef.borrowMaterial()!).material.materialDataID
437		let materialRoyalties =
438			TheFabricantS1MaterialNFT.getMaterialData(id: materialData).getRoyalty()
439		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
440		// initialize sale cuts for item, garment, material and contract
441		// add all flowToken capabilities for garment creators
442		for key in garmentRoyalties.keys{ 
443			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 1 Garment Creator", receiver: (garmentRoyalties[key]!).wallet,																																			 //receiver: getAccount(garmentRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
444																																			 initialAmount: (garmentRoyalties[key]!).initialCut, amount: (garmentRoyalties[key]!).cut))
445		}
446		// add all flowToken capabilities for material creators
447		for key in materialRoyalties.keys{ 
448			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 1 Material Creator", receiver: (materialRoyalties[key]!).wallet,																																			   //receiver: getAccount(materialRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
449																																			   initialAmount: (materialRoyalties[key]!).initialCut, amount: (materialRoyalties[key]!).cut))
450		}
451		
452		// add the flowToken capabilities for item creator and channel fee
453		saleCutArray.append(
454			TheFabricantMarketplace.SaleCut(
455				name: "Season 1 Item Creator",
456				receiver: itemCap,
457				initialAmount: itemRef.royaltyVault.initialCut,
458				amount: itemRef.royaltyVault.cut
459			)
460		)
461		saleCutArray.append(
462			TheFabricantMarketplace.SaleCut(
463				name: "Channel Fee Royalty",
464				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
465				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
466					.initialAmount,
467				amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
468			)
469		)
470		let listingID =
471			listingRef.createListing(
472				nftProviderCapability: nftProviderCapability,
473				nftType: nftType,
474				nftID: nftID,
475				paymentCapability: paymentCapability,
476				salePaymentVaultType: salePaymentVaultType,
477				price: price,
478				saleCuts: saleCutArray
479			)
480		emit S1ItemListed(
481			name: itemName,
482			mainImage: mainImage,
483			images: images,
484			listingID: listingID,
485			nftType: nftType,
486			nftID: nftID,
487			ftVaultType: salePaymentVaultType,
488			price: price,
489			seller: listingRef.owner?.address,
490			season: "1"
491		)
492	}
493	
494	// make an offer for an s1Item from TheFabricantS1ItemNFT contract, calling TheFabricantMarketplace's Offers' makeOffer function
495	access(all)
496	fun s1ItemMakeOffer(
497		initialNFTOwner: Address,
498		itemRef: &TheFabricantS1ItemNFT.NFT,
499		offerRef: &TheFabricantMarketplace.Offers,
500		ftProviderCapability: Capability<auth(FungibleToken.Withdraw)&{FungibleToken.Provider, FungibleToken.Balance}>,
501		nftType: Type,
502		nftID: UInt64,
503		nftReceiver: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
504		offerPaymentVaultType: Type,
505		price: UFix64
506	){ 
507		
508		// get all FlowToken royalty capabilities
509		let itemCap =
510			getAccount(itemRef.royaltyVault.wallet.address).capabilities.get<&FlowToken.Vault>(
511				/public/flowTokenReceiver
512			)
513		let garmentData = (itemRef.borrowGarment()!).garment.garmentDataID
514		let garmentRoyalties = TheFabricantS1GarmentNFT.getGarmentData(id: garmentData).getRoyalty()
515		let materialData = (itemRef.borrowMaterial()!).material.materialDataID
516		let materialRoyalties =
517			TheFabricantS1MaterialNFT.getMaterialData(id: materialData).getRoyalty()
518		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
519		
520		// initialize sale cuts for item, garment, material and contract
521		
522		// add all flowToken capabilities for garment creators
523		for key in garmentRoyalties.keys{ 
524			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 1 Garment Creator", receiver: (garmentRoyalties[key]!).wallet,																																			 //receiver: getAccount(garmentRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
525																																			 initialAmount: (garmentRoyalties[key]!).initialCut, amount: (garmentRoyalties[key]!).cut))
526		}
527		
528		// add all flowToken capabilities for material creators
529		for key in materialRoyalties.keys{ 
530			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 1 Material Creator", receiver: (materialRoyalties[key]!).wallet,																																			   //receiver: getAccount(materialRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
531																																			   initialAmount: (materialRoyalties[key]!).initialCut, amount: (materialRoyalties[key]!).cut))
532		}
533		
534		// add the flowToken capabilities for item creator and channel fee
535		saleCutArray.append(
536			TheFabricantMarketplace.SaleCut(
537				name: "Season 1 Item Creator",
538				receiver: itemCap,
539				initialAmount: itemRef.royaltyVault.initialCut,
540				amount: itemRef.royaltyVault.cut
541			)
542		)
543		saleCutArray.append(
544			TheFabricantMarketplace.SaleCut(
545				name: "Channel Fee Royalty",
546				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
547				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
548					.initialAmount,
549				amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
550			)
551		)
552		let offerID =
553			offerRef.makeOffer(
554				initialNFTOwner: initialNFTOwner,
555				ftProviderCapability: ftProviderCapability,
556				offerPaymentVaultType: offerPaymentVaultType,
557				nftType: nftType,
558				nftID: nftID,
559				nftReceiverCapability: nftReceiver,
560				price: price,
561				saleCuts: saleCutArray
562			)
563		emit S1ItemOfferMade(
564			offerID: offerID,
565			nftType: nftType,
566			nftID: nftID,
567			ftVaultType: offerPaymentVaultType,
568			price: price,
569			offerer: offerRef.owner?.address,
570			initialNFTOwner: initialNFTOwner,
571			season: "1"
572		)
573	}
574	
575	// list an s2Item from TheFabricantS2ItemNFT contract, calling TheFabricantMarketplace's Listings' createListing function
576	access(all)
577	fun s2ListItem(
578		itemRef: &TheFabricantS2ItemNFT.NFT,
579		listingRef: &TheFabricantMarketplace.Listings,
580		nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
581		nftType: Type,
582		nftID: UInt64,
583		paymentCapability: Capability<&{FungibleToken.Receiver}>,
584		salePaymentVaultType: Type,
585		price: UFix64
586	){ 
587		
588		// get the flowToken capabilities for each component of the item (garment, item, material)
589		let itemCap =
590			getAccount(itemRef.royaltyVault.wallet.address).capabilities.get<&FlowToken.Vault>(
591				/public/flowTokenReceiver
592			)
593		let itemDataID = itemRef.item.itemDataID
594		let itemData = TheFabricantS2ItemNFT.getItemData(id: itemDataID)
595		let itemMetadata = itemData.getMetadata()
596		let itemName = itemRef.name
597		let mainImage = (itemMetadata["itemImage"]!).metadataValue
598		var images: [String] = []
599		let itemImage2 = (itemMetadata["itemImage2"]!).metadataValue
600		let itemImage3 = (itemMetadata["itemImage3"]!).metadataValue
601		let itemImage4 = (itemMetadata["itemImage4"]!).metadataValue
602		images = images.concat([itemImage2, itemImage3, itemImage4])
603		let edition =
604			itemMetadata["edition"] != nil ? (itemMetadata["edition"]!).metadataValue : nil
605		let garmentData = (itemRef.borrowGarment()!).garment.garmentDataID
606		let garmentRoyalties = TheFabricantS2GarmentNFT.getGarmentData(id: garmentData).getRoyalty()
607		let materialData = (itemRef.borrowMaterial()!).material.materialDataID
608		let materialRoyalties =
609			TheFabricantS2MaterialNFT.getMaterialData(id: materialData).getRoyalty()
610		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
611		// initialize sale cuts for item, garment, material and contract
612		// add all flowToken capabilities for garment creators
613		for key in garmentRoyalties.keys{ 
614			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 2 Garment Creator", receiver: (garmentRoyalties[key]!).wallet,																																			 //receiver: getAccount(garmentRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
615																																			 initialAmount: (garmentRoyalties[key]!).initialCut, amount: (garmentRoyalties[key]!).cut))
616		}
617		// add all flowToken capabilities for material creators
618		for key in materialRoyalties.keys{ 
619			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 2 Material Creator", receiver: (materialRoyalties[key]!).wallet,																																			   //receiver: getAccount(materialRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
620																																			   initialAmount: (materialRoyalties[key]!).initialCut, amount: (materialRoyalties[key]!).cut))
621		}
622		
623		// add the flowToken capabilities for item creator and channel fee
624		saleCutArray.append(
625			TheFabricantMarketplace.SaleCut(
626				name: "Season 2 Item Creator",
627				receiver: itemCap,
628				initialAmount: itemRef.royaltyVault.initialCut,
629				amount: itemRef.royaltyVault.cut
630			)
631		)
632		saleCutArray.append(
633			TheFabricantMarketplace.SaleCut(
634				name: "Channel Fee Royalty",
635				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
636				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
637					.initialAmount,
638				amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
639			)
640		)
641		let listingID =
642			listingRef.createListing(
643				nftProviderCapability: nftProviderCapability,
644				nftType: nftType,
645				nftID: nftID,
646				paymentCapability: paymentCapability,
647				salePaymentVaultType: salePaymentVaultType,
648				price: price,
649				saleCuts: saleCutArray
650			)
651		emit S2ItemListed(
652			name: itemName,
653			mainImage: mainImage,
654			images: images,
655			listingID: listingID,
656			nftType: nftType,
657			nftID: nftID,
658			ftVaultType: salePaymentVaultType,
659			price: price,
660			seller: listingRef.owner?.address,
661			season: "2",
662			edition: edition
663		)
664	}
665	
666	// make an offer for an s1Item from TheFabricantS1ItemNFT contract, calling TheFabricantMarketplace's Offers' makeOffer function
667	access(all)
668	fun s2ItemMakeOffer(
669		initialNFTOwner: Address,
670		itemRef: &TheFabricantS2ItemNFT.NFT,
671		offerRef: &TheFabricantMarketplace.Offers,
672		ftProviderCapability: Capability<auth(FungibleToken.Withdraw)&{FungibleToken.Provider, FungibleToken.Balance}>,
673		nftType: Type,
674		nftID: UInt64,
675		nftReceiver: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
676		offerPaymentVaultType: Type,
677		price: UFix64
678	){ 
679		
680		// get all FlowToken royalty capabilities
681		let itemCap =
682			getAccount(itemRef.royaltyVault.wallet.address).capabilities.get<&FlowToken.Vault>(
683				/public/flowTokenReceiver
684			)
685		let itemDataID = itemRef.item.itemDataID
686		let itemData = TheFabricantS2ItemNFT.getItemData(id: itemDataID)
687		let itemMetadata = itemData.getMetadata()
688		let edition =
689			itemMetadata["edition"] != nil ? (itemMetadata["edition"]!).metadataValue : nil
690		let garmentData = (itemRef.borrowGarment()!).garment.garmentDataID
691		let garmentRoyalties = TheFabricantS2GarmentNFT.getGarmentData(id: garmentData).getRoyalty()
692		let materialData = (itemRef.borrowMaterial()!).material.materialDataID
693		let materialRoyalties =
694			TheFabricantS2MaterialNFT.getMaterialData(id: materialData).getRoyalty()
695		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
696		
697		// initialize sale cuts for item, garment, material and contract
698		
699		// add all flowToken capabilities for garment creators
700		for key in garmentRoyalties.keys{ 
701			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 2 Garment Creator", receiver: (garmentRoyalties[key]!).wallet,																																			 //receiver: getAccount(garmentRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
702																																			 initialAmount: (garmentRoyalties[key]!).initialCut, amount: (garmentRoyalties[key]!).cut))
703		}
704		
705		// add all flowToken capabilities for material creators
706		for key in materialRoyalties.keys{ 
707			saleCutArray.append(TheFabricantMarketplace.SaleCut(name: "Season 2 Material Creator", receiver: (materialRoyalties[key]!).wallet,																																			   //receiver: getAccount(materialRoyalties[key]!.wallet.address).getCapability<&FlowToken.Vault{FungibleToken.Receiver}>(/public/flowTokenReceiver),
708																																			   initialAmount: (materialRoyalties[key]!).initialCut, amount: (materialRoyalties[key]!).cut))
709		}
710		
711		// add the flowToken capabilities for item creator and channel fee
712		saleCutArray.append(
713			TheFabricantMarketplace.SaleCut(
714				name: "Season 2 Item Creator",
715				receiver: itemCap,
716				initialAmount: itemRef.royaltyVault.initialCut,
717				amount: itemRef.royaltyVault.cut
718			)
719		)
720		saleCutArray.append(
721			TheFabricantMarketplace.SaleCut(
722				name: "Channel Fee Royalty",
723				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
724				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
725					.initialAmount,
726				amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
727			)
728		)
729		let offerID =
730			offerRef.makeOffer(
731				initialNFTOwner: initialNFTOwner,
732				ftProviderCapability: ftProviderCapability,
733				offerPaymentVaultType: offerPaymentVaultType,
734				nftType: nftType,
735				nftID: nftID,
736				nftReceiverCapability: nftReceiver,
737				price: price,
738				saleCuts: saleCutArray
739			)
740		emit S2ItemOfferMade(
741			offerID: offerID,
742			nftType: nftType,
743			nftID: nftID,
744			ftVaultType: offerPaymentVaultType,
745			price: price,
746			offerer: offerRef.owner?.address,
747			initialNFTOwner: initialNFTOwner,
748			season: "2",
749			edition: edition
750		)
751	}
752	
753	access(all)
754	fun xxoryListItem(
755		itemRef: &TheFabricantXXories.NFT,
756		listingsRef: &TheFabricantMarketplace.Listings,
757		nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
758		nftType: Type,
759		nftID: UInt64,
760		paymentCapability: Capability<&{FungibleToken.Receiver}>,
761		salePaymentVaultType: Type,
762		price: UFix64
763	){ 
764		let name = itemRef.getFullName()
765		let royalties = itemRef.getTFRoyalties()
766		let imagesDict = itemRef.getImages()
767		let mainImage = imagesDict["mainImage"] ?? ""
768		let images = imagesDict.values
769		let editions = itemRef.getEditions()
770		let edition = editions.infoList[0].number
771		
772		// Create saleCuts
773		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
774		
775		// initialAmount: 10%
776		// amount: 5%
777		let channelFeeSaleCut =
778			TheFabricantMarketplace.SaleCut(
779				name: "Channel Fee Royalty",
780				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
781				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!)
782					.initialAmount,
783				amount: (TheFabricantMarketplaceHelper.saleCuts["channelFee"]!).amount
784			)
785		
786		// initialAmount: 10%
787		// amount: 5%
788		// NOTE: We can re-use the channel fee royalty cap here as they are the same.
789		let TFSaleCut =
790			TheFabricantMarketplace.SaleCut(
791				name: "The Fabricant XXories",
792				receiver: TheFabricantMarketplace.getChannelFeeCap()!,
793				initialAmount: (TheFabricantMarketplaceHelper.saleCuts["TheFabricantXXories"]!)
794					.initialAmount,
795				amount: (TheFabricantMarketplaceHelper.saleCuts["TheFabricantXXories"]!).amount
796			)
797		saleCutArray.append(channelFeeSaleCut)
798		saleCutArray.append(TFSaleCut)
799		let listingID =
800			listingsRef.createListing(
801				nftProviderCapability: nftProviderCapability,
802				nftType: nftType,
803				nftID: nftID,
804				paymentCapability: paymentCapability,
805				salePaymentVaultType: salePaymentVaultType,
806				price: price,
807				saleCuts: saleCutArray
808			)
809		emit XXoryListed(
810			name: name,
811			mainImage: mainImage,
812			images: images,
813			listingID: listingID,
814			nftType: nftType,
815			nftID: nftID,
816			ftVaultType: salePaymentVaultType,
817			price: price,
818			seller: listingsRef.owner?.address,
819			season: "3",
820			edition: edition.toString()
821		)
822	}
823	
824	access(all)
825	fun tfnftListItem(
826		itemRef: &{TheFabricantNFTStandardV2.TFNFT},
827		listingsRef: &TheFabricantMarketplace.Listings,
828		nftProviderCapability: Capability<auth(NonFungibleToken.Withdraw) &{NonFungibleToken.Provider, NonFungibleToken.CollectionPublic}>,
829		nftType: Type,
830		nftID: UInt64,
831		paymentCapability: Capability<&{FungibleToken.Receiver}>,
832		salePaymentVaultType: Type,
833		price: UFix64
834	){ 
835		let name = itemRef.getFullName()
836		let royalties = itemRef.getTFRoyalties()
837		let imagesDict = itemRef.getImages()
838		let mainImage = imagesDict["mainImage"] ?? ""
839		let images = imagesDict.values
840		let editions = itemRef.getEditions()
841		let edition = editions.infoList[0].number
842		
843		// Create saleCuts
844		var saleCutArray: [TheFabricantMarketplace.SaleCut] = []
845		let tfRoyalties = royalties.getRoyalties()
846		var i = 0
847		while i < tfRoyalties.length{ 
848			let cutInfo = tfRoyalties[i]
849			let TFSaleCut = TheFabricantMarketplace.SaleCut(name: cutInfo.description, receiver: cutInfo.receiver, initialAmount: cutInfo.initialCut, amount: cutInfo.cut)
850			saleCutArray.append(TFSaleCut)
851			i = i + 1
852		}
853		let listingID =
854			listingsRef.createListing(
855				nftProviderCapability: nftProviderCapability,
856				nftType: nftType,
857				nftID: nftID,
858				paymentCapability: paymentCapability,
859				salePaymentVaultType: salePaymentVaultType,
860				price: price,
861				saleCuts: saleCutArray
862			)
863		emit TFNFTListed(
864			name: name,
865			mainImage: mainImage,
866			images: images,
867			listingID: listingID,
868			nftType: nftType,
869			nftID: nftID,
870			ftVaultType: salePaymentVaultType,
871			price: price,
872			seller: listingsRef.owner?.address,
873			season: "s4",
874			edition: edition.toString()
875		)
876	}
877	
878	// Admin
879	// Admin can add salecutvalues
880	access(all)
881	resource Admin{ 
882		
883		// change contract royalty address
884		access(all)
885		fun addSaleCutValues(royaltyName: String, initialAmount: UFix64, amount: UFix64){ 
886			TheFabricantMarketplaceHelper.saleCuts[royaltyName] = TheFabricantMarketplaceHelper
887					.SaleCutValues(initialAmount: initialAmount, amount: amount)
888		}
889	}
890	
891	access(all)
892	fun getSaleCuts():{ String: SaleCutValues}{ 
893		return self.saleCuts
894	}
895	
896	access(all)
897	init(){ 
898		self.AdminStoragePath = /storage/fabricantTheFabricantMarketplaceHelperAdmin0021
899		self.saleCuts ={} 
900		self.account.storage.save<@Admin>(<-create Admin(), to: self.AdminStoragePath)
901	}
902}
903