@@ -113,52 +113,7 @@ extension web3.web3contract {
113
113
var allResults = [ EventParserResultProtocol] ( )
114
114
if ( self . filter != nil ) {
115
115
let eventFilter = self . filter!
116
- let filteredLogs = decodedLogs. filter { ( result) -> Bool in
117
- if eventFilter. addresses == nil {
118
- return true
119
- } else {
120
- if eventFilter. addresses!. contains ( result. contractAddress) {
121
- return true
122
- } else {
123
- return false
124
- }
125
- }
126
- } . filter { ( result) -> Bool in
127
- if eventFilter. parameterFilters == nil {
128
- return true
129
- } else {
130
- let keys = result. decodedResult. keys. filter ( { ( key) -> Bool in
131
- if let _ = UInt64 ( key) {
132
- return true
133
- }
134
- return false
135
- } )
136
- if keys. count < eventFilter. parameterFilters!. count {
137
- return false
138
- }
139
- for i in 0 ..< keys. count {
140
- let allowedValues = eventFilter. parameterFilters![ i]
141
- let actualValue = result. decodedResult [ " \( i) " ]
142
- if actualValue == nil {
143
- return false
144
- }
145
- if allowedValues == nil {
146
- continue
147
- }
148
- var inAllowed = false
149
- for value in allowedValues! {
150
- if value. isEqualTo ( actualValue! as AnyObject ) {
151
- inAllowed = true
152
- break
153
- }
154
- }
155
- if !inAllowed {
156
- return false
157
- }
158
- }
159
- return true
160
- }
161
- }
116
+ let filteredLogs = filterLogs ( decodedLogs: decodedLogs, eventFilter: eventFilter)
162
117
allResults = filteredLogs
163
118
} else {
164
119
allResults = decodedLogs
@@ -171,10 +126,149 @@ extension web3.web3contract {
171
126
guard let hash = transaction. hash else { return Result . failure ( Web3Error . dataError) }
172
127
return self . parseTransactionByHash ( hash)
173
128
}
174
-
175
- public func getEventsByTopics( _ filter: EventFilter ) -> Result < [ EventParserResultProtocol ] , Web3Error > {
176
- return Result . failure ( Web3Error . nodeError ( " NYI " ) )
129
+ }
130
+ }
131
+
132
+ extension web3 . web3contract {
133
+ public func getIndexedEvents( eventName: String ? , filter: EventFilter ) -> Result < [ EventParserResultProtocol ] , Web3Error > {
134
+ guard let rawContract = self . contract as? ContractV2 else { return Result . failure ( Web3Error . nodeError ( " ABIv1 is not supported for this method " ) ) }
135
+ var eventTopic : Data ? = nil
136
+ var event : ABIv2 . Element . Event ? = nil
137
+ if eventName != nil {
138
+ guard let ev = rawContract. events [ eventName!] else { return Result . failure ( Web3Error . dataError) }
139
+ event = ev
140
+ eventTopic = ev. topic
141
+ }
142
+ var topics = [ [ String? ] ? ] ( )
143
+ if eventTopic != nil {
144
+ topics. append ( [ eventTopic!. toHexString ( ) . addHexPrefix ( ) ] )
145
+ } else {
146
+ topics. append ( nil as [ String ? ] ? )
147
+ }
148
+ if filter. parameterFilters != nil {
149
+ if event == nil { return Result . failure ( Web3Error . dataError) }
150
+ // let indexedInputs = event!.inputs.filter { (inp) -> Bool in
151
+ // return inp.indexed
152
+ // }
153
+ var lastNonemptyFilter = 0
154
+ for i in 0 ..< filter. parameterFilters!. count {
155
+ let filterValue = filter. parameterFilters![ i]
156
+ if filterValue != nil {
157
+ lastNonemptyFilter = i
158
+ }
159
+ }
160
+ if lastNonemptyFilter != 0 {
161
+ guard lastNonemptyFilter <= event!. inputs. count else { return Result . failure ( Web3Error . dataError) }
162
+ for i in 0 ... lastNonemptyFilter {
163
+ let filterValues = filter. parameterFilters![ i]
164
+ let input = event!. inputs [ i]
165
+ if filterValues != nil && !input. indexed {
166
+ return Result . failure ( Web3Error . dataError)
167
+ }
168
+ if filterValues == nil {
169
+ topics. append ( nil as [ String ? ] ? )
170
+ continue
171
+ }
172
+ var encodings = [ String] ( )
173
+ for val in filterValues! {
174
+ guard let enc = val. eventFilterEncoded ( ) else { return Result . failure ( Web3Error . dataError) }
175
+ encodings. append ( enc)
176
+ }
177
+ // if encodings.count == 1 {
178
+ // topics.append(encodings[0] as AnyObject)
179
+ // } else {
180
+ topics. append ( encodings)
181
+ // }
182
+ }
183
+ }
184
+ }
185
+ var preEncoding = filter. rpcPreEncode ( )
186
+ preEncoding. topics = topics
187
+ let request = JSONRPCRequestFabric . prepareRequest ( . getLogs, parameters: [ preEncoding] )
188
+ let response = self . web3. provider. send ( request: request)
189
+ let result = ResultUnwrapper . getResponse ( response)
190
+ switch result {
191
+ case . failure( let error) :
192
+ return Result . failure ( error)
193
+ case . success( let payload) :
194
+ if payload is NSNull {
195
+ return Result . failure ( Web3Error . nodeError ( " Empty response " ) )
196
+ }
197
+ guard let resultArray = payload as? [ [ String : AnyObject ] ] else {
198
+ return Result . failure ( Web3Error . dataError)
199
+ }
200
+ var allLogs = [ EventLog] ( )
201
+ for log in resultArray {
202
+ guard let parsedLog = EventLog . init ( log) else { return Result . failure ( Web3Error . dataError) }
203
+ allLogs. append ( parsedLog)
204
+ }
205
+ if event != nil {
206
+ let decodedLogs = allLogs. compactMap ( { ( log) -> EventParserResultProtocol ? in
207
+ let ( n, d) = contract. parseEvent ( log)
208
+ guard let evName = n, let evData = d else { return nil }
209
+ return EventParserResult ( eventName: evName, transactionReceipt: nil , contractAddress: log. address, decodedResult: evData)
210
+ } ) . filter { ( res: EventParserResultProtocol ? ) -> Bool in
211
+ if eventName != nil {
212
+ return res != nil && res? . eventName == eventName
213
+ } else {
214
+ return res != nil
215
+ }
216
+ }
217
+ var allResults = [ EventParserResultProtocol] ( )
218
+ allResults = decodedLogs
219
+ return Result ( allResults)
220
+ }
221
+ return Result ( [ EventParserResultProtocol] ( ) )
177
222
}
178
223
}
179
224
}
180
225
226
+ fileprivate func filterLogs( decodedLogs: [ EventParserResultProtocol ] , eventFilter: EventFilter ) -> [ EventParserResultProtocol ] {
227
+ let filteredLogs = decodedLogs. filter { ( result) -> Bool in
228
+ if eventFilter. addresses == nil {
229
+ return true
230
+ } else {
231
+ if eventFilter. addresses!. contains ( result. contractAddress) {
232
+ return true
233
+ } else {
234
+ return false
235
+ }
236
+ }
237
+ } . filter { ( result) -> Bool in
238
+ if eventFilter. parameterFilters == nil {
239
+ return true
240
+ } else {
241
+ let keys = result. decodedResult. keys. filter ( { ( key) -> Bool in
242
+ if let _ = UInt64 ( key) {
243
+ return true
244
+ }
245
+ return false
246
+ } )
247
+ if keys. count < eventFilter. parameterFilters!. count {
248
+ return false
249
+ }
250
+ for i in 0 ..< eventFilter. parameterFilters!. count {
251
+ let allowedValues = eventFilter. parameterFilters![ i]
252
+ let actualValue = result. decodedResult [ " \( i) " ]
253
+ if actualValue == nil {
254
+ return false
255
+ }
256
+ if allowedValues == nil {
257
+ continue
258
+ }
259
+ var inAllowed = false
260
+ for value in allowedValues! {
261
+ if value. isEqualTo ( actualValue! as AnyObject ) {
262
+ inAllowed = true
263
+ break
264
+ }
265
+ }
266
+ if !inAllowed {
267
+ return false
268
+ }
269
+ }
270
+ return true
271
+ }
272
+ }
273
+ return filteredLogs
274
+ }
0 commit comments