@@ -9,10 +9,19 @@ import BigInt
9
9
import EthereumAddress
10
10
import PromiseKit
11
11
12
+ protocol IERC20 {
13
+ func getBalance( account: EthereumAddress ) throws -> BigUInt
14
+ func getAllowance( originalOwner: EthereumAddress , delegate: EthereumAddress ) throws -> BigUInt
15
+ func transfer( from: EthereumAddress , to: EthereumAddress , amount: String ) throws -> WriteTransaction
16
+ func transferFrom( from: EthereumAddress , to: EthereumAddress , originalOwner: EthereumAddress , amount: String ) throws -> WriteTransaction
17
+ func setAllowance( from: EthereumAddress , to: EthereumAddress , newAmount: String ) throws -> WriteTransaction
18
+ func approve( from: EthereumAddress , spender: EthereumAddress , amount: String ) throws -> WriteTransaction
19
+ }
20
+
12
21
// This namespace contains functions to work with ERC20 tokens.
13
22
// variables are lazyly evaluated or global token information (name, ticker, total supply)
14
23
// can be imperatively read and saved
15
- public class ERC20 {
24
+ public class ERC20 : IERC20 {
16
25
17
26
@available ( * , deprecated, renamed: " transactionOptions " )
18
27
public var options : Web3Options = . init( )
@@ -99,7 +108,7 @@ public class ERC20 {
99
108
} . wait ( )
100
109
}
101
110
102
- func getBalance( account: EthereumAddress ) throws -> BigUInt {
111
+ public func getBalance( account: EthereumAddress ) throws -> BigUInt {
103
112
let contract = self . contract
104
113
var transactionOptions = TransactionOptions ( )
105
114
transactionOptions. callOnBlock = . latest
@@ -185,5 +194,26 @@ public class ERC20 {
185
194
return tx
186
195
}
187
196
197
+ public func approve( from: EthereumAddress , spender: EthereumAddress , amount: String ) throws -> WriteTransaction {
198
+ let contract = self . contract
199
+ var basicOptions = TransactionOptions ( )
200
+ basicOptions. from = from
201
+ basicOptions. callOnBlock = . latest
202
+
203
+ // get the decimals manually
204
+ let callResult = try contract. read ( " decimals " , transactionOptions: basicOptions) !. call ( )
205
+ var decimals = BigUInt ( 0 )
206
+ guard let dec = callResult [ " 0 " ] , let decTyped = dec as? BigUInt else {
207
+ throw Web3Error . inputError ( desc: " Contract may be not ERC20 compatible, can not get decimals " ) }
208
+ decimals = decTyped
209
+
210
+ let intDecimals = Int ( decimals)
211
+ guard let value = Web3 . Utils. parseToBigUInt ( amount, decimals: intDecimals) else {
212
+ throw Web3Error . inputError ( desc: " Can not parse inputted amount " )
213
+ }
214
+
215
+ let tx = contract. write ( " approve " , parameters: [ spender, value] as [ AnyObject ] , transactionOptions: basicOptions) !
216
+ return tx
217
+ }
188
218
189
219
}
0 commit comments