@@ -12,20 +12,60 @@ import BigInt
12
12
import Foundation
13
13
14
14
public protocol WebsocketProvider {
15
- var socket : WebSocket ? { get set }
16
- var delegate : Web3SocketDelegate ? { get set }
17
- static func connectToSocket( _ provider: Web3Provider , delegate: Web3SocketDelegate ) -> Web3SocketProvider ?
18
- func subscribeOn( method: WebsocketMethod , params: JSONRPCparams ? ) throws
15
+ var socket : WebSocket { get }
16
+ var delegate : Web3SocketDelegate { get set }
17
+ static func connectToSocket( endpoint: URL ,
18
+ delegate: Web3SocketDelegate ,
19
+ keystoreManager manager: KeystoreManager ? ) -> Web3SocketProvider
20
+ func connectSocket( ) throws
19
21
func disconnectSocket( ) throws
20
22
}
21
23
22
- public enum WebsocketMethod {
23
- case pendingTransactions
24
+ public enum InfuraWebsocketMethod : String , Encodable {
24
25
25
- public var getJSONRPCmethod : JSONRPCmethod {
26
- switch self {
27
- case . pendingTransactions:
28
- return . newPendingTransactionFilter
26
+ case newPendingTransactionFilter = " eth_newPendingTransactionFilter "
27
+ case getFilterChanges = " eth_getFilterChanges "
28
+
29
+ public var requiredNumOfParameters : Int {
30
+ get {
31
+ switch self {
32
+ case . newPendingTransactionFilter:
33
+ return 0
34
+ case . getFilterChanges:
35
+ return 1
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ public struct InfuraWebsocketRequest : Encodable {
42
+ public var jsonrpc : String = " 2.0 "
43
+ public var method : InfuraWebsocketMethod ?
44
+ public var params : JSONRPCparams ?
45
+ public var id : UInt64 = Counter . increment ( )
46
+
47
+ enum CodingKeys : String , CodingKey {
48
+ case jsonrpc
49
+ case method
50
+ case params
51
+ case id
52
+ }
53
+
54
+ public func encode( to encoder: Encoder ) throws {
55
+ var container = encoder. container ( keyedBy: CodingKeys . self)
56
+ try container. encode ( jsonrpc, forKey: . jsonrpc)
57
+ try container. encode ( method? . rawValue, forKey: . method)
58
+ try container. encode ( params, forKey: . params)
59
+ try container. encode ( id, forKey: . id)
60
+ }
61
+
62
+ public var isValid : Bool {
63
+ get {
64
+ if self . method == nil {
65
+ return false
66
+ }
67
+ guard let method = self . method else { return false }
68
+ return method. requiredNumOfParameters == self . params? . params. count
29
69
}
30
70
}
31
71
}
@@ -34,57 +74,45 @@ public protocol Web3SocketDelegate {
34
74
func received( message: Any )
35
75
}
36
76
37
- /// The default websocket provider.
38
- public class Web3SocketProvider : WebsocketProvider {
39
-
40
- public var socket : WebSocket ?
41
- public var delegate : Web3SocketDelegate ?
77
+ public final class InfuraWeb3SocketProvider : Web3SocketProvider {
42
78
public var subscriptionKey : String ?
43
-
44
79
private var subscriptionTimer : Timer ?
45
80
46
- private init ( ) { }
47
-
48
- public static func connectToSocket( _ provider: Web3Provider , delegate: Web3SocketDelegate ) -> Web3SocketProvider ? {
49
- let socketProvider = Web3SocketProvider ( )
50
-
51
- guard let network = provider. network else { return nil }
81
+ public init ? ( _ network: Networks ,
82
+ delegate: Web3SocketDelegate ,
83
+ keystoreManager manager: KeystoreManager ? ) {
52
84
guard network == Networks . Kovan
53
85
|| network == Networks . Rinkeby
54
86
|| network == Networks . Ropsten
55
87
|| network == Networks . Mainnet else { return nil }
56
88
let networkName = network. name
57
89
let urlString = " wss:// \( networkName) .infura.io/ws "
58
90
guard let socketURL = URL ( string: urlString) else { return nil }
59
-
60
- socketProvider. socket = WebSocket ( url: socketURL)
61
- socketProvider. socket? . delegate = socketProvider
62
- socketProvider. socket? . connect ( )
63
- socketProvider. delegate = delegate
64
- return socketProvider
91
+ super. init ( endpoint: socketURL,
92
+ delegate: delegate,
93
+ keystoreManager: manager)
65
94
}
66
95
67
- public func disconnectSocket( ) throws {
68
- guard let socket = self . socket else {
69
- throw Web3Error . connectionError
70
- }
71
- socket. disconnect ( )
96
+ public static func connectToSocket( _ network: Networks ,
97
+ delegate: Web3SocketDelegate ,
98
+ keystoreManager manager: KeystoreManager ? ) -> Web3SocketProvider ? {
99
+ guard let socketProvider = InfuraWeb3SocketProvider ( network,
100
+ delegate: delegate,
101
+ keystoreManager: manager) else { return nil }
102
+ socketProvider. socket. connect ( )
103
+ return socketProvider
72
104
}
73
105
74
- public func subscribeOn( method: WebsocketMethod , params: JSONRPCparams ? = nil ) throws {
106
+ public func subscribeOn( method: InfuraWebsocketMethod , params: [ Encodable ] ? = nil ) throws {
75
107
do {
76
108
subscriptionTimer? . invalidate ( )
77
- guard let socket = self . socket else {
78
- throw Web3Error . connectionError
109
+ subscriptionKey = nil
110
+ let params = params ?? [ ]
111
+ let paramsCount = params. count
112
+ guard method. requiredNumOfParameters == paramsCount else {
113
+ throw Web3Error . inputError ( desc: " Wrong number of params: need - \( method. requiredNumOfParameters) , got - \( paramsCount) " )
79
114
}
80
- let jsonrpcMethod = method. getJSONRPCmethod
81
- let paramsCount = params == nil
82
- ? 0
83
- : params!. params. count
84
- guard jsonrpcMethod. requiredNumOfParameters == paramsCount else {
85
- throw Web3Error . inputError ( desc: " Wrong number of params: need - \( jsonrpcMethod. requiredNumOfParameters) , got - \( paramsCount) " )
86
- }
87
- let request = JSONRPCRequestFabric . prepareRequest ( jsonrpcMethod, parameters: [ ] )
115
+ let request = JSONRPCRequestFabric . prepareRequest ( method, parameters: params)
88
116
let encoder = JSONEncoder ( )
89
117
let requestData = try encoder. encode ( request)
90
118
socket. write ( data: requestData)
@@ -96,54 +124,126 @@ public class Web3SocketProvider: WebsocketProvider {
96
124
97
125
@objc public func getSubscriptionChanges( ) {
98
126
DispatchQueue . global ( ) . async { [ unowned self] in
99
- if let key = self . subscriptionKey,
100
- let socket = self . socket {
101
- // self.subscriptionTimer?.invalidate()
102
- // let method = JSONRPCmethod.getFilterChanges
103
- // let request = JSONRPCRequestFabric.prepareRequest(method, parameters: ["\(key)"])
104
- // let encoder = JSONEncoder()
105
- // if let requestData = try? encoder.encode(request) {
106
- // socket.write(data: requestData)
107
- // }
108
-
109
- // TODO: - This should be in another way, but only this works
110
- socket. write ( string: " { \" jsonrpc \" : \" 2.0 \" , \" method \" : \" eth_getFilterChanges \" , \" params \" :[ \" \( key) \" ], \" id \" :1} " )
127
+ if let key = self . subscriptionKey {
111
128
self . subscriptionTimer? . invalidate ( )
129
+ let method = InfuraWebsocketMethod . getFilterChanges
130
+ let request = JSONRPCRequestFabric . prepareRequest ( method, parameters: [ key] )
131
+ let encoder = JSONEncoder ( )
132
+ if let requestData = try ? encoder. encode ( request) {
133
+ self . socket. write ( data: requestData)
134
+ }
135
+
136
+ // // TODO: - This should be in another way, but only this works
137
+ // self.socket.write(string: "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getFilterChanges\",\"params\":[\"\(key)\"],\"id\":1}")
138
+ // self.subscriptionTimer?.invalidate()
112
139
}
113
140
}
114
141
}
115
- }
116
-
117
- extension Web3SocketProvider : WebSocketDelegate {
118
- public func websocketDidConnect( socket: WebSocketClient ) {
119
- print ( " websocket is connected " )
120
- }
121
142
122
- public func websocketDidDisconnect( socket: WebSocketClient , error: Error ? ) {
123
- print ( " websocket is disconnected with \( error? . localizedDescription ?? " no error " ) " )
124
- }
125
-
126
- public func websocketDidReceiveMessage( socket: WebSocketClient , text: String ) {
127
- print ( " got some text: \( text) " )
143
+ override public func websocketDidReceiveMessage( socket: WebSocketClient , text: String ) {
128
144
if let data = text. data ( using: String . Encoding. utf8) ,
129
145
let dictionary = try ? JSONSerialization . jsonObject ( with: data, options: [ ] ) as? [ String : AnyObject ] {
130
146
if subscriptionKey == nil ,
131
147
let result = dictionary [ " result " ] as? String {
132
148
subscriptionKey = result
133
149
} else {
134
150
let result = dictionary [ " result " ] as Any
135
- delegate? . received ( message: result)
151
+ delegate. received ( message: result)
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ /// The default websocket provider.
158
+ public class Web3SocketProvider : Web3Provider , WebsocketProvider , WebSocketDelegate {
159
+ public func sendAsync( _ request: JSONRPCrequest , queue: DispatchQueue ) -> Promise < JSONRPCresponse > {
160
+ if request. method == nil {
161
+ return Promise ( error: Web3Error . nodeError ( desc: " RPC method is nil " ) )
162
+ }
163
+
164
+ return Web3HttpProvider . post ( request, providerURL: self . url, queue: queue, session: self . session)
165
+ }
166
+
167
+ public func sendAsync( _ requests: JSONRPCrequestBatch , queue: DispatchQueue ) -> Promise < JSONRPCresponseBatch > {
168
+ return Web3HttpProvider . post ( requests, providerURL: self . url, queue: queue, session: self . session)
169
+ }
170
+
171
+ public var network : Networks ?
172
+ public var url : URL
173
+ public var session : URLSession = { ( ) -> URLSession in
174
+ let config = URLSessionConfiguration . default
175
+ let urlSession = URLSession ( configuration: config)
176
+ return urlSession
177
+ } ( )
178
+ public var attachedKeystoreManager : KeystoreManager ? = nil
179
+
180
+ public var socket : WebSocket
181
+ public var delegate : Web3SocketDelegate
182
+
183
+ public init ( endpoint: URL ,
184
+ delegate wsdelegate: Web3SocketDelegate ,
185
+ keystoreManager manager: KeystoreManager ? ,
186
+ network net: Networks ? = nil ) {
187
+ delegate = wsdelegate
188
+ attachedKeystoreManager = manager
189
+ url = endpoint
190
+ socket = WebSocket ( url: endpoint)
191
+ socket. delegate = self
192
+ if net == nil {
193
+ let request = JSONRPCRequestFabric . prepareRequest ( . getNetwork, parameters: [ ] )
194
+
195
+ if let response = try ? Web3HttpProvider . post ( request,
196
+ providerURL: endpoint,
197
+ queue: DispatchQueue . global ( qos: . userInteractive) ,
198
+ session: session) . wait ( ) ,
199
+ response. error == nil ,
200
+ let result: String = response. getValue ( ) ,
201
+ let intNetworkNumber = Int ( result) {
202
+ network = Networks . fromInt ( intNetworkNumber)
136
203
}
204
+ } else {
205
+ network = net
137
206
}
138
207
}
139
208
209
+ public func connectSocket( ) {
210
+ socket. connect ( )
211
+ }
212
+
213
+ public func disconnectSocket( ) {
214
+ socket. disconnect ( )
215
+ }
216
+
217
+ public static func connectToSocket( endpoint: URL ,
218
+ delegate: Web3SocketDelegate ,
219
+ keystoreManager manager: KeystoreManager ? ) -> Web3SocketProvider {
220
+ let socketProvider = Web3SocketProvider ( endpoint: endpoint,
221
+ delegate: delegate,
222
+ keystoreManager: manager)
223
+ socketProvider. connectSocket ( )
224
+ return socketProvider
225
+ }
226
+
227
+ public func websocketDidReceiveMessage( socket: WebSocketClient , text: String ) {
228
+ print ( " got some text: \( text) " )
229
+ delegate. received ( message: text)
230
+ }
231
+
140
232
public func websocketDidReceiveData( socket: WebSocketClient , data: Data ) {
141
233
print ( " got some data: \( data. count) " )
234
+ delegate. received ( message: data)
235
+ }
236
+
237
+ public func websocketDidConnect( socket: WebSocketClient ) {
238
+ print ( " websocket is connected " )
239
+ }
240
+
241
+ public func websocketDidDisconnect( socket: WebSocketClient , error: Error ? ) {
242
+ print ( " websocket is disconnected with \( error? . localizedDescription ?? " no error " ) " )
142
243
}
143
244
144
245
public func websocketDidReceivePong( socket: WebSocketClient , data: Data ? ) {
145
246
print ( " Got pong! Maybe some data: \( data? . count) " )
146
247
}
147
248
}
148
249
149
-
0 commit comments