8
8
9
9
import Foundation
10
10
import PromiseKit
11
+ import BigInt
11
12
12
- enum ListId : String {
13
- case listOfETH
14
- case listOfTokens
15
- }
16
-
17
- extension Scan {
18
- public func getTransactionsHistory( address publicAddress: String , tokenName name: String = " Ether " , page: Int = 1 , size: Int = 50 ) -> Promise < [ Transaction ] > {
13
+ extension BlockExporter {
14
+ public func getTransactionHistory ( address : EthereumAddress , tokenName name : String = " Ether " , page : Int = 1 , size : Int = 50 ) -> Promise < [ TransactionHistorical ] > {
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 < [ TransactionHistorical ] > {
19
20
20
21
//Configuring http request
21
- var listId : ListId
22
- if name == " Ether " {
23
- listId = . listOfETH
24
- } else {
25
- listId = . listOfTokens
26
- }
27
-
22
+ let listId : ListId = ( name == " Ether " ) ? . listOfETH : . listOfTokens
28
23
let url = URL ( string: urlStringList) !
29
24
var request = URLRequest ( url: url)
30
25
request. httpMethod = " POST "
31
- let internalParams : [ String : Any ] = [ " entityId " : publicAddress, " page " : page, " size " : size]
32
- let parameters : [ String : Any ] = [ " listId " : listId. rawValue, " moduleId " : " address " , " params " : internalParams]
33
-
34
-
35
- return Promise< [ Transaction] > { seal in
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< [ TransactionHistorical] > { seal in
36
30
do {
37
- request. httpBody = try JSONSerialization . data ( withJSONObject : parameters, options : [ ] )
31
+ request. httpBody = try JSONEncoder ( ) . encode ( parameters)
38
32
} catch {
39
33
seal. reject ( error)
40
34
}
@@ -60,37 +54,104 @@ extension Scan {
60
54
}
61
55
}
62
56
57
+ //MARK: - Decodable structures
58
+
63
59
public struct Response : Decodable {
64
- let rows : [ Transaction ]
60
+ let rows : [ TransactionHistorical ]
65
61
let head : Head
66
62
}
67
63
68
- public struct Transaction : Decodable {
64
+ public struct TransactionHistorical : Decodable {
69
65
70
66
let id : String
71
- let hash : String
72
- let block : Int
73
- let addrFrom : String
74
- let addrTo : String
67
+ let hash : Data
68
+ let block : BigUInt
69
+ let addressFrom : EthereumAddress
70
+ let addressTo : EthereumAddress
75
71
let isoTime : String
76
- let type : String
77
- let status : Int
72
+ let type : TransactionType
73
+ let status : TransactionStatus
78
74
let error : String
79
- let isContract : Int
80
- let isInner : Int
81
- let value : String
75
+ let isContract : Bool
76
+ let isInner : Bool
77
+ let value : BigUInt // in wei
82
78
let token : Token
83
- let txFee : String
84
- let gasUsed : Double
85
- let gasCost : Double
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
+ }
86
147
87
148
88
149
enum CodingKeys : String , CodingKey {
89
150
case id = " _id "
90
151
case hash
91
152
case block
92
- case addrFrom = " addrfrom "
93
- case addrTo = " addrto "
153
+ case addressFrom = " addrfrom "
154
+ case addressTo = " addrto "
94
155
case isoTime = " isotime "
95
156
case type
96
157
case status
@@ -107,10 +168,33 @@ public struct Transaction: Decodable {
107
168
}
108
169
109
170
public struct Token : Decodable {
110
- let addr : String
171
+ let address : EthereumAddress ?
111
172
let name : String
112
- let smbl : String
113
- let dcm : Int
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
+ }
114
198
}
115
199
116
200
public struct Head : Decodable {
@@ -123,5 +207,32 @@ public struct Head: Decodable {
123
207
let updateTime : String
124
208
}
125
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
+
126
237
127
238
0 commit comments