Michael Scoff 7 years ago
parent 857966b7df
commit f1cf3b8ea4
  1. 28
      Trust.xcodeproj/project.pbxproj
  2. 41
      Trust/EtherClient/CoinMarket/CoinMarketClient.swift
  3. 8
      Trust/EtherClient/CoinMarket/Types/CoinTicker.swift
  4. 15
      Trust/EtherClient/CoinMarket/Types/CoinTickerID.swift
  5. 74
      Trust/Settings/Coordinators/ExchangeRateCoordinator.swift
  6. 8
      Trust/Settings/ViewControllers/SettingsViewController.swift
  7. 6
      Trust/Transactions/ViewModels/BalanceViewModel.swift

@ -97,6 +97,9 @@
2963B6AD1F981A96003063C1 /* TransactionAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6AC1F981A96003063C1 /* TransactionAppearance.swift */; };
2963B6AF1F9823E6003063C1 /* UnconfirmedTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6AE1F9823E6003063C1 /* UnconfirmedTransaction.swift */; };
2963B6B11F9891F5003063C1 /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6B01F9891F5003063C1 /* UIButton.swift */; };
2963B6B61F9A7E49003063C1 /* CoinMarketClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6B51F9A7E49003063C1 /* CoinMarketClient.swift */; };
2963B6B91F9A7EEA003063C1 /* CoinTicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6B81F9A7EEA003063C1 /* CoinTicker.swift */; };
2963B6BB1F9A899A003063C1 /* CoinTickerID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6BA1F9A899A003063C1 /* CoinTickerID.swift */; };
296421951F70C1EC00EB363B /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296421941F70C1EC00EB363B /* LoadingView.swift */; };
296421971F70C1F200EB363B /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296421961F70C1F200EB363B /* ErrorView.swift */; };
296421991F70C1F900EB363B /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296421981F70C1F900EB363B /* EmptyView.swift */; };
@ -290,6 +293,9 @@
2963B6AC1F981A96003063C1 /* TransactionAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionAppearance.swift; sourceTree = "<group>"; };
2963B6AE1F9823E6003063C1 /* UnconfirmedTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnconfirmedTransaction.swift; sourceTree = "<group>"; };
2963B6B01F9891F5003063C1 /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; };
2963B6B51F9A7E49003063C1 /* CoinMarketClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinMarketClient.swift; sourceTree = "<group>"; };
2963B6B81F9A7EEA003063C1 /* CoinTicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinTicker.swift; sourceTree = "<group>"; };
2963B6BA1F9A899A003063C1 /* CoinTickerID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinTickerID.swift; sourceTree = "<group>"; };
296421941F70C1EC00EB363B /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
296421961F70C1F200EB363B /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = "<group>"; };
296421981F70C1F900EB363B /* EmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyView.swift; sourceTree = "<group>"; };
@ -622,6 +628,7 @@
291F52A01F6B6DBC00B369AB /* EtherClient */ = {
isa = PBXGroup;
children = (
2963B6B41F9A7E13003063C1 /* CoinMarket */,
296106BD1F76391B0006164B /* Etherscan */,
29282B561F7636600067F88D /* Ethplorer */,
291F52A31F6B760A00B369AB /* Requests */,
@ -753,6 +760,24 @@
path = Tokens;
sourceTree = "<group>";
};
2963B6B41F9A7E13003063C1 /* CoinMarket */ = {
isa = PBXGroup;
children = (
2963B6B71F9A7EDE003063C1 /* Types */,
2963B6B51F9A7E49003063C1 /* CoinMarketClient.swift */,
);
path = CoinMarket;
sourceTree = "<group>";
};
2963B6B71F9A7EDE003063C1 /* Types */ = {
isa = PBXGroup;
children = (
2963B6B81F9A7EEA003063C1 /* CoinTicker.swift */,
2963B6BA1F9A899A003063C1 /* CoinTickerID.swift */,
);
path = Types;
sourceTree = "<group>";
};
2977CAE11F7E0B17009682A0 /* Coordinators */ = {
isa = PBXGroup;
children = (
@ -1599,6 +1624,7 @@
29FC0CB61F8298820036089F /* TransactionCoordinator.swift in Sources */,
290B2B5B1F8F551E0053C83E /* LokaliseInitializer.swift in Sources */,
29B6AECB1F7C5FA900EC6DE3 /* PaymentCoordinator.swift in Sources */,
2963B6B91F9A7EEA003063C1 /* CoinTicker.swift in Sources */,
2996F14A1F6C9D10005C33AE /* ExportCoordinator.swift in Sources */,
2932488E1F88E69F008A9818 /* OnePasswordError.swift in Sources */,
291D73C61F7F500D00A8AB56 /* TransactionItemState.swift in Sources */,
@ -1621,7 +1647,9 @@
29285B421F6FB3E60044CF29 /* SendViewController.swift in Sources */,
29AD8A021F93D5CE008E10E7 /* PushNotificationsClient.swift in Sources */,
2996F14D1F6CA743005C33AE /* UIViewController.swift in Sources */,
2963B6BB1F9A899A003063C1 /* CoinTickerID.swift in Sources */,
296421991F70C1F900EB363B /* EmptyView.swift in Sources */,
2963B6B61F9A7E49003063C1 /* CoinMarketClient.swift in Sources */,
291A1B671F98092F00ADEC80 /* ConfirmPaymentViewController.swift in Sources */,
291EC9DF1F7053C50004EDD0 /* NavigationController.swift in Sources */,
291795011F95F5E200539A30 /* GetBalance.swift in Sources */,

@ -0,0 +1,41 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import Moya
enum CoinMarketService {
case price(id: String, currency: String)
}
extension CoinMarketService: TargetType {
var baseURL: URL { return URL(string: "https://api.coinmarketcap.com/v1")! }
var path: String {
switch self {
case .price(let id, _):
return "/ticker/\(id)"
}
}
var method: Moya.Method {
switch self {
case .price: return .get
}
}
var task: Task {
switch self {
case .price(_, let currency):
return .requestCompositeData(bodyData: Data(), urlParameters: ["convert": currency])
}
}
var sampleData: Data {
return Data()
}
var headers: [String: String]? {
return ["Content-type": "application/json"]
}
}

@ -0,0 +1,8 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
struct CoinTicker: Decodable {
let symbol: String
let price_usd: String
}

@ -0,0 +1,15 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
enum CoinTickerID {
case ETH
case custom(String)
var ID: String {
switch self {
case .ETH: return "ethereum"
case .custom(let ID): return ID
}
}
}

@ -1,7 +1,7 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import APIKit
import Moya
protocol ExchangeRateCoordinatorDelegate: class {
func didUpdate(rate: CurrencyRate, in coordinator: ExchangeRateCoordinator)
@ -11,72 +11,32 @@ class ExchangeRateCoordinator: NSObject {
weak var delegate: ExchangeRateCoordinatorDelegate?
override init() {
super.init()
fetch()
}
private let provider = MoyaProvider<CoinMarketService>()
func start() {
fetch()
}
func fetch() {
let request = GetRateRequest()
Session.send(request) { result in
switch result {
case .success(let response):
self.update(rate: response)
case .failure(let error):
self.update(error: error)
}
provider.request(.price(id: CoinTickerID.ETH.ID, currency: "USD")) { result in
guard case .success(let response) = result else { return }
do {
guard let ticker = try response.map([CoinTicker].self).first else { return }
self.update(ticker: ticker)
} catch { }
}
}
func update(rate: CurrencyRate) {
delegate?.didUpdate(rate: rate, in: self)
}
func update(error: Error) {
}
}
class GetRateRequest: Request {
typealias Response = CurrencyRate
var method: HTTPMethod {
return .get
}
var path: String {
return "/exchange-rates"
}
var parameters: Any? {
return ["currency", "USD"]
}
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
guard
let dictionary = object as? [String: AnyObject],
let data = dictionary["data"] as? [String: AnyObject],
let currency = data["currency"] as? String,
let rates = data["rates"] as? [String: String] else {
throw CastError(actualValue: object, expectedType: Response.self)
}
return CurrencyRate(
currency: currency,
rates: rates.map {
func update(ticker: CoinTicker) {
let rate = CurrencyRate(
currency: ticker.symbol,
rates: [
Rate(
code: $0.key,
price: Double($0.value) ?? 0
)
}
code: ticker.symbol,
price: Double(ticker.price_usd) ?? 0
),
]
)
}
var baseURL: URL {
return URL(string: "https://api.coinbase.com/v2")!
delegate?.didUpdate(rate: rate, in: self)
}
}

@ -151,10 +151,10 @@ class SettingsViewController: FormViewController {
<<< AppFormAppearance.button { button in
button.title = NSLocalizedString("Settings.PrivacyPolicy", value: "Privacy Policy", comment: "")
}.onCellSelection { _ in
UIApplication.shared.openURL(URL(string: "http://trustwalletapp.com/privacy-policy.html")!)
}.cellSetup { cell, _ in
cell.imageView?.image = R.image.settings_privacy_policy()
}.onCellSelection { _ in
UIApplication.shared.openURL(URL(string: "http://trustwalletapp.com/privacy-policy.html")!)
}.cellSetup { cell, _ in
cell.imageView?.image = R.image.settings_privacy_policy()
}
+++ Section()

@ -42,8 +42,8 @@ struct BalanceViewModel {
var currencyAmount: String? {
guard let rate = rate else { return nil }
guard let currentRate = (rate.rates.filter { $0.code == "ETH" }.first) else { return nil }
let totalAmount = amount / currentRate.price
guard let currentRate = (rate.rates.filter { $0.code == "ETH" }.first), currentRate.price > 0 else { return nil }
let totalAmount = amount * currentRate.price
return BalanceViewModel.formatter.string(from: NSNumber(value: totalAmount))
}
@ -63,7 +63,7 @@ struct BalanceViewModel {
}
private func attributes(primary: Bool) -> [String: AnyObject] {
switch (primary, rate, balance) {
switch (primary, currencyAmount, balance) {
case (true, .none, .none):
return largeLabelAttributed
case (false, .none, .none), (false, .none, .some), (false, .some, .none):

Loading…
Cancel
Save