@@ -12,20 +12,60 @@ import BigInt
1212import Foundation
1313
1414public 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
1921 func disconnectSocket( ) throws
2022}
2123
22- public enum WebsocketMethod {
23- case pendingTransactions
24+ public enum InfuraWebsocketMethod : String , Encodable {
2425
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
2969 }
3070 }
3171}
@@ -34,57 +74,45 @@ public protocol Web3SocketDelegate {
3474 func received( message: Any )
3575}
3676
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 {
4278 public var subscriptionKey : String ?
43-
4479 private var subscriptionTimer : Timer ?
4580
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 ? ) {
5284 guard network == Networks . Kovan
5385 || network == Networks . Rinkeby
5486 || network == Networks . Ropsten
5587 || network == Networks . Mainnet else { return nil }
5688 let networkName = network. name
5789 let urlString = " wss:// \( networkName) .infura.io/ws "
5890 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)
6594 }
6695
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
72104 }
73105
74- public func subscribeOn( method: WebsocketMethod , params: JSONRPCparams ? = nil ) throws {
106+ public func subscribeOn( method: InfuraWebsocketMethod , params: [ Encodable ] ? = nil ) throws {
75107 do {
76108 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) " )
79114 }
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)
88116 let encoder = JSONEncoder ( )
89117 let requestData = try encoder. encode ( request)
90118 socket. write ( data: requestData)
@@ -96,54 +124,126 @@ public class Web3SocketProvider: WebsocketProvider {
96124
97125 @objc public func getSubscriptionChanges( ) {
98126 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 {
111128 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()
112139 }
113140 }
114141 }
115- }
116-
117- extension Web3SocketProvider : WebSocketDelegate {
118- public func websocketDidConnect( socket: WebSocketClient ) {
119- print ( " websocket is connected " )
120- }
121142
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 ) {
128144 if let data = text. data ( using: String . Encoding. utf8) ,
129145 let dictionary = try ? JSONSerialization . jsonObject ( with: data, options: [ ] ) as? [ String : AnyObject ] {
130146 if subscriptionKey == nil ,
131147 let result = dictionary [ " result " ] as? String {
132148 subscriptionKey = result
133149 } else {
134150 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)
136203 }
204+ } else {
205+ network = net
137206 }
138207 }
139208
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+
140232 public func websocketDidReceiveData( socket: WebSocketClient , data: Data ) {
141233 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 " ) " )
142243 }
143244
144245 public func websocketDidReceivePong( socket: WebSocketClient , data: Data ? ) {
145246 print ( " Got pong! Maybe some data: \( data? . count) " )
146247 }
147248}
148249
149-
0 commit comments