diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.h b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.h deleted file mode 100644 index 684a28b59..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class DWDPRegistrationStatus; - -@interface DWDPRegistrationDoneTableViewCell : UITableViewCell - -@property (nullable, nonatomic, strong) DWDPRegistrationStatus *status; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.m b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.m deleted file mode 100644 index 994186e13..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.m +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "DWDPRegistrationDoneTableViewCell.h" - -#import "DWDPRegistrationStatus.h" -#import "DWDashPayAnimationView.h" -#import "DWProgressView.h" -#import "DWUIKit.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface DWDPRegistrationDoneTableViewCell () - -@property (weak, nonatomic) IBOutlet UILabel *titleLabel; -@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; - -@end - -NS_ASSUME_NONNULL_END - -@implementation DWDPRegistrationDoneTableViewCell - -- (void)awakeFromNib { - [super awakeFromNib]; - - self.titleLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleSubheadline]; - self.descriptionLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleCaption1]; -} - -- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { - [super setHighlighted:highlighted animated:animated]; - - [self dw_pressedAnimation:DWPressedAnimationStrength_Light pressed:highlighted]; -} - -- (void)setStatus:(DWDPRegistrationStatus *)status { - _status = status; - - NSParameterAssert(status.username); - - self.titleLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Hello %@,", @"Hello username,"), status.username]; - self.descriptionLabel.text = [status stateDescription]; -} - -@end diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.xib b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.xib deleted file mode 100644 index f98409c98..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationDoneTableViewCell.xib +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorRetryDelegate.h b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorRetryDelegate.h deleted file mode 100644 index a40e577ab..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorRetryDelegate.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@protocol DWDPRegistrationErrorRetryDelegate - -- (void)registrationErrorRetryAction; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.h b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.h deleted file mode 100644 index dff82ebfe..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -#import "DWDPRegistrationErrorRetryDelegate.h" - -NS_ASSUME_NONNULL_BEGIN - -@class DWDPRegistrationStatus; - -@interface DWDPRegistrationErrorTableViewCell : UITableViewCell - -@property (nullable, nonatomic, strong) DWDPRegistrationStatus *status; -@property (nullable, nonatomic, weak) id delegate; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.m b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.m deleted file mode 100644 index ff8a09302..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.m +++ /dev/null @@ -1,82 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "DWDPRegistrationErrorTableViewCell.h" - -#import "DWDPRegistrationStatus.h" -#import "DWProgressView.h" -#import "DWUIKit.h" - - -@interface DWDPImageTitleButton : UIButton -@end - -@implementation DWDPImageTitleButton - -- (CGSize)intrinsicContentSize { - CGSize s = [super intrinsicContentSize]; - - return CGSizeMake(s.width + self.titleEdgeInsets.left + self.titleEdgeInsets.right, - s.height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom); -} - -@end - -NS_ASSUME_NONNULL_BEGIN - -@interface DWDPRegistrationErrorTableViewCell () - -@property (weak, nonatomic) IBOutlet UILabel *titleLabel; -@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; -@property (weak, nonatomic) IBOutlet DWProgressView *progressView; -@property (weak, nonatomic) IBOutlet UIButton *retryButton; - -@end - -NS_ASSUME_NONNULL_END - -@implementation DWDPRegistrationErrorTableViewCell - -- (void)awakeFromNib { - [super awakeFromNib]; - - self.titleLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleSubheadline]; - self.titleLabel.text = NSLocalizedString(@"Error Upgrading", nil); - self.descriptionLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleCaption1]; - - self.retryButton.tintColor = [UIColor dw_dashBlueColor]; - self.retryButton.titleLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleCaption1]; -} - -- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { - [super setHighlighted:highlighted animated:animated]; - - [self dw_pressedAnimation:DWPressedAnimationStrength_Light pressed:highlighted]; -} - -- (void)setStatus:(DWDPRegistrationStatus *)status { - _status = status; - - self.descriptionLabel.text = [status stateDescription]; - [self.progressView setProgress:[status progress] animated:YES]; -} - -- (IBAction)retryButtonAction:(id)sender { - [self.delegate registrationErrorRetryAction]; -} - -@end diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.xib b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.xib deleted file mode 100644 index 740b8ed97..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationErrorTableViewCell.xib +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.h b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.h deleted file mode 100644 index 08f4f039e..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class DWDPRegistrationStatus; - -@interface DWDPRegistrationStatusTableViewCell : UITableViewCell - -@property (nullable, nonatomic, strong) DWDPRegistrationStatus *status; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.m b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.m deleted file mode 100644 index cffae4406..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2020 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "DWDPRegistrationStatusTableViewCell.h" - -#import "DWDPRegistrationStatus.h" -#import "DWDashPayAnimationView.h" -#import "DWProgressView.h" -#import "DWUIKit.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface DWDPRegistrationStatusTableViewCell () - -@property (weak, nonatomic) IBOutlet DWDashPayAnimationView *animationView; -@property (weak, nonatomic) IBOutlet UILabel *titleLabel; -@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; -@property (weak, nonatomic) IBOutlet DWProgressView *progressView; - -@end - -NS_ASSUME_NONNULL_END - -@implementation DWDPRegistrationStatusTableViewCell - -- (void)awakeFromNib { - [super awakeFromNib]; - - self.titleLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleSubheadline]; - self.titleLabel.text = NSLocalizedString(@"Upgrading to DashPay", nil); - self.descriptionLabel.font = [UIFont dw_fontForTextStyle:UIFontTextStyleCaption1]; -} - -- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { - [super setHighlighted:highlighted animated:animated]; - - [self dw_pressedAnimation:DWPressedAnimationStrength_Light pressed:highlighted]; -} - -- (void)setStatus:(DWDPRegistrationStatus *)status { - _status = status; - - self.descriptionLabel.text = [status stateDescription]; - [self.progressView setProgress:[status progress] animated:YES]; -} - -- (void)willMoveToWindow:(nullable UIWindow *)newWindow { - [super willMoveToWindow:newWindow]; - - if (newWindow == nil) { - [self.animationView stopAnimating]; - } -} - -- (void)didMoveToWindow { - if (self.window) { - [self.animationView startAnimating]; - } -} - -@end diff --git a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.xib b/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.xib deleted file mode 100644 index 290d3aaa1..000000000 --- a/DashPay/Presentation/Home/Cells/Registration Status/DWDPRegistrationStatusTableViewCell.xib +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DashSyncCurrentCommit b/DashSyncCurrentCommit index cca84091a..799e70fbe 100644 --- a/DashSyncCurrentCommit +++ b/DashSyncCurrentCommit @@ -1 +1 @@ -343de629f6e561188db22918b507ea27a0f9be17 +e37280a9b369c25dc14d2001260206c8c21ae271 diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index ee79d71a3..8c37494d5 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -47,7 +47,6 @@ 114CFED2296489CD005F421B /* MinimumDepositBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114CFED1296489CD005F421B /* MinimumDepositBanner.swift */; }; 114D16B629812730009A124C /* OnlineAccountDetailsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114D16B529812730009A124C /* OnlineAccountDetailsController.swift */; }; 114D16B829828BCC009A124C /* OnlineAccountConfirmationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 114D16B729828BCC009A124C /* OnlineAccountConfirmationController.swift */; }; - 11517C832949E6A3004FC7BF /* CrowdNodeAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C822949E6A3004FC7BF /* CrowdNodeAPI.swift */; }; 11517C852949E6F0004FC7BF /* CrowdNodeEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C842949E6F0004FC7BF /* CrowdNodeEndpoint.swift */; }; 11517C87294B0FED004FC7BF /* CrowdNodeWebService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C86294B0FED004FC7BF /* CrowdNodeWebService.swift */; }; 11517C8A294B11DD004FC7BF /* CrowdNodeBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C89294B11DD004FC7BF /* CrowdNodeBalance.swift */; }; @@ -164,8 +163,6 @@ 2A4E535C22F335C200E5168A /* DWTransactionListDataProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A4E535B22F335C200E5168A /* DWTransactionListDataProvider.m */; }; 2A5279BC23D994BC00F856D3 /* CoreNFC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A5279BB23D994BC00F856D3 /* CoreNFC.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 2A58815921A5906C00FD4D2C /* DWBaseLegacyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A58815821A5906C00FD4D2C /* DWBaseLegacyViewController.m */; }; - 2A5E4548243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A5E4546243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m */; }; - 2A5E4549243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A5E4547243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib */; }; 2A63003F2327B4BB00827825 /* DWPaymentOutput+DWView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A63003E2327B4BB00827825 /* DWPaymentOutput+DWView.m */; }; 2A6300422328CCE900827825 /* LockScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A6300412328CCE900827825 /* LockScreen.storyboard */; }; 2A6300452328D07500827825 /* DWLockPinInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6300442328D07500827825 /* DWLockPinInputView.m */; }; @@ -181,7 +178,6 @@ 2A74EFF823053ECE00C475EB /* DWIntrinsicTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A74EFF723053ECE00C475EB /* DWIntrinsicTextView.m */; }; 2A74EFFB2305464C00C475EB /* DWRecoverTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A74EFFA2305464C00C475EB /* DWRecoverTextView.m */; }; 2A74EFFE2305763F00C475EB /* DWRecoverModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A74EFFD2305763F00C475EB /* DWRecoverModel.m */; }; - 2A74F0042305C59700C475EB /* UIViewController+DWTxFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A74F0032305C59700C475EB /* UIViewController+DWTxFilter.m */; }; 2A7A7BAE234770C900451078 /* DWCaptureSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A7BAD234770C900451078 /* DWCaptureSessionManager.m */; }; 2A7A7BB22347927700451078 /* DWMainMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A7BB12347927700451078 /* DWMainMenuViewController.m */; }; 2A7A7BBE2347950700451078 /* DWMainMenuTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A7BBC2347950700451078 /* DWMainMenuTableViewCell.m */; }; @@ -325,14 +321,9 @@ 2AF26F3B230C0E4C007F9228 /* DWBaseSeedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF26F3A230C0E4C007F9228 /* DWBaseSeedViewController.m */; }; 2AFCB9C423BE76EC00FF59A6 /* DWUpholdTransactionObject+DWView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFCB9C323BE76EC00FF59A6 /* DWUpholdTransactionObject+DWView.m */; }; 2AFF01DB243F4559003718DC /* DWDPRegistrationStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFF01DA243F4559003718DC /* DWDPRegistrationStatus.m */; }; - 2AFF01DF243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFF01DD243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m */; }; - 2AFF01E0243F74BF003718DC /* DWDPRegistrationErrorTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AFF01DE243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.xib */; }; - 2AFF01E5243F8626003718DC /* DWDPRegistrationDoneTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFF01E3243F8625003718DC /* DWDPRegistrationDoneTableViewCell.m */; }; - 2AFF01E6243F8626003718DC /* DWDPRegistrationDoneTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AFF01E4243F8625003718DC /* DWDPRegistrationDoneTableViewCell.xib */; }; 435AD52C799FC0B38E732134 /* libPods-WatchApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 07283055DE20FE578E399BE7 /* libPods-WatchApp.a */; }; 470617D6299A671900DCC667 /* CrowdNodeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 470617D5299A671900DCC667 /* CrowdNodeCell.swift */; }; 47081197298CF20C003FCA3D /* Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47081196298CF20B003FCA3D /* Transaction.swift */; }; - 47081199298CF57D003FCA3D /* TransactionListDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47081198298CF57D003FCA3D /* TransactionListDataSource.swift */; }; 4708119F2990F56F003FCA3D /* TransactionDataItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4708119E2990F56F003FCA3D /* TransactionDataItem.swift */; }; 47083B3229892D770010AF71 /* DSTransaction+DashWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47083B3129892D770010AF71 /* DSTransaction+DashWallet.swift */; }; 4709C30F287E787700B4BD48 /* Migrations.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4709C30E287E787700B4BD48 /* Migrations.bundle */; }; @@ -586,6 +577,8 @@ 755C32392C358FC0007DA721 /* BackupSeedPhraseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755C32372C358FBD007DA721 /* BackupSeedPhraseViewController.swift */; }; 755E6DFE2A99E7A000A42870 /* DWInvitationSetupState.m in Sources */ = {isa = PBXBuildFile; fileRef = 755E6DFC2A99E7A000A42870 /* DWInvitationSetupState.m */; }; 756188212B1EE78A00B778E3 /* DPVotingResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756188202B1EE78A00B778E3 /* DPVotingResultView.swift */; }; + 756557B52CE84FFA0060348D /* FeeInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756557B42CE84FF70060348D /* FeeInfo.swift */; }; + 756557B62CE84FFA0060348D /* FeeInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756557B42CE84FF70060348D /* FeeInfo.swift */; }; 7566F4832BB6949E005238D2 /* ToolsMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7566F4822BB69498005238D2 /* ToolsMenuViewController.swift */; }; 7566F4842BB6949E005238D2 /* ToolsMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7566F4822BB69498005238D2 /* ToolsMenuViewController.swift */; }; 7566F48A2BB6CAF2005238D2 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7566F4892BB6CAF2005238D2 /* MenuItem.swift */; }; @@ -593,6 +586,10 @@ 756FE7062CDCBB1B00E6C195 /* CreateUsernameViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756FE7052CDCBB1900E6C195 /* CreateUsernameViewModel.swift */; }; 756FE7082CDCBBC800E6C195 /* UsernameValidationRuleResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756FE7072CDCBBBB00E6C195 /* UsernameValidationRuleResult.swift */; }; 756FE70A2CDCD6D600E6C195 /* ValidationCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756FE7092CDCD6CD00E6C195 /* ValidationCheck.swift */; }; + 7571119D2CF1EF3900A7D452 /* CoinJoinMixingFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7571119C2CF1EF3600A7D452 /* CoinJoinMixingFilter.swift */; }; + 7571119E2CF1EF3900A7D452 /* CoinJoinMixingFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7571119C2CF1EF3600A7D452 /* CoinJoinMixingFilter.swift */; }; + 757111A02CF20ED800A7D452 /* CoinJoinMixingTxSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7571119F2CF20ED000A7D452 /* CoinJoinMixingTxSet.swift */; }; + 757111A12CF20ED800A7D452 /* CoinJoinMixingTxSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7571119F2CF20ED000A7D452 /* CoinJoinMixingTxSet.swift */; }; 7573C2DF2B00C05900F4C347 /* CastVoteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7573C2DE2B00C05900F4C347 /* CastVoteViewController.swift */; }; 7573C2E12B01103900F4C347 /* VotingFilterItemSelectableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7573C2E02B01103900F4C347 /* VotingFilterItemSelectableCell.swift */; }; 7573C2E32B01105F00F4C347 /* MasternodeIPCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7573C2E22B01105F00F4C347 /* MasternodeIPCell.swift */; }; @@ -624,6 +621,8 @@ 759609212C4553A400F3BF04 /* BuyCreditsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759609202C4553A400F3BF04 /* BuyCreditsViewController.swift */; }; 759609232C455B2000F3BF04 /* SendIntro.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759609222C455B2000F3BF04 /* SendIntro.swift */; }; 759609242C455B2000F3BF04 /* SendIntro.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759609222C455B2000F3BF04 /* SendIntro.swift */; }; + 759A7EA72CFDA707009423AD /* UIViewController+DWTxFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759A7EA62CFDA6FF009423AD /* UIViewController+DWTxFilter.swift */; }; + 759A7EA82CFDA707009423AD /* UIViewController+DWTxFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759A7EA62CFDA6FF009423AD /* UIViewController+DWTxFilter.swift */; }; 759ADD572BF3447400767ACD /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759ADD562BF3447400767ACD /* Button.swift */; }; 759ADD582BF3447400767ACD /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759ADD562BF3447400767ACD /* Button.swift */; }; 759AFDE02CC63571007072D2 /* JoinDashPayScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759AFDDF2CC6356D007072D2 /* JoinDashPayScreen.swift */; }; @@ -931,7 +930,6 @@ C94D982E2A544E8E00F3BEE1 /* UIButton+Dash.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94D982D2A544E8E00F3BEE1 /* UIButton+Dash.swift */; }; C94F5E8829D3E7E30034FD57 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C94F5E8729D3E7E30034FD57 /* GoogleService-Info.plist */; }; C94F5E8A29D3FCCF0034FD57 /* ShortcutAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94F5E8929D3FCCF0034FD57 /* ShortcutAction.swift */; }; - C94F5E8C29D3FEC10034FD57 /* ShortcutsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94F5E8B29D3FEC10034FD57 /* ShortcutsModel.swift */; }; C94F5E8E29D404850034FD57 /* ShortcutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94F5E8D29D404850034FD57 /* ShortcutCell.swift */; }; C94F5E9029D4060A0034FD57 /* ShortcutsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94F5E8F29D4060A0034FD57 /* ShortcutsView.swift */; }; C956AF0C2A5B591A002FAB75 /* DashInputField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94D98202A4CC78F00F3BEE1 /* DashInputField.swift */; }; @@ -964,7 +962,6 @@ C9D2C6972A320AA000D15901 /* DWBiometricAuthViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A44314622CF82D9009BAF7F /* DWBiometricAuthViewController.m */; }; C9D2C6982A320AA000D15901 /* CrowdNodeWebService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C86294B0FED004FC7BF /* CrowdNodeWebService.swift */; }; C9D2C6992A320AA000D15901 /* DWStartViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AB231D12196E25D00A6E7E6 /* DWStartViewController.m */; }; - C9D2C69A2A320AA000D15901 /* CrowdNodeAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11517C822949E6A3004FC7BF /* CrowdNodeAPI.swift */; }; C9D2C69B2A320AA000D15901 /* DWStartModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AB231D62196E5CF00A6E7E6 /* DWStartModel.m */; }; C9D2C69C2A320AA000D15901 /* DWAdvancedSecurityModelStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AB3417923A929B6004E37A7 /* DWAdvancedSecurityModelStub.m */; }; C9D2C69D2A320AA000D15901 /* Foundation+Bitcoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4709C32028818D5400B4BD48 /* Foundation+Bitcoin.swift */; }; @@ -1098,7 +1095,6 @@ C9D2C7372A320AA000D15901 /* DWSegmentSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A1F6411238D650200A9B505 /* DWSegmentSlider.m */; }; C9D2C7382A320AA000D15901 /* CoinbasePlaceBuyOrderRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6EDFA528C896BC000427E7 /* CoinbasePlaceBuyOrderRequest.swift */; }; C9D2C7392A320AA000D15901 /* CoinbaseAmount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6EDFB128C896BC000427E7 /* CoinbaseAmount.swift */; }; - C9D2C73A2A320AA000D15901 /* DWDPRegistrationErrorTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFF01DD243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m */; }; C9D2C73B2A320AA000D15901 /* SendAmountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47B30D7D29102F6E0080C326 /* SendAmountModel.swift */; }; C9D2C73C2A320AA000D15901 /* DWDecimalInputValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A9FFF252233E5CF00956D5F /* DWDecimalInputValidator.m */; }; C9D2C73D2A320AA000D15901 /* PaymentMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47CF46A729655E8E0067B6EE /* PaymentMethods.swift */; }; @@ -1232,7 +1228,6 @@ C9D2C7DA2A320AA000D15901 /* CrowdNodeErrorResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 119E8D0F290949B900D406C1 /* CrowdNodeErrorResponse.swift */; }; C9D2C7DC2A320AA000D15901 /* DWHomeModelStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A913E8123A30623006A2A59 /* DWHomeModelStub.m */; }; C9D2C7DD2A320AA000D15901 /* UISearchBar+DWAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ADC9D1B24603C4F001D7C0D /* UISearchBar+DWAdditions.m */; }; - C9D2C7DE2A320AA000D15901 /* UIViewController+DWTxFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A74F0032305C59700C475EB /* UIViewController+DWTxFilter.m */; }; C9D2C7E02A320AA000D15901 /* TransactionFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 117ED4A728ED66F9006E3EE4 /* TransactionFilter.swift */; }; C9D2C7E22A320AA000D15901 /* CrowdNodeWithdrawalReceivedTx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111C3C53296D6A2D00788E18 /* CrowdNodeWithdrawalReceivedTx.swift */; }; C9D2C7E32A320AA000D15901 /* PointOfUseListSegmentedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AE8C0228C1F0C600490F5E /* PointOfUseListSegmentedCell.swift */; }; @@ -1240,7 +1235,6 @@ C9D2C7E52A320AA000D15901 /* CoinbaseAPIEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6EDFB528C896BC000427E7 /* CoinbaseAPIEndpoint.swift */; }; C9D2C7E62A320AA000D15901 /* ConfirmOrderCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F4B6CC29485A8B00AED4C9 /* ConfirmOrderCells.swift */; }; C9D2C7E72A320AA000D15901 /* CoinbaseUserAccountData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6EDFAA28C896BC000427E7 /* CoinbaseUserAccountData.swift */; }; - C9D2C7E82A320AA000D15901 /* DWDPRegistrationDoneTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFF01E3243F8625003718DC /* DWDPRegistrationDoneTableViewCell.m */; }; C9D2C7E92A320AA000D15901 /* AtmDAO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AE8BA428BFADD900490F5E /* AtmDAO.swift */; }; C9D2C7EA2A320AA000D15901 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475AE2B82974348F009A1055 /* App.swift */; }; C9D2C7EB2A320AA000D15901 /* DWPaymentProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A0C69A2231048DA001B8C90 /* DWPaymentProcessor.m */; }; @@ -1264,7 +1258,6 @@ C9D2C8052A320AA000D15901 /* IntegrationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47838B86290670630003E8AB /* IntegrationViewController.swift */; }; C9D2C8062A320AA000D15901 /* NSString+DWTextSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AD1CE7F22DC92BF00C99324 /* NSString+DWTextSize.m */; }; C9D2C8072A320AA000D15901 /* PointOfUseListFiltersCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AE8C0428C1F74A00490F5E /* PointOfUseListFiltersCell.swift */; }; - C9D2C8082A320AA000D15901 /* TransactionListDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47081198298CF57D003FCA3D /* TransactionListDataSource.swift */; }; C9D2C80A2A320AA000D15901 /* DWMainMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A7BB12347927700451078 /* DWMainMenuViewController.m */; }; C9D2C80B2A320AA000D15901 /* PointOfUseListFiltersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47838B7C290133610003E8AB /* PointOfUseListFiltersViewController.swift */; }; C9D2C80C2A320AA000D15901 /* AllMerchantLocationsDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47AE8C1928C6A21A00490F5E /* AllMerchantLocationsDataProvider.swift */; }; @@ -1288,7 +1281,6 @@ C9D2C8232A320AA000D15901 /* BaseNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478A2C6E28DC457000AD1420 /* BaseNavigationController.swift */; }; C9D2C8242A320AA000D15901 /* UIViewController+Coinbase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47CDEECB294A2BAD008AE06D /* UIViewController+Coinbase.swift */; }; C9D2C8262A320AA000D15901 /* CSVBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472D13E0299E1F2F006903F1 /* CSVBuilder.swift */; }; - C9D2C8272A320AA000D15901 /* DWDPRegistrationStatusTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A5E4546243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m */; }; C9D2C8282A320AA000D15901 /* CoinbaseUserAuthInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6EDF9D28C896BC000427E7 /* CoinbaseUserAuthInformation.swift */; }; C9D2C8292A320AA000D15901 /* DWTransactionStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A913EB523A7E145006A2A59 /* DWTransactionStub.m */; }; C9D2C82A2A320AA000D15901 /* OnlineAccountEmailController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 118C05B729928F7800717E65 /* OnlineAccountEmailController.swift */; }; @@ -1337,7 +1329,6 @@ C9D2C8592A320AA000D15901 /* CrowdNodePortalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1147687D294B789800FB1EEE /* CrowdNodePortalViewController.swift */; }; C9D2C85A2A320AA000D15901 /* ConfirmOrderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F4B6C929484C9800AED4C9 /* ConfirmOrderModel.swift */; }; C9D2C85B2A320AA000D15901 /* PointOfUseListEmptyResultsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472CEE002924AA6D00656B48 /* PointOfUseListEmptyResultsView.swift */; }; - C9D2C85C2A320AA000D15901 /* ShortcutsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94F5E8B29D3FEC10034FD57 /* ShortcutsModel.swift */; }; C9D2C85D2A320AA000D15901 /* DWLockPinInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6300442328D07500827825 /* DWLockPinInputView.m */; }; C9D2C85E2A320AA000D15901 /* UIView+DWHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A0C69AB23125074001B8C90 /* UIView+DWHUD.m */; }; C9D2C85F2A320AA000D15901 /* DWPayOptionModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A8B9E6722FFE4CC00FF8653 /* DWPayOptionModel.m */; }; @@ -1473,7 +1464,6 @@ C9D2C9072A320AA000D15901 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 222040C51C1A1940005CE1C3 /* WebKit.framework */; }; C9D2C9082A320AA000D15901 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 22B6A4471C0E963900673913 /* libbz2.tbd */; }; C9D2C90B2A320AA000D15901 /* DWShortcutCollectionViewCell~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A1AF6DC23C7681B00442AF5 /* DWShortcutCollectionViewCell~ipad.xib */; }; - C9D2C90C2A320AA000D15901 /* DWDPRegistrationErrorTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AFF01DE243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.xib */; }; C9D2C90D2A320AA000D15901 /* ExploreDash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 47838B7E290160860003E8AB /* ExploreDash.storyboard */; }; C9D2C90E2A320AA000D15901 /* TxDetailHeaderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 474C720C298A19D100475CA6 /* TxDetailHeaderCell.xib */; }; C9D2C90F2A320AA000D15901 /* StartStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2AB231D32196E27300A6E7E6 /* StartStoryboard.storyboard */; }; @@ -1488,7 +1478,6 @@ C9D2C91C2A320AA000D15901 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 2ADC722723B5547000D9DD37 /* Localizable.stringsdict */; }; C9D2C91D2A320AA000D15901 /* ShortcutsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A2CD71722F99CAE008C7BC9 /* ShortcutsView.xib */; }; C9D2C91E2A320AA000D15901 /* HomeBalanceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C9F067F329E457790022D958 /* HomeBalanceView.xib */; }; - C9D2C91F2A320AA000D15901 /* DWDPRegistrationStatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A5E4547243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib */; }; C9D2C9202A320AA000D15901 /* TxDetailInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 474C7212298A1EFC00475CA6 /* TxDetailInfoCell.xib */; }; C9D2C9212A320AA000D15901 /* UpholdOTPStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A9FFE552230FF4600956D5F /* UpholdOTPStoryboard.storyboard */; }; C9D2C9222A320AA000D15901 /* AppAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A4430F122CBD57A009BAF7F /* AppAssets.xcassets */; }; @@ -1510,7 +1499,6 @@ C9D2C9342A320AA000D15901 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A913E7023A2667E006A2A59 /* Onboarding.storyboard */; }; C9D2C9352A320AA000D15901 /* OperationStatus.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1193FF3D2962F1BE004EA8D7 /* OperationStatus.storyboard */; }; C9D2C9362A320AA000D15901 /* UpholdLogoutTutorialStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A9FFE662230FF4600956D5F /* UpholdLogoutTutorialStoryboard.storyboard */; }; - C9D2C9392A320AA000D15901 /* DWDPRegistrationDoneTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2AFF01E4243F8625003718DC /* DWDPRegistrationDoneTableViewCell.xib */; }; C9D2C93A2A320AA000D15901 /* ResetWalletInfo.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A10EB402358D2A900C38B61 /* ResetWalletInfo.storyboard */; }; C9D2C93B2A320AA000D15901 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB66977E212C0B940034BE4F /* LaunchScreen.storyboard */; }; C9D2C93C2A320AA000D15901 /* Pay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2A8B9E5B22FF6FE500FF8653 /* Pay.storyboard */; }; @@ -1693,7 +1681,6 @@ 114CFED1296489CD005F421B /* MinimumDepositBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MinimumDepositBanner.swift; sourceTree = ""; }; 114D16B529812730009A124C /* OnlineAccountDetailsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlineAccountDetailsController.swift; sourceTree = ""; }; 114D16B729828BCC009A124C /* OnlineAccountConfirmationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlineAccountConfirmationController.swift; sourceTree = ""; }; - 11517C822949E6A3004FC7BF /* CrowdNodeAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeAPI.swift; sourceTree = ""; }; 11517C842949E6F0004FC7BF /* CrowdNodeEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeEndpoint.swift; sourceTree = ""; }; 11517C86294B0FED004FC7BF /* CrowdNodeWebService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeWebService.swift; sourceTree = ""; }; 11517C89294B11DD004FC7BF /* CrowdNodeBalance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeBalance.swift; sourceTree = ""; }; @@ -1884,9 +1871,6 @@ 2A58815721A5906C00FD4D2C /* DWBaseLegacyViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWBaseLegacyViewController.h; sourceTree = ""; }; 2A58815821A5906C00FD4D2C /* DWBaseLegacyViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWBaseLegacyViewController.m; sourceTree = ""; }; 2A5BB89B2350BA4F00C87CCE /* DWWipeDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWWipeDelegate.h; sourceTree = ""; }; - 2A5E4545243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWDPRegistrationStatusTableViewCell.h; sourceTree = ""; }; - 2A5E4546243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWDPRegistrationStatusTableViewCell.m; sourceTree = ""; }; - 2A5E4547243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DWDPRegistrationStatusTableViewCell.xib; sourceTree = ""; }; 2A63003D2327B4BB00827825 /* DWPaymentOutput+DWView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DWPaymentOutput+DWView.h"; sourceTree = ""; }; 2A63003E2327B4BB00827825 /* DWPaymentOutput+DWView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "DWPaymentOutput+DWView.m"; sourceTree = ""; }; 2A6300412328CCE900827825 /* LockScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LockScreen.storyboard; sourceTree = ""; }; @@ -1914,8 +1898,6 @@ 2A74EFFA2305464C00C475EB /* DWRecoverTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWRecoverTextView.m; sourceTree = ""; }; 2A74EFFC2305763F00C475EB /* DWRecoverModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWRecoverModel.h; sourceTree = ""; }; 2A74EFFD2305763F00C475EB /* DWRecoverModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWRecoverModel.m; sourceTree = ""; }; - 2A74F0022305C59700C475EB /* UIViewController+DWTxFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+DWTxFilter.h"; sourceTree = ""; }; - 2A74F0032305C59700C475EB /* UIViewController+DWTxFilter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+DWTxFilter.m"; sourceTree = ""; }; 2A74F0082305F1C100C475EB /* DWRecoverAction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWRecoverAction.h; sourceTree = ""; }; 2A7A7BAC234770C900451078 /* DWCaptureSessionManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWCaptureSessionManager.h; sourceTree = ""; }; 2A7A7BAD234770C900451078 /* DWCaptureSessionManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWCaptureSessionManager.m; sourceTree = ""; }; @@ -2005,7 +1987,6 @@ 2A913E6D23A26663006A2A59 /* DWOnboardingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWOnboardingViewController.h; sourceTree = ""; }; 2A913E6E23A26663006A2A59 /* DWOnboardingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWOnboardingViewController.m; sourceTree = ""; }; 2A913E7023A2667E006A2A59 /* Onboarding.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Onboarding.storyboard; sourceTree = ""; }; - 2A913E7723A2F2B6006A2A59 /* DWTxDisplayModeProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWTxDisplayModeProtocol.h; sourceTree = ""; }; 2A913E7A23A2F7ED006A2A59 /* DWHomeProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWHomeProtocol.h; sourceTree = ""; }; 2A913E7B23A2FF4A006A2A59 /* DWRootProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWRootProtocol.h; sourceTree = ""; }; 2A913E7D23A30609006A2A59 /* DWRootModelStub.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWRootModelStub.h; sourceTree = ""; }; @@ -2210,19 +2191,11 @@ 2AFCB9C323BE76EC00FF59A6 /* DWUpholdTransactionObject+DWView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "DWUpholdTransactionObject+DWView.m"; sourceTree = ""; }; 2AFF01D9243F4559003718DC /* DWDPRegistrationStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWDPRegistrationStatus.h; sourceTree = ""; }; 2AFF01DA243F4559003718DC /* DWDPRegistrationStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWDPRegistrationStatus.m; sourceTree = ""; }; - 2AFF01DC243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWDPRegistrationErrorTableViewCell.h; sourceTree = ""; }; - 2AFF01DD243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWDPRegistrationErrorTableViewCell.m; sourceTree = ""; }; - 2AFF01DE243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DWDPRegistrationErrorTableViewCell.xib; sourceTree = ""; }; - 2AFF01E2243F8625003718DC /* DWDPRegistrationDoneTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWDPRegistrationDoneTableViewCell.h; sourceTree = ""; }; - 2AFF01E3243F8625003718DC /* DWDPRegistrationDoneTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DWDPRegistrationDoneTableViewCell.m; sourceTree = ""; }; - 2AFF01E4243F8625003718DC /* DWDPRegistrationDoneTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DWDPRegistrationDoneTableViewCell.xib; sourceTree = ""; }; 3410FBA3C9ECBF291385B203 /* Pods-dashwallet no watch.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-dashwallet no watch.release.xcconfig"; path = "Pods/Target Support Files/Pods-dashwallet no watch/Pods-dashwallet no watch.release.xcconfig"; sourceTree = ""; }; 362213F26B43E7CB81B2FCE2 /* Pods-dashwallet.testnet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-dashwallet.testnet.xcconfig"; path = "Pods/Target Support Files/Pods-dashwallet/Pods-dashwallet.testnet.xcconfig"; sourceTree = ""; }; 3BF640216ECD5FBFC17B85D3 /* Pods-dashpay.testflight.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-dashpay.testflight.xcconfig"; path = "Pods/Target Support Files/Pods-dashpay/Pods-dashpay.testflight.xcconfig"; sourceTree = ""; }; 470617D5299A671900DCC667 /* CrowdNodeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrowdNodeCell.swift; sourceTree = ""; }; 47081196298CF20B003FCA3D /* Transaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transaction.swift; sourceTree = ""; }; - 47081198298CF57D003FCA3D /* TransactionListDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TransactionListDataSource.swift; path = DashWallet/Sources/UI/Home/Models/TransactionListDataSource.swift; sourceTree = SOURCE_ROOT; }; - 4708119C298CF9E0003FCA3D /* DWDPRegistrationErrorRetryDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DWDPRegistrationErrorRetryDelegate.h; sourceTree = ""; }; 4708119E2990F56F003FCA3D /* TransactionDataItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionDataItem.swift; sourceTree = ""; }; 47083B3129892D770010AF71 /* DSTransaction+DashWallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DSTransaction+DashWallet.swift"; sourceTree = ""; }; 4709C30E287E787700B4BD48 /* Migrations.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Migrations.bundle; sourceTree = ""; }; @@ -2474,12 +2447,15 @@ 755E6DFC2A99E7A000A42870 /* DWInvitationSetupState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DWInvitationSetupState.m; sourceTree = ""; }; 755E6DFD2A99E7A000A42870 /* DWInvitationSetupState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWInvitationSetupState.h; sourceTree = ""; }; 756188202B1EE78A00B778E3 /* DPVotingResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DPVotingResultView.swift; sourceTree = ""; }; + 756557B42CE84FF70060348D /* FeeInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeeInfo.swift; sourceTree = ""; }; 7566F4822BB69498005238D2 /* ToolsMenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolsMenuViewController.swift; sourceTree = ""; }; 7566F4892BB6CAF2005238D2 /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; }; 756A8F131CE566F6007893E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Interface.strings; sourceTree = ""; }; 756FE7052CDCBB1900E6C195 /* CreateUsernameViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateUsernameViewModel.swift; sourceTree = ""; }; 756FE7072CDCBBBB00E6C195 /* UsernameValidationRuleResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsernameValidationRuleResult.swift; sourceTree = ""; }; 756FE7092CDCD6CD00E6C195 /* ValidationCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationCheck.swift; sourceTree = ""; }; + 7571119C2CF1EF3600A7D452 /* CoinJoinMixingFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinJoinMixingFilter.swift; sourceTree = ""; }; + 7571119F2CF20ED000A7D452 /* CoinJoinMixingTxSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinJoinMixingTxSet.swift; sourceTree = ""; }; 7573C2DE2B00C05900F4C347 /* CastVoteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CastVoteViewController.swift; sourceTree = ""; }; 7573C2E02B01103900F4C347 /* VotingFilterItemSelectableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingFilterItemSelectableCell.swift; sourceTree = ""; }; 7573C2E22B01105F00F4C347 /* MasternodeIPCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MasternodeIPCell.swift; sourceTree = ""; }; @@ -2503,6 +2479,7 @@ 759609222C455B2000F3BF04 /* SendIntro.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendIntro.swift; sourceTree = ""; }; 759816E519357D6F005060EA /* BRBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BRBubbleView.h; sourceTree = ""; }; 759816E619357D6F005060EA /* BRBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BRBubbleView.m; sourceTree = ""; }; + 759A7EA62CFDA6FF009423AD /* UIViewController+DWTxFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+DWTxFilter.swift"; sourceTree = ""; }; 759ADD562BF3447400767ACD /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; 759AFDDF2CC6356D007072D2 /* JoinDashPayScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinDashPayScreen.swift; sourceTree = ""; }; 759AFDE22CC67E89007072D2 /* VotingInfoScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingInfoScreen.swift; sourceTree = ""; }; @@ -3003,7 +2980,6 @@ C94D982D2A544E8E00F3BEE1 /* UIButton+Dash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Dash.swift"; sourceTree = ""; }; C94F5E8729D3E7E30034FD57 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; C94F5E8929D3FCCF0034FD57 /* ShortcutAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutAction.swift; sourceTree = ""; }; - C94F5E8B29D3FEC10034FD57 /* ShortcutsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsModel.swift; sourceTree = ""; }; C94F5E8D29D404850034FD57 /* ShortcutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutCell.swift; sourceTree = ""; }; C94F5E8F29D4060A0034FD57 /* ShortcutsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsView.swift; sourceTree = ""; }; C956AF152A5C3301002FAB75 /* DWPressableButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWPressableButton.h; sourceTree = ""; }; @@ -3358,7 +3334,6 @@ isa = PBXGroup; children = ( 11517C88294B11CE004FC7BF /* DTOs */, - 11517C822949E6A3004FC7BF /* CrowdNodeAPI.swift */, 11517C842949E6F0004FC7BF /* CrowdNodeEndpoint.swift */, ); path = API; @@ -3367,6 +3342,7 @@ 11517C88294B11CE004FC7BF /* DTOs */ = { isa = PBXGroup; children = ( + 756557B42CE84FF70060348D /* FeeInfo.swift */, 11517C89294B11DD004FC7BF /* CrowdNodeBalance.swift */, 111C3C4D296C52F800788E18 /* WithdrawalLimit.swift */, 1186092029758B2F00279FCC /* IsAddressInUse.swift */, @@ -3728,7 +3704,6 @@ 2A913EA123A799D9006A2A59 /* Transactions */, 2A4E533622F023AB00E5168A /* DWHomeModel.h */, 2A4E533722F023AB00E5168A /* DWHomeModel.m */, - 47081198298CF57D003FCA3D /* TransactionListDataSource.swift */, 2A56EF0424193AEB002C32F3 /* DWDashPayModel.h */, 2A56EF0524193AEB002C32F3 /* DWDashPayModel.m */, 2AFF01D9243F4559003718DC /* DWDPRegistrationStatus.h */, @@ -3754,7 +3729,6 @@ isa = PBXGroup; children = ( C94F5E8929D3FCCF0034FD57 /* ShortcutAction.swift */, - C94F5E8B29D3FEC10034FD57 /* ShortcutsModel.swift */, ); path = Models; sourceTree = ""; @@ -4068,23 +4042,6 @@ path = Cells; sourceTree = ""; }; - 2A5E4544243E0595006BA067 /* Registration Status */ = { - isa = PBXGroup; - children = ( - 4708119C298CF9E0003FCA3D /* DWDPRegistrationErrorRetryDelegate.h */, - 2AFF01E2243F8625003718DC /* DWDPRegistrationDoneTableViewCell.h */, - 2AFF01E3243F8625003718DC /* DWDPRegistrationDoneTableViewCell.m */, - 2AFF01E4243F8625003718DC /* DWDPRegistrationDoneTableViewCell.xib */, - 2AFF01DC243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.h */, - 2AFF01DD243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m */, - 2AFF01DE243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.xib */, - 2A5E4545243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.h */, - 2A5E4546243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m */, - 2A5E4547243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib */, - ); - path = "Registration Status"; - sourceTree = ""; - }; 2A6300402328CCAC00827825 /* LockScreen */ = { isa = PBXGroup; children = ( @@ -4477,7 +4434,6 @@ isa = PBXGroup; children = ( 2A913E7A23A2F7ED006A2A59 /* DWHomeProtocol.h */, - 2A913E7723A2F2B6006A2A59 /* DWTxDisplayModeProtocol.h */, 2A56EF0724193BA9002C32F3 /* DWDashPayProtocol.h */, ); path = Protocols; @@ -4600,8 +4556,7 @@ 2A913E7223A2EAEF006A2A59 /* Protocols */, 2A2CD6E522F46D1A008C7BC9 /* Models */, 2A307CB322E6FA7F00A18347 /* Views */, - 2A74F0022305C59700C475EB /* UIViewController+DWTxFilter.h */, - 2A74F0032305C59700C475EB /* UIViewController+DWTxFilter.m */, + 759A7EA62CFDA6FF009423AD /* UIViewController+DWTxFilter.swift */, C94946DE2A25EDA8008A678D /* DWHomeViewControllerDelegate.h */, 75FFD6B72BF47BA20032879E /* HomeViewController.swift */, 75FFD6BA2BF48DF80032879E /* HomeViewController+JailbreakCheck.swift */, @@ -6033,6 +5988,8 @@ 7503643C2C89D4890029EC0D /* CoinJoin */ = { isa = PBXGroup; children = ( + 7571119F2CF20ED000A7D452 /* CoinJoinMixingTxSet.swift */, + 7571119C2CF1EF3600A7D452 /* CoinJoinMixingFilter.swift */, 7503643D2C89D49A0029EC0D /* CoinJoinService.swift */, 753FD7E12CA44BDD00B7751F /* CoinJoinProgress.swift */, ); @@ -7326,7 +7283,6 @@ C943B55F2A40ECEC00AF23C5 /* Cells */ = { isa = PBXGroup; children = ( - 2A5E4544243E0595006BA067 /* Registration Status */, C943B55D2A40E6F200AF23C5 /* DWFilterHeaderView.h */, C943B55C2A40E6F200AF23C5 /* DWFilterHeaderView.m */, 2A4E534C22F03AAC00E5168A /* DWFilterHeaderView.xib */, @@ -7929,7 +7885,6 @@ buildActionMask = 2147483647; files = ( 2A1AF6DE23C7681B00442AF5 /* DWShortcutCollectionViewCell~ipad.xib in Resources */, - 2AFF01E0243F74BF003718DC /* DWDPRegistrationErrorTableViewCell.xib in Resources */, 47838B7F290160860003E8AB /* ExploreDash.storyboard in Resources */, 474C720D298A19D100475CA6 /* TxDetailHeaderCell.xib in Resources */, 75303FE52AE7B70500870D8B /* CrowdNode.storyboard in Resources */, @@ -7950,7 +7905,6 @@ 75E2F3C82AA4CF1900C3B458 /* Topper-Info.plist in Resources */, 2A2CD71822F99CAE008C7BC9 /* ShortcutsView.xib in Resources */, C9F067F429E543630022D958 /* HomeBalanceView.xib in Resources */, - 2A5E4549243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.xib in Resources */, 474C7213298A1EFC00475CA6 /* TxDetailInfoCell.xib in Resources */, 2A9FFE942230FF4700956D5F /* UpholdOTPStoryboard.storyboard in Resources */, 2A4430F222CBD57A009BAF7F /* AppAssets.xcassets in Resources */, @@ -7972,7 +7926,6 @@ 2A913E7123A2667E006A2A59 /* Onboarding.storyboard in Resources */, 1193FF3E2962F1BE004EA8D7 /* OperationStatus.storyboard in Resources */, 2A9FFE9C2230FF4700956D5F /* UpholdLogoutTutorialStoryboard.storyboard in Resources */, - 2AFF01E6243F8626003718DC /* DWDPRegistrationDoneTableViewCell.xib in Resources */, 2A10EB412358D2A900C38B61 /* ResetWalletInfo.storyboard in Resources */, FB66977F212C0B940034BE4F /* LaunchScreen.storyboard in Resources */, 2A8B9E5C22FF6FE500FF8653 /* Pay.storyboard in Resources */, @@ -8033,7 +7986,6 @@ files = ( C9D2C90B2A320AA000D15901 /* DWShortcutCollectionViewCell~ipad.xib in Resources */, 75AE5A7F2A87C363006CD4BA /* DWConfirmUsernameContentView.xib in Resources */, - C9D2C90C2A320AA000D15901 /* DWDPRegistrationErrorTableViewCell.xib in Resources */, C9D2C90D2A320AA000D15901 /* ExploreDash.storyboard in Resources */, C9D2C90E2A320AA000D15901 /* TxDetailHeaderCell.xib in Resources */, 752C3ED22B1AF19C00F46CD3 /* BuySellPortal.storyboard in Resources */, @@ -8052,7 +8004,6 @@ C943B4C12A40A54600AF23C5 /* DWTitleActionHeaderView.xib in Resources */, C9D2C91D2A320AA000D15901 /* ShortcutsView.xib in Resources */, C9D2C91E2A320AA000D15901 /* HomeBalanceView.xib in Resources */, - C9D2C91F2A320AA000D15901 /* DWDPRegistrationStatusTableViewCell.xib in Resources */, 753FDBEE2AECF52B0005EEC3 /* UsernameVoting.storyboard in Resources */, C9D2C9202A320AA000D15901 /* TxDetailInfoCell.xib in Resources */, C9D2C9212A320AA000D15901 /* UpholdOTPStoryboard.storyboard in Resources */, @@ -8080,7 +8031,6 @@ C9D2C9352A320AA000D15901 /* OperationStatus.storyboard in Resources */, C9D2C9362A320AA000D15901 /* UpholdLogoutTutorialStoryboard.storyboard in Resources */, C943B5542A40C23500AF23C5 /* DWFilterHeaderView.xib in Resources */, - C9D2C9392A320AA000D15901 /* DWDPRegistrationDoneTableViewCell.xib in Resources */, C9D2C93A2A320AA000D15901 /* ResetWalletInfo.storyboard in Resources */, C9D2C93B2A320AA000D15901 /* LaunchScreen.storyboard in Resources */, C9D2C93C2A320AA000D15901 /* Pay.storyboard in Resources */, @@ -8512,7 +8462,6 @@ 11517C87294B0FED004FC7BF /* CrowdNodeWebService.swift in Sources */, 75EBAA1D2BBA71D9004488E3 /* ZenLedgerInfoSheet.swift in Sources */, 2A4E531422E9F0A200E5168A /* DWStartViewController.m in Sources */, - 11517C832949E6A3004FC7BF /* CrowdNodeAPI.swift in Sources */, 2A4E531522E9F0A200E5168A /* DWStartModel.m in Sources */, 2AB3417A23A929B6004E37A7 /* DWAdvancedSecurityModelStub.m in Sources */, 4709C32128818D5400B4BD48 /* Foundation+Bitcoin.swift in Sources */, @@ -8569,6 +8518,7 @@ 110C679A29227948006B580C /* UINavigationController+CrowdNode.swift in Sources */, 2A8B9E7A2302E67400FF8653 /* DWReceiveModel.m in Sources */, 119E8D0A2905413F00D406C1 /* TransactionWrapper.swift in Sources */, + 759A7EA82CFDA707009423AD /* UIViewController+DWTxFilter.swift in Sources */, 479DBDDD2995168C00F30AF1 /* Transactions.swift in Sources */, 75F3F00D2C48F819004470EA /* RootEditProfileViewController.swift in Sources */, 2A74EFFB2305464C00C475EB /* DWRecoverTextView.m in Sources */, @@ -8607,6 +8557,7 @@ 47F2C6842860513900C2B774 /* TxReclassifyTransactionsWhereToChangeViewController.swift in Sources */, 2A7A7C16234B763600451078 /* DWLocalCurrencyViewController.m in Sources */, C9F451FD2A0CC4A300825057 /* BadgeView.swift in Sources */, + 756557B52CE84FFA0060348D /* FeeInfo.swift in Sources */, C9F451F52A0CAC9400825057 /* HomeHeaderView.swift in Sources */, C9F451F92A0CB08900825057 /* ProgressView.swift in Sources */, 2A2120EA2214566A009906DC /* DWAmountInputValidator.m in Sources */, @@ -8659,7 +8610,6 @@ 2A1F6412238D650200A9B505 /* DWSegmentSlider.m in Sources */, 0F6EDFCA28C896BD000427E7 /* CoinbasePlaceBuyOrderRequest.swift in Sources */, 0F6EDFD328C896BD000427E7 /* CoinbaseAmount.swift in Sources */, - 2AFF01DF243F74BE003718DC /* DWDPRegistrationErrorTableViewCell.m in Sources */, 75EBAA252BBA9DC2004488E3 /* ZenLedger.swift in Sources */, 47B30D7E29102F6E0080C326 /* SendAmountModel.swift in Sources */, 2A9FFF272233E5D000956D5F /* DWDecimalInputValidator.m in Sources */, @@ -8806,7 +8756,6 @@ 119E8D10290949B900D406C1 /* CrowdNodeErrorResponse.swift in Sources */, 2A913E8223A30623006A2A59 /* DWHomeModelStub.m in Sources */, 2ADC9D1C24603C4F001D7C0D /* UISearchBar+DWAdditions.m in Sources */, - 2A74F0042305C59700C475EB /* UIViewController+DWTxFilter.m in Sources */, 75CED0A02ACFED200095F10C /* CoinbaseDepositResponse.swift in Sources */, 117ED4A828ED66F9006E3EE4 /* TransactionFilter.swift in Sources */, 111C3C54296D6A2D00788E18 /* CrowdNodeWithdrawalReceivedTx.swift in Sources */, @@ -8817,7 +8766,6 @@ C956AF232A5C7D93002FAB75 /* ConfirmPaymentViewController.swift in Sources */, 0F6EDFCE28C896BD000427E7 /* CoinbaseUserAccountData.swift in Sources */, C94D982A2A53038400F3BEE1 /* EnterAddressModel.swift in Sources */, - 2AFF01E5243F8626003718DC /* DWDPRegistrationDoneTableViewCell.m in Sources */, 47AE8BA628BFADD900490F5E /* AtmDAO.swift in Sources */, 475AE2B92974348F009A1055 /* App.swift in Sources */, 2A0C69A3231048DA001B8C90 /* DWPaymentProcessor.m in Sources */, @@ -8834,6 +8782,7 @@ 2A858A0F237EE89C0097A7B5 /* DSWatchTransactionDataObject.m in Sources */, 47FA3B0229364991008D58DC /* HTTPClient.swift in Sources */, 2A8B9E6F2302A9C200FF8653 /* DWPasteboardAddressExtractor.m in Sources */, + 757111A12CF20ED800A7D452 /* CoinJoinMixingTxSet.swift in Sources */, 477F501529531C07003C7508 /* ViewModel+Coinbase.swift in Sources */, 47A2A2EC293E618600938DB7 /* CBUser.swift in Sources */, 47A2A2EE293E622700938DB7 /* CBSecureTokenService.swift in Sources */, @@ -8844,7 +8793,6 @@ 758A8F172C4D35A80012FA41 /* NSLayoutConstraint+DashWallet.swift in Sources */, 2AD1CE8022DC92BF00C99324 /* NSString+DWTextSize.m in Sources */, 47AE8C0528C1F74A00490F5E /* PointOfUseListFiltersCell.swift in Sources */, - 47081199298CF57D003FCA3D /* TransactionListDataSource.swift in Sources */, 2A7A7BB22347927700451078 /* DWMainMenuViewController.m in Sources */, 47838B7D290133610003E8AB /* PointOfUseListFiltersViewController.swift in Sources */, 47AE8C1A28C6A21A00490F5E /* AllMerchantLocationsDataProvider.swift in Sources */, @@ -8871,7 +8819,6 @@ 478A2C7228DC909C00AD1420 /* BaseNavigationController.swift in Sources */, 47CDEECC294A2BAD008AE06D /* UIViewController+Coinbase.swift in Sources */, 472D13E1299E1F2F006903F1 /* CSVBuilder.swift in Sources */, - 2A5E4548243E06E7006BA067 /* DWDPRegistrationStatusTableViewCell.m in Sources */, 0F6EDFC428C896BD000427E7 /* CoinbaseUserAuthInformation.swift in Sources */, 2A913EB623A7E145006A2A59 /* DWTransactionStub.m in Sources */, 118C05B829928F7800717E65 /* OnlineAccountEmailController.swift in Sources */, @@ -8924,7 +8871,6 @@ 1147687E294B789800FB1EEE /* CrowdNodePortalViewController.swift in Sources */, 47F4B6CA29484C9800AED4C9 /* ConfirmOrderModel.swift in Sources */, 472CEE012924AA6D00656B48 /* PointOfUseListEmptyResultsView.swift in Sources */, - C94F5E8C29D3FEC10034FD57 /* ShortcutsModel.swift in Sources */, 2A6300452328D07500827825 /* DWLockPinInputView.m in Sources */, 75E7CA092C076D8900C77368 /* CNCreateAccountTxDetailsModel.swift in Sources */, 2A0C69AC23125074001B8C90 /* UIView+DWHUD.m in Sources */, @@ -9064,6 +9010,7 @@ 47A5146428491C60005A8E3E /* TxDetailCells.swift in Sources */, 477F501729543834003C7508 /* BaseViewController+NetworkReachability.swift in Sources */, 75D5F3CE191EC270004AB296 /* main.m in Sources */, + 7571119D2CF1EF3900A7D452 /* CoinJoinMixingFilter.swift in Sources */, 2A8C24B423336FEA00000D43 /* DWQuickReceiveViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -9124,7 +9071,6 @@ 75A8C1652AE5726B0042256E /* UsernameRequestsDAO.swift in Sources */, C9D2C6992A320AA000D15901 /* DWStartViewController.m in Sources */, C943B4C02A40A54600AF23C5 /* DWContactsSearchInfoHeaderView.m in Sources */, - C9D2C69A2A320AA000D15901 /* CrowdNodeAPI.swift in Sources */, C9D2C69B2A320AA000D15901 /* DWStartModel.m in Sources */, 754495DD2AE91B6300492817 /* GroupedRequestCell.swift in Sources */, 7503643B2C89CFB70029EC0D /* CoinJoinProgressView.swift in Sources */, @@ -9259,6 +9205,7 @@ 759C8FA02B593589004B1305 /* CrowdNodeAPYView.swift in Sources */, C943B5162A40A54600AF23C5 /* DWCreateInvitationButton.m in Sources */, C9D2C6FE2A320AA000D15901 /* HomeHeaderView.swift in Sources */, + 757111A02CF20ED800A7D452 /* CoinJoinMixingTxSet.swift in Sources */, C9D2C6FF2A320AA000D15901 /* ProgressView.swift in Sources */, C9D2C7002A320AA000D15901 /* DWAmountInputValidator.m in Sources */, 7513DA8A2AB17666005D55F6 /* SupportedTopperAssets.swift in Sources */, @@ -9276,6 +9223,7 @@ C9D2C7072A320AA000D15901 /* AmountInputTypeSwitcher.swift in Sources */, C943B4FA2A40A54600AF23C5 /* DWDPOutgoingRequestNotificationObject.m in Sources */, 75EBAA132BB99B6B004488E3 /* BottomSheet.swift in Sources */, + 759A7EA72CFDA707009423AD /* UIViewController+DWTxFilter.swift in Sources */, C9D2C7082A320AA000D15901 /* DWPlaceholderFormCellModel.m in Sources */, C9D2C7092A320AA000D15901 /* DWOverlapControl.m in Sources */, C9D2C70A2A320AA000D15901 /* CoinsToAddressTxFilter.swift in Sources */, @@ -9341,7 +9289,6 @@ C943B5262A40A54600AF23C5 /* DWDashPayAnimationView.m in Sources */, C943B4EF2A40A54600AF23C5 /* DWUserProfileHeaderView.m in Sources */, C9D2C7392A320AA000D15901 /* CoinbaseAmount.swift in Sources */, - C9D2C73A2A320AA000D15901 /* DWDPRegistrationErrorTableViewCell.m in Sources */, C9D2C73B2A320AA000D15901 /* SendAmountModel.swift in Sources */, 75EBAA102BB99036004488E3 /* TextIntro.swift in Sources */, 757514E52B1735370026AD8E /* DPWelcomeMenuView.swift in Sources */, @@ -9521,6 +9468,7 @@ C9D2C7B22A320AA000D15901 /* (null) in Sources */, C9D2C7B32A320AA000D15901 /* SpecifyAmountViewController.swift in Sources */, C943B4EA2A40A54600AF23C5 /* DWUserProfileViewController.m in Sources */, + 756557B62CE84FFA0060348D /* FeeInfo.swift in Sources */, C943B5922A40ED7B00AF23C5 /* DWTextField.m in Sources */, 75EBAA0D2BB9792F004488E3 /* FeatureTopText.swift in Sources */, C9D2C7B42A320AA000D15901 /* DWUpholdTransactionObject+DWView.m in Sources */, @@ -9577,7 +9525,6 @@ C943B5122A40A54600AF23C5 /* DWInvitationHistoryModel.m in Sources */, C943B31A2A408CED00AF23C5 /* DWCurrentUserProfileView.m in Sources */, 751B61C22ADFF99D00D1C2EF /* CoinbaseDepositResponse.swift in Sources */, - C9D2C7DE2A320AA000D15901 /* UIViewController+DWTxFilter.m in Sources */, C943B4F32A40A54600AF23C5 /* DWDPEstablishedContactObject.m in Sources */, C9D2C7E02A320AA000D15901 /* TransactionFilter.swift in Sources */, C9D2C7E22A320AA000D15901 /* CrowdNodeWithdrawalReceivedTx.swift in Sources */, @@ -9591,7 +9538,6 @@ C9D2C7E62A320AA000D15901 /* ConfirmOrderCells.swift in Sources */, C9D2C7E72A320AA000D15901 /* CoinbaseUserAccountData.swift in Sources */, C943B3202A408CED00AF23C5 /* DWImgurInfoChildView.m in Sources */, - C9D2C7E82A320AA000D15901 /* DWDPRegistrationDoneTableViewCell.m in Sources */, C9D2C7E92A320AA000D15901 /* AtmDAO.swift in Sources */, C9D2C7EA2A320AA000D15901 /* App.swift in Sources */, 755E6DFE2A99E7A000A42870 /* DWInvitationSetupState.m in Sources */, @@ -9620,7 +9566,6 @@ C9D2C8052A320AA000D15901 /* IntegrationViewController.swift in Sources */, C9D2C8062A320AA000D15901 /* NSString+DWTextSize.m in Sources */, C9D2C8072A320AA000D15901 /* PointOfUseListFiltersCell.swift in Sources */, - C9D2C8082A320AA000D15901 /* TransactionListDataSource.swift in Sources */, C9D2C80A2A320AA000D15901 /* DWMainMenuViewController.m in Sources */, C9D2C80B2A320AA000D15901 /* PointOfUseListFiltersViewController.swift in Sources */, 75AA33D02BF9D44A00F12465 /* ButtonsGroup.swift in Sources */, @@ -9661,7 +9606,6 @@ C9D2C8232A320AA000D15901 /* BaseNavigationController.swift in Sources */, C9D2C8242A320AA000D15901 /* UIViewController+Coinbase.swift in Sources */, C9D2C8262A320AA000D15901 /* CSVBuilder.swift in Sources */, - C9D2C8272A320AA000D15901 /* DWDPRegistrationStatusTableViewCell.m in Sources */, C9D2C8282A320AA000D15901 /* CoinbaseUserAuthInformation.swift in Sources */, C943B5982A40EDEF00AF23C5 /* DWConfirmUsernameContentView.m in Sources */, C943B58C2A40ED6F00AF23C5 /* DWUsernameValidationRule.m in Sources */, @@ -9729,7 +9673,6 @@ C9D2C85A2A320AA000D15901 /* ConfirmOrderModel.swift in Sources */, C943B53F2A40A6BE00AF23C5 /* DPAlertChildContentsView.m in Sources */, C9D2C85B2A320AA000D15901 /* PointOfUseListEmptyResultsView.swift in Sources */, - C9D2C85C2A320AA000D15901 /* ShortcutsModel.swift in Sources */, 75A0A3F42CA7DBCF003ED48B /* TimeUtils.swift in Sources */, 75FFD6C82BF495800032879E /* HomeViewController+Shortcuts.swift in Sources */, C9D2C85D2A320AA000D15901 /* DWLockPinInputView.m in Sources */, @@ -9858,6 +9801,7 @@ C9D2C8C92A320AA000D15901 /* ServiceDataSource.swift in Sources */, C9D2C8CA2A320AA000D15901 /* ConverterView.swift in Sources */, C9D2C8CB2A320AA000D15901 /* DWModalBaseAnimation.m in Sources */, + 7571119E2CF1EF3900A7D452 /* CoinJoinMixingFilter.swift in Sources */, C9D2C8CC2A320AA000D15901 /* SpendableTransaction.swift in Sources */, C943B31F2A408CED00AF23C5 /* DWUserProfileModalQRViewController.m in Sources */, C9D2C8CD2A320AA000D15901 /* StakingInfoDialogController.swift in Sources */, @@ -10765,7 +10709,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.2.0; + MARKETING_VERSION = 8.2.3; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -10794,7 +10738,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.2.0; + MARKETING_VERSION = 8.2.3; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -11586,7 +11530,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.2.0; + MARKETING_VERSION = 8.2.3; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -11896,7 +11840,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.2.0; + MARKETING_VERSION = 8.2.3; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; diff --git a/DashWallet/Sources/Categories/DSTransaction+DashWallet.swift b/DashWallet/Sources/Categories/DSTransaction+DashWallet.swift index 804a7edcc..5bff6cd88 100644 --- a/DashWallet/Sources/Categories/DSTransaction+DashWallet.swift +++ b/DashWallet/Sources/Categories/DSTransaction+DashWallet.swift @@ -29,38 +29,6 @@ extension DSTransaction { let txDate = Date(timeIntervalSince1970: timestamp) return txDate; } - - var dashAmount: UInt64 { - var amount: UInt64 = 0 - - let chain = DWEnvironment.sharedInstance().currentChain - let currentAccount = DWEnvironment.sharedInstance().currentAccount; - let account = accounts.contains(where: { ($0 as! DSAccount) == currentAccount }) ? currentAccount : nil - - let direction = direction - - switch direction { - case .notAccountFunds, .moved: - amount = 0 - case .sent: - let amountSent = chain.amountSent(by: self) - let amountReceived = chain.amountReceived(from: self) - - // NOTE: During the sync we may get an incorectly amount from DashSync. - if amountReceived > amountSent { - return UInt64.max - } - - let fee = feeUsed == UInt64.max ? 0 : feeUsed - amount = amountSent - amountReceived - fee - case .received: - amount = account?.amountReceived(from: self) ?? 0 - @unknown default: - fatalError() - } - - return amount - } } extension DSTransaction { @@ -82,10 +50,6 @@ extension DSTransaction { return .classic; } - var direction: DSTransactionDirection { - return chain.direction(of: self) - } - var outputReceiveAddresses: [String] { var outputReceiveAddresses: [String] = [] diff --git a/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingFilter.swift b/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingFilter.swift new file mode 100644 index 000000000..9e6621933 --- /dev/null +++ b/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingFilter.swift @@ -0,0 +1,33 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2024 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +struct CoinJoinTxFilter: TransactionFilter { + let type: CoinJoinTransactionType + + init(type: CoinJoinTransactionType) { + self.type = type + } + + func matches(tx: DSTransaction) -> Bool { + return DSCoinJoinWrapper.coinJoinTxType(for: tx) == self.type + } + + static let createDenomination = CoinJoinTxFilter(type: CoinJoinTransactionType_CreateDenomination) + static let makeCollateral = CoinJoinTxFilter(type: CoinJoinTransactionType_MakeCollateralInputs) + static let mixingFee = CoinJoinTxFilter(type: CoinJoinTransactionType_MixingFee) + static let mixing = CoinJoinTxFilter(type: CoinJoinTransactionType_Mixing) +} diff --git a/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingTxSet.swift b/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingTxSet.swift new file mode 100644 index 000000000..34051ea94 --- /dev/null +++ b/DashWallet/Sources/Models/CoinJoin/CoinJoinMixingTxSet.swift @@ -0,0 +1,72 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2024 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +final class CoinJoinMixingTxSet: TransactionWrapper { + private var matchedFilters: [CoinJoinTxFilter] = [] + private let coinjoinTxFilters = [ + CoinJoinTxFilter.createDenomination, + CoinJoinTxFilter.makeCollateral, + CoinJoinTxFilter.mixingFee, + CoinJoinTxFilter.mixing + ] + + private(set) var amount: Int64 = 0 + var transactions: [Data: DSTransaction] = [:] + var id: String = "coinjoin" + var groupDay: Date = Date.now { + didSet { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd" + id = "coinjoin-\(dateFormatter.string(from: groupDay))" + } + } + + @discardableResult + func tryInclude(tx: DSTransaction) -> Bool { + let txHashData = tx.txHashData + + if transactions[txHashData] != nil { + transactions[txHashData] = tx + // Already included, return true + return true + } + + if let matchedFilter = coinjoinTxFilters.first(where: { $0.matches(tx: tx) }) { + if transactions.isEmpty { + groupDay = tx.date + } else if !Calendar.current.isDate(tx.date, inSameDayAs: groupDay) { + return false + } + + transactions[txHashData] = tx + matchedFilters.append(matchedFilter) + + switch tx.direction { + case .sent: + amount -= Int64(tx.dashAmount) + case .received: + amount += Int64(tx.dashAmount) + default: + break + } + + return true + } + + return false + } +} diff --git a/DashWallet/Sources/Models/CoinJoin/CoinJoinService.swift b/DashWallet/Sources/Models/CoinJoin/CoinJoinService.swift index e935807e8..f6dc43f7e 100644 --- a/DashWallet/Sources/Models/CoinJoin/CoinJoinService.swift +++ b/DashWallet/Sources/Models/CoinJoin/CoinJoinService.swift @@ -101,15 +101,18 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { private var currentMode: CoinJoinMode { get { - let current = CoinJoinMode(rawValue: UserDefaults.standard.integer(forKey: chainModeKey)) ?? .none + let current = CoinJoinMode(rawValue: UserDefaults.standard.integer(forKey: chainModeKey)) + DSLogger.log("[SW] CoinJoin: get currentMode: \(current == nil ? "nil" : String(describing: current!))") + let final = current ?? .none - if self.mode != current { - self.mode = current + if self.mode != final { + self.mode = final } - return current + return final } set(value) { + DSLogger.log("[SW] CoinJoin: set currentMode: \(value)") self.mode = value UserDefaults.standard.set(value.rawValue, forKey: chainModeKey) } @@ -142,8 +145,8 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { func updateMode(mode: CoinJoinMode, force: Bool = false) async { self.coinJoinManager?.updateOptions(withEnabled: mode != .none) - if mode != .none && (force || self.currentMode == .none) { - configureMixing() + if mode != .none && (force || mode != self.currentMode) { + configureMixing(mode: mode) configureObservers() } else if mode == .none { removeObservers() @@ -178,12 +181,12 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { } } - private func configureMixing() { + private func configureMixing(mode: CoinJoinMode) { guard let coinJoinManager = self.coinJoinManager ?? createCoinJoinManager() else { return } let account = DWEnvironment.sharedInstance().currentAccount let rounds: Int32 - switch currentMode { + switch mode { case .none: return case .intermediate: @@ -268,7 +271,7 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { } synchronized(self.updateMutex) { - DSLogger.log("CoinJoin: \(mode), \(timeSkew) s, \(hasAnonymizableBalance), \(networkStatus), synced: \(SyncingActivityMonitor.shared.state == .syncDone)") + DSLogger.log("CoinJoin updateState: \(mode), \(timeSkew)s, \(hasAnonymizableBalance), \(networkStatus), synced: \(SyncingActivityMonitor.shared.state == .syncDone)") self.networkStatus = networkStatus self.hasAnonymizableBalance = hasAnonymizableBalance @@ -278,7 +281,7 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { if mode == .none || !isInsideTimeSkewBounds(timeSkew: timeSkew) || DWGlobalOptions.sharedInstance().isResyncingWallet { updateMixingState(state: .notStarted) } else { - configureMixing() + configureMixing(mode: mode) if hasAnonymizableBalance { if networkStatus == .online && SyncingActivityMonitor.shared.state == .syncDone { @@ -337,6 +340,8 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { } private func restoreMode() { + DSLogger.log("[SW] CoinJoin: restoreMode, self.currentMode: \(self.currentMode)") + self.stopMixing() self.coinJoinManager = nil self.hasAnonymizableBalance = false @@ -368,6 +373,8 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { } private func configureObservers() { + self.removeObservers() + NotificationCenter.default.publisher(for: NSNotification.Name.DSWalletBalanceDidChange) .sink { [weak self] _ in guard let self = self else { return } @@ -392,6 +399,13 @@ class CoinJoinService: NSObject, NetworkReachabilityHandling { } .store(in: &cancellableBag) + NotificationCenter.default.publisher(for: NSNotification.Name.DWWillWipeWallet) + .sink { _ in + UserDefaults.standard.set(CoinJoinMode.none.rawValue, forKey: kCoinJoinMainnetMode) + UserDefaults.standard.set(CoinJoinMode.none.rawValue, forKey: kCoinJoinTestnetMode) + } + .store(in: &cancellableBag) + SyncingActivityMonitor.shared.add(observer: self) } diff --git a/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeAPI.swift b/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeAPI.swift deleted file mode 100644 index dcd520648..000000000 --- a/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeAPI.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Created by Andrei Ashikhmin -// Copyright © 2022 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -final class CrowdNodeAPI: HTTPClient { - static let shared = CrowdNodeAPI() -} diff --git a/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeEndpoint.swift b/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeEndpoint.swift index 6eb001742..64de5a96a 100644 --- a/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeEndpoint.swift +++ b/DashWallet/Sources/Models/CrowdNode/API/CrowdNodeEndpoint.swift @@ -33,6 +33,7 @@ public enum CrowdNodeEndpoint { case hasDefaultEmail(String) case sendSignedMessage(address: String, message: String, signature: String, messagetype: MessageType) case getMessages(String) + case getFees(String) } // MARK: TargetType @@ -53,9 +54,10 @@ extension CrowdNodeEndpoint: TargetType { case .hasDefaultEmail(let address): return "odata/apiaddresses/UsingDefaultApiEmail(address='\(address)')" case .sendSignedMessage(let address, let message, let signature, let messagetype): return "odata/apimessages/SendMessage(address='\(address)',message='\(message)',signature='\(signature)',messagetype=\(messagetype.rawValue))" case .getMessages(let address): return "odata/apimessages/GetMessages(address='\(address)')" + case .getFees(let address): return "odata/apifundings/GetFeeJson(address='\(address)')" } } - + public var method: Moya.Method { .get } @@ -68,3 +70,7 @@ extension CrowdNodeEndpoint: TargetType { [:] } } + +final class CrowdNodeAPI: HTTPClient { + static let shared = CrowdNodeAPI() +} diff --git a/DashWallet/Sources/Models/CrowdNode/API/DTOs/FeeInfo.swift b/DashWallet/Sources/Models/CrowdNode/API/DTOs/FeeInfo.swift new file mode 100644 index 000000000..59827bdb3 --- /dev/null +++ b/DashWallet/Sources/Models/CrowdNode/API/DTOs/FeeInfo.swift @@ -0,0 +1,46 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2024 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +private let kDefaultAmount = 100.0 +private let kTypeNormal = "Normal" + +struct FeeInfo: Codable { + static let empty = FeeInfo(feeLadder: [FeeLadder.empty]) + let feeLadder: [FeeLadder] + + enum CodingKeys: String, CodingKey { + case feeLadder = "FeeLadder" + } + + func getNormalFee() -> FeeLadder? { + return feeLadder.first { $0.type == kTypeNormal } + } +} + +struct FeeLadder: Codable { + let name: String + let type: String + let amount: Double + let fee: Double + + static let empty = FeeLadder( + name: "", + type: kTypeNormal, + amount: kDefaultAmount, + fee: CrowdNode.defaultFee * 100 + ) +} diff --git a/DashWallet/Sources/Models/CrowdNode/CrowdNode+Constants.swift b/DashWallet/Sources/Models/CrowdNode/CrowdNode+Constants.swift index e99c14c0b..629b29d6e 100644 --- a/DashWallet/Sources/Models/CrowdNode/CrowdNode+Constants.swift +++ b/DashWallet/Sources/Models/CrowdNode/CrowdNode+Constants.swift @@ -35,6 +35,7 @@ extension CrowdNode { static let minimumDeposit = UInt64(kOneDash / 2) static let minimumLeftoverBalance: UInt64 = 30_000 static let apiConfirmationDashAmount: UInt64 = 54321 + static let defaultFee = 0.35 static let notificationID = "CrowdNode" diff --git a/DashWallet/Sources/Models/CrowdNode/CrowdNode+UserDefaults.swift b/DashWallet/Sources/Models/CrowdNode/CrowdNode+UserDefaults.swift index 46c6dfc9c..bfad12759 100644 --- a/DashWallet/Sources/Models/CrowdNode/CrowdNode+UserDefaults.swift +++ b/DashWallet/Sources/Models/CrowdNode/CrowdNode+UserDefaults.swift @@ -32,6 +32,7 @@ private let kOnlineInfoShown = "crowdNodeOnlineInfoShownKey" private let kSignedEmailMessageId = "crowdNodeSignedEmailMessageId" private let kShouldShowConfirmedNotification = "shouldShowConfirmedNotification" private let kLastWithdrawalBlock = "lastWithdrawalBlockKey" +private let kFeePercentage = "feePercentageKey" // MARK: - CrowdNodeDefaults @@ -91,6 +92,15 @@ class CrowdNodeDefaults { UserDefaults.standard.set(value, forKey: kWithdrawalLimitPerDay) } } + + private var _feePercentage: Double? = nil + var feePercentage: Double { + get { _feePercentage ?? UserDefaults.standard.value(forKey: kFeePercentage) as? Double ?? CrowdNode.defaultFee } + set(value) { + _feePercentage = value + UserDefaults.standard.set(value, forKey: kFeePercentage) + } + } private var _withdrawalLimitsInfoShown: Bool? = nil var withdrawalLimitsInfoShown: Bool { diff --git a/DashWallet/Sources/Models/CrowdNode/CrowdNode.swift b/DashWallet/Sources/Models/CrowdNode/CrowdNode.swift index d3cc28baf..82d4b2d35 100644 --- a/DashWallet/Sources/Models/CrowdNode/CrowdNode.swift +++ b/DashWallet/Sources/Models/CrowdNode/CrowdNode.swift @@ -132,7 +132,8 @@ public final class CrowdNode { init() { masternodeAPY = DWEnvironment.sharedInstance().apy.doubleValue - crowdnodeAPY = masternodeAPY * 0.85 + crowdnodeAPY = masternodeAPY * (1 - prefs.feePercentage) + print("CrowdNode: masternodeAPY: \(masternodeAPY), crowdnodeAPY: \(crowdnodeAPY)") NotificationCenter.default.publisher(for: NSNotification.Name.DWWillWipeWallet) .sink { [weak self] _ in self?.reset() } @@ -195,6 +196,7 @@ extension CrowdNode { if tryRestoreSignUp() { refreshWithdrawalLimits() + refreshFees() restoreCreatedOnlineAccount(accountAddress) return } @@ -306,7 +308,8 @@ extension CrowdNode { if let apy = chain.calculateMasternodeAPY()?.doubleValue { masternodeAPY = apy - crowdnodeAPY = masternodeAPY * 0.85 + let multiplier = 1 - prefs.feePercentage + crowdnodeAPY = masternodeAPY * multiplier chain.apy = NSNumber(value: apy) } } @@ -612,6 +615,20 @@ extension CrowdNode { } } } + + private func refreshFees() { + Task { + do { + let feeInfo = try await webService.getFees(address: accountAddress) + + if let value = feeInfo.getNormalFee() { + prefs.feePercentage = value.fee / 100 + } + } catch { + DSLogger.log("CrowdNode refreshFees error: \(error.localizedDescription)") + } + } + } private func getWithdrawalLimit(_ period: WithdrawalLimitPeriod) -> UInt64 { switch period { diff --git a/DashWallet/Sources/Models/CrowdNode/Services/CrowdNodeWebService.swift b/DashWallet/Sources/Models/CrowdNode/Services/CrowdNodeWebService.swift index d837d476e..5a5dc76e7 100644 --- a/DashWallet/Sources/Models/CrowdNode/Services/CrowdNodeWebService.swift +++ b/DashWallet/Sources/Models/CrowdNode/Services/CrowdNodeWebService.swift @@ -101,4 +101,8 @@ extension CrowdNodeService { return nil } } + + func getFees(address: String) async throws -> FeeInfo { + try await httpClient.request(.getFees(address)) + } } diff --git a/DashWallet/Sources/Models/CrowdNode/TxFilters/CrowdNodeTopUpTx.swift b/DashWallet/Sources/Models/CrowdNode/TxFilters/CrowdNodeTopUpTx.swift index 86442948c..47de398ce 100644 --- a/DashWallet/Sources/Models/CrowdNode/TxFilters/CrowdNodeTopUpTx.swift +++ b/DashWallet/Sources/Models/CrowdNode/TxFilters/CrowdNodeTopUpTx.swift @@ -21,7 +21,7 @@ public final class CrowdNodeTopUpTx: CoinsToAddressTxFilter { } override func matches(tx: DSTransaction) -> Bool { - tx.direction() == DSTransactionDirection.moved && + tx.direction == DSTransactionDirection.moved && super.matches(tx: tx) } } diff --git a/DashWallet/Sources/Models/CrowdNode/TxFilters/FullCrowdNodeSignUpTxSet.swift b/DashWallet/Sources/Models/CrowdNode/TxFilters/FullCrowdNodeSignUpTxSet.swift index a3945744a..be8aec931 100644 --- a/DashWallet/Sources/Models/CrowdNode/TxFilters/FullCrowdNodeSignUpTxSet.swift +++ b/DashWallet/Sources/Models/CrowdNode/TxFilters/FullCrowdNodeSignUpTxSet.swift @@ -16,11 +16,17 @@ // final class FullCrowdNodeSignUpTxSet: TransactionWrapper { + static let id = "FullCrowdNodeSignUpTxSet" private let savedAccountAddress = CrowdNodeDefaults.shared.accountAddress private let januaryFirst2022 = 1640995200.0 // Safe to assume there weren't any CrowdNode accounts before this point private var matchedFilters: [CoinsToAddressTxFilter] = [] var transactions: [Data: DSTransaction] = [:] + private(set) var amount: Int64 = 0 + + var isComplete: Bool { + transactions.count == 5 + } var welcomeToApiResponse: CoinsToAddressTxFilter? { matchedFilters.first { filter in @@ -55,6 +61,7 @@ final class FullCrowdNodeSignUpTxSet: TransactionWrapper { let txHashData = tx.txHashData if transactions[txHashData] != nil { + transactions[txHashData] = tx // Already included, return true return true } @@ -73,6 +80,16 @@ final class FullCrowdNodeSignUpTxSet: TransactionWrapper { if let matchedFilter = crowdNodeTxFilters.first(where: { $0.matches(tx: tx) }) { transactions[txHashData] = tx matchedFilters.append(matchedFilter) + + let dashAmount = tx.dashAmount + switch tx.direction { + case .sent: + amount -= Int64(dashAmount) + case .received: + amount += Int64(dashAmount) + default: + break + } return true } diff --git a/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift b/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift index bda193242..ae9b17246 100644 --- a/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift +++ b/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift @@ -121,7 +121,7 @@ extension TxUserInfo { extension DSTransaction { @objc func defaultTaxCategory() -> TxUserInfoTaxCategory { - switch direction() { + switch direction { case .moved: return .expense case .sent: diff --git a/DashWallet/Sources/Models/Transactions/Model/Transaction.swift b/DashWallet/Sources/Models/Transactions/Model/Transaction.swift index 40e1af619..6f1c1a57b 100644 --- a/DashWallet/Sources/Models/Transactions/Model/Transaction.swift +++ b/DashWallet/Sources/Models/Transactions/Model/Transaction.swift @@ -17,6 +17,8 @@ import Foundation +let kConfirmationThreshold = Double(30 * 60) + // MARK: - Transaction class Transaction: TransactionDataItem, Identifiable { @@ -89,32 +91,31 @@ class Transaction: TransactionDataItem, Identifiable { } let chain = DWEnvironment.sharedInstance().currentChain - let currentAccount = DWEnvironment.sharedInstance().currentAccount; + let currentAccount = DWEnvironment.sharedInstance().currentAccount let account = tx.accounts.contains(where: { ($0 as! DSAccount) == currentAccount }) ? currentAccount : nil if account == nil { return .invalid } + let blockHeight = chain.lastTerminalBlockHeight let instantSendReceived = tx.instantSendReceived let processingInstantSend = tx.hasUnverifiedInstantSendLock let confirmed = tx.confirmed let confirms = (tx.blockHeight > blockHeight) ? 0 : (blockHeight - tx.blockHeight) + 1 - + if (direction == .sent || direction == .moved) && confirms == 0 - && !account!.transactionIsValid(tx) { + && !isValid(account, tx) { return .invalid } else if direction == .received { - if !instantSendReceived && confirms == 0 && account!.transactionIsPending(tx) { + if !instantSendReceived && confirms == 0 && isPending(account, tx) { // should be very hard to get here, a miner would have to include a non standard transaction into a block - return .locked; - } else if !instantSendReceived && confirms == 0 && !account!.transactionIsVerified(tx) { - return .processing; - } - else if account!.transactionOutputsAreLocked(tx) { - return .locked; - } - else if !instantSendReceived && !confirmed { + return .locked + } else if !instantSendReceived && confirms == 0 && !isVerified(account, tx) { + return .processing + } else if outputsAreLocked(account, tx) { + return .locked + } else if !instantSendReceived && !confirmed { let transactionAge = NSDate().timeIntervalSince1970 - tx .timestamp // we check the transaction age, as we might still be waiting on a transaction lock, 1 second seems like a good wait time if confirms == 0 && (processingInstantSend || transactionAge < 1.0) { @@ -123,16 +124,40 @@ class Transaction: TransactionDataItem, Identifiable { return .confirming } } - } else if direction != .notAccountFunds { - if !instantSendReceived - && confirms == 0 - && !account!.transactionIsVerified(tx) { - return .processing; - } + } else if direction == .notAccountFunds || instantSendReceived || confirms > 0 { + return .ok } - - return .ok + + return isVerified(account, tx) ? .ok : .processing }() + + private func outputsAreLocked(_ account: DSAccount?, _ tx: DSTransaction) -> Bool { + return account!.transactionOutputsAreLocked(tx) + } + + private func isPending(_ account: DSAccount?, _ tx: DSTransaction) -> Bool { + if tx.timestamp + kConfirmationThreshold < Date().timeIntervalSince1970 { + return false + } + + return account!.transactionIsPending(tx) + } + + private func isVerified(_ account: DSAccount?, _ tx: DSTransaction) -> Bool { + if tx.timestamp + kConfirmationThreshold < Date().timeIntervalSince1970 { + return true + } + + return account!.transactionIsVerified(tx) + } + + private func isValid(_ account: DSAccount?, _ tx: DSTransaction) -> Bool { + if tx.timestamp + kConfirmationThreshold < Date().timeIntervalSince1970 { + return true + } + + return account!.transactionIsValid(tx) + } private lazy var _shortDateString: String = tx.formattedShortTxDate var date: Date diff --git a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m index 15830fe78..a7f171e16 100644 --- a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m +++ b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m @@ -47,7 +47,6 @@ + (NSString *)transactionURLFormat { + (NSString *)logoutURLString { return @"https://uphold.com/"; - } @end diff --git a/DashWallet/Sources/UI/CrowdNode/Views/CrowdNodeAPYView.swift b/DashWallet/Sources/UI/CrowdNode/Views/CrowdNodeAPYView.swift index 91c2946c6..0cd221846 100644 --- a/DashWallet/Sources/UI/CrowdNode/Views/CrowdNodeAPYView.swift +++ b/DashWallet/Sources/UI/CrowdNode/Views/CrowdNodeAPYView.swift @@ -68,7 +68,7 @@ class CrowdNodeAPYView: UIView { } private var apy: String { - let apyValue = DWEnvironment.sharedInstance().apy.doubleValue * 0.85 + let apyValue = CrowdNode.shared.crowdnodeAPY let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .percent diff --git a/DashWallet/Sources/UI/DashPay/Profile/DWUserProfileViewController.m b/DashWallet/Sources/UI/DashPay/Profile/DWUserProfileViewController.m index b5f8695bf..300f1fc04 100644 --- a/DashWallet/Sources/UI/DashPay/Profile/DWUserProfileViewController.m +++ b/DashWallet/Sources/UI/DashPay/Profile/DWUserProfileViewController.m @@ -31,7 +31,7 @@ #import "DWUserProfileNavigationTitleView.h" #import "DWUserProfileSendRequestCell.h" #import "UICollectionView+DWDPItemDequeue.h" -#import "UIViewController+DWTxFilter.h" +#import "dashwallet-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -59,6 +59,7 @@ @interface DWUserProfileViewController () +@interface DWUserProfileModel : NSObject @property (readonly, nonatomic, strong) id item; @property (readonly, nonatomic, assign) DWUserProfileModelState state; diff --git a/DashWallet/Sources/UI/DashPay/Profile/Model/DWUserProfileModel.m b/DashWallet/Sources/UI/DashPay/Profile/Model/DWUserProfileModel.m index ab087d4bc..074f9e89c 100644 --- a/DashWallet/Sources/UI/DashPay/Profile/Model/DWUserProfileModel.m +++ b/DashWallet/Sources/UI/DashPay/Profile/Model/DWUserProfileModel.m @@ -24,6 +24,7 @@ #import "DWGlobalOptions.h" #import "DWProfileTxsFetchedDataSource.h" #import "DWUserProfileDataSourceObject.h" +#import "dashwallet-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -33,6 +34,7 @@ @interface DWUserProfileModel () dataSource; @property (readonly, nonatomic, strong) id txDataProvider; +@property (nonatomic, assign) DWHomeTxDisplayMode displayMode; @end @@ -303,11 +305,11 @@ - (void)updateDataSource { } BOOL shouldShowContactRequests = YES; - if (self.displayMode == DWHomeTxDisplayMode_Sent) { + if (self.displayMode == DWHomeTxDisplayModeSent) { meToFriend = nil; shouldShowContactRequests = NO; } - else if (self.displayMode == DWHomeTxDisplayMode_Received) { + else if (self.displayMode == DWHomeTxDisplayModeReceived) { friendToMe = nil; shouldShowContactRequests = NO; } diff --git a/DashWallet/Sources/UI/Home/HomeViewController+SecureWalletDelegateImpl.swift b/DashWallet/Sources/UI/Home/HomeViewController+SecureWalletDelegateImpl.swift index f61d211d6..fd9f62a1e 100644 --- a/DashWallet/Sources/UI/Home/HomeViewController+SecureWalletDelegateImpl.swift +++ b/DashWallet/Sources/UI/Home/HomeViewController+SecureWalletDelegateImpl.swift @@ -24,7 +24,7 @@ extension HomeViewController: DWSecureWalletDelegate { func secureWalletRoutineDidVerify(_ controller: UIViewController) { if let view = self.view as? HomeView { - view.reloadShortcuts() + view.viewModel.reloadShortcuts() } } diff --git a/DashWallet/Sources/UI/Home/HomeViewController.swift b/DashWallet/Sources/UI/Home/HomeViewController.swift index 86509834a..201cc7104 100644 --- a/DashWallet/Sources/UI/Home/HomeViewController.swift +++ b/DashWallet/Sources/UI/Home/HomeViewController.swift @@ -86,7 +86,6 @@ class HomeViewController: DWBasePayViewController, NavigationBarDisplayable { } model.registerForPushNotifications() - showReclassifyYourTransactionsIfPossible(with: model.allDataSource.items.first) model.checkCrowdNodeState() model.checkVotingState() } @@ -203,18 +202,11 @@ class HomeViewController: DWBasePayViewController, NavigationBarDisplayable { homeView.model = model } - private func showReclassifyYourTransactionsIfPossible(with transaction: DSTransaction?) { - guard presentedViewController == nil else { return } - - if model.isAllowedToShowReclassifyYourTransactions { - let vc = TxReclassifyTransactionsInfoViewController.controller() - vc.delegate = self - vc.transaction = transaction - DispatchQueue.main.async { - self.present(vc, animated: true, completion: nil) - } - DWGlobalOptions.sharedInstance().shouldDisplayReclassifyYourTransactionsFlow = false - } + private func showReclassifyTransaction(with transaction: DSTransaction?) { + let vc = TxReclassifyTransactionsInfoViewController.controller() + vc.delegate = self + vc.transaction = transaction + self.present(vc, animated: true, completion: nil) } private func presentTransactionDetails(_ transaction: DSTransaction) { @@ -240,6 +232,16 @@ class HomeViewController: DWBasePayViewController, NavigationBarDisplayable { NotificationCenter.default.publisher(for: .NSSystemClockDidChange) .sink { [weak self] _ in self?.viewModel.checkTimeSkew(force: true) } .store(in: &cancellableBag) + + viewModel.$showReclassifyTransaction + .removeDuplicates() + .filter { $0 != nil } + .receive(on: DispatchQueue.main) + .sink { [weak self] tx in + self?.showReclassifyTransaction(with: tx) + self?.viewModel.reclassifyTransactionShown(isShown: true) + } + .store(in: &cancellableBag) } private func showTimeSkewDialog(diffSeconds: Int64, coinjoin: Bool) { @@ -304,7 +306,9 @@ extension HomeViewController: HomeViewDelegate { } func homeView(_ homeView: HomeView, showTxFilter sender: UIView) { - showTxFilter(withSender: sender, displayModeProvider: model, shouldShowRewards: true) + showTxFilter(sender: sender, displayModeCallback: { [weak self] mode in + self?.viewModel.displayMode = mode + }, shouldShowRewards: true) } func homeView(_ homeView: HomeView, showSyncingStatus sender: UIView) { @@ -312,10 +316,6 @@ extension HomeViewController: HomeViewDelegate { present(controller, animated: true, completion: nil) } - func homeView(_ homeView: HomeView, showReclassifyYourTransactionsFlowWithTransaction transaction: DSTransaction) { - showReclassifyYourTransactionsIfPossible(with: transaction) - } - #if DASHPAY func homeView(_ homeView: HomeView, didUpdateProfile identity: DSBlockchainIdentity?, unreadNotifications: UInt) { avatarView.blockchainIdentity = identity @@ -330,7 +330,7 @@ extension HomeViewController: HomeViewDelegate { // MARK: - TxReclassifyTransactionsInfoViewControllerDelegate extension HomeViewController: TxReclassifyTransactionsInfoViewControllerDelegate { - func txReclassifyTransactionsFlowDidClosedWithUnderstanding(controller: TxReclassifyTransactionsInfoViewController, transaction: DSTransaction) { + func txReclassifyTransactionsFlowDidClose(controller: TxReclassifyTransactionsInfoViewController, transaction: DSTransaction) { presentTransactionDetails(transaction) } } diff --git a/DashWallet/Sources/UI/Home/Models/DWHomeModel.m b/DashWallet/Sources/UI/Home/Models/DWHomeModel.m index 5c5b9414b..18b62830c 100644 --- a/DashWallet/Sources/UI/Home/Models/DWHomeModel.m +++ b/DashWallet/Sources/UI/Home/Models/DWHomeModel.m @@ -50,10 +50,10 @@ @interface DWHomeModel () @property (nonatomic, strong) SyncingActivityMonitor *syncMonitor; -@property (readonly, nonatomic, strong) DWTransactionListDataSource *dataSource; -@property (null_resettable, nonatomic, strong) DWTransactionListDataSource *receivedDataSource; -@property (null_resettable, nonatomic, strong) DWTransactionListDataSource *sentDataSource; -@property (null_resettable, nonatomic, strong) DWTransactionListDataSource *rewardsDataSource; +@property (readonly, nonatomic, strong) NSArray *dataSource; +@property (null_resettable, nonatomic, strong) NSArray *receivedDataSource; +@property (null_resettable, nonatomic, strong) NSArray *sentDataSource; +@property (null_resettable, nonatomic, strong) NSArray *rewardsDataSource; @property (nonatomic, assign) BOOL upgradedExtendedKeys; @@ -61,13 +61,11 @@ @interface DWHomeModel () @implementation DWHomeModel -@synthesize displayMode = _displayMode; @synthesize payModel = _payModel; @synthesize receiveModel = _receiveModel; @synthesize dashPayModel = _dashPayModel; @synthesize updatesObserver = _updatesObserver; @synthesize allDataSource = _allDataSource; -@synthesize allowedToShowReclassifyYourTransactions = _allowedToShowReclassifyYourTransactions; - (instancetype)init { @@ -94,8 +92,7 @@ - (instancetype)init { #endif /* DASHPAY_ENABLED */ // set empty datasource - _allDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:@[] - registrationStatus:[_dashPayModel registrationStatus]]; + _allDataSource = @[]; _receiveModel = [[DWReceiveModel alloc] init]; [_receiveModel updateReceivingInfo]; @@ -115,15 +112,10 @@ - (instancetype)init { selector:@selector(walletBalanceDidChangeNotification) name:DSWalletBalanceDidChangeNotification object:nil]; - [notificationCenter addObserver:self - selector:@selector(transactionManagerTransactionStatusDidChangeNotification) - name:DSTransactionManagerTransactionStatusDidChangeNotification - object:nil]; [notificationCenter addObserver:self selector:@selector(chainWalletsDidChangeNotification:) name:DSChainWalletsDidChangeNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(willWipeWalletNotification) name:DWWillWipeWalletNotification @@ -133,15 +125,6 @@ - (instancetype)init { name:DWApp.fiatCurrencyDidChangeNotification object:nil]; -#if DASHPAY - [notificationCenter addObserver:self - selector:@selector(dashPayRegistrationStatusUpdatedNotification) - name:DWDashPayRegistrationStatusUpdatedNotification - object:nil]; -#endif - - [self reloadTxDataSource]; - NSDate *date = [NSDate new]; [[DWGlobalOptions sharedInstance] setActivationDateForReclassifyYourTransactionsFlowIfNeeded:date]; [[DWGlobalOptions sharedInstance] setActivationDateForHistoricalRates:date]; @@ -159,29 +142,10 @@ - (void)setUpdatesObserver:(nullable id)updatesObser _updatesObserver = updatesObserver; if (self.allDataSource) { - [updatesObserver homeModel:self didUpdateDataSource:self.dataSource shouldAnimate:NO]; + [updatesObserver homeModel:self didUpdate:self.dataSource shouldAnimate:NO]; } } -- (void)setDisplayMode:(DWHomeTxDisplayMode)displayMode { - if (_displayMode == displayMode) { - return; - } - - _displayMode = displayMode; - - [self.updatesObserver homeModel:self didUpdateDataSource:self.dataSource shouldAnimate:YES]; -} - -- (void)setAllowedToShowReclassifyYourTransactions:(BOOL)value { - _allowedToShowReclassifyYourTransactions = value; -} - -- (BOOL)isAllowedToShowReclassifyYourTransactions { - BOOL shouldDisplayReclassifyYourTransactionsFlow = [DWGlobalOptions sharedInstance].shouldDisplayReclassifyYourTransactionsFlow; - return _allowedToShowReclassifyYourTransactions && shouldDisplayReclassifyYourTransactionsFlow; -} - - (BOOL)isWalletEmpty { DSWallet *wallet = [DWEnvironment sharedInstance].currentWallet; const BOOL hasFunds = (wallet.totalReceived + wallet.totalSent > 0); @@ -189,19 +153,6 @@ - (BOOL)isWalletEmpty { return !hasFunds; } -- (DWTransactionListDataSource *)dataSource { - switch (self.displayMode) { - case DWHomeTxDisplayMode_All: - return self.allDataSource; - case DWHomeTxDisplayMode_Received: - return self.receivedDataSource; - case DWHomeTxDisplayMode_Sent: - return self.sentDataSource; - case DWHomeTxDisplayMode_Rewards: - return self.rewardsDataSource; - } -} - - (BOOL)shouldShowWalletBackupReminder { DWGlobalOptions *options = [DWGlobalOptions sharedInstance]; if (!options.walletNeedsBackup) { @@ -354,11 +305,6 @@ - (void)reachabilityDidChangeNotification { - (void)walletBalanceDidChangeNotification { [self updateBalance]; - [self reloadTxDataSource]; -} - -- (void)transactionManagerTransactionStatusDidChangeNotification { - [self reloadTxDataSource]; } - (void)applicationWillEnterForegroundNotification { @@ -367,7 +313,6 @@ - (void)applicationWillEnterForegroundNotification { - (void)fiatCurrencyDidChangeNotification { [self updateBalance]; - [self reloadTxDataSource]; [self.updatesObserver homeModelDidChangeInnerModels:self]; } @@ -379,13 +324,6 @@ - (void)chainWalletsDidChangeNotification:(NSNotification *)notification { } } -- (void)dashPayRegistrationStatusUpdatedNotification { - [self reloadTxDataSource]; -#if DASHPAY - [[DWDashPayContactsUpdater sharedInstance] beginUpdating]; -#endif -} - - (void)willWipeWalletNotification { #if DASHPAY [[DWDashPayContactsUpdater sharedInstance] endUpdating]; @@ -394,42 +332,6 @@ - (void)willWipeWalletNotification { #pragma mark - Private -- (void)notifyAboutNewTransaction { -} - -- (DWTransactionListDataSource *)receivedDataSource { - if (_receivedDataSource == nil) { - NSArray *transactions = [self filterTransactions:self.allDataSource.items - forDisplayMode:DWHomeTxDisplayMode_Received]; - _receivedDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:transactions - registrationStatus:[self.dashPayModel registrationStatus]]; - } - - return _receivedDataSource; -} - -- (DWTransactionListDataSource *)sentDataSource { - if (_sentDataSource == nil) { - NSArray *transactions = [self filterTransactions:self.allDataSource.items - forDisplayMode:DWHomeTxDisplayMode_Sent]; - _sentDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:transactions - registrationStatus:[self.dashPayModel registrationStatus]]; - } - - return _sentDataSource; -} - -- (DWTransactionListDataSource *)rewardsDataSource { - if (_rewardsDataSource == nil) { - NSArray *transactions = [self filterTransactions:self.allDataSource.items - forDisplayMode:DWHomeTxDisplayMode_Rewards]; - _rewardsDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:transactions - registrationStatus:[self.dashPayModel registrationStatus]]; - } - - return _rewardsDataSource; -} - - (void)startSyncIfNeeded { // This method might be called from init. Don't use any instance variables @@ -439,118 +341,11 @@ - (void)startSyncIfNeeded { } } -- (void)reloadTxDataSource { - dispatch_async(self.queue, ^{ - DSWallet *wallet = [DWEnvironment sharedInstance].currentWallet; - - NSString *sortKey = DW_KEYPATH(DSTransaction.new, timestamp); - - // Timestamps are set to 0 if the transaction hasn't yet been confirmed, they should be at the top of the list if this is the case - NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortKey - ascending:NO - comparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { - if ([obj1 unsignedIntValue] == 0) { - if ([obj2 unsignedIntValue] == 0) { - return NSOrderedSame; - } - else { - return NSOrderedDescending; - } - } - else if ([obj2 unsignedIntValue] == 0) { - return NSOrderedAscending; - } - else { - return [(NSNumber *)obj2 compare:obj2]; - } - }]; - NSArray *transactions = [wallet.allTransactions sortedArrayUsingDescriptors:@[ sortDescriptor ]]; - - BOOL receivedNewTransaction = NO; - BOOL allowedToShowReclassifyYourTransactions = NO; - BOOL shouldAnimate = YES; - - DSTransaction *prevTransaction = self.allDataSource.items.firstObject; - DSTransaction *newTransaction = transactions.firstObject; - - if (!prevTransaction || prevTransaction == newTransaction) { - shouldAnimate = NO; - } - - if (newTransaction && prevTransaction != newTransaction) { - receivedNewTransaction = YES; - - NSDate *dateReclassifyYourTransactionsFlowActivated = [DWGlobalOptions sharedInstance].dateReclassifyYourTransactionsFlowActivated; - allowedToShowReclassifyYourTransactions = [newTransaction.transactionDate compare:dateReclassifyYourTransactionsFlowActivated] == NSOrderedDescending; - } - - for (DSTransaction *tx in transactions) { - [Tx.shared updateRateIfNeededFor:tx]; - } - - self.allDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:transactions - registrationStatus:self.dashPayModel.registrationStatus]; - self.receivedDataSource = nil; - self.sentDataSource = nil; - - // pre-filter while in background queue - if (self.displayMode == DWHomeTxDisplayMode_Received) { - [self receivedDataSource]; - } - else if (self.displayMode == DWHomeTxDisplayMode_Sent) { - [self sentDataSource]; - } - else if (self.displayMode == DWHomeTxDisplayMode_Rewards) { - [self rewardsDataSource]; - } - - DWTransactionListDataSource *datasource = self.dataSource; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self setAllowedToShowReclassifyYourTransactions:allowedToShowReclassifyYourTransactions]; - - if (receivedNewTransaction) { - // TODO: try to do for all transactions - if (newTransaction.direction == DSTransactionDirection_Received) { - [self.updatesObserver homeModel:self didReceiveNewIncomingTransaction:newTransaction]; - } - } - [self.updatesObserver homeModel:self didUpdateDataSource:datasource shouldAnimate:shouldAnimate]; - }); - }); -} - - (void)updateBalance { [self.receiveModel updateReceivingInfo]; [self.updatesObserver homeModelWantToReloadShortcuts:self]; } -- (NSArray *)filterTransactions:(NSArray *)allTransactions - forDisplayMode:(DWHomeTxDisplayMode)displayMode { - NSAssert(displayMode != DWHomeTxDisplayMode_All, @"All transactions should not be filtered"); - if (displayMode == DWHomeTxDisplayMode_All) { - return allTransactions; - } - - DSAccount *account = [DWEnvironment sharedInstance].currentAccount; - NSMutableArray *mutableTransactions = [NSMutableArray array]; - - for (DSTransaction *tx in allTransactions) { - uint64_t sent = [account amountSentByTransaction:tx]; - if (displayMode == DWHomeTxDisplayMode_Sent && sent > 0) { - [mutableTransactions addObject:tx]; - } - else if (displayMode == DWHomeTxDisplayMode_Received && sent == 0 && ![tx isKindOfClass:[DSCoinbaseTransaction class]]) { - [mutableTransactions addObject:tx]; - } - else if (displayMode == DWHomeTxDisplayMode_Rewards && sent == 0 && [tx isKindOfClass:[DSCoinbaseTransaction class]]) { - [mutableTransactions addObject:tx]; - } - } - - return [mutableTransactions copy]; -} - #pragma mark SyncingActivityMonitorObserver - (void)syncingActivityMonitorProgressDidChange:(double)progress { @@ -573,7 +368,6 @@ - (void)syncingActivityMonitorStateDidChangeWithPreviousState:(enum SyncingActiv } [self updateBalance]; - [self reloadTxDataSource]; } @end diff --git a/DashWallet/Sources/UI/Home/Models/TransactionListDataSource.swift b/DashWallet/Sources/UI/Home/Models/TransactionListDataSource.swift deleted file mode 100644 index 5ddd7acb1..000000000 --- a/DashWallet/Sources/UI/Home/Models/TransactionListDataSource.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by tkhp -// Copyright © 2023 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import UIKit - -// MARK: - TransactionListDataSource - -@objc(DWTransactionListDataSource) -final class TransactionListDataSource: NSObject { - @objc - var items: [DSTransaction] - - var registrationStatus: DWDPRegistrationStatus? - - @objc - var retryDelegate: DWDPRegistrationErrorRetryDelegate? - - var showsRegistrationStatus: Bool { - registrationStatus != nil - } - - @objc - init(transactions: [DSTransaction], registrationStatus: DWDPRegistrationStatus?) { - self.items = transactions - self.registrationStatus = registrationStatus - } -} diff --git a/DashWallet/Sources/UI/Home/Protocols/DWHomeProtocol.h b/DashWallet/Sources/UI/Home/Protocols/DWHomeProtocol.h index bc717b670..56fa44161 100644 --- a/DashWallet/Sources/UI/Home/Protocols/DWHomeProtocol.h +++ b/DashWallet/Sources/UI/Home/Protocols/DWHomeProtocol.h @@ -19,12 +19,10 @@ #import "DWDashPayProtocol.h" #import "DWDashPayReadyProtocol.h" -#import "DWTxDisplayModeProtocol.h" NS_ASSUME_NONNULL_BEGIN @protocol DWHomeProtocol; -@class DWTransactionListDataSource; @class DSTransaction; @protocol DWPayModelProtocol; @protocol DWReceiveModelProtocol; @@ -33,18 +31,15 @@ NS_ASSUME_NONNULL_BEGIN @protocol DWHomeModelUpdatesObserver - (void)homeModel:(id)model - didUpdateDataSource:(DWTransactionListDataSource *)dataSource - shouldAnimate:(BOOL)shouldAnimate; - -- (void)homeModel:(id)model - didReceiveNewIncomingTransaction:(DSTransaction *)transaction; + didUpdate:(NSArray *)dataSource + shouldAnimate:(BOOL)shouldAnimate; - (void)homeModelDidChangeInnerModels:(id)model; - (void)homeModelWantToReloadShortcuts:(id)model; - (void)homeModelWantToReloadVoting:(id)model; @end -@protocol DWHomeProtocol +@protocol DWHomeProtocol @property (nullable, nonatomic, weak) id updatesObserver; @@ -52,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly, nonatomic, strong) id receiveModel; @property (readonly, nonatomic, strong) id dashPayModel; -@property (nonatomic, strong) DWTransactionListDataSource *allDataSource; +@property (nonatomic, strong) NSArray *allDataSource; @property (readonly, nonatomic, assign) BOOL shouldShowWalletBackupReminder; diff --git a/DashWallet/Sources/UI/Home/Protocols/DWTxDisplayModeProtocol.h b/DashWallet/Sources/UI/Home/Protocols/DWTxDisplayModeProtocol.h deleted file mode 100644 index 071af4d1b..000000000 --- a/DashWallet/Sources/UI/Home/Protocols/DWTxDisplayModeProtocol.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2019 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSUInteger, DWHomeTxDisplayMode) { - DWHomeTxDisplayMode_All, - DWHomeTxDisplayMode_Received, - DWHomeTxDisplayMode_Sent, - DWHomeTxDisplayMode_Rewards, -}; - -@protocol DWTxDisplayModeProtocol - -@property (nonatomic, assign) DWHomeTxDisplayMode displayMode; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.h b/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.h deleted file mode 100644 index 82eb6dca3..000000000 --- a/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2019 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import - -#import "DWTxDisplayModeProtocol.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface UIViewController (DWTxFilter) - -- (void)showTxFilterWithSender:(UIView *)sender - displayModeProvider:(id)displayModeProvider - shouldShowRewards:(BOOL)shouldShowRewards; - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.m b/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.m deleted file mode 100644 index 9c76296d3..000000000 --- a/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.m +++ /dev/null @@ -1,96 +0,0 @@ -// -// Created by Andrew Podkovyrin -// Copyright © 2019 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "UIViewController+DWTxFilter.h" - -#import "DWEnvironment.h" - -NS_ASSUME_NONNULL_BEGIN - -@implementation UIViewController (DWTxFilter) - -- (void)showTxFilterWithSender:(UIView *)sender - displayModeProvider:(id)displayModeProvider - shouldShowRewards:(BOOL)shouldShowRewards { - NSString *title = NSLocalizedString(@"Filter Transactions", nil); - UIAlertController *alert = [UIAlertController - alertControllerWithTitle:title - message:nil - preferredStyle:UIAlertControllerStyleActionSheet]; - { - UIAlertAction *action = [UIAlertAction - actionWithTitle:NSLocalizedString(@"All", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *_Nonnull action) { - displayModeProvider.displayMode = DWHomeTxDisplayMode_All; - }]; - [alert addAction:action]; - } - - { - UIAlertAction *action = [UIAlertAction - actionWithTitle:NSLocalizedString(@"Received", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *_Nonnull action) { - displayModeProvider.displayMode = DWHomeTxDisplayMode_Received; - }]; - [alert addAction:action]; - } - - DSAccount *account = [DWEnvironment sharedInstance].currentAccount; - - if (shouldShowRewards && [account hasCoinbaseTransaction]) { - UIAlertAction *action = [UIAlertAction - actionWithTitle:NSLocalizedString(@"Rewards", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *_Nonnull action) { - displayModeProvider.displayMode = DWHomeTxDisplayMode_Rewards; - }]; - [alert addAction:action]; - } - - { - UIAlertAction *action = [UIAlertAction - actionWithTitle:NSLocalizedString(@"Sent", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *_Nonnull action) { - displayModeProvider.displayMode = DWHomeTxDisplayMode_Sent; - }]; - [alert addAction:action]; - } - - { - UIAlertAction *action = [UIAlertAction - actionWithTitle:NSLocalizedString(@"Cancel", nil) - style:UIAlertActionStyleCancel - handler:nil]; - [alert addAction:action]; - } - - if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { - alert.popoverPresentationController.sourceView = sender; - alert.popoverPresentationController.sourceRect = sender.bounds; - } - - [self presentViewController:alert - animated:YES - completion:nil]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.swift b/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.swift new file mode 100644 index 000000000..5e2d007a7 --- /dev/null +++ b/DashWallet/Sources/UI/Home/UIViewController+DWTxFilter.swift @@ -0,0 +1,73 @@ +// +// Created by Andrew Podkovyrin +// Copyright © 2019 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +extension UIViewController { + @objc + func showTxFilter(sender: UIView, + displayModeCallback: @escaping (HomeTxDisplayMode) -> Void, + shouldShowRewards: Bool) { + let title = NSLocalizedString("Filter Transactions", comment: "") + let alert = UIAlertController(title: title, + message: nil, + preferredStyle: .actionSheet) + + let allAction = UIAlertAction( + title: NSLocalizedString("All", comment: ""), + style: .default) { _ in + displayModeCallback(.all) + } + alert.addAction(allAction) + + let receivedAction = UIAlertAction( + title: NSLocalizedString("Received", comment: ""), + style: .default) { _ in + displayModeCallback(.received) + } + alert.addAction(receivedAction) + + let account = DWEnvironment.sharedInstance().currentAccount + if shouldShowRewards && account.hasCoinbaseTransaction { + let rewardsAction = UIAlertAction( + title: NSLocalizedString("Rewards", comment: ""), + style: .default) { _ in + displayModeCallback(.rewards) + } + alert.addAction(rewardsAction) + } + + let sentAction = UIAlertAction( + title: NSLocalizedString("Sent", comment: ""), + style: .default) { _ in + displayModeCallback(.sent) + } + alert.addAction(sentAction) + + let cancelAction = UIAlertAction( + title: NSLocalizedString("Cancel", comment: ""), + style: .cancel) + alert.addAction(cancelAction) + + if UIDevice.current.userInterfaceIdiom == .pad { + alert.popoverPresentationController?.sourceView = sender + alert.popoverPresentationController?.sourceRect = sender.bounds + } + + present(alert, animated: true) + } +} diff --git a/DashWallet/Sources/UI/Home/Views/Cells/CoinJoinProgressView.swift b/DashWallet/Sources/UI/Home/Views/Cells/CoinJoinProgressView.swift index 79aea54c7..4619579f3 100644 --- a/DashWallet/Sources/UI/Home/Views/Cells/CoinJoinProgressView.swift +++ b/DashWallet/Sources/UI/Home/Views/Cells/CoinJoinProgressView.swift @@ -73,7 +73,7 @@ struct CoinJoinProgressInfo: View { .padding(.leading, state == .mixing ? 2 : 5) if state.isInProgress { - Text(progress.formatted(.percent.precision(.fractionLength(0...2)))) + Text(progress.formatted(.percent.precision(.fractionLength(0...1)))) .foregroundColor(textColor) .font(font) .padding(.leading, 4) diff --git a/DashWallet/Sources/UI/Home/Views/Home Header View/HomeHeaderView.swift b/DashWallet/Sources/UI/Home/Views/Home Header View/HomeHeaderView.swift index ad6f314a1..7396aade1 100644 --- a/DashWallet/Sources/UI/Home/Views/Home Header View/HomeHeaderView.swift +++ b/DashWallet/Sources/UI/Home/Views/Home Header View/HomeHeaderView.swift @@ -132,7 +132,6 @@ final class HomeHeaderView: UIView { } self?.reloadBalance() - self?.reloadShortcuts() } } @@ -149,10 +148,6 @@ final class HomeHeaderView: UIView { balanceView.state = isSyncing ? .syncing : .`default` } - func reloadShortcuts() { - shortcutsView.reloadData() - } - private func hideSyncView() { syncView.isHidden = true delegate?.homeHeaderViewDidUpdateContents(self) diff --git a/DashWallet/Sources/UI/Home/Views/HomeView.swift b/DashWallet/Sources/UI/Home/Views/HomeView.swift index 2da145329..6d312cf40 100644 --- a/DashWallet/Sources/UI/Home/Views/HomeView.swift +++ b/DashWallet/Sources/UI/Home/Views/HomeView.swift @@ -24,7 +24,6 @@ protocol HomeViewDelegate: AnyObject { func homeView(_ homeView: HomeView, showTxFilter sender: UIView) func homeView(_ homeView: HomeView, showSyncingStatus sender: UIView) func homeViewShowCoinJoin() - func homeView(_ homeView: HomeView, showReclassifyYourTransactionsFlowWithTransaction transaction: DSTransaction) #if DASHPAY func homeView(_ homeView: HomeView, didUpdateProfile identity: DSBlockchainIdentity?, unreadNotifications: UInt) @@ -34,15 +33,12 @@ protocol HomeViewDelegate: AnyObject { // MARK: - HomeView -final class HomeView: UIView, DWHomeModelUpdatesObserver, DWDPRegistrationErrorRetryDelegate { +final class HomeView: UIView, DWHomeModelUpdatesObserver { weak var delegate: HomeViewDelegate? private(set) var headerView: HomeHeaderView! private(set) var syncingHeaderView: SyncingHeaderView! - - // Strong ref to current dataSource to make sure it always exists while tableView uses it - var currentDataSource: TransactionListDataSource? - private let viewModel = HomeViewModel.shared + let viewModel = HomeViewModel.shared @objc var model: DWHomeProtocol? { @@ -134,27 +130,18 @@ final class HomeView: UIView, DWHomeModelUpdatesObserver, DWDPRegistrationErrorR // MARK: - DWHomeModelUpdatesObserver - func homeModel(_ model: DWHomeProtocol, didUpdate dataSource: TransactionListDataSource, shouldAnimate: Bool) { - currentDataSource = dataSource - dataSource.retryDelegate = self - - self.viewModel.updateItems(transactions: dataSource.items) - + func homeModel(_ model: any DWHomeProtocol, didUpdate dataSource: [DSTransaction], shouldAnimate: Bool) { + self.viewModel.reloadShortcuts() headerView.reloadBalance() - reloadShortcuts() - } - - func homeModel(_ model: DWHomeProtocol, didReceiveNewIncomingTransaction transaction: DSTransaction) { - delegate?.homeView(self, showReclassifyYourTransactionsFlowWithTransaction: transaction) } func homeModelDidChangeInnerModels(_ model: DWHomeProtocol) { headerView.reloadBalance() - reloadShortcuts() + viewModel.reloadShortcuts() } func homeModelWant(toReloadShortcuts model: DWHomeProtocol) { - reloadShortcuts() + viewModel.reloadShortcuts() #if DASHPAY updateHeaderView() #endif @@ -166,21 +153,15 @@ final class HomeView: UIView, DWHomeModelUpdatesObserver, DWDPRegistrationErrorR #endif } - // MARK: - DWDPRegistrationErrorRetryDelegate - func registrationErrorRetryAction() { + func registrationErrorRetryAction() { // TODO if model?.dashPayModel.canRetry() ?? false { model?.dashPayModel.retry() } else { - // TODO + } } - - @objc - func reloadShortcuts() { - headerView?.reloadShortcuts() - } // MARK: DWDashPayRegistrationStatusUpdated @@ -337,12 +318,12 @@ struct HomeViewContent: View { .foregroundColor(Color.primary.opacity(0.5)) .padding(.top, 20) } else { - ForEach(viewModel.txItems, id: \.0.key) { key, value in - Section(header: SectionHeader(key) + ForEach(viewModel.txItems) { group in + Section(header: SectionHeader(key: group.id, date: group.date) .padding(.bottom, -24) ) { VStack(spacing: 0) { - ForEach(value, id: \.id) { txItem in + ForEach(group.items, id: \.id) { txItem in TransactionPreviewFrom(txItem: txItem) .padding(.horizontal, 5) } @@ -408,19 +389,19 @@ struct HomeViewContent: View { } @ViewBuilder - private func SectionHeader(_ dateKey: DateKey) -> some View { + private func SectionHeader(key: String, date: Date) -> some View { VStack { Spacer() HStack { - Text(dateKey.key) + Text(key) .font(.footnote) .fontWeight(.medium) .padding(.leading, 15) Spacer() - Text(DWDateFormatter.sharedInstance.dayOfWeek(from: dateKey.date)) + Text(DWDateFormatter.sharedInstance.dayOfWeek(from: date)) .font(.footnote) .foregroundStyle(Color.tertiaryText) .padding(.trailing, 15) @@ -439,17 +420,29 @@ struct HomeViewContent: View { txItem txDataItem: TransactionListDataItem ) -> some View { switch txDataItem { - case .crowdnode(let txItems): + case .crowdnode(let set): TransactionPreview( title: NSLocalizedString("CrowdNode · Account", comment: "Crowdnode"), - subtitle: txItems.last?.shortTimeString ?? "", - topText: String(format: NSLocalizedString("%d transaction(s)", comment: "#bc-ignore!"), txItems.count), + subtitle: set.transactions.values.first?.formattedShortTxTime ?? "", + topText: String(format: NSLocalizedString("%d transaction(s)", comment: "#bc-ignore!"), set.transactions.count), icon: .custom("tx.item.cn.icon"), - dashAmount: self.crowdNodeAmount(txItems) + dashAmount: set.amount ) { self.selectedTxDataItem = txDataItem } .frame(height: 80) + + case .coinjoin(let set): + TransactionPreview( + title: NSLocalizedString("CoinJoin Mixing", comment: "CoinJoin"), + subtitle: set.transactions.values.first?.formattedShortTxTime ?? "", + topText: String(format: NSLocalizedString("%d transaction(s)", comment: "#bc-ignore!"), set.transactions.count), + icon: .custom("tx.item.cn.icon"), // TODO + dashAmount: set.amount + ) { +// self.selectedTxDataItem = txDataItem + } + .frame(height: 80) case .tx(let txItem): TransactionPreview( @@ -464,24 +457,6 @@ struct HomeViewContent: View { } } - private func crowdNodeAmount(_ transactions: [Transaction]) -> Int64 { - return transactions.reduce(0) { partialResult, tx in - var r = partialResult - let direction = tx.direction - - switch direction { - case .sent: - r -= Int64(tx.dashAmount) - case .received: - r += Int64(tx.dashAmount) - default: - break - } - - return r - } - } - #if DASHPAY private func finishMixDialogNavigation() { if navigateToDashPayFlow { @@ -518,9 +493,17 @@ struct TransactionDetailsSheet: View { from txDataItem: TransactionListDataItem ) -> some View { switch txDataItem { - case .crowdnode(let txItems): + case .crowdnode(let set): CrowdNodeGroupedTransactionsScreen( - model: CNCreateAccountTxDetailsModel(transactions: txItems), + model: CNCreateAccountTxDetailsModel(transactions: set.transactions.values.map { Transaction(transaction: $0) }), + backNavigationRequested: $backNavigationRequested, + onShowBackButton: { show in + showBackButton = show + } + ) + case .coinjoin(let set): + CrowdNodeGroupedTransactionsScreen( // TODO + model: CNCreateAccountTxDetailsModel(transactions: set.transactions.values.map { Transaction(transaction: $0) }), backNavigationRequested: $backNavigationRequested, onShowBackButton: { show in showBackButton = show diff --git a/DashWallet/Sources/UI/Home/Views/HomeViewModel.swift b/DashWallet/Sources/UI/Home/Views/HomeViewModel.swift index e625bdc4f..41635fb16 100644 --- a/DashWallet/Sources/UI/Home/Views/HomeViewModel.swift +++ b/DashWallet/Sources/UI/Home/Views/HomeViewModel.swift @@ -20,10 +20,19 @@ import Combine private let kBaseBalanceHeaderHeight: CGFloat = 250 private let kTimeskewTolerance: TimeInterval = 3600 // 1 hour +private let maxShortcutsCount = 4 + +@objc(DWHomeTxDisplayMode) +public enum HomeTxDisplayMode: UInt { + case all = 0 + case received + case sent + case rewards +} -@MainActor class HomeViewModel: ObservableObject { private var cancellableBag = Set() + private let queue = DispatchQueue(label: "HomeViewModel", qos: .userInitiated) private let coinJoinService = CoinJoinService.shared private var timeSkewDialogShown: Bool = false @@ -31,12 +40,22 @@ class HomeViewModel: ObservableObject { return HomeViewModel() }() - @Published private(set) var txItems: Array<(DateKey, [TransactionListDataItem])> = [] - @Published private(set) var balanceHeaderHeight: CGFloat = kBaseBalanceHeaderHeight // TDOO: move back to HomeView when fully transitioned to SwiftUI + private var txByHash: [String: TransactionListDataItem] = [:] + private var crowdNodeTxSet = FullCrowdNodeSignUpTxSet() + + @Published private(set) var txItems: [TransactionGroup] = [] + @Published var shortcutItems: [ShortcutAction] = [] @Published private(set) var coinJoinItem = CoinJoinMenuItemModel(title: NSLocalizedString("Mixing", comment: "CoinJoin"), isOn: false, state: .notStarted, progress: 0.0, mixed: 0.0, total: 0.0) @Published var showTimeSkewAlertDialog: Bool = false @Published private(set) var timeSkew: TimeInterval = 0 @Published var showJoinDashpay: Bool = true + @Published var displayMode: HomeTxDisplayMode = .all { + didSet { + reloadTxDataSource() + } + } + @Published private(set) var balanceHeaderHeight: CGFloat = kBaseBalanceHeaderHeight // TDOO: move back to HomeView when fully transitioned to SwiftUI + @Published private(set) var showReclassifyTransaction: DSTransaction? = nil private var model: SyncModel = SyncModelImpl() @@ -44,6 +63,21 @@ class HomeViewModel: ObservableObject { get { coinJoinService.mode } } + private var reclassifyTransactionsActivatedAt: Date { + get { DWGlobalOptions.sharedInstance().dateReclassifyYourTransactionsFlowActivated ?? Date() } + } + + private var shouldDisplayReclassifyTransaction: Bool { + get { DWGlobalOptions.sharedInstance().shouldDisplayReclassifyYourTransactionsFlow } + set(value) { + DWGlobalOptions.sharedInstance().shouldDisplayReclassifyYourTransactionsFlow = value + + if (!value) { + showReclassifyTransaction = nil + } + } + } + #if DASHPAY var shouldShowMixDashDialog: Bool { get { coinJoinService.mode == .none || !UsernamePrefs.shared.mixDashShown } @@ -60,42 +94,173 @@ class HomeViewModel: ObservableObject { model.networkStatusDidChange = { status in self.recalculateHeight() } + model.stateDidChage = { state in + self.reloadTxDataSource() + self.reloadShortcuts() + } + self.reloadTxDataSource() + self.reloadShortcuts() self.recalculateHeight() + self.observeCoinJoin() + self.observeWallet() + #if DASHPAY + self.observeDashPay() + #endif + } + + private func observeWallet() { + NotificationCenter.default.publisher(for: Notification.Name.fiatCurrencyDidChange) + .sink { [weak self] _ in + self?.reloadTxDataSource() + } + .store(in: &cancellableBag) + + NotificationCenter.default.publisher(for: .DSTransactionManagerTransactionStatusDidChange) + .sink { [weak self] notification in + if let tx = notification.userInfo?[DSTransactionManagerNotificationTransactionKey] as? DSTransaction { + self?.onTransactionStatusChanged(tx: tx) + } + } + .store(in: &cancellableBag) + + NotificationCenter.default.publisher(for: Notification.Name.DSChainManagerSyncWillStart) + .sink { [weak self] _ in + if DWGlobalOptions.sharedInstance().isResyncingWallet { + self?.reloadTxDataSource() + } + } + .store(in: &cancellableBag) } - func updateItems(transactions: [DSTransaction]) { - Task.detached { - let crowdNodeTxSet = FullCrowdNodeSignUpTxSet() + // This is expensive and should not be called often + private func reloadTxDataSource() { + self.queue.async { [weak self] in + guard let self = self else { return } + let wallet = DWEnvironment.sharedInstance().currentWallet + let transactions = wallet.allTransactions + self.crowdNodeTxSet = FullCrowdNodeSignUpTxSet() + var items: [TransactionListDataItem] = transactions.compactMap { - if crowdNodeTxSet.isComplete { return .tx(Transaction(transaction: $0)) } + Tx.shared.updateRateIfNeeded(for: $0) + + if self.displayMode == .sent && $0.direction != .sent { + return nil + } - return crowdNodeTxSet.tryInclude(tx: $0) ? nil : .tx(Transaction(transaction: $0)) + if self.displayMode == .received && ($0.direction != .received || $0 is DSCoinbaseTransaction) { + return nil + } + + if self.displayMode == .rewards && !($0 is DSCoinbaseTransaction) { + return nil + } + + return !self.crowdNodeTxSet.isComplete && self.crowdNodeTxSet.tryInclude(tx: $0) ? nil : .tx(Transaction(transaction: $0)) + } + + self.txByHash.removeAll() + items.forEach { item in + self.txByHash[item.id] = item } if !crowdNodeTxSet.transactions.isEmpty { - let crowdNodeTxs: [Transaction] = crowdNodeTxSet.transactions.values - .sorted { $0.date > $1.date } - .map { Transaction(transaction: $0) } - - items.insert(.crowdnode(crowdNodeTxs), at: 0) + let item: TransactionListDataItem = .crowdnode(crowdNodeTxSet) + items.insert(item, at: 0) + self.txByHash[FullCrowdNodeSignUpTxSet.id] = item } let groupedItems = Dictionary( grouping: items.sorted(by: { $0.date > $1.date }), - by: { DateKey(key: DWDateFormatter.sharedInstance.dateOnly(from: $0.date), date: $0.date) } + by: { DWDateFormatter.sharedInstance.dateOnly(from: $0.date) } ) - let arary = groupedItems.sorted(by: { kv1, kv2 in - kv1.key.date > kv2.key.date - }) + let array = groupedItems.map { key, items in + TransactionGroup(id: key, date: items.first!.date, items: items) + }.sorted { $0.date > $1.date } DispatchQueue.main.async { - self.txItems = arary + self.txItems = array } } } + private func onTransactionStatusChanged(tx: DSTransaction) { + self.queue.async { [weak self] in + guard let self = self else { return } + + if self.displayMode == .sent && tx.direction != .sent { + return + } + + if self.displayMode == .received && (tx.direction != .received || tx is DSCoinbaseTransaction) { + return + } + + if self.displayMode == .rewards && !(tx is DSCoinbaseTransaction) { + return + } + + Tx.shared.updateRateIfNeeded(for: tx) + var itemId = tx.txHashHexString + var isCrowdNode = false + + if self.crowdNodeTxSet.tryInclude(tx: tx) { + itemId = FullCrowdNodeSignUpTxSet.id + isCrowdNode = true + } + + let txItem: TransactionListDataItem = isCrowdNode ? .crowdnode(self.crowdNodeTxSet) : .tx(Transaction(transaction: tx)) + let dateKey = DWDateFormatter.sharedInstance.dateOnly(from: txItem.date) + + if let existingItem = self.txByHash[itemId] { + // Updating existing item + self.txByHash[itemId] = txItem + var isChanged = true + + if case let .tx(existingTx) = existingItem, case let .tx(newTx) = txItem { + isChanged = newTx.state != existingTx.state + } + + if isChanged { + if let groupIndex = self.txItems.firstIndex(where: { $0.id == dateKey }), + let itemIndex = self.txItems[groupIndex].items.firstIndex(where: { $0.id == itemId }) { + DispatchQueue.main.async { + self.txItems[groupIndex].items[itemIndex] = txItem + } + } + } + } else { + // New item + self.txByHash[itemId] = txItem + let shouldShowReclassify = self.shouldDisplayReclassifyTransaction && tx.date > reclassifyTransactionsActivatedAt + + if let groupIndex = self.txItems.firstIndex(where: { $0.id == dateKey }) { + // Add to an existing date group + DispatchQueue.main.async { + self.txItems[groupIndex].items.append(txItem) + self.txItems[groupIndex].items.sort { $0.date > $1.date } + self.showReclassifyTransaction = shouldShowReclassify ? tx : nil + } + } else { + // Create a new date group + let newGroup = TransactionGroup(id: dateKey, date: txItem.date, items: [txItem]) + let insertIndex = self.txItems.firstIndex(where: { $0.date < txItem.date }) + + DispatchQueue.main.async { + if let index = insertIndex { + self.txItems.insert(newGroup, at: index) + } else { + self.txItems.append(newGroup) + } + self.showReclassifyTransaction = shouldShowReclassify ? tx : nil + } + } + } + } + } + + @MainActor func checkTimeSkew(force: Bool = false) { Task { let (isTimeSkewed, timeSkew) = await getDeviceTimeSkew(force: force) @@ -108,6 +273,12 @@ class HomeViewModel: ObservableObject { } } + func reclassifyTransactionShown(isShown: Bool) { + if isShown { + shouldDisplayReclassifyTransaction = false + } + } + private func recalculateHeight() { var height = kBaseBalanceHeaderHeight let hasNetwork = model.networkStatus == .online @@ -139,6 +310,8 @@ class HomeViewModel: ObservableObject { } } +// MARK: - CoinJoin + extension HomeViewModel { private func observeCoinJoin() { coinJoinService.$progress @@ -178,27 +351,95 @@ extension HomeViewModel { } } + +// MARK: - Shortcuts + +extension HomeViewModel { + func reloadShortcuts() { + let options = DWGlobalOptions.sharedInstance() + let walletNeedsBackup = options.walletNeedsBackup + let userHasBalance = options.userHasBalance + + var mutableItems = [ShortcutAction]() + mutableItems.reserveCapacity(2) + + if walletNeedsBackup { + mutableItems.append(ShortcutAction(type: .secureWallet)) + + if userHasBalance { + mutableItems.append(ShortcutAction(type: .receive)) + mutableItems.append(ShortcutAction(type: .payToAddress)) + mutableItems.append(ShortcutAction(type: .scanToPay)) + } else { + mutableItems.append(ShortcutAction(type: .explore)) + mutableItems.append(ShortcutAction(type: .receive)) + + if DWEnvironment.sharedInstance().currentChain.isMainnet() { + mutableItems.append(ShortcutAction(type: .buySellDash)) + } + } + } else { + if userHasBalance { + mutableItems.append(ShortcutAction(type: .explore)) + mutableItems.append(ShortcutAction(type: .receive)) + mutableItems.append(ShortcutAction(type: .payToAddress)) + mutableItems.append(ShortcutAction(type: .scanToPay)) + } else { + mutableItems.append(ShortcutAction(type: .explore)) + mutableItems.append(ShortcutAction(type: .receive)) + + if DWEnvironment.sharedInstance().currentChain.isMainnet() { + mutableItems.append(ShortcutAction(type: .buySellDash)) + } + } + } + + self.shortcutItems = mutableItems + } +} + +// MARK: - DashPay + +#if DASHPAY +extension HomeViewModel { + private func observeDashPay() { + NotificationCenter.default.publisher(for: .DWDashPayRegistrationStatusUpdated) + .sink { [weak self] _ in + self?.reloadTxDataSource() + DWDashPayContactsUpdater.sharedInstance().beginUpdating() + } + .store(in: &cancellableBag) + } +} +#endif + // MARK: - TransactionListDataItem +class TransactionGroup: Identifiable { + let id: String + let date: Date + var items: [TransactionListDataItem] + + init(id: String, date: Date, items: [TransactionListDataItem]) { + self.id = id + self.date = date + self.items = items + } +} + enum TransactionListDataItem { case tx(Transaction) - case crowdnode([Transaction]) + case crowdnode(FullCrowdNodeSignUpTxSet) + case coinjoin(CoinJoinMixingTxSet) } extension TransactionListDataItem: Identifiable { - var tx: Transaction { - switch self { - case .crowdnode(let txs): - return txs.first! - case .tx(let tx): - return tx - } - } - var id: String { switch self { - case .crowdnode(let txs): - return txs.first!.txHashHexString + case .crowdnode(_): + return FullCrowdNodeSignUpTxSet.id + case .coinjoin(let set): + return set.id case .tx(let tx): return tx.txHashHexString } @@ -206,29 +447,12 @@ extension TransactionListDataItem: Identifiable { var date: Date { switch self { - case .crowdnode(let txs): - return txs.last!.date + case .crowdnode(let set): + return set.transactions.values.first!.date + case .coinjoin(let set): + return set.groupDay case .tx(let tx): return tx.date } } } - -struct DateKey: Hashable { - let key: String - let date: Date - - static func == (lhs: DateKey, rhs: DateKey) -> Bool { - return lhs.key == rhs.key - } - - func hash(into hasher: inout Hasher) { - hasher.combine(key) - } -} - -extension FullCrowdNodeSignUpTxSet { - var isComplete: Bool { - transactions.count == 5 - } -} diff --git a/DashWallet/Sources/UI/Home/Views/Shortcuts/Models/ShortcutsModel.swift b/DashWallet/Sources/UI/Home/Views/Shortcuts/Models/ShortcutsModel.swift deleted file mode 100644 index 76d8f17c9..000000000 --- a/DashWallet/Sources/UI/Home/Views/Shortcuts/Models/ShortcutsModel.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// Created by PT -// Copyright © 2023 Dash Core Group. All rights reserved. -// -// Licensed under the MIT License (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://opensource.org/licenses/MIT -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import Foundation - - -let MAX_SHORTCUTS_COUNT = 4 - -// MARK: - ShortcutsModel - -final class ShortcutsModel { - private var mutableItems: [ShortcutAction] = [] - - var shortcutItemsDidChangeHandler: (() -> ())? - - @objc - init() { - reloadShortcuts() - } - - var items: [ShortcutAction] { - mutableItems - } - - @objc - func reloadShortcuts() { - mutableItems = Self.userShortcuts() - shortcutItemsDidChangeHandler?() - } - - // TODO: Move this to HomeModel - static func userShortcuts() -> [ShortcutAction] { - let options = DWGlobalOptions.sharedInstance() - let walletNeedsBackup = options.walletNeedsBackup - let userHasBalance = options.userHasBalance - - var mutableItems = [ShortcutAction]() - mutableItems.reserveCapacity(2) - - if walletNeedsBackup { - mutableItems.append(ShortcutAction(type: .secureWallet)) - - if userHasBalance { - mutableItems.append(ShortcutAction(type: .receive)) - mutableItems.append(ShortcutAction(type: .payToAddress)) - mutableItems.append(ShortcutAction(type: .scanToPay)) - } else { - mutableItems.append(ShortcutAction(type: .explore)) - mutableItems.append(ShortcutAction(type: .receive)) - - if DWEnvironment.sharedInstance().currentChain.isMainnet() { - mutableItems.append(ShortcutAction(type: .buySellDash)) - } - } - } else { - if userHasBalance { - mutableItems.append(ShortcutAction(type: .explore)) - mutableItems.append(ShortcutAction(type: .receive)) - mutableItems.append(ShortcutAction(type: .payToAddress)) - mutableItems.append(ShortcutAction(type: .scanToPay)) - } else { - mutableItems.append(ShortcutAction(type: .explore)) - mutableItems.append(ShortcutAction(type: .receive)) - - if DWEnvironment.sharedInstance().currentChain.isMainnet() { - mutableItems.append(ShortcutAction(type: .buySellDash)) - } - } - } - - return mutableItems - } -} diff --git a/DashWallet/Sources/UI/Home/Views/Shortcuts/ShortcutsView.swift b/DashWallet/Sources/UI/Home/Views/Shortcuts/ShortcutsView.swift index 41406b389..572614bb8 100644 --- a/DashWallet/Sources/UI/Home/Views/Shortcuts/ShortcutsView.swift +++ b/DashWallet/Sources/UI/Home/Views/Shortcuts/ShortcutsView.swift @@ -16,6 +16,7 @@ // import UIKit +import Combine func cellSize(for contentSizeCategory: UIContentSizeCategory) -> CGSize { var size = CGSize.zero @@ -70,6 +71,9 @@ protocol ShortcutsViewDelegate: AnyObject { @objc class ShortcutsView: UIView { + private var cancellableBag = Set() + private let viewModel = HomeViewModel.shared + @objc weak var actionDelegate: ShortcutsActionDelegate? @@ -85,8 +89,6 @@ class ShortcutsView: UIView { @IBOutlet var collectionViewHeightConstraint: NSLayoutConstraint! - var model = ShortcutsModel() - override init(frame: CGRect) { super.init(frame: frame) commonInit() @@ -97,15 +99,15 @@ class ShortcutsView: UIView { commonInit() } - func reloadData() { - model.reloadShortcuts() - } - private func commonInit() { - model.shortcutItemsDidChangeHandler = { [weak self] in - self?.collectionView.reloadData() - } - + viewModel.$shortcutItems + .removeDuplicates() + .receive(on: DispatchQueue.main) + .sink { [weak self] text in + self?.collectionView.reloadData() + } + .store(in: &cancellableBag) + Bundle.main.loadNibNamed(String(describing: type(of: self)), owner: self, options: nil) backgroundColor = .dw_secondaryBackground() @@ -169,7 +171,7 @@ class ShortcutsView: UIView { extension ShortcutsView: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let action = model.items[indexPath.item] + let action = viewModel.shortcutItems[indexPath.item] let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ShortcutCell.reuseIdentifier, for: indexPath) as! ShortcutCell cell.model = action @@ -184,13 +186,13 @@ extension ShortcutsView: UICollectionViewDataSource, UICollectionViewDelegate, U } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - model.items.count + viewModel.shortcutItems.count } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { collectionView.deselectItem(at: indexPath, animated: true) - let action = model.items[indexPath.item] + let action = viewModel.shortcutItems[indexPath.item] guard action.enabled else { return } guard let cell = collectionView.cellForItem(at: indexPath) else { return } diff --git a/DashWallet/Sources/UI/Onboarding/Stubs/DWHomeModelStub.m b/DashWallet/Sources/UI/Onboarding/Stubs/DWHomeModelStub.m index 030a12eec..7312f8029 100644 --- a/DashWallet/Sources/UI/Onboarding/Stubs/DWHomeModelStub.m +++ b/DashWallet/Sources/UI/Onboarding/Stubs/DWHomeModelStub.m @@ -30,10 +30,9 @@ @interface DWHomeModelStub () @property (readonly, nonatomic, copy) NSArray *stubTxs; - @property (readonly, nonatomic, strong) DWTransactionListDataProviderStub *dataProvider; - -@property (readonly, nonatomic, strong) DWTransactionListDataSource *dataSource; +@property (readonly, nonatomic, strong) NSArray *dataSource; +@property (nonatomic, assign) DWHomeTxDisplayMode displayMode; @end @@ -76,7 +75,7 @@ - (void)setUpdatesObserver:(nullable id)updatesObser _updatesObserver = updatesObserver; if (self.allDataSource) { - [updatesObserver homeModel:self didUpdateDataSource:self.dataSource shouldAnimate:NO]; + [updatesObserver homeModel:self didUpdate:self.dataSource shouldAnimate:NO]; } } @@ -87,10 +86,10 @@ - (void)setDisplayMode:(DWHomeTxDisplayMode)displayMode { _displayMode = displayMode; - [self.updatesObserver homeModel:self didUpdateDataSource:self.dataSource shouldAnimate:YES]; + [self.updatesObserver homeModel:self didUpdate:self.dataSource shouldAnimate:YES]; } -- (DWTransactionListDataSource *)dataSource { +- (NSArray *)dataSource { return self.allDataSource; } @@ -146,10 +145,8 @@ - (void)updateBalance { } - (void)reloadTxDataSource { - self.allDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:self.stubTxs - registrationStatus:[self.dashPayModel registrationStatus]]; - - [self.updatesObserver homeModel:self didUpdateDataSource:self.dataSource shouldAnimate:NO]; + self.allDataSource = self.stubTxs; + [self.updatesObserver homeModel:self didUpdate:self.dataSource shouldAnimate:NO]; } @end diff --git a/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.h b/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.h index a1b954ef5..0faa5e177 100644 --- a/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.h +++ b/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.h @@ -24,8 +24,8 @@ NS_ASSUME_NONNULL_BEGIN @interface DWTransactionStub : DSTransaction -@property (nonatomic, assign) uint64_t dashAmount; -@property (nonatomic, assign) DSTransactionDirection direction; +@property (nonatomic, assign) uint64_t stubDashAmount; +@property (nonatomic, assign) DSTransactionDirection stubDirection; + (NSArray *)stubs; diff --git a/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.m b/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.m index 7cd1b8b0c..3cecba4c3 100644 --- a/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.m +++ b/DashWallet/Sources/UI/Onboarding/Stubs/DWTransactionStub.m @@ -32,6 +32,14 @@ static UInt256 RandomUInt256(void) { @implementation DWTransactionStub +- (uint64_t)dashAmount { + return self.stubDashAmount; +} + +- (DSTransactionDirection)direction { + return self.stubDirection; +} + + (NSArray *)stubs { NSMutableArray *stubs = [NSMutableArray array]; @@ -41,8 +49,8 @@ @implementation DWTransactionStub DWTransactionStub *tx = [[DWTransactionStub alloc] initOnChain:dummyChain]; tx.txHash = RandomUInt256(); tx.timestamp = [NSDate timeIntervalSince1970] - 0 * 100000; - tx.dashAmount = DUFFS * 3.140000000001; - tx.direction = DSTransactionDirection_Sent; + tx.stubDashAmount = DUFFS * 3.140000000001; + tx.stubDirection = DSTransactionDirection_Sent; [stubs addObject:tx]; } @@ -50,8 +58,8 @@ @implementation DWTransactionStub DWTransactionStub *tx = [[DWTransactionStub alloc] initOnChain:dummyChain]; tx.txHash = RandomUInt256(); tx.timestamp = [NSDate timeIntervalSince1970] - 1 * 100000; - tx.dashAmount = DUFFS * 2.710000000001; - tx.direction = DSTransactionDirection_Received; + tx.stubDashAmount = DUFFS * 2.710000000001; + tx.stubDirection = DSTransactionDirection_Received; [stubs addObject:tx]; } @@ -59,8 +67,8 @@ @implementation DWTransactionStub DWTransactionStub *tx = [[DWTransactionStub alloc] initOnChain:dummyChain]; tx.txHash = RandomUInt256(); tx.timestamp = [NSDate timeIntervalSince1970] - 2 * 100000; - tx.dashAmount = DUFFS * 1.6180000000001; - tx.direction = DSTransactionDirection_Sent; + tx.stubDashAmount = DUFFS * 1.6180000000001; + tx.stubDirection = DSTransactionDirection_Sent; [stubs addObject:tx]; } @@ -68,8 +76,8 @@ @implementation DWTransactionStub DWTransactionStub *tx = [[DWTransactionStub alloc] initOnChain:dummyChain]; tx.txHash = RandomUInt256(); tx.timestamp = [NSDate timeIntervalSince1970] - 3 * 100000; - tx.dashAmount = DUFFS * 44.0480000000001; - tx.direction = DSTransactionDirection_Received; + tx.stubDashAmount = DUFFS * 44.0480000000001; + tx.stubDirection = DSTransactionDirection_Received; [stubs addObject:tx]; } diff --git a/DashWallet/Sources/UI/Tx/Reclassify Transactions/TxReclassifyTransactionsInfoViewController.swift b/DashWallet/Sources/UI/Tx/Reclassify Transactions/TxReclassifyTransactionsInfoViewController.swift index dab031055..337b6ab77 100644 --- a/DashWallet/Sources/UI/Tx/Reclassify Transactions/TxReclassifyTransactionsInfoViewController.swift +++ b/DashWallet/Sources/UI/Tx/Reclassify Transactions/TxReclassifyTransactionsInfoViewController.swift @@ -22,8 +22,8 @@ import UIKit @objc protocol TxReclassifyTransactionsInfoViewControllerDelegate: AnyObject { @objc - func txReclassifyTransactionsFlowDidClosedWithUnderstanding(controller: TxReclassifyTransactionsInfoViewController, - transaction: DSTransaction) + func txReclassifyTransactionsFlowDidClose(controller: TxReclassifyTransactionsInfoViewController, + transaction: DSTransaction) } // MARK: - TxReclassifyTransactionsInfoViewController @@ -61,7 +61,7 @@ class TxReclassifyTransactionsInfoViewController: BasePageSheetViewController { @IBAction func iUndersandAction() { dismiss(animated: true) { - self.delegate?.txReclassifyTransactionsFlowDidClosedWithUnderstanding(controller: self, transaction: self.transaction) + self.delegate?.txReclassifyTransactionsFlowDidClose(controller: self, transaction: self.transaction) } } diff --git a/DashWallet/Sources/Utils/TimeUtils.swift b/DashWallet/Sources/Utils/TimeUtils.swift index 96c8f3629..4d245f433 100644 --- a/DashWallet/Sources/Utils/TimeUtils.swift +++ b/DashWallet/Sources/Utils/TimeUtils.swift @@ -20,7 +20,7 @@ class TimeUtils { } connection.send(content: message, completion: .contentProcessed({ error in - if let error = error { + if error != nil { connection.cancel() continuation.resume(returning: nil) return @@ -29,7 +29,7 @@ class TimeUtils { connection.receive(minimumIncompleteLength: 48, maximumLength: 48) { content, _, _, error in defer { connection.cancel() } - if let error = error { + if error != nil { continuation.resume(returning: nil) return } @@ -60,7 +60,6 @@ class TimeUtils { // Check if we can use the cached skew if !force && (lastTimeWhenSkewChecked + 60_000 > currentTimeMillis) { - print("CoinJoin: timeskew: \(lastTimeSkew); using last value") return lastTimeSkew } @@ -104,7 +103,6 @@ class TimeUtils { } } - print("CoinJoin: timeskew: network time is \(String(describing: networkTime))") guard networkTime != nil else { throw NSError(domain: "TimeUtils", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to get network time"]) } diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index 8f46c56b9..1fb87d558 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "تأكد"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "ساعدنا على تحسين تجربتك"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "دعم"; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index a6a48c5fe..f3d0936fb 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Потвърди"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Помогнете ни да подобрим вашето преживяване"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index 11d52e78b..7b4e36e6f 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index e5d179208..48281308d 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Potvrdit"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Při aktualizaci profilu se stala chyba"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Chyba při aktualizaci"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d z %2$d"; -/* Hello username, */ -"Hello %@," = "Ahoj %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Pomozte nám aplikaci vylepšit"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgradovat na Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgraduji na DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index c8726c573..43d702b92 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/dashwallet-Bridging-Header.h b/DashWallet/dashwallet-Bridging-Header.h index c1c4ff8b6..60ab6052a 100644 --- a/DashWallet/dashwallet-Bridging-Header.h +++ b/DashWallet/dashwallet-Bridging-Header.h @@ -50,7 +50,6 @@ static const bool _SNAPSHOT = 0; #import "DSTransaction+DashWallet.h" #import "DWAlertController.h" #import "DWHomeProtocol.h" -#import "DWDPRegistrationErrorRetryDelegate.h" #import "UIDevice+DashWallet.h" #import "DWCenteredTableView.h" @@ -98,10 +97,6 @@ static const bool _SNAPSHOT = 0; #import "DWDPBasicUserItem.h" #import "DWDPAvatarView.h" #import "DWDPRegistrationStatus.h" -#import "DWDPRegistrationErrorTableViewCell.h" -#import "DWDPRegistrationDoneTableViewCell.h" -#import "DWDPRegistrationStatusTableViewCell.h" -#import "DWDPRegistrationErrorRetryDelegate.h" #import "DWDPUserObject.h" #import "DWModalUserProfileViewController.h" #import "DWInvitationActionsView.h" @@ -134,6 +129,7 @@ static const bool _SNAPSHOT = 0; #import "DWDPWelcomeCollectionViewController.h" #import "DWGetStarted.h" #import "DWGetStartedContentViewController.h" +#import "DWDashPayContactsUpdater.h" #endif //MARK: CrowdNode @@ -155,7 +151,6 @@ static const bool _SNAPSHOT = 0; //MARK: Home #import "DWHomeModel.h" #import "DWRecoverViewController.h" -#import "UIViewController+DWTxFilter.h" #import "DSAuthenticationManager.h" #import "DWSecureWalletDelegate.h" #import "DWSettingsMenuModel.h" @@ -178,3 +173,7 @@ static const bool _SNAPSHOT = 0; //MARK: CoinJoin #import "DSCoinJoinManager.h" + + +// TODO +#import "DSInstantSendTransactionLock.h" diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index a7d3703a7..379ae1854 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Bestätigen"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Fehler beim Updaten deines Profils"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Fehler beim Aktualisieren"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "Header #%1$d von %2$d"; -/* Hello username, */ -"Hello %@," = "Hallo %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Hilf uns, deine Erfahrung zu verbessern"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Zu Evolution upgraden"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Auf DashPay upgraden"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 534b41399..a3fced160 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Επιβεβαίωση"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Σφάλμα ενημέρωσης του προφίλ σας"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Σφάλμα Αναβάθμισης"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Γεια σας %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Βοηθήστε μας να βελτιώσουμε την εμπειρία σας"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Αναβάθμιση σε Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Αναβάθμιση σε DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index 7cca08a84..d2d2a18fe 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index 8700b8e88..0f83ff52a 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index 653ff4cdf..dcfd442d7 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirmar"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error al actualizar tu perfil"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error al actualizar"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "encabezado #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hola %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Ayúdanos a mejorar tu experiencia"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Actualizar a Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Actualizando a DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index e751a2726..3ac48c5c3 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Kinnita"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index f07d0dc67..8b8c1bf13 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "تائید"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "به ما برای بهبود تجربه‌تان کمک کنید"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "آپهولد"; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index ad4dc6bd5..5d274cc13 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index 681e8f0a6..9fdf52166 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Kumpirmahin"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error sa pag-update ng iyong profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Kamalian sa Pag-upgrade"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d ng %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Tulungan kaming mapabuti ang iyong karanasan"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Mag-upgrade sa Ebolusyon"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Pag-a-upgrade sa DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index f5290dcb0..0dcb6602c 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirmer"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Erreur en modifiant votre profil"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Erreur pendant la mise à jour"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "en-tête #%1$d sur %2$d"; -/* Hello username, */ -"Hello %@," = "Bonjour %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Aidez-nous à améliorer votre expérience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Mise à jour vers Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Mise à jour vers DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index a1602814e..1cc330def 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index 59408b2ce..6c67c90b2 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Megerősítés"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 82656fdb8..ad8a8b4d0 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Memastikan"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Terjadi kesalahan saat memperbarui profil Anda"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Kesalahan Mengupgrade"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d dari %2$d"; -/* Hello username, */ -"Hello %@," = "Halo %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Bantu kami meningkatkan pengalaman Anda"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Tingkatkan ke Evolusi"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Meningkatkan ke DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index bad6162c3..29141a904 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Conferma"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Errore durante l'aggiornamento del tuo profilo "; -/* No comment provided by engineer. */ -"Error Upgrading" = "Errore durante l'aggiornamento"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "intestazione #%1$d di %2$d"; -/* Hello username, */ -"Hello %@," = "Ciao %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Aiutaci a migliorare raccontaci tua esperienza"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Passa a Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Aggiornamento a DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index 67a7e5af7..1f2acec72 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "確認する"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "プロフィールの更新エラー"; -/* No comment provided by engineer. */ -"Error Upgrading" = "アップグレード中のエラー"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "%2$dのヘッダー#%1$d"; -/* Hello username, */ -"Hello %@," = "こんにちは、%@。"; - /* No comment provided by engineer. */ "Help us improve your experience" = "品質を向上させるためにご協力ください"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "進化版にアップグレードする"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "DashPayにアップグレード中"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index bbf816ef3..c05f04377 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "코인조인"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "승인"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "프로필 업데이트 오류"; -/* No comment provided by engineer. */ -"Error Upgrading" = "업그레이드 오류"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "헤더 %2$d 중 #%1$d"; -/* Hello username, */ -"Hello %@," = "%@님 안녕하세요,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "우리가 당신의 경험을 향상할 수 있도록 도와주세요"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "에볼루션으로 업그레이드 하기"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "대시페이로 업그레이드 중"; - /* No comment provided by engineer. */ "Uphold" = "업홀드"; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index 1afb23e5d..5a46896ea 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index c4efd4287..c771e7081 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Terima"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index 41ad52247..a45d3fa47 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index a6c3016cf..a6a4c2fbf 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Bevestig"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Fout bij bijwerken van je profiel"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Fout bij het upgraden"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "koptekst #%1$d van %2$d"; -/* Hello username, */ -"Hello %@," = "Hallo %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help ons je ervaring te verbeteren"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade naar Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgraden naar DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index 2bda9b1a7..831feaa7f 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Potwierdź"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Wystąpił błąd podczas aktualizacji twojego profilu"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Wystąpił błąd podczas ulepszania"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "nagłówek #%1$d z %2$d"; -/* Hello username, */ -"Hello %@," = "Witaj %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Pomóż nam poprawić Twoje wrażenia"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Przenieś sie na Ewolucję"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Ulepszenie do DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index 8495752b3..6679a756f 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirme"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Erro ao atualizar seu perfil"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Erro no Upgrade"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "cabeçalho #%1$d de %2$d"; -/* Hello username, */ -"Hello %@," = "Olá %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Ajude-nos a melhorar a sua experiência"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Atualize para a evolução"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrade para DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index 6a541118c..dd555390d 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirmă"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index 5acf014b8..a4f5e98ac 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Подтвердить"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Ошибка при обновлении профиля"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Ошибка при обновлении"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "заголовок блока #%1$d из %2$d"; -/* Hello username, */ -"Hello %@," = "Привет, %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Помогите нам стать лучше"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Обновиться до Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Обновление до DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 8d8976b41..368829ecd 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Potvrdiť"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Pri aktualizácii vášho profilu sa vyskytla chyba"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Chyba pri inovácii"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "hlavička číslo %1$d z %2$d"; -/* Hello username, */ -"Hello %@," = "Ahoj %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Pomôžte nám vylepšiť váš zážitok"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Inovujte na Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Inovuje sa na DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index d1baf34fa..190339486 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index 92615852b..34d2510e9 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index 4441b3905..ce9ad666a 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Confirm"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 56a41f73c..e470304fa 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Potvrdi"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index 4c0097dd2..15086b52f 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Bekräfta"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index 2091d6eb4..24dd321cd 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "ยืนยัน"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "ข้อผิดพลาดในการอัปเดตโปรไฟล์ของคุณ"; -/* No comment provided by engineer. */ -"Error Upgrading" = "อัพเกรดข้อผิดพลาด"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "หัวข้อ #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "สวัสดี %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "ช่วยเราเพื่อพัฒนาประสบการณ์ของคุณ"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "อัพเกรดเป็นวิวัฒนาการ"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "อัพเกรดเป็น DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index e1c0e8910..9b0c4b407 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Onayla"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Profiliniz güncellenirken hata oluştu"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Yükseltme Hatası"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "başlık #%1$d / %2$d"; -/* Hello username, */ -"Hello %@," = "Merhaba %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Deneyiminizi geliştirmemize yardımcı olun"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Evolution'a Yükselt"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "DashPay'e yükseltiliyor"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index 5b0fa4c38..41f6b6211 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Підтверджую"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Помилка оновлення профіля"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Помилка оновлення"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "заголовок #%1$d з %2$d"; -/* Hello username, */ -"Hello %@," = "Привіт, %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Допоможіть нам стати кращими"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Оновлення до Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Оновлення до DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index 847361260..ee45f1b50 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "Xác thực"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Lỗi nâng cấp"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "phần đầu # %1$d của %2$d"; -/* Hello username, */ -"Hello %@," = "Chào %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Hãy giúp chúng tôi cải thiện trải nghiệm cho bạn"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Đang nâng cấp cho DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index 72c2912a7..311b412cf 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* No comment provided by engineer. */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "确认"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index 8321b39ef..541ddfbb4 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* No comment provided by engineer. */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "確認:"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "Error updating your profile"; -/* No comment provided by engineer. */ -"Error Upgrading" = "Error Upgrading"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "header #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "Hello %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "Help us improve your experience"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "Upgrade to Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "Upgrading to DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index e8e899a23..33b8b7ad4 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "确认"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "更新您个人资料时出错"; -/* No comment provided by engineer. */ -"Error Upgrading" = "错误升级"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "头部 %2$d分之#%1$d"; -/* Hello username, */ -"Hello %@," = "您好 %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "帮助我们改善您的体验"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "升级到Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "正在升级到DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold"; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index da1f3a467..4d4e634fd 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -440,6 +440,9 @@ /* CoinJoin */ "CoinJoin" = "CoinJoin"; +/* CoinJoin */ +"CoinJoin Mixing" = "CoinJoin Mixing"; + /* No comment provided by engineer. */ "Confirm" = "確認:"; @@ -784,9 +787,6 @@ /* No comment provided by engineer. */ "Error updating your profile" = "更新您的個人資料時出錯"; -/* No comment provided by engineer. */ -"Error Upgrading" = "錯誤升級"; - /* CoinJoin */ "Error ·" = "Error ·"; @@ -976,9 +976,6 @@ /* No comment provided by engineer. */ "header #%d of %d" = "標頭 #%1$d of %2$d"; -/* Hello username, */ -"Hello %@," = "您好 %@,"; - /* No comment provided by engineer. */ "Help us improve your experience" = "幫助我們改善您的體驗"; @@ -2438,9 +2435,6 @@ /* No comment provided by engineer. */ "Upgrade to Evolution" = "升級到 Evolution"; -/* No comment provided by engineer. */ -"Upgrading to DashPay" = "升級到 DashPay"; - /* No comment provided by engineer. */ "Uphold" = "Uphold";