Smart Contract

QuestReward

A.35f9e7ac86111b22.QuestReward

Deployed

3d ago
Feb 25, 2026, 12:00:13 AM UTC

Dependents

2 imports
1import NonFungibleToken from 0x1d7e57aa55817448
2
3access(all)
4contract QuestReward: NonFungibleToken { 
5	
6	// -----------------------------------------------------------------------
7	// NonFungibleToken Standard Events
8	// -----------------------------------------------------------------------
9	access(all)
10	event ContractInitialized()
11	
12	access(all)
13	event Withdraw(id: UInt64, from: Address?)
14	
15	access(all)
16	event Deposit(id: UInt64, to: Address?)
17	
18	// -----------------------------------------------------------------------
19	// Contract Events
20	// -----------------------------------------------------------------------
21	access(all)
22	event Minted(id: UInt64, minterID: UInt64, rewardTemplateID: UInt32, rewardTemplate: RewardTemplate, minterAddress: Address?)
23	
24	access(all)
25	event RewardTemplateAdded(minterID: UInt64, minterAddress: Address?, rewardTemplateID: UInt32, name: String, description: String, image: String)
26	
27	access(all)
28	event RewardTemplateUpdated(minterID: UInt64, minterAddress: Address?, rewardTemplateID: UInt32, name: String, description: String, image: String)
29	
30	// -----------------------------------------------------------------------
31	// Named Paths
32	// -----------------------------------------------------------------------
33	access(all)
34	let CollectionStoragePath: StoragePath
35	
36	access(all)
37	let CollectionPublicPath: PublicPath
38	
39	access(all)
40	let CollectionPrivatePath: PrivatePath
41	
42	// -----------------------------------------------------------------------
43	// Contract Fields
44	// -----------------------------------------------------------------------
45	access(all)
46	var totalSupply: UInt64
47	
48	access(all)
49	var rewardTemplateSupply: UInt32
50	
51	access(all)
52	var minterSupply: UInt64
53	
54	access(self)
55	var numberMintedPerRewardTemplate:{ UInt32: UInt64}
56	
57	// -----------------------------------------------------------------------
58	// Future Contract Extensions
59	// -----------------------------------------------------------------------
60	access(self)
61	var metadata:{ String: AnyStruct}
62	
63	access(self)
64	var resources: @{String: AnyResource}
65	
66	access(all)
67	struct RewardTemplate{ 
68		access(all)
69		let minterID: UInt64
70		
71		access(all)
72		let id: UInt32
73		
74		access(all)
75		let name: String
76		
77		access(all)
78		let description: String
79		
80		access(all)
81		let image: String
82		
83		init(minterID: UInt64, id: UInt32, name: String, description: String, image: String){ 
84			self.minterID = minterID
85			self.id = id
86			self.name = name
87			self.description = description
88			self.image = image
89		}
90	}
91	
92	access(all)
93	resource interface Public{ 
94		access(all)
95		let id: UInt64
96		
97		access(all)
98		let minterID: UInt64
99		
100		access(all)
101		let rewardTemplateID: UInt32
102		
103		access(all)
104		let dateMinted: UFix64
105		
106		access(all)
107		var revealed: Bool
108	}
109	
110	access(all)
111	resource NFT: Public, NonFungibleToken.NFT{ 
112		access(all)
113		let id: UInt64
114		
115		access(all)
116		let minterID: UInt64
117		
118		access(all)
119		let rewardTemplateID: UInt32
120		
121		access(all)
122		let dateMinted: UFix64
123		
124		access(all)
125		var revealed: Bool
126		
127		access(self)
128		var metadata:{ String: AnyStruct}
129		
130		access(self)
131		var resources: @{String: AnyResource}
132
133		access(all) view fun getViews(): [Type] { 
134			return []
135		}
136		
137		access(all) fun resolveView(_ view: Type): AnyStruct? { 
138			return nil
139		}
140		
141		access(all)
142		fun createEmptyCollection(): @{NonFungibleToken.Collection}{ 
143			return <-create Collection()
144		}
145		
146		init(minterID: UInt64, rewardTemplateID: UInt32, rewardTemplate: RewardTemplate, minterAddress: Address?){ 
147			self.id = self.uuid
148			self.minterID = minterID
149			self.rewardTemplateID = rewardTemplateID
150			self.dateMinted = getCurrentBlock().timestamp
151			self.revealed = false
152			self.metadata ={} 
153			self.resources <-{} 
154			QuestReward.totalSupply = QuestReward.totalSupply + 1
155			QuestReward.numberMintedPerRewardTemplate[rewardTemplateID] = QuestReward.numberMintedPerRewardTemplate[rewardTemplateID]! + 1
156			emit Minted(id: self.id, minterID: self.minterID, rewardTemplateID: self.rewardTemplateID, rewardTemplate: rewardTemplate, minterAddress: minterAddress)
157		}
158		
159		access(all)
160		fun reveal(){ 
161			self.revealed = true
162		}
163	}
164	
165	access(all)
166	resource interface CollectionPublic{ 
167		access(all)
168		fun getIDs(): [UInt64]
169		
170		access(all)
171		fun borrowQuestReward(id: UInt64): &QuestReward.NFT?{ 
172			post{ 
173				result == nil || result?.id == id:
174					"Cannot borrow QuestReward reference: The ID of the returned reference is incorrect"
175			}
176		}
177	}
178	
179	access(all)
180	resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.Collection, NonFungibleToken.CollectionPublic{ 
181		access(all)
182		var ownedNFTs: @{UInt64:{ NonFungibleToken.NFT}}
183		
184		init(){ 
185			self.ownedNFTs <-{} 
186		}
187		
188		access(NonFungibleToken.Withdraw)
189		fun withdraw(withdrawID: UInt64): @{NonFungibleToken.NFT}{ 
190			let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("Cannot withdraw QuestReward from Collection: Missing NFT")
191			emit Withdraw(id: withdrawID, from: self.owner?.address)
192			return <-token
193		}
194		
195		access(all)
196		fun deposit(token: @{NonFungibleToken.NFT}){ 
197			let token <- token as! @QuestReward.NFT
198			let id: UInt64 = token.id
199			let oldToken <- self.ownedNFTs[id] <- token
200			emit Deposit(id: id, to: self.owner?.address)
201			destroy oldToken
202		}
203		
204		access(all)
205		view fun getIDs(): [UInt64]{ 
206			return self.ownedNFTs.keys
207		}
208		
209		access(all)
210		view fun borrowNFT(_ id: UInt64): &{NonFungibleToken.NFT}?{ 
211			return (&self.ownedNFTs[id] as &{NonFungibleToken.NFT}?)!
212		}
213		
214		access(all)
215		fun borrowQuestReward(id: UInt64): &QuestReward.NFT?{ 
216			let ref = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}?
217			return (ref as! &QuestReward.NFT?)!
218		}
219		
220		access(all)
221		fun borrowEntireQuestReward(id: UInt64): &QuestReward.NFT?{ 
222			let ref = &self.ownedNFTs[id] as &{NonFungibleToken.NFT}?
223			return (ref as! &QuestReward.NFT?)!
224		}
225		
226		access(all) view fun getSupportedNFTTypes():{ Type: Bool} { 
227			return {
228				Type<@QuestReward.NFT>(): true
229			}
230		}
231		
232		access(all) view fun isSupportedNFTType(type: Type): Bool { 
233			return type == Type<@QuestReward.NFT>()
234		}
235		
236		access(all)
237		fun createEmptyCollection(): @{NonFungibleToken.Collection}{ 
238			return <-create Collection()
239		}
240	}
241	
242	access(all)
243	resource interface MinterPublic{ 
244		access(all)
245		let id: UInt64
246		
247		access(all)
248		let name: String
249		
250		access(all)
251		fun getRewardTemplate(id: UInt32): RewardTemplate?
252		
253		access(all)
254		fun getRewardTemplates():{ UInt32: RewardTemplate}
255	}
256	
257	access(all)
258	resource Minter: MinterPublic{ 
259		access(all)
260		let id: UInt64
261		
262		access(all)
263		let name: String
264		
265		access(self)
266		var rewardTemplates:{ UInt32: RewardTemplate}
267		
268		access(self)
269		var metadata:{ String: AnyStruct}
270		
271		access(self)
272		var resources: @{String: AnyResource}
273		
274		init(name: String){ 
275			self.id = QuestReward.minterSupply
276			self.name = name
277			self.rewardTemplates ={} 
278			self.metadata ={} 
279			self.resources <-{} 
280			QuestReward.minterSupply = QuestReward.minterSupply + 1
281		}
282		
283		access(all)
284		fun mintReward(rewardTemplateID: UInt32): @NFT{ 
285			pre{ 
286				self.rewardTemplates[rewardTemplateID] != nil:
287					"Reward Template does not exist"
288			}
289			return <-create NFT(minterID: self.id, rewardTemplateID: rewardTemplateID, rewardTemplate: self.getRewardTemplate(id: rewardTemplateID)!, minterAddress: self.owner?.address)
290		}
291		
292		access(all)
293		fun addRewardTemplate(name: String, description: String, image: String){ 
294			let id: UInt32 = QuestReward.rewardTemplateSupply
295			self.rewardTemplates[id] = RewardTemplate(minterID: self.id, id: id, name: name, description: description, image: image)
296			QuestReward.rewardTemplateSupply = QuestReward.rewardTemplateSupply + 1
297			QuestReward.numberMintedPerRewardTemplate[id] = 0
298			emit RewardTemplateAdded(minterID: self.id, minterAddress: self.owner?.address, rewardTemplateID: id, name: name, description: description, image: image)
299		}
300		
301		access(all)
302		fun updateRewardTemplate(id: UInt32, name: String, description: String, image: String){ 
303			pre{ 
304				self.rewardTemplates[id] != nil:
305					"Reward Template does not exist"
306			}
307			self.rewardTemplates[id] = RewardTemplate(minterID: self.id, id: id, name: name, description: description, image: image)
308			emit RewardTemplateUpdated(minterID: self.id, minterAddress: self.owner?.address, rewardTemplateID: id, name: name, description: description, image: image)
309		}
310		
311		access(all)
312		fun getRewardTemplate(id: UInt32): RewardTemplate?{ 
313			return self.rewardTemplates[id]
314		}
315		
316		access(all)
317		fun getRewardTemplates():{ UInt32: RewardTemplate}{ 
318			return self.rewardTemplates
319		}
320	}
321	
322	access(all)
323	fun createEmptyCollection(nftType: Type): @{NonFungibleToken.Collection}{ 
324		return <-create Collection()
325	}
326	
327	access(all)
328	fun createMinter(name: String): @Minter{ 
329		return <-create Minter(name: name)
330	}
331	
332	access(all)
333	fun getNumberMintedPerRewardTemplateKeys(): [UInt32]{ 
334		return self.numberMintedPerRewardTemplate.keys
335	}
336	
337	access(all)
338	fun getNumberMintedPerRewardTemplate(id: UInt32): UInt64?{ 
339		return self.numberMintedPerRewardTemplate[id]
340	}
341	
342	access(all)
343	fun getNumberMintedPerRewardTemplates():{ UInt32: UInt64}{ 
344		return self.numberMintedPerRewardTemplate
345	}
346
347	// -----------------------------------------------------------------------
348	// MetadataViews - Purposely Empty
349	// -----------------------------------------------------------------------
350    access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? {
351        return nil
352    }
353
354    access(all) view fun getContractViews(resourceType: Type?): [Type] {
355        return []
356    }
357	
358	init(){ 
359		self.CollectionStoragePath = /storage/WonderlandQuestRewardCollection_2
360		self.CollectionPublicPath = /public/WonderlandQuestRewardCollection_2
361		self.CollectionPrivatePath = /private/WonderlandQuestRewardCollection_2
362		self.totalSupply = 0
363		self.rewardTemplateSupply = 0
364		self.minterSupply = 0
365		self.numberMintedPerRewardTemplate ={} 
366		self.metadata ={} 
367		self.resources <-{} 
368		emit ContractInitialized()
369	}
370}
371