forked from anchorpw/ethereum-kit-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
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 #86 from yuzushioh/httpclient
Remove APIKit and Result
- Loading branch information
Showing
27 changed files
with
553 additions
and
265 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
github "ishkawa/APIKit" | ||
github "krzyzanowskim/CryptoSwift" |
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 |
---|---|---|
@@ -1,3 +1 @@ | ||
github "antitypical/Result" "3.2.4" | ||
github "ishkawa/APIKit" "3.2.1" | ||
github "krzyzanowskim/CryptoSwift" "0.9.0" |
Large diffs are not rendered by default.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,25 @@ | ||
public enum EthereumKitError: Error { | ||
case apiClientError(APIClientError) | ||
case failedToSign | ||
case failedToEncode(Any) | ||
case keyDerivateionFailed | ||
|
||
public enum RequestError: Error { | ||
case invalidURL | ||
case invalidParameters(Any) | ||
} | ||
|
||
public enum ResponseError: Error { | ||
case jsonrpcError(JSONRPCError) | ||
case connectionError(Error) | ||
case unexpected(Error) | ||
case unacceptableStatusCode(Int) | ||
case noContentProvided | ||
} | ||
|
||
public enum CryptoError: Error { | ||
case failedToSign | ||
case failedToEncode(Any) | ||
case keyDerivateionFailed | ||
} | ||
|
||
case requestError(RequestError) | ||
case responseError(ResponseError) | ||
case cryptoError(CryptoError) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
public enum Result<Object> { | ||
case success(Object) | ||
case failure(EthereumKitError) | ||
} |
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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,48 +1,123 @@ | ||
import Result | ||
|
||
/// Geth is responsible for interacting with Ethereum blockchain | ||
public final class Geth { | ||
|
||
private let etherClient: JSONRPCClient | ||
private let etherscanClient: EtherscanClient | ||
private let configuration: Configuration | ||
private let httpClient: HTTPClient | ||
|
||
/// init initialize Geth instance | ||
/// | ||
/// - Parameter configuration: configuration to use in http client | ||
public init(configuration: Configuration) { | ||
etherClient = JSONRPCClient(configuration: configuration) | ||
etherscanClient = EtherscanClient(configuration: configuration) | ||
self.configuration = configuration | ||
self.httpClient = HTTPClient(configuration: configuration) | ||
} | ||
|
||
// MARK: - JSONRPC APIs | ||
|
||
public func getGasPrice(handler: @escaping (Result<Wei, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.GetGasPrice(), handler: handler) | ||
/// getGasPrice returns currenct gas price | ||
/// | ||
/// - Parameters: | ||
/// - completionHandler: | ||
public func getGasPrice(completionHandler: @escaping (Result<Wei>) -> Void) { | ||
httpClient.send(JSONRPC.GetGasPrice(), completionHandler: completionHandler) | ||
} | ||
|
||
public func getBalance(of address: String, blockParameter: BlockParameter = .latest, handler: @escaping (Result<Balance, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.GetBalance(address: address, blockParameter: blockParameter), handler: handler) | ||
/// getBalance returns currenct balance of specified address. | ||
/// | ||
/// - Parameters: | ||
/// - address: address you want to get the balance of | ||
/// - blockParameter: | ||
/// - completionHandler: | ||
public func getBalance(of address: String, blockParameter: BlockParameter = .latest, completionHandler: @escaping (Result<Balance>) -> Void) { | ||
httpClient.send(JSONRPC.GetBalance(address: address, blockParameter: blockParameter), completionHandler: completionHandler) | ||
} | ||
|
||
public func getTransactionCount(of address: String, blockParameter: BlockParameter = .latest, handler: @escaping (Result<Int, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.GetTransactionCount(address: address, blockParameter: blockParameter), handler: handler) | ||
/// getTransactionCount returns the current nonce of specified address | ||
/// | ||
/// - Parameters: | ||
/// - address: address to check | ||
/// - blockParameter: | ||
/// - completionHandler: | ||
public func getTransactionCount(of address: String, blockParameter: BlockParameter = .latest, completionHandler: @escaping (Result<Int>) -> Void) { | ||
httpClient.send(JSONRPC.GetTransactionCount(address: address, blockParameter: blockParameter), completionHandler: completionHandler) | ||
} | ||
|
||
public func sendRawTransaction(rawTransaction: String, handler: @escaping (Result<SentTransaction, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.SendRawTransaction(rawTransaction: rawTransaction), handler: handler) | ||
/// sendRawTransaction sends the raw transaction string | ||
/// | ||
/// - Parameters: | ||
/// - rawTransaction: raw transaction encoded in rlp hex format | ||
/// - completionHandler: | ||
public func sendRawTransaction(rawTransaction: String, completionHandler: @escaping (Result<SentTransaction>) -> Void) { | ||
httpClient.send(JSONRPC.SendRawTransaction(rawTransaction: rawTransaction), completionHandler: completionHandler) | ||
} | ||
|
||
public func call(from: String? = nil, to: String, gasLimit: Gas.GasLimit? = nil, gasPrice: Gas.GasPrice? = nil, value: Int? = nil, data: String? = nil, blockParameter: BlockParameter = .latest, handler: @escaping (Result<String, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.Call(from: from, to: to, gas: gasLimit.map { $0.value }, gasPrice: gasPrice.map { $0.value }, value: value, data: data, blockParameter: blockParameter), handler: handler) | ||
/// getBlockNumber returns the latest block number | ||
/// | ||
/// - Parameter completionHandler: | ||
public func getBlockNumber(completionHandler: @escaping (Result<Int>) -> Void) { | ||
httpClient.send(JSONRPC.GetBlockNumber(), completionHandler: completionHandler) | ||
} | ||
|
||
public func getEstimateGas(from: String? = nil, to: String, gasLimit: Gas.GasLimit? = nil, gasPrice: Gas.GasPrice? = nil, value: Int? = nil, data: String? = nil, handler: @escaping (Result<Wei, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.GetEstimatGas(from: from, to: to, gas: gasLimit.map { $0.value }, gasPrice: gasPrice.map { $0.value }, value: value, data: data), handler: handler) | ||
/// call sends transaction to a contract method | ||
/// | ||
/// - Parameters: | ||
/// - from: which address to send from | ||
/// - to: which address to send to | ||
/// - gasLimit: gas limit | ||
/// - gasPrice: gas price | ||
/// - value: value in wei | ||
/// - data: data to include in tx | ||
/// - blockParameter: | ||
/// - completionHandler: | ||
public func call(from: String? = nil, to: String, gasLimit: Gas.GasLimit? = nil, gasPrice: Gas.GasPrice? = nil, value: Int? = nil, data: String? = nil, blockParameter: BlockParameter = .latest, completionHandler: @escaping (Result<String>) -> Void) { | ||
let request = JSONRPC.Call( | ||
from: from, | ||
to: to, | ||
gas: gasLimit.map { $0.value }, | ||
gasPrice: gasPrice.map { $0.value }, | ||
value: value, | ||
data: data, | ||
blockParameter: blockParameter | ||
) | ||
|
||
httpClient.send(request, completionHandler: completionHandler) | ||
} | ||
|
||
public func getBlockNumber(handler: @escaping (Result<Int, EthereumKitError>) -> Void) { | ||
etherClient.send(JSONRPC.GetBlockNumber(), handler: handler) | ||
/// getEstimateGas returns estimated gas for the tx | ||
/// | ||
/// - Parameters: | ||
/// - from: which address to send from | ||
/// - to: which address to send to | ||
/// - gasLimit: gas limit | ||
/// - gasPrice: gas price | ||
/// - value: value in wei | ||
/// - data: data to include in tx | ||
/// - completionHandler: | ||
public func getEstimateGas(from: String? = nil, to: String, gasLimit: Gas.GasLimit? = nil, gasPrice: Gas.GasPrice? = nil, value: Int? = nil, data: String? = nil, completionHandler: @escaping (Result<Wei>) -> Void) { | ||
let request = JSONRPC.GetEstimatGas( | ||
from: from, | ||
to: to, | ||
gas: gasLimit.map { $0.value }, | ||
gasPrice: gasPrice.map { $0.value }, | ||
value: value, | ||
data: data | ||
) | ||
|
||
httpClient.send(request, completionHandler: completionHandler) | ||
} | ||
|
||
// MARK: - Etherscan APIs | ||
|
||
public func getTransactions(address: String, sort: Etherscan.GetTransactions.Sort = .des, startBlock: Int64 = 0, endBlock: Int64 = 99999999, handler: @escaping (Result<Transactions, EthereumKitError>) -> Void) { | ||
etherscanClient.send(Etherscan.GetTransactions(address: address, sort: sort, startBlock: startBlock, endBlock: endBlock), handler: handler) | ||
/// getTransactions returns the list of transaction for the specified address. | ||
/// | ||
/// - Parameters: | ||
/// - address: address to get transactions from | ||
/// - completionHandler: | ||
public func getTransactions(address: String, completionHandler: @escaping (Result<Transactions>) -> Void) { | ||
let request = Etherscan.GetTransactions( | ||
configuration: .init(baseURL: configuration.etherscanURL, apiKey: configuration.etherscanAPIKey), | ||
address: address | ||
) | ||
httpClient.send(request, completionHandler: completionHandler) | ||
} | ||
} |
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,5 @@ | ||
public protocol Cancellable: class { | ||
func cancel() | ||
} | ||
|
||
extension URLSessionTask: Cancellable {} |
File renamed without changes.
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,55 @@ | ||
/// HTTPClient is responsible for sending and canceling url requests | ||
public class HTTPClient: HTTPClientType { | ||
|
||
/// batchFactory is used for creating batch request for JSONRPC request | ||
private let batchFactory = BatchFactory(version: "2.0") | ||
|
||
/// configuration is used for configuring request information | ||
public let configuration: Configuration | ||
|
||
|
||
/// init initialize HTTPClient | ||
/// | ||
/// - Parameter configuration: configuration to use to configure requests | ||
public init(configuration: Configuration) { | ||
self.configuration = configuration | ||
} | ||
|
||
/// send method sends specified jsonrpc request and returns a session task. | ||
/// | ||
/// - Parameters: | ||
/// - request: request to send. needs to be conformed to JSONRPCRequest protocol | ||
/// - completionHandler: | ||
/// - Returns: session task used to send request | ||
@discardableResult | ||
public func send<Request: JSONRPCRequest>(_ request: Request, completionHandler: @escaping (Result<Request.Response>) -> Void) -> Cancellable? { | ||
let httpRequest = HTTPJSONRPCRequest(batch: batchFactory.create(request), endpoint: URL(string: configuration.nodeEndpoint)!) | ||
return send(httpRequest, completionHandler: completionHandler) | ||
} | ||
|
||
/// send method sends specified json request and returns a session task. | ||
/// | ||
/// - Parameters: | ||
/// - request: request to send, needs to be conformed to RequestType protocol | ||
/// - completionHandler: | ||
/// - Returns: session task used to send request | ||
@discardableResult | ||
public func send<Request: RequestType>(_ request: Request, completionHandler: @escaping (Result<Request.Response>) -> Void) -> Cancellable? { | ||
switch request.build() { | ||
case .success(let urlRequest): | ||
let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in | ||
let result = request.buildResponse(from: data, response: response, error: error) | ||
DispatchQueue.main.async { | ||
completionHandler(result) | ||
} | ||
} | ||
|
||
task.resume() | ||
return task | ||
|
||
case .failure(let error): | ||
completionHandler(.failure(error)) | ||
return nil | ||
} | ||
} | ||
} |
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,11 @@ | ||
public protocol HTTPClientType { | ||
@discardableResult | ||
func send<Request: RequestType>( | ||
_ request: Request, | ||
completionHandler: @escaping (Result<Request.Response>) -> Void) -> Cancellable? | ||
|
||
@discardableResult | ||
func send<Request: JSONRPCRequest>( | ||
_ request: Request, | ||
completionHandler: @escaping (Result<Request.Response>) -> Void) -> Cancellable? | ||
} |
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,13 @@ | ||
public enum Method: String { | ||
case get | ||
case post | ||
|
||
public var prefersQueryParameters: Bool { | ||
switch self { | ||
case .get: | ||
return true | ||
case .post: | ||
return false | ||
} | ||
} | ||
} |
Oops, something went wrong.