Skip to content

Commit b5e9fb4

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into develop
2 parents 1fff2c6 + 57fb16b commit b5e9fb4

33 files changed

+373
-331
lines changed

Sources/Core/Transaction/Envelope/LegacyEnvelope.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,12 @@ extension LegacyEnvelope {
195195
let fields: [AnyObject]
196196
switch type {
197197
case .transaction:
198-
fields = [self.nonce, self.gasPrice, self.gasLimit, self.to.addressData, self.value, self.data, v, r, s] as [AnyObject]
198+
fields = [nonce, gasPrice, gasLimit, to.addressData, value, data, v, r, s] as [AnyObject]
199199
case .signature:
200-
if let chainID = self.chainID, chainID != 0 {
201-
fields = [self.nonce, self.gasPrice, self.gasLimit, self.to.addressData, self.value, self.data, chainID, BigUInt(0), BigUInt(0)] as [AnyObject]
200+
if let chainID = chainID, chainID != 0 {
201+
fields = [nonce, gasPrice, gasLimit, to.addressData, value, data, chainID, BigUInt(0), BigUInt(0)] as [AnyObject]
202202
} else {
203-
fields = [self.nonce, self.gasPrice, self.gasLimit, self.to.addressData, self.value, self.data] as [AnyObject]
203+
fields = [nonce, gasPrice, gasLimit, to.addressData, value, data] as [AnyObject]
204204
}
205205
}
206206
return RLP.encode(fields)

Sources/Core/Utility/Utilities.swift

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//
22
// Utilities.swift
3-
//
3+
//
44
//
55
// Created by Yaroslav Yashin on 11.07.2022.
66
//
@@ -87,7 +87,7 @@ public struct Utilities {
8787
/// Parse a user-supplied string using the number of decimals for particular Ethereum unit.
8888
/// If input is non-numeric or precision is not sufficient - returns nil.
8989
/// Allowed decimal separators are ".", ",".
90-
public static func parseToBigUInt(_ amount: String, units: Utilities.Units = .eth) -> BigUInt? {
90+
public static func parseToBigUInt(_ amount: String, units: Utilities.Units = .ether) -> BigUInt? {
9191
let unitDecimals = units.decimals
9292
return parseToBigUInt(amount, decimals: unitDecimals)
9393
}
@@ -112,29 +112,14 @@ public struct Utilities {
112112
return mainPart
113113
}
114114

115-
/// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
116-
/// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
117-
///
118-
/// Returns nil of formatting is not possible to satisfy.
119-
static func formatToEthereumUnits(_ bigNumber: BigInt, toUnits: Utilities.Units = .eth, decimals: Int = 4, decimalSeparator: String = ".") -> String? {
120-
let magnitude = BigInt(bigNumber.magnitude)
121-
guard let formatted = formatToEthereumUnits(magnitude, toUnits: toUnits, decimals: decimals, decimalSeparator: decimalSeparator) else {return nil}
122-
switch bigNumber.sign {
123-
case .plus:
124-
return formatted
125-
case .minus:
126-
return "-" + formatted
127-
}
128-
}
129-
130-
/// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
115+
/// Formats a BigInt object to String. The supplied number is first divided into integer and decimal part based on "units",
131116
/// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
132117
/// Fallbacks to scientific format if higher precision is required.
133118
///
134119
/// Returns nil of formatting is not possible to satisfy.
135-
public static func formatToPrecision(_ bigNumber: BigInt, numberDecimals: Int = 18, formattingDecimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String? {
120+
public static func formatToPrecision(_ bigNumber: BigInt, units: Utilities.Units = .ether, formattingDecimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String {
136121
let magnitude = bigNumber.magnitude
137-
guard let formatted = formatToPrecision(magnitude, numberDecimals: numberDecimals, formattingDecimals: formattingDecimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific) else {return nil}
122+
let formatted = formatToPrecision(magnitude, units: units, formattingDecimals: formattingDecimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific)
138123
switch bigNumber.sign {
139124
case .plus:
140125
return formatted
@@ -143,31 +128,24 @@ public struct Utilities {
143128
}
144129
}
145130

146-
// /// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "toUnits",
147-
// /// then limit the decimal part to "decimals" symbols and uses a "decimalSeparator" as a separator.
148-
// ///
149-
// /// Returns nil of formatting is not possible to satisfy.
150-
// static func formatToEthereumUnits(_ bigNumber: BigUInt, toUnits: Utilities.Units = .eth, decimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String? {
151-
// return formatToPrecision(bigNumber, numberDecimals: toUnits.decimals, formattingDecimals: decimals, decimalSeparator: decimalSeparator, fallbackToScientific: fallbackToScientific)
152-
// }
153-
154-
/// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "numberDecimals",
131+
/// Formats a BigUInt object to String. The supplied number is first divided into integer and decimal part based on "units",
155132
/// then limits the decimal part to "formattingDecimals" symbols and uses a "decimalSeparator" as a separator.
156133
/// Fallbacks to scientific format if higher precision is required.
157134
///
158135
/// Returns nil of formatting is not possible to satisfy.
159-
public static func formatToPrecision(_ bigNumber: BigUInt, numberDecimals: Int = 18, formattingDecimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String? {
136+
public static func formatToPrecision(_ bigNumber: BigUInt, units: Utilities.Units = .ether, formattingDecimals: Int = 4, decimalSeparator: String = ".", fallbackToScientific: Bool = false) -> String {
160137
if bigNumber == 0 {
161138
return "0"
162139
}
140+
let unitDecimals = units.decimals
163141
var toDecimals = formattingDecimals
164-
if numberDecimals < toDecimals {
165-
toDecimals = numberDecimals
142+
if unitDecimals < toDecimals {
143+
toDecimals = unitDecimals
166144
}
167-
let divisor = BigUInt(10).power(numberDecimals)
145+
let divisor = BigUInt(10).power(unitDecimals)
168146
let (quotient, remainder) = bigNumber.quotientAndRemainder(dividingBy: divisor)
169147
var fullRemainder = "\(remainder)"
170-
let fullPaddedRemainder = fullRemainder.leftPadding(toLength: numberDecimals, withPad: "0")
148+
let fullPaddedRemainder = fullRemainder.leftPadding(toLength: unitDecimals, withPad: "0")
171149
let remainderPadded = fullPaddedRemainder[0..<toDecimals]
172150
if remainderPadded == String(repeating: "0", count: toDecimals) {
173151
if quotient != 0 {
@@ -201,7 +179,7 @@ public struct Utilities {
201179
return fullRemainder + "e-" + String(firstDigit)
202180
}
203181
}
204-
if (toDecimals == 0) {
182+
if toDecimals == 0 {
205183
return "\(quotient)"
206184
}
207185
return "\(quotient)" + decimalSeparator + remainderPadded
@@ -309,32 +287,57 @@ public struct Utilities {
309287
extension Utilities {
310288
/// Various units used in Ethereum ecosystem
311289
public enum Units {
312-
case eth
313290
case wei
314-
case Kwei
315-
case Mwei
316-
case Gwei
317-
case Microether
318-
case Finney
291+
case kwei
292+
case babbage
293+
case femtoether
294+
case mwei
295+
case lovelace
296+
case picoether
297+
case gwei
298+
case shannon
299+
case nanoether
300+
case nano
301+
case microether
302+
case szabo
303+
case micro
304+
case finney
305+
case milliether
306+
case milli
307+
case ether
308+
case kether
309+
case grand
310+
case mether
311+
case gether
312+
case tether
313+
case custom(Int)
319314

320315
public var decimals: Int {
321-
get {
322-
switch self {
323-
case .eth:
324-
return 18
325-
case .wei:
326-
return 0
327-
case .Kwei:
328-
return 3
329-
case .Mwei:
330-
return 6
331-
case .Gwei:
332-
return 9
333-
case .Microether:
334-
return 12
335-
case .Finney:
336-
return 15
337-
}
316+
switch self {
317+
case .wei:
318+
return 0
319+
case .kwei, .babbage, .femtoether:
320+
return 3
321+
case .mwei, .lovelace, .picoether:
322+
return 6
323+
case .gwei, .shannon, .nanoether, .nano:
324+
return 9
325+
case .microether, .szabo, .micro:
326+
return 12
327+
case .finney, .milliether, .milli:
328+
return 15
329+
case .ether:
330+
return 18
331+
case .kether, .grand:
332+
return 21
333+
case .mether:
334+
return 24
335+
case .gether:
336+
return 27
337+
case .tether:
338+
return 30
339+
case .custom(let decimals):
340+
return max(0, decimals)
338341
}
339342
}
340343
}

Sources/web3swift/EthereumAPICalls/Ethereum/Eth+GetBlockByHash.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Core
99

1010
extension Web3.Eth {
1111
public func block(by hash: Data, fullTransactions: Bool = false) async throws -> Block {
12-
let request = APIRequest.getBlockByHash(hash.toHexString().addHexPrefix(), fullTransactions)
12+
let request: APIRequest = .getBlockByHash(hash.toHexString().addHexPrefix(), fullTransactions)
1313
return try await APIRequest.sendRequest(with: provider, for: request).result
1414
}
1515
}

Sources/web3swift/Operations/ReadOperation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class ReadOperation {
3636

3737
// TODO: Remove type erasing here, some broad wide protocol should be added instead
3838
public func callContractMethod() async throws -> [String: Any] {
39-
// try await transaction.resolve(provider: web3.provider)
39+
4040
// MARK: Read data from ABI flow
4141
// FIXME: This should be dropped, and after `execute()` call, just to decode raw data.
4242
let data: Data = try await self.web3.eth.callTransaction(transaction)

Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,14 @@ protocol IERC1376: IERC20 {
6767

6868
// FIXME: Rewrite this to CodableTransaction
6969
public class ERC1376: IERC1376, ERC20BaseProperties {
70-
71-
internal var _name: String?
72-
internal var _symbol: String?
73-
internal var _decimals: UInt8?
74-
internal var _hasReadProperties: Bool = false
75-
70+
public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
7671
public var transaction: CodableTransaction
7772
public var web3: Web3
7873
public var provider: Web3Provider
7974
public var address: EthereumAddress
8075
public var abi: String
8176

82-
lazy var contract: Web3.Contract = {
83-
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
84-
precondition(contract != nil)
85-
return contract!
86-
}()
77+
public let contract: Web3.Contract
8778

8879
public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1376ABI, transaction: CodableTransaction = .emptyTransaction) {
8980
self.web3 = web3
@@ -92,6 +83,9 @@ public class ERC1376: IERC1376, ERC20BaseProperties {
9283
self.transaction = transaction
9384
self.transaction.to = address
9485
self.abi = abi
86+
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
87+
contract = web3.contract(abi, at: address)!
88+
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
9589
}
9690

9791
public func getBalance(account: EthereumAddress) async throws -> BigUInt {

Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,14 @@ protocol IERC1400: IERC20 {
6464
// can be imperatively read and saved
6565
// FIXME: Rewrite this to CodableTransaction
6666
public class ERC1400: IERC1400, ERC20BaseProperties {
67-
68-
internal var _name: String?
69-
internal var _symbol: String?
70-
internal var _decimals: UInt8?
71-
internal var _hasReadProperties: Bool = false
72-
67+
public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
7368
public var transaction: CodableTransaction
7469
public var web3: Web3
7570
public var provider: Web3Provider
7671
public var address: EthereumAddress
7772
public var abi: String
7873

79-
lazy var contract: Web3.Contract = {
80-
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
81-
precondition(contract != nil)
82-
return contract!
83-
}()
74+
public let contract: Web3.Contract
8475

8576
public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1400ABI, transaction: CodableTransaction = .emptyTransaction) {
8677
self.web3 = web3
@@ -89,6 +80,9 @@ public class ERC1400: IERC1400, ERC20BaseProperties {
8980
self.transaction = transaction
9081
self.transaction.to = address
9182
self.abi = abi
83+
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
84+
contract = web3.contract(abi, at: address)!
85+
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
9286
}
9387

9488
public func getBalance(account: EthereumAddress) async throws -> BigUInt {

Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,14 @@ protocol IERC1410: IERC20 {
4242

4343
// FIXME: Rewrite this to CodableTransaction
4444
public class ERC1410: IERC1410, ERC20BaseProperties {
45-
46-
internal var _name: String?
47-
internal var _symbol: String?
48-
internal var _decimals: UInt8?
49-
private var _totalSupply: BigUInt?
50-
internal var _hasReadProperties: Bool = false
51-
45+
public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
5246
public var transaction: CodableTransaction
5347
public var web3: Web3
5448
public var provider: Web3Provider
5549
public var address: EthereumAddress
5650
public var abi: String
5751

58-
lazy var contract: Web3.Contract = {
59-
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
60-
precondition(contract != nil)
61-
return contract!
62-
}()
52+
public let contract: Web3.Contract
6353

6454
public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1410ABI, transaction: CodableTransaction = .emptyTransaction) {
6555
self.web3 = web3
@@ -68,6 +58,9 @@ public class ERC1410: IERC1410, ERC20BaseProperties {
6858
self.abi = abi
6959
self.transaction = transaction
7060
self.transaction.to = address
61+
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
62+
contract = web3.contract(abi, at: address)!
63+
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
7164
}
7265

7366
public func getBalance(account: EthereumAddress) async throws -> BigUInt {

Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,14 @@ protocol IERC1594: IERC20 {
3232

3333
// FIXME: Rewrite this to CodableTransaction
3434
public class ERC1594: IERC1594, ERC20BaseProperties {
35-
36-
internal var _name: String?
37-
internal var _symbol: String?
38-
internal var _decimals: UInt8?
39-
internal var _hasReadProperties: Bool = false
40-
35+
public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
4136
public var transaction: CodableTransaction
4237
public var web3: Web3
4338
public var provider: Web3Provider
4439
public var address: EthereumAddress
4540
public var abi: String
4641

47-
lazy var contract: Web3.Contract = {
48-
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
49-
precondition(contract != nil)
50-
return contract!
51-
}()
42+
public let contract: Web3.Contract
5243

5344
public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1594ABI, transaction: CodableTransaction = .emptyTransaction) {
5445
self.web3 = web3
@@ -57,6 +48,9 @@ public class ERC1594: IERC1594, ERC20BaseProperties {
5748
self.transaction = transaction
5849
self.transaction.to = address
5950
self.abi = abi
51+
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
52+
contract = web3.contract(abi, at: address)!
53+
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
6054
}
6155

6256
public func getBalance(account: EthereumAddress) async throws -> BigUInt {

Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,14 @@ protocol IERC1633: IERC20, IERC165 {
1919
}
2020

2121
public class ERC1633: IERC1633, ERC20BaseProperties {
22-
23-
internal var _name: String?
24-
internal var _symbol: String?
25-
internal var _decimals: UInt8?
26-
internal var _hasReadProperties: Bool = false
27-
22+
public private(set) var basePropertiesProvider: ERC20BasePropertiesProvider
2823
public var transaction: CodableTransaction
2924
public var web3: Web3
3025
public var provider: Web3Provider
3126
public var address: EthereumAddress
3227
public var abi: String
3328

34-
lazy var contract: Web3.Contract = {
35-
let contract = self.web3.contract(self.abi, at: self.address, abiVersion: 2)
36-
precondition(contract != nil)
37-
return contract!
38-
}()
29+
public let contract: Web3.Contract
3930

4031
public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1633ABI, transaction: CodableTransaction = .emptyTransaction) {
4132
self.web3 = web3
@@ -44,6 +35,9 @@ public class ERC1633: IERC1633, ERC20BaseProperties {
4435
self.transaction = transaction
4536
self.transaction.to = address
4637
self.abi = abi
38+
// TODO: Make `init` and `web3.contract.init` throwing. Forced because this should fail if ABI is wrongly configured
39+
contract = web3.contract(abi, at: address)!
40+
basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract)
4741
}
4842

4943
public func getBalance(account: EthereumAddress) async throws -> BigUInt {

0 commit comments

Comments
 (0)