6
6
//
7
7
8
8
import Foundation
9
-
10
- public protocol APIResponseType : Decodable { }
9
+ import BigInt
11
10
12
11
public typealias Hash = String // 32 bytes hash of block (64 chars length without 0x)
13
12
public typealias Receipt = Hash
@@ -96,15 +95,17 @@ extension APIRequest {
96
95
}
97
96
}
98
97
99
- public var responseType : APIResponseType . Type {
98
+ public var responseType : APIResultType . Type {
100
99
switch self {
101
100
case . blockNumber: return UInt . self
101
+ case . getAccounts: return [ EthereumAddress ] . self
102
+ case . feeHistory: return Web3 . Oracle. FeeHistory. self
102
103
default : return String . self
103
104
}
104
105
}
105
106
106
107
var encodedBody : Data {
107
- let request = RequestBody ( method: self . call, parameters : self . parameters)
108
+ let request = RequestBody ( method: self . call, params : self . parameters)
108
109
// this is safe to force try this here
109
110
// Because request must failed to compile if it not conformable with `Encodable` protocol
110
111
return try ! JSONEncoder ( ) . encode ( request)
@@ -142,7 +143,7 @@ extension APIRequest {
142
143
case . getBlockByNumber( let hash, let bool) :
143
144
return [ RequestParameter . string ( hash) , RequestParameter . bool ( bool) ]
144
145
case . feeHistory( let uInt, let blockNumber, let array) :
145
- return [ RequestParameter . uint ( uInt) , RequestParameter . string ( blockNumber. stringValue) , RequestParameter . doubleArray ( array) ]
146
+ return [ RequestParameter . string ( uInt. hexString ) , RequestParameter . string ( blockNumber. stringValue) , RequestParameter . doubleArray ( array) ]
146
147
case . createAccount( let string) :
147
148
return [ RequestParameter] ( )
148
149
case . unlockAccount( let address, let string, let optional) :
@@ -188,31 +189,35 @@ extension APIRequest {
188
189
}
189
190
190
191
extension APIRequest {
191
- public static func sendRequest< U > ( with call: APIRequest ) async throws -> APIResponse < U > {
192
- /// Don't even try to make network request if the U type dosen't equal to supposed by API
192
+ public static func sendRequest< Result > ( with provider : Web3Provider , for call: APIRequest ) async throws -> APIResponse < Result > {
193
+ /// Don't even try to make network request if the `Result` type dosen't equal to supposed by API
193
194
// FIXME: Add appropriate error thrown
194
- guard U . self == call. responseType else { throw Web3Error . unknownError }
195
+ guard Result . self == call. responseType else { throw Web3Error . unknownError }
195
196
196
- let request = setupRequest ( for: call)
197
- let ( data, response) = try await URLSession . shared . data ( for: request)
197
+ let request = setupRequest ( for: call, with : provider )
198
+ let ( data, response) = try await provider . session . data ( for: request)
198
199
199
200
// FIXME: Add appropriate error thrown
200
201
guard let httpResponse = response as? HTTPURLResponse ,
201
202
200 ..< 400 ~= httpResponse. statusCode else { throw Web3Error . connectionError }
202
203
203
- if U . self == UInt . self || U . self == Int . self || U . self == BigInt . self || U . self == BigUInt . self {
204
- let some = try ! JSONDecoder ( ) . decode ( APIResponse< String> . self , from: data)
204
+ if Result . self == UInt . self || Result . self == Int . self || Result . self == BigInt . self || Result . self == BigUInt . self {
205
+ /// This types for sure conformed with `LiteralInitiableFromString`
206
+ // FIXME: Make appropriate error
207
+ guard let U = Result . self as? LiteralInitiableFromString . Type else { throw Web3Error . unknownError}
208
+ let responseAsString = try ! JSONDecoder ( ) . decode ( APIResponse< String> . self , from: data)
205
209
// FIXME: Add appropriate error thrown.
206
- guard let tmpAnother = U ( from: some. result) else { throw Web3Error . unknownError }
207
- return APIResponse ( id: some. id, jsonrpc: some. jsonrpc, result: tmpAnother)
210
+ guard let literalValue = U . init ( from: responseAsString. result) else { throw Web3Error . unknownError }
211
+ /// `U` is a APIResponseType type, which `LiteralInitiableFromString` conforms to, so it is safe to cast that.
212
+ // FIXME: Make appropriate error
213
+ guard let asT = literalValue as? Result else { throw Web3Error . unknownError }
214
+ return APIResponse ( id: responseAsString. id, jsonrpc: responseAsString. jsonrpc, result: asT)
208
215
}
209
- return try JSONDecoder ( ) . decode ( APIResponse< U > . self , from: data)
216
+ return try JSONDecoder ( ) . decode ( APIResponse< Result > . self , from: data)
210
217
}
211
218
212
- static func setupRequest( for call: APIRequest ) -> URLRequest {
213
- // FIXME: Make custom url
214
- let url = URL ( string: " https://mainnet.infura.io/v3/4406c3acf862426c83991f1752c46dd8 " ) !
215
- var urlRequest = URLRequest ( url: url, cachePolicy: . reloadIgnoringCacheData)
219
+ static func setupRequest( for call: APIRequest , with provider: Web3Provider ) -> URLRequest {
220
+ var urlRequest = URLRequest ( url: provider. url, cachePolicy: . reloadIgnoringCacheData)
216
221
urlRequest. setValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
217
222
urlRequest. setValue ( " application/json " , forHTTPHeaderField: " Accept " )
218
223
urlRequest. httpMethod = call. method. rawValue
@@ -226,17 +231,17 @@ public enum REST: String {
226
231
case GET
227
232
}
228
233
229
- public struct RequestBody : Encodable {
234
+ struct RequestBody : Encodable {
230
235
var jsonrpc = " 2.0 "
231
236
var id = Counter . increment ( )
232
237
233
238
var method : String
234
- var parameters : [ RequestParameter ]
239
+ var params : [ RequestParameter ]
235
240
}
236
241
237
242
/// JSON RPC response structure for serialization and deserialization purposes.
238
- public struct APIResponse < T > : Decodable where T : LiteralInitableFromString {
243
+ public struct APIResponse < Result > : Decodable where Result : APIResultType {
239
244
public var id : Int
240
245
public var jsonrpc = " 2.0 "
241
- public var result : T
246
+ public var result : Result
242
247
}
0 commit comments