Skip to content

Commit 7665ff5

Browse files
Merge pull request #589 from yaroslavyaroslav/network-split
Split library into modules
2 parents 858135b + 4d655bd commit 7665ff5

File tree

166 files changed

+1749
-1560
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

166 files changed

+1749
-1560
lines changed

Package.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ let package = Package(
1919
products: [
2020
.library(name: "web3swift", targets: ["web3swift"])
2121
],
22-
2322
dependencies: [
2423
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.3.0"),
2524
.package(url: "https://github.com/daltoniam/Starscream.git", from: "4.0.4"),
2625
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.5.1")
2726
],
2827
targets: [
2928
.target(name: "secp256k1"),
29+
.target(
30+
name: "Core",
31+
dependencies: ["BigInt", "secp256k1", "CryptoSwift"]
32+
),
3033
.target(
3134
name: "web3swift",
32-
dependencies: ["BigInt", "secp256k1", "Starscream", "CryptoSwift"],
35+
dependencies: ["Core", "BigInt", "secp256k1", "Starscream"],
3336
exclude: excludeFiles,
3437
resources: [
3538
.copy("./Browser/browser.js"),

Sources/web3swift/EthereumAddress/EthereumAddress.swift renamed to Sources/Core/EthereumAddress/EthereumAddress.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ extension EthereumAddress {
124124

125125
}
126126

127+
extension EthereumAddress: Codable {
128+
public init(from decoder: Decoder) throws {
129+
let container = try decoder.singleValueContainer()
130+
let stringValue = try container.decode(String.self)
131+
self.init(stringValue)!
132+
}
133+
134+
public func encode(to encoder: Encoder) throws {
135+
let value = self.address.lowercased()
136+
var signleValuedCont = encoder.singleValueContainer()
137+
try signleValuedCont.encode(value)
138+
}
139+
}
140+
127141
extension EthereumAddress: Hashable { }
128142

129143
extension EthereumAddress: APIResultType { }
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//
2+
// APIRequest+ComputedProperties.swift
3+
//
4+
//
5+
// Created by Yaroslav Yashin on 12.07.2022.
6+
//
7+
8+
import Foundation
9+
10+
extension APIRequest {
11+
var method: REST {
12+
switch self {
13+
default: return .POST
14+
}
15+
}
16+
17+
public var encodedBody: Data {
18+
let request = RequestBody(method: self.call, params: self.parameters)
19+
// this is safe to force try this here
20+
// Because request must failed to compile if it not conformable with `Encodable` protocol
21+
return try! JSONEncoder().encode(request)
22+
}
23+
24+
var parameters: [RequestParameter] {
25+
switch self {
26+
case .gasPrice, .blockNumber, .getNetwork, .getAccounts, .getTxPoolStatus, .getTxPoolContent, .getTxPoolInspect:
27+
return [RequestParameter]()
28+
29+
case .estimateGas(let transactionParameters, let blockNumber):
30+
return [.transaction(transactionParameters), .string(blockNumber.stringValue)]
31+
32+
case let .sendRawTransaction(hash):
33+
return [.string(hash)]
34+
35+
case let .sendTransaction(transactionParameters):
36+
return [.transaction(transactionParameters)]
37+
38+
case .getTransactionByHash(let hash):
39+
return [.string(hash)]
40+
41+
case .getTransactionReceipt(let receipt):
42+
return [.string(receipt)]
43+
44+
case .getLogs(let eventFilterParameters):
45+
return [.eventFilter(eventFilterParameters)]
46+
47+
case .personalSign(let address, let string):
48+
return [.string(address), .string(string)]
49+
50+
case .call(let transactionParameters, let blockNumber):
51+
return [.transaction(transactionParameters), .string(blockNumber.stringValue)]
52+
53+
case .getTransactionCount(let address, let blockNumber):
54+
return [.string(address), .string(blockNumber.stringValue)]
55+
56+
case .getBalance(let address, let blockNumber):
57+
return [.string(address), .string(blockNumber.stringValue)]
58+
59+
case .getStorageAt(let address, let bigUInt, let blockNumber):
60+
return [.string(address), .string(bigUInt.hexString), .string(blockNumber.stringValue)]
61+
62+
case .getCode(let address, let blockNumber):
63+
return [.string(address), .string(blockNumber.stringValue)]
64+
65+
case .getBlockByHash(let hash, let bool):
66+
return [.string(hash), .bool(bool)]
67+
68+
case .getBlockByNumber(let block, let bool):
69+
return [.string(block.stringValue), .bool(bool)]
70+
71+
case .feeHistory(let uInt, let blockNumber, let array):
72+
return [.string(uInt.hexString), .string(blockNumber.stringValue), .doubleArray(array)]
73+
74+
case .createAccount(let string):
75+
return [.string(string)]
76+
77+
case .unlockAccount(let address, let string, let uInt):
78+
return [.string(address), .string(string), .uint(uInt ?? 0)]
79+
}
80+
}
81+
82+
public var call: String {
83+
switch self {
84+
case .gasPrice: return "eth_gasPrice"
85+
case .blockNumber: return "eth_blockNumber"
86+
case .getNetwork: return "net_version"
87+
case .getAccounts: return "eth_accounts"
88+
case .sendRawTransaction: return "eth_sendRawTransaction"
89+
case .sendTransaction: return "eth_sendTransaction"
90+
case .getTransactionByHash: return "eth_getTransactionByHash"
91+
case .getTransactionReceipt: return "eth_getTransactionReceipt"
92+
case .personalSign: return "eth_sign"
93+
case .getLogs: return "eth_getLogs"
94+
case .call: return "eth_call"
95+
case .estimateGas: return "eth_estimateGas"
96+
case .getTransactionCount: return "eth_getTransactionCount"
97+
case .getBalance: return "eth_getBalance"
98+
case .getStorageAt: return "eth_getStorageAt"
99+
case .getCode: return "eth_getCode"
100+
case .getBlockByHash: return "eth_getBlockByHash"
101+
case .getBlockByNumber: return "eth_getBlockByNumber"
102+
case .feeHistory: return "eth_feeHistory"
103+
104+
case .unlockAccount: return "personal_unlockAccount"
105+
case .createAccount: return "personal_createAccount"
106+
case .getTxPoolStatus: return "txpool_status"
107+
case .getTxPoolContent: return "txpool_content"
108+
case .getTxPoolInspect: return "txpool_inspect"
109+
}
110+
}
111+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// APIRequest+Methods.swift
3+
//
4+
//
5+
// Created by Yaroslav Yashin on 12.07.2022.
6+
//
7+
8+
import Foundation
9+
import BigInt
10+
11+
extension APIRequest {
12+
public static func sendRequest<Result>(with provider: Web3Provider, for call: APIRequest) async throws -> APIResponse<Result> {
13+
let request = setupRequest(for: call, with: provider)
14+
return try await APIRequest.send(uRLRequest: request, with: provider.session)
15+
}
16+
17+
static func setupRequest(for call: APIRequest, with provider: Web3Provider) -> URLRequest {
18+
var urlRequest = URLRequest(url: provider.url, cachePolicy: .reloadIgnoringCacheData)
19+
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
20+
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")
21+
urlRequest.httpMethod = call.method.rawValue
22+
urlRequest.httpBody = call.encodedBody
23+
return urlRequest
24+
}
25+
26+
public static func send<Result>(uRLRequest: URLRequest, with session: URLSession) async throws -> APIResponse<Result> {
27+
let (data, response) = try await session.data(for: uRLRequest)
28+
29+
guard 200 ..< 400 ~= response.statusCode else {
30+
if 400 ..< 500 ~= response.statusCode {
31+
throw Web3Error.clientError(code: response.statusCode)
32+
} else {
33+
throw Web3Error.serverError(code: response.statusCode)
34+
}
35+
}
36+
37+
/// This bit of code is purposed to work with literal types that comes in Response in hexString type.
38+
/// Currently it's just `Data` and any kind of Integers `(U)Int`, `Big(U)Int`.
39+
if Result.self == Data.self || Result.self == UInt.self || Result.self == Int.self || Result.self == BigInt.self || Result.self == BigUInt.self {
40+
guard let LiteralType = Result.self as? LiteralInitiableFromString.Type else { throw Web3Error.typeError }
41+
guard let responseAsString = try? JSONDecoder().decode(APIResponse<String>.self, from: data) else { throw Web3Error.dataError }
42+
guard let literalValue = LiteralType.init(from: responseAsString.result) else { throw Web3Error.dataError }
43+
/// `Literal` conforming `LiteralInitiableFromString`, that conforming to an `APIResponseType` type, so it's never fails.
44+
guard let result = literalValue as? Result else { throw Web3Error.typeError }
45+
return APIResponse(id: responseAsString.id, jsonrpc: responseAsString.jsonrpc, result: result)
46+
}
47+
return try JSONDecoder().decode(APIResponse<Result>.self, from: data)
48+
}
49+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// APIRequest+UtilityTypes.swift
3+
//
4+
//
5+
// Created by Yaroslav Yashin on 12.07.2022.
6+
//
7+
8+
import Foundation
9+
10+
/// JSON RPC response structure for serialization and deserialization purposes.
11+
public struct APIResponse<Result>: Decodable where Result: APIResultType {
12+
public var id: Int
13+
public var jsonrpc = "2.0"
14+
public var result: Result
15+
}
16+
17+
enum REST: String {
18+
case POST
19+
case GET
20+
}
21+
22+
struct RequestBody: Encodable {
23+
var jsonrpc = "2.0"
24+
var id = Counter.increment()
25+
26+
var method: String
27+
var params: [RequestParameter]
28+
}

0 commit comments

Comments
 (0)