Smart Contract
RelatedAccounts
A.097bafa4e0b48eef.RelatedAccounts
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