Skip to content

Commit 273bef7

Browse files
authored
Merge pull request #173 from BANKEX/develop
Merge block explorer functions
2 parents bed90b3 + bd2888c commit 273bef7

16 files changed

+312
-29
lines changed

web3swift.xcodeproj/project.pbxproj

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0073F22620D949F7000791F1 /* BlockExplorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0073F22520D949F7000791F1 /* BlockExplorer.swift */; };
11+
0073F22820D94A11000791F1 /* BlockExplorer+GetTransactionHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0073F22720D94A11000791F1 /* BlockExplorer+GetTransactionHistory.swift */; };
1012
13AE5971A972F5B55FA6FB69 /* libPods-web3swift-iOS_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8349531F1984454E50389370 /* libPods-web3swift-iOS_Tests.a */; };
1113
1CD91B321FD769A6007BFB45 /* web3swiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD91B311FD769A6007BFB45 /* web3swiftTests.swift */; };
1214
1CD91B341FD769A6007BFB45 /* web3swift_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CD91AFC1FD76910007BFB45 /* web3swift_iOS.framework */; };
@@ -113,7 +115,6 @@
113115
818D16D0204D42940084D2A4 /* Web3+EventParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 818D16CE204D42910084D2A4 /* Web3+EventParser.swift */; };
114116
818D810E1FDC1A2000663CE3 /* RLP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 818D810D1FDC1A2000663CE3 /* RLP.swift */; };
115117
818EABDA1FDC9A5C00E013FC /* Contract.swift in Sources */ = {isa = PBXBuildFile; fileRef = 818EABD91FDC9A5C00E013FC /* Contract.swift */; };
116-
81A0FA0320BFEF2B00417C64 /* key.json in Resources */ = {isa = PBXBuildFile; fileRef = 81A0FA0220BFEF2700417C64 /* key.json */; };
117118
81A1821520D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A1821420D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift */; };
118119
81A1821620D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A1821420D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift */; };
119120
81A1821A20D5A6F70016741F /* Promise+HttpProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A1821720D5A3E70016741F /* Promise+HttpProvider.swift */; };
@@ -227,6 +228,8 @@
227228
/* End PBXContainerItemProxy section */
228229

229230
/* Begin PBXFileReference section */
231+
0073F22520D949F7000791F1 /* BlockExplorer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockExplorer.swift; sourceTree = "<group>"; };
232+
0073F22720D94A11000791F1 /* BlockExplorer+GetTransactionHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BlockExplorer+GetTransactionHistory.swift"; sourceTree = "<group>"; };
230233
08BD06D432296DA533D07D20 /* Pods_Web3Swift_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Web3Swift_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; };
231234
0F133EC83594B17BA8C71784 /* Pods_web3swift_ios_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_web3swift_ios_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
232235
10C02100CDF7C2D5C79A52B9 /* Pods_web3Swift_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_web3Swift_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -299,7 +302,6 @@
299302
818D16CE204D42910084D2A4 /* Web3+EventParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+EventParser.swift"; sourceTree = "<group>"; };
300303
818D810D1FDC1A2000663CE3 /* RLP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RLP.swift; sourceTree = "<group>"; };
301304
818EABD91FDC9A5C00E013FC /* Contract.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contract.swift; sourceTree = "<group>"; };
302-
81A0FA0220BFEF2700417C64 /* key.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = key.json; sourceTree = "<group>"; };
303305
81A1821420D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Promise+Web3+Eth+GetBalance.swift"; sourceTree = "<group>"; };
304306
81A1821720D5A3E70016741F /* Promise+HttpProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Promise+HttpProvider.swift"; sourceTree = "<group>"; };
305307
81A1821C20D5C6C10016741F /* web3swift_promises_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = web3swift_promises_Tests.swift; sourceTree = "<group>"; };
@@ -404,6 +406,23 @@
404406
/* End PBXFrameworksBuildPhase section */
405407

406408
/* Begin PBXGroup section */
409+
0073F22320D949D7000791F1 /* BlockExplorer */ = {
410+
isa = PBXGroup;
411+
children = (
412+
0073F22420D949E8000791F1 /* Classes */,
413+
);
414+
path = BlockExplorer;
415+
sourceTree = "<group>";
416+
};
417+
0073F22420D949E8000791F1 /* Classes */ = {
418+
isa = PBXGroup;
419+
children = (
420+
0073F22520D949F7000791F1 /* BlockExplorer.swift */,
421+
0073F22720D94A11000791F1 /* BlockExplorer+GetTransactionHistory.swift */,
422+
);
423+
path = Classes;
424+
sourceTree = "<group>";
425+
};
407426
1CD91AF21FD76910007BFB45 = {
408427
isa = PBXGroup;
409428
children = (
@@ -430,6 +449,7 @@
430449
1CD91AFE1FD76910007BFB45 /* web3swift */ = {
431450
isa = PBXGroup;
432451
children = (
452+
0073F22320D949D7000791F1 /* BlockExplorer */,
433453
81A1821220D5A2430016741F /* Promises */,
434454
81FB2204207BCFD9007F9A83 /* Resources */,
435455
8103BBB4207638F800499769 /* Concurrency */,
@@ -452,7 +472,6 @@
452472
isa = PBXGroup;
453473
children = (
454474
81A1821C20D5C6C10016741F /* web3swift_promises_Tests.swift */,
455-
81A0FA0220BFEF2700417C64 /* key.json */,
456475
1CD91B311FD769A6007BFB45 /* web3swiftTests.swift */,
457476
4EFFCB6F208554EB008165FE /* web3swift_remote_Tests.swift */,
458477
4EFFCB6D208552F2008165FE /* web3swift_local_node_Tests.swift */,
@@ -944,7 +963,6 @@
944963
isa = PBXResourcesBuildPhase;
945964
buildActionMask = 2147483647;
946965
files = (
947-
81A0FA0320BFEF2B00417C64 /* key.json in Resources */,
948966
);
949967
runOnlyForDeploymentPostprocessing = 0;
950968
};
@@ -1135,6 +1153,8 @@
11351153
8113D2CE1FD7E1590074282C /* EthereumTransaction.swift in Sources */,
11361154
81A1821F20D676BC0016741F /* Promise+Web3+Eth+GetTransactionCount.swift in Sources */,
11371155
81A1821520D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift in Sources */,
1156+
0073F22820D94A11000791F1 /* BlockExplorer+GetTransactionHistory.swift in Sources */,
1157+
0073F22620D949F7000791F1 /* BlockExplorer.swift in Sources */,
11381158
81C0FD012044A89300D82FAF /* Web3+TransactionIntermediate.swift in Sources */,
11391159
8103BBC02076800500499769 /* Web3+EthOperations.swift in Sources */,
11401160
81A1823C20D79C270016741F /* Promise+Web3+Eth+Call.swift in Sources */,
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
//
2+
// BlockExporter+GetTransactionHistory.swift
3+
// web3swift-iOS
4+
//
5+
// Created by Георгий Фесенко on 19/06/2018.
6+
// Copyright © 2018 Bankex Foundation. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import PromiseKit
11+
import BigInt
12+
13+
extension BlockExplorer {
14+
public func getTransactionHistory(address: EthereumAddress, tokenName name: String = "Ether", page: Int = 1, size: Int = 50) -> Promise<[TransactionHistoryRecord]> {
15+
let address = address.address
16+
return getTransactionsHistory(address: address, tokenName: name, page: page, size: size)
17+
}
18+
19+
public func getTransactionsHistory(address publicAddress: String, tokenName name: String = "Ether", page: Int = 1, size: Int = 50) -> Promise<[TransactionHistoryRecord]> {
20+
21+
//Configuring http request
22+
let listId: ListId = (name == "Ether") ? .listOfETH : .listOfTokens
23+
let url = URL(string: urlStringList)!
24+
var request = URLRequest(url: url)
25+
request.httpMethod = "POST"
26+
let internalParams = InternalParam(entityId: publicAddress, page: page, size: size)
27+
let parameters = Body(listId: listId.rawValue, moduleId: "address", params: internalParams)
28+
29+
return Promise<[TransactionHistoryRecord]> {seal in
30+
do {
31+
request.httpBody = try JSONEncoder().encode(parameters)
32+
} catch {
33+
seal.reject(error)
34+
}
35+
//Performing the request
36+
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
37+
if let error = error { seal.reject(error); return }
38+
guard let data = data else { return }
39+
40+
do {
41+
//Parsing JSON
42+
let jsonResponce = try JSONDecoder().decode(Response.self, from: data)
43+
if listId == .listOfETH {
44+
seal.fulfill(jsonResponce.rows)
45+
} else {
46+
seal.fulfill( jsonResponce.rows.filter { $0.token.name == name } )
47+
}
48+
} catch {
49+
seal.reject(error)
50+
}
51+
})
52+
task.resume()
53+
}
54+
}
55+
}
56+
57+
//MARK: - Decodable structures
58+
59+
public struct Response: Decodable {
60+
let rows: [TransactionHistoryRecord]
61+
let head: Head
62+
}
63+
64+
public struct TransactionHistoryRecord: Decodable {
65+
66+
let id: String
67+
let hash: Data
68+
let block: BigUInt
69+
let addressFrom: EthereumAddress
70+
let addressTo: EthereumAddress
71+
let isoTime: String
72+
let type: TransactionType
73+
let status: TransactionStatus
74+
let error: String
75+
let isContract: Bool
76+
let isInner: Bool
77+
let value: BigUInt // in wei
78+
let token: Token
79+
let txFee: BigUInt // in wei
80+
let gasUsed: BigUInt // in wei
81+
let gasCost: BigUInt // in wei
82+
83+
public init(from decoder: Decoder) throws {
84+
let container = try decoder.container(keyedBy: CodingKeys.self)
85+
id = try container.decode(String.self, forKey: CodingKeys.id)
86+
let hashString = try container.decode(String.self, forKey: CodingKeys.hash)
87+
guard let hashData = hashString.interpretAsBinaryData() else {
88+
throw Web3Error.transactionSerializationError
89+
}
90+
hash = hashData
91+
let intBlock = try container.decode(UInt64.self, forKey: CodingKeys.block)
92+
block = BigUInt.init(integerLiteral: intBlock)
93+
let stringAddressFrom = try container.decode(String.self, forKey: CodingKeys.addressFrom)
94+
guard let nativeAddressFrom = EthereumAddress(stringAddressFrom, type: .normal, ignoreChecksum: true) else {
95+
throw Web3Error.transactionSerializationError
96+
}
97+
addressFrom = nativeAddressFrom
98+
let stringAddressTo = try container.decode(String.self, forKey: CodingKeys.addressTo)
99+
100+
guard let nativeAddressTo = EthereumAddress(stringAddressTo, type: .normal, ignoreChecksum: true) else {
101+
throw Web3Error.transactionSerializationError
102+
}
103+
addressTo = nativeAddressTo
104+
isoTime = try container.decode(String.self, forKey: CodingKeys.isoTime)
105+
let stringType = try container.decode(String.self, forKey: CodingKeys.type)
106+
var nativeType: TransactionType
107+
switch stringType {
108+
case "tx":
109+
nativeType = .tx
110+
case "call":
111+
nativeType = .call
112+
case "create":
113+
nativeType = .create
114+
case "suicide":
115+
nativeType = .suicide
116+
case "token":
117+
nativeType = .token
118+
default:
119+
nativeType = .tx
120+
}
121+
type = nativeType
122+
123+
let intStatus = try container.decode(Int.self, forKey: CodingKeys.status)
124+
status = intStatus == 0 ? .failed : .succeeded
125+
error = try container.decode(String.self, forKey: CodingKeys.error)
126+
let intIsContract = try container.decode(Int.self, forKey: CodingKeys.isContract)
127+
isContract = intIsContract == 0 ? false : true
128+
let intIsInner = try container.decode(Int.self, forKey: CodingKeys.isInner)
129+
isInner = intIsInner == 0 ? false : true
130+
let stringValue = try container.decode(String.self, forKey: CodingKeys.value)
131+
guard let uintValue = UInt64(stringValue, radix: 16) else {
132+
throw Web3Error.transactionSerializationError
133+
}
134+
value = BigUInt(integerLiteral: uintValue)
135+
token = try container.decode(Token.self, forKey: CodingKeys.token)
136+
let stringTxFee = try container.decode(String.self, forKey: CodingKeys.txFee)
137+
guard let uintTxFee = UInt64(stringTxFee, radix: 16) else {
138+
throw Web3Error.transactionSerializationError
139+
}
140+
141+
txFee = BigUInt.init(integerLiteral: uintTxFee)
142+
let intGasUsed = try container.decode(UInt64.self, forKey: CodingKeys.gasUsed)
143+
gasUsed = BigUInt(integerLiteral: intGasUsed)
144+
let intGasCost = try container.decode(UInt64.self, forKey: CodingKeys.gasCost)
145+
gasCost = BigUInt(integerLiteral: intGasCost)
146+
}
147+
148+
149+
enum CodingKeys: String, CodingKey {
150+
case id = "_id"
151+
case hash
152+
case block
153+
case addressFrom = "addrfrom"
154+
case addressTo = "addrto"
155+
case isoTime = "isotime"
156+
case type
157+
case status
158+
case error
159+
case isContract = "iscontract"
160+
case isInner = "isinner"
161+
case value
162+
case token
163+
case txFee = "txfee"
164+
case gasUsed = "gasused"
165+
case gasCost = "gascost"
166+
}
167+
168+
}
169+
170+
public struct Token: Decodable {
171+
let address: EthereumAddress?
172+
let name: String
173+
let symbol: String
174+
let decimal: Int
175+
176+
enum CodingKeys: String, CodingKey {
177+
case address = "addr"
178+
case name
179+
case symbol = "smbl"
180+
case decimal = "dcm"
181+
}
182+
183+
public init(from decoder: Decoder) throws {
184+
let container = try decoder.container(keyedBy: CodingKeys.self)
185+
let stringAddress = try container.decode(String.self, forKey: CodingKeys.address)
186+
if !stringAddress.isEmpty {
187+
guard let nativeAddress = EthereumAddress(stringAddress, type: .normal, ignoreChecksum: true) else {
188+
throw Web3Error.transactionSerializationError
189+
}
190+
address = nativeAddress
191+
} else {
192+
address = nil
193+
}
194+
name = try container.decode(String.self, forKey: .name)
195+
symbol = try container.decode(String.self, forKey: .symbol)
196+
decimal = try container.decode(Int.self, forKey: .decimal)
197+
}
198+
}
199+
200+
public struct Head: Decodable {
201+
let totalEntities: Int
202+
let pageNumber: Int
203+
let pageSize: Int
204+
let listId: String
205+
let moduleId: String
206+
let entityId: String
207+
let updateTime: String
208+
}
209+
210+
//MARK: - enums
211+
public enum TransactionType {
212+
case tx, call, create, suicide, token
213+
}
214+
215+
public enum TransactionStatus {
216+
case failed, succeeded
217+
}
218+
219+
public enum ListId: String {
220+
case listOfETH
221+
case listOfTokens
222+
}
223+
224+
//MARK: - HTTP body structures
225+
public struct Body:Codable {
226+
let listId:String
227+
let moduleId:String
228+
let params:InternalParam
229+
}
230+
231+
public struct InternalParam:Codable {
232+
let entityId:String
233+
let page:Int
234+
let size:Int
235+
}
236+
237+
238+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// BlockExporter.swift
3+
// web3swift-iOS
4+
//
5+
// Created by Георгий Фесенко on 19/06/2018.
6+
// Copyright © 2018 Bankex Foundation. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public class BlockExplorer {
12+
public var urlStringList = "https://scan.bankex.com/api/list"
13+
}

web3swift/Concurrency/Classes/Web3+Concurrency.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Result
1111

1212
public typealias Callback = ((Result<AnyObject, Web3Error>) -> ())
1313

14+
@available(*, deprecated)
1415
public class OperationDispatcher {
1516
public var MAX_WAIT_TIME: TimeInterval = 0.2
1617
private var provider: Web3Provider
@@ -188,6 +189,7 @@ protocol OperationProtocol{
188189
var error: Web3Error? {get set}
189190
}
190191

192+
@available(*, deprecated)
191193
public class Web3Operation: Operation, OperationProtocol {
192194
var web3: web3
193195

0 commit comments

Comments
 (0)