Support for ERC20 sending! Yaaaaa

pull/2/head
Michael Scoff 7 years ago
parent 1de81f918a
commit f86a73027c
  1. 12
      Trust.xcodeproj/project.pbxproj
  2. 2
      Trust/Models/Token.swift
  3. 56
      Trust/Tokens/Coordinator/TokensCoordinator.swift
  4. 10
      Trust/Tokens/ViewControllers/TokensViewController.swift
  5. 20
      Trust/Transactions/Coordinators/TransactionCoordinator.swift
  6. 49
      Trust/Transfer/Controllers/ConfirmPaymentViewController.swift
  7. 33
      Trust/Transfer/Controllers/PaymentCoordinator.swift
  8. 2
      Trust/Transfer/Controllers/RequestViewController.swift
  9. 8
      Trust/Transfer/Controllers/SendViewController.swift
  10. 7
      Trust/Transfer/Coordinators/SendTransactionCoordinator.swift
  11. 2
      Trust/Transfer/Types/PaymentFlow.swift
  12. 2
      Trust/Transfer/Types/TransferType.swift

@ -173,6 +173,7 @@
29E2E3411F7B1585000CF94A /* ActionButtonRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29E2E3401F7B1585000CF94A /* ActionButtonRow.swift */; };
29EB102A1F6CBD23000907A4 /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EB10291F6CBD23000907A4 /* UIAlertController.swift */; };
29F114E91FA3EC9E00114A29 /* InCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F114E81FA3EC9E00114A29 /* InCoordinatorTests.swift */; };
29F114EC1FA448F400114A29 /* TokensCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29F114EB1FA448F400114A29 /* TokensCoordinator.swift */; };
29FC0CB61F8298820036089F /* TransactionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29FC0CB51F8298820036089F /* TransactionCoordinator.swift */; };
29FC0CB81F8299510036089F /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29FC0CB71F8299510036089F /* Coordinator.swift */; };
29FC9BC61F830899000209CD /* MirgrationInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29FC9BC51F830880000209CD /* MirgrationInitializer.swift */; };
@ -382,6 +383,7 @@
29E2E3401F7B1585000CF94A /* ActionButtonRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionButtonRow.swift; sourceTree = "<group>"; };
29EB10291F6CBD23000907A4 /* UIAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = "<group>"; };
29F114E81FA3EC9E00114A29 /* InCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InCoordinatorTests.swift; sourceTree = "<group>"; };
29F114EB1FA448F400114A29 /* TokensCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensCoordinator.swift; sourceTree = "<group>"; };
29FC0CB51F8298820036089F /* TransactionCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionCoordinator.swift; sourceTree = "<group>"; };
29FC0CB71F8299510036089F /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
29FC9BC51F830880000209CD /* MirgrationInitializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MirgrationInitializer.swift; sourceTree = "<group>"; };
@ -784,6 +786,7 @@
296106C01F7640240006164B /* Tokens */ = {
isa = PBXGroup;
children = (
29F114EA1FA448DE00114A29 /* Coordinator */,
2977CAF31F7E0C5D009682A0 /* Types */,
2977CAF21F7E0C3A009682A0 /* ViewModels */,
2977CAF11F7E0C33009682A0 /* ViewControllers */,
@ -1172,6 +1175,14 @@
path = Storage;
sourceTree = "<group>";
};
29F114EA1FA448DE00114A29 /* Coordinator */ = {
isa = PBXGroup;
children = (
29F114EB1FA448F400114A29 /* TokensCoordinator.swift */,
);
path = Coordinator;
sourceTree = "<group>";
};
29FC9BC31F830880000209CD /* Core */ = {
isa = PBXGroup;
children = (
@ -1692,6 +1703,7 @@
290B2B5B1F8F551E0053C83E /* LokaliseInitializer.swift in Sources */,
29B6AECB1F7C5FA900EC6DE3 /* PaymentCoordinator.swift in Sources */,
2963B6B91F9A7EEA003063C1 /* CoinTicker.swift in Sources */,
29F114EC1FA448F400114A29 /* TokensCoordinator.swift in Sources */,
2996F14A1F6C9D10005C33AE /* ExportCoordinator.swift in Sources */,
2932488E1F88E69F008A9818 /* OnePasswordError.swift in Sources */,
293E62711FA2F63500CB0A66 /* InitialWalletCreationCoordinator.swift in Sources */,

@ -15,7 +15,7 @@ extension Token {
static func from(address: String, json: [String: AnyObject]) -> Token {
let tokenInfo = json["tokenInfo"] as? [String: AnyObject] ?? [:]
return Token(
address: Address(address: address),
address: Address(address: tokenInfo["address"] as? String ?? ""),
name: tokenInfo["name"] as? String ?? "",
symbol: tokenInfo["symbol"] as? String ?? "",
totalSupply: tokenInfo["symbol"] as? String ?? "",

@ -0,0 +1,56 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import UIKit
protocol TokensCoordinatorDelegate: class {
func didCancel(in coordinator: TokensCoordinator)
}
class TokensCoordinator: Coordinator {
let navigationController: UINavigationController
let account: Account
var coordinators: [Coordinator] = []
weak var delegate: TokensCoordinatorDelegate?
init(
navigationController: UINavigationController,
account: Account
) {
self.navigationController = navigationController
self.account = account
}
func start() {
showTokens()
}
func showTokens() {
let controller = TokensViewController(account: account)
controller.delegate = self
if UIDevice.current.userInterfaceIdiom == .pad {
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .formSheet
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .cancel,
target: self,
action: #selector(dismiss)
)
navigationController.present(nav, animated: true, completion: nil)
} else {
navigationController.pushViewController(controller, animated: true)
}
}
@objc func dismiss() {
navigationController.dismiss(animated: true, completion: nil)
delegate?.didCancel(in: self)
}
}
extension TokensCoordinator: TokensViewControllerDelegate {
func didSelect(token: Token, in viewController: UIViewController) {
//
}
}

@ -5,6 +5,10 @@ import UIKit
import StatefulViewController
import Result
protocol TokensViewControllerDelegate: class {
func didSelect(token: Token, in viewController: UIViewController)
}
class TokensViewController: UIViewController {
private lazy var dataStore: TokensDataStore = {
@ -15,6 +19,7 @@ class TokensViewController: UIViewController {
let account: Account
let tableView: UITableView
let refreshControl = UIRefreshControl()
weak var delegate: TokensViewControllerDelegate?
init(
account: Account
@ -84,7 +89,10 @@ extension TokensViewController: StatefulViewController {
extension TokensViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true )
tableView.deselectRow(at: indexPath, animated: true)
let token = viewModel.item(for: indexPath.row, section: indexPath.section)
delegate?.didSelect(token: token, in: self)
}
}

@ -69,10 +69,15 @@ class TransactionCoordinator: Coordinator {
func showTokens(for account: Account) {
let controller = TokensViewController(account: account)
controller.delegate = self
if UIDevice.current.userInterfaceIdiom == .pad {
let nav = UINavigationController(rootViewController: controller)
nav.modalPresentationStyle = .formSheet
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(dismiss))
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .cancel,
target: self,
action: #selector(dismiss)
)
navigationController.present(nav, animated: true, completion: nil)
} else {
navigationController.pushViewController(controller, animated: true)
@ -143,7 +148,7 @@ extension TransactionCoordinator: SettingsCoordinatorDelegate {
break
case .donate(let address):
coordinator.navigationController.dismiss(animated: true) {
self.showPaymentFlow(for: .send(destination: address), session: self.session)
self.showPaymentFlow(for: .send(type: .ether(destination: address)), session: self.session)
}
}
}
@ -155,7 +160,7 @@ extension TransactionCoordinator: SettingsCoordinatorDelegate {
extension TransactionCoordinator: TransactionsViewControllerDelegate {
func didPressSend(in viewController: TransactionsViewController) {
showPaymentFlow(for: .send(destination: .none), session: session)
showPaymentFlow(for: .send(type: .ether(destination: .none)), session: session)
}
func didPressRequest(in viewController: TransactionsViewController) {
@ -210,3 +215,12 @@ extension TransactionCoordinator: AccountsCoordinatorDelegate {
delegate?.didRestart(with: account, in: self)
}
}
extension TransactionCoordinator: TokensViewControllerDelegate {
func didSelect(token: Token, in viewController: UIViewController) {
showPaymentFlow(for: .send(
type: .token(token)),
session: session
)
}
}

@ -12,6 +12,7 @@ class ConfirmPaymentViewController: UIViewController {
let transaction: UnconfirmedTransaction
let session: WalletSession
let transferType: TransferType
let stackViewController = StackViewController()
lazy var sendTransactionCoordinator = {
return SendTransactionCoordinator(session: self.session)
@ -28,10 +29,12 @@ class ConfirmPaymentViewController: UIViewController {
init(
session: WalletSession,
transaction: UnconfirmedTransaction
transaction: UnconfirmedTransaction,
transferType: TransferType
) {
self.session = session
self.transaction = transaction
self.transferType = transferType
super.init(nibName: nil, bundle: nil)
@ -80,19 +83,39 @@ class ConfirmPaymentViewController: UIViewController {
func send() {
self.displayLoading()
self.sendTransactionCoordinator.send(
address: transaction.address,
value: transaction.amount,
configuration: self.configuration
) { [weak self] result in
guard let `self` = self else { return }
switch result {
case .success(let transaction):
self.delegate?.didCompleted(transaction: transaction, in: self)
case .failure(let error):
self.displayError(error: error)
switch transferType {
case .ether:
self.sendTransactionCoordinator.send(
address: transaction.address,
value: transaction.amount,
configuration: self.configuration
) { [weak self] result in
guard let `self` = self else { return }
switch result {
case .success(let transaction):
self.delegate?.didCompleted(transaction: transaction, in: self)
case .failure(let error):
self.displayError(error: error)
}
self.hideLoading()
}
case .token(let token):
self.sendTransactionCoordinator.send(
contract: token.address,
to: transaction.address,
amount: transaction.amount,
decimals: token.decimals
) { [weak self] result in
guard let `self` = self else { return }
switch result {
case .success(let transaction):
self.delegate?.didCompleted(transaction: transaction, in: self)
case .failure(let error):
self.displayError(error: error)
}
self.hideLoading()
}
self.hideLoading()
}
}
}

@ -33,11 +33,20 @@ class PaymentCoordinator: Coordinator {
switch self.flow {
case .request:
return self.requestViewController
case .send(let destination):
case .send(let type):
return self.sendViewController
}
}()
lazy var transferType: TransferType = {
switch self.flow {
case .send(let type):
return type
case .request:
return .ether(destination: .none)
}
}()
init(
navigationController: UINavigationController = UINavigationController(),
flow: PaymentFlow,
@ -52,7 +61,10 @@ class PaymentCoordinator: Coordinator {
}
func makeSendViewController() -> SendViewController {
let controller = SendViewController(account: self.session.account)
let controller = SendViewController(
account: session.account,
transferType: transferType
)
controller.navigationItem.titleView = titleView
controller.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(dismiss))
controller.navigationItem.rightBarButtonItem = UIBarButtonItem(
@ -61,10 +73,16 @@ class PaymentCoordinator: Coordinator {
target: controller,
action: #selector(SendViewController.send)
)
if case .send(let destination) = flow {
controller.addressRow?.value = destination?.address
controller.addressRow?.cell.row.updateCell()
if case .send(let type) = flow {
switch type {
case .ether(let destination):
controller.addressRow?.value = destination?.address
controller.addressRow?.cell.row.updateCell()
case .token:
break
}
}
controller.delegate = self
return controller
}
@ -103,10 +121,11 @@ extension PaymentCoordinator: SendViewControllerDelegate {
delegate?.didCreatePendingTransaction(transaction, in: self)
}
func didPressConfirm(transaction: UnconfirmedTransaction, in viewController: SendViewController) {
func didPressConfirm(transaction: UnconfirmedTransaction, transferType: TransferType, in viewController: SendViewController) {
let controller = ConfirmPaymentViewController(
session: session,
transaction: transaction
transaction: transaction,
transferType: transferType
)
controller.delegate = self
navigationController.pushViewController(controller, animated: true)

@ -59,7 +59,7 @@ class RequestViewController: UIViewController {
let transferType: TransferType
init(account: Account, transferType: TransferType = .ether) {
init(account: Account, transferType: TransferType = .ether(destination: .none)) {
self.account = account
self.transferType = transferType

@ -9,7 +9,7 @@ import APIKit
import QRCodeReaderViewController
protocol SendViewControllerDelegate: class {
func didPressConfirm(transaction: UnconfirmedTransaction, in viewController: SendViewController)
func didPressConfirm(transaction: UnconfirmedTransaction, transferType: TransferType, in viewController: SendViewController)
func didCreatePendingTransaction(_ transaction: SentTransaction, in viewController: SendViewController)
}
@ -36,7 +36,7 @@ class SendViewController: FormViewController {
return form.rowBy(tag: Values.amount) as? TextFloatLabelRow
}
init(account: Account, transferType: TransferType = .ether) {
init(account: Account, transferType: TransferType = .ether(destination: .none)) {
self.account = account
self.transferType = transferType
@ -58,7 +58,7 @@ class SendViewController: FormViewController {
button.addTarget(self, action: #selector(self.openReader), for: .touchUpInside)
cell.textField.textAlignment = .left
cell.textField.placeholder = "\(self.viewModel.symbol) " + NSLocalizedString("Send.AddressPlaceholder", value: "Address", comment: "")
cell.textField.placeholder = "Ethereum " + NSLocalizedString("Send.AddressPlaceholder", value: "Address", comment: "")
cell.textField.rightView = button
cell.textField.rightViewMode = .always
}
@ -102,7 +102,7 @@ class SendViewController: FormViewController {
amount: amount,
address: address
)
self.delegate?.didPressConfirm(transaction: transaction, in: self)
self.delegate?.didPressConfirm(transaction: transaction, transferType: transferType, in: self)
}
@objc func openReader() {

@ -51,22 +51,17 @@ class SendTransactionCoordinator {
decimals: Int64,
completion: @escaping (Result<SentTransaction, AnyError>) -> Void
) {
//let contract = "0x47c5a08256065306216b3e7cd82b599937540d1f"
//let to = "0x0039f22efb07a647557c7c5d17854cfd6d489ef3"
session.web3.request(request: ContractERC20Transfer(amount: amount, decimals: decimals, address: to.address)) { result in
switch result {
case .success(let res):
NSLog("result \(res)")
self.send(
address: contract,
value: 0,
data: Data(hex: res.drop0x),
configuration: TransactionConfiguration(
speed: TransactionSpeed.custom(
gasPrice: TransactionSpeed.regular.gasPrice,
gasPrice: TransactionSpeed.cheap.gasPrice,
gasLimit: GethNewBigInt(2900000)
)
),

@ -3,6 +3,6 @@
import Foundation
enum PaymentFlow {
case send(destination: Address?)
case send(type: TransferType)
case request
}

@ -3,7 +3,7 @@
import Foundation
enum TransferType {
case ether
case ether(destination: Address?)
case token(Token)
}

Loading…
Cancel
Save