-
Notifications
You must be signed in to change notification settings - Fork 448
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #589 from yaroslavyaroslav/network-split
Split library into modules
- Loading branch information
Showing
166 changed files
with
1,749 additions
and
1,560 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
Sources/Core/EthereumNetwork/Request/APIRequest+ComputedProperties.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// | ||
// APIRequest+ComputedProperties.swift | ||
// | ||
// | ||
// Created by Yaroslav Yashin on 12.07.2022. | ||
// | ||
|
||
import Foundation | ||
|
||
extension APIRequest { | ||
var method: REST { | ||
switch self { | ||
default: return .POST | ||
} | ||
} | ||
|
||
public var encodedBody: Data { | ||
let request = RequestBody(method: self.call, params: self.parameters) | ||
// this is safe to force try this here | ||
// Because request must failed to compile if it not conformable with `Encodable` protocol | ||
return try! JSONEncoder().encode(request) | ||
} | ||
|
||
var parameters: [RequestParameter] { | ||
switch self { | ||
case .gasPrice, .blockNumber, .getNetwork, .getAccounts, .getTxPoolStatus, .getTxPoolContent, .getTxPoolInspect: | ||
return [RequestParameter]() | ||
|
||
case .estimateGas(let transactionParameters, let blockNumber): | ||
return [.transaction(transactionParameters), .string(blockNumber.stringValue)] | ||
|
||
case let .sendRawTransaction(hash): | ||
return [.string(hash)] | ||
|
||
case let .sendTransaction(transactionParameters): | ||
return [.transaction(transactionParameters)] | ||
|
||
case .getTransactionByHash(let hash): | ||
return [.string(hash)] | ||
|
||
case .getTransactionReceipt(let receipt): | ||
return [.string(receipt)] | ||
|
||
case .getLogs(let eventFilterParameters): | ||
return [.eventFilter(eventFilterParameters)] | ||
|
||
case .personalSign(let address, let string): | ||
return [.string(address), .string(string)] | ||
|
||
case .call(let transactionParameters, let blockNumber): | ||
return [.transaction(transactionParameters), .string(blockNumber.stringValue)] | ||
|
||
case .getTransactionCount(let address, let blockNumber): | ||
return [.string(address), .string(blockNumber.stringValue)] | ||
|
||
case .getBalance(let address, let blockNumber): | ||
return [.string(address), .string(blockNumber.stringValue)] | ||
|
||
case .getStorageAt(let address, let bigUInt, let blockNumber): | ||
return [.string(address), .string(bigUInt.hexString), .string(blockNumber.stringValue)] | ||
|
||
case .getCode(let address, let blockNumber): | ||
return [.string(address), .string(blockNumber.stringValue)] | ||
|
||
case .getBlockByHash(let hash, let bool): | ||
return [.string(hash), .bool(bool)] | ||
|
||
case .getBlockByNumber(let block, let bool): | ||
return [.string(block.stringValue), .bool(bool)] | ||
|
||
case .feeHistory(let uInt, let blockNumber, let array): | ||
return [.string(uInt.hexString), .string(blockNumber.stringValue), .doubleArray(array)] | ||
|
||
case .createAccount(let string): | ||
return [.string(string)] | ||
|
||
case .unlockAccount(let address, let string, let uInt): | ||
return [.string(address), .string(string), .uint(uInt ?? 0)] | ||
} | ||
} | ||
|
||
public var call: String { | ||
switch self { | ||
case .gasPrice: return "eth_gasPrice" | ||
case .blockNumber: return "eth_blockNumber" | ||
case .getNetwork: return "net_version" | ||
case .getAccounts: return "eth_accounts" | ||
case .sendRawTransaction: return "eth_sendRawTransaction" | ||
case .sendTransaction: return "eth_sendTransaction" | ||
case .getTransactionByHash: return "eth_getTransactionByHash" | ||
case .getTransactionReceipt: return "eth_getTransactionReceipt" | ||
case .personalSign: return "eth_sign" | ||
case .getLogs: return "eth_getLogs" | ||
case .call: return "eth_call" | ||
case .estimateGas: return "eth_estimateGas" | ||
case .getTransactionCount: return "eth_getTransactionCount" | ||
case .getBalance: return "eth_getBalance" | ||
case .getStorageAt: return "eth_getStorageAt" | ||
case .getCode: return "eth_getCode" | ||
case .getBlockByHash: return "eth_getBlockByHash" | ||
case .getBlockByNumber: return "eth_getBlockByNumber" | ||
case .feeHistory: return "eth_feeHistory" | ||
|
||
case .unlockAccount: return "personal_unlockAccount" | ||
case .createAccount: return "personal_createAccount" | ||
case .getTxPoolStatus: return "txpool_status" | ||
case .getTxPoolContent: return "txpool_content" | ||
case .getTxPoolInspect: return "txpool_inspect" | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
Sources/Core/EthereumNetwork/Request/APIRequest+Methods.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// | ||
// APIRequest+Methods.swift | ||
// | ||
// | ||
// Created by Yaroslav Yashin on 12.07.2022. | ||
// | ||
|
||
import Foundation | ||
import BigInt | ||
|
||
extension APIRequest { | ||
public static func sendRequest<Result>(with provider: Web3Provider, for call: APIRequest) async throws -> APIResponse<Result> { | ||
let request = setupRequest(for: call, with: provider) | ||
return try await APIRequest.send(uRLRequest: request, with: provider.session) | ||
} | ||
|
||
static func setupRequest(for call: APIRequest, with provider: Web3Provider) -> URLRequest { | ||
var urlRequest = URLRequest(url: provider.url, cachePolicy: .reloadIgnoringCacheData) | ||
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") | ||
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept") | ||
urlRequest.httpMethod = call.method.rawValue | ||
urlRequest.httpBody = call.encodedBody | ||
return urlRequest | ||
} | ||
|
||
public static func send<Result>(uRLRequest: URLRequest, with session: URLSession) async throws -> APIResponse<Result> { | ||
let (data, response) = try await session.data(for: uRLRequest) | ||
|
||
guard 200 ..< 400 ~= response.statusCode else { | ||
if 400 ..< 500 ~= response.statusCode { | ||
throw Web3Error.clientError(code: response.statusCode) | ||
} else { | ||
throw Web3Error.serverError(code: response.statusCode) | ||
} | ||
} | ||
|
||
/// This bit of code is purposed to work with literal types that comes in Response in hexString type. | ||
/// Currently it's just `Data` and any kind of Integers `(U)Int`, `Big(U)Int`. | ||
if Result.self == Data.self || Result.self == UInt.self || Result.self == Int.self || Result.self == BigInt.self || Result.self == BigUInt.self { | ||
guard let LiteralType = Result.self as? LiteralInitiableFromString.Type else { throw Web3Error.typeError } | ||
guard let responseAsString = try? JSONDecoder().decode(APIResponse<String>.self, from: data) else { throw Web3Error.dataError } | ||
guard let literalValue = LiteralType.init(from: responseAsString.result) else { throw Web3Error.dataError } | ||
/// `Literal` conforming `LiteralInitiableFromString`, that conforming to an `APIResponseType` type, so it's never fails. | ||
guard let result = literalValue as? Result else { throw Web3Error.typeError } | ||
return APIResponse(id: responseAsString.id, jsonrpc: responseAsString.jsonrpc, result: result) | ||
} | ||
return try JSONDecoder().decode(APIResponse<Result>.self, from: data) | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
Sources/Core/EthereumNetwork/Request/APIRequest+UtilityTypes.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// APIRequest+UtilityTypes.swift | ||
// | ||
// | ||
// Created by Yaroslav Yashin on 12.07.2022. | ||
// | ||
|
||
import Foundation | ||
|
||
/// JSON RPC response structure for serialization and deserialization purposes. | ||
public struct APIResponse<Result>: Decodable where Result: APIResultType { | ||
public var id: Int | ||
public var jsonrpc = "2.0" | ||
public var result: Result | ||
} | ||
|
||
enum REST: String { | ||
case POST | ||
case GET | ||
} | ||
|
||
struct RequestBody: Encodable { | ||
var jsonrpc = "2.0" | ||
var id = Counter.increment() | ||
|
||
var method: String | ||
var params: [RequestParameter] | ||
} |
Oops, something went wrong.