From 8a30c23687985a85ae6e9631ca80dfd802c4a36d Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Sat, 1 Mar 2025 20:13:16 +0700 Subject: [PATCH 01/36] [trello.com/c/vawidi4o] Add UI for Secret Wallets and combine it with service --- Adamant.xcodeproj/project.pbxproj | 36 ++++- Adamant/App/DI/AppAssembly.swift | 11 +- Adamant/Modules/Account/AccountFactory.swift | 4 +- Adamant/Modules/Account/AccountHeader.xib | 24 ++- .../Modules/Account/AccountHeaderView.swift | 6 + .../AccountViewController.swift | 28 +++- .../AccountWallets/AccountWalletsState.swift | 10 +- .../AccountWalletsViewModel.swift | 49 +++--- .../SecretWalletsAlertService.swift | 149 ++++++++++++++++++ .../SecretWallets/SecretWalletsState.swift | 23 +++ .../SecretWalletsViewModel.swift | 58 +++++++ .../Wallets/ERC20/ERC20WalletService.swift | 3 +- .../EthBIP32Service/EthBIP32Service.swift | 18 +-- .../Wallets/Ethereum/EthWalletService.swift | 4 +- .../SecretWalletsManagerProtocol.swift | 9 +- .../AdamantDialogService.swift | 22 ++- Adamant/Services/SecretWalletsFactory.swift | 18 ++- ...rvice.swift => SecretWalletsManager.swift} | 38 ++--- 18 files changed, 411 insertions(+), 99 deletions(-) create mode 100644 Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift create mode 100644 Adamant/Modules/SecretWallets/SecretWalletsState.swift create mode 100644 Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift rename Adamant/Services/{SecretWalletsService.swift => SecretWalletsManager.swift} (62%) diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 7cb0de6de..e25a2c41e 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -187,9 +187,13 @@ 41CA598C29A0D84F002BFDE4 /* TaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA598B29A0D84F002BFDE4 /* TaskManager.swift */; }; 41CE153A297FF98200CC9254 /* Web3Swift+Adamant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CE1539297FF98200CC9254 /* Web3Swift+Adamant.swift */; }; 41E3C9CC2A0E20F500AF0985 /* AdamantCoinTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */; }; + 48023DEF2D72EA7F00852961 /* AccountHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48023DEE2D72EA7F00852961 /* AccountHeader.xib */; }; + 48023DF12D72FB3500852961 /* SecretWalletsAlertService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */; }; 4803FC9A2D6715AF00452D2C /* SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */; }; - 481558702D65A7660011B470 /* SecretWalletsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4815586F2D65A7660011B470 /* SecretWalletsService.swift */; }; + 481558702D65A7660011B470 /* SecretWalletsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */; }; 481558722D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */; }; + 482231212D714C3D00D592D8 /* SecretWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */; }; + 488C1E8A2D7150F900E955E8 /* SecretWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */; }; 48B6A8EB2D5738D800326EE8 /* WalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */; }; 48B6A8ED2D57390400326EE8 /* AdamantWalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */; }; 48B6A8EF2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */; }; @@ -607,7 +611,6 @@ E94008872114F05B00CD2D67 /* AddressValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = E94008862114F05B00CD2D67 /* AddressValidationResult.swift */; }; E940088B2114F63000CD2D67 /* NSRegularExpression+adamant.swift in Sources */ = {isa = PBXBuildFile; fileRef = E940088A2114F63000CD2D67 /* NSRegularExpression+adamant.swift */; }; E940088F2119A9E800CD2D67 /* BigInt+Decimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = E940088E2119A9E800CD2D67 /* BigInt+Decimal.swift */; }; - E941CCDB20E786D800C96220 /* AccountHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = E941CCDA20E786D700C96220 /* AccountHeader.xib */; }; E941CCDE20E7B70200C96220 /* WalletCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E941CCDC20E7B70200C96220 /* WalletCollectionViewCell.swift */; }; E941CCDF20E7B70200C96220 /* WalletCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E941CCDD20E7B70200C96220 /* WalletCollectionViewCell.xib */; }; E9484B79227C617E008E10F0 /* BalanceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9484B77227C617D008E10F0 /* BalanceTableViewCell.swift */; }; @@ -919,9 +922,13 @@ 41CA598B29A0D84F002BFDE4 /* TaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskManager.swift; sourceTree = ""; }; 41CE1539297FF98200CC9254 /* Web3Swift+Adamant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3Swift+Adamant.swift"; sourceTree = ""; }; 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantCoinTools.swift; sourceTree = ""; }; + 48023DEE2D72EA7F00852961 /* AccountHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountHeader.xib; sourceTree = ""; }; + 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsAlertService.swift; sourceTree = ""; }; 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsFactory.swift; sourceTree = ""; }; - 4815586F2D65A7660011B470 /* SecretWalletsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsService.swift; sourceTree = ""; }; + 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManager.swift; sourceTree = ""; }; 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManagerProtocol.swift; sourceTree = ""; }; + 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsViewModel.swift; sourceTree = ""; }; + 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsState.swift; sourceTree = ""; }; 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsStoreService.swift; sourceTree = ""; }; 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletsStoreService.swift; sourceTree = ""; }; 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletStoreServiceProvider.swift; sourceTree = ""; }; @@ -1315,7 +1322,6 @@ E94008862114F05B00CD2D67 /* AddressValidationResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressValidationResult.swift; sourceTree = ""; }; E940088A2114F63000CD2D67 /* NSRegularExpression+adamant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+adamant.swift"; sourceTree = ""; }; E940088E2119A9E800CD2D67 /* BigInt+Decimal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BigInt+Decimal.swift"; sourceTree = ""; }; - E941CCDA20E786D700C96220 /* AccountHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AccountHeader.xib; sourceTree = ""; }; E941CCDC20E7B70200C96220 /* WalletCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletCollectionViewCell.swift; sourceTree = ""; }; E941CCDD20E7B70200C96220 /* WalletCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WalletCollectionViewCell.xib; sourceTree = ""; }; E9484B77227C617D008E10F0 /* BalanceTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceTableViewCell.swift; sourceTree = ""; }; @@ -1796,6 +1802,16 @@ path = RichTransactionReplyService; sourceTree = ""; }; + 482231222D714C4400D592D8 /* SecretWallets */ = { + isa = PBXGroup; + children = ( + 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */, + 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */, + 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */, + ); + path = SecretWallets; + sourceTree = ""; + }; 48EE54F52D4BBD240036D340 /* AccountWallets */ = { isa = PBXGroup; children = ( @@ -2622,7 +2638,7 @@ E9E7CDBF2003AF6D00DFC4DB /* AdamantCellFactory.swift */, E93D7ABF2052CF63005D19DC /* AdamantNotificationService.swift */, 41047B75294C62710039E956 /* AdamantVisibleWalletsService.swift */, - 4815586F2D65A7660011B470 /* SecretWalletsService.swift */, + 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */, 4153045829C09902000E4BEA /* AdamantIncreaseFeeService.swift */, 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */, 4184F1722A33102800D7B8B9 /* AdamantCrashlysticsService.swift */, @@ -2756,6 +2772,7 @@ E940086C2114A8FD00CD2D67 /* Wallets */, 938F7D552955C05D001915CA /* Chat */, E9E7CDA52002AE1C00DFC4DB /* Account */, + 482231222D714C4400D592D8 /* SecretWallets */, E95F857B2008C8B20070534A /* ChatsList */, 644EC35020EFA96700F40C73 /* Delegates */, E919479A20001007001362F8 /* Login */, @@ -3069,7 +3086,7 @@ 85B405002D3012BD000AB744 /* AccountViewController */, E983AE2020E655C500497E1A /* AccountHeaderView.swift */, 269E13512B594B2D008D1CA7 /* AccountFooterView.swift */, - E941CCDA20E786D700C96220 /* AccountHeader.xib */, + 48023DEE2D72EA7F00852961 /* AccountHeader.xib */, E983AE2C20E6720D00497E1A /* AccountFooter.xib */, E941CCDC20E7B70200C96220 /* WalletCollectionViewCell.swift */, E941CCDD20E7B70200C96220 /* WalletCollectionViewCell.xib */, @@ -3394,6 +3411,7 @@ E9942B89203D9ECA00C163AF /* QrCell.xib in Resources */, 93496BB22A6CAED100DD062F /* Exo+2_400_italic.ttf in Resources */, 93496BAD2A6CAED100DD062F /* Roboto_700_normal.ttf in Resources */, + 48023DEF2D72EA7F00852961 /* AccountHeader.xib in Resources */, E921597D2065031D0000CA5C /* ButtonsStripe.xib in Resources */, 269B83342C74B4EC002AA1D7 /* welcome.mp3 in Resources */, 93496BAE2A6CAED100DD062F /* Exo+2_700_normal.ttf in Resources */, @@ -3406,7 +3424,6 @@ E90EA5C321BA8BF400A2CE25 /* DelegateDetailsViewController.xib in Resources */, 269B83242C74B4EC002AA1D7 /* droplet.mp3 in Resources */, E94E7B01205D3F090042B639 /* ChatListViewController.xib in Resources */, - E941CCDB20E786D800C96220 /* AccountHeader.xib in Resources */, 269B83322C74B4EC002AA1D7 /* slide.mp3 in Resources */, 93496BB72A6CAED100DD062F /* Roboto_500_normal.ttf in Resources */, 269B83102C74A2FF002AA1D7 /* note.mp3 in Resources */, @@ -3720,6 +3737,7 @@ 3A7BD0102AA9BD030045AAB0 /* AdamantVibroService.swift in Sources */, 85B405022D3012D5000AB744 /* AccountViewController+Form.swift in Sources */, 937EDFC02C9CF6B300F219BB /* VersionFooterView.swift in Sources */, + 488C1E8A2D7150F900E955E8 /* SecretWalletsState.swift in Sources */, A5E04227282A8BDC0076CD13 /* BtcBalanceResponse.swift in Sources */, 64F085D920E2D7600006DE68 /* AdmTransactionsViewController.swift in Sources */, 9322E87B2970431200B8357C /* ChatMessageFactory.swift in Sources */, @@ -3795,7 +3813,7 @@ A50A41142822FC35006BDFE1 /* BtcTransferViewController.swift in Sources */, 93294B8E2AAD2C6B00911109 /* SwiftyOnboardPage.swift in Sources */, E971591A21681D6900A5F904 /* TransactionStatus.swift in Sources */, - 481558702D65A7660011B470 /* SecretWalletsService.swift in Sources */, + 481558702D65A7660011B470 /* SecretWalletsManager.swift in Sources */, 648CE3A022999C890070A2CC /* BaseBtcTransaction.swift in Sources */, A50A410A2822F8CE006BDFE1 /* BtcWallet.swift in Sources */, E908472C2196FEA80095825D /* CoreDataAccount+CoreDataClass.swift in Sources */, @@ -3883,6 +3901,7 @@ AAB01CAD2D3AE44B007D6BF4 /* BitcoinKitTransactionFactory.swift in Sources */, 648CE3A222999CE70070A2CC /* BTCRawTransaction.swift in Sources */, 648DD79E2236A0B500B811FD /* DogeTransactionsViewController.swift in Sources */, + 48023DF12D72FB3500852961 /* SecretWalletsAlertService.swift in Sources */, 3A26D9392C3C1C62003AD832 /* KlyWalletFactory.swift in Sources */, 3A299C6B2B838F2300B54C61 /* ChatMediaContainerView.swift in Sources */, 64B5736F2209B892005DC968 /* BtcTransactionDetailsViewController.swift in Sources */, @@ -4076,6 +4095,7 @@ 41BCB310295C6082004B12AB /* VisibleWalletsResetTableViewCell.swift in Sources */, 93CCAE7B2B06D9B500EA5B94 /* DogeBlocksDTO.swift in Sources */, 3AF08D612B4EB3C400EB82B1 /* LanguageStorageProtocol.swift in Sources */, + 482231212D714C3D00D592D8 /* SecretWalletsViewModel.swift in Sources */, E9E7CDB12002B97B00DFC4DB /* AccountFactory.swift in Sources */, E9AA8BF82129F13000F9249F /* ComplexTransferViewController.swift in Sources */, E9A174B52057EDCE003667CD /* AdamantTransfersProvider+backgroundFetch.swift in Sources */, diff --git a/Adamant/App/DI/AppAssembly.swift b/Adamant/App/DI/AppAssembly.swift index a8264dea3..59ac26814 100644 --- a/Adamant/App/DI/AppAssembly.swift +++ b/Adamant/App/DI/AppAssembly.swift @@ -87,7 +87,8 @@ struct AppAssembly: MainThreadAssembly { SecretWalletsFactory( visibleWalletsService: r.resolve(VisibleWalletsService.self)!, accountService: r.resolve(AccountService.self)!, - securedStore: r.resolve(SecuredStore.self)! + securedStore: r.resolve(SecuredStore.self)!, + container: container ) }.inObjectScope(.container) @@ -489,5 +490,13 @@ struct AppAssembly: MainThreadAssembly { container.register(EthBIP32ServiceProtocol.self) { r in EthBIP32Service(ethApiService: r.resolve(ERC20ApiService.self)!) }.inObjectScope(.container) + + // MARK: SecretWalletsAlertService + container.register(SecretWalletsAlertService.self) { r in + SecretWalletsAlertService( + dialogService: r.resolve(DialogService.self)!, + secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)! + ) + }.inObjectScope(.transient) } } diff --git a/Adamant/Modules/Account/AccountFactory.swift b/Adamant/Modules/Account/AccountFactory.swift index 6fe0716c9..2102d004c 100644 --- a/Adamant/Modules/Account/AccountFactory.swift +++ b/Adamant/Modules/Account/AccountFactory.swift @@ -26,7 +26,9 @@ struct AccountFactory { currencyInfoService: assembler.resolve(InfoServiceProtocol.self)!, languageService: assembler.resolve(LanguageStorageProtocol.self)!, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletsManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletsAlertService: assembler.resolve(SecretWalletsAlertService.self)! ) } } diff --git a/Adamant/Modules/Account/AccountHeader.xib b/Adamant/Modules/Account/AccountHeader.xib index e0c1f2f3f..ee91360ee 100644 --- a/Adamant/Modules/Account/AccountHeader.xib +++ b/Adamant/Modules/Account/AccountHeader.xib @@ -1,9 +1,9 @@ - + - + @@ -53,6 +53,18 @@ + @@ -60,9 +72,11 @@ + + @@ -70,12 +84,14 @@ + - + - + + diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index b52c2ee9b..bdbd79bf0 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -11,6 +11,7 @@ import UIKit @MainActor protocol AccountHeaderViewDelegate: AnyObject { func addressLabelTapped(from: UIView) + func walletsButtonTapped(from: UIView) } final class AccountHeaderView: UIView { @@ -19,10 +20,15 @@ final class AccountHeaderView: UIView { @IBOutlet weak var avatarImageView: UIImageView! @IBOutlet weak var addressButton: UIButton! @IBOutlet weak var walletViewContainer: UIView! + @IBOutlet weak var walletsButton: UIButton! weak var delegate: AccountHeaderViewDelegate? @IBAction func addressButtonTapped(_ sender: UIButton) { delegate?.addressLabelTapped(from: sender) } + + @IBAction func walletsButtonTapped(_ sender: UIButton) { + delegate?.walletsButtonTapped(from: sender) + } } diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index da6de2adb..ffe555084 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -45,8 +45,10 @@ final class AccountViewController: FormViewController { private let currencyInfoService: InfoServiceProtocol private let languageService: LanguageStorageProtocol private let apiServiceCompose: ApiServiceComposeProtocol - private lazy var viewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) - + private let secretWalletsManager: SecretWalletsManagerProtocol + private lazy var walletsViewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) + private let secretWalletsAlertService: SecretWalletsAlertService + let accountService: AccountService let dialogService: DialogService let localAuth: LocalAuthentication @@ -90,7 +92,7 @@ final class AccountViewController: FormViewController { private var currentWalletIndex: Int = .zero private var currentSelectedWalletItem: WalletCollectionViewCell.Model? { - viewModel.state.wallets.first { wallet in + walletsViewModel.state.wallets.first { wallet in wallet.index == currentWalletIndex } } @@ -111,7 +113,9 @@ final class AccountViewController: FormViewController { currencyInfoService: InfoServiceProtocol, languageService: LanguageStorageProtocol, walletServiceCompose: WalletServiceCompose, - apiServiceCompose: ApiServiceComposeProtocol + apiServiceCompose: ApiServiceComposeProtocol, + secretWalletsManager: SecretWalletsManagerProtocol, + secretWalletsAlertService: SecretWalletsAlertService ) { self.walletStoreServiceProvider = walletStoreServiceProvider self.accountService = accountService @@ -124,6 +128,8 @@ final class AccountViewController: FormViewController { self.currencyInfoService = currencyInfoService self.languageService = languageService self.apiServiceCompose = apiServiceCompose + self.secretWalletsManager = secretWalletsManager + self.secretWalletsAlertService = secretWalletsAlertService super.init(nibName: nil, bundle: nil) } @@ -202,12 +208,14 @@ final class AccountViewController: FormViewController { pagingViewController.borderColor = UIColor.clear - viewModel.$state + walletsViewModel.$state .removeDuplicates() .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.pagingViewController.reloadMenu() + self.setupWalletsVC() //TODO: Change it to use it only when wallets are changed + self.pagingViewController.reloadData() + pagingViewController.select(index: currentWalletIndex) } .store(in: ¬ificationsSet) @@ -852,7 +860,7 @@ final class AccountViewController: FormViewController { guard let self = self else { return } self.setupWalletsVC() - self.viewModel.updateState() + self.walletsViewModel.updateState() self.updatePagingItemHeight() self.pagingViewController.reloadData() @@ -987,6 +995,10 @@ final class AccountViewController: FormViewController { // MARK: - AccountHeaderViewDelegate extension AccountViewController: AccountHeaderViewDelegate { + func walletsButtonTapped(from sender: UIView) { + secretWalletsAlertService.presentSecretWalletsActionSheet(from: sender) + } + func addressLabelTapped(from: UIView) { guard let address = accountService.account?.address else { return @@ -1054,7 +1066,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr MainActor.assertIsolated() return DispatchQueue.onMainThreadSyncSafe { - return viewModel.state.wallets[safe: index] ?? WalletCollectionViewCell.Model.default + return walletsViewModel.state.wallets[safe: index] ?? WalletCollectionViewCell.Model.default } } diff --git a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift index 865eb4e84..a2a314f24 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift @@ -6,8 +6,10 @@ // Copyright © 2025 Adamant. All rights reserved. // -struct AccountWalletsState: Equatable { - var wallets: [WalletCollectionViewCell.Model] - - static let `default` = Self(wallets: []) +extension AccountViewController { + struct AccountWalletsState: Equatable { + var wallets: [WalletCollectionViewCell.Model] + + static let `default` = Self(wallets: []) + } } diff --git a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift index c5d12de0c..3e971729e 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift @@ -10,25 +10,38 @@ import Foundation import CommonKit import Combine -@MainActor -final class AccountWalletsViewModel { - @ObservableValue var state: AccountWalletsState = .default - - private let walletsStoreService: WalletStoreServiceProviderProtocol - private var subscriptions = Set() - - init(walletsStoreService: WalletStoreServiceProviderProtocol) { - self.walletsStoreService = walletsStoreService - setup() +extension AccountViewController { + @MainActor + final class AccountWalletsViewModel { + @ObservableValue var state: AccountWalletsState = .default + + private let walletsStoreService: WalletStoreServiceProviderProtocol + private var walletSubscriptions: Set = [] + private var currentWalletPublisherSubscription: Set = [] + + init(walletsStoreService: WalletStoreServiceProviderProtocol) { + self.walletsStoreService = walletsStoreService + setup() + } } } -private extension AccountWalletsViewModel { +private extension AccountViewController.AccountWalletsViewModel { func setup() { addObservers() } func addObservers() { + walletsStoreService.currentWalletPublisher + .sink( + receiveValue: { [weak self] _ in + self?.updateState() + } + ) + .store(in: ¤tWalletPublisherSubscription) + } + + func addWalletObservers() { for wallet in walletsStoreService.sorted(includeInvisible: false) { updateInfo(for: wallet) wallet.core.walletUpdatePublisher @@ -37,10 +50,10 @@ private extension AccountWalletsViewModel { self?.updateInfo(for: wallet) } ) - .store(in: &subscriptions) + .store(in: &walletSubscriptions) } } - + func updateInfo(for wallet: WalletService) { let coreService = wallet.core if let index = state.wallets.firstIndex(where: { $0.coinID == coreService.tokenUniqueID }) { @@ -49,8 +62,8 @@ private extension AccountWalletsViewModel { state.wallets[index].notificationBadgeCount = coreService.wallet?.notifications ?? 0 } else { let network = ERC20Token.supportedTokens.contains(where: { $0.symbol == coreService.tokenSymbol }) - ? type(of: coreService).tokenNetworkSymbol - : "" + ? type(of: coreService).tokenNetworkSymbol + : "" let model = WalletCollectionViewCell.Model( index: state.wallets.count, coinID: coreService.tokenUniqueID, @@ -67,10 +80,10 @@ private extension AccountWalletsViewModel { } } -extension AccountWalletsViewModel { +extension AccountViewController.AccountWalletsViewModel { func updateState() { - subscriptions.removeAll() + walletSubscriptions.removeAll() state.wallets.removeAll() - setup() + addWalletObservers() } } diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift new file mode 100644 index 000000000..642d3978a --- /dev/null +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift @@ -0,0 +1,149 @@ +// +// SecretWalletsAlertService.swift +// Adamant +// +// Created by Dmitrij Meidus on 01.03.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import UIKit + +@MainActor +final class SecretWalletsAlertService { + private let dialogService: DialogService + private let secretWalletsViewModel: SecretWalletsViewModel + + init( + dialogService: DialogService, + secretWalletsManager: SecretWalletsManagerProtocol + ) { + self.dialogService = dialogService + self.secretWalletsViewModel = .init(secretWalletsManager: secretWalletsManager) + } + + func presentSecretWalletsActionSheet(from sourceView: UIView) { + var actions = [AdamantAlertAction]() + let state = secretWalletsViewModel.state + + for (index, wallet) in state.wallets.enumerated() { + let isSelected = (index == state.currentActiveIndex) + let prefix = isSelected ? "✓ " : "" + + let action = AdamantAlertAction( + title: prefix + wallet.name, + style: .default + ) { [weak self] in + self?.secretWalletsViewModel.pickWallet(at: index) + } + actions.append(action) + } + + let enableWalletAction = AdamantAlertAction( + title: "Add secret wallet", + style: .default + ) { [weak self] in + self?.showEnableSecretWalletAlert() + } + actions.append(enableWalletAction) + +// let removeWalletAction = AdamantAlertAction( +// title: "Remove secret wallet", +// style: .destructive +// ) { [weak self] in +// self?.showRemoveSecretWalletAlert(from: sourceView) +// } +// actions.append(removeWalletAction) + + let infoAction = AdamantAlertAction( + title: "Tell me more", + style: .default + ) { [weak self] in + self?.showSecretWalletInfoAlert() + } + actions.append(infoAction) + + let cancelAction = AdamantAlertAction( + title: "Cancel", + style: .cancel, + handler: nil + ) + actions.append(cancelAction) + + let source: UIAlertController.SourceView = .view(sourceView) + dialogService.showAlert( + title: nil, + message: nil, + style: .actionSheet, + actions: actions, + from: source + ) + } + + private func showRemoveSecretWalletAlert(from sourceView: UIView) { + let state = secretWalletsViewModel.state + let alert = UIAlertController( + title: "Remove Secret Wallet", + message: "Select the secret wallet to remove:", + preferredStyle: .actionSheet + ) + + for (index, wallet) in state.wallets.enumerated() where index != 0 { + let action = UIAlertAction( + title: wallet.name, + style: .destructive + ) { [weak self] _ in + self?.secretWalletsViewModel.removeSecretWallet(at: index) + } + alert.addAction(action) + } + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { [weak self] _ in + self?.presentSecretWalletsActionSheet(from: sourceView) + } + + alert.addAction(cancelAction) + + dialogService.present(alert, animated: true, completion: nil) + } + + private func showEnableSecretWalletAlert() { + let passwordAlert = UIAlertController( + title: "Enter password to add secret wallet", + message: nil, + preferredStyle: .alert + ) + + passwordAlert.addTextField { textField in + textField.isSecureTextEntry = true + textField.placeholder = "Password" + } + + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) + passwordAlert.addAction(cancelAction) + + let enableAction = UIAlertAction(title: "Enable", style: .default) { [weak self] _ in + guard + let self = self, + let password = passwordAlert.textFields?.first?.text, + !password.isEmpty + else { + return + } + self.secretWalletsViewModel.createSecretWallet(password: password) + } + passwordAlert.addAction(enableAction) + + dialogService.present(passwordAlert, animated: true, completion: nil) + } + + private func showSecretWalletInfoAlert() { + let infoAlert = UIAlertController( + title: "Secret Wallets", + message: "Secret wallets are encrypted and require a password...", + preferredStyle: .alert + ) + infoAlert.addAction(.init(title: "Got it", style: .default)) + + dialogService.present(infoAlert, animated: true, completion: nil) + } +} diff --git a/Adamant/Modules/SecretWallets/SecretWalletsState.swift b/Adamant/Modules/SecretWallets/SecretWalletsState.swift new file mode 100644 index 000000000..6182de383 --- /dev/null +++ b/Adamant/Modules/SecretWallets/SecretWalletsState.swift @@ -0,0 +1,23 @@ +// +// SecretWalletsState.swift +// Adamant +// +// Created by Dmitrij Meidus on 28.02.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import Foundation + +extension SecretWalletsAlertService { + struct SecretWalletsState: Equatable { + var wallets: [WalletItem] + var currentActiveIndex: Int + + static let `default` = Self(wallets: [], currentActiveIndex: -1) + } + + struct WalletItem: Equatable, Identifiable { + let id = UUID() + let name: String + } +} diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift new file mode 100644 index 000000000..1b16eedf0 --- /dev/null +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -0,0 +1,58 @@ +// +// SecretWalletsViewModel.swift +// Adamant +// +// Created by Dmitrij Meidus on 28.02.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import CommonKit +import Combine + +extension SecretWalletsAlertService { + @MainActor + final class SecretWalletsViewModel: ObservableObject { + @Published private(set) var state: SecretWalletsState = .default + + private let secretWalletsManager: SecretWalletsManagerProtocol + private var subscriptions = Set() + + init(secretWalletsManager: SecretWalletsManagerProtocol) { + self.secretWalletsManager = secretWalletsManager + + setup() + } + + private func setup() { + self.state.currentActiveIndex = secretWalletsManager.currentWalletIndex + self.state.wallets.append(WalletItem(name: "Regular")) + for index in 0...secretWalletsManager.getSecretWallets().count - 1 where index > 0 { + state.wallets.append(WalletItem(name: "Secret \(index)")) + } + } + + func pickWallet(at index: Int) { + state.currentActiveIndex = index + secretWalletsManager.activateWallet(at: index) + } + + func createSecretWallet(password: String) { + let index = state.wallets.count + + secretWalletsManager.createSecretWallet(withPassword: password) + secretWalletsManager.activateWallet(at: index ) + + self.state.wallets.append(WalletItem(name: "Secret \(index)")) + self.state.currentActiveIndex = index + } + + func removeSecretWallet(at index: Int) { + _ = secretWalletsManager.removeSecretWallet(at: index) + state.wallets.remove(at: index) + if index == state.currentActiveIndex { + state.currentActiveIndex = 0 + secretWalletsManager.activateWallet(at: 0) + } + } + } +} diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift index 62479376b..288bf7aa9 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift @@ -382,9 +382,8 @@ extension ERC20WalletService { NotificationCenter.default.post(name: serviceEnabledChanged, object: self) } - let keystore = try await ethBIP32Service.keyStore(passphrase: passphrase) + let keystore = try await ethBIP32Service.keyStore(passphrase: passphrase, withPassword: password) - guard let ethAddress = keystore.addresses?.first else { throw WalletServiceError.internalError(message: "ETH Wallet: failed to create Keystore", error: nil) } diff --git a/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift b/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift index 5bce3ac8c..68e74d7d2 100644 --- a/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift +++ b/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift @@ -8,32 +8,26 @@ import Web3Core protocol EthBIP32ServiceProtocol { - func keyStore(passphrase: String) async throws -> BIP32Keystore + func keyStore(passphrase: String, withPassword password: String) async throws -> BIP32Keystore } -actor EthBIP32Service: EthBIP32ServiceProtocol { - private var passphrase: String? - private var keystore: BIP32Keystore? - +// TODO: Return optimization +struct EthBIP32Service: EthBIP32ServiceProtocol { private var ethApiService: EthApiServiceProtocol init(ethApiService: EthApiServiceProtocol) { self.ethApiService = ethApiService } - func keyStore(passphrase: String) async throws -> BIP32Keystore { - if let keystore = self.keystore, passphrase == self.passphrase { - return keystore - } + + func keyStore(passphrase: String, withPassword password: String) async throws -> BIP32Keystore { do { guard let store = try BIP32Keystore(mnemonics: passphrase, password: EthWalletService.walletPassword, - mnemonicsPassword: "", + mnemonicsPassword: password, language: .english, prefixPath: EthWalletService.walletPath) else { throw WalletServiceError.internalError(message: "ETH Wallet: failed to create Keystore", error: nil) } - self.passphrase = passphrase - self.keystore = store await ethApiService.setKeystoreManager(.init([store])) return store } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index dfc775e95..77cea2268 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -417,11 +417,9 @@ extension EthWalletService { // MARK: 2. Create keys and addresses - let store = try await ethBIP32Service.keyStore(passphrase: passphrase) + let store = try await ethBIP32Service.keyStore(passphrase: passphrase, withPassword: password) walletStorage = .init(keystore: store, unicId: tokenUniqueID) - - let eWallet = walletStorage?.getWallet() guard let eWallet = eWallet else { diff --git a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift index c3cb70409..7abbac0b5 100644 --- a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift +++ b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift @@ -9,18 +9,17 @@ import CommonKit protocol SecretWalletsManagerProtocol { - var statePublisher: AnyObservable { get } + var statePublisher: ObservableSender { get } + var currentWalletIndex: Int { get } func createSecretWallet(withPassword password: String) func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? func getCurrentWallet() -> WalletStoreServiceProtocol func getSecretWallets() -> [WalletStoreServiceProtocol] - func activateSecretWallet(at index: Int) - func activateDefaultWallet() + func activateWallet(at index: Int) } protocol SecretWalletsManagerStateProtocol { var currentWallet: WalletStoreServiceProtocol { get set } - var defaultWallet: WalletStoreServiceProtocol { get } - var secretWallets: [WalletStoreServiceProtocol] { get set } + var wallets: [WalletStoreServiceProtocol] { get set } } diff --git a/Adamant/Services/AdmDialogService/AdamantDialogService.swift b/Adamant/Services/AdmDialogService/AdamantDialogService.swift index 1645a7823..e39b2b1aa 100644 --- a/Adamant/Services/AdmDialogService/AdamantDialogService.swift +++ b/Adamant/Services/AdmDialogService/AdamantDialogService.swift @@ -602,18 +602,16 @@ fileprivate extension AdamantAlertAction { } extension AdamantDialogService { - func showAlert(title: String?, message: String?, style: AdamantAlertStyle, actions: [AdamantAlertAction]?, from: UIAlertController.SourceView?) { - switch style { - case .alert, .actionSheet: - let uiStyle = style.asUIAlertControllerStyle() - if let actions = actions { - let uiActions: [UIAlertAction] = actions.map { $0.asUIAlertAction() } - - showAlert(title: title, message: message, style: uiStyle, actions: uiActions, from: from) - } else { - showAlert(title: title, message: message, style: uiStyle, actions: nil, from: from) - } - } + func showAlert( + title: String?, + message: String?, + style: AdamantAlertStyle, + actions: [AdamantAlertAction]?, + from: UIAlertController.SourceView? + ) { + let uiStyle = style.asUIAlertControllerStyle() + let uiActions = actions?.map { $0.asUIAlertAction() } + showAlert(title: title, message: message, style: uiStyle, actions: uiActions, from: from) } func showAlert(title: String?, message: String?, style: UIAlertController.Style, actions: [UIAlertAction]?, from: UIAlertController.SourceView?) { diff --git a/Adamant/Services/SecretWalletsFactory.swift b/Adamant/Services/SecretWalletsFactory.swift index 4e662f2d9..e21d55c72 100644 --- a/Adamant/Services/SecretWalletsFactory.swift +++ b/Adamant/Services/SecretWalletsFactory.swift @@ -7,20 +7,26 @@ // import CommonKit +import Swinject + +//TODO: Что на счет заинджектить сюда все зависимости для кошельков и тут инициализировать все кошельки? struct SecretWalletsFactory { private let visibleWalletsService: VisibleWalletsService private let accountService: AccountService private let securedStore: SecuredStore + private let container: Container init( visibleWalletsService: VisibleWalletsService, accountService: AccountService, - securedStore: SecuredStore + securedStore: SecuredStore, + container: Container ) { self.visibleWalletsService = visibleWalletsService self.accountService = accountService self.securedStore = securedStore + self.container = container } func makeSecretWallet(withPassword password: String) -> WalletStoreServiceProtocol { @@ -38,7 +44,8 @@ struct SecretWalletsFactory { } wallets.append(contentsOf: erc20WalletServices) let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) - Task.detached(priority: .userInitiated){ + Task { @MainActor in + await injectDependencies(in: walletServiceCompose) await initWallets(withPass: password, for: walletServiceCompose) } let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) @@ -46,6 +53,13 @@ struct SecretWalletsFactory { return wallet } + @MainActor + private func injectDependencies(in walletService: WalletServiceCompose) async { + walletService.getWallets().forEach { wallet in + (wallet.core as? SwinjectDependentService)?.injectDependencies(from: container) + } + } + private func initWallets(withPass password: String, for walletService: WalletServiceCompose) async { guard let passphrase: String = securedStore.get(StoreKey.accountService.passphrase) else { print("No passphrase found") diff --git a/Adamant/Services/SecretWalletsService.swift b/Adamant/Services/SecretWalletsManager.swift similarity index 62% rename from Adamant/Services/SecretWalletsService.swift rename to Adamant/Services/SecretWalletsManager.swift index 245224254..ce6467f31 100644 --- a/Adamant/Services/SecretWalletsService.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -13,8 +13,8 @@ import CommonKit extension AdamantSecretWalletsManager { struct State: SecretWalletsManagerStateProtocol { var currentWallet: WalletStoreServiceProtocol - let defaultWallet: WalletStoreServiceProtocol - var secretWallets: [WalletStoreServiceProtocol] = [] + /// Where 0 is regular wallet and 1... are secret wallets + var wallets: [WalletStoreServiceProtocol] = [] } } @@ -22,35 +22,35 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { private let secretWalletsFactory: SecretWalletsFactory private let lock = NSLock() + private var state: SecretWalletsManagerStateProtocol + var statePublisher = ObservableSender() + + private(set) var currentWalletIndex: Int = 0 + init( walletsStoreService: WalletStoreServiceProtocol, secretWalletsFactory: SecretWalletsFactory ) { self.state = State( currentWallet: walletsStoreService, - defaultWallet: walletsStoreService + wallets: [walletsStoreService] ) self.secretWalletsFactory = secretWalletsFactory } - @ObservableValue private var state: SecretWalletsManagerStateProtocol - var statePublisher: AnyObservable { - $state.eraseToAnyPublisher() - } - // MARK: - Manage state func createSecretWallet(withPassword password: String) { let wallet = secretWalletsFactory.makeSecretWallet(withPassword: password) lock.lock() defer { lock.unlock() } - state.secretWallets.append(wallet) + state.wallets.append(wallet) } func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? { lock.lock() defer { lock.unlock() } - guard state.secretWallets.indices.contains(index) else { return nil } - return state.secretWallets.remove(at: index) + guard index == 0 || state.wallets.indices.contains(index) else { return nil } + return state.wallets.remove(at: index) } func getCurrentWallet() -> WalletStoreServiceProtocol { @@ -58,19 +58,19 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { } func getSecretWallets() -> [WalletStoreServiceProtocol] { - state.secretWallets + state.wallets } - func activateSecretWallet(at index: Int) { - lock.lock() - defer { lock.unlock() } - guard index < state.secretWallets.count else { return } - state.currentWallet = state.secretWallets[index] + func getCurrentWalletIndex() -> Int { + currentWalletIndex } - func activateDefaultWallet() { + func activateWallet(at index: Int) { lock.lock() defer { lock.unlock() } - state.currentWallet = state.defaultWallet + guard index < state.wallets.count else { return } + state.currentWallet = state.wallets[index] + currentWalletIndex = index + statePublisher.send(state) } } From 615c1a3f8afd3bfb149ba4442a283e7fa7c2e687 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 6 Mar 2025 16:11:52 +0700 Subject: [PATCH 02/36] [trello.com/c/vawidi4o] Code improvments. Add icons for the secret wallets menu. --- .../AccountViewController.swift | 2 +- .../SecretWalletsAlertService.swift | 55 ++++--------------- .../SecretWalletsViewModel.swift | 26 ++++----- .../EthBIP32Service/EthBIP32Service.swift | 8 ++- .../SecretWalletsManagerProtocol.swift | 7 ++- Adamant/Services/SecretWalletsFactory.swift | 4 +- Adamant/Services/SecretWalletsManager.swift | 33 ++++++----- 7 files changed, 54 insertions(+), 81 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index ffe555084..33ad64c86 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -213,7 +213,7 @@ final class AccountViewController: FormViewController { .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.setupWalletsVC() //TODO: Change it to use it only when wallets are changed + self.setupWalletsVC() self.pagingViewController.reloadData() pagingViewController.select(index: currentWalletIndex) } diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift index 642d3978a..143feb5b1 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift @@ -27,10 +27,10 @@ final class SecretWalletsAlertService { for (index, wallet) in state.wallets.enumerated() { let isSelected = (index == state.currentActiveIndex) - let prefix = isSelected ? "✓ " : "" + let suffix = isSelected ? " ✓" : "" let action = AdamantAlertAction( - title: prefix + wallet.name, + title: wallet.name + suffix, style: .default ) { [weak self] in self?.secretWalletsViewModel.pickWallet(at: index) @@ -38,24 +38,18 @@ final class SecretWalletsAlertService { actions.append(action) } - let enableWalletAction = AdamantAlertAction( - title: "Add secret wallet", - style: .default - ) { [weak self] in - self?.showEnableSecretWalletAlert() + if state.wallets.count < 6 { + let enableWalletAction = AdamantAlertAction( + title: "🪄 Add secret wallet", + style: .default + ) { [weak self] in + self?.showEnableSecretWalletAlert() + } + actions.append(enableWalletAction) } - actions.append(enableWalletAction) - -// let removeWalletAction = AdamantAlertAction( -// title: "Remove secret wallet", -// style: .destructive -// ) { [weak self] in -// self?.showRemoveSecretWalletAlert(from: sourceView) -// } -// actions.append(removeWalletAction) let infoAction = AdamantAlertAction( - title: "Tell me more", + title: "💡 Tell me more", style: .default ) { [weak self] in self?.showSecretWalletInfoAlert() @@ -79,33 +73,6 @@ final class SecretWalletsAlertService { ) } - private func showRemoveSecretWalletAlert(from sourceView: UIView) { - let state = secretWalletsViewModel.state - let alert = UIAlertController( - title: "Remove Secret Wallet", - message: "Select the secret wallet to remove:", - preferredStyle: .actionSheet - ) - - for (index, wallet) in state.wallets.enumerated() where index != 0 { - let action = UIAlertAction( - title: wallet.name, - style: .destructive - ) { [weak self] _ in - self?.secretWalletsViewModel.removeSecretWallet(at: index) - } - alert.addAction(action) - } - - let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { [weak self] _ in - self?.presentSecretWalletsActionSheet(from: sourceView) - } - - alert.addAction(cancelAction) - - dialogService.present(alert, animated: true, completion: nil) - } - private func showEnableSecretWalletAlert() { let passwordAlert = UIAlertController( title: "Enter password to add secret wallet", diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 1b16eedf0..ee0339dd6 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -9,6 +9,8 @@ import CommonKit import Combine +//TODO: Consider logout + extension SecretWalletsAlertService { @MainActor final class SecretWalletsViewModel: ObservableObject { @@ -24,35 +26,29 @@ extension SecretWalletsAlertService { } private func setup() { - self.state.currentActiveIndex = secretWalletsManager.currentWalletIndex - self.state.wallets.append(WalletItem(name: "Regular")) - for index in 0...secretWalletsManager.getSecretWallets().count - 1 where index > 0 { - state.wallets.append(WalletItem(name: "Secret \(index)")) - } + self.state.currentActiveIndex = 0 + self.state.wallets.append(WalletItem(name: "💰 Regular")) } func pickWallet(at index: Int) { state.currentActiveIndex = index - secretWalletsManager.activateWallet(at: index) + guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } + secretWalletsManager.activateSecretWallet(at: index - 1) } func createSecretWallet(password: String) { let index = state.wallets.count secretWalletsManager.createSecretWallet(withPassword: password) - secretWalletsManager.activateWallet(at: index ) + secretWalletsManager.activateSecretWallet(at: index - 1) - self.state.wallets.append(WalletItem(name: "Secret \(index)")) + state.wallets.append(makeWalletItem(withIndex: index)) self.state.currentActiveIndex = index } - func removeSecretWallet(at index: Int) { - _ = secretWalletsManager.removeSecretWallet(at: index) - state.wallets.remove(at: index) - if index == state.currentActiveIndex { - state.currentActiveIndex = 0 - secretWalletsManager.activateWallet(at: 0) - } + private func makeWalletItem(withIndex index: Int) -> WalletItem { + let icon = index <= 5 ? "\(index)️⃣" : "🔢" + return WalletItem(name: "🔐\(icon) Secret \(index)") } } } diff --git a/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift b/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift index 68e74d7d2..be18ee5ac 100644 --- a/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift +++ b/Adamant/Modules/Wallets/EthBIP32Service/EthBIP32Service.swift @@ -11,15 +11,18 @@ protocol EthBIP32ServiceProtocol { func keyStore(passphrase: String, withPassword password: String) async throws -> BIP32Keystore } -// TODO: Return optimization -struct EthBIP32Service: EthBIP32ServiceProtocol { +actor EthBIP32Service: EthBIP32ServiceProtocol { private var ethApiService: EthApiServiceProtocol + private var keystores: [String: BIP32Keystore] = [:] init(ethApiService: EthApiServiceProtocol) { self.ethApiService = ethApiService } func keyStore(passphrase: String, withPassword password: String) async throws -> BIP32Keystore { + if let keystore = self.keystores[passphrase + password] { + return keystore + } do { guard let store = try BIP32Keystore(mnemonics: passphrase, password: EthWalletService.walletPassword, @@ -29,6 +32,7 @@ struct EthBIP32Service: EthBIP32ServiceProtocol { throw WalletServiceError.internalError(message: "ETH Wallet: failed to create Keystore", error: nil) } await ethApiService.setKeystoreManager(.init([store])) + keystores[passphrase + password] = store return store } } diff --git a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift index 7abbac0b5..3ec8d56d5 100644 --- a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift +++ b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift @@ -10,16 +10,17 @@ import CommonKit protocol SecretWalletsManagerProtocol { var statePublisher: ObservableSender { get } - var currentWalletIndex: Int { get } func createSecretWallet(withPassword password: String) func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? func getCurrentWallet() -> WalletStoreServiceProtocol func getSecretWallets() -> [WalletStoreServiceProtocol] - func activateWallet(at index: Int) + func activateSecretWallet(at index: Int) + func activateDefaultWallet() } protocol SecretWalletsManagerStateProtocol { var currentWallet: WalletStoreServiceProtocol { get set } - var wallets: [WalletStoreServiceProtocol] { get set } + var regularWallet: WalletStoreServiceProtocol { get set } + var secretWallets: [WalletStoreServiceProtocol] { get set } } diff --git a/Adamant/Services/SecretWalletsFactory.swift b/Adamant/Services/SecretWalletsFactory.swift index e21d55c72..fee55b566 100644 --- a/Adamant/Services/SecretWalletsFactory.swift +++ b/Adamant/Services/SecretWalletsFactory.swift @@ -9,7 +9,7 @@ import CommonKit import Swinject -//TODO: Что на счет заинджектить сюда все зависимости для кошельков и тут инициализировать все кошельки? +//TODO: ‼️‼️‼️ Double check wallets initialization and dependencies injection while making the review ‼️‼️‼️ struct SecretWalletsFactory { private let visibleWalletsService: VisibleWalletsService @@ -43,11 +43,13 @@ struct SecretWalletsFactory { ERC20WalletService(token: $0) } wallets.append(contentsOf: erc20WalletServices) + let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) Task { @MainActor in await injectDependencies(in: walletServiceCompose) await initWallets(withPass: password, for: walletServiceCompose) } + let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) return wallet diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index ce6467f31..3ba116ef4 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -13,19 +13,20 @@ import CommonKit extension AdamantSecretWalletsManager { struct State: SecretWalletsManagerStateProtocol { var currentWallet: WalletStoreServiceProtocol - /// Where 0 is regular wallet and 1... are secret wallets - var wallets: [WalletStoreServiceProtocol] = [] + var regularWallet: WalletStoreServiceProtocol + var secretWallets: [WalletStoreServiceProtocol] = [] } } final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { private let secretWalletsFactory: SecretWalletsFactory - private let lock = NSLock() private var state: SecretWalletsManagerStateProtocol var statePublisher = ObservableSender() - private(set) var currentWalletIndex: Int = 0 + var wallets: [WalletStoreServiceProtocol] { [state.regularWallet] + state.secretWallets } + + private let lock = NSLock() init( walletsStoreService: WalletStoreServiceProtocol, @@ -33,7 +34,7 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { ) { self.state = State( currentWallet: walletsStoreService, - wallets: [walletsStoreService] + regularWallet: walletsStoreService ) self.secretWalletsFactory = secretWalletsFactory } @@ -43,14 +44,14 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { let wallet = secretWalletsFactory.makeSecretWallet(withPassword: password) lock.lock() defer { lock.unlock() } - state.wallets.append(wallet) + state.secretWallets.append(wallet) } func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? { lock.lock() defer { lock.unlock() } - guard index == 0 || state.wallets.indices.contains(index) else { return nil } - return state.wallets.remove(at: index) + guard state.secretWallets.indices.contains(index) else { return nil } + return state.secretWallets.remove(at: index) } func getCurrentWallet() -> WalletStoreServiceProtocol { @@ -58,19 +59,21 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { } func getSecretWallets() -> [WalletStoreServiceProtocol] { - state.wallets + state.secretWallets } - func getCurrentWalletIndex() -> Int { - currentWalletIndex + func activateSecretWallet(at index: Int) { + lock.lock() + defer { lock.unlock() } + guard index < state.secretWallets.count else { return } + state.currentWallet = state.secretWallets[index] + statePublisher.send(state) } - func activateWallet(at index: Int) { + func activateDefaultWallet() { lock.lock() defer { lock.unlock() } - guard index < state.wallets.count else { return } - state.currentWallet = state.wallets[index] - currentWalletIndex = index + state.currentWallet = state.regularWallet statePublisher.send(state) } } From f544814a52722e003106b4855c6140d379ad8aec Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 6 Mar 2025 17:28:49 +0700 Subject: [PATCH 03/36] [trello.com/c/vawidi4o] Add localisations --- .../SecretWallets/SecretWalletsAlertService.swift | 6 +++--- .../SecretWallets/SecretWalletsViewModel.swift | 9 ++------- .../Assets/Localization/de.lproj/Localizable.strings | 11 +++++++++++ .../Assets/Localization/en.lproj/Localizable.strings | 11 +++++++++++ .../Assets/Localization/ru.lproj/Localizable.strings | 11 +++++++++++ .../Assets/Localization/zh.lproj/Localizable.strings | 11 +++++++++++ 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift index 143feb5b1..9f0744916 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift @@ -40,7 +40,7 @@ final class SecretWalletsAlertService { if state.wallets.count < 6 { let enableWalletAction = AdamantAlertAction( - title: "🪄 Add secret wallet", + title: String.localized("SecretWallets.Menu.AddSecretWallet", comment: "Secret wallet menu: add secret wallet"), style: .default ) { [weak self] in self?.showEnableSecretWalletAlert() @@ -49,7 +49,7 @@ final class SecretWalletsAlertService { } let infoAction = AdamantAlertAction( - title: "💡 Tell me more", + title: String.localized("SecretWallets.Menu.TellMeMore", comment: "Secret wallet menu: tell me more"), style: .default ) { [weak self] in self?.showSecretWalletInfoAlert() @@ -65,7 +65,7 @@ final class SecretWalletsAlertService { let source: UIAlertController.SourceView = .view(sourceView) dialogService.showAlert( - title: nil, + title: String.localized("SecretWallets.Menu.Title", comment: "Secret wallet menu: title"), message: nil, style: .actionSheet, actions: actions, diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index ee0339dd6..be7344d92 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -27,7 +27,7 @@ extension SecretWalletsAlertService { private func setup() { self.state.currentActiveIndex = 0 - self.state.wallets.append(WalletItem(name: "💰 Regular")) + self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) } func pickWallet(at index: Int) { @@ -42,13 +42,8 @@ extension SecretWalletsAlertService { secretWalletsManager.createSecretWallet(withPassword: password) secretWalletsManager.activateSecretWallet(at: index - 1) - state.wallets.append(makeWalletItem(withIndex: index)) + state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Secret\(index)", comment: "Secret wallet menu: regular wallet"))) self.state.currentActiveIndex = index } - - private func makeWalletItem(withIndex index: Int) -> WalletItem { - let icon = index <= 5 ? "\(index)️⃣" : "🔢" - return WalletItem(name: "🔐\(icon) Secret \(index)") - } } } diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 02bec70dd..6d0f610ea 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1385,3 +1385,14 @@ "Chat.Alert.ReviewNodesList" = "ADM-Knotenliste überprüfen"; "Chat.Timestamp.InFuture.Error" = "Ein Netzwerkknoten hat die Nachricht abgelehnt, weil die Zeit auf Ihrem Gerät vorgeht.\nÜberprüfen Sie die Uhrzeit des Geräts oder versuchen Sie erneut, eine Nachricht zu senden."; + +/* Secret Wallets */ +"SecretWallets.Menu.Regular" = "Normal"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ Geheim"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ Geheim"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ Geheim"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ Geheim"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ Geheim"; +"SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; +"SecretWallets.Menu.TellMeMore" = "Über Wallets"; +"SecretWallets.Menu.Title" = "Aktive Wallets"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 0e9d10136..e70800e22 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1361,3 +1361,14 @@ "Chat.Alert.ReviewNodesList" = "Review ADM node list"; "Chat.Timestamp.InFuture.Error" = "A network node rejected the message because the time on your device is ahead.\nCheck the device's time or try sending a message again."; + +/* Secret Wallets */ +"SecretWallets.Menu.Regular" = "💰 Regular"; +"SecretWallets.Menu.Secret1" = "🔐1️⃣ Secret"; +"SecretWallets.Menu.Secret2" = "🔐2️⃣ Secret"; +"SecretWallets.Menu.Secret3" = "🔐3️⃣ Secret"; +"SecretWallets.Menu.Secret4" = "🔐4️⃣ Secret"; +"SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret"; +"SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; +"SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; +"SecretWallets.Menu.Title" = "Active wallets"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 56e672c06..a0abaf777 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1362,3 +1362,14 @@ "Chat.Alert.ReviewNodesList" = "К списку узлов ADM"; "Chat.Timestamp.InFuture.Error" = "Узел сети отклонил сообщение, потому что время на вашем устройстве спешит.\nПроверьте время на устройстве или попробуйте отправить сообщение снова."; + +/* Secret Wallets */ +"SecretWallets.Menu.Regular" = "Обычный"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ Секретный"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ Секретный"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ Секретный"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ Секретный"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ Секретный"; +"SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; +"SecretWallets.Menu.TellMeMore" = "О кошельках"; +"SecretWallets.Menu.Title" = "Активные кошельки"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index fbbd33ae4..a611d6ddf 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1352,3 +1352,14 @@ "Chat.Alert.ReviewNodesList" = "查看 ADM 节点列表"; "Chat.Timestamp.InFuture.Error" = "由于您设备上的时间超前,网络节点拒绝了信息。\n请检查设备的时间或再次尝试发送信息。"; + +/* Secret Wallets */ +"SecretWallets.Menu.Regular" = "普通"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ 秘密"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ 秘密"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ 秘密"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ 秘密"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ 秘密"; +"SecretWallets.Menu.AddSecretWallet" = "添加秘密"; +"SecretWallets.Menu.TellMeMore" = "关于钱包"; +"SecretWallets.Menu.Title" = "活动钱包"; From 799bd958414b8470b43000345a28d540c2257653 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 6 Mar 2025 20:54:23 +0700 Subject: [PATCH 04/36] [trello.com/c/vawidi4o] Add secret wallet item to the menu items. --- .../AccountViewController+Form.swift | 5 ++++- .../AccountViewController.swift | 17 +++++++++++++++++ .../SecretWalletsAlertService.swift | 8 ++++++-- .../Localization/de.lproj/Localizable.strings | 1 + .../Localization/en.lproj/Localizable.strings | 1 + .../Localization/ru.lproj/Localizable.strings | 1 + .../Localization/zh.lproj/Localizable.strings | 1 + 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift index 869e318cd..cc49f295e 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift @@ -36,7 +36,7 @@ extension AccountViewController { enum Rows { case balance, sendTokens // Wallet - case security, nodes, coinsNodes, theme, currency, language, about, visibleWallets, contribute, storage // Application + case security, nodes, coinsNodes, theme, currency, language, about, visibleWallets, secretWallets, contribute, storage // Application case voteForDelegates, generateQr, generatePk, logout // Actions case stayIn, biometry, notifications // Security @@ -57,6 +57,7 @@ extension AccountViewController { case .biometry: return "biometry" case .notifications: return "notifications" case .visibleWallets: return "visibleWallets" + case .secretWallets: return "secretWallets" case .contribute: return "contribute" case .coinsNodes: return "coinsNodes" case .language: return "language" @@ -81,6 +82,7 @@ extension AccountViewController { case .biometry: return SecurityViewController.Rows.biometry.localized case .notifications: return SecurityViewController.Rows.notificationsMode.localized case .visibleWallets: return .localized("VisibleWallets.Title", comment: "Visible Wallets page: scene title") + case .secretWallets: return .localized("SecretWallets.Row.Title", comment: "Secret wallets page: row title") case .contribute: return .localized("AccountTab.Row.Contribute", comment: "Account tab: 'Contribute' row") case .coinsNodes: return .adamant.coinsNodesList.title case .language: return .localized("AccountTab.Row.Language", comment: "Account tab: 'Language' row") @@ -107,6 +109,7 @@ extension AccountViewController { case .biometry: image = nil // Determined by localAuth service case .notifications: image = .asset(named: "row_Notifications.png") case .visibleWallets: image = .asset(named: "row_balance") + case .secretWallets: image = .asset(named: "row_security") case .contribute: image = .asset(named: "row_contribute") case .language: image = .asset(named: "row_language") case .storage: image = .asset(named: "row_storage") diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 33ad64c86..53f83be1e 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -255,6 +255,23 @@ final class AccountViewController: FormViewController { appSection.append(visibleWalletsRow) + // Secret Wallets + let secretWalletsRow = LabelRow { + $0.tag = Rows.secretWallets.tag + $0.title = Rows.secretWallets.localized + $0.cell.imageView?.image = Rows.secretWallets.image + $0.cell.selectionStyle = .gray + }.cellUpdate { (cell, row) in + cell.accessoryType = .disclosureIndicator + row.title = Rows.secretWallets.localized + }.onCellSelection { [weak self] (cell, _) in + guard let self = self else { return } + self.secretWalletsAlertService.presentSecretWalletsActionSheet(from: cell) + } + + // Добавление строки в секцию + appSection.append(secretWalletsRow) + // Node list let nodesRow = LabelRow { $0.title = Rows.nodes.localized diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift index 9f0744916..134a6edd4 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift @@ -27,10 +27,14 @@ final class SecretWalletsAlertService { for (index, wallet) in state.wallets.enumerated() { let isSelected = (index == state.currentActiveIndex) - let suffix = isSelected ? " ✓" : "" + var walletName = wallet.name + if isSelected { + walletName.insert("[", at: walletName.index(walletName.startIndex, offsetBy: 0)) + walletName.insert("]", at: walletName.index(walletName.startIndex, offsetBy: index == 0 ? 2 : 3)) + } let action = AdamantAlertAction( - title: wallet.name + suffix, + title: walletName, style: .default ) { [weak self] in self?.secretWalletsViewModel.pickWallet(at: index) diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 6d0f610ea..c30cb4bf1 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1396,3 +1396,4 @@ "SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "Über Wallets"; "SecretWallets.Menu.Title" = "Aktive Wallets"; +"SecretWallets.Row.Title" = "Geheime Geldbörsen"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index e70800e22..741da13ac 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1372,3 +1372,4 @@ "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.Title" = "Active wallets"; +"SecretWallets.Row.Title" = "Secret wallets"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index a0abaf777..b499aeda4 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1373,3 +1373,4 @@ "SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "О кошельках"; "SecretWallets.Menu.Title" = "Активные кошельки"; +"SecretWallets.Row.Title" = "Секретные кошельки"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index a611d6ddf..d456fcf52 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1363,3 +1363,4 @@ "SecretWallets.Menu.AddSecretWallet" = "添加秘密"; "SecretWallets.Menu.TellMeMore" = "关于钱包"; "SecretWallets.Menu.Title" = "活动钱包"; +"SecretWallets.Row.Title" = "秘密钱包"; From 8603e3102383d47e5508ed33b1cc6ad790a65369 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 6 Mar 2025 21:38:31 +0700 Subject: [PATCH 05/36] [trello.com/c/vawidi4o] Change padding of wallet view controller title to it is rows. --- Adamant/Modules/Wallets/WalletViewControllerBase.xib | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Adamant/Modules/Wallets/WalletViewControllerBase.xib b/Adamant/Modules/Wallets/WalletViewControllerBase.xib index e96b04ae1..110d01984 100644 --- a/Adamant/Modules/Wallets/WalletViewControllerBase.xib +++ b/Adamant/Modules/Wallets/WalletViewControllerBase.xib @@ -1,9 +1,9 @@ - + - + @@ -31,10 +31,10 @@ - + - + From 837055da9800cd6d65c8241cb599e20a30143e02 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 7 Mar 2025 11:07:07 +0700 Subject: [PATCH 06/36] [trello.com/c/vawidi4o] Update labels for secret wallet options in the menu --- Adamant.xcodeproj/project.pbxproj | 8 ++++---- Adamant/App/DI/AppAssembly.swift | 4 ++-- Adamant/Modules/Account/AccountFactory.swift | 2 +- .../AccountViewController/AccountViewController.swift | 4 ++-- ...tService.swift => SecretWalletsAlertMenuView.swift} | 10 +++------- Adamant/Modules/SecretWallets/SecretWalletsState.swift | 2 +- .../Modules/SecretWallets/SecretWalletsViewModel.swift | 2 +- .../Assets/Localization/de.lproj/Localizable.strings | 10 +++++----- .../Assets/Localization/en.lproj/Localizable.strings | 10 +++++----- .../Assets/Localization/ru.lproj/Localizable.strings | 10 +++++----- .../Assets/Localization/zh.lproj/Localizable.strings | 10 +++++----- 11 files changed, 34 insertions(+), 38 deletions(-) rename Adamant/Modules/SecretWallets/{SecretWalletsAlertService.swift => SecretWalletsAlertMenuView.swift} (90%) diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index e25a2c41e..ed87af38c 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -188,7 +188,7 @@ 41CE153A297FF98200CC9254 /* Web3Swift+Adamant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CE1539297FF98200CC9254 /* Web3Swift+Adamant.swift */; }; 41E3C9CC2A0E20F500AF0985 /* AdamantCoinTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */; }; 48023DEF2D72EA7F00852961 /* AccountHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48023DEE2D72EA7F00852961 /* AccountHeader.xib */; }; - 48023DF12D72FB3500852961 /* SecretWalletsAlertService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */; }; + 48023DF12D72FB3500852961 /* SecretWalletsAlertMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */; }; 4803FC9A2D6715AF00452D2C /* SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */; }; 481558702D65A7660011B470 /* SecretWalletsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */; }; 481558722D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */; }; @@ -923,7 +923,7 @@ 41CE1539297FF98200CC9254 /* Web3Swift+Adamant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3Swift+Adamant.swift"; sourceTree = ""; }; 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantCoinTools.swift; sourceTree = ""; }; 48023DEE2D72EA7F00852961 /* AccountHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountHeader.xib; sourceTree = ""; }; - 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsAlertService.swift; sourceTree = ""; }; + 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsAlertMenuView.swift; sourceTree = ""; }; 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsFactory.swift; sourceTree = ""; }; 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManager.swift; sourceTree = ""; }; 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManagerProtocol.swift; sourceTree = ""; }; @@ -1807,7 +1807,7 @@ children = ( 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */, 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */, - 48023DF02D72FB3500852961 /* SecretWalletsAlertService.swift */, + 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */, ); path = SecretWallets; sourceTree = ""; @@ -3901,7 +3901,7 @@ AAB01CAD2D3AE44B007D6BF4 /* BitcoinKitTransactionFactory.swift in Sources */, 648CE3A222999CE70070A2CC /* BTCRawTransaction.swift in Sources */, 648DD79E2236A0B500B811FD /* DogeTransactionsViewController.swift in Sources */, - 48023DF12D72FB3500852961 /* SecretWalletsAlertService.swift in Sources */, + 48023DF12D72FB3500852961 /* SecretWalletsAlertMenuView.swift in Sources */, 3A26D9392C3C1C62003AD832 /* KlyWalletFactory.swift in Sources */, 3A299C6B2B838F2300B54C61 /* ChatMediaContainerView.swift in Sources */, 64B5736F2209B892005DC968 /* BtcTransactionDetailsViewController.swift in Sources */, diff --git a/Adamant/App/DI/AppAssembly.swift b/Adamant/App/DI/AppAssembly.swift index 59ac26814..c77dc667f 100644 --- a/Adamant/App/DI/AppAssembly.swift +++ b/Adamant/App/DI/AppAssembly.swift @@ -492,8 +492,8 @@ struct AppAssembly: MainThreadAssembly { }.inObjectScope(.container) // MARK: SecretWalletsAlertService - container.register(SecretWalletsAlertService.self) { r in - SecretWalletsAlertService( + container.register(SecretWalletsAlertMenuView.self) { r in + SecretWalletsAlertMenuView( dialogService: r.resolve(DialogService.self)!, secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)! ) diff --git a/Adamant/Modules/Account/AccountFactory.swift b/Adamant/Modules/Account/AccountFactory.swift index 2102d004c..22baeaa09 100644 --- a/Adamant/Modules/Account/AccountFactory.swift +++ b/Adamant/Modules/Account/AccountFactory.swift @@ -28,7 +28,7 @@ struct AccountFactory { walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, secretWalletsManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, - secretWalletsAlertService: assembler.resolve(SecretWalletsAlertService.self)! + secretWalletsAlertService: assembler.resolve(SecretWalletsAlertMenuView.self)! ) } } diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 53f83be1e..1a96e04c9 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -47,7 +47,7 @@ final class AccountViewController: FormViewController { private let apiServiceCompose: ApiServiceComposeProtocol private let secretWalletsManager: SecretWalletsManagerProtocol private lazy var walletsViewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) - private let secretWalletsAlertService: SecretWalletsAlertService + private let secretWalletsAlertService: SecretWalletsAlertMenuView let accountService: AccountService let dialogService: DialogService @@ -115,7 +115,7 @@ final class AccountViewController: FormViewController { walletServiceCompose: WalletServiceCompose, apiServiceCompose: ApiServiceComposeProtocol, secretWalletsManager: SecretWalletsManagerProtocol, - secretWalletsAlertService: SecretWalletsAlertService + secretWalletsAlertService: SecretWalletsAlertMenuView ) { self.walletStoreServiceProvider = walletStoreServiceProvider self.accountService = accountService diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift similarity index 90% rename from Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift rename to Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift index 134a6edd4..4fe4a1354 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertService.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift @@ -9,7 +9,7 @@ import UIKit @MainActor -final class SecretWalletsAlertService { +final class SecretWalletsAlertMenuView { private let dialogService: DialogService private let secretWalletsViewModel: SecretWalletsViewModel @@ -26,12 +26,8 @@ final class SecretWalletsAlertService { let state = secretWalletsViewModel.state for (index, wallet) in state.wallets.enumerated() { - let isSelected = (index == state.currentActiveIndex) - var walletName = wallet.name - if isSelected { - walletName.insert("[", at: walletName.index(walletName.startIndex, offsetBy: 0)) - walletName.insert("]", at: walletName.index(walletName.startIndex, offsetBy: index == 0 ? 2 : 3)) - } + let isSelected = index == state.currentActiveIndex + var walletName = isSelected ? "[ " + wallet.name + " ]" : wallet.name let action = AdamantAlertAction( title: walletName, diff --git a/Adamant/Modules/SecretWallets/SecretWalletsState.swift b/Adamant/Modules/SecretWallets/SecretWalletsState.swift index 6182de383..97e6aaffd 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsState.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsState.swift @@ -8,7 +8,7 @@ import Foundation -extension SecretWalletsAlertService { +extension SecretWalletsAlertMenuView { struct SecretWalletsState: Equatable { var wallets: [WalletItem] var currentActiveIndex: Int diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index be7344d92..5ffd75052 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -11,7 +11,7 @@ import Combine //TODO: Consider logout -extension SecretWalletsAlertService { +extension SecretWalletsAlertMenuView { @MainActor final class SecretWalletsViewModel: ObservableObject { @Published private(set) var state: SecretWalletsState = .default diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index c30cb4bf1..7f760c2aa 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1388,11 +1388,11 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "Normal"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ Geheim"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ Geheim"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ Geheim"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ Geheim"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ Geheim"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ Geheim 1"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ Geheim 2"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ Geheim 3"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ Geheim 4"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ Geheim 5"; "SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "Über Wallets"; "SecretWallets.Menu.Title" = "Aktive Wallets"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 741da13ac..0d37fde61 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1364,11 +1364,11 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Regular"; -"SecretWallets.Menu.Secret1" = "🔐1️⃣ Secret"; -"SecretWallets.Menu.Secret2" = "🔐2️⃣ Secret"; -"SecretWallets.Menu.Secret3" = "🔐3️⃣ Secret"; -"SecretWallets.Menu.Secret4" = "🔐4️⃣ Secret"; -"SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret"; +"SecretWallets.Menu.Secret1" = "🔐1️⃣ Secret 1"; +"SecretWallets.Menu.Secret2" = "🔐2️⃣ Secret 2"; +"SecretWallets.Menu.Secret3" = "🔐3️⃣ Secret 3"; +"SecretWallets.Menu.Secret4" = "🔐4️⃣ Secret 4"; +"SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret 5"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.Title" = "Active wallets"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index b499aeda4..e32d5bbcb 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1365,11 +1365,11 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "Обычный"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ Секретный"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ Секретный"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ Секретный"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ Секретный"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ Секретный"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ Секретный 1"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ Секретный 2"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ Секретный 3"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ Секретный 4"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ Секретный 5"; "SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "О кошельках"; "SecretWallets.Menu.Title" = "Активные кошельки"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index d456fcf52..d13a5f73d 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1355,11 +1355,11 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "普通"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ 秘密"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ 秘密"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ 秘密"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ 秘密"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ 秘密"; +"SecretWallets.Menu.Secret" = "🔐1️⃣ 秘密 1"; +"SecretWallets.Menu.Secret" = "🔐2️⃣ 秘密 2"; +"SecretWallets.Menu.Secret" = "🔐3️⃣ 秘密 3"; +"SecretWallets.Menu.Secret" = "🔐4️⃣ 秘密 4"; +"SecretWallets.Menu.Secret" = "🔐5️⃣ 秘密 5"; "SecretWallets.Menu.AddSecretWallet" = "添加秘密"; "SecretWallets.Menu.TellMeMore" = "关于钱包"; "SecretWallets.Menu.Title" = "活动钱包"; From c7e0284067ac7a4202c32412aed8c5629e34e99f Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 7 Mar 2025 11:25:43 +0700 Subject: [PATCH 07/36] [trello.com/c/vawidi4o] Change icon of secret wallet option in the menu --- .../AccountViewController+Form.swift | 2 +- .../row_secret_wallets.imageset/Contents.json | 23 ++++++++++++++++++ .../secure_wallet_badge_active.png | Bin 0 -> 1190 bytes .../secure_wallet_badge_active@2x.png | Bin 0 -> 2276 bytes .../secure_wallet_badge_active@3x.png | Bin 0 -> 3227 bytes 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/Contents.json create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active.png create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active@2x.png create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active@3x.png diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift index cc49f295e..f90e46cb0 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift @@ -109,7 +109,7 @@ extension AccountViewController { case .biometry: image = nil // Determined by localAuth service case .notifications: image = .asset(named: "row_Notifications.png") case .visibleWallets: image = .asset(named: "row_balance") - case .secretWallets: image = .asset(named: "row_security") + case .secretWallets: image = .asset(named: "row_secret_wallets") case .contribute: image = .asset(named: "row_contribute") case .language: image = .asset(named: "row_language") case .storage: image = .asset(named: "row_storage") diff --git a/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/Contents.json b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/Contents.json new file mode 100644 index 000000000..255d2781c --- /dev/null +++ b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "secure_wallet_badge_active.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "secure_wallet_badge_active@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "secure_wallet_badge_active@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active.png b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active.png new file mode 100644 index 0000000000000000000000000000000000000000..2aeab0f6149a72fdbf2bd7e76fbca428edeaf805 GIT binary patch literal 1190 zcmV;X1X=ruP)#d%G*Al!29*;H$G zq6uh21EA|kF(K@BF0Tofg$u&p@I$}wf$+L>EfCJPwYAky5V^(CN>U67hlL$_nIb5L zqSjCxXN9A}+roCe77A-HLPO+$w>Y&DMcs8Se}fS;3x6y5fFfzdG2t2KdJRTo;PWGy z;?zn5!aF$VdQ)i3O1_{-x@^C5Efh`)gDh(%ipy}lSv22DzR0rXWRl1gk$?@n2j4%p(;ncUIB$O$RmazleztI zO9i2p=THoE$B)?WZi^Z1zrdsi_QfL8D*K%6ctw)swqrNtMOT4)ZF(qzRB=g`+jbt< z2$;XdJ=#4-V?pJVmi5JPx-Jt|Htf)c7EQ7{*o%r;7(-*?cJrvb_eQ)TEue(%jTMG{ zzm25IG;v?Gyo_qYiu;~anID zLS#*O=3zEDxNcu0xiUn*@o0Aj#b8&UgR}-&;sO|PT*~GsK5t5()r%%(AJ{H4pVlB% z92Ynx-vuyx1hk${&LWmz0?{e>gE?^_M|-X~TbB&d8r7SLzlRY=7w{EF3s0b23~HG< z*{wG#sKE?t=w4L`EM3YF8U2mO6elL9uo?Y2ifX`GtL|o`&wOqg=3nB!HHf1Hy9ZN1 z2;)_ms4GsbH=JcL=;p#^`U`Ea*{d1|2tIZ;#`mms)r&O-rZ2y}&U#NVS)I~NMA zTk3;)^uhK;nzbZx2~7}26ke2d1aeev*D4zw#V{)VbwxBFtZ5K8ede6JdnLS@a#Ami z7lcdBZyZ%FO@^MM+|-x*Asq4)Hl)WFBR$eMj4FcXBpFE^3uKAx6Mk~qu0*YHG&p8O zS0oRRj>kmNS_5b`B#4Y+qS#kE(8`GRpL<@>@1=|S14E(16VLw)#{d8T07*qoM6N<$ Ef_YCQ{r~^~ literal 0 HcmV?d00001 diff --git a/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active@2x.png b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Row/row_secret_wallets.imageset/secure_wallet_badge_active@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7318f68bc7412d3745cb106727d535eb04fe32 GIT binary patch literal 2276 zcmVDg|00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPlv>C9x-Cpn-LCjkVH$@o$X_`{RKP1c9ZQ{TF)B(dlUc@@)Ul7$P}k+ zpR+C2JpPF7KHE*Umo?9xVmr$!XEaHqj!W;2eH1x~PQoWZwW4pz+O7&i5!XCC`Y!|6sMD!J}v54#B z0fUOCLL&q_N7Y^i;9Xa!nU|S@P>PUxs^+&ON#Z!Z~Yvga5 z?+dowjb&RAt;AE|5yDk@+B|ugDW=_xDGPXm3^5i@dE8^t3+H>9?+Ydg&XQ?TV-kU7o^SU225>JK9&B85s*?Sam z#RIm3g=?eG`5HCj1w~xa=zTU7FX91Fynu<~1xyq#V4`>d6U7UdC|M{jyhG|4k#D^%#?Q5DZf+nD9KR`5g5#m<4&r_8*Oav51EedCWIfl^ehl zuTm!Bw`{*q;EbWogK)R0zD^_uB0}i80wM1SUA$a~J!B6iKo3&DgdR3g52Ew9ygUQ* zWJp?2Qz^?0AULX-zo0+~Sv+{1F7#pb(WjY2;wOaB# zD%*55H%BQ@LKaWgUey&u=?Z{@ZTH3`9z?0@zrCd0;vJws8Po8XX%Wv;aor?S^@2FI z88A`2fQjM-Oi2B_eBe26quvppqceVi>Z$rUBs2FYkb!H{a(Apz*b=wjqJH_4%*QX= zfPw2zsNX3h`L`W5+1%AAY?>^3=on1%^dTHT*Wok`%a+MQHf>%auKRkKpl;c;Yx?d! z?0A>#EdQGPkd1iK`}R`A1#*zUILg^1ED75Og=>s(47m#S3}xjFZNbaCO~WC@OUMu# z@uVvc?Rgkcagh}cz4PH4;@T)=f;Mg5`xJ4(A#t6MA#KDvL=hLr0rrFpu@O)9JAxgJ z_YC4Yz9PZ#rsQK2VH&T z0gb&5wDr7W6lsIp&gwU^z*an6(h}@Uv&P%|O0T{Ng9J$HX<6 zjFqk(#cPHPnKQDaiFh+{Ex$n#Gd>g7cgYfK@zkDJvcDIzPCM|vWFL7(mNYGcz=ob@ z3)d(m@4I9i3rs@Y15K9c-)%DC-Bdgr{!kPTApmOx`YavTL*a&N88Yus0~%G2m4wcr zO9w(h?sALw*q?ZcYvQ_Y|Kv8HqN`7@zDeC7L*|{PH9~E-=9h&sC#k!(4+8>N5ZPs@ z#24f`b^AB`A?_LPDJ^L=i_8LU(9SLTv7qq`MasbXz@q1&WBx8Rq;19YinvCHJx&wp zf!E1dm=$V4EAf=O&&2JoDWU_5L5pAPr0tP3F4ii@LmZHGM(^7R+Ubkpp7G%qWwaJg zeS4C^E&Pv~tQnXm5RGy@$R#dUsa)jT4T z6yUTeaVnmg#+PHB_#@^meCocm>#omIcfQC%jd|jny@kT(lieWHu$eA=j(zA18FuI4GN-e(X(izkVH49vV?3HPU!>W2 zxXkHvVPVNRvuOVy;3)QaR$xf*SK1ve8_(65(CH>R>Kmu)KKw}IDi_2gv96t)QHONC z1ComOvi(Du_gIF{(8lRX8!l7F^tK*bGx`Fs|K%kLmkYEzK}jgv1gG=8Yx>-K>;&x| zyhipJY8RqRxTU@}9qM%_1eL(R0~f?cp&i?;6ApqM?kcm?(d({%>JP&K?uqzF_cDB? zOt_^!g#&}^K~mv?sFyrX{!%5J)$%MC47Pzxg@D-A2<3x5^#jqZL3coAm4gWf2HpLq zLO`E7@_D~hmURp&92j(`+ln?2FAO6VLyv`GtnvZrH@Z1Iq;O#9eYdtz9*8Adi<*zo z7epr7_jD2l5p-W32zH|H)Ms|~`{kdiLj z#0$j)Co;V*$3*e_bzu@XE0^BE=LhM{O1Q8W)pvo>*^ZA%D- yYqXV%G$Oq3Dl{R@vc=<+buW&hjGE*uc6IeZ)V-=EMnEwUe}%(LIjJE0(I?K!25+V^*RIK zok5wI*_yhXq94H{emy~5qkie_jZQCn{i5Vg;5_@qdkODiE|yN%=RN1_lz|?n4*P@E z=d$}wZho-Fy#&j-(ECr%>m~n=;kP)#j5NB;+PQS}9SLuYr(p6hvPv>4yg-8hd!gU} zU&}NlhwQP_cpiB|9o{{51U>u~whaUSp(!u$5_l-MD|&dGz^$rAG$#m#ap91HQ)+gc z@&?>dFw+4i@zFFV=V*T{_a;^p+N@z;`a^0C>T#<4`d1Z}r&l$UbY#i6$`=yO)iv%H zeiArImj+yf$q5DmP{80`_s}SJZ)`XE9Bm99?u`|d9355_dfR4j{{Aq}EqG@Qj0J@s z8KrMzu0=pZ#DN6cjY*Oe+E}0Afo8cbxKUiW99lv$PlUcs&rY`pnxvPSax{-t0Yoh} zCQ<3|TZ$yZR!R}B%D_04QU3i^U5bpdkMQ!@#%?J5-1jI4<))FZ zoksU~Bu4LhyZrTVV~8U!Wm*=zA4N%BAbISjo6Ic;gJ;@kWMZ6F8(v&GEC#I}m#I&E zK9X<2$eE2(2Y=eBy9fDUUy$3+CVDYgJ4E1^GTo-9qzaPo2($6TFCYvPaC6{^A>p;b z|BG%D9ftAjpU3iY*8$QNSzN*rWasd*`Q%u?uAeq`ug+<%{Y2G)w58L9i}~>N5}XD! zQblvBrV%vm)ytNsv(1)LJWtga4tylEF#%6V2Q(3+ll2D*OlP@?*UoacWPui+98!>q z2Me2%Zd0}_(5^X~z#f{6>_Wee22GDKe^{-nIq`bh4Pv2PbYUH~enP^Bzw_W=@l(6t zn>VSnoOSo;$@dnv;o^3&krTOM-S*SPF1O70VMZS+PJ4uorEhp9!BO!9L{^`3v9#x# zv1jvlg*3uL=Dqj}I}HcWS47*FR(j8$)W2vFHy~bl%)c7R*ts~g6u-Iu57i%C2LGw? zia+fx{BhU!v+Di-#@m~-r9OjcRMvabVW7sh3%m(80R(VULiT^aBV@Qh)z?IKR4n<55*x}#7;tAw z;_;12aNr^<2qKKXBur6ZFqyn!h~Jgxoxci_Y#C=BfWC)7)8dUJNcfW9GbkMB&_7a# zUy3&~z#f=5FidAc;xcz}Z7nT+hAWEk5b;`MVJ_3yu;A!4^URWBo_Tvdd%&m%@~~Mw zz92ita;GY|43Sq?tz@hF7~u;fwB?|ONp~e}clZYSCd7wUNxts9S*%ko=h*8A3&PZ^ zGZ&{(x*WviVO_(c+xa}dg#Hs<>RT;GM}FPva{lV18X z43mj%oHdV-ANaKf1~L^@tM%_I|Gd&J-F-zA@lO)dWB?3aVYd;<>gE;}w+(0RNb11! z##hld^$Y=L*K;|$@e+<*`B2lm)kMfZ)H-Zd87>3 z3<%(*6JDp~VffMsnKNvbgsoIZ>m+E63~I6g|3doseUVQa$N)2H4CWx!IBM*Lgq4W6 z;5;({6r+!zZASNFopwF5zp3ej2nb0oY2VvDMmo~1EXG!*0w~W4Uz2|(<|iV$%i6~x z*n(oYTld_VXEtBtlKgIcF;S?aQFSCjo+Qbc8JPk?*<9L!)!ACe9dD)~{Op|SSZ|*m zaCi16q<@xwniSX_2N}?00t^S=VRmt`}yZYzmhlf|_S$wZMbzacLP zah$ze$M&SI$Iul_j7HNp3!9XDioa48M@>#fb2Z0L@n28w!zbEz;#6 zyDJ<%`}(=xKDB__EuG$@-#F-*j%sb^pYG!)pS85V_#|lsBGSeBTwxp*cKhIGY7ul8 z*IF}`5gG4gpA>RBuOp+6LLx|_R-8H4WKxgDy@*{)N+0h(zzOI6==ce#k{G5K5XTD1 zH7Rei^c(W?@&FPxWG!C=>M(UvH%=a7$fg^|4{NgP*M^oD54w{n8Sckh1Dm)@)Gr|8EW4e5_*M+y6Xvd?825(C>*hH zj+Y98skptHiAkZUQ*(X7HxSHcO62o+@h&)l;&?4FDS>IB{jc|v&^Je=P&mPskPj!) z#Nn#SkxVtmdwmqaPUk(-ZpJ8I?12vn<9@)+QkY0dts{aM*C7&jR~R3O9AgUmdP}5E zBb~?}#Tu)%@fvA}N+su!U4{iK$!>po)$O*0cjxsdQXytHhTW0G9kaLb=&huhkPwCG zhg#%T?^t|+IU(%Nz+Rai|GN(I_qR3huWl*NSvTa=N(fg>NEuR;CUGM0`)l)9q~i8& z5s2TcLf_B0@ZpuH&A1pjgVU{hCDQ*(k*Bih4J4b@i`z}A>FM`H0M3(wivK{5Pzqj1 z#f%lwR^UJtN)w7mC9ezqykmz~6%Sja%eX|#40vkXMowtn?o*0u#g4_OQ`khyy1#cM z=&neOS80J#*hS0kfPBX;@*hTJ=D3@XKlgIUN}5Fwu~+R{G0z~^a^EwtJO9zZ0oOAo z^ghU*5%=_R2s)B(>o`m0gquDldqi$#Tb7@_u+5iT=Nqp4w7vm3S(Go2fr#8T?ETt_ zDn^>9!bXbO5=H3G@feWZR3YsUm?L16?IW?%kY+^CHkM2!D&+T|>_JO14xvf!wNSeE zq!iy-YO-e6fN{&4+=cT35f!^Mz`4Ol5yQ4?&h$dgGH-hZu~o2$Rp0qL#C5SE2s|%$ z)GiRe+Env6DoV?!#R!l5brft|NNXK9`g=v(IkYWRD1YqbS9E00X#}}((pWSr(*p-m ziBs*PIGO}JUn~|zOQ>R@cyViRuO~I*1L_ zQz}Ov5)}F5k8dix*2u>=PDncrX2PH5dhzmU1h}Y5wD0n_9M6T09~nGV2VN#_R~GUv z<_DRM+3^hc1Hje+o7m4=^S3-c#6BkoFsoaMY^GTy#I%0CJzRhVesbvN|DE*CC~4q{ zl~!qNsN+OxL{k!`zW}lZ&})93 Date: Thu, 13 Mar 2025 18:55:49 +0700 Subject: [PATCH 08/36] [trello.com/c/vawidi4o] Change icon of secret wallet. Change caption of wallet section and address row. --- Adamant.xcodeproj/project.pbxproj | 24 ++--- Adamant/App/DI/AppAssembly.swift | 15 ++-- Adamant/Modules/Account/AccountFactory.swift | 3 +- Adamant/Modules/Account/AccountHeader.xib | 29 +++--- .../Modules/Account/AccountHeaderView.swift | 71 ++++++++++++++- .../AccountViewController+Form.swift | 2 +- .../AccountViewController.swift | 45 +++++----- .../ChatsList/ChatListViewController.swift | 2 + .../DelegateDetailsViewController.swift | 3 +- .../SecretWallets/AddSecretWalletView.swift | 45 ++++++++++ .../SecretWalletsAlertMenuView.swift | 6 +- .../SecretWallets/SecretWalletsFactory.swift | 9 ++ .../SecretWalletsMenuViewModel.swift | 70 +++++++++++++++ .../SecretWallets/SecretWalletsState.swift | 25 +++--- .../SecretWalletsViewModel.swift | 61 ++++++------- .../PKGenerator/PKGeneratorViewModel.swift | 1 + .../Wallets/Adamant/AdmWalletFactory.swift | 1 + .../Adamant/AdmWalletViewController.swift | 7 +- .../Wallets/Bitcoin/BtcWalletFactory.swift | 1 + .../Bitcoin/BtcWalletViewController.swift | 15 +++- .../Wallets/Dash/DashWalletFactory.swift | 1 + .../Dash/DashWalletViewController.swift | 15 +++- .../Wallets/Doge/DogeWalletFactory.swift | 1 + .../Doge/DogeWalletViewController.swift | 15 +++- .../Wallets/ERC20/ERC20WalletFactory.swift | 1 + .../ERC20/ERC20WalletViewController.swift | 17 +++- .../Wallets/Ethereum/EthWalletFactory.swift | 1 + .../Ethereum/EthWalletViewController.swift | 15 +++- .../Wallets/Klayr/KlyWalletFactory.swift | 1 + .../Klayr/KlyWalletViewController.swift | 15 +++- ...TransactionDetailsViewControllerBase.swift | 2 +- .../Wallets/TransferViewControllerBase.swift | 2 +- .../Wallets/WalletViewControllerBase.swift | 5 ++ Adamant/ServiceProtocols/DialogService.swift | 4 +- ...tWalletsManager+SecretWalletsFactory.swift | 83 ++++++++++++++++++ .../AdamantDialogService.swift | 11 +-- Adamant/Services/SecretWalletsFactory.swift | 82 ----------------- .../Localization/de.lproj/Localizable.strings | 8 ++ .../Localization/en.lproj/Localizable.strings | 8 ++ .../Localization/ru.lproj/Localizable.strings | 8 ++ .../Localization/zh.lproj/Localizable.strings | 8 ++ .../Share_button.png | Bin 233 -> 0 bytes .../Share_button@2x.png | Bin 373 -> 0 bytes .../Share_button@3x.png | Bin 483 -> 0 bytes .../Contents.json | 3 + .../secure_wallet_badge_active.png | Bin .../secure_wallet_badge_active@2x.png | Bin .../secure_wallet_badge_active@3x.png | Bin .../Contents.json | 9 +- .../secure_wallet_badge_regular.png | Bin 0 -> 931 bytes .../secure_wallet_badge_regular@2x.png | Bin 0 -> 1780 bytes .../secure_wallet_badge_regular@3x.png | Bin 0 -> 2361 bytes 52 files changed, 538 insertions(+), 212 deletions(-) create mode 100644 Adamant/Modules/SecretWallets/AddSecretWalletView.swift create mode 100644 Adamant/Modules/SecretWallets/SecretWalletsFactory.swift create mode 100644 Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift create mode 100644 Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift delete mode 100644 Adamant/Services/SecretWalletsFactory.swift delete mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/Share_button_small.imageset/Share_button.png delete mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/Share_button_small.imageset/Share_button@2x.png delete mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/Share_button_small.imageset/Share_button@3x.png rename CommonKit/Sources/CommonKit/Assets/Shared.xcassets/{Row/row_secret_wallets.imageset => Buttons/secret_wallets_active.imageset}/Contents.json (86%) rename CommonKit/Sources/CommonKit/Assets/Shared.xcassets/{Row/row_secret_wallets.imageset => Buttons/secret_wallets_active.imageset}/secure_wallet_badge_active.png (100%) rename CommonKit/Sources/CommonKit/Assets/Shared.xcassets/{Row/row_secret_wallets.imageset => Buttons/secret_wallets_active.imageset}/secure_wallet_badge_active@2x.png (100%) rename CommonKit/Sources/CommonKit/Assets/Shared.xcassets/{Row/row_secret_wallets.imageset => Buttons/secret_wallets_active.imageset}/secure_wallet_badge_active@3x.png (100%) rename CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/{Share_button_small.imageset => secret_wallets_regular.imageset}/Contents.json (58%) create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/secret_wallets_regular.imageset/secure_wallet_badge_regular.png create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/secret_wallets_regular.imageset/secure_wallet_badge_regular@2x.png create mode 100644 CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/secret_wallets_regular.imageset/secure_wallet_badge_regular@3x.png diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index ed87af38c..6339b0e08 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -189,14 +189,14 @@ 41E3C9CC2A0E20F500AF0985 /* AdamantCoinTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */; }; 48023DEF2D72EA7F00852961 /* AccountHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48023DEE2D72EA7F00852961 /* AccountHeader.xib */; }; 48023DF12D72FB3500852961 /* SecretWalletsAlertMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */; }; - 4803FC9A2D6715AF00452D2C /* SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */; }; + 4803FC9A2D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */; }; 481558702D65A7660011B470 /* SecretWalletsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */; }; 481558722D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */; }; - 482231212D714C3D00D592D8 /* SecretWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */; }; - 488C1E8A2D7150F900E955E8 /* SecretWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */; }; 48B6A8EB2D5738D800326EE8 /* WalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */; }; 48B6A8ED2D57390400326EE8 /* AdamantWalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */; }; 48B6A8EF2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */; }; + 48C034F92D81560800F50E35 /* SecretWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034F82D81560800F50E35 /* SecretWalletsState.swift */; }; + 48C034FF2D81587800F50E35 /* SecretWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */; }; 48DA2FCF2D4A0519008F9FC1 /* AccountWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */; }; 48DA2FD12D4A054E008F9FC1 /* AccountWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA2FD02D4A054E008F9FC1 /* AccountWalletsState.swift */; }; 48DA2FD62D4A58D8008F9FC1 /* WalletCollectionViewCell+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA2FD52D4A58D8008F9FC1 /* WalletCollectionViewCell+Model.swift */; }; @@ -924,14 +924,14 @@ 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantCoinTools.swift; sourceTree = ""; }; 48023DEE2D72EA7F00852961 /* AccountHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountHeader.xib; sourceTree = ""; }; 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsAlertMenuView.swift; sourceTree = ""; }; - 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsFactory.swift; sourceTree = ""; }; + 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdamantSecretWalletsManager+SecretWalletsFactory.swift"; sourceTree = ""; }; 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManager.swift; sourceTree = ""; }; 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManagerProtocol.swift; sourceTree = ""; }; - 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsViewModel.swift; sourceTree = ""; }; - 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsState.swift; sourceTree = ""; }; 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsStoreService.swift; sourceTree = ""; }; 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletsStoreService.swift; sourceTree = ""; }; 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletStoreServiceProvider.swift; sourceTree = ""; }; + 48C034F82D81560800F50E35 /* SecretWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsState.swift; sourceTree = ""; }; + 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsViewModel.swift; sourceTree = ""; }; 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWalletsViewModel.swift; sourceTree = ""; }; 48DA2FD02D4A054E008F9FC1 /* AccountWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWalletsState.swift; sourceTree = ""; }; 48DA2FD52D4A58D8008F9FC1 /* WalletCollectionViewCell+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletCollectionViewCell+Model.swift"; sourceTree = ""; }; @@ -1805,9 +1805,9 @@ 482231222D714C4400D592D8 /* SecretWallets */ = { isa = PBXGroup; children = ( - 488C1E892D7150F900E955E8 /* SecretWalletsState.swift */, - 482231202D714C3D00D592D8 /* SecretWalletsViewModel.swift */, + 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */, 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */, + 48C034F82D81560800F50E35 /* SecretWalletsState.swift */, ); path = SecretWallets; sourceTree = ""; @@ -2640,7 +2640,7 @@ 41047B75294C62710039E956 /* AdamantVisibleWalletsService.swift */, 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */, 4153045829C09902000E4BEA /* AdamantIncreaseFeeService.swift */, - 4803FC992D6715AF00452D2C /* SecretWalletsFactory.swift */, + 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */, 4184F1722A33102800D7B8B9 /* AdamantCrashlysticsService.swift */, 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */, 3A9015A62A614A62002A2464 /* AdamantEmojiService.swift */, @@ -3634,7 +3634,7 @@ 4186B332294200B4006594A3 /* BtcWalletService+DynamicConstants.swift in Sources */, 3AFE7E432B19E4D900718739 /* WalletServiceCompose.swift in Sources */, 3A26D93D2C3C1CC3003AD832 /* KlyNodeApiService.swift in Sources */, - 4803FC9A2D6715AF00452D2C /* SecretWalletsFactory.swift in Sources */, + 4803FC9A2D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */, 93A118512993167500E144CC /* ChatMessageBackgroundColor.swift in Sources */, 93760BD72C656CF8002507C3 /* DefaultNodesProvider.swift in Sources */, 3A26D93B2C3C1C97003AD832 /* KlyApiCore.swift in Sources */, @@ -3737,7 +3737,6 @@ 3A7BD0102AA9BD030045AAB0 /* AdamantVibroService.swift in Sources */, 85B405022D3012D5000AB744 /* AccountViewController+Form.swift in Sources */, 937EDFC02C9CF6B300F219BB /* VersionFooterView.swift in Sources */, - 488C1E8A2D7150F900E955E8 /* SecretWalletsState.swift in Sources */, A5E04227282A8BDC0076CD13 /* BtcBalanceResponse.swift in Sources */, 64F085D920E2D7600006DE68 /* AdmTransactionsViewController.swift in Sources */, 9322E87B2970431200B8357C /* ChatMessageFactory.swift in Sources */, @@ -3770,6 +3769,7 @@ 6449BA6A235CA0930033B936 /* ERC20Wallet.swift in Sources */, E9147B612050599000145913 /* LoginViewController+QR.swift in Sources */, 9399F5ED29A85A48006C3E30 /* ChatCacheService.swift in Sources */, + 48C034F92D81560800F50E35 /* SecretWalletsState.swift in Sources */, 3A9015A92A615893002A2464 /* ChatMessagesListViewModel.swift in Sources */, 936658952B0AC15300BDB2D3 /* Node+UI.swift in Sources */, 26A976012B7E852E0095C367 /* ChatSelectTextViewFactory.swift in Sources */, @@ -3967,6 +3967,7 @@ 41C1698C29E7F34900FEB3CB /* RichTransactionReplyService.swift in Sources */, 9390C5032976B42800270CDF /* ChatDialogManager.swift in Sources */, E926E02E213EAABF005E536B /* TransferViewControllerBase+Alert.swift in Sources */, + 48C034FF2D81587800F50E35 /* SecretWalletsViewModel.swift in Sources */, 936658A52B0AE67A00BDB2D3 /* CoinsNodesListFactory.swift in Sources */, 2621AB3B2C613C8100046D7A /* NotificationsFactory.swift in Sources */, E9B1AA572121ACC000080A2A /* AdmWalletViewController.swift in Sources */, @@ -4095,7 +4096,6 @@ 41BCB310295C6082004B12AB /* VisibleWalletsResetTableViewCell.swift in Sources */, 93CCAE7B2B06D9B500EA5B94 /* DogeBlocksDTO.swift in Sources */, 3AF08D612B4EB3C400EB82B1 /* LanguageStorageProtocol.swift in Sources */, - 482231212D714C3D00D592D8 /* SecretWalletsViewModel.swift in Sources */, E9E7CDB12002B97B00DFC4DB /* AccountFactory.swift in Sources */, E9AA8BF82129F13000F9249F /* ComplexTransferViewController.swift in Sources */, E9A174B52057EDCE003667CD /* AdamantTransfersProvider+backgroundFetch.swift in Sources */, diff --git a/Adamant/App/DI/AppAssembly.swift b/Adamant/App/DI/AppAssembly.swift index c77dc667f..e4bcef84d 100644 --- a/Adamant/App/DI/AppAssembly.swift +++ b/Adamant/App/DI/AppAssembly.swift @@ -83,8 +83,8 @@ struct AppAssembly: MainThreadAssembly { }.inObjectScope(.container) // MARK: Secret Wallets - container.register(SecretWalletsFactory.self) { r in - SecretWalletsFactory( + container.register(AdamantSecretWalletsManager.SecretWalletsFactory.self) { r in + AdamantSecretWalletsManager.SecretWalletsFactory( visibleWalletsService: r.resolve(VisibleWalletsService.self)!, accountService: r.resolve(AccountService.self)!, securedStore: r.resolve(SecuredStore.self)!, @@ -95,7 +95,7 @@ struct AppAssembly: MainThreadAssembly { container.register(SecretWalletsManagerProtocol.self) { r in AdamantSecretWalletsManager( walletsStoreService: r.resolve(WalletStoreServiceProtocol.self)!, - secretWalletsFactory: r.resolve(SecretWalletsFactory.self)! + secretWalletsFactory: r.resolve(AdamantSecretWalletsManager.SecretWalletsFactory.self)! ) }.inObjectScope(.container) @@ -410,7 +410,7 @@ struct AppAssembly: MainThreadAssembly { coreDataStack: r.resolve(CoreDataStack.self)!, apiService: r.resolve(AdamantApiServiceProtocol.self)!, adamantCore: r.resolve(AdamantCore.self)!, - accountService: r.resolve(AccountService.self)!, + accountService: r.resolve(AccountService.self)!, walletServiceCompose: r.resolve(WalletServiceCompose.self)! ) }.inObjectScope(.container) @@ -491,11 +491,16 @@ struct AppAssembly: MainThreadAssembly { EthBIP32Service(ethApiService: r.resolve(ERC20ApiService.self)!) }.inObjectScope(.container) + // MARK: SecretWalletsViewModel + container.register(SecretWalletsViewModel.self) { r in + SecretWalletsViewModel(secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)!) + }.inObjectScope(.container) + // MARK: SecretWalletsAlertService container.register(SecretWalletsAlertMenuView.self) { r in SecretWalletsAlertMenuView( dialogService: r.resolve(DialogService.self)!, - secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)! + secretWalletsViewModel: r.resolve(SecretWalletsViewModel.self)! ) }.inObjectScope(.transient) } diff --git a/Adamant/Modules/Account/AccountFactory.swift b/Adamant/Modules/Account/AccountFactory.swift index 22baeaa09..669a10ff9 100644 --- a/Adamant/Modules/Account/AccountFactory.swift +++ b/Adamant/Modules/Account/AccountFactory.swift @@ -28,7 +28,8 @@ struct AccountFactory { walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, secretWalletsManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, - secretWalletsAlertService: assembler.resolve(SecretWalletsAlertMenuView.self)! + secretWalletsAlertService: assembler.resolve(SecretWalletsAlertMenuView.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } } diff --git a/Adamant/Modules/Account/AccountHeader.xib b/Adamant/Modules/Account/AccountHeader.xib index ee91360ee..e55f07d31 100644 --- a/Adamant/Modules/Account/AccountHeader.xib +++ b/Adamant/Modules/Account/AccountHeader.xib @@ -1,9 +1,9 @@ - - + + - + @@ -53,45 +53,40 @@ - + + - + - + - - + diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index bdbd79bf0..ed3def2c6 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -20,15 +20,80 @@ final class AccountHeaderView: UIView { @IBOutlet weak var avatarImageView: UIImageView! @IBOutlet weak var addressButton: UIButton! @IBOutlet weak var walletViewContainer: UIView! - @IBOutlet weak var walletsButton: UIButton! + @IBOutlet weak var secretWalletsImageView: UIImageView! + private var outlineLayer: CAShapeLayer? weak var delegate: AccountHeaderViewDelegate? + override func awakeFromNib() { + super.awakeFromNib() + + setWalletIcon(.regular, badgeCount: 0) + addPersistentOutline() + + setupGestureRecognizers() + } + + func setWalletIcon(_ icon: WalletIcon, badgeCount: Int) { + secretWalletsImageView.tintColor = .adamant.secondary + secretWalletsImageView.image = .asset(named: icon.rawValue)?.withRenderingMode(.alwaysTemplate) ?? .init() + updateWalletBadge(count: badgeCount) + } + @IBAction func addressButtonTapped(_ sender: UIButton) { delegate?.addressLabelTapped(from: sender) } - @IBAction func walletsButtonTapped(_ sender: UIButton) { - delegate?.walletsButtonTapped(from: sender) + @objc private func walletsButtonTapped() { + animateOutline() + delegate?.walletsButtonTapped(from: secretWalletsImageView) + } + + override func layoutSubviews() { + super.layoutSubviews() + + guard let outlineLayer = outlineLayer else { return } + guard !secretWalletsImageView.frame.isEmpty else { return } + + let imageView = secretWalletsImageView! + let center = imageView.center + let radius = imageView.bounds.width + let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true) + outlineLayer.path = path.cgPath + } +} + +private extension AccountHeaderView { + func setupGestureRecognizers() { + secretWalletsImageView.isUserInteractionEnabled = true + + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(walletsButtonTapped)) + secretWalletsImageView.addGestureRecognizer(tapGesture) + } + + func updateWalletBadge(count: Int) { + secretWalletsImageView.viewWithTag(99)?.removeFromSuperview() + + guard count > 0 else { return } + + } + + private func addPersistentOutline() { + + } + + private func animateOutline() { + + } +} + +extension AccountHeaderView{ + enum WalletIcon: String{ + case regular = "secret_wallets_regular" + case secret = "secret_wallets_active" + + func image() -> UIImage? { + return UIImage(named: self.rawValue) + } } } diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift index f90e46cb0..21965217b 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController+Form.swift @@ -109,7 +109,7 @@ extension AccountViewController { case .biometry: image = nil // Determined by localAuth service case .notifications: image = .asset(named: "row_Notifications.png") case .visibleWallets: image = .asset(named: "row_balance") - case .secretWallets: image = .asset(named: "row_secret_wallets") + case .secretWallets: image = .asset(named: "secret_wallets_active") case .contribute: image = .asset(named: "row_contribute") case .language: image = .asset(named: "row_language") case .storage: image = .asset(named: "row_storage") diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 1a96e04c9..8b5ec208b 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -48,7 +48,8 @@ final class AccountViewController: FormViewController { private let secretWalletsManager: SecretWalletsManagerProtocol private lazy var walletsViewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) private let secretWalletsAlertService: SecretWalletsAlertMenuView - + private let secretWalletsViewModel: SecretWalletsViewModel + let accountService: AccountService let dialogService: DialogService let localAuth: LocalAuthentication @@ -62,7 +63,7 @@ final class AccountViewController: FormViewController { private var pagingViewController: PagingViewController! private var notificationsSet: Set = [] - + // MARK: StayIn var showLoggedInOptions: Bool { @@ -115,7 +116,8 @@ final class AccountViewController: FormViewController { walletServiceCompose: WalletServiceCompose, apiServiceCompose: ApiServiceComposeProtocol, secretWalletsManager: SecretWalletsManagerProtocol, - secretWalletsAlertService: SecretWalletsAlertMenuView + secretWalletsAlertService: SecretWalletsAlertMenuView, + secretWalletsViewModel: SecretWalletsViewModel ) { self.walletStoreServiceProvider = walletStoreServiceProvider self.accountService = accountService @@ -130,6 +132,7 @@ final class AccountViewController: FormViewController { self.apiServiceCompose = apiServiceCompose self.secretWalletsManager = secretWalletsManager self.secretWalletsAlertService = secretWalletsAlertService + self.secretWalletsViewModel = secretWalletsViewModel super.init(nibName: nil, bundle: nil) } @@ -174,6 +177,16 @@ final class AccountViewController: FormViewController { accountHeaderView = header accountHeaderView.delegate = self + secretWalletsViewModel.$state + .map{ $0.currentActiveIndex } + .removeDuplicates() + .receive(on: DispatchQueue.main) + .sink { [weak self] index in + guard index >= 0 else { return } + self?.accountHeaderView.setWalletIcon(index == 0 ? .regular : .secret, badgeCount: index) + } + .store(in: ¬ificationsSet) + updateAccountInfo() tableView.tableHeaderView = header @@ -271,7 +284,7 @@ final class AccountViewController: FormViewController { // Добавление строки в секцию appSection.append(secretWalletsRow) - + // Node list let nodesRow = LabelRow { $0.title = Rows.nodes.localized @@ -739,7 +752,7 @@ final class AccountViewController: FormViewController { pagingViewController?.indicatorColor = UIColor.adamant.primary } - + deinit { NotificationCenter.default.removeObserver(self) } @@ -891,7 +904,7 @@ final class AccountViewController: FormViewController { private func updateUI() { let appSection = form.sectionBy(tag: Sections.application.tag) appSection?.header?.title = Sections.application.localized - + let walletSection = form.sectionBy(tag: Sections.wallet.tag) walletSection?.header?.title = Sections.wallet.localized @@ -968,10 +981,10 @@ final class AccountViewController: FormViewController { func layoutTableHeaderView() { guard let view = tableView.tableHeaderView else { return } var frame = view.frame - + frame.size.height = 300 view.frame = frame - + self.tableView.tableHeaderView = view } @@ -1022,17 +1035,7 @@ extension AccountViewController: AccountHeaderViewDelegate { } let encodedAddress = AdamantUriTools.encode(request: AdamantUri.address(address: address, params: nil)) - dialogService.presentShareAlertFor(stringForPasteboard: address, - stringForShare: encodedAddress, - stringForQR: encodedAddress, - types: [.copyToPasteboard, - .share, - .generateQr(encodedContent: encodedAddress, sharingTip: address, withLogo: true) - ], - excludedActivityTypes: ShareContentType.address.excludedActivityTypes, - animated: true, - from: from, - completion: nil) + dialogService.presentShareAlertFor(title: nil, stringForPasteboard: address, stringForShare: encodedAddress, stringForQR: encodedAddress, types: [.copyToPasteboard, .share, .generateQr(encodedContent: encodedAddress, sharingTip: address, withLogo: true)], excludedActivityTypes: ShareContentType.address.excludedActivityTypes, animated: true, from: from, completion: nil) } } @@ -1078,7 +1081,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr walletViewControllers[index].viewController } } - + nonisolated func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem { MainActor.assertIsolated() @@ -1101,7 +1104,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr first.height != second.height else { return } - + updateHeaderSize(with: second, animated: true) } } diff --git a/Adamant/Modules/ChatsList/ChatListViewController.swift b/Adamant/Modules/ChatsList/ChatListViewController.swift index edc07df14..c664714c7 100644 --- a/Adamant/Modules/ChatsList/ChatListViewController.swift +++ b/Adamant/Modules/ChatsList/ChatListViewController.swift @@ -1209,6 +1209,7 @@ extension ChatListViewController { guard !partner.isSystem else { self.dialogService.presentShareAlertFor( + title: nil, string: address, types: [ .copyToPasteboard, @@ -1270,6 +1271,7 @@ extension ChatListViewController { guard let self = self else { return } self.dialogService.presentShareAlertFor( + title: title, string: address, types: [ .copyToPasteboard, diff --git a/Adamant/Modules/Delegates/DelegateDetailsViewController.swift b/Adamant/Modules/Delegates/DelegateDetailsViewController.swift index 2511c1c98..f0d5f6aec 100644 --- a/Adamant/Modules/Delegates/DelegateDetailsViewController.swift +++ b/Adamant/Modules/Delegates/DelegateDetailsViewController.swift @@ -193,7 +193,8 @@ extension DelegateDetailsViewController: UITableViewDelegate, UITableViewDataSou tableView.deselectRow(at: indexPath, animated: true) } - dialogService.presentShareAlertFor(string: value, + dialogService.presentShareAlertFor(title: nil, + string: value, types: [.copyToPasteboard, .share], excludedActivityTypes: nil, animated: true, from: cell, diff --git a/Adamant/Modules/SecretWallets/AddSecretWalletView.swift b/Adamant/Modules/SecretWallets/AddSecretWalletView.swift new file mode 100644 index 000000000..f4021c25f --- /dev/null +++ b/Adamant/Modules/SecretWallets/AddSecretWalletView.swift @@ -0,0 +1,45 @@ +import SwiftUI +import CommonKit + +struct AddSecretWalletView: View { + private var viewModel: SecretWalletsMenuViewModel + @Binding private var password: String + + var body: some View { + VStack { + + } + .background(Color(.adamant.secondBackgroundColor)) + .navigationTitle(String.adamant.AddSecretWallet.title) + .navigationBarTitleDisplayMode(.inline) + } + + init(viewModel: SecretWalletsMenuViewModel) { + self.viewModel = viewModel + self._password = Binding.constant("") + } +} + +private extension AddSecretWalletView { + var inputSection: some View { + Section { + Group { + Text(String.adamant.AddSecretWallet.description) + .multilineTextAlignment(.center) + .padding(.vertical, 5) + + AdamantSecureField( + placeholder: .adamant.AddSecretWallet.passwordPlaceholder, + text: $password + ) + + Button(action: { viewModel.createSecretWallet(password: password) }) { + Text(String.adamant.pkGenerator.generateButton) + .foregroundStyle(Color(uiColor: .adamant.primary)) + .padding(.horizontal, 30) + .expanded(axes: .horizontal) + } + }.listRowBackground(Color(uiColor: .adamant.cellColor)) + } + } +} diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift index 4fe4a1354..3a598fe92 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift @@ -15,10 +15,10 @@ final class SecretWalletsAlertMenuView { init( dialogService: DialogService, - secretWalletsManager: SecretWalletsManagerProtocol + secretWalletsViewModel: SecretWalletsViewModel ) { self.dialogService = dialogService - self.secretWalletsViewModel = .init(secretWalletsManager: secretWalletsManager) + self.secretWalletsViewModel = secretWalletsViewModel } func presentSecretWalletsActionSheet(from sourceView: UIView) { @@ -27,7 +27,7 @@ final class SecretWalletsAlertMenuView { for (index, wallet) in state.wallets.enumerated() { let isSelected = index == state.currentActiveIndex - var walletName = isSelected ? "[ " + wallet.name + " ]" : wallet.name + let walletName = isSelected ? "[ " + wallet.name + " ]" : wallet.name let action = AdamantAlertAction( title: walletName, diff --git a/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift b/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift new file mode 100644 index 000000000..68b291993 --- /dev/null +++ b/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift @@ -0,0 +1,9 @@ +// +// SecretWalletsFactory.swift +// Adamant +// +// Created by Dmitrij Meidus on 12.03.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import Foundation diff --git a/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift new file mode 100644 index 000000000..93dcb92b6 --- /dev/null +++ b/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift @@ -0,0 +1,70 @@ +// +// SecretWalletsViewModel.swift +// Adamant +// +// Created by Dmitrij Meidus on 28.02.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import CommonKit +import Combine + +extension String.adamant { + enum AddSecretWallet { + static var title: String { + .localized( + "SecretWallets.AddSecretWallet.Title", + comment: "Secret wallet: add secret wallet title" + ) + } + static var description: String { + .localized( + "SecretWallets.AddSecretWallet.Description", + comment: "Secret wallet: add secret wallet description" + ) + } + static var passwordPlaceholder: String { + .localized( + "SecretWallets.AddSecretWallet.PasswordPlaceholder", + comment: "Secret wallet: add secret wallet description" + ) + } + } +} + +@MainActor +final class SecretWalletsMenuViewModel: ObservableObject { + @Published private(set) var state: SecretWalletsMenuState = .default + + private let secretWalletsManager: SecretWalletsManagerProtocol + private var subscriptions = Set() + + nonisolated init(secretWalletsManager: SecretWalletsManagerProtocol) { + self.secretWalletsManager = secretWalletsManager + + Task{ @MainActor in + setup() + } + } + + private func setup() { + self.state.currentActiveIndex = 0 + self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) + } + + func pickWallet(at index: Int) { + state.currentActiveIndex = index + guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } + secretWalletsManager.activateSecretWallet(at: index - 1) + } + + func createSecretWallet(password: String) { + let index = state.wallets.count + + secretWalletsManager.createSecretWallet(withPassword: password) + secretWalletsManager.activateSecretWallet(at: index - 1) + + state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Secret\(index)", comment: "Secret wallet menu: regular wallet"))) + self.state.currentActiveIndex = index + } +} diff --git a/Adamant/Modules/SecretWallets/SecretWalletsState.swift b/Adamant/Modules/SecretWallets/SecretWalletsState.swift index 97e6aaffd..02b949cf4 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsState.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsState.swift @@ -2,22 +2,25 @@ // SecretWalletsState.swift // Adamant // -// Created by Dmitrij Meidus on 28.02.25. +// Created by Dmitrij Meidus on 12.03.25. // Copyright © 2025 Adamant. All rights reserved. // import Foundation -extension SecretWalletsAlertMenuView { - struct SecretWalletsState: Equatable { - var wallets: [WalletItem] - var currentActiveIndex: Int - - static let `default` = Self(wallets: [], currentActiveIndex: -1) - } +struct SecretWalletsState: Equatable { + var wallets: [WalletItem] + var currentActiveIndex: Int - struct WalletItem: Equatable, Identifiable { - let id = UUID() - let name: String + var currentWallet: WalletItem? { + guard currentActiveIndex >= 0 else { return nil } + return wallets[currentActiveIndex] } + + static let `default` = Self(wallets: [], currentActiveIndex: -1) +} + +struct WalletItem: Equatable, Identifiable { + let id = UUID() + let name: String } diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 5ffd75052..d209e3d29 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -10,40 +10,37 @@ import CommonKit import Combine //TODO: Consider logout - -extension SecretWalletsAlertMenuView { - @MainActor - final class SecretWalletsViewModel: ObservableObject { - @Published private(set) var state: SecretWalletsState = .default - - private let secretWalletsManager: SecretWalletsManagerProtocol - private var subscriptions = Set() - - init(secretWalletsManager: SecretWalletsManagerProtocol) { - self.secretWalletsManager = secretWalletsManager - - setup() - } +@MainActor +final class SecretWalletsViewModel: ObservableObject { + @Published private(set) var state: SecretWalletsState = .default + + private let secretWalletsManager: SecretWalletsManagerProtocol + private var subscriptions = Set() + + init(secretWalletsManager: SecretWalletsManagerProtocol) { + self.secretWalletsManager = secretWalletsManager - private func setup() { - self.state.currentActiveIndex = 0 - self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) - } + setup() + } + + private func setup() { + self.state.currentActiveIndex = 0 + self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) + } + + func pickWallet(at index: Int) { + state.currentActiveIndex = index + guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } + secretWalletsManager.activateSecretWallet(at: index - 1) + } + + func createSecretWallet(password: String) { + let index = state.wallets.count - func pickWallet(at index: Int) { - state.currentActiveIndex = index - guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } - secretWalletsManager.activateSecretWallet(at: index - 1) - } + secretWalletsManager.createSecretWallet(withPassword: password) + secretWalletsManager.activateSecretWallet(at: index - 1) - func createSecretWallet(password: String) { - let index = state.wallets.count - - secretWalletsManager.createSecretWallet(withPassword: password) - secretWalletsManager.activateSecretWallet(at: index - 1) - - state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Secret\(index)", comment: "Secret wallet menu: regular wallet"))) - self.state.currentActiveIndex = index - } + state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Secret\(index)", comment: "Secret wallet menu: regular wallet"))) + self.state.currentActiveIndex = index } } diff --git a/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift b/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift index dec39e087..ef991c9c1 100644 --- a/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift +++ b/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift @@ -63,6 +63,7 @@ final class PKGeneratorViewModel: ObservableObject { func onTap(key: String) { dialogService.presentShareAlertFor( + title: nil, string: key, types: [ .copyToPasteboard, diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift index 702c21a08..14a3208bb 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift @@ -23,6 +23,7 @@ struct AdmWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift index ed7f63e58..447b92ac7 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift @@ -246,6 +246,7 @@ final class AdmWalletViewController: WalletViewControllerBase { let explorerAddressUrl = URL(string: explorerAddress + address) { let encodedAddress = AdamantUriTools.encode(request: AdamantUri.address(address: address, params: nil)) self?.dialogService.presentShareAlertFor( + title: self?.makeTitle(), stringForPasteboard: address, stringForShare: encodedAddress, stringForQR: encodedAddress, @@ -268,7 +269,11 @@ final class AdmWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.wallets.adamant + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + String.adamant.wallets.adamant } func updateRows() { diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift index a575d21f9..6272b2ded 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift @@ -23,6 +23,7 @@ struct BtcWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift index c74711b0f..09fa745cb 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift @@ -14,6 +14,10 @@ extension String.adamant { String.localized("AccountTab.Wallets.bitcoin_wallet", comment: "Account tab: Bitcoin wallet") } + static var secretBitcoin: String { + String.localized("SecretWallets.Bitcoin.Secret", comment: "Secret wallets: Bitcoin") + } + static var sendBtc: String { String.localized("AccountTab.Row.SendBtc", comment: "Account tab: 'Send BTC tokens' button") } @@ -30,6 +34,15 @@ final class BtcWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.bitcoin + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.bitcoin + } else { + return String.adamant.secretBitcoin + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift index 254644865..e5d0ec1a4 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift @@ -23,6 +23,7 @@ struct DashWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift index 552b5f216..ae95599b8 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift @@ -15,6 +15,10 @@ extension String.adamant { String.localized("AccountTab.Wallets.dash_wallet", comment: "Account tab: Dash wallet") } + static var secretDash: String { + String.localized("SecretWallets.Dash.Secret", comment: "Account tab: Dash wallet") + } + static var sendDash: String { String.localized("AccountTab.Row.SendDash", comment: "Account tab: 'Send Dash tokens' button") } @@ -30,6 +34,15 @@ final class DashWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.dash + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.dash + }else { + return String.adamant.secretDash + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift index 0ece9a4e8..707c73371 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift @@ -23,6 +23,7 @@ struct DogeWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift index fe411605e..21372ff21 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift @@ -14,6 +14,10 @@ extension String.adamant { String.localized("AccountTab.Wallets.doge_wallet", comment: "Account tab: Doge wallet") } + static var secretDoge: String { + String.localized("SecretWallets.Doge.Secret", comment: "Secret wallets: Doge") + } + static var sendDoge: String { String.localized("AccountTab.Row.SendDoge", comment: "Account tab: 'Send DOGE tokens' button") } @@ -29,6 +33,15 @@ final class DogeWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.doge + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.doge + } else { + return String.adamant.secretDoge + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift index f77913123..8f71f5d65 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift @@ -23,6 +23,7 @@ struct ERC20WalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift index 050955703..b3b8b9a02 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift @@ -16,6 +16,10 @@ extension String.adamant.wallets { return String(format: .localized("AccountTab.Wallets.erc20_wallet", comment: "Account tab: Ethereum wallet"), token) } + static func secretTokenWallet(_ token: String) -> String { + return String(format: .localized("SecretWallets.erc20_wallet.Secret", comment: "Account tab: Ethereum wallet"), token) + } + static func sendToken(_ token: String) -> String { return String(format: .localized("AccountTab.Row.SendToken", comment: "Account tab: 'Send ERC20 tokens' button"), token) } @@ -30,7 +34,7 @@ final class ERC20WalletViewController: WalletViewControllerBase { let networkFont = currencyFont.withSize(8) let currencyAttributes: [NSAttributedString.Key: Any] = [.font: currencyFont] let networkAttributes: [NSAttributedString.Key: Any] = [.font: networkFont] - + let defaultString = NSMutableAttributedString( string: tokenSymbol, attributes: currencyAttributes @@ -50,6 +54,15 @@ final class ERC20WalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.wallets.erc20.tokenWallet(service?.core.tokenName ?? "") + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.wallets.erc20.tokenWallet(service?.core.tokenName ?? "") + } else { + return String.adamant.wallets.erc20.secretTokenWallet(service?.core.tokenName ?? "") + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift index 51b00bc72..252eef064 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift @@ -23,6 +23,7 @@ struct EthWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift index 9345c01d1..63763158a 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift @@ -14,6 +14,10 @@ extension String.adamant.wallets { String.localized("AccountTab.Wallets.ethereum_wallet", comment: "Account tab: Ethereum wallet") } + static var secretEthereum: String { + String.localized("SecretWallets.Ethereum.Secret", comment: "Account tab: Ethereum wallet") + } + static var sendEth: String { String.localized("AccountTab.Row.SendEth", comment: "Account tab: 'Send ETH tokens' button") } @@ -29,6 +33,15 @@ final class EthWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.wallets.ethereum + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String { + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.wallets.ethereum + } else { + return String.adamant.wallets.secretEthereum + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift index f09d2701a..4197a698d 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift @@ -24,6 +24,7 @@ struct KlyWalletFactory: WalletFactory { accountService: assembler.resolve(AccountService.self)!, screensFactory: screensFactory, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)!, service: service ) } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift index 3a3934c90..5023eb17b 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift @@ -14,6 +14,10 @@ extension String.adamant { String.localized("AccountTab.Wallets.kly_wallet", comment: "Account tab: Klayr wallet") } + static var secretKLY: String { + String.localized("SecretWallets.kly.Secret", comment: "Account tab: Klayr wallet") + } + static var sendKly: String { String.localized("AccountTab.Row.SendKly", comment: "Account tab: 'Send KLY tokens' button") } @@ -29,6 +33,15 @@ final class KlyWalletViewController: WalletViewControllerBase { } override func setTitle() { - walletTitleLabel.text = String.adamant.kly + walletTitleLabel.text = makeTitle() + } + + override func makeTitle() -> String{ + let index = secretWalletsViewModel.state.currentActiveIndex + if index <= 0 { + return String.adamant.secretKLY + } else { + return String.adamant.secretKLY + " \(index)" + } } } diff --git a/Adamant/Modules/Wallets/TransactionDetailsViewControllerBase.swift b/Adamant/Modules/Wallets/TransactionDetailsViewControllerBase.swift index 73bbcd864..1c18d7a74 100644 --- a/Adamant/Modules/Wallets/TransactionDetailsViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransactionDetailsViewControllerBase.swift @@ -1031,7 +1031,7 @@ class TransactionDetailsViewControllerBase: FormViewController { // MARK: - Tools func shareValue(_ value: String, from: UIView) { - dialogService.presentShareAlertFor(string: value, types: [.copyToPasteboard, .share], excludedActivityTypes: nil, animated: true, from: from) { [weak self] in + dialogService.presentShareAlertFor(title: nil, string: value, types: [.copyToPasteboard, .share], excludedActivityTypes: nil, animated: true, from: from) { [weak self] in guard let tableView = self?.tableView else { return } diff --git a/Adamant/Modules/Wallets/TransferViewControllerBase.swift b/Adamant/Modules/Wallets/TransferViewControllerBase.swift index 139d9bdc5..76223e470 100644 --- a/Adamant/Modules/Wallets/TransferViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransferViewControllerBase.swift @@ -1262,7 +1262,7 @@ extension TransferViewControllerBase { return } - dialogService.presentShareAlertFor(string: value, types: [.copyToPasteboard, .share], excludedActivityTypes: nil, animated: true, from: from) { [weak self] in + dialogService.presentShareAlertFor(title: nil, string: value, types: [.copyToPasteboard, .share], excludedActivityTypes: nil, animated: true, from: from) { [weak self] in guard let tableView = self?.tableView else { return } if let indexPath = tableView.indexPathForSelectedRow { diff --git a/Adamant/Modules/Wallets/WalletViewControllerBase.swift b/Adamant/Modules/Wallets/WalletViewControllerBase.swift index b96f0a2b3..26e180eb9 100644 --- a/Adamant/Modules/Wallets/WalletViewControllerBase.swift +++ b/Adamant/Modules/Wallets/WalletViewControllerBase.swift @@ -54,6 +54,7 @@ class WalletViewControllerBase: FormViewController, WalletViewController { let dialogService: DialogService let screensFactory: ScreensFactory + let secretWalletsViewModel: SecretWalletsViewModel var service: WalletService? // MARK: - Properties, WalletViewController @@ -89,6 +90,7 @@ class WalletViewControllerBase: FormViewController, WalletViewController { accountService: AccountService, screensFactory: ScreensFactory, walletServiceCompose: WalletServiceCompose, + secretWalletsViewModel: SecretWalletsViewModel, service: WalletService? ) { self.dialogService = dialogService @@ -96,6 +98,7 @@ class WalletViewControllerBase: FormViewController, WalletViewController { self.accountService = accountService self.screensFactory = screensFactory self.walletServiceCompose = walletServiceCompose + self.secretWalletsViewModel = secretWalletsViewModel self.service = service super.init(nibName: "WalletViewControllerBase", bundle: nil) } @@ -310,6 +313,7 @@ class WalletViewControllerBase: FormViewController, WalletViewController { } self?.dialogService.presentShareAlertFor( + title: self?.makeTitle(), string: address, types: types, excludedActivityTypes: ShareContentType.address.excludedActivityTypes, @@ -322,6 +326,7 @@ class WalletViewControllerBase: FormViewController, WalletViewController { return addressRow } + func makeTitle() -> String { fatalError("Should be overriden") } func setTitle() { } // MARK: - Other diff --git a/Adamant/ServiceProtocols/DialogService.swift b/Adamant/ServiceProtocols/DialogService.swift index 60e7704b1..d49e8c171 100644 --- a/Adamant/ServiceProtocols/DialogService.swift +++ b/Adamant/ServiceProtocols/DialogService.swift @@ -194,8 +194,8 @@ protocol DialogService: AnyObject { // MARK: - ActivityControllers func presentShareAlertFor(adm: String, name: String, types: [AddressChatShareType], animated: Bool, from: UIView?, completion: (() -> Void)?, didSelect: ((AddressChatShareType) -> Void)?) - func presentShareAlertFor(string: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) - func presentShareAlertFor(stringForPasteboard: String, stringForShare: String, stringForQR: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) + func presentShareAlertFor(title: String?, string: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) + func presentShareAlertFor(title: String?, stringForPasteboard: String, stringForShare: String, stringForQR: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) func presentShareAlertFor(string: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIBarButtonItem?, completion: (() -> Void)?) func presentShareAlertFor( string: String, diff --git a/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift b/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift new file mode 100644 index 000000000..721481249 --- /dev/null +++ b/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift @@ -0,0 +1,83 @@ +// +// SecretWalletsFactory.swift +// Adamant +// +// Created by Dmitrij Meidus on 20.02.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import CommonKit +import Swinject + +//TODO: ‼️‼️‼️ Double check wallets initialization and dependencies injection while making the review ‼️‼️‼️ +extension AdamantSecretWalletsManager{ + struct SecretWalletsFactory { + private let visibleWalletsService: VisibleWalletsService + private let accountService: AccountService + private let securedStore: SecuredStore + private let container: Container + + init( + visibleWalletsService: VisibleWalletsService, + accountService: AccountService, + securedStore: SecuredStore, + container: Container + ) { + self.visibleWalletsService = visibleWalletsService + self.accountService = accountService + self.securedStore = securedStore + self.container = container + } + + func makeSecretWallet(withPassword password: String) -> WalletStoreServiceProtocol { + var wallets: [WalletCoreProtocol] = [ + AdmWalletService(), + BtcWalletService(), + EthWalletService(), + KlyWalletService(), + DogeWalletService(), + DashWalletService() + ] + + let erc20WalletServices = ERC20Token.supportedTokens.map { + ERC20WalletService(token: $0) + } + wallets.append(contentsOf: erc20WalletServices) + + let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) + Task { @MainActor in + await injectDependencies(in: walletServiceCompose) + await initWallets(withPass: password, for: walletServiceCompose) + } + + let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) + + return wallet + } + + @MainActor + private func injectDependencies(in walletService: WalletServiceCompose) async { + walletService.getWallets().forEach { wallet in + (wallet.core as? SwinjectDependentService)?.injectDependencies(from: container) + } + } + + private func initWallets(withPass password: String, for walletService: WalletServiceCompose) async { + guard let passphrase: String = securedStore.get(StoreKey.accountService.passphrase) else { + print("No passphrase found") + return + } + + await withTaskGroup(of: Void.self) { taskGroup in + for wallet in walletService.getWallets() { + taskGroup.addTask { + _ = try? await wallet.core.initWallet( + withPassphrase: passphrase, + withPassword: password + ) + } + } + } + } + } +} diff --git a/Adamant/Services/AdmDialogService/AdamantDialogService.swift b/Adamant/Services/AdmDialogService/AdamantDialogService.swift index e39b2b1aa..e2c240ba1 100644 --- a/Adamant/Services/AdmDialogService/AdamantDialogService.swift +++ b/Adamant/Services/AdmDialogService/AdamantDialogService.swift @@ -308,10 +308,10 @@ extension AdamantDialogService { present(alert, animated: animated, completion: completion) } - func presentShareAlertFor(string: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) { + func presentShareAlertFor(title: String? = nil, string: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) { let source: UIAlertController.SourceView? = from.map { .view($0) } - let alert = createShareAlertFor(stringForPasteboard: string, stringForShare: string, stringForQR: string, types: types, excludedActivityTypes: excludedActivityTypes, animated: animated, from: source, completion: completion) + let alert = createShareAlertFor(title: title, stringForPasteboard: string, stringForShare: string, stringForQR: string, types: types, excludedActivityTypes: excludedActivityTypes, animated: animated, from: source, completion: completion) alert.modalPresentationStyle = .overFullScreen present(alert, animated: animated, completion: completion) @@ -326,16 +326,17 @@ extension AdamantDialogService { present(alert, animated: animated, completion: completion) } - func presentShareAlertFor(stringForPasteboard: String, stringForShare: String, stringForQR: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) { + func presentShareAlertFor(title: String?, stringForPasteboard: String, stringForShare: String, stringForQR: String, types: [ShareType], excludedActivityTypes: [UIActivity.ActivityType]?, animated: Bool, from: UIView?, completion: (() -> Void)?) { let source: UIAlertController.SourceView? = from.map { .view($0) } - let alert = createShareAlertFor(stringForPasteboard: stringForPasteboard, stringForShare: stringForShare, stringForQR: stringForQR, types: types, excludedActivityTypes: excludedActivityTypes, animated: animated, from: source, completion: completion) + let alert = createShareAlertFor(title: title, stringForPasteboard: stringForPasteboard, stringForShare: stringForShare, stringForQR: stringForQR, types: types, excludedActivityTypes: excludedActivityTypes, animated: animated, from: source, completion: completion) alert.modalPresentationStyle = .overFullScreen present(alert, animated: animated, completion: completion) } private func createShareAlertFor( + title: String? = nil, stringForPasteboard: String, stringForShare: String, stringForQR: String, @@ -347,7 +348,7 @@ extension AdamantDialogService { didSelect: ((ShareType) -> Void)? = nil ) -> UIAlertController { let alert = UIAlertController( - title: nil, + title: title, message: nil, preferredStyleSafe: .actionSheet, source: from diff --git a/Adamant/Services/SecretWalletsFactory.swift b/Adamant/Services/SecretWalletsFactory.swift deleted file mode 100644 index fee55b566..000000000 --- a/Adamant/Services/SecretWalletsFactory.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// SecretWalletsFactory.swift -// Adamant -// -// Created by Dmitrij Meidus on 20.02.25. -// Copyright © 2025 Adamant. All rights reserved. -// - -import CommonKit -import Swinject - -//TODO: ‼️‼️‼️ Double check wallets initialization and dependencies injection while making the review ‼️‼️‼️ - -struct SecretWalletsFactory { - private let visibleWalletsService: VisibleWalletsService - private let accountService: AccountService - private let securedStore: SecuredStore - private let container: Container - - init( - visibleWalletsService: VisibleWalletsService, - accountService: AccountService, - securedStore: SecuredStore, - container: Container - ) { - self.visibleWalletsService = visibleWalletsService - self.accountService = accountService - self.securedStore = securedStore - self.container = container - } - - func makeSecretWallet(withPassword password: String) -> WalletStoreServiceProtocol { - var wallets: [WalletCoreProtocol] = [ - AdmWalletService(), - BtcWalletService(), - EthWalletService(), - KlyWalletService(), - DogeWalletService(), - DashWalletService() - ] - - let erc20WalletServices = ERC20Token.supportedTokens.map { - ERC20WalletService(token: $0) - } - wallets.append(contentsOf: erc20WalletServices) - - let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) - Task { @MainActor in - await injectDependencies(in: walletServiceCompose) - await initWallets(withPass: password, for: walletServiceCompose) - } - - let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) - - return wallet - } - - @MainActor - private func injectDependencies(in walletService: WalletServiceCompose) async { - walletService.getWallets().forEach { wallet in - (wallet.core as? SwinjectDependentService)?.injectDependencies(from: container) - } - } - - private func initWallets(withPass password: String, for walletService: WalletServiceCompose) async { - guard let passphrase: String = securedStore.get(StoreKey.accountService.passphrase) else { - print("No passphrase found") - return - } - - await withTaskGroup(of: Void.self) { taskGroup in - for wallet in walletService.getWallets() { - taskGroup.addTask { - _ = try? await wallet.core.initWallet( - withPassphrase: passphrase, - withPassword: password - ) - } - } - } - } -} diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 7f760c2aa..5a165c10e 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1397,3 +1397,11 @@ "SecretWallets.Menu.TellMeMore" = "Über Wallets"; "SecretWallets.Menu.Title" = "Aktive Wallets"; "SecretWallets.Row.Title" = "Geheime Geldbörsen"; + +/* Secret Wallets Coins name*/ +"SecretWallets.Bitcoin.Secret" = "Geheime Bitcoin-Wallet"; +"SecretWallets.Doge.Secret" = "Geheime Doge-Wallet"; +"SecretWallets.erc20_wallet.Secret" = "Geheime %@-Wallet"; +"SecretWallets.Dash.Secret" = "Geheime Dash-Wallet"; +"SecretWallets.Ethereum.Secret" = "Geheime Ethereum-Wallet"; +"SecretWallets.kly.Secret" = "Geheime KLY-Wallet"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 0d37fde61..4270cd50a 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1373,3 +1373,11 @@ "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.Title" = "Active wallets"; "SecretWallets.Row.Title" = "Secret wallets"; + +/* Secret Wallets Coins name*/ +"SecretWallets.Bitcoin.Secret" = "Secret Bitcoin Wallet"; +"SecretWallets.Doge.Secret" = "Secret Doge Wallet"; +"SecretWallets.erc20_wallet.Secret" = "Secret %@ Wallet"; +"SecretWallets.Dash.Secret" = "Secret Dash Wallet"; +"SecretWallets.Ethereum.Secret" = "Secret Ethereum Wallet"; +"SecretWallets.kly.Secret" = "Secret KLY Wallet"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index e32d5bbcb..03de67afb 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1374,3 +1374,11 @@ "SecretWallets.Menu.TellMeMore" = "О кошельках"; "SecretWallets.Menu.Title" = "Активные кошельки"; "SecretWallets.Row.Title" = "Секретные кошельки"; + +/* Secret Wallets Coins name*/ +"SecretWallets.Bitcoin.Secret" = "Секретный Bitcoin кошелек"; +"SecretWallets.Doge.Secret" = "Секретный Doge кошелек"; +"SecretWallets.erc20_wallet.Secret" = "Секретный %@ кошелек"; +"SecretWallets.Dash.Secret" = "Секретный Dash кошелек"; +"SecretWallets.Ethereum.Secret" = "Секретный Ethereum кошелек"; +"SecretWallets.kly.Secret" = "Секретный KLY кошелек"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index d13a5f73d..4c7443348 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1364,3 +1364,11 @@ "SecretWallets.Menu.TellMeMore" = "关于钱包"; "SecretWallets.Menu.Title" = "活动钱包"; "SecretWallets.Row.Title" = "秘密钱包"; + +/* Secret Wallets Coins name*/ +"SecretWallets.Bitcoin.Secret" = "比特币秘密钱包"; +"SecretWallets.Doge.Secret" = "狗狗币秘密钱包"; +"SecretWallets.erc20_wallet.Secret" = "秘密 %@ 钱包"; +"SecretWallets.Dash.Secret" = "达世币秘密钱包"; +"SecretWallets.Ethereum.Secret" = "以太坊秘密钱包"; +"SecretWallets.kly.Secret" = "KLY 秘密钱包"; diff --git a/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/Share_button_small.imageset/Share_button.png b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/Share_button_small.imageset/Share_button.png deleted file mode 100644 index ece3149afb874dfea57006def864845693138aff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+i!3HFQj;9L&DaPU;cPEB*=VV?2Ig34A978Mw zlM@c`N;C$kIq)pV8x z91uDo+|(7*dMV3c7W*l+SxuS8RyDF}yy833e=%kK!jFzIx+aE^0UmWMkLG3wB?j1? zNXylb7AZKvkfOKP)Px$FG)l}R9Fe^STPO(K@>$4dbL6!3KyVo1{IA{IDjLFQ)oB{7f=z2sPz(Ly_cQ8 z*=(}A=C9c;%uD{xH~+tR=FMaiYBfE^pfXBDA8Jn%%u7KRDp$nY1arPx$ok>JNRA>e5nbA$eFbswd#2|=87=SlkSc45JhT@rwfS7(Dmt zC6X=qEXR)X-QV0pb%%qU-Pnz`nLJ?ZH=MBxdjKVYk1;ZD+U`L20Z+h;%(>pA<-lJc zByfsNg6F^le2dVGN%^M0B{1_4p&6&@SU#W40R;8smea~bKhBvs?nz`U~x+6)T`}HJ-f$%6E)~f zKwGcJro-26cIdUrE#23p(pUJFFY%kcBhr`H(~@S7aP{gTPa;2-vsSI+MTTSmb%hr(u%?Po69X~gQ&NZl5aHr!^Hpdy0R|s Z^bgamb@9TM+MNIZ002ovPDHLkV1ixe>qYuiOs});AJM;X~?_Z%zQJm3ltO-6#Q>=I-NPu4NL=SrY8C% zI_mT};NK7u@`J0QNK{t?SY{qcOwGts7~St^xoB7+%>8Fn=oGm*-LW*RVtSU=AB$~`R^^{NMV=-cD;zV{%rMc(;<2bMYD?rUr8OGJ+=wQEQNk{{ul2iPF!nX_ zc1x$LMOt?`>qIb0?9H5q`F*jkQO}$jT7xk}GigcEb~$V2w(6o-mEWHH%oMTBO1E2b zRUk#p^N%!g1>q5k9+bF3fEk>`M#Xlu_b^eh)AyuP5iMzbljaU!rtjA(OLEZOgE1Qd z8>)60{k+t08Z9L1p%^1Jk5*}}r5_eBWpK9K5j__zir%HPt0NpLwo=m7#xBgHaXrz9 z6Uj#e3?tVRab?ZC#_0LhejgAHOkLf)JHsu5M2`j|z34MnLpbyn6=l7!qvax|2x~6Z zl8$FFC3M%8(lwjXHSM@t#_2Kk0|AoU6|ieQf$5sAxvL0}q`4Tz+=}Rh(=Mb5h1(z= zBK0?`y5%|2k6cSK8QMH|8R5{&&vrtAo+8DG2EkKyKL6Bm2~&V;Zd*$(qJvKfC(P+V z3%e(c%_DHio@-4lmk~I=(=X<`24R<_3jp z*0JsKeW}1*in;toAY?tC`v(8xsfP%Ja>n0c1WuMYdn!gY5C)v=o@%|B`S4L+hj@uF zS;}G7v;xKAuy}nUUP*5-we*ufi4T9jn?CJmj002ovPDHLk FV1k=ysE7an literal 0 HcmV?d00001 diff --git a/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/secret_wallets_regular.imageset/secure_wallet_badge_regular@2x.png b/CommonKit/Sources/CommonKit/Assets/Shared.xcassets/Buttons/secret_wallets_regular.imageset/secure_wallet_badge_regular@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4b3cb3ce1a0c3d2c206a35b99adabee0669f8862 GIT binary patch literal 1780 zcmVDg|00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yPQ21JHSM9FahiY$I_O0X3Jd_5QJI_nAF{dwCR*39yS^RmSwyXBk{QRcm z`ky58!kmG6-Z`nsDVYOID1=yj2@8b~2SVk7m5F8Zy9|p5Z+}+>{8wslBE>V_mDgN& z4axBSluWE$^K%_`9p|pA)e4^{B5WG5kYFIu=*w}D>_eVt-R z2A%c1^thvuXNJDs1#vK5Aq+yaSJE!{JvR!+m!&415wD>{10MBUvKv`96o&lnqIicL znmQ#z)L}D%M59R%GGAKf?yGp~5=c~@*I=Rnp`Oe1y=xNq;NU}4%sOj@&Y6nWaH3JQ z=9(q=Fcrl^V|!7(??3{Wdf03z(a6*IX(Sp=f>znj*14N1-lhc5y5|)_;rnW9GW(iq zmgFT!v1CB#+>`)X@w^k3Xf(}ZwQGgr1NFQ!5B)^Yv5%un{%CWvb19p^Vyyqmdrdor5tL#Q8Rd`AP*8}>{vuD>f3u1T({ zeIuhza^{ptP?oJXzB4w78`d$r?Y5An!TJ|CgWVHd?TNdS|47Pt$2xv0q%B;_GL|8p zUB88nR}7WyGID<*o;{a@M1<*o2Y`5qP?J zO=px0RqMAGa4-M>j{^rlr z=}mag?zXU4kBmv;CDw61yG|lul6ah5kDRgMadtg^dL{4MCBp?F(NHFy9Xj(?8Hs>0 z@i@C4F%!ibGwyLUbtIH|9<2$)+3?eAJ0P#K-&RiT(DQu3JU9Sqhx7Wln3N*&Q z7IH+@F%RrW7Irwvsr z;k(mqBGopRbJ69Ey`#h@Y=Y2nkFRlZza`n27gIwU8?tqJ zsba|P?)Dc^%0P`55b<2I>ywCiSNBe5z}{gK ztuh_=AYi}ZAHfa!M6xznOdS$559Uie1IE3+$Mq<%efKgWC4_`ckO-MMLE??s=8?3^ zNSPJtc_6Wlxiq3ZT)Ph+)DiC=>lk&@Eg?+<(H=X_C&3RtG|$Z2bG(&5#+ow#^?6US z^+NWyvj#eJovZcaN)-?f#qjC2kY>29;%(Iln_yi69@d{9lhu4`H99J_-h_(vnJV7nOB4~0R$UJ))aXd`aE?)2qA{B=6((8$000041^@s6P>A$*00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP4v2 zjZ`iM9#%`$VLT=Ne$sMR%imf~Yk4Jdul@OZTJ|LaYRnB`&9ic5vgrR6Iv{}259L#;8Nlne;w8fh3Uh%;G)(Z2Vt6)kvm2*1(tM~9y|spSU= zhx43D=5K*(h1QtoBr$^NEaRZ%R#kqIG``gGQsCN?sYmBD zv5oyXp~^uE(WeyYj8~xqABkn)1bwISoaf$3|dmK ze&)%B&y!CZQDZh(X`W}*_uf(rTD;lc?R>-Mwj_E+!+A#%A()k=K})JRMU!LD;>rGw z=L6SfT9O5GvQ2qaE6(KK=6P5Atz*#Q$yS1X4qQt*Z8WK1W|~u6_n^hwFVegUlypJM*UDj_8g-{}`nU?#Sx4qR1M}k?6sx6RvGG0As0oq(%4d;=jTrb|1;d>aH z<`hG_pMfTi&qaDXDzBRFzM+h*wAeGrgc5yR)f}F+k^7?>vueWcclg1&dA1NU|EXY#+A6I( z8qBkGFw4mQ=;NyN5nH+{S{Z8&mhoL=k=LJ}Ux{rA?aNXvcSXM-K^;&tM<=wzNuZrK?<8xZx5g{3A5yNG}x3Lc(aykz8XiTb3tTH%D@@qpoe* zsA=$BB{1uva20y(H6|uVF)}2gk+*`MzelqS(X;gS;OUed9u$5ZoHlu zHOo$LhNjCa`#g8GTPTMd1dHus^O(V4b~%PH*3V=Bgd|#n$*y*+L)U{_W4qcJ1i@X` zU>1>UY=eV4k6^Mq33r`>$)Q`wtP}j-2|w=ZCY} zkwxEN7LjXAw!=-|V6r@kEP4gAnl_pTE;G>%H$&bf$)Q_FZb&d=%{jFuTnq_jY*#xq zCS3FmX3Nu)9J&P;L*G|^Gjff|c8oSOn6Z8)>*g43P%x`q?JQ3snJy2bg@g{>@?w3} zl&eX9X}K%I4hKVGV}e;ox?tMVa|e>1J$n41jDJlGoDJ<`ny)1d+Ypi?l*Vf1kA#_o zjWalyExX#s$lXV^P_i(vVaC*$=118Me+f3q*kBgo&)zlJ=h&ICc#Yr&8WqfzUF}0z zDBqMkqvZ$HpM?!GW>j7)w7f39?rC{J(!P$`LdjIohVlre^)tPLS-U5gq_KTWlWN)s z6E-@SEr)IagLu@K=B5CSyn;z{4p$z7A5-sYKP5hFBz{r0bElF`=6@!v&quigv*oPz zA%2kUJwU!A>}ubW#mlO;b)Tf|pkhZ;gm*A) zKJ%*hxFJlbOqOd?o^V$?CdRvuX|`ooJJu*gFbe@jat~&;t38CL5mAd~Aw`X8=7G;S zr31CtjLV%=!3^~?qpt$SWVGdAo+_9{Qlx1n#-|kC% z8=Os`+axo~a?@aa%4cP99#yP=`GE%WN|In24d=doxgSNa45FS)RHwSenP0||EXsx-cUkKe0ty!Wh@PXst> zE{i_p{_2I~HRiIa_T1O Date: Thu, 13 Mar 2025 19:14:26 +0700 Subject: [PATCH 09/36] [trello.com/c/vawidi4o] Remove unnecessary files --- Adamant.xcodeproj/project.pbxproj | 10 ++- .../SecretWallets/AddSecretWalletView.swift | 45 ------------ .../SecretWallets/SecretWalletsFactory.swift | 9 --- .../SecretWalletsMenuViewModel.swift | 70 ------------------- 4 files changed, 4 insertions(+), 130 deletions(-) delete mode 100644 Adamant/Modules/SecretWallets/AddSecretWalletView.swift delete mode 100644 Adamant/Modules/SecretWallets/SecretWalletsFactory.swift delete mode 100644 Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 0d76b8e5a..949331c4c 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -267,16 +267,16 @@ 64F085D920E2D7600006DE68 /* AdmTransactionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F085D820E2D7600006DE68 /* AdmTransactionsViewController.swift */; }; 64FA53CD20E1300B006783C9 /* EthTransactionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FA53CC20E1300A006783C9 /* EthTransactionsViewController.swift */; }; 64FA53D120E24942006783C9 /* TransactionDetailsViewControllerBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FA53D020E24941006783C9 /* TransactionDetailsViewControllerBase.swift */; }; + 6F030E1C2D4C0E950077ACA2 /* EthBIP32Service.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F030E1B2D4C0E770077ACA2 /* EthBIP32Service.swift */; }; 6FB686162D3AAE8800CAB6DD /* AdamantWalletsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6FB686152D3AAE8800CAB6DD /* AdamantWalletsKit */; }; 6FB686182D3AB9E200CAB6DD /* SmartTokenInfoProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB686172D3AB9E200CAB6DD /* SmartTokenInfoProtocol.swift */; }; 6FB6861A2D3ABA1400CAB6DD /* WalletStaticCoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB686192D3ABA1400CAB6DD /* WalletStaticCoreProtocol.swift */; }; 6FB6861C2D3ABE0200CAB6DD /* DashWalletService+Transactions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB6861B2D3ABE0200CAB6DD /* DashWalletService+Transactions.swift */; }; - 6F030E1C2D4C0E950077ACA2 /* EthBIP32Service.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F030E1B2D4C0E770077ACA2 /* EthBIP32Service.swift */; }; 6FCF2D522D54F2B600F64D20 /* AdmDialogService+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCF2D502D54F2B600F64D20 /* AdmDialogService+Extension.swift */; }; 6FCF2D532D54F2B600F64D20 /* AdamantDialogService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCF2D4F2D54F2B600F64D20 /* AdamantDialogService.swift */; }; 6FF9F08C2D6CEB340013A3B1 /* CoreDataRealationMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF9F08B2D6CEB150013A3B1 /* CoreDataRealationMapper.swift */; }; - 85ACCA662D68DC57005658CE /* ChatMessagesSortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85ACCA652D68DC52005658CE /* ChatMessagesSortDescriptor.swift */; }; 851FF2762D7B3E6B00276625 /* ChatViewController+NavigationControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851FF2752D7B3E5B00276625 /* ChatViewController+NavigationControllerDelegate.swift */; }; + 85ACCA662D68DC57005658CE /* ChatMessagesSortDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85ACCA652D68DC52005658CE /* ChatMessagesSortDescriptor.swift */; }; 85B405022D3012D5000AB744 /* AccountViewController+Form.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B405012D3012C7000AB744 /* AccountViewController+Form.swift */; }; 9300F94629D0149100FEDDB8 /* RichMessageProviderWithStatusCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9300F94529D0149100FEDDB8 /* RichMessageProviderWithStatusCheck.swift */; }; 9304F8BE292F88F900173F18 /* ANSPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9304F8BD292F88F900173F18 /* ANSPayload.swift */; }; @@ -1003,16 +1003,16 @@ 64F085D820E2D7600006DE68 /* AdmTransactionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdmTransactionsViewController.swift; sourceTree = ""; }; 64FA53CC20E1300A006783C9 /* EthTransactionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthTransactionsViewController.swift; sourceTree = ""; }; 64FA53D020E24941006783C9 /* TransactionDetailsViewControllerBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionDetailsViewControllerBase.swift; sourceTree = ""; }; + 6F030E1B2D4C0E770077ACA2 /* EthBIP32Service.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthBIP32Service.swift; sourceTree = ""; }; 6FB686172D3AB9E200CAB6DD /* SmartTokenInfoProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartTokenInfoProtocol.swift; sourceTree = ""; }; 6FB686192D3ABA1400CAB6DD /* WalletStaticCoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletStaticCoreProtocol.swift; sourceTree = ""; }; 6FB6861B2D3ABE0200CAB6DD /* DashWalletService+Transactions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DashWalletService+Transactions.swift"; sourceTree = ""; }; - 6F030E1B2D4C0E770077ACA2 /* EthBIP32Service.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthBIP32Service.swift; sourceTree = ""; }; 6FCF2D4F2D54F2B600F64D20 /* AdamantDialogService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantDialogService.swift; sourceTree = ""; }; 6FCF2D502D54F2B600F64D20 /* AdmDialogService+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdmDialogService+Extension.swift"; sourceTree = ""; }; 6FF9F08B2D6CEB150013A3B1 /* CoreDataRealationMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataRealationMapper.swift; sourceTree = ""; }; 74D5744703A7ECC98E244B14 /* Pods-AdmCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AdmCore.debug.xcconfig"; path = "Target Support Files/Pods-AdmCore/Pods-AdmCore.debug.xcconfig"; sourceTree = ""; }; - 85ACCA652D68DC52005658CE /* ChatMessagesSortDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessagesSortDescriptor.swift; sourceTree = ""; }; 851FF2752D7B3E5B00276625 /* ChatViewController+NavigationControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatViewController+NavigationControllerDelegate.swift"; sourceTree = ""; }; + 85ACCA652D68DC52005658CE /* ChatMessagesSortDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessagesSortDescriptor.swift; sourceTree = ""; }; 85B405012D3012C7000AB744 /* AccountViewController+Form.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountViewController+Form.swift"; sourceTree = ""; }; 9300F94529D0149100FEDDB8 /* RichMessageProviderWithStatusCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RichMessageProviderWithStatusCheck.swift; sourceTree = ""; }; 9304F8BD292F88F900173F18 /* ANSPayload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ANSPayload.swift; sourceTree = ""; }; @@ -1840,7 +1840,6 @@ 6403F5E322723F8C00D58779 /* DashWalletService.swift */, 93B28EC12B076D31007F268B /* DashApiService.swift */, AAC641502D42D67700619DFE /* DashApiServiceProtocol.swift */, - A578BDE42623051C00090141 /* DashWalletService+Transactions.swift */, 648CE3A5229AD1CD0070A2CC /* DashWalletService+Send.swift */, 648CE3A7229AD1E20070A2CC /* DashWalletService+RichMessageProvider.swift */, 648CE3A9229AD1F90070A2CC /* DashWalletService+RichMessageProviderWithStatusCheck.swift */, @@ -1896,7 +1895,6 @@ 93CCAE782B06D81D00EA5B94 /* DogeApiService.swift */, AAB01CB02D3AF015007D6BF4 /* DogeApiServiceProtocol.swift */, AAB01CB42D3AF278007D6BF4 /* DogeInternalApiProtocol.swift */, - 4186B337294200E8006594A3 /* DogeWalletService+DynamicConstants.swift */, 648DD7A32237DB9E00B811FD /* DogeWalletService+Send.swift */, 648DD7A72239147800B811FD /* DogeWalletService+RichMessageProvider.swift */, 648DD7A92239150E00B811FD /* DogeWalletService+RichMessageProviderWithStatusCheck.swift */, diff --git a/Adamant/Modules/SecretWallets/AddSecretWalletView.swift b/Adamant/Modules/SecretWallets/AddSecretWalletView.swift deleted file mode 100644 index f4021c25f..000000000 --- a/Adamant/Modules/SecretWallets/AddSecretWalletView.swift +++ /dev/null @@ -1,45 +0,0 @@ -import SwiftUI -import CommonKit - -struct AddSecretWalletView: View { - private var viewModel: SecretWalletsMenuViewModel - @Binding private var password: String - - var body: some View { - VStack { - - } - .background(Color(.adamant.secondBackgroundColor)) - .navigationTitle(String.adamant.AddSecretWallet.title) - .navigationBarTitleDisplayMode(.inline) - } - - init(viewModel: SecretWalletsMenuViewModel) { - self.viewModel = viewModel - self._password = Binding.constant("") - } -} - -private extension AddSecretWalletView { - var inputSection: some View { - Section { - Group { - Text(String.adamant.AddSecretWallet.description) - .multilineTextAlignment(.center) - .padding(.vertical, 5) - - AdamantSecureField( - placeholder: .adamant.AddSecretWallet.passwordPlaceholder, - text: $password - ) - - Button(action: { viewModel.createSecretWallet(password: password) }) { - Text(String.adamant.pkGenerator.generateButton) - .foregroundStyle(Color(uiColor: .adamant.primary)) - .padding(.horizontal, 30) - .expanded(axes: .horizontal) - } - }.listRowBackground(Color(uiColor: .adamant.cellColor)) - } - } -} diff --git a/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift b/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift deleted file mode 100644 index 68b291993..000000000 --- a/Adamant/Modules/SecretWallets/SecretWalletsFactory.swift +++ /dev/null @@ -1,9 +0,0 @@ -// -// SecretWalletsFactory.swift -// Adamant -// -// Created by Dmitrij Meidus on 12.03.25. -// Copyright © 2025 Adamant. All rights reserved. -// - -import Foundation diff --git a/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift deleted file mode 100644 index 93dcb92b6..000000000 --- a/Adamant/Modules/SecretWallets/SecretWalletsMenuViewModel.swift +++ /dev/null @@ -1,70 +0,0 @@ -// -// SecretWalletsViewModel.swift -// Adamant -// -// Created by Dmitrij Meidus on 28.02.25. -// Copyright © 2025 Adamant. All rights reserved. -// - -import CommonKit -import Combine - -extension String.adamant { - enum AddSecretWallet { - static var title: String { - .localized( - "SecretWallets.AddSecretWallet.Title", - comment: "Secret wallet: add secret wallet title" - ) - } - static var description: String { - .localized( - "SecretWallets.AddSecretWallet.Description", - comment: "Secret wallet: add secret wallet description" - ) - } - static var passwordPlaceholder: String { - .localized( - "SecretWallets.AddSecretWallet.PasswordPlaceholder", - comment: "Secret wallet: add secret wallet description" - ) - } - } -} - -@MainActor -final class SecretWalletsMenuViewModel: ObservableObject { - @Published private(set) var state: SecretWalletsMenuState = .default - - private let secretWalletsManager: SecretWalletsManagerProtocol - private var subscriptions = Set() - - nonisolated init(secretWalletsManager: SecretWalletsManagerProtocol) { - self.secretWalletsManager = secretWalletsManager - - Task{ @MainActor in - setup() - } - } - - private func setup() { - self.state.currentActiveIndex = 0 - self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) - } - - func pickWallet(at index: Int) { - state.currentActiveIndex = index - guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } - secretWalletsManager.activateSecretWallet(at: index - 1) - } - - func createSecretWallet(password: String) { - let index = state.wallets.count - - secretWalletsManager.createSecretWallet(withPassword: password) - secretWalletsManager.activateSecretWallet(at: index - 1) - - state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Secret\(index)", comment: "Secret wallet menu: regular wallet"))) - self.state.currentActiveIndex = index - } -} From 1c90f5ac5d091cd23bc39b4db93d63ff5dc668c9 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 14 Mar 2025 12:31:58 +0700 Subject: [PATCH 10/36] [trello.com/c/vawidi4o] Setting secret wallet icon displaying. --- .../xcshareddata/swiftpm/Package.resolved | 4 +- Adamant/Modules/Account/AccountHeader.xib | 4 +- .../Modules/Account/AccountHeaderView.swift | 42 ++++++++++++------- .../Helpers/UIHelpers/UIColor+adamant.swift | 7 ++++ 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Adamant.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Adamant.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4c9dca0d0..50471f920 100644 --- a/Adamant.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Adamant.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -39,10 +39,10 @@ }, { "package": "CryptoSwift", - "repositoryURL": "https://github.com/ChrisBenua/CryptoSwift", + "repositoryURL": "https://github.com/Adamant-im/CryptoSwift.git", "state": { "branch": null, - "revision": "f0ea2cac7983c4a808cade78743b391726ecc0ea", + "revision": "ae1cc15340ddf0f607981f9118fe80d7fd7cd2b5", "version": null } }, diff --git a/Adamant/Modules/Account/AccountHeader.xib b/Adamant/Modules/Account/AccountHeader.xib index e55f07d31..ddd29b4e6 100644 --- a/Adamant/Modules/Account/AccountHeader.xib +++ b/Adamant/Modules/Account/AccountHeader.xib @@ -54,7 +54,7 @@ - + @@ -64,11 +64,11 @@ + - diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index ed3def2c6..b9e7ceb7e 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -21,7 +21,8 @@ final class AccountHeaderView: UIView { @IBOutlet weak var addressButton: UIButton! @IBOutlet weak var walletViewContainer: UIView! @IBOutlet weak var secretWalletsImageView: UIImageView! - private var outlineLayer: CAShapeLayer? + + private var circularBackgroundView: UIView? weak var delegate: AccountHeaderViewDelegate? @@ -34,6 +35,20 @@ final class AccountHeaderView: UIView { setupGestureRecognizers() } + override func layoutSubviews() { + super.layoutSubviews() + guard let bgView = circularBackgroundView else { return } + + let iconFrame = secretWalletsImageView.frame + let bgWidth = iconFrame.width * 2 + let bgHeight = iconFrame.height * 2 + bgView.frame = CGRect(x: iconFrame.midX - bgWidth / 2, + y: iconFrame.midY - bgHeight / 2, + width: bgWidth, + height: bgHeight) + bgView.layer.cornerRadius = bgWidth / 2 + } + func setWalletIcon(_ icon: WalletIcon, badgeCount: Int) { secretWalletsImageView.tintColor = .adamant.secondary secretWalletsImageView.image = .asset(named: icon.rawValue)?.withRenderingMode(.alwaysTemplate) ?? .init() @@ -48,19 +63,6 @@ final class AccountHeaderView: UIView { animateOutline() delegate?.walletsButtonTapped(from: secretWalletsImageView) } - - override func layoutSubviews() { - super.layoutSubviews() - - guard let outlineLayer = outlineLayer else { return } - guard !secretWalletsImageView.frame.isEmpty else { return } - - let imageView = secretWalletsImageView! - let center = imageView.center - let radius = imageView.bounds.width - let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true) - outlineLayer.path = path.cgPath - } } private extension AccountHeaderView { @@ -79,7 +81,15 @@ private extension AccountHeaderView { } private func addPersistentOutline() { + let bgView = UIView() + bgView.backgroundColor = UIColor { traitCollection in + return traitCollection.userInterfaceStyle == .dark + ? .adamant.secondary + : UIColor.black + } + secretWalletsImageView.superview?.insertSubview(bgView, belowSubview: secretWalletsImageView) + self.circularBackgroundView = bgView } private func animateOutline() { @@ -87,8 +97,8 @@ private extension AccountHeaderView { } } -extension AccountHeaderView{ - enum WalletIcon: String{ +extension AccountHeaderView { + enum WalletIcon: String { case regular = "secret_wallets_regular" case secret = "secret_wallets_active" diff --git a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift index c775b2100..00c79f233 100644 --- a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift +++ b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift @@ -271,5 +271,12 @@ extension UIColor { // Outcome transfer icon background, light red public static let transferOutcomeIconBackground = #colorLiteral(red: 0.9411764706, green: 0.5215686275, blue: 0.5294117647, alpha: 1) //#F08587 + + // MARK: Secret Wallets + public static var secretWalletButtonBackground: UIColor { + let colorWhiteTheme = #colorLiteral(red: 0.9450980392, green: 0.9450980392, blue: 0.9647058824, alpha: 1) //#F1F1F6 + let colorDarkTheme = UIColor.white.withAlphaComponent(0.3) + return returnColorByTheme(colorWhiteTheme: colorWhiteTheme, colorDarkTheme: colorDarkTheme) + } } } From a4d95c19e64a79c0764a3cd8738f77c86aca20a7 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 14 Mar 2025 17:31:43 +0700 Subject: [PATCH 11/36] [trello.com/c/vawidi4o] Remove secret wallets storing in KVS --- Adamant/Modules/Wallets/Adamant/AdmWalletService.swift | 2 +- Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift | 3 ++- Adamant/Modules/Wallets/Dash/DashWalletService.swift | 4 +++- Adamant/Modules/Wallets/Doge/DogeWalletService.swift | 4 +++- Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift | 2 +- Adamant/Modules/Wallets/Ethereum/EthWalletService.swift | 4 +++- .../Wallets/Klayr/WalletService/KlyWalletService.swift | 8 +++++--- .../Wallets/WalletsService/WalletCoreProtocol.swift | 2 +- Adamant/Services/AdamantAccountService.swift | 3 ++- ...AdamantSecretWalletsManager+SecretWalletsFactory.swift | 4 ++-- 10 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift index 055935bcf..fd0c6f329 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift @@ -225,7 +225,7 @@ final class AdmWalletService: NSObject, WalletCoreProtocol, WalletStaticCoreProt .init(sentDate: nil, status: .notInitiated) } - func initWallet(withPassphrase: String, withPassword: String) async throws -> WalletAccount { + func initWallet(withPassphrase: String, withPassword: String, storeInKVC: Bool) async throws -> WalletAccount { throw InternalAPIError.unknownError } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift index e7478210e..48865345a 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift @@ -445,7 +445,7 @@ extension BtcWalletService { btcWallet = nil } - func initWallet(withPassphrase passphrase: String, withPassword password: String) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -483,6 +483,7 @@ extension BtcWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + guard storeInKVC else { return eWallet } // MARK: 4. Save address into KVS let service = self do { diff --git a/Adamant/Modules/Wallets/Dash/DashWalletService.swift b/Adamant/Modules/Wallets/Dash/DashWalletService.swift index 8c4383415..b007fcc4c 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletService.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletService.swift @@ -300,7 +300,7 @@ extension DashWalletService { } @MainActor - func initWallet(withPassphrase passphrase: String, withPassword password: String) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -340,6 +340,8 @@ extension DashWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + guard storeInKVC else { return eWallet } + // MARK: 4. Save address into KVS do { let address = try await getWalletAddress(byAdamantAddress: adamant.address) diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift index 6dca6d239..ea0968c17 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift @@ -319,7 +319,7 @@ extension DogeWalletService { dogeWallet = nil } - func initWallet(withPassphrase passphrase: String, withPassword password: String) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -358,6 +358,8 @@ extension DogeWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + guard storeInKVC else { return eWallet } + // MARK: 4. Save address into KVS let service = self do { diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift index d7bd45e9a..ec492a7b2 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift @@ -368,7 +368,7 @@ final class ERC20WalletService: WalletCoreProtocol, @unchecked Sendable { // MARK: - WalletInitiatedWithPassphrase extension ERC20WalletService { - func initWallet(withPassphrase passphrase: String, withPassword password: String) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { // MARK: 1. Prepare setState(.notInitiated) diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index 3a545fbde..a4a371275 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -403,7 +403,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar // MARK: - WalletInitiatedWithPassphrase extension EthWalletService { - func initWallet(withPassphrase passphrase: String, withPassword password: String) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { guard let adamant = accountService?.account else { throw WalletServiceError.notLogged } @@ -444,6 +444,8 @@ extension EthWalletService { NotificationCenter.default.post(name: serviceEnabledChanged, object: self) } + guard storeInKVC else { return eWallet } + // MARK: 4. Save into KVS let service = self do { diff --git a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift index 30f23eb08..48e60a509 100644 --- a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift +++ b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift @@ -99,9 +99,9 @@ final class KlyWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @unc // MARK: - func initWallet( - withPassphrase passphrase: String, withPassword password: String + withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool ) async throws -> WalletAccount { - try await initWallet(passphrase: passphrase, password: password) + try await initWallet(passphrase: passphrase, password: password, storeInKVC: storeInKVC) } func setInitiationFailed(reason: String) { @@ -413,7 +413,7 @@ private extension KlyWalletService { // MARK: - Init Wallet private extension KlyWalletService { - func initWallet(passphrase: String, password: String) async throws -> WalletAccount { + func initWallet(passphrase: String, password: String, storeInKVC: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -465,6 +465,8 @@ private extension KlyWalletService { throw WalletServiceError.accountNotFound } + guard storeInKVC else { return eWallet } + // Save into KVS do { diff --git a/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift b/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift index e982e6c5c..679e1ad33 100644 --- a/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift +++ b/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift @@ -305,7 +305,7 @@ protocol WalletCoreProtocol: AnyObject, Sendable { func updateStatus(for id: String, status: TransactionStatus?) func isExist(address: String) async throws -> Bool func statusInfoFor(transaction: CoinTransaction) async -> TransactionStatusInfo - func initWallet(withPassphrase: String, withPassword: String) async throws -> WalletAccount + func initWallet(withPassphrase: String, withPassword: String, storeInKVC: Bool) async throws -> WalletAccount func setInitiationFailed(reason: String) func shortDescription(for transaction: RichMessageTransaction) -> NSAttributedString func getFee(comment: String) -> Decimal diff --git a/Adamant/Services/AdamantAccountService.swift b/Adamant/Services/AdamantAccountService.swift index 5f9047cc4..1d65a2d79 100644 --- a/Adamant/Services/AdamantAccountService.swift +++ b/Adamant/Services/AdamantAccountService.swift @@ -423,7 +423,8 @@ extension AdamantAccountService { group.addTask { let result = try? await wallet.core.initWallet( withPassphrase: passphrase, - withPassword: .empty + withPassword: .empty, + storeInKVC: true ) return result } diff --git a/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift b/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift index 721481249..380e48839 100644 --- a/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift +++ b/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift @@ -9,7 +9,6 @@ import CommonKit import Swinject -//TODO: ‼️‼️‼️ Double check wallets initialization and dependencies injection while making the review ‼️‼️‼️ extension AdamantSecretWalletsManager{ struct SecretWalletsFactory { private let visibleWalletsService: VisibleWalletsService @@ -73,7 +72,8 @@ extension AdamantSecretWalletsManager{ taskGroup.addTask { _ = try? await wallet.core.initWallet( withPassphrase: passphrase, - withPassword: password + withPassword: password, + storeInKVC: false ) } } From aa0c2e36cc14e6119803ea01e5b22850aaabb20f Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 14 Mar 2025 16:35:18 +0700 Subject: [PATCH 12/36] [trello.com/c/MItbYG4c] Update PK generation for Secret wallets --- Adamant.xcodeproj/project.pbxproj | 8 +- .../PKGenerator/PKGeneratorState.swift | 6 +- .../PKGenerator/PKGeneratorView.swift | 25 +++++- .../PKGenerator/PKGeneratorViewModel.swift | 53 +++++++---- .../Settings/PrivateKeyGenerator.swift | 2 +- .../Settings/QRGeneratorViewController.swift | 6 ++ .../Wallets/Bitcoin/BtcWalletService.swift | 4 +- .../Wallets/Dash/DashWalletService.swift | 4 +- .../Wallets/Doge/DogeWalletService.swift | 4 +- .../Wallets/Ethereum/EthWalletService.swift | 87 +++++++++---------- .../KlyWalletService+WalletCore.swift | 4 +- .../Localization/de.lproj/Localizable.strings | 6 ++ .../Localization/en.lproj/Localizable.strings | 6 ++ .../Localization/ru.lproj/Localizable.strings | 6 ++ .../Localization/zh.lproj/Localizable.strings | 6 ++ 15 files changed, 151 insertions(+), 76 deletions(-) diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 949331c4c..983e89a43 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -183,12 +183,12 @@ 41E3C9CC2A0E20F500AF0985 /* AdamantCoinTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */; }; 48023DEF2D72EA7F00852961 /* AccountHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48023DEE2D72EA7F00852961 /* AccountHeader.xib */; }; 48023DF12D72FB3500852961 /* SecretWalletsAlertMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */; }; - 4803FC9A2D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */; }; 481558702D65A7660011B470 /* SecretWalletsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */; }; 481558722D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */; }; 48B6A8EB2D5738D800326EE8 /* WalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */; }; 48B6A8ED2D57390400326EE8 /* AdamantWalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */; }; 48B6A8EF2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */; }; + 48B799A82D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */; }; 48C034F92D81560800F50E35 /* SecretWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034F82D81560800F50E35 /* SecretWalletsState.swift */; }; 48C034FF2D81587800F50E35 /* SecretWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */; }; 48DA2FCF2D4A0519008F9FC1 /* AccountWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */; }; @@ -917,12 +917,12 @@ 41E3C9CB2A0E20F500AF0985 /* AdamantCoinTools.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantCoinTools.swift; sourceTree = ""; }; 48023DEE2D72EA7F00852961 /* AccountHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountHeader.xib; sourceTree = ""; }; 48023DF02D72FB3500852961 /* SecretWalletsAlertMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsAlertMenuView.swift; sourceTree = ""; }; - 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdamantSecretWalletsManager+SecretWalletsFactory.swift"; sourceTree = ""; }; 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManager.swift; sourceTree = ""; }; 481558712D65A7BD0011B470 /* SecretWalletsManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsManagerProtocol.swift; sourceTree = ""; }; 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsStoreService.swift; sourceTree = ""; }; 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletsStoreService.swift; sourceTree = ""; }; 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletStoreServiceProvider.swift; sourceTree = ""; }; + 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdamantSecretWalletsManager+SecretWalletsFactory.swift"; sourceTree = ""; }; 48C034F82D81560800F50E35 /* SecretWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsState.swift; sourceTree = ""; }; 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsViewModel.swift; sourceTree = ""; }; 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWalletsViewModel.swift; sourceTree = ""; }; @@ -2645,7 +2645,7 @@ 41047B75294C62710039E956 /* AdamantVisibleWalletsService.swift */, 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */, 4153045829C09902000E4BEA /* AdamantIncreaseFeeService.swift */, - 4803FC992D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */, + 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */, 4184F1722A33102800D7B8B9 /* AdamantCrashlysticsService.swift */, 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */, 3A9015A62A614A62002A2464 /* AdamantEmojiService.swift */, @@ -3637,7 +3637,6 @@ E9960B3621F5154300C840A8 /* DummyAccount+CoreDataProperties.swift in Sources */, 3AFE7E432B19E4D900718739 /* WalletServiceCompose.swift in Sources */, 3A26D93D2C3C1CC3003AD832 /* KlyNodeApiService.swift in Sources */, - 4803FC9A2D6715AF00452D2C /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */, 93A118512993167500E144CC /* ChatMessageBackgroundColor.swift in Sources */, 93760BD72C656CF8002507C3 /* DefaultNodesProvider.swift in Sources */, 3A26D93B2C3C1C97003AD832 /* KlyApiCore.swift in Sources */, @@ -3661,6 +3660,7 @@ 4184F1732A33102800D7B8B9 /* AdamantCrashlysticsService.swift in Sources */, 6403F5E422723F8C00D58779 /* DashWalletService.swift in Sources */, 9371E561295CD53100438F2C /* ChatLocalization.swift in Sources */, + 48B799A82D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */, 93BF4A6629E4859900505CD0 /* DelegatesBottomPanel.swift in Sources */, 9332C39D2C76BE7500164B80 /* FileApiServiceResult.swift in Sources */, 9322E877297042FA00B8357C /* ChatMessage.swift in Sources */, diff --git a/Adamant/Modules/Settings/PKGenerator/PKGeneratorState.swift b/Adamant/Modules/Settings/PKGenerator/PKGeneratorState.swift index dc28a23ce..ee0d978a4 100644 --- a/Adamant/Modules/Settings/PKGenerator/PKGeneratorState.swift +++ b/Adamant/Modules/Settings/PKGenerator/PKGeneratorState.swift @@ -13,12 +13,16 @@ struct PKGeneratorState { var keys: [KeyInfo] var buttonDescription: AttributedString var isLoading: Bool + var isSecretWalletsEnabled: Bool + var secretWalletPassword: String static let `default` = Self( passphrase: .empty, keys: .init(), buttonDescription: .init(), - isLoading: false + isLoading: false, + isSecretWalletsEnabled: false, + secretWalletPassword: "" ) } diff --git a/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift b/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift index 336558c6e..81cc44278 100644 --- a/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift +++ b/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift @@ -32,6 +32,13 @@ struct PKGeneratorView: View { } private extension PKGeneratorView { + private var inactiveBaseColor: Color { + Color(UIColor.gray.withAlphaComponent(0.5)) + } + private var activeBaseColor: Color { + Color(UIColor.adamant.primary) + } + var loadingBackground: some View { HStack { Spacer() @@ -61,13 +68,26 @@ private extension PKGeneratorView { text: $viewModel.state.passphrase ) - Button(action: { viewModel.generateKeys() }) { + Toggle(isOn: $viewModel.state.isSecretWalletsEnabled) { + Text(String.adamant.qrGenerator.toggleTitle) + .foregroundColor(viewModel.state.isSecretWalletsEnabled ? activeBaseColor : inactiveBaseColor) + } + .toggleStyle(SwitchToggleStyle(tint: Color(uiColor: .adamant.active))) + + if viewModel.state.isSecretWalletsEnabled { + AdamantSecureField( + placeholder: .adamant.qrGenerator.passwordPlaceholder, + text: $viewModel.state.secretWalletPassword + ) + } + + Button(action: { viewModel.generateKeys() }, label: { Text(String.adamant.pkGenerator.generateButton) .foregroundStyle(Color(uiColor: .adamant.primary)) .padding(.horizontal, 30) .background(loadingBackground) .expanded(axes: .horizontal) - } + }) }.listRowBackground(Color(uiColor: .adamant.cellColor)) } } @@ -76,7 +96,6 @@ private extension PKGeneratorView { NavigationButton(action: { viewModel.onTap(key: keyInfo.key) }) { HStack { Image(uiImage: keyInfo.icon) - .renderingMode(.template) .resizable() .frame(squareSize: 25) .foregroundStyle(Color(uiColor: .adamant.tableRowIcons)) diff --git a/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift b/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift index ef991c9c1..0aa2346ba 100644 --- a/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift +++ b/Adamant/Modules/Settings/PKGenerator/PKGeneratorViewModel.swift @@ -85,14 +85,16 @@ final class PKGeneratorViewModel: ObservableObject { guard !state.isLoading else { return } withAnimation { state.isLoading = true } let passphrase = state.passphrase.lowercased() + let password = state.secretWalletPassword Task { defer { withAnimation { state.isLoading = false } } do { let keys = try await Task.detached { [walletServiceCompose] in - try generatePrivateKeys( + try await generatePrivateKeys( passphrase: passphrase, + password: password, walletServiceCompose: walletServiceCompose ) }.value @@ -135,22 +137,43 @@ private extension PKGeneratorViewModel { private func generatePrivateKeys( passphrase: String, + password: String, walletServiceCompose: WalletServiceCompose -) throws -> [PKGeneratorState.KeyInfo] { - guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase) - else { throw AdamantError(message: .adamant.qrGenerator.wrongPassphraseError) } +) async throws -> [PKGeneratorState.KeyInfo] { + guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase) else { + throw AdamantError(message: .adamant.qrGenerator.wrongPassphraseError) + } + + let wallets = walletServiceCompose.getWallets() - return walletServiceCompose.getWallets().compactMap { - guard - let generator = $0.core as? PrivateKeyGenerator, - let key = generator.generatePrivateKeyFor(passphrase: passphrase) - else { return nil } + return await withTaskGroup(of: PKGeneratorState.KeyInfo?.self, returning: [PKGeneratorState.KeyInfo].self) { group in + for wallet in wallets { + group.addTask { + guard let generator = wallet.core as? PrivateKeyGenerator else { + return nil + } + + let key = await generator.generatePrivateKeyFor(passphrase: passphrase, password: password) + guard let key = key else { + return nil + } + + return PKGeneratorState.KeyInfo( + title: generator.rowTitle, + description: .adamant.pkGenerator.keyFormat(generator.keyFormat.rawValue), + icon: generator.rowImage ?? .init(), + key: key + ) + } + } - return PKGeneratorState.KeyInfo( - title: generator.rowTitle, - description: .adamant.pkGenerator.keyFormat(generator.keyFormat.rawValue), - icon: generator.rowImage ?? .init(), - key: key - ) + var result: [PKGeneratorState.KeyInfo] = [] + for await keyInfo in group { + if let keyInfo = keyInfo { + result.append(keyInfo) + } + } + + return result } } diff --git a/Adamant/Modules/Settings/PrivateKeyGenerator.swift b/Adamant/Modules/Settings/PrivateKeyGenerator.swift index c7415ad4b..f821b2a94 100644 --- a/Adamant/Modules/Settings/PrivateKeyGenerator.swift +++ b/Adamant/Modules/Settings/PrivateKeyGenerator.swift @@ -18,5 +18,5 @@ protocol PrivateKeyGenerator { var rowImage: UIImage? { get } var keyFormat: KeyFormat { get } - func generatePrivateKeyFor(passphrase: String) -> String? + func generatePrivateKeyFor(passphrase: String, password: String) async -> String? } diff --git a/Adamant/Modules/Settings/QRGeneratorViewController.swift b/Adamant/Modules/Settings/QRGeneratorViewController.swift index 6f3eee2a1..c5e5d4ce0 100644 --- a/Adamant/Modules/Settings/QRGeneratorViewController.swift +++ b/Adamant/Modules/Settings/QRGeneratorViewController.swift @@ -24,12 +24,18 @@ extension String.adamant { static var passphrasePlaceholder: String { String.localized("QrGeneratorScene.Passphrase.Placeholder", comment: "QRGenerator: Passphrase textview placeholder") } + static var passwordPlaceholder: String { + String.localized("QrGeneratorScene.Password.Placeholder", comment: "QRGenerator: Password textview placeholder") + } static var wrongPassphraseError: String { String.localized("QrGeneratorScene.Error.InvalidPassphrase", comment: "QRGenerator: user typed in invalid passphrase") } static var internalError: String { String.localized("QrGeneratorScene.Error.InternalErrorFormat", comment: "QRGenerator: Bad Internal generator error message format. Using %@ for error description") } + static var toggleTitle: String { + String.localized("QrGeneratorScene.Toggle.Title", comment: "QRGenerator: Toggle button title") + } } } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift index 48865345a..7415d8440 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift @@ -791,10 +791,10 @@ extension BtcWalletService: PrivateKeyGenerator { var keyFormat: KeyFormat { .WIF } - func generatePrivateKeyFor(passphrase: String) -> String? { + func generatePrivateKeyFor(passphrase: String, password: String = "") -> String? { guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase), - let privateKeyData = passphrase.data(using: .utf8)?.sha256() + let privateKeyData = makeBinarySeed(withMnemonicSentence: passphrase, withSalt: password) else { return nil } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletService.swift b/Adamant/Modules/Wallets/Dash/DashWalletService.swift index b007fcc4c..e856317ab 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletService.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletService.swift @@ -621,8 +621,8 @@ extension DashWalletService: PrivateKeyGenerator { var keyFormat: KeyFormat { .WIF } - func generatePrivateKeyFor(passphrase: String) -> String? { - guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase), let privateKeyData = passphrase.data(using: .utf8)?.sha256() else { + func generatePrivateKeyFor(passphrase: String, password: String) -> String? { + guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase), let privateKeyData = makeBinarySeed(withMnemonicSentence: passphrase, withSalt: password) else { return nil } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift index ea0968c17..a378d3528 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift @@ -740,8 +740,8 @@ extension DogeWalletService: PrivateKeyGenerator { var keyFormat: KeyFormat { .WIF } - func generatePrivateKeyFor(passphrase: String) -> String? { - guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase), let privateKeyData = passphrase.data(using: .utf8)?.sha256() else { + func generatePrivateKeyFor(passphrase: String, password: String) -> String? { + guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase), let privateKeyData = makeBinarySeed(withMnemonicSentence: passphrase, withSalt: password) else { return nil } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index a4a371275..cf6f83b07 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -47,20 +47,20 @@ extension Web3Error { return .networkError case .generalError(let error), - .keystoreError(let error as Error): + .keystoreError(let error as Error): return .internalError(message: error.localizedDescription, error: error) case .inputError(let message), .processingError(let message): return .internalError(message: message, error: nil) case .transactionSerializationError, - .dataError, - .walletError, - .unknownError, - .rpcError, - .revert, - .revertCustom, - .typeError: + .dataError, + .walletError, + .unknownError, + .rpcError, + .revert, + .revertCustom, + .typeError: return .internalError(message: "Unknown error", error: nil) case .valueError(desc: let desc): return .internalError(message: "Unknown error \(String(describing: desc))", error: nil) @@ -74,10 +74,10 @@ extension Web3Error { final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, SmartTokenInfoProtocol, @unchecked Sendable { static let currencySymbol = "ETH" - // MARK: - Constants - let addressRegex = try! NSRegularExpression(pattern: "^0x[a-fA-F0-9]{40}$") - - static let currencyLogo = UIImage.asset(named: "ethereum_wallet") ?? .init() + // MARK: - Constants + let addressRegex = try! NSRegularExpression(pattern: "^0x[a-fA-F0-9]{40}$") + + static let currencyLogo = UIImage.asset(named: "ethereum_wallet") ?? .init() var tokenSymbol: String { return type(of: self).currencySymbol @@ -86,7 +86,6 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar var tokenLogo: UIImage { return type(of: self).currencyLogo } - static var tokenNetworkSymbol: String { return "ERC20" } @@ -101,12 +100,12 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar var richMessageType: String { return Self.richMessageType - } - + } + var qqPrefix: String { return Self.qqPrefix - } - + } + var isSupportIncreaseFee: Bool { return true } @@ -129,9 +128,9 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar @Atomic private(set) var gasLimit: BigUInt = 0 @Atomic private(set) var isWarningGasPrice = false @Atomic private var balanceInvalidationSubscription: AnyCancellable? - - static let transferGas: Decimal = 21000 - static let kvsAddress = "eth:address" + + static let transferGas: Decimal = 21000 + static let kvsAddress = "eth:address" static let walletPath = "m/44'/60'/3'/1" static let walletPassword = "" @@ -162,8 +161,8 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar // MARK: RichMessageProvider properties static let richMessageType = "eth_transaction" - // MARK: - Properties - + // MARK: - Properties + public static let transactionsListApiSubpath = "ethtxs" @Atomic private(set) var enabled = true @Atomic private var subscriptions = Set() @@ -171,7 +170,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar @ObservableValue private(set) var historyTransactions: [TransactionDetails] = [] @ObservableValue private(set) var hasMoreOldTransactions: Bool = true - + var transactionsPublisher: AnyObservable<[TransactionDetails]> { $historyTransactions.eraseToAnyPublisher() } @@ -318,7 +317,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar setState(.upToDate) await calculateFee() - } + } private func markBalanceAsFresh(_ wallet: EthWallet) { wallet.isBalanceInitialized = true @@ -355,7 +354,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar gasLimit = gasLimitRaw == nil ? gasLimit : gasLimit + gasLimitPercent - + var newFee = (price * gasLimit).asDecimal(exponent: EthWalletService.currencyExponent) newFee = isIncreaseFeeEnabled @@ -366,7 +365,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar transactionFee = newFee let incGasPrice = UInt64(price.asDouble() * defaultIncreaseFee.doubleValue) - + gasPrice = isIncreaseFeeEnabled ? BigUInt(integerLiteral: incGasPrice) : price @@ -376,18 +375,18 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar NotificationCenter.default.post(name: transactionFeeUpdated, object: self, userInfo: nil) } - - // MARK: - Tools - - func validate(address: String) -> AddressValidationResult { - return addressRegex.perfectMatch(with: address) ? .valid : .invalid(description: nil) - } - - func getGasPrices() async throws -> BigUInt { + + // MARK: - Tools + + func validate(address: String) -> AddressValidationResult { + return addressRegex.perfectMatch(with: address) ? .valid : .invalid(description: nil) + } + + func getGasPrices() async throws -> BigUInt { try await ethApiService.requestWeb3(waitsForConnectivity: false) { web3 in try await web3.eth.gasPrice() }.get() - } + } func getGasLimit(to address: EthereumAddress?) async throws -> BigUInt { guard let ethWallet = ethWallet else { throw WalletServiceError.internalError(.endpointBuildFailed) } @@ -556,15 +555,15 @@ extension EthWalletService { return try await getBalance(forAddress: address) } - func getBalance(forAddress address: EthereumAddress) async throws -> Decimal { + func getBalance(forAddress address: EthereumAddress) async throws -> Decimal { let balance = try await ethApiService.requestWeb3(waitsForConnectivity: false) { web3 in try await web3.eth.getBalance(for: address) }.get() return balance.asDecimal(exponent: EthWalletService.currencyExponent) - } - - func getWalletAddress(byAdamantAddress address: String) async throws -> String { + } + + func getWalletAddress(byAdamantAddress address: String) async throws -> String { if let address = cachedWalletAddress[address], !address.isEmpty { return address } @@ -584,7 +583,7 @@ extension EthWalletService { message: "ETH Wallet: failed to get address from KVS" ) } - } + } } #if DEBUG @@ -841,14 +840,14 @@ extension EthWalletService: PrivateKeyGenerator { var keyFormat: KeyFormat { .HEX } - func generatePrivateKeyFor(passphrase: String) -> String? { + func generatePrivateKeyFor(passphrase: String, password: String) async -> String? { guard AdamantUtilities.validateAdamantPassphrase(passphrase: passphrase) else { return nil } - guard let keystore = try? BIP32Keystore(mnemonics: passphrase, password: EthWalletService.walletPassword, mnemonicsPassword: "", language: .english, prefixPath: EthWalletService.walletPath), - let account = keystore.addresses?.first, - let privateKeyData = try? keystore.UNSAFE_getPrivateKeyData(password: EthWalletService.walletPassword, account: account) else { + guard let keystore = try? await ethBIP32Service.keyStore(passphrase: passphrase, withPassword: password), + let account = keystore.addresses?.first, + let privateKeyData = try? keystore.UNSAFE_getPrivateKeyData(password: EthWalletService.walletPassword, account: account) else { return nil } diff --git a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService+WalletCore.swift b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService+WalletCore.swift index e6321d402..cbf69fb12 100644 --- a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService+WalletCore.swift +++ b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService+WalletCore.swift @@ -79,11 +79,11 @@ extension KlyWalletService: PrivateKeyGenerator { var keyFormat: KeyFormat { .HEX } - func generatePrivateKeyFor(passphrase: String) -> String? { + func generatePrivateKeyFor(passphrase: String, password: String) -> String? { guard AdamantUtilities.validateAdamantPassphrase(passphrase), let keypair = try? LiskKit.Crypto.keyPair( fromPassphrase: passphrase, - salt: salt + salt: password.isEmpty ? salt : "mnemonic\(password)" ) else { return nil diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 386346cc1..c0a23c920 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -884,6 +884,12 @@ /* QRGenerator: Passphrase textview placeholder */ "QrGeneratorScene.Passphrase.Placeholder" = "Passphrase"; +/* QRGenerator: Password textview placeholder */ +"QrGeneratorScene.Password.Placeholder" = "Passwort"; + +/* QRGenerator: Toggle textview title */ +"QrGeneratorScene.Toggle.Title" = "Geheime Wallets"; + /* QRGenerator: small 'Tap to save' tooltip under generated QR */ "QrGeneratorScene.TapToSave" = "Tippen, um zu speichern"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 4f10fa5d2..14d490143 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -875,6 +875,12 @@ /* QRGenerator: Passphrase textview placeholder */ "QrGeneratorScene.Passphrase.Placeholder" = "Passphrase"; +/* QRGenerator: Password textview placeholder */ +"QrGeneratorScene.Password.Placeholder" = "Password"; + +/* QRGenerator: Toggle textview title */ +"QrGeneratorScene.Toggle.Title" = "Secret wallets"; + /* QRGenerator: small 'Tap to save' tooltip under generated QR */ "QrGeneratorScene.TapToSave" = "Tap to save"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 8b7f80be7..ebb343698 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -876,6 +876,12 @@ /* QRGenerator: Passphrase textview placeholder */ "QrGeneratorScene.Passphrase.Placeholder" = "Пароль"; +/* QRGenerator: Password textview placeholder */ +"QrGeneratorScene.Password.Placeholder" = "Пароль"; + +/* QRGenerator: Toggle textview title */ +"QrGeneratorScene.Toggle.Title" = "Секретные кошельки"; + /* QRGenerator: small 'Tap to save' tooltip under generated QR */ "QrGeneratorScene.TapToSave" = "Нажмите для сохранения"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 5f9b867a6..baaaa7492 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -868,6 +868,12 @@ /* QRGenerator: Passphrase textview placeholder */ "QrGeneratorScene.Passphrase.Placeholder" = "密码短语"; +/* QRGenerator: Password textview placeholder */ +"QrGeneratorScene.Password.Placeholder" = "密码"; + +/* QRGenerator: Toggle textview title */ +"QrGeneratorScene.Toggle.Title" = "秘密钱包"; + /* QRGenerator: small 'Tap to save' tooltip under generated QR */ "QrGeneratorScene.TapToSave" = "点击保存"; From efc02d3700aae0a6d496583e3ababed42e14bd16 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 14 Mar 2025 17:31:43 +0700 Subject: [PATCH 13/36] [trello.com/c/vawidi4o] Remove secret wallets storing in KVS --- .../AccountViewController.swift | 11 ++++++---- .../Wallets/Bitcoin/BtcWalletService.swift | 21 +++++++----------- .../Wallets/Dash/DashWalletService.swift | 20 ++++++----------- .../Wallets/Doge/DogeWalletService.swift | 21 ++++++------------ .../Wallets/Ethereum/EthWalletService.swift | 22 +++++++------------ .../WalletService/KlyWalletService.swift | 18 +++++---------- 6 files changed, 43 insertions(+), 70 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 8ab755d6b..162ce99f1 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -178,12 +178,16 @@ final class AccountViewController: FormViewController { accountHeaderView.delegate = self secretWalletsViewModel.$state - .map{ $0.currentActiveIndex } + .map { $0.currentActiveIndex } .removeDuplicates() .receive(on: DispatchQueue.main) .sink { [weak self] index in + guard let self = self else { return } + self.setupWalletsVC() + self.pagingViewController.reloadData() + self.pagingViewController.select(index: currentWalletIndex, animated: false) guard index >= 0 else { return } - self?.accountHeaderView.setWalletIcon(index == 0 ? .regular : .secret, badgeCount: index) + self.accountHeaderView.setWalletIcon(index == 0 ? .regular : .secret, badgeCount: index) } .store(in: ¬ificationsSet) @@ -223,11 +227,10 @@ final class AccountViewController: FormViewController { walletsViewModel.$state .removeDuplicates() - .debounce(for: .nanoseconds(500_000_000), scheduler: DispatchQueue.main) + .debounce(for: .seconds(1) , scheduler: DispatchQueue.main) .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.setupWalletsVC() self.pagingViewController.reloadMenu() self.pagingViewController.select(index: currentWalletIndex, animated: false) } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift index 7415d8440..d3ec914b6 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift @@ -468,7 +468,6 @@ extension BtcWalletService { addressConverter: addressConverter ) self.btcWallet = eWallet - let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) NotificationCenter.default.post( name: walletUpdatedNotification, @@ -483,8 +482,16 @@ extension BtcWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + self.setState(.upToDate) + + Task { + self.update() + } + guard storeInKVC else { return eWallet } + // MARK: 4. Save address into KVS + let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) let service = self do { let address = try await getWalletAddress(byAdamantAddress: adamant.address) @@ -495,23 +502,12 @@ extension BtcWalletService { throw WalletServiceError.accountNotFound } - service.setState(.upToDate) - - Task { - service.update() - } - return eWallet } catch let error as WalletServiceError { switch error { case .walletNotInitiated: /// The ADM Wallet is not initialized. Check the balance of the current wallet /// and save the wallet address to kvs when dropshipping ADM - service.setState(.upToDate) - - Task { - await service.update() - } if let kvsAddressModel { service.save(kvsAddressModel) { result in @@ -522,7 +518,6 @@ extension BtcWalletService { return eWallet default: - service.setState(.upToDate) throw error } } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletService.swift b/Adamant/Modules/Wallets/Dash/DashWalletService.swift index e856317ab..8f952c4b2 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletService.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletService.swift @@ -325,7 +325,6 @@ extension DashWalletService { ) self.dashWallet = eWallet - let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) NotificationCenter.default.post( name: walletUpdatedNotification, @@ -340,9 +339,16 @@ extension DashWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + self.setState(.upToDate) + + Task { + self.update() + } + guard storeInKVC else { return eWallet } // MARK: 4. Save address into KVS + let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) do { let address = try await getWalletAddress(byAdamantAddress: adamant.address) let service = self @@ -352,11 +358,6 @@ extension DashWalletService { } } - service.setState(.upToDate) - - Task { - service.update() - } return eWallet } catch let error as WalletServiceError { let service = self @@ -364,11 +365,6 @@ extension DashWalletService { case .walletNotInitiated: /// The ADM Wallet is not initialized. Check the balance of the current wallet /// and save the wallet address to kvs when dropshipping ADM - service.setState(.upToDate) - - Task { - await service.update() - } if let kvsAddressModel { service.save(kvsAddressModel) { result in @@ -376,11 +372,9 @@ extension DashWalletService { } } - service.setState(.upToDate) return eWallet default: - service.setState(.upToDate) throw error } } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift index a378d3528..589d29e31 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift @@ -343,7 +343,6 @@ extension DogeWalletService { addressConverter: addressConverter ) self.dogeWallet = eWallet - let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) NotificationCenter.default.post( name: walletUpdatedNotification, @@ -358,9 +357,16 @@ extension DogeWalletService { NotificationCenter.default.post(name: self.serviceEnabledChanged, object: self) } + self.setState(.upToDate) + + Task { + await self.update() + } + guard storeInKVC else { return eWallet } // MARK: 4. Save address into KVS + let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) let service = self do { let address = try await getWalletAddress(byAdamantAddress: adamant.address) @@ -370,23 +376,12 @@ extension DogeWalletService { } } - service.setState(.upToDate) - - Task { - await service.update() - } - return eWallet } catch let error as WalletServiceError { switch error { case .walletNotInitiated: /// The ADM Wallet is not initialized. Check the balance of the current wallet /// and save the wallet address to kvs when dropshipping ADM - service.setState(.upToDate) - - Task { - await service.update() - } if let kvsAddressModel { service.save(kvsAddressModel) { result in @@ -394,11 +389,9 @@ extension DogeWalletService { } } - service.setState(.upToDate) return eWallet default: - service.setState(.upToDate) throw error } } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index cf6f83b07..7eb829d3e 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -428,7 +428,6 @@ extension EthWalletService { // MARK: 3. Update ethWallet = eWallet - let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) NotificationCenter.default.post( name: walletUpdatedNotification, @@ -443,9 +442,16 @@ extension EthWalletService { NotificationCenter.default.post(name: serviceEnabledChanged, object: self) } + self.setState(.upToDate) + + Task { + await self.update() + } + guard storeInKVC else { return eWallet } // MARK: 4. Save into KVS + let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) let service = self do { let address = try await getWalletAddress(byAdamantAddress: adamant.address) @@ -455,24 +461,13 @@ extension EthWalletService { } } - service.setState(.upToDate) - - Task { - await service.update() - } - return eWallet } catch let error as WalletServiceError { switch error { case .walletNotInitiated: /// The ADM Wallet is not initialized. Check the balance of the current wallet /// and save the wallet address to kvs when dropshipping ADM - service.setState(.upToDate) - - Task { - await service.update() - } - + if let kvsAddressModel { service.save(kvsAddressModel) { result in service.kvsSaveCompletionRecursion(kvsAddressModel, result: result) @@ -482,7 +477,6 @@ extension EthWalletService { return eWallet default: - service.setState(.upToDate) throw error } } diff --git a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift index 48e60a509..ea056df2b 100644 --- a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift +++ b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift @@ -465,6 +465,12 @@ private extension KlyWalletService { throw WalletServiceError.accountNotFound } + setState(.upToDate) + + Task { + await update() + } + guard storeInKVC else { return eWallet } // Save into KVS @@ -476,29 +482,17 @@ private extension KlyWalletService { updateKvsAddress(kvsAddressModel) } - setState(.upToDate) - - Task { - await update() - } - return eWallet } catch let error as WalletServiceError { switch error { case .walletNotInitiated: /// The ADM Wallet is not initialized. Check the balance of the current wallet /// and save the wallet address to kvs when dropshipping ADM - setState(.upToDate) - - Task { - await update() - } updateKvsAddress(kvsAddressModel) return eWallet default: - setState(.upToDate) throw error } } From a88f45eee6afa60554b38ce44c15005c82e2ca65 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 17 Mar 2025 15:14:00 +0700 Subject: [PATCH 14/36] [trello.com/c/vawidi4o] Setting secret wallet icon and its badge displaying. --- Adamant/Modules/Account/AccountHeader.xib | 4 +- .../Modules/Account/AccountHeaderView.swift | 56 +++++++++++++++++-- .../Helpers/UIHelpers/UIColor+adamant.swift | 8 +-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/Adamant/Modules/Account/AccountHeader.xib b/Adamant/Modules/Account/AccountHeader.xib index ddd29b4e6..b9f6afbb5 100644 --- a/Adamant/Modules/Account/AccountHeader.xib +++ b/Adamant/Modules/Account/AccountHeader.xib @@ -54,7 +54,7 @@ - + @@ -64,11 +64,11 @@ - + diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index b9e7ceb7e..9f5e9dcb3 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -68,24 +68,53 @@ final class AccountHeaderView: UIView { private extension AccountHeaderView { func setupGestureRecognizers() { secretWalletsImageView.isUserInteractionEnabled = true - let tapGesture = UITapGestureRecognizer(target: self, action: #selector(walletsButtonTapped)) secretWalletsImageView.addGestureRecognizer(tapGesture) + + guard self.circularBackgroundView != nil else { return } + circularBackgroundView!.isUserInteractionEnabled = true + let bgTapGesture = UITapGestureRecognizer(target: self, action: #selector(walletsButtonTapped)) + circularBackgroundView!.addGestureRecognizer(bgTapGesture) } func updateWalletBadge(count: Int) { - secretWalletsImageView.viewWithTag(99)?.removeFromSuperview() + guard let bgView = circularBackgroundView else { return } + + bgView.viewWithTag(99)?.removeFromSuperview() guard count > 0 else { return } + let badgeLabel = UILabel() + badgeLabel.tag = 99 + badgeLabel.text = "\(count)" + badgeLabel.font = .systemFont(ofSize: 14, weight: .medium) + badgeLabel.textAlignment = .center + badgeLabel.textColor = UIColor { traitCollection in + return traitCollection.userInterfaceStyle == .light ? .white : .black + } + badgeLabel.backgroundColor = .adamant.secondary + + let badgeSize: CGFloat = 24 + badgeLabel.layer.cornerRadius = badgeSize / 2 + badgeLabel.layer.masksToBounds = true + + badgeLabel.translatesAutoresizingMaskIntoConstraints = false + bgView.addSubview(badgeLabel) + + NSLayoutConstraint.activate([ + badgeLabel.widthAnchor.constraint(equalToConstant: badgeSize), + badgeLabel.heightAnchor.constraint(equalToConstant: badgeSize), + badgeLabel.trailingAnchor.constraint(equalTo: bgView.trailingAnchor, constant: 0), + badgeLabel.bottomAnchor.constraint(equalTo: bgView.bottomAnchor, constant: 0) + ]) } - + private func addPersistentOutline() { let bgView = UIView() bgView.backgroundColor = UIColor { traitCollection in - return traitCollection.userInterfaceStyle == .dark - ? .adamant.secondary - : UIColor.black + return traitCollection.userInterfaceStyle == .light + ? .adamant.secondBackgroundColor + : .adamant.background } secretWalletsImageView.superview?.insertSubview(bgView, belowSubview: secretWalletsImageView) @@ -93,7 +122,22 @@ private extension AccountHeaderView { } private func animateOutline() { + guard let bgView = circularBackgroundView else { return } + + let originalColor = bgView.backgroundColor + let highlightColor = UIColor.systemGray5 + UIView.animate(withDuration: 0.1, animations: { + bgView.backgroundColor = highlightColor + bgView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) + self.secretWalletsImageView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) + }, completion: { _ in + UIView.animate(withDuration: 0.1, animations: { + bgView.backgroundColor = originalColor + bgView.transform = .identity + self.secretWalletsImageView.transform = .identity + }) + }) } } diff --git a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift index 00c79f233..7f2ea0dfb 100644 --- a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift +++ b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift @@ -271,12 +271,6 @@ extension UIColor { // Outcome transfer icon background, light red public static let transferOutcomeIconBackground = #colorLiteral(red: 0.9411764706, green: 0.5215686275, blue: 0.5294117647, alpha: 1) //#F08587 - - // MARK: Secret Wallets - public static var secretWalletButtonBackground: UIColor { - let colorWhiteTheme = #colorLiteral(red: 0.9450980392, green: 0.9450980392, blue: 0.9647058824, alpha: 1) //#F1F1F6 - let colorDarkTheme = UIColor.white.withAlphaComponent(0.3) - return returnColorByTheme(colorWhiteTheme: colorWhiteTheme, colorDarkTheme: colorDarkTheme) - } + } } From c1c549e5ca1b5c80f8a5bf22b7c96ab555404071 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 17 Mar 2025 19:03:37 +0700 Subject: [PATCH 15/36] [trello.com/c/vawidi4o] Fix a walletViewControllerBase view bug --- .../AccountViewController.swift | 132 +++++++++--------- .../SecretWalletsViewModel.swift | 9 +- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 162ce99f1..953a944bf 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -236,6 +236,74 @@ final class AccountViewController: FormViewController { } .store(in: ¬ificationsSet) + setupSections() + + // MARK: Notification Center + addObservers() + + setColors() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(true, animated: animated) + + if let indexPath = tableView.indexPathForSelectedRow { + tableView.deselectRow(at: indexPath, animated: animated) + } + + for vc in pagingViewController.pageViewController.children { + vc.viewWillAppear(animated) + } + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + navigationController?.setNavigationBarHidden(false, animated: animated) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if !initiated { + initiated = true + } + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + if UIScreen.main.traitCollection.userInterfaceIdiom == .pad { + tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0) + } + + if UIScreen.main.traitCollection.userInterfaceIdiom == .pad, !initiated { + layoutTableHeaderView() + if !initiated { + initiated = true + } + } + + pagingViewController?.indicatorColor = UIColor.adamant.primary + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + // MARK: TableView configuration + + override func insertAnimation(forSections sections: [Section]) -> UITableView.RowAnimation { + return .fade + } + + override func deleteAnimation(forSections sections: [Section]) -> UITableView.RowAnimation { + return .fade + } + + // MARK: Other + + private func setupSections() { // MARK: Rows&Sections // MARK: Application @@ -707,72 +775,8 @@ final class AccountViewController: FormViewController { form.append(appSection) form.allRows.forEach { $0.baseCell.imageView?.tintColor = UIColor.adamant.tableRowIcons } - - // MARK: Notification Center - addObservers() - - setColors() } - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - navigationController?.setNavigationBarHidden(true, animated: animated) - - if let indexPath = tableView.indexPathForSelectedRow { - tableView.deselectRow(at: indexPath, animated: animated) - } - - for vc in pagingViewController.pageViewController.children { - vc.viewWillAppear(animated) - } - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - navigationController?.setNavigationBarHidden(false, animated: animated) - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - if !initiated { - initiated = true - } - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - - if UIScreen.main.traitCollection.userInterfaceIdiom == .pad { - tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 100, right: 0) - } - - if UIScreen.main.traitCollection.userInterfaceIdiom == .pad, !initiated { - layoutTableHeaderView() - if !initiated { - initiated = true - } - } - - pagingViewController?.indicatorColor = UIColor.adamant.primary - } - - deinit { - NotificationCenter.default.removeObserver(self) - } - - // MARK: TableView configuration - - override func insertAnimation(forSections sections: [Section]) -> UITableView.RowAnimation { - return .fade - } - - override func deleteAnimation(forSections sections: [Section]) -> UITableView.RowAnimation { - return .fade - } - - // MARK: Other - func addObservers() { NotificationCenter.default.addObserver( forName: Notification.Name.AdamantAccountService.userLoggedIn, diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index d209e3d29..a9c435a95 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -29,9 +29,12 @@ final class SecretWalletsViewModel: ObservableObject { } func pickWallet(at index: Int) { - state.currentActiveIndex = index - guard index != 0 else { return secretWalletsManager.activateDefaultWallet() } - secretWalletsManager.activateSecretWallet(at: index - 1) + if index == 0 { + secretWalletsManager.activateDefaultWallet() + } else { + secretWalletsManager.activateSecretWallet(at: index - 1) + } + state.currentActiveIndex = index // We must change state after to avoid bugs } func createSecretWallet(password: String) { From c2410180485905dd3efcbd9baacc0ab58340571b Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 17 Mar 2025 20:27:37 +0700 Subject: [PATCH 16/36] [trello.com/c/hzqPFC5l] Update "Send Crypto" screen to use with secret wallets --- .../Wallets/Adamant/AdmWalletFactory.swift | 4 +- .../Wallets/Bitcoin/BtcWalletFactory.swift | 4 +- .../Wallets/Dash/DashWalletFactory.swift | 4 +- .../Wallets/Doge/DogeWalletFactory.swift | 4 +- .../Wallets/ERC20/ERC20WalletFactory.swift | 4 +- .../Wallets/Ethereum/EthWalletFactory.swift | 4 +- .../Wallets/Klayr/KlyWalletFactory.swift | 4 +- .../Wallets/TransferViewControllerBase.swift | 38 ++++++++++++++++++- .../SecretWalletsManagerProtocol.swift | 1 + Adamant/Services/SecretWalletsManager.swift | 4 ++ .../Localization/de.lproj/Localizable.strings | 6 +++ .../Localization/en.lproj/Localizable.strings | 6 +++ .../Localization/ru.lproj/Localizable.strings | 6 +++ .../Localization/zh.lproj/Localizable.strings | 6 +++ 14 files changed, 87 insertions(+), 8 deletions(-) diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift index 14a3208bb..4873c5db5 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift @@ -54,7 +54,9 @@ struct AdmWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift index 6272b2ded..25b4db29d 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift @@ -50,7 +50,9 @@ struct BtcWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift index e5d0ec1a4..2ad9e5e87 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift @@ -49,7 +49,9 @@ struct DashWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift index 707c73371..24c767db4 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift @@ -49,7 +49,9 @@ struct DogeWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift index 8f71f5d65..4a8f13d23 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift @@ -49,7 +49,9 @@ struct ERC20WalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift index 252eef064..8217f3bed 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift @@ -49,7 +49,9 @@ struct EthWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift index 4197a698d..401165497 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift @@ -50,7 +50,9 @@ struct KlyWalletFactory: WalletFactory { vibroService: assembler.resolve(VibroService.self)!, walletService: service, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)! + apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, + secretWalletManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + secretWalletViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/TransferViewControllerBase.swift b/Adamant/Modules/Wallets/TransferViewControllerBase.swift index 76223e470..1fe9da76c 100644 --- a/Adamant/Modules/Wallets/TransferViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransferViewControllerBase.swift @@ -90,6 +90,8 @@ class TransferViewControllerBase: FormViewController { // MARK: - Rows enum BaseRows { + case senderAddress + case type case balance case amount case fiat @@ -105,6 +107,8 @@ class TransferViewControllerBase: FormViewController { var tag: String { switch self { + case .senderAddress: return "senderAddress" + case .type: return "type" case .balance: return "balance" case .amount: return "amount" case .fiat: return "fiat" @@ -122,6 +126,8 @@ class TransferViewControllerBase: FormViewController { var localized: String { switch self { + case .senderAddress: return .localized("TransferScene.Row.SenderAddress", comment: "Transfer: sender address") + case .type: return .localized("TransferScene.Row.Type", comment: "Transfer: transaction type") case .balance: return .localized("TransferScene.Row.Balance", comment: "Transfer: logged user balance.") case .amount: return .localized("TransferScene.Row.Amount", comment: "Transfer: amount of adamant to transfer.") case .fiat: return .localized("TransferScene.Row.Fiat", comment: "Transfer: fiat value of crypto-amout") @@ -188,6 +194,8 @@ class TransferViewControllerBase: FormViewController { let walletCore: WalletCoreProtocol let reachabilityMonitor: ReachabilityMonitor let apiServiceCompose: ApiServiceComposeProtocol + let secretWalletManager: SecretWalletsManagerProtocol + let secretWalletViewModel: SecretWalletsViewModel // MARK: - Properties @@ -319,7 +327,9 @@ class TransferViewControllerBase: FormViewController { vibroService: VibroService, walletService: WalletService, reachabilityMonitor: ReachabilityMonitor, - apiServiceCompose: ApiServiceComposeProtocol + apiServiceCompose: ApiServiceComposeProtocol, + secretWalletManager: SecretWalletsManagerProtocol, + secretWalletViewModel: SecretWalletsViewModel ) { self.accountService = accountService self.accountsProvider = accountsProvider @@ -333,6 +343,8 @@ class TransferViewControllerBase: FormViewController { self.walletCore = walletService.core self.reachabilityMonitor = reachabilityMonitor self.apiServiceCompose = apiServiceCompose + self.secretWalletManager = secretWalletManager + self.secretWalletViewModel = secretWalletViewModel super.init(style: .insetGrouped) } @@ -501,6 +513,8 @@ class TransferViewControllerBase: FormViewController { $0.tag = Sections.wallet.tag } + section.append(defaultRowFor(baseRow: BaseRows.senderAddress)) + section.append(defaultRowFor(baseRow: BaseRows.type)) section.append(defaultRowFor(baseRow: BaseRows.balance)) section.append(defaultRowFor(baseRow: BaseRows.maxToTransfer)) @@ -1023,6 +1037,28 @@ class TransferViewControllerBase: FormViewController { extension TransferViewControllerBase { func defaultRowFor(baseRow: BaseRows) -> BaseRow { switch baseRow { + case .senderAddress: + return LabelRow { [weak self] in + $0.title = BaseRows.senderAddress.localized + $0.tag = BaseRows.senderAddress.tag + $0.disabled = true + $0.cell.detailTextLabel?.lineBreakMode = .byTruncatingMiddle + $0.value = self?.walletCore.wallet?.address + } + case .type: + return LabelRow { + $0.title = BaseRows.type.localized + $0.tag = BaseRows.type.tag + $0.disabled = true + + $0.value = secretWalletViewModel.state.currentWallet?.name ?? String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") + + for wallet in secretWalletManager.getRegularWallet().sorted(includeInvisible: false) where wallet.core.wallet?.address == walletCore.wallet?.address { + $0.value = String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") + break + } + } + case .balance: return SafeDecimalRow { [weak self] in $0.title = BaseRows.balance.localized diff --git a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift index 3ec8d56d5..da0ba57fd 100644 --- a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift +++ b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift @@ -14,6 +14,7 @@ protocol SecretWalletsManagerProtocol { func createSecretWallet(withPassword password: String) func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? func getCurrentWallet() -> WalletStoreServiceProtocol + func getRegularWallet() -> WalletStoreServiceProtocol func getSecretWallets() -> [WalletStoreServiceProtocol] func activateSecretWallet(at index: Int) func activateDefaultWallet() diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index 3ba116ef4..df0b4e688 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -58,6 +58,10 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { state.currentWallet } + func getRegularWallet() -> WalletStoreServiceProtocol { + state.regularWallet + } + func getSecretWallets() -> [WalletStoreServiceProtocol] { state.secretWallets } diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index c0a23c920..c780d2108 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1211,6 +1211,12 @@ /* Transfer: fiat value of crypto-amout */ "TransferScene.Row.Fiat" = "Wert"; +/* Transfer: sender address */ +"TransferScene.Row.SenderAddress" = "Adresse"; + +/* Transfer: type of wallet */ +"TransferScene.Row.Type" = "Typ"; + /* Transfer: logged user balance. */ "TransferScene.Row.Balance" = "Kontostand"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 14d490143..e2bdabcaa 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1187,6 +1187,12 @@ /* Transfer: fiat value of crypto-amout */ "TransferScene.Row.Fiat" = "Value"; +/* Transfer: sender address */ +"TransferScene.Row.SenderAddress" = "Address"; + +/* Transfer: type of wallet */ +"TransferScene.Row.Type" = "Type"; + /* Transfer: logged user balance. */ "TransferScene.Row.Balance" = "Balance"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index ebb343698..f487709fa 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1188,6 +1188,12 @@ /* Transfer: fiat value of crypto-amout */ "TransferScene.Row.Fiat" = "Ценность"; +/* Transfer: sender address */ +"TransferScene.Row.SenderAddress" = "Адрес"; + +/* Transfer: type of wallet */ +"TransferScene.Row.Type" = "Тип"; + /* Transfer: logged user balance. */ "TransferScene.Row.Balance" = "Баланс"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index baaaa7492..c20e22c23 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1177,6 +1177,12 @@ /* Transfer: fiat value of crypto-amout */ "TransferScene.Row.Fiat" = "价值"; +/* Transfer: sender address */ +"TransferScene.Row.SenderAddress" = "地址"; + +/* Transfer: type of wallet */ +"TransferScene.Row.Type" = "类型"; + /* Transfer: logged user balance. */ "TransferScene.Row.Balance" = "余额"; From a4fac39d53c160d4aa13db7439e4408a0cafbc45 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Tue, 18 Mar 2025 13:37:25 +0700 Subject: [PATCH 17/36] [trello.com/c/vawidi4o] Self review/Refactoring --- Adamant/App/DI/AppAssembly.swift | 24 ++++++++--------- .../Modules/Account/AccountHeaderView.swift | 26 ++++++++++--------- .../AccountViewController.swift | 1 - .../SecretWalletsAlertMenuView.swift | 6 ++--- .../SecretWalletsViewModel.swift | 1 - .../PKGenerator/PKGeneratorView.swift | 7 ++--- .../Localization/de.lproj/Localizable.strings | 13 ++++++---- .../Localization/en.lproj/Localizable.strings | 3 +++ .../Localization/ru.lproj/Localizable.strings | 13 ++++++---- .../Localization/zh.lproj/Localizable.strings | 13 ++++++---- .../Helpers/UIHelpers/UIColor+adamant.swift | 1 - 11 files changed, 59 insertions(+), 49 deletions(-) diff --git a/Adamant/App/DI/AppAssembly.swift b/Adamant/App/DI/AppAssembly.swift index 82d061ad3..ebbc7ee6a 100644 --- a/Adamant/App/DI/AppAssembly.swift +++ b/Adamant/App/DI/AppAssembly.swift @@ -105,6 +105,17 @@ struct AppAssembly: MainThreadAssembly { ) }.inObjectScope(.container) + container.register(SecretWalletsViewModel.self) { r in + SecretWalletsViewModel(secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)!) + }.inObjectScope(.container) + + container.register(SecretWalletsAlertMenuView.self) { r in + SecretWalletsAlertMenuView( + dialogService: r.resolve(DialogService.self)!, + secretWalletsViewModel: r.resolve(SecretWalletsViewModel.self)! + ) + }.inObjectScope(.transient) + // MARK: IncreaseFeeService container.register(IncreaseFeeService.self) { r in AdamantIncreaseFeeService( @@ -495,18 +506,5 @@ struct AppAssembly: MainThreadAssembly { container.register(CoreDataRealationMapperProtocol.self) { r in CoreDataRealationMapper(stack: r.resolve(CoreDataStack.self)!) }.inObjectScope(.container) - - // MARK: SecretWalletsViewModel - container.register(SecretWalletsViewModel.self) { r in - SecretWalletsViewModel(secretWalletsManager: r.resolve(SecretWalletsManagerProtocol.self)!) - }.inObjectScope(.container) - - // MARK: SecretWalletsAlertService - container.register(SecretWalletsAlertMenuView.self) { r in - SecretWalletsAlertMenuView( - dialogService: r.resolve(DialogService.self)!, - secretWalletsViewModel: r.resolve(SecretWalletsViewModel.self)! - ) - }.inObjectScope(.transient) } } diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index 9f5e9dcb3..6ddef03fb 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -35,6 +35,15 @@ final class AccountHeaderView: UIView { setupGestureRecognizers() } + @IBAction func addressButtonTapped(_ sender: UIButton) { + delegate?.addressLabelTapped(from: sender) + } + + @objc private func walletsButtonTapped() { + animateOutline() + delegate?.walletsButtonTapped(from: secretWalletsImageView) + } + override func layoutSubviews() { super.layoutSubviews() guard let bgView = circularBackgroundView else { return } @@ -48,21 +57,14 @@ final class AccountHeaderView: UIView { height: bgHeight) bgView.layer.cornerRadius = bgWidth / 2 } - +} + +extension AccountHeaderView { func setWalletIcon(_ icon: WalletIcon, badgeCount: Int) { secretWalletsImageView.tintColor = .adamant.secondary secretWalletsImageView.image = .asset(named: icon.rawValue)?.withRenderingMode(.alwaysTemplate) ?? .init() updateWalletBadge(count: badgeCount) } - - @IBAction func addressButtonTapped(_ sender: UIButton) { - delegate?.addressLabelTapped(from: sender) - } - - @objc private func walletsButtonTapped() { - animateOutline() - delegate?.walletsButtonTapped(from: secretWalletsImageView) - } } private extension AccountHeaderView { @@ -109,7 +111,7 @@ private extension AccountHeaderView { ]) } - private func addPersistentOutline() { + func addPersistentOutline() { let bgView = UIView() bgView.backgroundColor = UIColor { traitCollection in return traitCollection.userInterfaceStyle == .light @@ -121,7 +123,7 @@ private extension AccountHeaderView { self.circularBackgroundView = bgView } - private func animateOutline() { + func animateOutline() { guard let bgView = circularBackgroundView else { return } let originalColor = bgView.backgroundColor diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 953a944bf..894671bfa 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -1109,7 +1109,6 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr first.height != second.height else { return } - updateHeaderSize(with: second, animated: true) } } diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift index 3a598fe92..34658152c 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift @@ -75,7 +75,7 @@ final class SecretWalletsAlertMenuView { private func showEnableSecretWalletAlert() { let passwordAlert = UIAlertController( - title: "Enter password to add secret wallet", + title: String.localized("SecretWallets.Menu.AddSecretWallet.Title", comment: "Add secret wallet title"), message: nil, preferredStyle: .alert ) @@ -85,10 +85,10 @@ final class SecretWalletsAlertMenuView { textField.placeholder = "Password" } - let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) + let cancelAction = UIAlertAction(title: String.localized("Cancel", comment: "Cancel adding password"), style: .cancel) passwordAlert.addAction(cancelAction) - let enableAction = UIAlertAction(title: "Enable", style: .default) { [weak self] _ in + let enableAction = UIAlertAction(title: String.localized("SecretWallets.Menu.AddSecretWallet.Add", comment: "Confirm adding secret password"), style: .default) { [weak self] _ in guard let self = self, let password = passwordAlert.textFields?.first?.text, diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index a9c435a95..587eff9fd 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -9,7 +9,6 @@ import CommonKit import Combine -//TODO: Consider logout @MainActor final class SecretWalletsViewModel: ObservableObject { @Published private(set) var state: SecretWalletsState = .default diff --git a/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift b/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift index 81cc44278..40fa2b411 100644 --- a/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift +++ b/Adamant/Modules/Settings/PKGenerator/PKGeneratorView.swift @@ -93,10 +93,11 @@ private extension PKGeneratorView { } func keyView(_ keyInfo: PKGeneratorState.KeyInfo) -> some View { - NavigationButton(action: { viewModel.onTap(key: keyInfo.key) }) { + NavigationButton(action: { viewModel.onTap(key: keyInfo.key) }, content: { HStack { Image(uiImage: keyInfo.icon) - .resizable() + .renderingMode(.template) + .resizable() .frame(squareSize: 25) .foregroundStyle(Color(uiColor: .adamant.tableRowIcons)) @@ -112,6 +113,6 @@ private extension PKGeneratorView { Text(keyInfo.key).lineLimit(1) .foregroundStyle(Color(uiColor: .adamant.secondary)) } - } + }) } } diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index c0a23c920..1152aa70c 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1395,14 +1395,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "Normal"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ Geheim 1"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ Geheim 2"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ Geheim 3"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ Geheim 4"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ Geheim 5"; +"SecretWallets.Menu.Secret1" = "🔐1️⃣ Geheim 1"; +"SecretWallets.Menu.Secret2" = "🔐2️⃣ Geheim 2"; +"SecretWallets.Menu.Secret3" = "🔐3️⃣ Geheim 3"; +"SecretWallets.Menu.Secret4" = "🔐4️⃣ Geheim 4"; +"SecretWallets.Menu.Secret5" = "🔐5️⃣ Geheim 5"; "SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "Über Wallets"; "SecretWallets.Menu.Title" = "Aktive Wallets"; +"SecretWallets.Menu.AddSecretWallet.Title" = "Geben Sie das Passwort ein, um eine geheime Wallet hinzuzufügen"; +"SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Passwort"; +"SecretWallets.Menu.AddSecretWallet.Add" = "Hinzufügen"; "SecretWallets.Row.Title" = "Geheime Geldbörsen"; /* Secret Wallets Coins name*/ diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 14d490143..ad4af9a41 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1379,6 +1379,9 @@ "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.Title" = "Active wallets"; +"SecretWallets.Menu.AddSecretWallet.Title" = "Enter password to add secret wallet"; +"SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Password"; +"SecretWallets.Menu.AddSecretWallet.Add" = "Add"; "SecretWallets.Row.Title" = "Secret wallets"; /* Secret Wallets Coins name*/ diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index ebb343698..6777a7339 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1372,14 +1372,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "Обычный"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ Секретный 1"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ Секретный 2"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ Секретный 3"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ Секретный 4"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ Секретный 5"; +"SecretWallets.Menu.Secret1" = "🔐1️⃣ Секретный 1"; +"SecretWallets.Menu.Secret2" = "🔐2️⃣ Секретный 2"; +"SecretWallets.Menu.Secret3" = "🔐3️⃣ Секретный 3"; +"SecretWallets.Menu.Secret4" = "🔐4️⃣ Секретный 4"; +"SecretWallets.Menu.Secret5" = "🔐5️⃣ Секретный 5"; "SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "О кошельках"; "SecretWallets.Menu.Title" = "Активные кошельки"; +"SecretWallets.Menu.AddSecretWallet.Title" = "Введите пароль, чтобы добавить секретный кошелек"; +"SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Пароль"; +"SecretWallets.Menu.AddSecretWallet.Add" = "Добавить"; "SecretWallets.Row.Title" = "Секретные кошельки"; /* Secret Wallets Coins name*/ diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index baaaa7492..3bc93e2a1 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1362,14 +1362,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "普通"; -"SecretWallets.Menu.Secret" = "🔐1️⃣ 秘密 1"; -"SecretWallets.Menu.Secret" = "🔐2️⃣ 秘密 2"; -"SecretWallets.Menu.Secret" = "🔐3️⃣ 秘密 3"; -"SecretWallets.Menu.Secret" = "🔐4️⃣ 秘密 4"; -"SecretWallets.Menu.Secret" = "🔐5️⃣ 秘密 5"; +"SecretWallets.Menu.Secret1" = "🔐1️⃣ 秘密 1"; +"SecretWallets.Menu.Secret2" = "🔐2️⃣ 秘密 2"; +"SecretWallets.Menu.Secret3" = "🔐3️⃣ 秘密 3"; +"SecretWallets.Menu.Secret4" = "🔐4️⃣ 秘密 4"; +"SecretWallets.Menu.Secret5" = "🔐5️⃣ 秘密 5"; "SecretWallets.Menu.AddSecretWallet" = "添加秘密"; "SecretWallets.Menu.TellMeMore" = "关于钱包"; "SecretWallets.Menu.Title" = "活动钱包"; +"SecretWallets.Menu.AddSecretWallet.Title" = "输入密码以添加秘密钱包"; +"SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "密码"; +"SecretWallets.Menu.AddSecretWallet.Add" = "添加"; "SecretWallets.Row.Title" = "秘密钱包"; /* Secret Wallets Coins name*/ diff --git a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift index 7f2ea0dfb..c775b2100 100644 --- a/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift +++ b/CommonKit/Sources/CommonKit/Helpers/UIHelpers/UIColor+adamant.swift @@ -271,6 +271,5 @@ extension UIColor { // Outcome transfer icon background, light red public static let transferOutcomeIconBackground = #colorLiteral(red: 0.9411764706, green: 0.5215686275, blue: 0.5294117647, alpha: 1) //#F08587 - } } From 0ae6d61114c952c9b44f1c9795ba628eca559db8 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Wed, 19 Mar 2025 15:20:56 +0700 Subject: [PATCH 18/36] [trello.com/c/vawidi4o] Update "Tell me more" button on a secret wallet menu --- .../SecretWallets/SecretWalletsAlertMenuView.swift | 13 ++++++++++--- .../Localization/de.lproj/Localizable.strings | 3 +++ .../Localization/en.lproj/Localizable.strings | 3 +++ .../Localization/ru.lproj/Localizable.strings | 3 +++ .../Localization/zh.lproj/Localizable.strings | 3 +++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift index 34658152c..03d1dbe39 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsAlertMenuView.swift @@ -105,11 +105,18 @@ final class SecretWalletsAlertMenuView { private func showSecretWalletInfoAlert() { let infoAlert = UIAlertController( - title: "Secret Wallets", - message: "Secret wallets are encrypted and require a password...", + title: String.localized("SecretWallets.Menu.TellMeMore.Title", comment: "Tell me more about secret wallets"), + message: String.localized("SecretWallets.Menu.TellMeMore.Subtitle", comment: "Subtitle for tell me more alert"), preferredStyle: .alert ) - infoAlert.addAction(.init(title: "Got it", style: .default)) + infoAlert.addAction(.init(title: String.localized("Cancel"), style: .cancel)) + + let learnMoreAction = UIAlertAction(title: String.localized("SecretWallets.Menu.TellMeMore.LearnMore", comment: "Learn more about secret wallets") , style: .default) { _ in + if let url = URL(string: "http://news.adamant.im/") { + UIApplication.shared.open(url) + } + } + infoAlert.addAction(learnMoreAction) dialogService.present(infoAlert, animated: true, completion: nil) } diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 1152aa70c..894f98300 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1402,6 +1402,9 @@ "SecretWallets.Menu.Secret5" = "🔐5️⃣ Geheim 5"; "SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "Über Wallets"; +"SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; +"SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; +"SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; "SecretWallets.Menu.Title" = "Aktive Wallets"; "SecretWallets.Menu.AddSecretWallet.Title" = "Geben Sie das Passwort ein, um eine geheime Wallet hinzuzufügen"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Passwort"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index ad4af9a41..66d346845 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1378,6 +1378,9 @@ "SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret 5"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; +"SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; +"SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; +"SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; "SecretWallets.Menu.Title" = "Active wallets"; "SecretWallets.Menu.AddSecretWallet.Title" = "Enter password to add secret wallet"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Password"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 6777a7339..a3775750e 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1379,6 +1379,9 @@ "SecretWallets.Menu.Secret5" = "🔐5️⃣ Секретный 5"; "SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "О кошельках"; +"SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; +"SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; +"SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; "SecretWallets.Menu.Title" = "Активные кошельки"; "SecretWallets.Menu.AddSecretWallet.Title" = "Введите пароль, чтобы добавить секретный кошелек"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Пароль"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 3bc93e2a1..f31d89ec3 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1369,6 +1369,9 @@ "SecretWallets.Menu.Secret5" = "🔐5️⃣ 秘密 5"; "SecretWallets.Menu.AddSecretWallet" = "添加秘密"; "SecretWallets.Menu.TellMeMore" = "关于钱包"; +"SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; +"SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; +"SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; "SecretWallets.Menu.Title" = "活动钱包"; "SecretWallets.Menu.AddSecretWallet.Title" = "输入密码以添加秘密钱包"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "密码"; From bd8cf28f386d5f37c9d33e186bd1193aa2558cd8 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 24 Mar 2025 13:31:19 +0700 Subject: [PATCH 19/36] [trello.com/c/vawidi4o] Localisation update --- .../Assets/Localization/de.lproj/Localizable.strings | 6 +++--- .../Assets/Localization/ru.lproj/Localizable.strings | 6 +++--- .../Assets/Localization/zh.lproj/Localizable.strings | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 1ce820899..41f3ff763 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1396,14 +1396,14 @@ "Chat.Timestamp.InFuture.Error" = "Ein Netzwerkknoten hat die Nachricht abgelehnt, weil die Zeit auf Ihrem Gerät vorgeht.\nÜberprüfen Sie die Uhrzeit des Geräts oder versuchen Sie erneut, eine Nachricht zu senden."; /* Secret Wallets */ -"SecretWallets.Menu.Regular" = "Normal"; +"SecretWallets.Menu.Regular" = "💰 Normal"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Geheim 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Geheim 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Geheim 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Geheim 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Geheim 5"; -"SecretWallets.Menu.AddSecretWallet" = "Geheimen hinzufügen"; -"SecretWallets.Menu.TellMeMore" = "Über Wallets"; +"SecretWallets.Menu.AddSecretWallet" = "🪄 Geheimen hinzufügen"; +"SecretWallets.Menu.TellMeMore" = "💡 Über Wallets"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; "SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; "SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 510f26d26..1f8e7e111 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1373,14 +1373,14 @@ "Chat.Timestamp.InFuture.Error" = "Узел сети отклонил сообщение, потому что время на вашем устройстве спешит.\nПроверьте время на устройстве или попробуйте отправить сообщение снова."; /* Secret Wallets */ -"SecretWallets.Menu.Regular" = "Обычный"; +"SecretWallets.Menu.Regular" = "💰 Обычный"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Секретный 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Секретный 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Секретный 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Секретный 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Секретный 5"; -"SecretWallets.Menu.AddSecretWallet" = "Добавить секретный"; -"SecretWallets.Menu.TellMeMore" = "О кошельках"; +"SecretWallets.Menu.AddSecretWallet" = "🪄 Добавить секретный"; +"SecretWallets.Menu.TellMeMore" = "💡 О кошельках"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; "SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; "SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 39753c0c8..69ea08a04 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1363,14 +1363,14 @@ "Chat.Timestamp.InFuture.Error" = "由于您设备上的时间超前,网络节点拒绝了信息。\n请检查设备的时间或再次尝试发送信息。"; /* Secret Wallets */ -"SecretWallets.Menu.Regular" = "普通"; +"SecretWallets.Menu.Regular" = "💰 普通"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ 秘密 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ 秘密 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ 秘密 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ 秘密 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ 秘密 5"; -"SecretWallets.Menu.AddSecretWallet" = "添加秘密"; -"SecretWallets.Menu.TellMeMore" = "关于钱包"; +"SecretWallets.Menu.AddSecretWallet" = "🪄 添加秘密"; +"SecretWallets.Menu.TellMeMore" = "💡 关于钱包"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; "SecretWallets.Menu.TellMeMore.Subtitle" = "is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; "SecretWallets.Menu.TellMeMore.LearnMore" = "Learn more"; From 6efd38af077c67e7cbd31247132327c4b130a7d9 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 24 Mar 2025 13:43:29 +0700 Subject: [PATCH 20/36] [trello.com/c/vawidi4o] A little refactoring of secret wallets factory. Fix bug when secret wallets do not init without "stay logged in" feature. --- Adamant.xcodeproj/project.pbxproj | 8 +- Adamant/App/DI/AppAssembly.swift | 6 +- Adamant/ServiceProtocols/AccountService.swift | 3 + Adamant/Services/AdamantAccountService.swift | 4 + ...tWalletsManager+SecretWalletsFactory.swift | 83 ------------------- Adamant/Services/SecretWalletsFactory.swift | 79 ++++++++++++++++++ Adamant/Services/SecretWalletsManager.swift | 2 +- 7 files changed, 94 insertions(+), 91 deletions(-) delete mode 100644 Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift create mode 100644 Adamant/Services/SecretWalletsFactory.swift diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 760981dd0..d7eb3e34b 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -188,7 +188,7 @@ 48B6A8EB2D5738D800326EE8 /* WalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */; }; 48B6A8ED2D57390400326EE8 /* AdamantWalletsStoreService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */; }; 48B6A8EF2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */; }; - 48B799A82D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */; }; + 48B799A82D84144C00BFD6A4 /* SecretWalletsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48B799A72D84144C00BFD6A4 /* SecretWalletsFactory.swift */; }; 48C034F92D81560800F50E35 /* SecretWalletsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034F82D81560800F50E35 /* SecretWalletsState.swift */; }; 48C034FF2D81587800F50E35 /* SecretWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */; }; 48DA2FCF2D4A0519008F9FC1 /* AccountWalletsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */; }; @@ -923,7 +923,7 @@ 48B6A8EA2D5738D800326EE8 /* WalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletsStoreService.swift; sourceTree = ""; }; 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletsStoreService.swift; sourceTree = ""; }; 48B6A8EE2D573A3C00326EE8 /* AdamantWalletStoreServiceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdamantWalletStoreServiceProvider.swift; sourceTree = ""; }; - 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdamantSecretWalletsManager+SecretWalletsFactory.swift"; sourceTree = ""; }; + 48B799A72D84144C00BFD6A4 /* SecretWalletsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsFactory.swift; sourceTree = ""; }; 48C034F82D81560800F50E35 /* SecretWalletsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsState.swift; sourceTree = ""; }; 48C034FE2D81587800F50E35 /* SecretWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecretWalletsViewModel.swift; sourceTree = ""; }; 48DA2FCE2D4A0519008F9FC1 /* AccountWalletsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWalletsViewModel.swift; sourceTree = ""; }; @@ -2648,7 +2648,7 @@ 41047B75294C62710039E956 /* AdamantVisibleWalletsService.swift */, 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */, 4153045829C09902000E4BEA /* AdamantIncreaseFeeService.swift */, - 48B799A72D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift */, + 48B799A72D84144C00BFD6A4 /* SecretWalletsFactory.swift */, 4184F1722A33102800D7B8B9 /* AdamantCrashlysticsService.swift */, 48B6A8EC2D57390400326EE8 /* AdamantWalletsStoreService.swift */, 3A9015A62A614A62002A2464 /* AdamantEmojiService.swift */, @@ -3663,7 +3663,7 @@ 4184F1732A33102800D7B8B9 /* AdamantCrashlysticsService.swift in Sources */, 6403F5E422723F8C00D58779 /* DashWalletService.swift in Sources */, 9371E561295CD53100438F2C /* ChatLocalization.swift in Sources */, - 48B799A82D84144C00BFD6A4 /* AdamantSecretWalletsManager+SecretWalletsFactory.swift in Sources */, + 48B799A82D84144C00BFD6A4 /* SecretWalletsFactory.swift in Sources */, 93BF4A6629E4859900505CD0 /* DelegatesBottomPanel.swift in Sources */, 9332C39D2C76BE7500164B80 /* FileApiServiceResult.swift in Sources */, 9322E877297042FA00B8357C /* ChatMessage.swift in Sources */, diff --git a/Adamant/App/DI/AppAssembly.swift b/Adamant/App/DI/AppAssembly.swift index ebbc7ee6a..478c53673 100644 --- a/Adamant/App/DI/AppAssembly.swift +++ b/Adamant/App/DI/AppAssembly.swift @@ -83,8 +83,8 @@ struct AppAssembly: MainThreadAssembly { }.inObjectScope(.container) // MARK: Secret Wallets - container.register(AdamantSecretWalletsManager.SecretWalletsFactory.self) { r in - AdamantSecretWalletsManager.SecretWalletsFactory( + container.register(SecretWalletsFactory.self) { r in + SecretWalletsFactory( visibleWalletsService: r.resolve(VisibleWalletsService.self)!, accountService: r.resolve(AccountService.self)!, securedStore: r.resolve(SecuredStore.self)!, @@ -95,7 +95,7 @@ struct AppAssembly: MainThreadAssembly { container.register(SecretWalletsManagerProtocol.self) { r in AdamantSecretWalletsManager( walletsStoreService: r.resolve(WalletStoreServiceProtocol.self)!, - secretWalletsFactory: r.resolve(AdamantSecretWalletsManager.SecretWalletsFactory.self)! + secretWalletsFactory: r.resolve(SecretWalletsFactory.self)! ) }.inObjectScope(.container) diff --git a/Adamant/ServiceProtocols/AccountService.swift b/Adamant/ServiceProtocols/AccountService.swift index 0f6cd39ae..36fb50730 100644 --- a/Adamant/ServiceProtocols/AccountService.swift +++ b/Adamant/ServiceProtocols/AccountService.swift @@ -196,4 +196,7 @@ protocol AccountService: AnyObject, Sendable { /// Update use TouchID or FaceID to log in func updateUseBiometry(_ newValue: Bool) + + /// Get current passphrase + func getCurrentPassphrase() -> String? } diff --git a/Adamant/Services/AdamantAccountService.swift b/Adamant/Services/AdamantAccountService.swift index 1d65a2d79..acc0cb74a 100644 --- a/Adamant/Services/AdamantAccountService.swift +++ b/Adamant/Services/AdamantAccountService.swift @@ -134,6 +134,10 @@ extension AdamantAccountService { return securedStore.get(.passphrase) } + func getCurrentPassphrase() -> String? { + passphrase + } + func dropSavedAccount() { useBiometry = false isBalanceExpired = true diff --git a/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift b/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift deleted file mode 100644 index 380e48839..000000000 --- a/Adamant/Services/AdamantSecretWalletsManager+SecretWalletsFactory.swift +++ /dev/null @@ -1,83 +0,0 @@ -// -// SecretWalletsFactory.swift -// Adamant -// -// Created by Dmitrij Meidus on 20.02.25. -// Copyright © 2025 Adamant. All rights reserved. -// - -import CommonKit -import Swinject - -extension AdamantSecretWalletsManager{ - struct SecretWalletsFactory { - private let visibleWalletsService: VisibleWalletsService - private let accountService: AccountService - private let securedStore: SecuredStore - private let container: Container - - init( - visibleWalletsService: VisibleWalletsService, - accountService: AccountService, - securedStore: SecuredStore, - container: Container - ) { - self.visibleWalletsService = visibleWalletsService - self.accountService = accountService - self.securedStore = securedStore - self.container = container - } - - func makeSecretWallet(withPassword password: String) -> WalletStoreServiceProtocol { - var wallets: [WalletCoreProtocol] = [ - AdmWalletService(), - BtcWalletService(), - EthWalletService(), - KlyWalletService(), - DogeWalletService(), - DashWalletService() - ] - - let erc20WalletServices = ERC20Token.supportedTokens.map { - ERC20WalletService(token: $0) - } - wallets.append(contentsOf: erc20WalletServices) - - let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) - Task { @MainActor in - await injectDependencies(in: walletServiceCompose) - await initWallets(withPass: password, for: walletServiceCompose) - } - - let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) - - return wallet - } - - @MainActor - private func injectDependencies(in walletService: WalletServiceCompose) async { - walletService.getWallets().forEach { wallet in - (wallet.core as? SwinjectDependentService)?.injectDependencies(from: container) - } - } - - private func initWallets(withPass password: String, for walletService: WalletServiceCompose) async { - guard let passphrase: String = securedStore.get(StoreKey.accountService.passphrase) else { - print("No passphrase found") - return - } - - await withTaskGroup(of: Void.self) { taskGroup in - for wallet in walletService.getWallets() { - taskGroup.addTask { - _ = try? await wallet.core.initWallet( - withPassphrase: passphrase, - withPassword: password, - storeInKVC: false - ) - } - } - } - } - } -} diff --git a/Adamant/Services/SecretWalletsFactory.swift b/Adamant/Services/SecretWalletsFactory.swift new file mode 100644 index 000000000..4305f9078 --- /dev/null +++ b/Adamant/Services/SecretWalletsFactory.swift @@ -0,0 +1,79 @@ +// +// SecretWalletsFactory.swift +// Adamant +// +// Created by Dmitrij Meidus on 20.02.25. +// Copyright © 2025 Adamant. All rights reserved. +// + +import CommonKit +import Swinject + +struct SecretWalletsFactory { + private let visibleWalletsService: VisibleWalletsService + private let accountService: AccountService + private let container: Container + + init( + visibleWalletsService: VisibleWalletsService, + accountService: AccountService, + securedStore: SecuredStore, + container: Container + ) { + self.visibleWalletsService = visibleWalletsService + self.accountService = accountService + self.container = container + } + + func makeSecretWallet(withPassword password: String) -> WalletStoreServiceProtocol { + var wallets: [WalletCoreProtocol] = [ + AdmWalletService(), + BtcWalletService(), + EthWalletService(), + KlyWalletService(), + DogeWalletService(), + DashWalletService() + ] + + let erc20WalletServices = ERC20Token.supportedTokens.map { + ERC20WalletService(token: $0) + } + wallets.append(contentsOf: erc20WalletServices) + + let walletServiceCompose = AdamantWalletServiceCompose(wallets: wallets) + Task { @MainActor in + await injectDependencies(in: walletServiceCompose) + await initWallets(withPass: password, for: walletServiceCompose) + } + + let wallet = AdamantWalletStoreService(visibleWalletsService: visibleWalletsService, walletServiceCompose: walletServiceCompose) + + return wallet + } + + @MainActor + private func injectDependencies(in walletService: WalletServiceCompose) async { + walletService.getWallets().forEach { wallet in + (wallet.core as? SwinjectDependentService)?.injectDependencies(from: container) + } + } + + private func initWallets(withPass password: String, for walletService: WalletServiceCompose) async { + guard let passphrase: String = accountService.getCurrentPassphrase() else { + print("No passphrase found") + return + } + + await withTaskGroup(of: Void.self) { taskGroup in + for wallet in walletService.getWallets() { + taskGroup.addTask { + _ = try? await wallet.core.initWallet( + withPassphrase: passphrase, + withPassword: password, + storeInKVC: false + ) + } + } + } + } +} diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index 3ba116ef4..93181719b 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -10,7 +10,7 @@ import Foundation import Swinject import CommonKit -extension AdamantSecretWalletsManager { +private extension AdamantSecretWalletsManager { struct State: SecretWalletsManagerStateProtocol { var currentWallet: WalletStoreServiceProtocol var regularWallet: WalletStoreServiceProtocol From ae0a2e34aca48821cb617a8d7e7dc69e348b62bf Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Tue, 25 Mar 2025 13:26:23 +0700 Subject: [PATCH 21/36] [trello.com/c/vawidi4o] Improvments after merging --- Adamant.xcodeproj/project.pbxproj | 2 +- Adamant/Modules/Account/AccountFactory.swift | 3 +-- .../AccountViewController.swift | 21 ++++++++----------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index 77498ac6b..aff50f247 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -2657,7 +2657,7 @@ E9E7CDBF2003AF6D00DFC4DB /* AdamantCellFactory.swift */, E93D7ABF2052CF63005D19DC /* AdamantNotificationService.swift */, 48F338A22D8BF2E0005C2E4A /* AdamantVisibleWalletsService */, - 4815586F2D65A7660011B470 /* SecretWalletsService.swift */, + 4815586F2D65A7660011B470 /* SecretWalletsManager.swift */, 4153045829C09902000E4BEA /* AdamantIncreaseFeeService.swift */, 48B799A72D84144C00BFD6A4 /* SecretWalletsFactory.swift */, 4184F1722A33102800D7B8B9 /* AdamantCrashlysticsService.swift */, diff --git a/Adamant/Modules/Account/AccountFactory.swift b/Adamant/Modules/Account/AccountFactory.swift index ce99c5802..a80376870 100644 --- a/Adamant/Modules/Account/AccountFactory.swift +++ b/Adamant/Modules/Account/AccountFactory.swift @@ -27,8 +27,7 @@ struct AccountFactory { languageService: assembler.resolve(LanguageStorageProtocol.self)!, walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, - visibleWalletsService: assembler.resolve(VisibleWalletsService.self)! - secretWalletsManager: assembler.resolve(SecretWalletsManagerProtocol.self)!, + visibleWalletsService: assembler.resolve(VisibleWalletsService.self)!, secretWalletsAlertService: assembler.resolve(SecretWalletsAlertMenuView.self)!, secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index d9b39fd6e..200512839 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -46,8 +46,6 @@ final class AccountViewController: FormViewController { private let languageService: LanguageStorageProtocol private let apiServiceCompose: ApiServiceComposeProtocol private let visibleWalletsService: VisibleWalletsService - private lazy var viewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) - private let secretWalletsManager: SecretWalletsManagerProtocol private lazy var walletsViewModel: AccountWalletsViewModel = .init(walletsStoreService: walletStoreServiceProvider) private let secretWalletsAlertService: SecretWalletsAlertMenuView private let secretWalletsViewModel: SecretWalletsViewModel @@ -95,7 +93,7 @@ final class AccountViewController: FormViewController { private var currentWalletCoinID: String = "" private var currentSelectedWalletItem: WalletCollectionViewCell.Model? { - viewModel.state.wallets.first { wallet in + walletsViewModel.state.wallets.first { wallet in wallet.coinID == currentWalletCoinID } } @@ -117,8 +115,7 @@ final class AccountViewController: FormViewController { languageService: LanguageStorageProtocol, walletServiceCompose: WalletServiceCompose, apiServiceCompose: ApiServiceComposeProtocol, - visibleWalletsService: VisibleWalletsService - secretWalletsManager: SecretWalletsManagerProtocol, + visibleWalletsService: VisibleWalletsService, secretWalletsAlertService: SecretWalletsAlertMenuView, secretWalletsViewModel: SecretWalletsViewModel ) { @@ -134,7 +131,6 @@ final class AccountViewController: FormViewController { self.languageService = languageService self.apiServiceCompose = apiServiceCompose self.visibleWalletsService = visibleWalletsService - self.secretWalletsManager = secretWalletsManager self.secretWalletsAlertService = secretWalletsAlertService self.secretWalletsViewModel = secretWalletsViewModel @@ -189,7 +185,7 @@ final class AccountViewController: FormViewController { guard let self = self else { return } self.setupWalletsVC() self.pagingViewController.reloadData() - self.pagingViewController.select(index: currentWalletIndex, animated: false) + selectCurrentWallet() guard index >= 0 else { return } self.accountHeaderView.setWalletIcon(index == 0 ? .regular : .secret, badgeCount: index) } @@ -234,6 +230,7 @@ final class AccountViewController: FormViewController { .sink { [weak self] _ in guard let self = self else { return } self.pagingViewController.reloadMenu() + self.selectCurrentWallet() } .store(in: ¬ificationsSet) @@ -355,7 +352,6 @@ final class AccountViewController: FormViewController { self.secretWalletsAlertService.presentSecretWalletsActionSheet(from: cell) } - // Добавление строки в секцию appSection.append(secretWalletsRow) // Node list @@ -1028,10 +1024,10 @@ final class AccountViewController: FormViewController { } private func selectCurrentWallet() { - if let index = viewModel.state.wallets.firstIndex(where: { $0.coinID == currentWalletCoinID }) { + if let index = walletsViewModel.state.wallets.firstIndex(where: { $0.coinID == currentWalletCoinID }) { pagingViewController.select(index: index, animated: false) - } else if let firstWalletID = viewModel.state.wallets.first?.coinID { - currentWalletCoinID = firstWalletID + } else if let firstWalletID = walletsViewModel.state.wallets.first?.coinID { + currentWalletCoinID = firstWalletID } } } @@ -1117,6 +1113,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr first.height != second.height else { return } + updateHeaderSize(with: second, animated: true) } } @@ -1126,7 +1123,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr didSelectItem pagingItem: PagingItem ) { Task { @MainActor in - currentWalletCoinID = viewModel.state.wallets.first(where: { wallet in + currentWalletCoinID = walletsViewModel.state.wallets.first(where: { wallet in wallet.index == pagingItem.identifier })?.coinID ?? "" } From 7b46536fa5440ae0a57b8eb3ac8b62636f6175ff Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Wed, 19 Mar 2025 13:15:38 +0700 Subject: [PATCH 22/36] =?UTF-8?q?[trello.com/c/Aw0Vfnmd]=20{Secret=20walle?= =?UTF-8?q?ts}=20UI:=20Show=20Transactions=20=F0=9F=94=90=201=EF=B8=8F?= =?UTF-8?q?=E2=83=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Adamant.xcdatamodel/contents | 3 ++- .../CoinTransaction+CoreDataProperties.swift | 1 + .../AdmTransactionsViewController.swift | 6 ++++-- .../Wallets/Adamant/AdmWalletFactory.swift | 3 ++- .../Wallets/Adamant/AdmWalletService.swift | 1 + .../BtcTransactionsViewController.swift | 6 ++++-- .../Wallets/Bitcoin/BtcWalletFactory.swift | 3 ++- .../Wallets/Bitcoin/BtcWalletService.swift | 6 +++--- .../Wallets/Dash/DashWalletFactory.swift | 3 ++- .../Wallets/Dash/DashWalletService.swift | 6 +++--- .../Wallets/Doge/DogeWalletFactory.swift | 3 ++- .../Wallets/Doge/DogeWalletService.swift | 4 ++-- .../Wallets/ERC20/ERC20WalletFactory.swift | 3 ++- .../Wallets/ERC20/ERC20WalletService.swift | 6 +++--- .../Wallets/Ethereum/EthWalletFactory.swift | 3 ++- .../Wallets/Ethereum/EthWalletService.swift | 4 ++-- .../Wallets/Klayr/KlyWalletFactory.swift | 3 ++- .../WalletService/KlyWalletService.swift | 6 +++--- .../TransactionsListViewControllerBase.swift | 7 +++++-- .../Services/AdamantCoinStorageService.swift | 19 ++++++++++++++----- 20 files changed, 61 insertions(+), 35 deletions(-) diff --git a/Adamant/Adamant.xcdatamodeld/Adamant.xcdatamodel/contents b/Adamant/Adamant.xcdatamodeld/Adamant.xcdatamodel/contents index ebf5ff422..18bd22603 100644 --- a/Adamant/Adamant.xcdatamodeld/Adamant.xcdatamodel/contents +++ b/Adamant/Adamant.xcdatamodeld/Adamant.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -53,6 +53,7 @@ + diff --git a/Adamant/Models/CoreData/CoinTransaction+CoreDataProperties.swift b/Adamant/Models/CoreData/CoinTransaction+CoreDataProperties.swift index b399faa13..6570b8466 100644 --- a/Adamant/Models/CoreData/CoinTransaction+CoreDataProperties.swift +++ b/Adamant/Models/CoreData/CoinTransaction+CoreDataProperties.swift @@ -19,6 +19,7 @@ extension CoinTransaction { @NSManaged public var amount: NSDecimalNumber? @NSManaged public var transactionId: String @NSManaged public var coinId: String? + @NSManaged public var uniqueId: String? @NSManaged public var senderId: String? @NSManaged public var recipientId: String? @NSManaged public var date: NSDate? diff --git a/Adamant/Modules/Wallets/Adamant/AdmTransactionsViewController.swift b/Adamant/Modules/Wallets/Adamant/AdmTransactionsViewController.swift index fffb4340c..b6b6eca04 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmTransactionsViewController.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmTransactionsViewController.swift @@ -42,7 +42,8 @@ final class AdmTransactionsViewController: TransactionsListViewControllerBase { screensFactory: ScreensFactory, addressBookService: AddressBookService, walletService: WalletService, - reachabilityMonitor: ReachabilityMonitor + reachabilityMonitor: ReachabilityMonitor, + secretWalletsViewModel: SecretWalletsViewModel ) { self.accountService = accountService self.transfersProvider = transfersProvider @@ -54,7 +55,8 @@ final class AdmTransactionsViewController: TransactionsListViewControllerBase { walletService: walletService, dialogService: dialogService, reachabilityMonitor: reachabilityMonitor, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: secretWalletsViewModel ) } diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift index 14a3208bb..902aaecfb 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletFactory.swift @@ -38,7 +38,8 @@ struct AdmWalletFactory: WalletFactory { screensFactory: screensFactory, addressBookService: assembler.resolve(AddressBookService.self)!, walletService: service, - reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)! + reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift index fd0c6f329..cd3b82c8f 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift @@ -117,6 +117,7 @@ final class AdmWalletService: NSObject, WalletCoreProtocol, WalletStaticCoreProt private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcTransactionsViewController.swift b/Adamant/Modules/Wallets/Bitcoin/BtcTransactionsViewController.swift index 50ec5ff4e..ebc22c5e0 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcTransactionsViewController.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcTransactionsViewController.swift @@ -23,7 +23,8 @@ final class BtcTransactionsViewController: TransactionsListViewControllerBase { dialogService: DialogService, reachabilityMonitor: ReachabilityMonitor, screensFactory: ScreensFactory, - addressBook: AddressBookService + addressBook: AddressBookService, + secretWalletsViewModel: SecretWalletsViewModel ) { self.addressBook = addressBook @@ -31,7 +32,8 @@ final class BtcTransactionsViewController: TransactionsListViewControllerBase { walletService: walletService, dialogService: dialogService, reachabilityMonitor: reachabilityMonitor, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: secretWalletsViewModel ) } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift index 6272b2ded..f278f8b37 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletFactory.swift @@ -34,7 +34,8 @@ struct BtcWalletFactory: WalletFactory { dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, screensFactory: screensFactory, - addressBook: assembler.resolve(AddressBookService.self)! + addressBook: assembler.resolve(AddressBookService.self)!, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift index d3ec914b6..310b8e545 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift @@ -202,6 +202,7 @@ final class BtcWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @unc private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) @@ -485,7 +486,8 @@ extension BtcWalletService { self.setState(.upToDate) Task { - self.update() + await self.update() + self.addTransactionObserver() } guard storeInKVC else { return eWallet } @@ -545,8 +547,6 @@ extension BtcWalletService: SwinjectDependentService { btcTransactionFactory = container.resolve(BitcoinKitTransactionFactoryProtocol.self) vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) - - addTransactionObserver() } } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift index e5d0ec1a4..06f558288 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletFactory.swift @@ -33,7 +33,8 @@ struct DashWalletFactory: WalletFactory { walletService: service, dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletService.swift b/Adamant/Modules/Wallets/Dash/DashWalletService.swift index 8f952c4b2..c907f3b4f 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletService.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletService.swift @@ -149,6 +149,7 @@ final class DashWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @un private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) @@ -342,7 +343,8 @@ extension DashWalletService { self.setState(.upToDate) Task { - self.update() + await self.update() + self.addTransactionObserver() } guard storeInKVC else { return eWallet } @@ -403,8 +405,6 @@ extension DashWalletService: SwinjectDependentService { dashApiService = container.resolve(DashApiService.self) vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) - - addTransactionObserver() } } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift index 707c73371..b03d3de75 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletFactory.swift @@ -33,7 +33,8 @@ struct DogeWalletFactory: WalletFactory { walletService: service, dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift index 589d29e31..902f9400d 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift @@ -170,6 +170,7 @@ final class DogeWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @un private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) @@ -361,6 +362,7 @@ extension DogeWalletService { Task { await self.update() + self.addTransactionObserver() } guard storeInKVC else { return eWallet } @@ -419,8 +421,6 @@ extension DogeWalletService: SwinjectDependentService { vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) chatsProvider = container.resolve(ChatsProvider.self) - - addTransactionObserver() } } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift index 8f71f5d65..37c864903 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletFactory.swift @@ -33,7 +33,8 @@ struct ERC20WalletFactory: WalletFactory { walletService: service, dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift index ec492a7b2..37fbd0d1a 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift @@ -187,6 +187,7 @@ final class ERC20WalletService: WalletCoreProtocol, @unchecked Sendable { private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: dynamicRichMessageType ) @@ -408,7 +409,8 @@ extension ERC20WalletService { self.setState(.upToDate, silent: true) Task { - await update() + await self.update() + self.addTransactionObserver() } return eWallet } @@ -431,8 +433,6 @@ extension ERC20WalletService: SwinjectDependentService { vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) ethBIP32Service = container.resolve(EthBIP32ServiceProtocol.self) - - addTransactionObserver() } } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift index 252eef064..4511845a6 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletFactory.swift @@ -33,7 +33,8 @@ struct EthWalletFactory: WalletFactory { walletService: service, dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index 7eb829d3e..1ef636e92 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -191,6 +191,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) @@ -446,6 +447,7 @@ extension EthWalletService { Task { await self.update() + self.addTransactionObserver() } guard storeInKVC else { return eWallet } @@ -534,8 +536,6 @@ extension EthWalletService: SwinjectDependentService { vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) ethBIP32Service = container.resolve(EthBIP32ServiceProtocol.self) - - addTransactionObserver() } } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift index 4197a698d..28e83848a 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletFactory.swift @@ -34,7 +34,8 @@ struct KlyWalletFactory: WalletFactory { walletService: service, dialogService: assembler.resolve(DialogService.self)!, reachabilityMonitor: assembler.resolve(ReachabilityMonitor.self)!, - screensFactory: screensFactory + screensFactory: screensFactory, + secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } diff --git a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift index ea056df2b..914a816bb 100644 --- a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift +++ b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift @@ -72,6 +72,7 @@ final class KlyWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @unc private(set) lazy var coinStorage: CoinStorageService = AdamantCoinStorageService( coinId: tokenUniqueID, + coinAddress: wallet?.address ?? "", coreDataStack: coreDataStack, blockchainType: richMessageType ) @@ -193,8 +194,6 @@ extension KlyWalletService: SwinjectDependentService { klyNodeApiService = container.resolve(KlyNodeApiService.self) vibroService = container.resolve(VibroService.self) coreDataStack = container.resolve(CoreDataStack.self) - - addTransactionObserver() } func addTransactionObserver() { @@ -468,7 +467,8 @@ private extension KlyWalletService { setState(.upToDate) Task { - await update() + await self.update() + self.addTransactionObserver() } guard storeInKVC else { return eWallet } diff --git a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift index 366a7d1a0..704cace50 100644 --- a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift @@ -55,6 +55,7 @@ class TransactionsListViewControllerBase: UIViewController { let dialogService: DialogService let reachabilityMonitor: ReachabilityMonitor let screensFactory: ScreensFactory + let secretWalletsViewModel: SecretWalletsViewModel // MARK: - Proprieties @@ -94,12 +95,14 @@ class TransactionsListViewControllerBase: UIViewController { walletService: WalletService, dialogService: DialogService, reachabilityMonitor: ReachabilityMonitor, - screensFactory: ScreensFactory + screensFactory: ScreensFactory, + secretWalletsViewModel: SecretWalletsViewModel ) { self.walletService = walletService self.dialogService = dialogService self.reachabilityMonitor = reachabilityMonitor self.screensFactory = screensFactory + self.secretWalletsViewModel = secretWalletsViewModel super.init(nibName: String(describing: TransactionsListViewControllerBase.self), bundle: nil) } @@ -114,7 +117,7 @@ class TransactionsListViewControllerBase: UIViewController { super.viewDidLoad() navigationItem.largeTitleDisplayMode = .never - navigationItem.title = String.adamant.transactionList.title + navigationItem.title = String.adamant.transactionList.title + (secretWalletsViewModel.state.currentWallet?.name ?? "") emptyLabel.text = String.adamant.transactionList.noTransactionYet update(walletService.core.getLocalTransactionHistory()) diff --git a/Adamant/Services/AdamantCoinStorageService.swift b/Adamant/Services/AdamantCoinStorageService.swift index d39721797..beff065ab 100644 --- a/Adamant/Services/AdamantCoinStorageService.swift +++ b/Adamant/Services/AdamantCoinStorageService.swift @@ -17,6 +17,7 @@ final class AdamantCoinStorageService: NSObject, CoinStorageService { private let blockchainType: String private let coinId: String + private let coinAddress: String private let coreDataStack: CoreDataStack private lazy var transactionController = getTransactionController() private var subscriptions = Set() @@ -29,8 +30,9 @@ final class AdamantCoinStorageService: NSObject, CoinStorageService { // MARK: Init - init(coinId: String, coreDataStack: CoreDataStack, blockchainType: String) { + init(coinId: String, coinAddress: String, coreDataStack: CoreDataStack, blockchainType: String) { self.coinId = coinId + self.coinAddress = coinAddress self.coreDataStack = coreDataStack self.blockchainType = blockchainType super.init() @@ -67,6 +69,7 @@ final class AdamantCoinStorageService: NSObject, CoinStorageService { coinTransaction.senderId = transaction.senderAddress coinTransaction.isOutgoing = transaction.isOutgoing coinTransaction.coinId = coinId + coinTransaction.uniqueId = coinId + coinAddress coinTransaction.transactionId = transaction.txId coinTransaction.transactionStatus = transaction.transactionStatus coinTransaction.blockchainType = blockchainType @@ -105,15 +108,21 @@ private extension AdamantCoinStorageService { .sink { [weak self] notification in let changes = notification.managedObjectContextChanges(of: CoinTransaction.self) + guard self != nil, self?.coinId != nil && self?.coinAddress != nil else { + return + } + + let uniqueId = self!.coinId + self!.coinAddress + if let inserted = changes.inserted, !inserted.isEmpty { let filteredInserted: [TransactionDetails] = inserted.filter { - $0.coinId == self?.coinId + $0.uniqueId == uniqueId } self?.transactions.append(contentsOf: filteredInserted) } if let updated = changes.updated, !updated.isEmpty { - let filteredUpdated = updated.filter { $0.coinId == self?.coinId } + let filteredUpdated = updated.filter { $0.uniqueId == uniqueId } filteredUpdated.forEach { coinTransaction in guard let index = self?.transactions.firstIndex(where: { @@ -133,7 +142,7 @@ private extension AdamantCoinStorageService { entityName: CoinTransaction.entityCoinName ) request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [ - NSPredicate(format: "coinId = %@", coinId) + NSPredicate(format: "uniqueId = %@", coinId + coinAddress) ]) request.sortDescriptors = [ NSSortDescriptor(key: "date", ascending: true), @@ -154,7 +163,7 @@ private extension AdamantCoinStorageService { /// - Returns: Transaction, if found func getTransactionFromDB(id: String, context: NSManagedObjectContext) -> CoinTransaction? { let request = NSFetchRequest(entityName: CoinTransaction.entityCoinName) - request.predicate = NSPredicate(format: "transactionId == %@", String(id)) + request.predicate = NSPredicate(format: "transactionId == %@ AND uniqueId == %@", String(id), coinId + coinAddress) request.fetchLimit = 1 do { From c87b13d9a4c43ab73dd2013e45fed22af68e0aa2 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 21 Mar 2025 16:11:18 +0700 Subject: [PATCH 23/36] [trello.com/c/Aw0Vfnmd] Handle case when user sends money from regular account to a secret one. --- .../Services/AdamantCoinStorageService.swift | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Adamant/Services/AdamantCoinStorageService.swift b/Adamant/Services/AdamantCoinStorageService.swift index beff065ab..970856faf 100644 --- a/Adamant/Services/AdamantCoinStorageService.swift +++ b/Adamant/Services/AdamantCoinStorageService.swift @@ -23,7 +23,7 @@ final class AdamantCoinStorageService: NSObject, CoinStorageService { private var subscriptions = Set() @ObservableValue private var transactions: [TransactionDetails] = [] - + var transactionsPublisher: any Observable<[TransactionDetails]> { $transactions } @@ -107,7 +107,7 @@ private extension AdamantCoinStorageService { ) .sink { [weak self] notification in let changes = notification.managedObjectContextChanges(of: CoinTransaction.self) - + guard self != nil, self?.coinId != nil && self?.coinAddress != nil else { return } @@ -130,7 +130,26 @@ private extension AdamantCoinStorageService { }) else { return } - self?.transactions[index] = coinTransaction + /* + Workaround to correctly set isOutgoing when multiple transactions share the same txId across different accounts. + + This situation can happen when sending funds from a regular account to a secret one — technically two different transactions, but with the same txId. + Currently, there's no reliable way to assign a truly unique ID to each TransactionDetails instance, so this workaround helps distinguish them for now. + PR - https://github.com/Adamant-im/adamant-iOS/pull/741 + */ + self?.transactions[index] = SimpleTransactionDetails( + defaultCurrencySymbol: coinTransaction.defaultCurrencySymbol, + txId: coinTransaction.txId, + senderAddress: coinTransaction.senderAddress, + recipientAddress: coinTransaction.recipientAddress, + dateValue: coinTransaction.dateValue, + amountValue: coinTransaction.amountValue, + feeValue: coinTransaction.feeValue, + confirmationsValue: coinTransaction.confirmationsValue, + blockValue: coinTransaction.blockValue, + isOutgoing: self?.coinAddress == coinTransaction.senderAddress ? true : false, + transactionStatus: coinTransaction.transactionStatus, + nonceRaw: coinTransaction.nonceRaw) } } } From 247261392b266bb559cb0444fc421af7fe181860 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Wed, 26 Mar 2025 13:45:49 +0700 Subject: [PATCH 24/36] [trello.com/c/Aw0Vfnmd] Code review improvments. --- Adamant/Services/AdamantCoinStorageService.swift | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Adamant/Services/AdamantCoinStorageService.swift b/Adamant/Services/AdamantCoinStorageService.swift index 970856faf..eb7d85a47 100644 --- a/Adamant/Services/AdamantCoinStorageService.swift +++ b/Adamant/Services/AdamantCoinStorageService.swift @@ -108,24 +108,24 @@ private extension AdamantCoinStorageService { .sink { [weak self] notification in let changes = notification.managedObjectContextChanges(of: CoinTransaction.self) - guard self != nil, self?.coinId != nil && self?.coinAddress != nil else { + guard let self else { return } - let uniqueId = self!.coinId + self!.coinAddress + let uniqueId = self.coinId + self.coinAddress if let inserted = changes.inserted, !inserted.isEmpty { let filteredInserted: [TransactionDetails] = inserted.filter { $0.uniqueId == uniqueId } - self?.transactions.append(contentsOf: filteredInserted) + self.transactions.append(contentsOf: filteredInserted) } if let updated = changes.updated, !updated.isEmpty { let filteredUpdated = updated.filter { $0.uniqueId == uniqueId } filteredUpdated.forEach { coinTransaction in - guard let index = self?.transactions.firstIndex(where: { + guard let index = self.transactions.firstIndex(where: { $0.txId == coinTransaction.txId }) else { return } @@ -133,11 +133,12 @@ private extension AdamantCoinStorageService { /* Workaround to correctly set isOutgoing when multiple transactions share the same txId across different accounts. - This situation can happen when sending funds from a regular account to a secret one — technically two different transactions, but with the same txId. + This situation can happen when sending funds from a regular account to a secret one or vica versa — technically is the same transaction, but it should show different isOutgoing for sender and reciever. + Currently, there's no reliable way to assign a truly unique ID to each TransactionDetails instance, so this workaround helps distinguish them for now. PR - https://github.com/Adamant-im/adamant-iOS/pull/741 */ - self?.transactions[index] = SimpleTransactionDetails( + self.transactions[index] = SimpleTransactionDetails( defaultCurrencySymbol: coinTransaction.defaultCurrencySymbol, txId: coinTransaction.txId, senderAddress: coinTransaction.senderAddress, @@ -147,7 +148,7 @@ private extension AdamantCoinStorageService { feeValue: coinTransaction.feeValue, confirmationsValue: coinTransaction.confirmationsValue, blockValue: coinTransaction.blockValue, - isOutgoing: self?.coinAddress == coinTransaction.senderAddress ? true : false, + isOutgoing: self.coinAddress == coinTransaction.senderAddress ? true : false, transactionStatus: coinTransaction.transactionStatus, nonceRaw: coinTransaction.nonceRaw) } From b09d1fb492b9d1984556a48813ba4bb24504478b Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Wed, 26 Mar 2025 19:02:54 +0700 Subject: [PATCH 25/36] [trello.com/c/YsjIF3DY] (Secret wallets) Handle logout/login case --- .../AccountViewController.swift | 2 +- .../SecretWalletsViewModel.swift | 24 +++++++++++++++---- .../SecretWalletsManagerProtocol.swift | 1 + Adamant/Services/AdamantAccountService.swift | 16 ++++++------- Adamant/Services/SecretWalletsManager.swift | 8 +++++++ 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 200512839..2024c6c91 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -178,8 +178,8 @@ final class AccountViewController: FormViewController { accountHeaderView.delegate = self secretWalletsViewModel.$state - .map { $0.currentActiveIndex } .removeDuplicates() + .map { $0.currentActiveIndex } .receive(on: DispatchQueue.main) .sink { [weak self] index in guard let self = self else { return } diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 587eff9fd..d620d5f1c 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -6,6 +6,7 @@ // Copyright © 2025 Adamant. All rights reserved. // +import Foundation import CommonKit import Combine @@ -22,11 +23,6 @@ final class SecretWalletsViewModel: ObservableObject { setup() } - private func setup() { - self.state.currentActiveIndex = 0 - self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) - } - func pickWallet(at index: Int) { if index == 0 { secretWalletsManager.activateDefaultWallet() @@ -46,3 +42,21 @@ final class SecretWalletsViewModel: ObservableObject { self.state.currentActiveIndex = index } } + +private extension SecretWalletsViewModel { + func setup() { + self.state.currentActiveIndex = 0 + self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) + + NotificationCenter.default.notifications(named: .AdamantAccountService.userLoggedOut) + .sink { [weak self] _ in await self?.removeAllSecretWallets() } + .store(in: &subscriptions) + } + + func removeAllSecretWallets() { + secretWalletsManager.removeAllSecretWallets() + secretWalletsManager.activateDefaultWallet() + state.currentActiveIndex = 0 + state.wallets.removeLast(state.wallets.count - 1) + } +} diff --git a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift index 3ec8d56d5..e97510c40 100644 --- a/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift +++ b/Adamant/ServiceProtocols/SecretWalletsManagerProtocol.swift @@ -17,6 +17,7 @@ protocol SecretWalletsManagerProtocol { func getSecretWallets() -> [WalletStoreServiceProtocol] func activateSecretWallet(at index: Int) func activateDefaultWallet() + func removeAllSecretWallets() } protocol SecretWalletsManagerStateProtocol { diff --git a/Adamant/Services/AdamantAccountService.swift b/Adamant/Services/AdamantAccountService.swift index acc0cb74a..ef612a00b 100644 --- a/Adamant/Services/AdamantAccountService.swift +++ b/Adamant/Services/AdamantAccountService.swift @@ -316,6 +316,14 @@ extension AdamantAccountService { _ = await initWallets() + let userInfo = [AdamantUserInfoKey.AccountService.loggedAccountAddress: account.address] + + NotificationCenter.default.post( + name: Notification.Name.AdamantAccountService.userLoggedIn, + object: self, + userInfo: userInfo + ) + return .success(account: account, alert: nil) } @@ -387,14 +395,6 @@ extension AdamantAccountService { self.keypair = keypair markBalanceAsFresh() - let userInfo = [AdamantUserInfoKey.AccountService.loggedAccountAddress: account.address] - - NotificationCenter.default.post( - name: Notification.Name.AdamantAccountService.userLoggedIn, - object: self, - userInfo: userInfo - ) - self.state = .loggedIn return account } catch let error as ApiServiceError { diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index 93181719b..a65e36b23 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -9,6 +9,7 @@ import Foundation import Swinject import CommonKit +import Combine private extension AdamantSecretWalletsManager { struct State: SecretWalletsManagerStateProtocol { @@ -27,6 +28,7 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { var wallets: [WalletStoreServiceProtocol] { [state.regularWallet] + state.secretWallets } private let lock = NSLock() + private var subscriptions = Set() init( walletsStoreService: WalletStoreServiceProtocol, @@ -76,4 +78,10 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { state.currentWallet = state.regularWallet statePublisher.send(state) } + + func removeAllSecretWallets() { + lock.lock() + defer { lock.unlock() } + state.secretWallets.removeAll() + } } From 04fbcbb2f82fb8204ef5d147209bc90f1c39f137 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 27 Mar 2025 13:52:29 +0700 Subject: [PATCH 26/36] [trello.com/c/YsjIF3DY] Code improvments --- Adamant/Modules/SecretWallets/SecretWalletsState.swift | 10 +++++++++- .../Modules/SecretWallets/SecretWalletsViewModel.swift | 3 --- Adamant/Services/SecretWalletsManager.swift | 2 -- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Adamant/Modules/SecretWallets/SecretWalletsState.swift b/Adamant/Modules/SecretWallets/SecretWalletsState.swift index 02b949cf4..0091b550f 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsState.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsState.swift @@ -17,7 +17,15 @@ struct SecretWalletsState: Equatable { return wallets[currentActiveIndex] } - static let `default` = Self(wallets: [], currentActiveIndex: -1) + static let `default` = Self( + wallets: [WalletItem( + name: String.localized( + "SecretWallets.Menu.Regular", + comment: "Secret wallet menu: regular wallet" + ) + )], + currentActiveIndex: 0 + ) } struct WalletItem: Equatable, Identifiable { diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index d620d5f1c..5648626b7 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -45,9 +45,6 @@ final class SecretWalletsViewModel: ObservableObject { private extension SecretWalletsViewModel { func setup() { - self.state.currentActiveIndex = 0 - self.state.wallets.append(WalletItem(name: String.localized("SecretWallets.Menu.Regular", comment: "Secret wallet menu: regular wallet"))) - NotificationCenter.default.notifications(named: .AdamantAccountService.userLoggedOut) .sink { [weak self] _ in await self?.removeAllSecretWallets() } .store(in: &subscriptions) diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index a65e36b23..512fa4487 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -9,7 +9,6 @@ import Foundation import Swinject import CommonKit -import Combine private extension AdamantSecretWalletsManager { struct State: SecretWalletsManagerStateProtocol { @@ -28,7 +27,6 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { var wallets: [WalletStoreServiceProtocol] { [state.regularWallet] + state.secretWallets } private let lock = NSLock() - private var subscriptions = Set() init( walletsStoreService: WalletStoreServiceProtocol, From 7e531f4c1bbdf5a92d28fce801049b7204fe5ffd Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Fri, 28 Mar 2025 10:46:15 +0700 Subject: [PATCH 27/36] [trello.com/c/vawidi4o] Fix `storeInKVS` typo --- Adamant/Modules/Wallets/Adamant/AdmWalletService.swift | 2 +- Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift | 4 ++-- Adamant/Modules/Wallets/Dash/DashWalletService.swift | 4 ++-- Adamant/Modules/Wallets/Doge/DogeWalletService.swift | 4 ++-- Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift | 2 +- Adamant/Modules/Wallets/Ethereum/EthWalletService.swift | 4 ++-- .../Wallets/Klayr/WalletService/KlyWalletService.swift | 8 ++++---- .../Wallets/WalletsService/WalletCoreProtocol.swift | 2 +- Adamant/Services/AdamantAccountService.swift | 2 +- Adamant/Services/SecretWalletsFactory.swift | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift index fd0c6f329..1b35003fd 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletService.swift @@ -225,7 +225,7 @@ final class AdmWalletService: NSObject, WalletCoreProtocol, WalletStaticCoreProt .init(sentDate: nil, status: .notInitiated) } - func initWallet(withPassphrase: String, withPassword: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase: String, withPassword: String, storeInKVS: Bool) async throws -> WalletAccount { throw InternalAPIError.unknownError } diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift index d3ec914b6..06162b5e8 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletService.swift @@ -445,7 +445,7 @@ extension BtcWalletService { btcWallet = nil } - func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -488,7 +488,7 @@ extension BtcWalletService { self.update() } - guard storeInKVC else { return eWallet } + guard storeInKVS else { return eWallet } // MARK: 4. Save address into KVS let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) diff --git a/Adamant/Modules/Wallets/Dash/DashWalletService.swift b/Adamant/Modules/Wallets/Dash/DashWalletService.swift index 8f952c4b2..6516f2c07 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletService.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletService.swift @@ -300,7 +300,7 @@ extension DashWalletService { } @MainActor - func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -345,7 +345,7 @@ extension DashWalletService { self.update() } - guard storeInKVC else { return eWallet } + guard storeInKVS else { return eWallet } // MARK: 4. Save address into KVS let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift index 589d29e31..260ea6def 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletService.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletService.swift @@ -319,7 +319,7 @@ extension DogeWalletService { dogeWallet = nil } - func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -363,7 +363,7 @@ extension DogeWalletService { await self.update() } - guard storeInKVC else { return eWallet } + guard storeInKVS else { return eWallet } // MARK: 4. Save address into KVS let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift index ec492a7b2..d12b034a3 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletService.swift @@ -368,7 +368,7 @@ final class ERC20WalletService: WalletCoreProtocol, @unchecked Sendable { // MARK: - WalletInitiatedWithPassphrase extension ERC20WalletService { - func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool) async throws -> WalletAccount { // MARK: 1. Prepare setState(.notInitiated) diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift index 7eb829d3e..3cfff39b3 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletService.swift @@ -402,7 +402,7 @@ final class EthWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, Smar // MARK: - WalletInitiatedWithPassphrase extension EthWalletService { - func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool) async throws -> WalletAccount { guard let adamant = accountService?.account else { throw WalletServiceError.notLogged } @@ -448,7 +448,7 @@ extension EthWalletService { await self.update() } - guard storeInKVC else { return eWallet } + guard storeInKVS else { return eWallet } // MARK: 4. Save into KVS let kvsAddressModel = makeKVSAddressModel(wallet: eWallet) diff --git a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift index ea056df2b..c7ce72d7d 100644 --- a/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift +++ b/Adamant/Modules/Wallets/Klayr/WalletService/KlyWalletService.swift @@ -99,9 +99,9 @@ final class KlyWalletService: WalletCoreProtocol, WalletStaticCoreProtocol, @unc // MARK: - func initWallet( - withPassphrase passphrase: String, withPassword password: String, storeInKVC: Bool + withPassphrase passphrase: String, withPassword password: String, storeInKVS: Bool ) async throws -> WalletAccount { - try await initWallet(passphrase: passphrase, password: password, storeInKVC: storeInKVC) + try await initWallet(passphrase: passphrase, password: password, storeInKVS: storeInKVS) } func setInitiationFailed(reason: String) { @@ -413,7 +413,7 @@ private extension KlyWalletService { // MARK: - Init Wallet private extension KlyWalletService { - func initWallet(passphrase: String, password: String, storeInKVC: Bool) async throws -> WalletAccount { + func initWallet(passphrase: String, password: String, storeInKVS: Bool) async throws -> WalletAccount { guard let adamant = accountService.account else { throw WalletServiceError.notLogged } @@ -471,7 +471,7 @@ private extension KlyWalletService { await update() } - guard storeInKVC else { return eWallet } + guard storeInKVS else { return eWallet } // Save into KVS diff --git a/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift b/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift index 679e1ad33..8dcb63b26 100644 --- a/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift +++ b/Adamant/Modules/Wallets/WalletsService/WalletCoreProtocol.swift @@ -305,7 +305,7 @@ protocol WalletCoreProtocol: AnyObject, Sendable { func updateStatus(for id: String, status: TransactionStatus?) func isExist(address: String) async throws -> Bool func statusInfoFor(transaction: CoinTransaction) async -> TransactionStatusInfo - func initWallet(withPassphrase: String, withPassword: String, storeInKVC: Bool) async throws -> WalletAccount + func initWallet(withPassphrase: String, withPassword: String, storeInKVS: Bool) async throws -> WalletAccount func setInitiationFailed(reason: String) func shortDescription(for transaction: RichMessageTransaction) -> NSAttributedString func getFee(comment: String) -> Decimal diff --git a/Adamant/Services/AdamantAccountService.swift b/Adamant/Services/AdamantAccountService.swift index acc0cb74a..1b0802368 100644 --- a/Adamant/Services/AdamantAccountService.swift +++ b/Adamant/Services/AdamantAccountService.swift @@ -428,7 +428,7 @@ extension AdamantAccountService { let result = try? await wallet.core.initWallet( withPassphrase: passphrase, withPassword: .empty, - storeInKVC: true + storeInKVS: true ) return result } diff --git a/Adamant/Services/SecretWalletsFactory.swift b/Adamant/Services/SecretWalletsFactory.swift index 4305f9078..697d6a18e 100644 --- a/Adamant/Services/SecretWalletsFactory.swift +++ b/Adamant/Services/SecretWalletsFactory.swift @@ -70,7 +70,7 @@ struct SecretWalletsFactory { _ = try? await wallet.core.initWallet( withPassphrase: passphrase, withPassword: password, - storeInKVC: false + storeInKVS: false ) } } From 8def2c712c1b9bff41eca7e7b242e87d173e19d4 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 31 Mar 2025 17:23:12 +0700 Subject: [PATCH 28/36] [trello.com/c/vawidi4o] Replace lock mechanizm with @Atomic property wrapper for SecretWalletsManager --- Adamant/Services/SecretWalletsManager.swift | 28 ++++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index 93181719b..70811bb83 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -21,13 +21,11 @@ private extension AdamantSecretWalletsManager { final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { private let secretWalletsFactory: SecretWalletsFactory - private var state: SecretWalletsManagerStateProtocol + @Atomic private var state: SecretWalletsManagerStateProtocol var statePublisher = ObservableSender() var wallets: [WalletStoreServiceProtocol] { [state.regularWallet] + state.secretWallets } - private let lock = NSLock() - init( walletsStoreService: WalletStoreServiceProtocol, secretWalletsFactory: SecretWalletsFactory @@ -42,16 +40,16 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { // MARK: - Manage state func createSecretWallet(withPassword password: String) { let wallet = secretWalletsFactory.makeSecretWallet(withPassword: password) - lock.lock() - defer { lock.unlock() } - state.secretWallets.append(wallet) + _state.mutate { + $0.secretWallets.append(wallet) + } } func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? { - lock.lock() - defer { lock.unlock() } guard state.secretWallets.indices.contains(index) else { return nil } - return state.secretWallets.remove(at: index) + return _state.mutate { + return $0.secretWallets.remove(at: index) + } } func getCurrentWallet() -> WalletStoreServiceProtocol { @@ -63,17 +61,17 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { } func activateSecretWallet(at index: Int) { - lock.lock() - defer { lock.unlock() } guard index < state.secretWallets.count else { return } - state.currentWallet = state.secretWallets[index] + _state.mutate { + $0.currentWallet = state.secretWallets[index] + } statePublisher.send(state) } func activateDefaultWallet() { - lock.lock() - defer { lock.unlock() } - state.currentWallet = state.regularWallet + _state.mutate { + $0.currentWallet = state.regularWallet + } statePublisher.send(state) } } From e8a05ff97320d17c09983249054c3731f59cc458 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 31 Mar 2025 17:33:25 +0700 Subject: [PATCH 29/36] [trello.com/c/YsjIF3DY] Update after merge --- Adamant/Services/SecretWalletsManager.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index dcbcff980..a0f007006 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -76,8 +76,8 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { } func removeAllSecretWallets() { - lock.lock() - defer { lock.unlock() } - state.secretWallets.removeAll() + _state.mutate { + $0.secretWallets.removeAll() + } } } From 2ce09c681acaf2d0e9785995b45f5fbdae25bf5c Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 31 Mar 2025 18:10:29 +0700 Subject: [PATCH 30/36] [trello.com/c/vawidi4o] Code review fix --- .../AccountWallets/AccountWalletsState.swift | 10 +++---- .../AccountWalletsViewModel.swift | 28 +++++++++---------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift index a2a314f24..865eb4e84 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift @@ -6,10 +6,8 @@ // Copyright © 2025 Adamant. All rights reserved. // -extension AccountViewController { - struct AccountWalletsState: Equatable { - var wallets: [WalletCollectionViewCell.Model] - - static let `default` = Self(wallets: []) - } +struct AccountWalletsState: Equatable { + var wallets: [WalletCollectionViewCell.Model] + + static let `default` = Self(wallets: []) } diff --git a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift index 36d300bec..c7d78603b 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift @@ -10,23 +10,21 @@ import Foundation import CommonKit import Combine -extension AccountViewController { - @MainActor - final class AccountWalletsViewModel { - @ObservableValue var state: AccountWalletsState = .default - - private let walletsStoreService: WalletStoreServiceProviderProtocol - private var walletSubscriptions: Set = [] - private var currentWalletPublisherSubscription: Set = [] - - init(walletsStoreService: WalletStoreServiceProviderProtocol) { - self.walletsStoreService = walletsStoreService - setup() - } +@MainActor +final class AccountWalletsViewModel { + @ObservableValue var state: AccountWalletsState = .default + + private let walletsStoreService: WalletStoreServiceProviderProtocol + private var walletSubscriptions: Set = [] + private var currentWalletPublisherSubscription: Set = [] + + init(walletsStoreService: WalletStoreServiceProviderProtocol) { + self.walletsStoreService = walletsStoreService + setup() } } -private extension AccountViewController.AccountWalletsViewModel { +private extension AccountWalletsViewModel { func setup() { addObservers() } @@ -79,7 +77,7 @@ private extension AccountViewController.AccountWalletsViewModel { } } -extension AccountViewController.AccountWalletsViewModel { +extension AccountWalletsViewModel { func updateState() { walletSubscriptions.removeAll() state.wallets.removeAll() From 7b96f7e46d391548e00f79f55e58c46f6bda7ae3 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Mon, 31 Mar 2025 19:36:02 +0700 Subject: [PATCH 31/36] [trello.com/c/vawidi4o] Atoimc in secretWalletsManager improvments --- .../AccountViewController.swift | 20 ++++++++++++++++++- Adamant/Services/SecretWalletsManager.swift | 16 ++++----------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index 200512839..44ed29354 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -1044,7 +1044,25 @@ extension AccountViewController: AccountHeaderViewDelegate { } let encodedAddress = AdamantUriTools.encode(request: AdamantUri.address(address: address, params: nil)) - dialogService.presentShareAlertFor(title: nil, stringForPasteboard: address, stringForShare: encodedAddress, stringForQR: encodedAddress, types: [.copyToPasteboard, .share, .generateQr(encodedContent: encodedAddress, sharingTip: address, withLogo: true)], excludedActivityTypes: ShareContentType.address.excludedActivityTypes, animated: true, from: from, completion: nil) + dialogService.presentShareAlertFor( + title: nil, + stringForPasteboard: address, + stringForShare: encodedAddress, + stringForQR: encodedAddress, + types: [ + .copyToPasteboard, + .share, + .generateQr( + encodedContent: encodedAddress, + sharingTip: address, + withLogo: true + ) + ], + excludedActivityTypes: ShareContentType.address.excludedActivityTypes, + animated: true, + from: from, + completion: nil + ) } } diff --git a/Adamant/Services/SecretWalletsManager.swift b/Adamant/Services/SecretWalletsManager.swift index 70811bb83..f31dff74b 100644 --- a/Adamant/Services/SecretWalletsManager.swift +++ b/Adamant/Services/SecretWalletsManager.swift @@ -40,16 +40,12 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { // MARK: - Manage state func createSecretWallet(withPassword password: String) { let wallet = secretWalletsFactory.makeSecretWallet(withPassword: password) - _state.mutate { - $0.secretWallets.append(wallet) - } + state.secretWallets.append(wallet) } func removeSecretWallet(at index: Int) -> WalletStoreServiceProtocol? { guard state.secretWallets.indices.contains(index) else { return nil } - return _state.mutate { - return $0.secretWallets.remove(at: index) - } + return state.secretWallets.remove(at: index) } func getCurrentWallet() -> WalletStoreServiceProtocol { @@ -62,16 +58,12 @@ final class AdamantSecretWalletsManager: SecretWalletsManagerProtocol { func activateSecretWallet(at index: Int) { guard index < state.secretWallets.count else { return } - _state.mutate { - $0.currentWallet = state.secretWallets[index] - } + state.currentWallet = state.secretWallets[index] statePublisher.send(state) } func activateDefaultWallet() { - _state.mutate { - $0.currentWallet = state.regularWallet - } + state.currentWallet = state.regularWallet statePublisher.send(state) } } From 9dd0bc0bee3a12d3ee01f56802fec8aca8a01309 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Tue, 1 Apr 2025 11:13:32 +0700 Subject: [PATCH 32/36] [trello.com/c/vawidi4o] Update NSLayoutConstraint to SnapKit in accountHeaderView.swift --- Adamant/Modules/Account/AccountHeaderView.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Adamant/Modules/Account/AccountHeaderView.swift b/Adamant/Modules/Account/AccountHeaderView.swift index 6ddef03fb..253915ef8 100644 --- a/Adamant/Modules/Account/AccountHeaderView.swift +++ b/Adamant/Modules/Account/AccountHeaderView.swift @@ -103,12 +103,11 @@ private extension AccountHeaderView { badgeLabel.translatesAutoresizingMaskIntoConstraints = false bgView.addSubview(badgeLabel) - NSLayoutConstraint.activate([ - badgeLabel.widthAnchor.constraint(equalToConstant: badgeSize), - badgeLabel.heightAnchor.constraint(equalToConstant: badgeSize), - badgeLabel.trailingAnchor.constraint(equalTo: bgView.trailingAnchor, constant: 0), - badgeLabel.bottomAnchor.constraint(equalTo: bgView.bottomAnchor, constant: 0) - ]) + badgeLabel.snp.makeConstraints { make in + make.width.height.equalTo(badgeSize) + make.trailing.equalTo(bgView.snp.trailing) + make.bottom.equalTo(bgView.snp.bottom) + } } func addPersistentOutline() { From a4c8ac8a263d33c1c80ca3650816204ddcd3a92e Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Tue, 8 Apr 2025 23:07:22 +0700 Subject: [PATCH 33/36] [trello.com/c/1SZ08BQ6] Add appropriate naming related to secret wallets --- Adamant.xcodeproj/project.pbxproj | 22 +++--- .../SecretWalletsViewModel.swift | 73 ++++++++++++++++++- .../Modules/Settings/SettingsFactory.swift | 2 +- .../VisibleWalletsViewController.swift | 7 +- .../Bitcoin/BtcWalletViewController.swift | 17 ----- .../Dash/DashWalletViewController.swift | 17 ----- .../Doge/DogeWalletViewController.swift | 17 ----- .../ERC20/ERC20WalletViewController.swift | 17 ----- .../Ethereum/EthWalletViewController.swift | 17 ----- .../Klayr/KlyWalletViewController.swift | 17 ----- .../TransactionsListViewControllerBase.swift | 2 +- .../Wallets/TransferViewControllerBase.swift | 7 +- .../Wallets/WalletViewControllerBase.swift | 10 ++- .../Localization/de.lproj/Localizable.strings | 25 ++++--- .../Localization/en.lproj/Localizable.strings | 25 ++++--- .../Localization/ru.lproj/Localizable.strings | 25 ++++--- .../Localization/zh.lproj/Localizable.strings | 25 ++++--- 17 files changed, 162 insertions(+), 163 deletions(-) diff --git a/Adamant.xcodeproj/project.pbxproj b/Adamant.xcodeproj/project.pbxproj index e386a6b2e..e02b12c4d 100644 --- a/Adamant.xcodeproj/project.pbxproj +++ b/Adamant.xcodeproj/project.pbxproj @@ -18,7 +18,7 @@ 557AC306287B10D8004699D7 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 557AC305287B10D8004699D7 /* SnapKit */; }; 55D1D84F287B78F200F94A4E /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 55D1D84E287B78F200F94A4E /* SnapKit */; }; 55D1D851287B78FC00F94A4E /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 55D1D850287B78FC00F94A4E /* SnapKit */; }; - 6403F5DB2272389800D58779 /* BuildFile in Sources */ = {isa = PBXBuildFile; }; + 6403F5DB2272389800D58779 /* (null) in Sources */ = {isa = PBXBuildFile; }; 6FB686162D3AAE8800CAB6DD /* AdamantWalletsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6FB686152D3AAE8800CAB6DD /* AdamantWalletsKit */; }; 9342F6C22A6A35E300A9B39F /* CommonKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9342F6C12A6A35E300A9B39F /* CommonKit */; }; 937751A52A68B3320054BD65 /* CommonKit in Frameworks */ = {isa = PBXBuildFile; productRef = 937751A42A68B3320054BD65 /* CommonKit */; }; @@ -31,7 +31,7 @@ A5241B70262DEDE1009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B6F262DEDE1009FA43E /* Clibsodium */; }; A5241B77262DEDEF009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B76262DEDEF009FA43E /* Clibsodium */; }; A5241B7E262DEDFE009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B7D262DEDFE009FA43E /* Clibsodium */; }; - A530B0D82842110D003F0210 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + A530B0D82842110D003F0210 /* (null) in Frameworks */ = {isa = PBXBuildFile; }; A544F0D4262C9878001F1A6D /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = A544F0D3262C9878001F1A6D /* Eureka */; }; A57282CA262C94CD00C96FA8 /* DateToolsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A57282C9262C94CD00C96FA8 /* DateToolsSwift */; }; A57282D1262C94DA00C96FA8 /* DateToolsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A57282D0262C94DA00C96FA8 /* DateToolsSwift */; }; @@ -249,8 +249,6 @@ }; D3A860F82DA1C1980007B599 /* NotificationsShared */ = { isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); path = NotificationsShared; sourceTree = ""; }; @@ -317,7 +315,7 @@ A5DBBABD262C7221004AC028 /* Clibsodium in Frameworks */, 6FB686162D3AAE8800CAB6DD /* AdamantWalletsKit in Frameworks */, 938F7D582955C1DA001915CA /* MessageKit in Frameworks */, - A530B0D82842110D003F0210 /* BuildFile in Frameworks */, + A530B0D82842110D003F0210 /* (null) in Frameworks */, 4177E5E12A52DA7100C089FE /* AdvancedContextMenuKit in Frameworks */, A5D87BA3262CA01D00DC28F0 /* ProcedureKit in Frameworks */, A5C99E0E262C9E3A00F7B1B7 /* Reachability in Frameworks */, @@ -669,12 +667,12 @@ A57282C8262C94CD00C96FA8 /* XCRemoteSwiftPackageReference "DateTools" */, A544F0D2262C9878001F1A6D /* XCRemoteSwiftPackageReference "Eureka" */, A5F0A049262C9CA90009672A /* XCRemoteSwiftPackageReference "Swinject" */, - A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */, + A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */, A5D87BA1262CA01D00DC28F0 /* XCRemoteSwiftPackageReference "ProcedureKit" */, A5AC8DFD262E0B030053A7E2 /* XCRemoteSwiftPackageReference "SipHash" */, 3A8875ED27BBF38D00436195 /* XCRemoteSwiftPackageReference "Parchment" */, 557AC304287B10D8004699D7 /* XCRemoteSwiftPackageReference "SnapKit" */, - 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */, + 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */, 938F7D562955C1DA001915CA /* XCRemoteSwiftPackageReference "MessageKit" */, 4184F16F2A33044E00D7B8B9 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, 3AC76E3B2AB09118008042C4 /* XCRemoteSwiftPackageReference "Elegant-Emoji-Picker" */, @@ -824,7 +822,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6403F5DB2272389800D58779 /* BuildFile in Sources */, + 6403F5DB2272389800D58779 /* (null) in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1367,7 +1365,7 @@ kind = branch; }; }; - 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */ = { + 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/socketio/socket.io-client-swift"; requirement = { @@ -1447,7 +1445,7 @@ minimumVersion = 1.2.2; }; }; - A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */ = { + A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/ashleymills/Reachability.swift"; requirement = { @@ -1526,7 +1524,7 @@ }; 416F5EA3290162EB00EF0400 /* SocketIO */ = { isa = XCSwiftPackageProductDependency; - package = 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */; + package = 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */; productName = SocketIO; }; 4177E5E02A52DA7100C089FE /* AdvancedContextMenuKit */ = { @@ -1644,7 +1642,7 @@ }; A5C99E0D262C9E3A00F7B1B7 /* Reachability */ = { isa = XCSwiftPackageProductDependency; - package = A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */; + package = A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */; productName = Reachability; }; A5D87BA2262CA01D00DC28F0 /* ProcedureKit */ = { diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 5648626b7..7830879c7 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -29,7 +29,7 @@ final class SecretWalletsViewModel: ObservableObject { } else { secretWalletsManager.activateSecretWallet(at: index - 1) } - state.currentActiveIndex = index // We must change state after to avoid bugs + state.currentActiveIndex = index } func createSecretWallet(password: String) { @@ -57,3 +57,74 @@ private extension SecretWalletsViewModel { state.wallets.removeLast(state.wallets.count - 1) } } + +// MARK: Naming generation +extension SecretWalletsViewModel { + func getCurrentWalletName(regularWithEmodji: Bool = true) -> String { + guard !regularWithEmodji else { + return state.wallets[state.currentActiveIndex].name + } + + if state.currentActiveIndex == 0 { + return String.localized("SecretWallets.Menu.Regular.WithoutEmodji", comment: "Regular Wallet") + } else { + return state.wallets[state.currentActiveIndex].name + } + } + + // Used in transferViewControllerBase + func getNameFor(walletCore: WalletCoreProtocol, regularWithEmodji: Bool = true) -> String { + let regular = regularWithEmodji ? String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") : String.localized("SecretWallets.Menu.Regular.WithoutEmodji", comment: "Regular Wallet") + var name = state.currentWallet?.name ?? regular + + for wallet in secretWalletsManager.getRegularWallet().sorted(includeInvisible: false) where wallet.core.wallet?.address == walletCore.wallet?.address { + name = regular + break + } + + return name + } + + // Used in wallet list, transactions list + func getCurrentWalletEmodji() -> String { + guard state.currentActiveIndex != 0 else { + return "" + } + return String.localized("SecretWallets.Menu.Secret\(state.currentActiveIndex).Emodji") + } + + // Used in walletViewControllerBase + func getCurrentWalletCoinName(withWalletService wallet: WalletService) -> String { + if state.wallets.count == 1 { + return String.localizedStringWithFormat( + String.localized( + "SecretWallets.Coin.Regular", + comment: "Regular Wallet" + ), + wallet.core.tokenName + ) + } + + if state.currentActiveIndex != 0 { + return String.localizedStringWithFormat( + String.localized( + "SecretWallets.Coin.Secret\(state.currentActiveIndex)", + comment: "Secret Wallet" + ), + wallet.core.tokenName + ) + } + + return String.localizedStringWithFormat( + String.localized( + "SecretWallets.Coin.SecretRegular", + comment: "Regular Wallet" + ), + wallet.core.tokenName + ) + } +} + +private extension SecretWalletsViewModel { + +} diff --git a/Adamant/Modules/Settings/SettingsFactory.swift b/Adamant/Modules/Settings/SettingsFactory.swift index 32abc40ec..6ad75dec0 100644 --- a/Adamant/Modules/Settings/SettingsFactory.swift +++ b/Adamant/Modules/Settings/SettingsFactory.swift @@ -44,7 +44,7 @@ struct SettingsFactory { VisibleWalletsViewController( visibleWalletsService: assembler.resolve(VisibleWalletsService.self)!, accountService: assembler.resolve(AccountService.self)!, - walletsStoreService: assembler.resolve(WalletStoreServiceProviderProtocol.self)! + walletsStoreService: assembler.resolve(WalletStoreServiceProviderProtocol.self)!, secretWalletsViewModel: assembler.resolve(SecretWalletsViewModel.self)! ) } } diff --git a/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift b/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift index 108d1550f..081960a05 100644 --- a/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift +++ b/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift @@ -54,6 +54,7 @@ final class VisibleWalletsViewController: KeyboardObservingViewController { var visibleWalletsService: VisibleWalletsService var walletsStoreService: WalletStoreServiceProviderProtocol var accountService: AccountService + var secretWalletsViewModel: SecretWalletsViewModel // MARK: - Properties @@ -75,11 +76,13 @@ final class VisibleWalletsViewController: KeyboardObservingViewController { init( visibleWalletsService: VisibleWalletsService, accountService: AccountService, - walletsStoreService: WalletStoreServiceProviderProtocol + walletsStoreService: WalletStoreServiceProviderProtocol, + secretWalletsViewModel: SecretWalletsViewModel ) { self.visibleWalletsService = visibleWalletsService self.accountService = accountService self.walletsStoreService = walletsStoreService + self.secretWalletsViewModel = secretWalletsViewModel super.init(nibName: nil, bundle: nil) } @@ -152,7 +155,7 @@ final class VisibleWalletsViewController: KeyboardObservingViewController { } private func setupView() { - navigationItem.title = String.adamant.visibleWallets.title + navigationItem.title = String.adamant.visibleWallets.title + " \(secretWalletsViewModel.getCurrentWalletEmodji())" navigationItem.searchController = searchController navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .search, target: self, action: #selector(activateSearch)) diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift index c2357dee8..ae90fef35 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift @@ -14,10 +14,6 @@ extension String.adamant { String.localized("AccountTab.Wallets.bitcoin_wallet", comment: "Account tab: Bitcoin wallet") } - static var secretBitcoin: String { - String.localized("SecretWallets.Bitcoin.Secret", comment: "Secret wallets: Bitcoin") - } - static var sendBtc: String { String.localized("AccountTab.Row.SendBtc", comment: "Account tab: 'Send BTC tokens' button") } @@ -32,17 +28,4 @@ final class BtcWalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "bitcoin:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String { - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.bitcoin - } else { - return String.adamant.secretBitcoin + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift index b6556b1d3..82c3ddeb2 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift @@ -15,10 +15,6 @@ extension String.adamant { String.localized("AccountTab.Wallets.dash_wallet", comment: "Account tab: Dash wallet") } - static var secretDash: String { - String.localized("SecretWallets.Dash.Secret", comment: "Account tab: Dash wallet") - } - static var sendDash: String { String.localized("AccountTab.Row.SendDash", comment: "Account tab: 'Send Dash tokens' button") } @@ -32,17 +28,4 @@ final class DashWalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "dash:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String { - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.dash - }else { - return String.adamant.secretDash + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift index 9de89aedb..3dfdedc49 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift @@ -14,10 +14,6 @@ extension String.adamant { String.localized("AccountTab.Wallets.doge_wallet", comment: "Account tab: Doge wallet") } - static var secretDoge: String { - String.localized("SecretWallets.Doge.Secret", comment: "Secret wallets: Doge") - } - static var sendDoge: String { String.localized("AccountTab.Row.SendDoge", comment: "Account tab: 'Send DOGE tokens' button") } @@ -31,17 +27,4 @@ final class DogeWalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "doge:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String { - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.doge - } else { - return String.adamant.secretDoge + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift index f56b0fc48..fbd09e79e 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift @@ -16,10 +16,6 @@ extension String.adamant.wallets { return String(format: .localized("AccountTab.Wallets.erc20_wallet", comment: "Account tab: Ethereum wallet"), token) } - static func secretTokenWallet(_ token: String) -> String { - return String(format: .localized("SecretWallets.erc20_wallet.Secret", comment: "Account tab: Ethereum wallet"), token) - } - static func sendToken(_ token: String) -> String { return String(format: .localized("AccountTab.Row.SendToken", comment: "Account tab: 'Send ERC20 tokens' button"), token) } @@ -52,17 +48,4 @@ final class ERC20WalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "ethereum:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String { - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.wallets.erc20.tokenWallet(service?.core.tokenName ?? "") - } else { - return String.adamant.wallets.erc20.secretTokenWallet(service?.core.tokenName ?? "") + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift index 7ffc09240..c142b23f0 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift @@ -14,10 +14,6 @@ extension String.adamant.wallets { String.localized("AccountTab.Wallets.ethereum_wallet", comment: "Account tab: Ethereum wallet") } - static var secretEthereum: String { - String.localized("SecretWallets.Ethereum.Secret", comment: "Account tab: Ethereum wallet") - } - static var sendEth: String { String.localized("AccountTab.Row.SendEth", comment: "Account tab: 'Send ETH tokens' button") } @@ -31,17 +27,4 @@ final class EthWalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "ethereum:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String { - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.wallets.ethereum - } else { - return String.adamant.wallets.secretEthereum + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift index 8df791802..651c1e967 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift @@ -14,10 +14,6 @@ extension String.adamant { String.localized("AccountTab.Wallets.kly_wallet", comment: "Account tab: Klayr wallet") } - static var secretKLY: String { - String.localized("SecretWallets.kly.Secret", comment: "Account tab: Klayr wallet") - } - static var sendKly: String { String.localized("AccountTab.Row.SendKly", comment: "Account tab: 'Send KLY tokens' button") } @@ -31,17 +27,4 @@ final class KlyWalletViewController: WalletViewControllerBase { override func encodeForQr(address: String) -> String? { return "klayr:\(address)" } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } - - override func makeTitle() -> String{ - let index = secretWalletsViewModel.state.currentActiveIndex - if index <= 0 { - return String.adamant.secretKLY - } else { - return String.adamant.secretKLY + " \(index)" - } - } } diff --git a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift index b2ae46c74..387d103c2 100644 --- a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift @@ -117,7 +117,7 @@ class TransactionsListViewControllerBase: UIViewController { super.viewDidLoad() navigationItem.largeTitleDisplayMode = .never - navigationItem.title = String.adamant.transactionList.title + (secretWalletsViewModel.state.currentWallet?.name ?? "") + navigationItem.title = String.adamant.transactionList.title + " " + secretWalletsViewModel.getCurrentWalletEmodji() emptyLabel.text = String.adamant.transactionList.noTransactionYet update(walletService.core.getLocalTransactionHistory()) diff --git a/Adamant/Modules/Wallets/TransferViewControllerBase.swift b/Adamant/Modules/Wallets/TransferViewControllerBase.swift index 539382d0e..6f89338cf 100644 --- a/Adamant/Modules/Wallets/TransferViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransferViewControllerBase.swift @@ -1078,12 +1078,7 @@ extension TransferViewControllerBase { $0.tag = BaseRows.type.tag $0.disabled = true - $0.value = secretWalletViewModel.state.currentWallet?.name ?? String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") - - for wallet in secretWalletManager.getRegularWallet().sorted(includeInvisible: false) where wallet.core.wallet?.address == walletCore.wallet?.address { - $0.value = String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") - break - } + $0.value = secretWalletViewModel.getNameFor(walletCore: walletCore, regularWithEmodji: false) } case .balance: diff --git a/Adamant/Modules/Wallets/WalletViewControllerBase.swift b/Adamant/Modules/Wallets/WalletViewControllerBase.swift index cbb4ee10b..43f668573 100644 --- a/Adamant/Modules/Wallets/WalletViewControllerBase.swift +++ b/Adamant/Modules/Wallets/WalletViewControllerBase.swift @@ -329,8 +329,14 @@ class WalletViewControllerBase: FormViewController, WalletViewController { return addressRow } - func makeTitle() -> String { fatalError("Should be overriden") } - func setTitle() { } + func makeTitle() -> String { + guard let service = service else { return "" } + return secretWalletsViewModel.getCurrentWalletCoinName(withWalletService: service) + } + + func setTitle() { + walletTitleLabel.text = makeTitle() + } // MARK: - Other diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 5890413bb..1350cdc80 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1408,11 +1408,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Normal"; +"SecretWallets.Menu.Regular.WithoutEmodji" = "Normal"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Geheim 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Geheim 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Geheim 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Geheim 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Geheim 5"; +"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "💡 Über Wallets"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; @@ -1422,12 +1428,13 @@ "SecretWallets.Menu.AddSecretWallet.Title" = "Geben Sie das Passwort ein, um eine geheime Wallet hinzuzufügen"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Passwort"; "SecretWallets.Menu.AddSecretWallet.Add" = "Hinzufügen"; -"SecretWallets.Row.Title" = "Geheime Geldbörsen"; - -/* Secret Wallets Coins name*/ -"SecretWallets.Bitcoin.Secret" = "Geheime Bitcoin-Wallet"; -"SecretWallets.Doge.Secret" = "Geheime Doge-Wallet"; -"SecretWallets.erc20_wallet.Secret" = "Geheime %@-Wallet"; -"SecretWallets.Dash.Secret" = "Geheime Dash-Wallet"; -"SecretWallets.Ethereum.Secret" = "Geheime Ethereum-Wallet"; -"SecretWallets.kly.Secret" = "Geheime KLY-Wallet"; +"SecretWallets.Row.Title" = "Geheime Wallets (Hinzufügen)"; + +/* Secret Wallets Coins names*/ +"SecretWallets.Coin.Regular" = "%@ Wallet"; +"SecretWallets.Coin.SecretRegular" = "Reguläres %@ Wallet"; +"SecretWallets.Coin.Secret1" = "Geheimes %@ Wallet 🔐1️⃣"; +"SecretWallets.Coin.Secret2" = "Geheimes %@ Wallet 🔐2️⃣"; +"SecretWallets.Coin.Secret3" = "Geheimes %@ Wallet 🔐3️⃣"; +"SecretWallets.Coin.Secret4" = "Geheimes %@ Wallet 🔐4️⃣"; +"SecretWallets.Coin.Secret5" = "Geheimes %@ Wallet 🔐5️⃣"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index e4e7e9011..f5832563a 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1384,11 +1384,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Regular"; +"SecretWallets.Menu.Regular.WithoutEmodji" = "Regular"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Secret 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Secret 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Secret 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Secret 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret 5"; +"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; @@ -1398,12 +1404,13 @@ "SecretWallets.Menu.AddSecretWallet.Title" = "Enter password to add secret wallet"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Password"; "SecretWallets.Menu.AddSecretWallet.Add" = "Add"; -"SecretWallets.Row.Title" = "Secret wallets"; - -/* Secret Wallets Coins name*/ -"SecretWallets.Bitcoin.Secret" = "Secret Bitcoin Wallet"; -"SecretWallets.Doge.Secret" = "Secret Doge Wallet"; -"SecretWallets.erc20_wallet.Secret" = "Secret %@ Wallet"; -"SecretWallets.Dash.Secret" = "Secret Dash Wallet"; -"SecretWallets.Ethereum.Secret" = "Secret Ethereum Wallet"; -"SecretWallets.kly.Secret" = "Secret KLY Wallet"; +"SecretWallets.Row.Title" = "Secret wallets (Add)"; + +/* Secret Wallets Coins names*/ +"SecretWallets.Coin.Regular" = "%@ Wallet"; +"SecretWallets.Coin.SecretRegular" = "Regular %@ Wallet"; +"SecretWallets.Coin.Secret1" = "Secret %@ Wallet 🔐1️⃣"; +"SecretWallets.Coin.Secret2" = "Secret %@ Wallet 🔐2️⃣"; +"SecretWallets.Coin.Secret3" = "Secret %@ Wallet 🔐3️⃣"; +"SecretWallets.Coin.Secret4" = "Secret %@ Wallet 🔐4️⃣"; +"SecretWallets.Coin.Secret5" = "Secret %@ Wallet 🔐5️⃣"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index e5ca7b020..28f8bc5f2 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1385,11 +1385,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Обычный"; +"SecretWallets.Menu.Regular.WithoutEmodji" = "Обычный"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Секретный 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Секретный 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Секретный 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Секретный 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Секретный 5"; +"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "💡 О кошельках"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; @@ -1399,12 +1405,13 @@ "SecretWallets.Menu.AddSecretWallet.Title" = "Введите пароль, чтобы добавить секретный кошелек"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "Пароль"; "SecretWallets.Menu.AddSecretWallet.Add" = "Добавить"; -"SecretWallets.Row.Title" = "Секретные кошельки"; - -/* Secret Wallets Coins name*/ -"SecretWallets.Bitcoin.Secret" = "Секретный Bitcoin кошелек"; -"SecretWallets.Doge.Secret" = "Секретный Doge кошелек"; -"SecretWallets.erc20_wallet.Secret" = "Секретный %@ кошелек"; -"SecretWallets.Dash.Secret" = "Секретный Dash кошелек"; -"SecretWallets.Ethereum.Secret" = "Секретный Ethereum кошелек"; -"SecretWallets.kly.Secret" = "Секретный KLY кошелек"; +"SecretWallets.Row.Title" = "Секретные кошельки (Добавить)"; + +/* Secret Wallets Coins names*/ +"SecretWallets.Coin.Regular" = "%@ кошелёк"; +"SecretWallets.Coin.SecretRegular" = "Обычный %@ кошелёк"; +"SecretWallets.Coin.Secret1" = "Секретный %@ кошелёк 🔐1️⃣"; +"SecretWallets.Coin.Secret2" = "Секретный %@ кошелёк 🔐2️⃣"; +"SecretWallets.Coin.Secret3" = "Секретный %@ кошелёк 🔐3️⃣"; +"SecretWallets.Coin.Secret4" = "Секретный %@ кошелёк 🔐4️⃣"; +"SecretWallets.Coin.Secret5" = "Секретный %@ кошелёк 🔐5️⃣"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 8a6fe8406..303370531 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1375,11 +1375,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 普通"; +"SecretWallets.Menu.Regular.WithoutEmodji" = "普通"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ 秘密 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ 秘密 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ 秘密 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ 秘密 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ 秘密 5"; +"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 添加秘密"; "SecretWallets.Menu.TellMeMore" = "💡 关于钱包"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; @@ -1389,12 +1395,13 @@ "SecretWallets.Menu.AddSecretWallet.Title" = "输入密码以添加秘密钱包"; "SecretWallets.Menu.AddSecretWallet.PasswordPlaceholder" = "密码"; "SecretWallets.Menu.AddSecretWallet.Add" = "添加"; -"SecretWallets.Row.Title" = "秘密钱包"; - -/* Secret Wallets Coins name*/ -"SecretWallets.Bitcoin.Secret" = "比特币秘密钱包"; -"SecretWallets.Doge.Secret" = "狗狗币秘密钱包"; -"SecretWallets.erc20_wallet.Secret" = "秘密 %@ 钱包"; -"SecretWallets.Dash.Secret" = "达世币秘密钱包"; -"SecretWallets.Ethereum.Secret" = "以太坊秘密钱包"; -"SecretWallets.kly.Secret" = "KLY 秘密钱包"; +"SecretWallets.Row.Title" = "秘密钱包(添加)"; + +/* Secret Wallets Coins names*/ +"SecretWallets.Coin.Regular" = "%@ 钱包"; +"SecretWallets.Coin.SecretRegular" = "常规 %@ 钱包"; +"SecretWallets.Coin.Secret1" = "秘密 %@ 钱包 🔐1️⃣"; +"SecretWallets.Coin.Secret2" = "秘密 %@ 钱包 🔐2️⃣"; +"SecretWallets.Coin.Secret3" = "秘密 %@ 钱包 🔐3️⃣"; +"SecretWallets.Coin.Secret4" = "秘密 %@ 钱包 🔐4️⃣"; +"SecretWallets.Coin.Secret5" = "秘密 %@ 钱包 🔐5️⃣"; From 0c47621986cdec2bfbb21689bc1963c63f5c82fa Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Wed, 9 Apr 2025 01:23:25 +0700 Subject: [PATCH 34/36] [trello.com/c/1SZ08BQ6] Handle right coins names --- .../SecretWalletsViewModel.swift | 8 ++++---- .../Adamant/AdmWalletViewController.swift | 20 ++++++++++--------- .../Bitcoin/BtcWalletViewController.swift | 9 ++++----- .../Dash/DashWalletViewController.swift | 8 ++++---- .../Doge/DogeWalletViewController.swift | 8 ++++---- .../ERC20/ERC20WalletViewController.swift | 9 +++++---- .../Ethereum/EthWalletViewController.swift | 7 +++---- .../Klayr/KlyWalletViewController.swift | 8 ++++---- .../Wallets/WalletViewControllerBase.swift | 8 ++++++-- .../Localization/de.lproj/Localizable.strings | 14 ++++++------- .../Localization/en.lproj/Localizable.strings | 14 ++++++------- .../Localization/ru.lproj/Localizable.strings | 14 ++++++------- .../Localization/zh.lproj/Localizable.strings | 14 ++++++------- 13 files changed, 73 insertions(+), 68 deletions(-) diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 7830879c7..4c97218b5 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -94,14 +94,14 @@ extension SecretWalletsViewModel { } // Used in walletViewControllerBase - func getCurrentWalletCoinName(withWalletService wallet: WalletService) -> String { + func getCurrentWalletCoinName(withCoinName name: String) -> String { if state.wallets.count == 1 { return String.localizedStringWithFormat( String.localized( "SecretWallets.Coin.Regular", comment: "Regular Wallet" ), - wallet.core.tokenName + name ) } @@ -111,7 +111,7 @@ extension SecretWalletsViewModel { "SecretWallets.Coin.Secret\(state.currentActiveIndex)", comment: "Secret Wallet" ), - wallet.core.tokenName + name ) } @@ -120,7 +120,7 @@ extension SecretWalletsViewModel { "SecretWallets.Coin.SecretRegular", comment: "Regular Wallet" ), - wallet.core.tokenName + name ) } } diff --git a/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift b/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift index 01cc99287..a147881fc 100644 --- a/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift +++ b/Adamant/Modules/Wallets/Adamant/AdmWalletViewController.swift @@ -12,10 +12,6 @@ import SafariServices import UIKit extension String.adamant.wallets { - static var adamant: String { - String.localized("AccountTab.Wallets.adamant_wallet", comment: "Account tab: Adamant wallet") - } - static var sendAdm: String { String.localized("AccountTab.Row.SendAdm", comment: "Account tab: 'Send ADM tokens' button") } @@ -56,6 +52,10 @@ extension String.adamant.wallets { } final class AdmWalletViewController: WalletViewControllerBase { + override var walletName: String { + String.localized("AccountTab.Wallets.adamant", comment: "Account tab: Adamant wallet") + } + // MARK: - Rows & Sections enum Rows { case stakeAdm, buyTokens, freeTokens @@ -279,13 +279,15 @@ final class AdmWalletViewController: WalletViewControllerBase { } return addressRow } - - override func setTitle() { - walletTitleLabel.text = makeTitle() - } override func makeTitle() -> String { - String.adamant.wallets.adamant + String.localizedStringWithFormat( + String.localized( + "SecretWallets.Coin.Regular", + comment: "Regular Wallet" + ), + walletName + ) } func updateRows() { diff --git a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift index ae90fef35..b4fb7a6bf 100644 --- a/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift +++ b/Adamant/Modules/Wallets/Bitcoin/BtcWalletViewController.swift @@ -10,17 +10,16 @@ import CommonKit import UIKit extension String.adamant { - static var bitcoin: String { - String.localized("AccountTab.Wallets.bitcoin_wallet", comment: "Account tab: Bitcoin wallet") - } - static var sendBtc: String { String.localized("AccountTab.Row.SendBtc", comment: "Account tab: 'Send BTC tokens' button") } } final class BtcWalletViewController: WalletViewControllerBase { - + override var walletName: String { + String.localized("AccountTab.Wallets.bitcoin", comment: "Account tab: Bitcoin wallet") + } + override func sendRowLocalizedLabel() -> NSAttributedString { return NSAttributedString(string: String.adamant.sendBtc) } diff --git a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift index 82c3ddeb2..006ee0544 100644 --- a/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift +++ b/Adamant/Modules/Wallets/Dash/DashWalletViewController.swift @@ -11,16 +11,16 @@ import Foundation import UIKit extension String.adamant { - static var dash: String { - String.localized("AccountTab.Wallets.dash_wallet", comment: "Account tab: Dash wallet") - } - static var sendDash: String { String.localized("AccountTab.Row.SendDash", comment: "Account tab: 'Send Dash tokens' button") } } final class DashWalletViewController: WalletViewControllerBase { + override var walletName: String { + String.localized("AccountTab.Wallets.dash", comment: "Account tab: Dash wallet") + } + override func sendRowLocalizedLabel() -> NSAttributedString { return NSAttributedString(string: String.adamant.sendDash) } diff --git a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift index 3dfdedc49..aa9e92bef 100644 --- a/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift +++ b/Adamant/Modules/Wallets/Doge/DogeWalletViewController.swift @@ -10,16 +10,16 @@ import CommonKit import UIKit extension String.adamant { - static var doge: String { - String.localized("AccountTab.Wallets.doge_wallet", comment: "Account tab: Doge wallet") - } - static var sendDoge: String { String.localized("AccountTab.Row.SendDoge", comment: "Account tab: 'Send DOGE tokens' button") } } final class DogeWalletViewController: WalletViewControllerBase { + override var walletName: String { + String.localized("AccountTab.Wallets.doge", comment: "Account tab: Doge wallet") + } + override func sendRowLocalizedLabel() -> NSAttributedString { return NSAttributedString(string: String.adamant.sendDoge) } diff --git a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift index fbd09e79e..40d581ff9 100644 --- a/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift +++ b/Adamant/Modules/Wallets/ERC20/ERC20WalletViewController.swift @@ -12,10 +12,6 @@ import UIKit extension String.adamant.wallets { enum erc20 { - static func tokenWallet(_ token: String) -> String { - return String(format: .localized("AccountTab.Wallets.erc20_wallet", comment: "Account tab: Ethereum wallet"), token) - } - static func sendToken(_ token: String) -> String { return String(format: .localized("AccountTab.Row.SendToken", comment: "Account tab: 'Send ERC20 tokens' button"), token) } @@ -23,6 +19,11 @@ extension String.adamant.wallets { } final class ERC20WalletViewController: WalletViewControllerBase { + override var walletName: String { + guard let tokenName = service?.core.tokenName else { return "" } + return String(format: .localized("AccountTab.Wallets.erc20", comment: "Account tab: Ethereum wallet"), tokenName) + } + override func sendRowLocalizedLabel() -> NSAttributedString { let networkSymbol = ERC20WalletService.tokenNetworkSymbol let tokenSymbol = String.adamant.wallets.erc20.sendToken(service?.core.tokenSymbol ?? "") diff --git a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift index c142b23f0..3556c04e8 100644 --- a/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift +++ b/Adamant/Modules/Wallets/Ethereum/EthWalletViewController.swift @@ -10,16 +10,15 @@ import CommonKit import UIKit extension String.adamant.wallets { - static var ethereum: String { - String.localized("AccountTab.Wallets.ethereum_wallet", comment: "Account tab: Ethereum wallet") - } - static var sendEth: String { String.localized("AccountTab.Row.SendEth", comment: "Account tab: 'Send ETH tokens' button") } } final class EthWalletViewController: WalletViewControllerBase { + override var walletName: String { + String.localized("AccountTab.Wallets.ethereum", comment: "Account tab: Ethereum wallet") + } override func sendRowLocalizedLabel() -> NSAttributedString { return NSAttributedString(string: String.adamant.wallets.sendEth) } diff --git a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift index 651c1e967..9ecfb634d 100644 --- a/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift +++ b/Adamant/Modules/Wallets/Klayr/KlyWalletViewController.swift @@ -10,16 +10,16 @@ import CommonKit import UIKit extension String.adamant { - static var kly: String { - String.localized("AccountTab.Wallets.kly_wallet", comment: "Account tab: Klayr wallet") - } - static var sendKly: String { String.localized("AccountTab.Row.SendKly", comment: "Account tab: 'Send KLY tokens' button") } } final class KlyWalletViewController: WalletViewControllerBase { + override var walletName: String { + String.localized("AccountTab.Wallets.kly", comment: "Account tab: Klayr wallet") + } + override func sendRowLocalizedLabel() -> NSAttributedString { return NSAttributedString(string: String.adamant.sendKly) } diff --git a/Adamant/Modules/Wallets/WalletViewControllerBase.swift b/Adamant/Modules/Wallets/WalletViewControllerBase.swift index 43f668573..417b167bb 100644 --- a/Adamant/Modules/Wallets/WalletViewControllerBase.swift +++ b/Adamant/Modules/Wallets/WalletViewControllerBase.swift @@ -23,6 +23,10 @@ protocol WalletViewControllerDelegate: AnyObject { } class WalletViewControllerBase: FormViewController, WalletViewController { + var walletName: String { + fatalError("Should be overridden") + } + // MARK: - Rows enum BaseRows { case address, balance, send @@ -330,8 +334,8 @@ class WalletViewControllerBase: FormViewController, WalletViewController { } func makeTitle() -> String { - guard let service = service else { return "" } - return secretWalletsViewModel.getCurrentWalletCoinName(withWalletService: service) + guard service != nil else { return "" } + return secretWalletsViewModel.getCurrentWalletCoinName(withCoinName: walletName) } func setTitle() { diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index 1350cdc80..b6aaafe42 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -251,25 +251,25 @@ "AccountTab.Section.Application" = "Application"; /* Account tab: Adamant wallet */ -"AccountTab.Wallets.adamant_wallet" = "ADAMANT Wallet"; +"AccountTab.Wallets.adamant" = "ADAMANT"; /* Account tab: Ethereum wallet */ -"AccountTab.Wallets.ethereum_wallet" = "Ethereum Wallet"; +"AccountTab.Wallets.ethereum" = "Ethereum"; /* Account tab: Klayr wallet */ -"AccountTab.Wallets.kly_wallet" = "Klayr Wallet"; +"AccountTab.Wallets.kly" = "Klayr"; /* Account tab: Bitcoin wallet */ -"AccountTab.Wallets.bitcoin_wallet" = "Bitcoin Wallet"; +"AccountTab.Wallets.bitcoin" = "Bitcoin"; /* Account tab: Doge wallet */ -"AccountTab.Wallets.doge_wallet" = "Doge Wallet"; +"AccountTab.Wallets.doge" = "Doge"; /* Account tab: Dash wallet */ -"AccountTab.Wallets.dash_wallet" = "Dash Wallet"; +"AccountTab.Wallets.dash" = "Dash"; /* Account tab: ERC20 wallet */ -"AccountTab.Wallets.erc20_wallet" = "%@ Wallet"; +"AccountTab.Wallets.erc20" = "%@"; /* Account page: scene title */ "AccountTab.Title" = "Konto"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index f5832563a..91553d70f 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -248,25 +248,25 @@ "AccountTab.Section.Application" = "Application"; /* Account tab: Adamant wallet */ -"AccountTab.Wallets.adamant_wallet" = "ADAMANT Wallet"; +"AccountTab.Wallets.adamant" = "ADAMANT"; /* Account tab: Ethereum wallet */ -"AccountTab.Wallets.ethereum_wallet" = "Ethereum Wallet"; +"AccountTab.Wallets.ethereum" = "Ethereum"; /* Account tab: Klayr wallet */ -"AccountTab.Wallets.kly_wallet" = "Klayr Wallet"; +"AccountTab.Wallets.kly" = "Klayr"; /* Account tab: Bitcoin wallet */ -"AccountTab.Wallets.bitcoin_wallet" = "Bitcoin Wallet"; +"AccountTab.Wallets.bitcoin" = "Bitcoin"; /* Account tab: Doge wallet */ -"AccountTab.Wallets.doge_wallet" = "Doge Wallet"; +"AccountTab.Wallets.doge" = "Doge"; /* Account tab: Dash wallet */ -"AccountTab.Wallets.dash_wallet" = "Dash Wallet"; +"AccountTab.Wallets.dash" = "Dash"; /* Account tab: ERC20 wallet */ -"AccountTab.Wallets.erc20_wallet" = "%@ Wallet"; +"AccountTab.Wallets.erc20" = "%@"; /* Account page: scene title */ "AccountTab.Title" = "Account"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 28f8bc5f2..7a0eb8b6a 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -248,25 +248,25 @@ "AccountTab.Section.Application" = "Приложение"; /* Account tab: Adamant wallet */ -"AccountTab.Wallets.adamant_wallet" = "Кошелек ADAMANT"; +"AccountTab.Wallets.adamant" = "ADAMANT"; /* Account tab: Ethereum wallet */ -"AccountTab.Wallets.ethereum_wallet" = "Кошелек Ethereum"; +"AccountTab.Wallets.ethereum" = "Ethereum"; /* Account tab: Klayr wallet */ -"AccountTab.Wallets.kly_wallet" = "Кошелек Klayr"; +"AccountTab.Wallets.kly" = "Klayr"; /* Account tab: Bitcoin wallet */ -"AccountTab.Wallets.bitcoin_wallet" = "Кошелек Bitcoin"; +"AccountTab.Wallets.bitcoin" = "Bitcoin"; /* Account tab: Doge wallet */ -"AccountTab.Wallets.doge_wallet" = "Кошелек Doge"; +"AccountTab.Wallets.doge" = "Doge"; /* Account tab: Dash wallet */ -"AccountTab.Wallets.dash_wallet" = "Кошелек Dash"; +"AccountTab.Wallets.dash" = "Dash"; /* Account tab: ERC20 wallet */ -"AccountTab.Wallets.erc20_wallet" = "Кошелек %@"; +"AccountTab.Wallets.erc20" = "%@"; /* Account tab: Delegates section title */ "AccountTab.Section.Delegates" = "Делегаты"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 303370531..51f165c63 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -248,25 +248,25 @@ "AccountTab.Section.Application" = "应用"; /* Account tab: Adamant wallet */ -"AccountTab.Wallets.adamant_wallet" = "ADAMANT钱包"; +"AccountTab.Wallets.adamant" = "ADAMANT"; /* Account tab: Ethereum wallet */ -"AccountTab.Wallets.ethereum_wallet" = "以太坊钱包"; +"AccountTab.Wallets.ethereum" = "以太坊"; /* Account tab: Klayr wallet */ -"AccountTab.Wallets.kly_wallet" = "Klayr钱包"; +"AccountTab.Wallets.kly" = "Klayr"; /* Account tab: Bitcoin wallet */ -"AccountTab.Wallets.bitcoin_wallet" = "比特币钱包"; +"AccountTab.Wallets.bitcoin" = "比特币"; /* Account tab: Doge wallet */ -"AccountTab.Wallets.doge_wallet" = "狗狗钱包"; +"AccountTab.Wallets.doge" = "狗狗"; /* Account tab: Dash wallet */ -"AccountTab.Wallets.dash_wallet" = "达世币钱包"; +"AccountTab.Wallets.dash" = "达世币"; /* Account tab: ERC20 wallet */ -"AccountTab.Wallets.erc20_wallet" = "%@钱包"; +"AccountTab.Wallets.erc20" = "%@"; /* Account page: scene title */ "AccountTab.Title" = "帐户"; From 774189ca64f26ea149aff5be754e0115d30b1b36 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 10 Apr 2025 11:11:58 +0300 Subject: [PATCH 35/36] [trello.com/c/ONt29HWW] Save the index of the current selected crypto in a carousel when switching between secrets and regular. --- .../Account/AccountViewController/AccountViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift index da2adb3fa..348700cbc 100644 --- a/Adamant/Modules/Account/AccountViewController/AccountViewController.swift +++ b/Adamant/Modules/Account/AccountViewController/AccountViewController.swift @@ -184,6 +184,9 @@ final class AccountViewController: FormViewController { guard let self = self else { return } self.setupWalletsVC() self.pagingViewController.reloadData() + if let pagingItemIndex = currentSelectedWallet?.identifier { + self.pagingViewController.select(index: pagingItemIndex, animated: false) + } guard index >= 0 else { return } self.accountHeaderView.setWalletIcon(index == 0 ? .regular : .secret, badgeCount: index) } From 64e17f7264fd52727475ced8466bbd611b0e3011 Mon Sep 17 00:00:00 2001 From: Dmitrij Meidus Date: Thu, 10 Apr 2025 11:31:44 +0300 Subject: [PATCH 36/36] [trello.com/c/1SZ08BQ6] Fix typo --- .../SecretWallets/SecretWalletsViewModel.swift | 14 +++++++------- .../VisibleWalletsViewController.swift | 2 +- .../TransactionsListViewControllerBase.swift | 2 +- .../Wallets/TransferViewControllerBase.swift | 2 +- .../Localization/de.lproj/Localizable.strings | 12 ++++++------ .../Localization/en.lproj/Localizable.strings | 12 ++++++------ .../Localization/ru.lproj/Localizable.strings | 12 ++++++------ .../Localization/zh.lproj/Localizable.strings | 12 ++++++------ 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift index 4c97218b5..28db16dc9 100644 --- a/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift +++ b/Adamant/Modules/SecretWallets/SecretWalletsViewModel.swift @@ -60,21 +60,21 @@ private extension SecretWalletsViewModel { // MARK: Naming generation extension SecretWalletsViewModel { - func getCurrentWalletName(regularWithEmodji: Bool = true) -> String { - guard !regularWithEmodji else { + func getCurrentWalletName(regularWithEmoji: Bool = true) -> String { + guard !regularWithEmoji else { return state.wallets[state.currentActiveIndex].name } if state.currentActiveIndex == 0 { - return String.localized("SecretWallets.Menu.Regular.WithoutEmodji", comment: "Regular Wallet") + return String.localized("SecretWallets.Menu.Regular.WithoutEmoji", comment: "Regular Wallet") } else { return state.wallets[state.currentActiveIndex].name } } // Used in transferViewControllerBase - func getNameFor(walletCore: WalletCoreProtocol, regularWithEmodji: Bool = true) -> String { - let regular = regularWithEmodji ? String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") : String.localized("SecretWallets.Menu.Regular.WithoutEmodji", comment: "Regular Wallet") + func getNameFor(walletCore: WalletCoreProtocol, regularWithEmoji: Bool = true) -> String { + let regular = regularWithEmoji ? String.localized("SecretWallets.Menu.Regular", comment: "Regular Wallet") : String.localized("SecretWallets.Menu.Regular.WithoutEmoji", comment: "Regular Wallet") var name = state.currentWallet?.name ?? regular for wallet in secretWalletsManager.getRegularWallet().sorted(includeInvisible: false) where wallet.core.wallet?.address == walletCore.wallet?.address { @@ -86,11 +86,11 @@ extension SecretWalletsViewModel { } // Used in wallet list, transactions list - func getCurrentWalletEmodji() -> String { + func getCurrentWalletEmoji() -> String { guard state.currentActiveIndex != 0 else { return "" } - return String.localized("SecretWallets.Menu.Secret\(state.currentActiveIndex).Emodji") + return String.localized("SecretWallets.Menu.Secret\(state.currentActiveIndex).Emoji") } // Used in walletViewControllerBase diff --git a/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift b/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift index 081960a05..f1902a53c 100644 --- a/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift +++ b/Adamant/Modules/Settings/VisibleWallets/VisibleWalletsViewController.swift @@ -155,7 +155,7 @@ final class VisibleWalletsViewController: KeyboardObservingViewController { } private func setupView() { - navigationItem.title = String.adamant.visibleWallets.title + " \(secretWalletsViewModel.getCurrentWalletEmodji())" + navigationItem.title = String.adamant.visibleWallets.title + " \(secretWalletsViewModel.getCurrentWalletEmoji())" navigationItem.searchController = searchController navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .search, target: self, action: #selector(activateSearch)) diff --git a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift index 387d103c2..059754bf8 100644 --- a/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransactionsListViewControllerBase.swift @@ -117,7 +117,7 @@ class TransactionsListViewControllerBase: UIViewController { super.viewDidLoad() navigationItem.largeTitleDisplayMode = .never - navigationItem.title = String.adamant.transactionList.title + " " + secretWalletsViewModel.getCurrentWalletEmodji() + navigationItem.title = String.adamant.transactionList.title + " " + secretWalletsViewModel.getCurrentWalletEmoji() emptyLabel.text = String.adamant.transactionList.noTransactionYet update(walletService.core.getLocalTransactionHistory()) diff --git a/Adamant/Modules/Wallets/TransferViewControllerBase.swift b/Adamant/Modules/Wallets/TransferViewControllerBase.swift index 6f89338cf..c0d8bb6da 100644 --- a/Adamant/Modules/Wallets/TransferViewControllerBase.swift +++ b/Adamant/Modules/Wallets/TransferViewControllerBase.swift @@ -1078,7 +1078,7 @@ extension TransferViewControllerBase { $0.tag = BaseRows.type.tag $0.disabled = true - $0.value = secretWalletViewModel.getNameFor(walletCore: walletCore, regularWithEmodji: false) + $0.value = secretWalletViewModel.getNameFor(walletCore: walletCore, regularWithEmoji: false) } case .balance: diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings index b6aaafe42..c91f46cbf 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/de.lproj/Localizable.strings @@ -1408,17 +1408,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Normal"; -"SecretWallets.Menu.Regular.WithoutEmodji" = "Normal"; +"SecretWallets.Menu.Regular.WithoutEmoji" = "Normal"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Geheim 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Geheim 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Geheim 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Geheim 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Geheim 5"; -"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; -"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; -"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; -"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; -"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; +"SecretWallets.Menu.Secret1.Emoji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emoji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emoji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emoji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emoji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Geheimen hinzufügen"; "SecretWallets.Menu.TellMeMore" = "💡 Über Wallets"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings index 91553d70f..07fff666b 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/en.lproj/Localizable.strings @@ -1384,17 +1384,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Regular"; -"SecretWallets.Menu.Regular.WithoutEmodji" = "Regular"; +"SecretWallets.Menu.Regular.WithoutEmoji" = "Regular"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Secret 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Secret 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Secret 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Secret 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Secret 5"; -"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; -"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; -"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; -"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; -"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; +"SecretWallets.Menu.Secret1.Emoji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emoji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emoji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emoji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emoji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Add secret wallet"; "SecretWallets.Menu.TellMeMore" = "💡 Tell me more"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings index 7a0eb8b6a..fd5f29aa4 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/ru.lproj/Localizable.strings @@ -1385,17 +1385,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 Обычный"; -"SecretWallets.Menu.Regular.WithoutEmodji" = "Обычный"; +"SecretWallets.Menu.Regular.WithoutEmoji" = "Обычный"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ Секретный 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ Секретный 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ Секретный 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ Секретный 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ Секретный 5"; -"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; -"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; -"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; -"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; -"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; +"SecretWallets.Menu.Secret1.Emoji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emoji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emoji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emoji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emoji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 Добавить секретный"; "SecretWallets.Menu.TellMeMore" = "💡 О кошельках"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum"; diff --git a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings index 51f165c63..00606360a 100644 --- a/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings +++ b/CommonKit/Sources/CommonKit/Assets/Localization/zh.lproj/Localizable.strings @@ -1375,17 +1375,17 @@ /* Secret Wallets */ "SecretWallets.Menu.Regular" = "💰 普通"; -"SecretWallets.Menu.Regular.WithoutEmodji" = "普通"; +"SecretWallets.Menu.Regular.WithoutEmoji" = "普通"; "SecretWallets.Menu.Secret1" = "🔐1️⃣ 秘密 1"; "SecretWallets.Menu.Secret2" = "🔐2️⃣ 秘密 2"; "SecretWallets.Menu.Secret3" = "🔐3️⃣ 秘密 3"; "SecretWallets.Menu.Secret4" = "🔐4️⃣ 秘密 4"; "SecretWallets.Menu.Secret5" = "🔐5️⃣ 秘密 5"; -"SecretWallets.Menu.Secret1.Emodji" = "🔐1️⃣"; -"SecretWallets.Menu.Secret2.Emodji" = "🔐2️⃣"; -"SecretWallets.Menu.Secret3.Emodji" = "🔐3️⃣"; -"SecretWallets.Menu.Secret4.Emodji" = "🔐4️⃣"; -"SecretWallets.Menu.Secret5.Emodji" = "🔐5️⃣"; +"SecretWallets.Menu.Secret1.Emoji" = "🔐1️⃣"; +"SecretWallets.Menu.Secret2.Emoji" = "🔐2️⃣"; +"SecretWallets.Menu.Secret3.Emoji" = "🔐3️⃣"; +"SecretWallets.Menu.Secret4.Emoji" = "🔐4️⃣"; +"SecretWallets.Menu.Secret5.Emoji" = "🔐5️⃣"; "SecretWallets.Menu.AddSecretWallet" = "🪄 添加秘密"; "SecretWallets.Menu.TellMeMore" = "💡 关于钱包"; "SecretWallets.Menu.TellMeMore.Title" = "Lorem Ipsum";