Smart Contract

TheFabricantAccessList

A.7752ea736384322f.TheFabricantAccessList

Deployed

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

Dependents

0 imports
1// Used for managing access lists on the BC. It does not manage the 
2// minting process, only the access lists.
3access(all)
4contract TheFabricantAccessList{ 
5	
6	// -----------------------------------------------------------------------
7	// Paths
8	// -----------------------------------------------------------------------
9	access(all)
10	let AdminStoragePath: StoragePath
11
12	
13	// -----------------------------------------------------------------------
14	// Contract Events
15	// -----------------------------------------------------------------------
16	access(all)
17	event ContractInitialized()
18	
19	access(all)
20	event AccessListDetailsCreated(
21		id: UInt64,
22		collection: String,
23		description: String?,
24		accessListStoragePath: String,
25		testingListStoragePath: String
26	)
27	
28	access(all)
29	event AccessListDetailUpdated(
30		id: UInt64,
31		collection: String,
32		description: String?,
33		accessListStoragePath: String,
34		testingListStoragePath: String
35	)
36	
37	access(all)
38	event AccessListDetailDeleted(
39		id: UInt64,
40		collection: String,
41		description: String?,
42		accessListStoragePath: String,
43		testingListStoragePath: String
44	)
45	
46	access(all)
47	event AccessListDetailsIsActiveUpdated(
48		isActive: Bool,
49		onlyUseTestingList: Bool,
50		id: UInt64,
51		collection: String,
52		description: String?,
53		accessListStoragePath: String,
54		testingListStoragePath: String
55	)
56	
57	access(all)
58	event AccessListDetailsOnlyUseTestingListUpdated(
59		isActive: Bool,
60		onlyUseTestingList: Bool,
61		id: UInt64,
62		collection: String,
63		description: String?,
64		accessListStoragePath: String,
65		testingListStoragePath: String
66	)
67	
68	access(all)
69	event AccessListAddressesAdded(
70		accessListDetailsId: UInt64,
71		addresses:{ 
72			Address: Bool
73		},
74		accessListStoragePath: String,
75		testingListStoragePath: String
76	)
77	
78	access(all)
79	event AddressRemovedFromAccessList(
80		accessListDetailsId: UInt64,
81		address: Address,
82		accessListStoragePath: String,
83		testingListStoragePath: String
84	)
85	
86	access(all)
87	event AddressRemovedFromTestingList(
88		accessListDetailsId: UInt64,
89		address: Address,
90		accessListStoragePath: String,
91		testingListStoragePath: String
92	)
93	
94	access(all)
95	event AccessListEmptied(
96		isActive: Bool,
97		onlyUseTestingList: Bool,
98		id: UInt64,
99		collection: String,
100		description: String?,
101		accessListStoragePath: String,
102		testingListStoragePath: String
103	)
104	
105	access(all)
106	event TestingListEmptied(
107		isActive: Bool,
108		onlyUseTestingList: Bool,
109		id: UInt64,
110		collection: String,
111		description: String?,
112		accessListStoragePath: String,
113		testingListStoragePath: String
114	)
115	
116	// TODO:
117	access(all)
118	event IsAccessListClosedChanged()
119	
120	access(all)
121	event TestingListAddressesAdded(
122		accessListDetailsId: UInt64,
123		addresses:{ 
124			Address: Bool
125		},
126		accessListStoragePath: String,
127		testingListStoragePath: String
128	)
129	
130	// -----------------------------------------------------------------------
131	// Contract State
132	// -----------------------------------------------------------------------
133	access(self)
134	var accessListDetails:{ UInt64: AccessListDetails}
135	
136	access(self)
137	var testingLists:{ UInt64:{ Address: Bool}}
138	
139	access(contract)
140	var nextAccessListId: UInt64
141	
142	// -----------------------------------------------------------------------
143	// Address List Struct
144	// -----------------------------------------------------------------------
145	// * The AL struct can represent an internal testing list or an extenral access list.
146	// * It is saved to the Admin's account storage under a constructed storage path.
147	// * It is linked to a public path, exposing the AddressListPublic interface.
148	// * The AL struct is distinct from the AccessListDetails struct to minimise the
149	// size of the AL struct in storage (and therefore to maximise the number of
150	// addresses that can be stored).
151	// * The AL struct is stored in account storage to ensure that the size of other AL 
152	// structs don't impact the computational cost of accessing individual AL structs.
153	// 
154	access(all)
155	struct interface AddressListPublic{ 
156		access(all)
157		fun getAddressList():{ Address: Bool}
158		
159		access(all)
160		fun getAddressListLength(): Int
161		
162		access(all)
163		fun containsAddress(address: Address): Bool
164	}
165	
166	// An AddressList can be an AccessList or a TestingList
167	access(all)
168	struct AddressList: AddressListPublic{ 
169		access(self)
170		var addressList:{ Address: Bool}
171		
172		access(all)
173		fun getAddressList():{ Address: Bool}{ 
174			return self.addressList
175		}
176		
177		access(all)
178		fun getAddressListLength(): Int{ 
179			return self.addressList.length
180		}
181		
182		access(all)
183		fun containsAddress(address: Address): Bool{ 
184			return self.addressList.containsKey(address)
185		}
186		
187		access(all)
188		fun addAddressesToAddressList(addressDict:{ Address: Bool}){ 
189			var i = 0
190			while i < addressDict.length{ 
191				self.addressList.insert(key: addressDict.keys[i], addressDict.values[i])
192				i = i + 1
193			}
194		}
195		
196		access(all)
197		fun removeAddressFromAddressList(address: Address): Bool{ 
198			if !self.addressList.containsKey(address){ 
199				return false
200			} else{ 
201				self.addressList.remove(key: address)
202				return true
203			}
204		}
205		
206		access(all)
207		fun emptyAddressList(){ 
208			self.addressList ={} 
209		}
210		
211		init(){ 
212			self.addressList ={} 
213		}
214	}
215	
216	// -----------------------------------------------------------------------
217	// Access List Details
218	// -----------------------------------------------------------------------
219	// * Contains the details for a related Address List struct and maintains
220	// the open/closed state.
221	// * Used to determine if an address has access via the checkAccessFor(address:)
222	// function.
223	access(all)
224	struct AccessListDetails{ 
225		
226		// Identifier for ALD, but also the corresponding AL and TL
227		access(contract)
228		var id: UInt64
229		
230		access(contract)
231		var collection: String
232		
233		access(contract)
234		var description: String?
235		
236		access(contract)
237		var dateCreated: UFix64
238		
239		// access(contract)
240		// var accessListStoragePath: StoragePath
241		
242		// access(contract)
243		// var testingListStoragePath: StoragePath
244		
245		// access(contract)
246		// var accessListPublicPath: PublicPath
247		
248		// access(contract)
249		// var testingListPublicPath: PublicPath
250		
251		access(contract)
252		var isActive: Bool
253		
254		access(contract)
255		var onlyUseTestingList: Bool
256		
257		access(self)
258		fun isOpenExternally(): Bool{ 
259			if self.isOpen() && !self.onlyUseTestingList{ 
260				return true
261			}
262			return false
263		}
264		
265		access(self)
266		fun isOpenInternally(): Bool{ 
267			if self.isOpen() && self.onlyUseTestingList{ 
268				return true
269			}
270			return false
271		}
272		
273		access(self)
274		fun isOpen(): Bool{ 
275			if self.isActive{ 
276				return true
277			}
278			return false
279		}
280		
281		access(all)
282		fun getAccessListOpenState():{ String: Bool}{ 
283			var state:{ String: Bool} ={} 
284			state["isOpen"] = self.isOpen()
285			state["isOpenExternally"] = self.isOpenExternally()
286			state["isOpenInternally"] = self.isOpenInternally()
287			return state
288		}
289		
290		access(all)
291		fun getAccessListDetails():{ String: AnyStruct}{ 
292			var ret:{ String: AnyStruct} ={} 
293			ret["id"] = self.id
294			ret["collection"] = self.collection
295			ret["description"] = self.description
296			ret["dateCreated"] = self.dateCreated
297			ret["onlyUseTestingList"] = self.onlyUseTestingList
298			ret["isOpenExternally"] = self.isOpenExternally()
299			ret["isOpenInternally"] = self.isOpenInternally()
300			ret["isOpen"] = self.isOpen()
301			ret["accessListLength"] = self.borrowAccessList().getAddressListLength()
302			ret["testingListLength"] = self.borrowTestingList().getAddressListLength()
303			return ret
304		}
305		
306		access(all)
307		fun setIsActive(isActive: Bool){ 
308			self.isActive = isActive
309		}
310		
311		access(all)
312		fun setOnlyUseInternalTestingList(useTestingList: Bool){ 
313			self.onlyUseTestingList = useTestingList
314		}
315		
316		// NOTE: This is the function that should be used for determining
317		// access via the contract level doesAddressHaveAccess()!
318		access(all)
319		fun checkAccessFor(address: Address): Bool{ 
320			if self.isOpenInternally(){ 
321				// In testing mode
322				let testingList = self.borrowTestingList()
323				return testingList.containsAddress(address: address)
324			}
325			if self.isOpenExternally(){ 
326				// NOT in testing mode
327				let accessList = self.borrowAccessList()
328				return accessList.containsAddress(address: address)
329			}
330			return false
331		}
332		
333		// NOTE: WARNING! This function should not be used for determining access.
334		// Use doesAddressHaveAccess for access rights.
335		// This function tells you what lists the address is in and what the state of the
336		// ALD currently is.
337		access(all)
338		fun addressIsInList(address: Address):{ String: AnyStruct}{ 
339			var ret:{ String: AnyStruct} ={} 
340			ret["AccessListDetailsId"] = self.id
341			ret["isInAccessList"] = self.borrowAccessList().containsAddress(address: address)
342			ret["isInTestingList"] = self.borrowTestingList().containsAddress(address: address)
343			ret["isOpenExternally"] = self.isOpenExternally()
344			ret["isOpenInternally"] = self.isOpenInternally()
345			ret["isOpen"] = self.isOpen()
346			return ret
347		}
348		
349		access(all)
350		fun updateAccessListDetails(collection: String?, description: String?){ 
351			if let collection = collection{ 
352				self.collection = collection
353			}
354			if let description = description{ 
355				self.description = description
356			}
357		}
358		
359		access(self)
360		fun borrowAccessList(): &AddressList{ 
361			return TheFabricantAccessList.account.capabilities.get<&AddressList>(
362				PublicPath(identifier: "path")!
363			).borrow()
364			?? panic("No access list exists in storage for this AccessListDetails")
365		}
366		
367		access(self)
368		fun borrowTestingList(): &AddressList{ 
369			return TheFabricantAccessList.account.capabilities.get<&AddressList>(
370				PublicPath(identifier: "path")!
371			).borrow()
372			?? panic("No access list exists in storage for this AccessListDetails")
373		}
374		
375		init(collection: String, description: String?){ 
376			pre{ 
377				!TheFabricantAccessList.accessListDetails.containsKey(TheFabricantAccessList.nextAccessListId)
378			}
379			self.collection = collection
380			self.description = description
381			self.dateCreated = getCurrentBlock().timestamp
382			self.id = TheFabricantAccessList.nextAccessListId
383			let masterPathString = "master_accesslist"
384			let accessListString = "_accessLists_".concat(self.id.toString())
385			let accessListStoragePathString = masterPathString.concat("accessListString")
386			// Remove /storage/ by slicing
387			let accessListPathString =
388				accessListStoragePathString.slice(from: 9, upTo: accessListStoragePathString.length)
389			let testingListString = "_testingLists_".concat(self.id.toString())
390			let testingListStoragePathString = masterPathString.concat(testingListString)
391			// Remove /storage/ by slicing
392			let testingListPathString =
393				testingListStoragePathString.slice(
394					from: 9,
395					upTo: testingListStoragePathString.length
396				)
397			// self.accessListStoragePath = StoragePath(identifier: accessListPathString)!
398			// self.testingListStoragePath = StoragePath(identifier: testingListPathString)!
399			// self.accessListPublicPath = PublicPath(identifier: accessListPathString)!
400			// self.testingListPublicPath = PublicPath(identifier: testingListPathString)!
401			self.isActive = false
402			self.onlyUseTestingList = true
403		}
404	}
405	
406	// -----------------------------------------------------------------------
407	// Admin Resource
408	// -----------------------------------------------------------------------
409	// * Used to control CRUD ALDs + ALs. 
410	access(all)
411	resource Admin{ 
412		access(all)
413		fun setIsActive(accessListDetailsId: UInt64, isActive: Bool){ 
414			let accessListDetails =
415				TheFabricantAccessList.accessListDetails[accessListDetailsId]
416				?? panic("Can't setIsActive as no AccessListDetail exists with this id!")
417			accessListDetails.setIsActive(isActive: isActive)
418			TheFabricantAccessList.accessListDetails[accessListDetailsId] = accessListDetails
419			emit AccessListDetailsIsActiveUpdated(
420				isActive: accessListDetails.isActive,
421				onlyUseTestingList: accessListDetails.onlyUseTestingList,
422				id: accessListDetails.id,
423				collection: accessListDetails.collection,
424				description: accessListDetails.description,
425				accessListStoragePath: "accessliststoragepath",
426				testingListStoragePath: "testingliststoragepath"
427			)
428		}
429		
430		// NOTE: WARNING! Setting this to false will open up the external (public) access list!
431		access(all)
432		fun setOnlyUseInternalTestingList(accessListDetailsId: UInt64, useTestingList: Bool){ 
433			let accessListDetails =
434				TheFabricantAccessList.accessListDetails[accessListDetailsId]
435				?? panic(
436					"Can't set onlyUseTestingList as no AccessListDetails with this id exists!"
437				)
438			accessListDetails.setOnlyUseInternalTestingList(useTestingList: useTestingList)
439			TheFabricantAccessList.accessListDetails[accessListDetailsId] = accessListDetails
440			emit AccessListDetailsOnlyUseTestingListUpdated(
441				isActive: accessListDetails.isActive,
442				onlyUseTestingList: accessListDetails.onlyUseTestingList,
443				id: accessListDetails.id,
444				collection: accessListDetails.collection,
445				description: accessListDetails.description,
446				accessListStoragePath: "accessliststoragepath",
447				testingListStoragePath: "testingliststoragepath"
448			)
449		}
450		
451		// The user must create an ALD before creating an AL
452		access(all)
453		fun createAccessListDetails(collection: String, description: String?){ 
454			let accessListDetails: AccessListDetails =
455				TheFabricantAccessList.AccessListDetails(
456					collection: collection,
457					description: description
458				)
459			TheFabricantAccessList.accessListDetails[accessListDetails.id] = accessListDetails
460			TheFabricantAccessList.nextAccessListId = TheFabricantAccessList.nextAccessListId + 1
461			var accessList: TheFabricantAccessList.AddressList =
462				TheFabricantAccessList.AddressList()
463			var testingList: TheFabricantAccessList.AddressList =
464				TheFabricantAccessList.AddressList()
465			TheFabricantAccessList.account.storage.save(
466				accessList,
467				to: StoragePath(identifier: "accessListPathString")!
468			)
469			TheFabricantAccessList.account.storage.save(
470				testingList,
471				to: TheFabricantAccessList.constructTestingListStoragePath(
472					accessListDetailsId: accessListDetails.id
473				)
474			)
475			TheFabricantAccessList.account.capabilities.storage.issue<&AddressList>(
476				StoragePath(identifier: "accessListPathString")!
477			)
478			TheFabricantAccessList.account.capabilities.storage.issue<&AddressList>(
479				TheFabricantAccessList.constructTestingListStoragePath(
480					accessListDetailsId: accessListDetails.id
481				)
482			)
483			emit AccessListDetailsCreated(
484				id: accessListDetails.id,
485				collection: collection,
486				description: description,
487				accessListStoragePath: "accessliststoragepath",
488				testingListStoragePath: "testingliststoragepath"
489			)
490		}
491		
492		access(all)
493		fun updateAccessListDetails(
494			accessListDetailsId: UInt64,
495			collection: String?,
496			description: String?
497		){ 
498			let accessListDetails: AccessListDetails =
499				TheFabricantAccessList.accessListDetails[accessListDetailsId]
500				?? panic("Can't update details of AccessListDetails as no ALD with this id exists!")
501			accessListDetails.updateAccessListDetails(
502				collection: collection,
503				description: description
504			)
505			TheFabricantAccessList.accessListDetails[accessListDetailsId] = accessListDetails
506			emit AccessListDetailUpdated(
507				id: accessListDetails.id,
508				collection: accessListDetails.collection,
509				description: accessListDetails.description,
510				accessListStoragePath: "accessliststoragepath",
511				testingListStoragePath: "testingliststoragepath"
512			)
513		}
514		
515		access(all)
516		fun deleteAccessListDetails(accessListDetailsId: UInt64){ 
517			// Delete entire details and list from top level dictionary
518			pre{ 
519				TheFabricantAccessList.accessListDetails[accessListDetailsId] != nil:
520					"No accessListDetails exists with this Id"
521			}
522			let accessListDetails = TheFabricantAccessList.accessListDetails[accessListDetailsId]
523			TheFabricantAccessList.accessListDetails.remove(key: accessListDetailsId)
524			
525			// Loading a struct and doing nothing with it is equivalent to destroying a resource
526			let accessList =
527				TheFabricantAccessList.account.storage.load<AddressList>(
528					from: StoragePath(identifier: "accessListPathString")!
529				)
530			let testingList =
531				TheFabricantAccessList.account.storage.load<AddressList>(
532					from: TheFabricantAccessList.constructTestingListStoragePath(
533						accessListDetailsId: accessListDetailsId
534					)
535				)
536			emit AccessListDetailDeleted(
537				id: (accessListDetails!).id,
538				collection: (accessListDetails!).collection,
539				description: (accessListDetails!).description,
540				accessListStoragePath: "accessListPathString",
541				testingListStoragePath: "testingliststoragepath"
542			)
543		}
544		
545		access(all)
546		fun addAddressesToAccessList(accessListDetailsId: UInt64, addresses:{ Address: Bool}){ 
547			let accessListDetails =
548				TheFabricantAccessList.accessListDetails[accessListDetailsId]
549				?? panic("No AccessListDetails exists with this id")
550			let addressList = self.borrowAccessList(accessListDetailsId: accessListDetailsId)
551			addressList.addAddressesToAddressList(addressDict: addresses)
552			emit AccessListAddressesAdded(
553				accessListDetailsId: accessListDetailsId,
554				addresses: addresses,
555				accessListStoragePath: "accessliststoragepath",
556				testingListStoragePath: "testingliststoragepath"
557			)
558		}
559		
560		access(all)
561		fun removeAddressFromAccessList(accessListDetailsId: UInt64, address: Address): Bool{ 
562			let accessListDetails =
563				TheFabricantAccessList.accessListDetails[accessListDetailsId]
564				?? panic(
565					"Can't remove address from AL as no AccessListDetails exists with this id!"
566				)
567			let addressRemoved: Bool =
568				self.borrowAccessList(accessListDetailsId: accessListDetailsId)
569					.removeAddressFromAddressList(address: address)
570			if addressRemoved{ 
571				emit AddressRemovedFromAccessList(accessListDetailsId: accessListDetailsId, address: address, accessListStoragePath: "accessliststoragepath", testingListStoragePath: "testingliststoragepath")
572			}
573			return addressRemoved
574		}
575		
576		access(all)
577		fun emptyAccessList(accessListDetailsId: UInt64){ 
578			let accessListDetails =
579				TheFabricantAccessList.accessListDetails[accessListDetailsId]
580				?? panic("No AccessListDetails exists with this id")
581			self.borrowAccessList(accessListDetailsId: accessListDetailsId).emptyAddressList()
582			emit AccessListEmptied(
583				isActive: accessListDetails.isActive,
584				onlyUseTestingList: accessListDetails.onlyUseTestingList,
585				id: accessListDetails.id,
586				collection: accessListDetails.collection,
587				description: accessListDetails.description,
588				accessListStoragePath: "accessliststoragepath",
589				testingListStoragePath: "testingliststoragepath"
590			)
591		}
592		
593		access(all)
594		fun addAddressesToTestingList(accessListDetailsId: UInt64, addresses:{ Address: Bool}){ 
595			let accessListDetails =
596				TheFabricantAccessList.accessListDetails[accessListDetailsId]
597				?? panic("No AccessListDetails exists with this id")
598			let addressList = self.borrowTestingList(accessListDetailsId: accessListDetailsId)
599			addressList.addAddressesToAddressList(addressDict: addresses)
600			emit TestingListAddressesAdded(
601				accessListDetailsId: accessListDetailsId,
602				addresses: addresses,
603				accessListStoragePath: "accessliststoragepath",
604				testingListStoragePath: "testingliststoragepath"
605			)
606		}
607		
608		access(all)
609		fun removeAddressFromTestingList(accessListDetailsId: UInt64, address: Address): Bool{ 
610			let accessListDetails =
611				TheFabricantAccessList.accessListDetails[accessListDetailsId]
612				?? panic("No AccessListDetail exists with this id")
613			let addressRemoved: Bool =
614				self.borrowTestingList(accessListDetailsId: accessListDetailsId)
615					.removeAddressFromAddressList(address: address)
616			if addressRemoved{ 
617				emit AddressRemovedFromTestingList(accessListDetailsId: accessListDetailsId, address: address, accessListStoragePath: "accessliststoragepath", testingListStoragePath: "testingliststoragepath")
618			}
619			return addressRemoved
620		}
621		
622		access(all)
623		fun emptyTestingList(accessListDetailsId: UInt64){ 
624			let accessListDetails =
625				TheFabricantAccessList.accessListDetails[accessListDetailsId]
626				?? panic("No AccessListDetails exists with this id")
627			self.borrowTestingList(accessListDetailsId: accessListDetailsId).emptyAddressList()
628			emit TestingListEmptied(
629				isActive: accessListDetails.isActive,
630				onlyUseTestingList: accessListDetails.onlyUseTestingList,
631				id: accessListDetails.id,
632				collection: accessListDetails.collection,
633				description: accessListDetails.description,
634				accessListStoragePath: "accessliststoragepath",
635				testingListStoragePath: "testingliststoragepath"
636			)
637		}
638		
639		access(self)
640		fun borrowAccessList(accessListDetailsId: UInt64): &AddressList{ 
641			return TheFabricantAccessList.account.storage.borrow<&AddressList>(
642				from: TheFabricantAccessList.constructAccessListStoragePath(
643					accessListDetailsId: accessListDetailsId
644				)
645			)
646			?? panic("No access list exists in storage for this AccessListDetails")
647		}
648		
649		access(self)
650		fun borrowTestingList(accessListDetailsId: UInt64): &AddressList{ 
651			return TheFabricantAccessList.account.storage.borrow<&AddressList>(
652				from: TheFabricantAccessList.constructTestingListStoragePath(
653					accessListDetailsId: accessListDetailsId
654				)
655			)
656			?? panic("No access list exists in storage for this AccessListDetails")
657		}
658	}
659	
660	// -----------------------------------------------------------------------
661	// Public Query Functions
662	// -----------------------------------------------------------------------
663	access(all)
664	fun getAccessList(accessListDetailsId: UInt64):{ Address: Bool}?{ 
665		return nil
666	}
667	
668	access(all)
669	fun getAllAccessLists():{ UInt64:{ Address: Bool}}{ 
670		let keys: [UInt64] = TheFabricantAccessList.accessListDetails.keys
671		var ret:{ UInt64:{ Address: Bool}} ={} 
672		var i: UInt64 = 1
673		while i <= UInt64(keys.length){ 
674			let accessListDetails = TheFabricantAccessList.accessListDetails[i as! UInt64] ?? nil
675			let publicPath = PublicPath(identifier: "path")!
676			if let addressListRef = TheFabricantAccessList.account.capabilities.get<&AddressList>(PublicPath(identifier: "path")!).borrow(){ 
677				let addressList = addressListRef.getAddressList()
678				ret[i] = addressList
679			}
680			i = i + 1
681		}
682		return ret
683	}
684	
685	access(all)
686	fun getTestingList(accessListDetailsId: UInt64):{ Address: Bool}?{ 
687		if let accessListDetails = TheFabricantAccessList.accessListDetails[accessListDetailsId]{ 
688			if let addressListRef = TheFabricantAccessList.account.capabilities.get<&AddressList>(PublicPath(identifier: "path")!).borrow(){ 
689				return addressListRef.getAddressList()
690			}
691		}
692		return nil
693	}
694	
695	access(all)
696	fun getAllTestingLists():{ UInt64:{ Address: Bool}}{ 
697		let keys: [UInt64] = TheFabricantAccessList.accessListDetails.keys
698		var ret:{ UInt64:{ Address: Bool}} ={} 
699		var i: Int = 1
700		while i < keys.length{ 
701			let accessListDetails = TheFabricantAccessList.accessListDetails[i as! UInt64] ?? nil
702			if accessListDetails == nil{ 
703				return ret
704			}
705			let publicPath = PublicPath(identifier: "path")!
706			if let addressListRef = TheFabricantAccessList.account.capabilities.get<&AddressList>(PublicPath(identifier: "path")!).borrow(){ 
707				let addressList = addressListRef.getAddressList()
708				ret[i as! UInt64] = addressList
709			}
710		}
711		return ret
712	}
713	
714	access(all)
715	fun getAccessListDetails(accessListDetailsId: UInt64):{ String: AnyStruct}?{ 
716		if let accessListDetails = self.accessListDetails[accessListDetailsId]{ 
717			return accessListDetails.getAccessListDetails()
718		}
719		return nil
720	}
721	
722	access(all)
723	fun getAllAccessListDetails():{ UInt64: TheFabricantAccessList.AccessListDetails}{ 
724		return TheFabricantAccessList.accessListDetails
725	}
726	
727	// NOTE: WARNING This should not be used to grant access to addresses.
728	// Use checkAccessForAddress() for granting access.
729	// This should only be used to check if an address is on a list or not,
730	// remember that an AL may not be active (hence why you should not use 
731	// this to grant access)
732	// This function returns a dict containing
733	// a Bool that determines if the address has access and details on the
734	// state of the ALD.
735	access(all)
736	fun isAddressInList(accessListDetailsId: UInt64, address: Address):{ String: AnyStruct}?{ 
737		if let accessListDetail = TheFabricantAccessList.accessListDetails[accessListDetailsId]{ 
738			return accessListDetail.addressIsInList(address: address)
739		}
740		return nil
741	}
742	
743	access(all)
744	fun checkAccessForAddress(accessListDetailsId: UInt64, address: Address): Bool{ 
745		if let accessListDetail = TheFabricantAccessList.accessListDetails[accessListDetailsId]{ 
746			return accessListDetail.checkAccessFor(address: address)
747		}
748		return false
749	}
750	
751	// -----------------------------------------------------------------------
752	// Public Utility Functions
753	// -----------------------------------------------------------------------
754	access(all)
755	fun constructAccessListStoragePath(accessListDetailsId: UInt64): StoragePath{ 
756		return StoragePath(identifier: "accessListPathString")!
757	}
758	
759	access(all)
760	fun constructAccessListPublicPath(accessListDetailsId: UInt64): PublicPath{ 
761		return PublicPath(identifier: "accessListPathString")!
762	}
763	
764	access(all)
765	fun constructTestingListStoragePath(accessListDetailsId: UInt64): StoragePath{ 
766		return StoragePath(identifier: "testingListPathString")!
767	}
768	
769	access(all)
770	fun constructTestingListPublicPath(accessListDetailsId: UInt64): PublicPath{ 
771		return PublicPath(identifier: "testingListPathString")!
772	}
773	
774	init(){ 
775		self.AdminStoragePath = /storage/TheFabricantAccessListAdminStoragePath001
776		self.accessListDetails ={} 
777		self.nextAccessListId = 1
778		self.testingLists ={} 
779		self.account.storage.save(<-create Admin(), to: self.AdminStoragePath)
780	}
781}
782