Smart Contract

RelatedAccounts

A.097bafa4e0b48eef.RelatedAccounts

Deployed

2d ago
Feb 26, 2026, 03:12:51 AM UTC

Dependents

0 imports
1pub contract RelatedAccounts {
2
3	pub let storagePath: StoragePath
4	pub let publicPath: PublicPath
5
6	// Deprecated
7	pub event RelatedFlowAccountAdded()
8	pub event RelatedFlowAccountRemoved()
9
10	pub event RelatedAccountAdded(name: String, address: Address, related: String, network: String)
11	pub event RelatedAccountRemoved(name: String, address: Address, related: String, network: String)
12
13	pub struct AccountInformation{
14		// unique alias for each wallet
15		pub let name:String
16		pub let address:Address?
17		pub let network:String //do not use enum because of contract upgrade
18		pub let otherAddress: String? //other networks besides flow may be not support Address
19
20		init(name:String, address:Address?, network:String, otherAddress:String?){
21			self.name=name
22			self.address=address
23			self.network=network
24			self.otherAddress=otherAddress
25		}
26	}
27
28	pub resource interface Public{
29		pub fun getFlowAccounts() : {String: Address} 
30		pub fun getRelatedAccounts(_ network: String) : {String : String} 
31		pub fun getAllRelatedAccounts() : {String : {String : String}}
32		pub fun verify(network: String, address: String) : Bool 
33	}
34
35	/// This is just an empty resource we create in storage, you can safely send a reference to it to obtain msg.sender
36	pub resource Accounts: Public {
37
38		access(self) let accounts: { String: AccountInformation}
39
40		pub fun verify(network: String, address: String) : Bool {
41			for account in self.accounts.keys {
42				let item = self.accounts[account]!
43				let addr = item.address?.toString() ?? item.otherAddress! 
44				if item.network == network && addr == address {
45					return true
46				}
47			}
48			return false
49		}
50
51		pub fun getFlowAccounts() : {String: Address} {
52			let items : {String: Address} ={}
53			for account in self.accounts.keys {
54				let item = self.accounts[account]!
55				if item.network == "Flow" {
56					items[item.name]=item.address!
57				}
58			}
59			return items
60		}
61
62		pub fun getRelatedAccounts(_ network: String) : {String : String} {
63			let items : {String: String} ={}
64			for account in self.accounts.keys {
65				let item = self.accounts[account]!
66				if item.network == network {
67					let address = item.address?.toString() ?? item.otherAddress!
68					items[item.name]=address
69				}
70			}
71			return items
72		}
73
74		pub fun getAllRelatedAccounts() : {String : {String : String}} {
75			let items : {String: {String : String}} ={}
76			for account in self.accounts.keys {
77				let item = self.accounts[account]!
78				if item.address != nil {
79					let i = items[item.network] ?? {}
80					i[item.name] = item.address!.toString()
81					items[item.name] = i
82					continue
83				}
84				let i = items[item.network] ?? {}
85				i[item.name] = item.otherAddress!
86				items[item.name] = i
87			}
88			return items
89		}
90
91		pub fun setFlowAccount(name: String, address:Address) {
92			self.accounts[name] = AccountInformation(name: name, address:address, network: "Flow", otherAddress:nil)
93			emit RelatedAccountAdded(name:name, address: self.owner!.address, related:address.toString(), network: "Flow")
94		}
95
96		pub fun setRelatedAccount(name: String, address: String, network: String) {
97			self.accounts[name] = AccountInformation(name: name, address:nil, network: network, otherAddress:address)
98			emit RelatedAccountAdded(name:name, address: self.owner!.address, related:address, network: network)
99		}
100
101		pub fun deleteAccount(name: String) {
102			let item =self.accounts.remove(key: name)!
103			emit RelatedAccountRemoved(name:name,address: self.owner!.address, related: item.address?.toString() ?? item.otherAddress!, network: "Flow")
104		}
105
106		init() {
107			self.accounts={}
108		}
109	}
110
111	pub fun createEmptyAccounts() : @Accounts{
112		return <- create Accounts()
113	}
114
115	pub fun findRelatedFlowAccounts(address:Address) : { String: Address} {
116		let cap = getAccount(address).getCapability<&Accounts{Public}>(self.publicPath)
117		if !cap.check(){
118			return {}
119		}
120
121		return cap.borrow()!.getFlowAccounts()
122	}
123
124	init() {
125
126		self.storagePath = /storage/findAccounts
127		self.publicPath = /public/findAccounts
128	}
129
130}
131
132
133