diff --git a/.swift-version b/.swift-version new file mode 100644 index 00000000..ac301e4f --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +5.8 \ No newline at end of file diff --git a/Package.swift b/Package.swift index 8720efba..e90ddd79 100644 --- a/Package.swift +++ b/Package.swift @@ -10,7 +10,8 @@ let package = Package( products: [ .library( name: "LitecoinKit", - targets: ["LitecoinKit"]), + targets: ["LitecoinKit"] + ), ], dependencies: [ .package(url: "https://github.com/horizontalsystems/BitcoinCore.Swift.git", .upToNextMajor(from: "2.2.0")), diff --git a/Sources/LitecoinKit/Classes/Core/Kit.swift b/Sources/LitecoinKit/Classes/Core/Kit.swift index e5b27d28..3ecc1137 100644 --- a/Sources/LitecoinKit/Classes/Core/Kit.swift +++ b/Sources/LitecoinKit/Classes/Core/Kit.swift @@ -30,10 +30,10 @@ public class Kit: AbstractKit { var network: INetwork { switch self { - case .mainNet: - return MainNet() - case .testNet: - return TestNet() + case .mainNet: + return MainNet() + case .testNet: + return TestNet() } } } @@ -53,22 +53,22 @@ public class Kit: AbstractKit { let apiTransactionProvider: IApiTransactionProvider switch networkType { - case .mainNet: - let apiTransactionProviderUrl = "https://ltc.blocksdecoded.com/api" - - if case .blockchair(let key) = syncMode { - let blockchairApi = BlockchairApi(secretKey: key, chainId: network.blockchairChainId, logger: logger) - let blockchairBlockHashFetcher = BlockchairBlockHashFetcher(blockchairApi: blockchairApi) - let blockchairProvider = BlockchairTransactionProvider(blockchairApi: blockchairApi, blockHashFetcher: blockchairBlockHashFetcher) - let bCoinApiProvider = BCoinApi(url: apiTransactionProviderUrl, logger: logger) - - apiTransactionProvider = BiApiBlockProvider(restoreProvider: bCoinApiProvider, syncProvider: blockchairProvider, apiSyncStateManager: apiSyncStateManager) - } else { - apiTransactionProvider = BCoinApi(url: apiTransactionProviderUrl, logger: logger) - } + case .mainNet: + let apiTransactionProviderUrl = "https://ltc.blocksdecoded.com/api" + + if case let .blockchair(key) = syncMode { + let blockchairApi = BlockchairApi(secretKey: key, chainId: network.blockchairChainId, logger: logger) + let blockchairBlockHashFetcher = BlockchairBlockHashFetcher(blockchairApi: blockchairApi) + let blockchairProvider = BlockchairTransactionProvider(blockchairApi: blockchairApi, blockHashFetcher: blockchairBlockHashFetcher) + let bCoinApiProvider = BCoinApi(url: apiTransactionProviderUrl, logger: logger) + + apiTransactionProvider = BiApiBlockProvider(restoreProvider: bCoinApiProvider, syncProvider: blockchairProvider, apiSyncStateManager: apiSyncStateManager) + } else { + apiTransactionProvider = BCoinApi(url: apiTransactionProviderUrl, logger: logger) + } - case .testNet: - apiTransactionProvider = BCoinApi(url: "", logger: logger) + case .testNet: + apiTransactionProvider = BCoinApi(url: "", logger: logger) } let paymentAddressParser = PaymentAddressParser(validScheme: "litecoin", removeScheme: true) @@ -90,12 +90,12 @@ public class Kit: AbstractKit { ) switch networkType { - case .mainNet: - blockValidatorChain.add(blockValidator: difficultyAdjustmentValidator) - blockValidatorChain.add(blockValidator: BitsValidator()) - case .testNet: - blockValidatorChain.add(blockValidator: difficultyAdjustmentValidator) - blockValidatorChain.add(blockValidator: LegacyTestNetDifficultyValidator(blockHelper: blockHelper, heightInterval: Kit.heightInterval, targetSpacing: Kit.targetSpacing, maxTargetBits: Kit.maxTargetBits)) + case .mainNet: + blockValidatorChain.add(blockValidator: difficultyAdjustmentValidator) + blockValidatorChain.add(blockValidator: BitsValidator()) + case .testNet: + blockValidatorChain.add(blockValidator: difficultyAdjustmentValidator) + blockValidatorChain.add(blockValidator: LegacyTestNetDifficultyValidator(blockHelper: blockHelper, heightInterval: Kit.heightInterval, targetSpacing: Kit.targetSpacing, maxTargetBits: Kit.maxTargetBits)) } blockValidatorSet.add(blockValidator: blockValidatorChain) @@ -118,18 +118,18 @@ public class Kit: AbstractKit { .build() super.init(bitcoinCore: bitcoinCore, network: network) - + let base58AddressConverter = Base58AddressConverter(addressVersion: network.pubKeyHash, addressScriptVersion: network.scriptHash) switch purpose { - case .bip44: - bitcoinCore.add(restoreKeyConverter: Bip44RestoreKeyConverter(addressConverter: base58AddressConverter)) - case .bip49: - bitcoinCore.add(restoreKeyConverter: Bip49RestoreKeyConverter(addressConverter: base58AddressConverter)) - case .bip84: - bitcoinCore.add(restoreKeyConverter: KeyHashRestoreKeyConverter(scriptType: .p2wpkh)) - case .bip86: - bitcoinCore.add(restoreKeyConverter: KeyHashRestoreKeyConverter(scriptType: .p2tr)) + case .bip44: + bitcoinCore.add(restoreKeyConverter: Bip44RestoreKeyConverter(addressConverter: base58AddressConverter)) + case .bip49: + bitcoinCore.add(restoreKeyConverter: Bip49RestoreKeyConverter(addressConverter: base58AddressConverter)) + case .bip84: + bitcoinCore.add(restoreKeyConverter: KeyHashRestoreKeyConverter(scriptType: .p2wpkh)) + case .bip86: + bitcoinCore.add(restoreKeyConverter: KeyHashRestoreKeyConverter(scriptType: .p2tr)) } } @@ -157,7 +157,7 @@ public class Kit: AbstractKit { public convenience init(extendedKey: HDExtendedKey, purpose: Purpose, walletId: String, syncMode: BitcoinCore.SyncMode = .api, hasher: ((Data) -> Data)?, networkType: NetworkType = .mainNet, confirmationsThreshold: Int = 6, logger: Logger?) throws { let network = networkType.network - + try self.init(extendedKey: extendedKey, watchAddressPublicKey: nil, purpose: purpose, walletId: walletId, @@ -194,7 +194,6 @@ public class Kit: AbstractKit { confirmationsThreshold: confirmationsThreshold, logger: logger) - bitcoinCore.prepend(addressConverter: bech32AddressConverter) } } diff --git a/Sources/LitecoinKit/Classes/Core/LegacyDifficultyAdjustmentValidator.swift b/Sources/LitecoinKit/Classes/Core/LegacyDifficultyAdjustmentValidator.swift index 2dc70e32..20993976 100644 --- a/Sources/LitecoinKit/Classes/Core/LegacyDifficultyAdjustmentValidator.swift +++ b/Sources/LitecoinKit/Classes/Core/LegacyDifficultyAdjustmentValidator.swift @@ -24,9 +24,9 @@ class LegacyDifficultyAdjustmentValidator: IBlockChainedValidator { } var timespan = previousBlock.timestamp - beforeFirstBlock.timestamp - if (timespan < targetTimespan / 4) { + if timespan < targetTimespan / 4 { timespan = targetTimespan / 4 - } else if (timespan > targetTimespan * 4) { + } else if timespan > targetTimespan * 4 { timespan = targetTimespan * 4 } @@ -45,8 +45,7 @@ class LegacyDifficultyAdjustmentValidator: IBlockChainedValidator { } } - func isBlockValidatable(block: Block, previousBlock: Block) -> Bool { + func isBlockValidatable(block: Block, previousBlock _: Block) -> Bool { block.height % heightInterval == 0 } - } diff --git a/Sources/LitecoinKit/Classes/Core/ProofOfWorkValidator.swift b/Sources/LitecoinKit/Classes/Core/ProofOfWorkValidator.swift index 7fb66186..cae3028f 100644 --- a/Sources/LitecoinKit/Classes/Core/ProofOfWorkValidator.swift +++ b/Sources/LitecoinKit/Classes/Core/ProofOfWorkValidator.swift @@ -1,6 +1,6 @@ -import Foundation -import BitcoinCore import BigInt +import BitcoinCore +import Foundation class ProofOfWorkValidator: IBlockValidator { var hasher: (Data) -> Data @@ -24,13 +24,12 @@ class ProofOfWorkValidator: IBlockValidator { return data } - func validate(block: Block, previousBlock: Block) throws { + func validate(block: Block, previousBlock _: Block) throws { let header = serializeHeader(block: block) let hash = hasher(header) - guard (difficultyEncoder.compactFrom(hash: hash) < block.bits) else { + guard difficultyEncoder.compactFrom(hash: hash) < block.bits else { throw BitcoinCoreErrors.BlockValidation.invalidProofOfWork } } - } diff --git a/Sources/LitecoinKit/Classes/Network/MainNet.swift b/Sources/LitecoinKit/Classes/Network/MainNet.swift index a86935e5..972257eb 100644 --- a/Sources/LitecoinKit/Classes/Network/MainNet.swift +++ b/Sources/LitecoinKit/Classes/Network/MainNet.swift @@ -4,12 +4,12 @@ public class MainNet: INetwork { public let bundleName = "Litecoin" public let pubKeyHash: UInt8 = 0x30 - public let privateKey: UInt8 = 0xb0 + public let privateKey: UInt8 = 0xB0 public let scriptHash: UInt8 = 0x32 public let bech32PrefixPattern: String = "ltc" - public let xPubKey: UInt32 = 0x0488b21e - public let xPrivKey: UInt32 = 0x0488ade4 - public let magic: UInt32 = 0xfbc0b6db + public let xPubKey: UInt32 = 0x0488_B21E + public let xPrivKey: UInt32 = 0x0488_ADE4 + public let magic: UInt32 = 0xFBC0_B6DB public let port = 9333 public let coinType: UInt32 = 2 public let sigHash: SigHashType = .bitcoinAll @@ -20,11 +20,10 @@ public class MainNet: INetwork { "x5.dnsseed.thrasher.io", "x5.dnsseed.litecointools.com", "x5.dnsseed.litecoinpool.org", - "seed-a.litecoin.loshan.co.uk" + "seed-a.litecoin.loshan.co.uk", ] public let dustRelayTxFee = 3000 public init() {} - } diff --git a/Sources/LitecoinKit/Classes/Network/TestNet.swift b/Sources/LitecoinKit/Classes/Network/TestNet.swift index 8364187b..0d385d9c 100644 --- a/Sources/LitecoinKit/Classes/Network/TestNet.swift +++ b/Sources/LitecoinKit/Classes/Network/TestNet.swift @@ -3,13 +3,13 @@ import BitcoinCore class TestNet: INetwork { let bundleName = "Litecoin" - let pubKeyHash: UInt8 = 0x6f - let privateKey: UInt8 = 0xef - let scriptHash: UInt8 = 0x3a + let pubKeyHash: UInt8 = 0x6F + let privateKey: UInt8 = 0xEF + let scriptHash: UInt8 = 0x3A let bech32PrefixPattern: String = "tltc" - let xPubKey: UInt32 = 0x043587cf - let xPrivKey: UInt32 = 0x04358394 - let magic: UInt32 = 0xfdd2c8f1 + let xPubKey: UInt32 = 0x0435_87CF + let xPrivKey: UInt32 = 0x0435_8394 + let magic: UInt32 = 0xFDD2_C8F1 let port = 19335 let coinType: UInt32 = 1 let sigHash: SigHashType = .bitcoinAll diff --git a/iOS Example/Sources/Adapters/BaseAdapter.swift b/iOS Example/Sources/Adapters/BaseAdapter.swift index 684c0596..139b4695 100644 --- a/iOS Example/Sources/Adapters/BaseAdapter.swift +++ b/iOS Example/Sources/Adapters/BaseAdapter.swift @@ -1,6 +1,6 @@ -import Foundation -import Combine import BitcoinCore +import Combine +import Foundation class BaseAdapter { var feeRate: Int { 3 } @@ -28,8 +28,8 @@ class BaseAdapter { for input in transaction.inputs { from.append(TransactionInputOutput( - mine: input.mine, address: input.address, value: input.value, - changeOutput: false, pluginId: nil, pluginData: nil + mine: input.mine, address: input.address, value: input.value, + changeOutput: false, pluginId: nil, pluginData: nil )) } @@ -39,25 +39,25 @@ class BaseAdapter { } to.append(TransactionInputOutput( - mine: output.mine, address: output.address, value: output.value, - changeOutput: output.changeOutput, pluginId: output.pluginId, pluginData: output.pluginData + mine: output.mine, address: output.address, value: output.value, + changeOutput: output.changeOutput, pluginId: output.pluginId, pluginData: output.pluginData )) } return TransactionRecord( - uid: transaction.uid, - transactionHash: transaction.transactionHash, - transactionIndex: transaction.transactionIndex, - interTransactionIndex: 0, - status: TransactionStatus(rawValue: transaction.status.rawValue) ?? TransactionStatus.new, - type: transaction.type, - blockHeight: transaction.blockHeight, - amount: Decimal(transaction.amount) / coinRate, - fee: transaction.fee.map { Decimal($0) / coinRate }, - date: Date(timeIntervalSince1970: Double(transaction.timestamp)), - from: from, - to: to, - conflictingHash: transaction.conflictingHash + uid: transaction.uid, + transactionHash: transaction.transactionHash, + transactionIndex: transaction.transactionIndex, + interTransactionIndex: 0, + status: TransactionStatus(rawValue: transaction.status.rawValue) ?? TransactionStatus.new, + type: transaction.type, + blockHeight: transaction.blockHeight, + amount: Decimal(transaction.amount) / coinRate, + fee: transaction.fee.map { Decimal($0) / coinRate }, + date: Date(timeIntervalSince1970: Double(transaction.timestamp)), + from: from, + to: to, + conflictingHash: transaction.conflictingHash ) } @@ -70,25 +70,23 @@ class BaseAdapter { func transactions(fromUid: String?, type: TransactionFilterType? = nil, limit: Int) -> [TransactionRecord] { abstractKit.transactions(fromUid: fromUid, type: type, limit: limit) - .compactMap { - transactionRecord(fromTransaction: $0) - } + .compactMap { + transactionRecord(fromTransaction: $0) + } } - } extension BaseAdapter { - var lastBlockPublisher: AnyPublisher { lastBlockSubject - .throttle(for: .milliseconds(200), scheduler: RunLoop.current, latest: true) - .eraseToAnyPublisher() + .throttle(for: .milliseconds(200), scheduler: RunLoop.current, latest: true) + .eraseToAnyPublisher() } var syncStatePublisher: AnyPublisher { syncStateSubject - .throttle(for: .milliseconds(200), scheduler: RunLoop.current, latest: true) - .eraseToAnyPublisher() + .throttle(for: .milliseconds(200), scheduler: RunLoop.current, latest: true) + .eraseToAnyPublisher() } var balancePublisher: AnyPublisher { @@ -178,7 +176,6 @@ extension BaseAdapter { func rawTransaction(transactionHash: String) -> String? { abstractKit.rawTransaction(transactionHash: transactionHash) } - } enum SendError: Error { diff --git a/iOS Example/Sources/Adapters/LitecoinAdapter.swift b/iOS Example/Sources/Adapters/LitecoinAdapter.swift index 41abd77a..2d2eff23 100644 --- a/iOS Example/Sources/Adapters/LitecoinAdapter.swift +++ b/iOS Example/Sources/Adapters/LitecoinAdapter.swift @@ -1,7 +1,7 @@ -import LitecoinKit import BitcoinCore -import HsToolKit import HdWalletKit +import HsToolKit +import LitecoinKit class LitecoinAdapter: BaseAdapter { let litecoinKit: Kit @@ -24,25 +24,23 @@ class LitecoinAdapter: BaseAdapter { } extension LitecoinAdapter: BitcoinCoreDelegate { - - func transactionsUpdated(inserted: [TransactionInfo], updated: [TransactionInfo]) { + func transactionsUpdated(inserted _: [TransactionInfo], updated _: [TransactionInfo]) { transactionsSubject.send() } - func transactionsDeleted(hashes: [String]) { + func transactionsDeleted(hashes _: [String]) { transactionsSubject.send() } - func balanceUpdated(balance: BalanceInfo) { + func balanceUpdated(balance _: BalanceInfo) { balanceSubject.send() } - func lastBlockInfoUpdated(lastBlockInfo: BlockInfo) { + func lastBlockInfoUpdated(lastBlockInfo _: BlockInfo) { lastBlockSubject.send() } - public func kitStateUpdated(state: BitcoinCore.KitState) { + public func kitStateUpdated(state _: BitcoinCore.KitState) { syncStateSubject.send() } - } diff --git a/iOS Example/Sources/AppDelegate.swift b/iOS Example/Sources/AppDelegate.swift index 77a158e7..67e65257 100644 --- a/iOS Example/Sources/AppDelegate.swift +++ b/iOS Example/Sources/AppDelegate.swift @@ -1,13 +1,12 @@ import UIKit -@UIApplicationMain +@main class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - private var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid + private var backgroundTask: UIBackgroundTaskIdentifier = .invalid - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let controller = Manager.shared.savedWords == nil ? UINavigationController(rootViewController: WordsController()) : MainController() window = UIWindow(frame: UIScreen.main.bounds) @@ -18,27 +17,23 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func applicationWillResignActive(_ application: UIApplication) { - } + func applicationWillResignActive(_: UIApplication) {} - func applicationDidEnterBackground(_ application: UIApplication) { + func applicationDidEnterBackground(_: UIApplication) { backgroundTask = UIApplication.shared.beginBackgroundTask { UIApplication.shared.endBackgroundTask(self.backgroundTask) self.backgroundTask = UIBackgroundTaskIdentifier.invalid } } - func applicationWillEnterForeground(_ application: UIApplication) { + func applicationWillEnterForeground(_: UIApplication) { if backgroundTask != UIBackgroundTaskIdentifier.invalid { UIApplication.shared.endBackgroundTask(backgroundTask) backgroundTask = UIBackgroundTaskIdentifier.invalid } } - func applicationDidBecomeActive(_ application: UIApplication) { - } - - func applicationWillTerminate(_ application: UIApplication) { - } + func applicationDidBecomeActive(_: UIApplication) {} + func applicationWillTerminate(_: UIApplication) {} } diff --git a/iOS Example/Sources/Configuration.swift b/iOS Example/Sources/Configuration.swift index e887b970..8f6fd279 100644 --- a/iOS Example/Sources/Configuration.swift +++ b/iOS Example/Sources/Configuration.swift @@ -7,8 +7,7 @@ class Configuration { let minLogLevel: Logger.Level = .verbose let testNet = false let defaultWords = [ -// "current force clump paper shrug extra zebra employ prefer upon mobile hire", + // "current force clump paper shrug extra zebra employ prefer upon mobile hire", "popular game latin harvest silly excess much valid elegant illness edge silk", ] - } diff --git a/iOS Example/Sources/Controllers/BalanceController.swift b/iOS Example/Sources/Controllers/BalanceController.swift index 516780fc..32257d5a 100644 --- a/iOS Example/Sources/Controllers/BalanceController.swift +++ b/iOS Example/Sources/Controllers/BalanceController.swift @@ -20,11 +20,11 @@ class BalanceController: UITableViewController { tableView.estimatedRowHeight = 0 Manager.shared.adapterSubject - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.updateAdapters() - } - .store(in: &cancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.updateAdapters() + } + .store(in: &cancellables) updateAdapters() } @@ -37,18 +37,18 @@ class BalanceController: UITableViewController { for (index, adapter) in adapters.enumerated() { Publishers.MergeMany(adapter.lastBlockPublisher, adapter.syncStatePublisher, adapter.balancePublisher) - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.update(index: index) - } - .store(in: &adapterCancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.update(index: index) + } + .store(in: &adapterCancellables) } } @objc func logout() { Manager.shared.logout() - if let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first { + if let window = UIApplication.shared.windows.filter(\.isKeyWindow).first { UIView.transition(with: window, duration: 0.5, options: .transitionCrossDissolve, animations: { window.rootViewController = UINavigationController(rootViewController: WordsController()) }) @@ -71,11 +71,11 @@ class BalanceController: UITableViewController { // print(Manager.shared.ethereumKit.debugInfo) } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { adapters.count } - override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + override func tableView(_: UITableView, heightForRowAt _: IndexPath) -> CGFloat { 220 } @@ -83,7 +83,7 @@ class BalanceController: UITableViewController { tableView.dequeueReusableCell(withIdentifier: String(describing: BalanceCell.self), for: indexPath) } - override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + override func tableView(_: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if let cell = cell as? BalanceCell { cell.bind(adapter: adapters[indexPath.row]) } @@ -92,5 +92,4 @@ class BalanceController: UITableViewController { private func update(index: Int) { tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .none) } - } diff --git a/iOS Example/Sources/Controllers/Cells/BalanceCell.swift b/iOS Example/Sources/Controllers/Cells/BalanceCell.swift index 1b40ed9f..07b99447 100644 --- a/iOS Example/Sources/Controllers/Cells/BalanceCell.swift +++ b/iOS Example/Sources/Controllers/Cells/BalanceCell.swift @@ -1,5 +1,5 @@ -import UIKit import BitcoinCore +import UIKit class BalanceCell: UITableViewCell { static let dateFormatter: DateFormatter = { @@ -9,10 +9,10 @@ class BalanceCell: UITableViewCell { return formatter }() - @IBOutlet weak var nameLabel: UILabel? - @IBOutlet weak var titleLabel: UILabel? - @IBOutlet weak var valueLabel: UILabel? - @IBOutlet weak var errorLabel: UILabel? + @IBOutlet var nameLabel: UILabel? + @IBOutlet var titleLabel: UILabel? + @IBOutlet var valueLabel: UILabel? + @IBOutlet var errorLabel: UILabel? func bind(adapter: BaseAdapter) { let syncStateString: String @@ -20,9 +20,9 @@ class BalanceCell: UITableViewCell { switch adapter.syncState { case .synced: syncStateString = "Synced!" - case .apiSyncing(let transactionsFound): syncStateString = "API Syncing \(transactionsFound) txs" - case .syncing(let progress): syncStateString = "Syncing \(Int(progress * 100))%" - case .notSynced(let error): + case let .apiSyncing(transactionsFound): syncStateString = "API Syncing \(transactionsFound) txs" + case let .syncing(progress): syncStateString = "Syncing \(Int(progress * 100))%" + case let .notSynced(error): syncStateString = "Not Synced" errorString = "\(error)" } @@ -43,20 +43,20 @@ class BalanceCell: UITableViewCell { } set(string: """ - Sync state: - Last block: + Sync state: + Last block: - Spendable balance: - Unspendable balance: - """, alignment: .left, label: titleLabel) + Spendable balance: + Unspendable balance: + """, alignment: .left, label: titleLabel) set(string: """ - \(syncStateString) - \(lastBlockHeightString) - \(lastBlockDateString) - \(adapter.spendableBalance.formattedAmount) \(adapter.coinCode) - \(adapter.unspendableBalance.formattedAmount) \(adapter.coinCode) - """, alignment: .right, label: valueLabel) + \(syncStateString) + \(lastBlockHeightString) + \(lastBlockDateString) + \(adapter.spendableBalance.formattedAmount) \(adapter.coinCode) + \(adapter.unspendableBalance.formattedAmount) \(adapter.coinCode) + """, alignment: .right, label: valueLabel) } private func set(string: String, alignment: NSTextAlignment, label: UILabel?) { @@ -65,9 +65,8 @@ class BalanceCell: UITableViewCell { paragraphStyle.alignment = alignment let attributedString = NSMutableAttributedString(string: string) - attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) label?.attributedText = attributedString } - } diff --git a/iOS Example/Sources/Controllers/Cells/TransactionCell.swift b/iOS Example/Sources/Controllers/Cells/TransactionCell.swift index 53431158..bcd83970 100644 --- a/iOS Example/Sources/Controllers/Cells/TransactionCell.swift +++ b/iOS Example/Sources/Controllers/Cells/TransactionCell.swift @@ -9,15 +9,15 @@ class TransactionCell: UITableViewCell { return formatter }() - @IBOutlet weak var titleLabel: UILabel? - @IBOutlet weak var valueLabel: UILabel? - @IBOutlet weak var transactionTypeLabel: UILabel? + @IBOutlet var titleLabel: UILabel? + @IBOutlet var valueLabel: UILabel? + @IBOutlet var transactionTypeLabel: UILabel? private let coinRate: Decimal = pow(10, 8) func bind(index: Int, transaction: TransactionRecord, coinCode: String, lastBlockHeight: Int?) { var confirmations = "n/a" - if let lastBlockHeight = lastBlockHeight, let blockHeight = transaction.blockHeight { + if let lastBlockHeight, let blockHeight = transaction.blockHeight { confirmations = "\(lastBlockHeight - blockHeight + 1)" } @@ -47,35 +47,35 @@ class TransactionCell: UITableViewCell { } set(string: """ - Tx Hash: \(index) - Tx Status: - Tx Index: - Date: - Type: - Amount: - Fee: - Block: - ConflictingHash: - Confirmations: - \(from.map { _ in "From:" }.joined(separator: "\n")) - \(transaction.to.map { "To:\(String(repeating: "\n", count: TransactionCell.rowsCount(address: $0)))" }.joined(separator: "")) - """, alignment: .left, label: titleLabel) + Tx Hash: \(index) + Tx Status: + Tx Index: + Date: + Type: + Amount: + Fee: + Block: + ConflictingHash: + Confirmations: + \(from.map { _ in "From:" }.joined(separator: "\n")) + \(transaction.to.map { "To:\(String(repeating: "\n", count: TransactionCell.rowsCount(address: $0)))" }.joined(separator: "")) + """, alignment: .left, label: titleLabel) set(string: """ - \(format(hash: transaction.transactionHash)) - \(transaction.status) - \(transaction.transactionIndex) - \(TransactionCell.dateFormatter.string(from: transaction.date)) - \(transaction.type.rawValue) - \(transaction.amount.formattedAmount) \(coinCode) - \(transaction.fee?.formattedAmount ?? "") \(coinCode) - \(transaction.blockHeight.map { "# \($0)" } ?? "n/a") - \(format(hash: transaction.conflictingHash ?? "n/a")) - \(confirmations) - \(from.joined(separator: "\n")) - \(to.joined(separator: "\n")) - """, alignment: .right, label: valueLabel) - + \(format(hash: transaction.transactionHash)) + \(transaction.status) + \(transaction.transactionIndex) + \(TransactionCell.dateFormatter.string(from: transaction.date)) + \(transaction.type.rawValue) + \(transaction.amount.formattedAmount) \(coinCode) + \(transaction.fee?.formattedAmount ?? "") \(coinCode) + \(transaction.blockHeight.map { "# \($0)" } ?? "n/a") + \(format(hash: transaction.conflictingHash ?? "n/a")) + \(confirmations) + \(from.joined(separator: "\n")) + \(to.joined(separator: "\n")) + """, alignment: .right, label: valueLabel) + transactionTypeLabel?.isHidden = transaction.transactionExtraType == nil transactionTypeLabel?.text = transaction.transactionExtraType } @@ -86,7 +86,7 @@ class TransactionCell: UITableViewCell { paragraphStyle.alignment = alignment let attributedString = NSMutableAttributedString(string: string) - attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) label?.attributedText = attributedString } @@ -98,12 +98,10 @@ class TransactionCell: UITableViewCell { return "\(hash[.. Int { + static func rowsCount(address _: TransactionInputOutput) -> Int { 1 } @@ -117,5 +115,4 @@ extension TransactionCell { return height } - } diff --git a/iOS Example/Sources/Controllers/MainController.swift b/iOS Example/Sources/Controllers/MainController.swift index c9083183..49aad253 100644 --- a/iOS Example/Sources/Controllers/MainController.swift +++ b/iOS Example/Sources/Controllers/MainController.swift @@ -1,7 +1,6 @@ import UIKit class MainController: UITabBarController { - override func viewDidLoad() { super.viewDidLoad() @@ -23,5 +22,4 @@ class MainController: UITabBarController { viewControllers = [balanceNavigation, transactionsNavigation, sendNavigation, receiveNavigation] } - } diff --git a/iOS Example/Sources/Controllers/ReceiveController.swift b/iOS Example/Sources/Controllers/ReceiveController.swift index d86d6e2d..cf8af650 100644 --- a/iOS Example/Sources/Controllers/ReceiveController.swift +++ b/iOS Example/Sources/Controllers/ReceiveController.swift @@ -1,11 +1,11 @@ +import BitcoinCore import Combine import UIKit -import BitcoinCore class ReceiveController: UIViewController { private var cancellables = Set() - @IBOutlet weak var addressLabel: UILabel? + @IBOutlet var addressLabel: UILabel? private var adapters = [BaseAdapter]() private let segmentedControl = UISegmentedControl() @@ -19,11 +19,11 @@ class ReceiveController: UIViewController { addressLabel?.clipsToBounds = true Manager.shared.adapterSubject - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.updateAdapters() - } - .store(in: &cancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.updateAdapters() + } + .store(in: &cancellables) updateAdapters() segmentedControl.addTarget(self, action: #selector(onSegmentChanged), for: .valueChanged) @@ -55,11 +55,12 @@ class ReceiveController: UIViewController { currentAdapter?.printDebugs() } + func updateAddress() { addressLabel?.text = " \(currentAdapter?.receiveAddress() ?? "") " } - @IBAction func onAddressTypeChanged(_ sender: Any) { + @IBAction func onAddressTypeChanged(_: Any) { updateAddress() } @@ -80,5 +81,4 @@ class ReceiveController: UIViewController { return adapters[segmentedControl.selectedSegmentIndex] } - } diff --git a/iOS Example/Sources/Controllers/SendController.swift b/iOS Example/Sources/Controllers/SendController.swift index 3afecbea..4f012dfc 100644 --- a/iOS Example/Sources/Controllers/SendController.swift +++ b/iOS Example/Sources/Controllers/SendController.swift @@ -1,16 +1,16 @@ +import BitcoinCore import Combine import UIKit -import BitcoinCore class SendController: UIViewController { private var cancellables = Set() - @IBOutlet weak var addressTextField: UITextField? - @IBOutlet weak var amountTextField: UITextField? - @IBOutlet weak var coinLabel: UILabel? - @IBOutlet weak var feeLabel: UILabel? - @IBOutlet weak var timeLockSwitch: UISwitch? - @IBOutlet weak var picker: UIPickerView? + @IBOutlet var addressTextField: UITextField? + @IBOutlet var amountTextField: UITextField? + @IBOutlet var coinLabel: UILabel? + @IBOutlet var feeLabel: UILabel? + @IBOutlet var timeLockSwitch: UISwitch? + @IBOutlet var picker: UIPickerView? private var adapters = [BaseAdapter]() private let segmentedControl = UISegmentedControl() @@ -22,11 +22,11 @@ class SendController: UIViewController { segmentedControl.addTarget(self, action: #selector(onSegmentChanged), for: .valueChanged) Manager.shared.adapterSubject - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.updateAdapters() - } - .store(in: &cancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.updateAdapters() + } + .store(in: &cancellables) updateAdapters() } @@ -53,8 +53,7 @@ class SendController: UIViewController { do { try currentAdapter?.validate(address: addressStr) address = addressStr - } catch { - } + } catch {} } guard let amountString = amountTextField?.text, let amount = Decimal(string: amountString) else { @@ -78,15 +77,15 @@ class SendController: UIViewController { updateFee() } - @IBAction func onAddressEditEnded(_ sender: Any) { + @IBAction func onAddressEditEnded(_: Any) { updateFee() } - @IBAction func onAmountEditEnded(_ sender: Any) { + @IBAction func onAmountEditEnded(_: Any) { updateFee() } - @IBAction func onTimeLockSwitchToggle(_ sender: Any) { + @IBAction func onTimeLockSwitchToggle(_: Any) { timeLockEnabled = !timeLockEnabled updateFee() } @@ -98,8 +97,7 @@ class SendController: UIViewController { do { try currentAdapter?.validate(address: addressStr) address = addressStr - } catch { - } + } catch {} } if let maxAmount = currentAdapter?.availableBalance(for: address, pluginData: [:]) { @@ -115,8 +113,7 @@ class SendController: UIViewController { do { try currentAdapter?.validate(address: addressStr) address = addressStr - } catch { - } + } catch {} } if let minAmount = currentAdapter?.minSpendableAmount(for: address) { @@ -173,5 +170,4 @@ class SendController: UIViewController { return adapters[segmentedControl.selectedSegmentIndex] } - } diff --git a/iOS Example/Sources/Controllers/TransactionsController.swift b/iOS Example/Sources/Controllers/TransactionsController.swift index e7cbc113..4d95e017 100644 --- a/iOS Example/Sources/Controllers/TransactionsController.swift +++ b/iOS Example/Sources/Controllers/TransactionsController.swift @@ -25,11 +25,11 @@ class TransactionsController: UITableViewController { segmentedControl.addTarget(self, action: #selector(onSegmentChanged), for: .valueChanged) Manager.shared.adapterSubject - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.updateAdapters() - } - .store(in: &cancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.updateAdapters() + } + .store(in: &cancellables) updateAdapters() } @@ -45,18 +45,18 @@ class TransactionsController: UITableViewController { segmentedControl.insertSegment(withTitle: adapter.coinCode, at: index, animated: false) adapter.lastBlockPublisher - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.onLastBlockHeightUpdated(index: index) - } - .store(in: &adapterCancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.onLastBlockHeightUpdated(index: index) + } + .store(in: &adapterCancellables) adapter.transactionsPublisher - .receive(on: DispatchQueue.main) - .sink { [weak self] in - self?.onTransactionsUpdated(index: index) - } - .store(in: &adapterCancellables) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + self?.onTransactionsUpdated(index: index) + } + .store(in: &adapterCancellables) } navigationItem.titleView = segmentedControl @@ -72,11 +72,11 @@ class TransactionsController: UITableViewController { loadNext() } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { transactions.count } - override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + override func tableView(_: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { CGFloat(TransactionCell.rowHeight(for: transactions[indexPath.row])) } @@ -84,8 +84,8 @@ class TransactionsController: UITableViewController { tableView.dequeueReusableCell(withIdentifier: String(describing: TransactionCell.self), for: indexPath) } - override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { - guard let currentAdapter = currentAdapter, indexPath.row < transactions.count else { + override func tableView(_: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + guard let currentAdapter, indexPath.row < transactions.count else { return } @@ -156,5 +156,4 @@ class TransactionsController: UITableViewController { onSegmentChanged() } } - } diff --git a/iOS Example/Sources/Controllers/WordsController.swift b/iOS Example/Sources/Controllers/WordsController.swift index 5bd4e772..6aa43d1f 100644 --- a/iOS Example/Sources/Controllers/WordsController.swift +++ b/iOS Example/Sources/Controllers/WordsController.swift @@ -1,11 +1,10 @@ -import UIKit import HdWalletKit +import UIKit class WordsController: UIViewController { - - @IBOutlet weak var textView: UITextView? - @IBOutlet weak var wordListControl: UISegmentedControl! - @IBOutlet weak var syncModeListControl: UISegmentedControl! + @IBOutlet var textView: UITextView? + @IBOutlet var wordListControl: UISegmentedControl! + @IBOutlet var syncModeListControl: UISegmentedControl! override func viewDidLoad() { super.viewDidLoad() @@ -26,7 +25,7 @@ class WordsController: UIViewController { return } wordListControl.removeAllSegments() - for index in 0..