diff --git a/.tx/config b/.tx/config index dbdf8e57c..386915217 100644 --- a/.tx/config +++ b/.tx/config @@ -1,37 +1,38 @@ [main] host = https://www.transifex.com -[dash-mobile-wallets.app-localizable-strings] -file_filter = DashWallet/.lproj/Localizable.strings +[o:dash:p:dash-mobile-wallets:r:app-localizable-strings] +file_filter = DashWallet/.lproj/Localizable.strings +source_file = DashWallet/en.lproj/Localizable.strings +source_lang = en +type = STRINGS minimum_perc = 0 -source_file = DashWallet/en.lproj/Localizable.strings -source_lang = en -type = STRINGS -[dash-mobile-wallets.app-localizable-strings-dict] -file_filter = DashWallet/.lproj/Localizable.stringsdict +[o:dash:p:dash-mobile-wallets:r:app-localizable-strings-dict] +file_filter = DashWallet/.lproj/Localizable.stringsdict +source_file = DashWallet/en.lproj/Localizable.stringsdict +source_lang = en +type = STRINGSDICT minimum_perc = 0 -source_file = DashWallet/en.lproj/Localizable.stringsdict -source_lang = en -type = STRINGSDICT -[dash-mobile-wallets.watch-interface-strings] -file_filter = WatchApp/.lproj/Interface.strings +[o:dash:p:dash-mobile-wallets:r:appstore-description] +file_filter = fastlane/metadata//description.txt +source_file = fastlane/metadata/en-US/description.txt +source_lang = en +type = TXT minimum_perc = 0 -source_file = WatchApp/en.lproj/Interface.strings -source_lang = en -type = STRINGS -[dash-mobile-wallets.appstore-description] -file_filter = fastlane/metadata//description.txt +[o:dash:p:dash-mobile-wallets:r:appstore-release_notes] +file_filter = fastlane/metadata//release_notes.txt +source_file = fastlane/metadata/en-US/release_notes.txt +source_lang = en +type = TXT minimum_perc = 0 -source_file = fastlane/metadata/en-US/description.txt -source_lang = en -type = TXT -[dash-mobile-wallets.appstore-release_notes] -file_filter = fastlane/metadata//release_notes.txt +[o:dash:p:dash-mobile-wallets:r:watch-interface-strings] +file_filter = WatchApp/.lproj/Interface.strings +source_file = WatchApp/en.lproj/Interface.strings +source_lang = en +type = STRINGS minimum_perc = 0 -source_file = fastlane/metadata/en-US/release_notes.txt -source_lang = en -type = TXT + diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index fc121c645..72ad29fe5 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -512,7 +512,9 @@ 478C983C2945801D00FAA0F0 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478C983B2945801D00FAA0F0 /* Constants.swift */; }; 47976E4A2987772700612988 /* AmountObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47976E492987772700612988 /* AmountObjectTests.swift */; }; 47976E4B2987781A00612988 /* DWAmountInputValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2120E92214566A009906DC /* DWAmountInputValidator.m */; }; + 479DBDDD2995168C00F30AF1 /* Transactions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479DBDDC2995168C00F30AF1 /* Transactions.swift */; }; 479E7924287C00EC00D0F7D7 /* DatabaseConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 479E7923287C00EC00D0F7D7 /* DatabaseConnection.swift */; }; + 47A184E5299CC19A0017E32C /* rates.json in Resources */ = {isa = PBXBuildFile; fileRef = 47A184E4299CC19A0017E32C /* rates.json */; }; 47A2A2E2293DCCEA00938DB7 /* Coinbase+Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A2A2E1293DCCEA00938DB7 /* Coinbase+Constants.swift */; }; 47A2A2E9293E612900938DB7 /* CBAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A2A2E8293E612900938DB7 /* CBAuth.swift */; }; 47A2A2EC293E618600938DB7 /* CBUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47A2A2EB293E618600938DB7 /* CBUser.swift */; }; @@ -573,7 +575,6 @@ 47B30D7C29100ABA0080C326 /* UIStackView+DashWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47B30D7B29100ABA0080C326 /* UIStackView+DashWallet.swift */; }; 47B30D7E29102F6E0080C326 /* SendAmountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47B30D7D29102F6E0080C326 /* SendAmountModel.swift */; }; 47B30D80291123D30080C326 /* SendAmountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47B30D7F291123D30080C326 /* SendAmountViewController.swift */; }; - 47B30D822911259D0080C326 /* UIViewController+Payments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47B30D812911259D0080C326 /* UIViewController+Payments.swift */; }; 47C661AB28F9707A00028A8D /* NumberKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C661AA28F9707A00028A8D /* NumberKeyboard.swift */; }; 47C661AD28F972BD00028A8D /* NumberKeyboardButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C661AC28F972BD00028A8D /* NumberKeyboardButton.swift */; }; 47C661AF28FDAA3400028A8D /* BaseAmountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C661AE28FDAA3300028A8D /* BaseAmountViewController.swift */; }; @@ -1670,7 +1671,9 @@ 478C98362943A60000FAA0F0 /* PaymentMethodCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentMethodCell.swift; sourceTree = ""; }; 478C983B2945801D00FAA0F0 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 47976E492987772700612988 /* AmountObjectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmountObjectTests.swift; sourceTree = ""; }; + 479DBDDC2995168C00F30AF1 /* Transactions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transactions.swift; sourceTree = ""; }; 479E7923287C00EC00D0F7D7 /* DatabaseConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseConnection.swift; sourceTree = ""; }; + 47A184E4299CC19A0017E32C /* rates.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = rates.json; sourceTree = ""; }; 47A2A2E1293DCCEA00938DB7 /* Coinbase+Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Coinbase+Constants.swift"; sourceTree = ""; }; 47A2A2E8293E612900938DB7 /* CBAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBAuth.swift; sourceTree = ""; }; 47A2A2EB293E618600938DB7 /* CBUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBUser.swift; sourceTree = ""; }; @@ -2596,6 +2599,7 @@ 2A44313D22CF632F009BAF7F /* Models */ = { isa = PBXGroup; children = ( + 479DBDDB2995167800F30AF1 /* Tx */, 0F6EDF9328C894B9000427E7 /* Coinbase */, 47AE8B9328BF873800490F5E /* Explore Dash */, 471A2602289ACCD20056B7B2 /* Taxes */, @@ -4632,6 +4636,14 @@ path = Views; sourceTree = ""; }; + 479DBDDB2995167800F30AF1 /* Tx */ = { + isa = PBXGroup; + children = ( + 479DBDDC2995168C00F30AF1 /* Transactions.swift */, + ); + path = Tx; + sourceTree = ""; + }; 479E7922287C00A000D0F7D7 /* Infrastructure */ = { isa = PBXGroup; children = ( @@ -5237,6 +5249,7 @@ 75D5F3EC191EC270004AB296 /* DashWalletTests */ = { isa = PBXGroup; children = ( + 47A184E4299CC19A0017E32C /* rates.json */, 75CE50B51B5216F100DBC18C /* Info.plist */, 471DD1BE290AE9F000E030C8 /* DashWalletTests-Bridging-Header.h */, 2A2120EB22145CAE009906DC /* DWAmountInputValidatorTests.m */, @@ -5678,6 +5691,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 47A184E5299CC19A0017E32C /* rates.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6038,6 +6052,7 @@ 2A913E8923A30DA8006A2A59 /* DWBalanceDisplayOptionsStub.m in Sources */, 2A0C69CD23142F90001B8C90 /* DWModalPresentationAnimation.m in Sources */, 2A8B9E7A2302E67400FF8653 /* DWReceiveModel.m in Sources */, + 479DBDDD2995168C00F30AF1 /* Transactions.swift in Sources */, 2A74EFFB2305464C00C475EB /* DWRecoverTextView.m in Sources */, 4709C315287EA11900B4BD48 /* TxUserInfo.swift in Sources */, 2A7AF3182480E35A001D74F9 /* DWContactsFetchedDataSource.m in Sources */, @@ -6465,7 +6480,6 @@ 2A7A7BBE2347950700451078 /* DWMainMenuTableViewCell.m in Sources */, 2AB2373824488DB80081B62C /* DWUserSearchViewController.m in Sources */, 478483E829629C0700E05A5A /* CBAuthInterop.swift in Sources */, - 47B30D822911259D0080C326 /* UIViewController+Payments.swift in Sources */, 2A7AF38F2482BDF1001D74F9 /* UIFont+DWDPItem.m in Sources */, 4789D27029825F5400BAFEFA /* CoinbaseAmountViewController.swift in Sources */, 2A9FFE8E2230FF4700956D5F /* DWUpholdAuthViewController.m in Sources */, @@ -6946,7 +6960,7 @@ CLIENT_ID = 0c38beb67db0c68191326be347d7ec0abd7d77adb02a79db1abeba343f16a0f7; CLIENT_SECRET = cc980185754f905e24250f877792817c03540b3d0e0959721df291c816797e59; CODE_SIGN_ENTITLEMENTS = dashwallet/dashwallet.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; @@ -6972,7 +6986,7 @@ INFOPLIST_KEY_CFBundleDisplayName = Dash; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; @@ -6995,7 +7009,7 @@ CLIENT_ID = 0c38beb67db0c68191326be347d7ec0abd7d77adb02a79db1abeba343f16a0f7; CLIENT_SECRET = cc980185754f905e24250f877792817c03540b3d0e0959721df291c816797e59; CODE_SIGN_ENTITLEMENTS = dashwallet/dashwallet.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -7030,7 +7044,7 @@ INFOPLIST_KEY_CFBundleDisplayName = Dash; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "DashWallet/dashwallet-Bridging-Header.h"; @@ -7110,19 +7124,19 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Debug; }; @@ -7132,19 +7146,19 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Release; }; @@ -7152,13 +7166,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = C98AA93FF5283EC6405BCE4B /* Pods-WatchApp Extension.debug.xcconfig */; buildSettings = { - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; ENABLE_BITCODE = YES; EXCLUDED_ARCHS = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -7167,7 +7181,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Debug; }; @@ -7175,13 +7189,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = CE02413EF0C60B1D1EDE6457 /* Pods-WatchApp Extension.release.xcconfig */; buildSettings = { - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; ENABLE_BITCODE = YES; EXCLUDED_ARCHS = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -7190,7 +7204,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Release; }; @@ -7199,7 +7213,7 @@ baseConfigurationReference = 206554BC730E9F2BB594D044 /* Pods-TodayExtension.debug.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = dashwallet/dashwalletTodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; @@ -7209,7 +7223,7 @@ INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -7224,7 +7238,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = dashwallet/dashwalletTodayExtension.entitlements; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; @@ -7234,7 +7248,7 @@ INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -7316,7 +7330,7 @@ CLIENT_ID = 0c38beb67db0c68191326be347d7ec0abd7d77adb02a79db1abeba343f16a0f7; CLIENT_SECRET = cc980185754f905e24250f877792817c03540b3d0e0959721df291c816797e59; CODE_SIGN_ENTITLEMENTS = dashwallet/dashwallet.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -7351,7 +7365,7 @@ INFOPLIST_KEY_CFBundleDisplayName = Dash; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "DashWallet/dashwallet-Bridging-Header.h"; @@ -7369,7 +7383,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = dashwallet/dashwalletTodayExtension.entitlements; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; @@ -7379,7 +7393,7 @@ INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -7426,19 +7440,19 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Testflight; }; @@ -7446,13 +7460,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 556B5EBEBAEA571D74FF69A3 /* Pods-WatchApp Extension.testflight.xcconfig */; buildSettings = { - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; ENABLE_BITCODE = YES; EXCLUDED_ARCHS = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -7461,7 +7475,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Testflight; }; @@ -7543,7 +7557,7 @@ CLIENT_ID = 0c38beb67db0c68191326be347d7ec0abd7d77adb02a79db1abeba343f16a0f7; CLIENT_SECRET = cc980185754f905e24250f877792817c03540b3d0e0959721df291c816797e59; CODE_SIGN_ENTITLEMENTS = dashwallet/dashwallet.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -7568,7 +7582,7 @@ INFOPLIST_KEY_CFBundleDisplayName = Dash; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "DashWallet/dashwallet-Bridging-Header.h"; @@ -7585,7 +7599,7 @@ baseConfigurationReference = 8A9877BEC5093CED81768D3D /* Pods-TodayExtension.testnet.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = dashwallet/dashwalletTodayExtension.entitlements; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; @@ -7595,7 +7609,7 @@ INFOPLIST_FILE = TodayExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.TodayExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -7641,19 +7655,19 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Testnet; }; @@ -7661,13 +7675,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 29B232FD70BA2EDF87F86A56 /* Pods-WatchApp Extension.testnet.xcconfig */; buildSettings = { - CURRENT_PROJECT_VERSION = 49; + CURRENT_PROJECT_VERSION = 6; DEVELOPMENT_TEAM = 44RJ69WHFF; ENABLE_BITCODE = YES; EXCLUDED_ARCHS = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 6.2.0; + MARKETING_VERSION = 6.2.1; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -7676,7 +7690,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; - WATCHOS_DEPLOYMENT_TARGET = 3.0; + WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Testnet; }; diff --git a/DashWallet/Sources/Application/Tools.swift b/DashWallet/Sources/Application/Tools.swift index 5575a9eb5..d26a222e5 100644 --- a/DashWallet/Sources/Application/Tools.swift +++ b/DashWallet/Sources/Application/Tools.swift @@ -17,6 +17,8 @@ import Foundation +private var _cachedFormatters: [String: NumberFormatter] = [:] + private var _decimalFormatter: NumberFormatter! private var _fiatFormatter: NumberFormatter! private var _dashFormatter: NumberFormatter = { @@ -93,6 +95,10 @@ extension NumberFormatter { } static func cryptoFormatter(currencyCode: String, exponent: Int) -> NumberFormatter { + if let formatter = _cachedFormatters[currencyCode] { + return formatter + } + let formatter = NumberFormatter() formatter.isLenient = true formatter.numberStyle = .currency @@ -109,16 +115,23 @@ extension NumberFormatter { formatter.maximumFractionDigits = exponent formatter.minimumFractionDigits = 0 + _cachedFormatters[currencyCode] = formatter return formatter } static func fiatFormatter(currencyCode: String) -> NumberFormatter { + if let formatter = _cachedFormatters[currencyCode] { + return formatter + } + let formatter = NumberFormatter() formatter.isLenient = true formatter.numberStyle = .currency formatter.generatesDecimalNumbers = true formatter.currencyCode = currencyCode + _cachedFormatters[currencyCode] = formatter + return formatter } } diff --git a/DashWallet/Sources/Categories/DSTransaction+DashWallet.h b/DashWallet/Sources/Categories/DSTransaction+DashWallet.h index 0c15ad0fc..a086f020b 100644 --- a/DashWallet/Sources/Categories/DSTransaction+DashWallet.h +++ b/DashWallet/Sources/Categories/DSTransaction+DashWallet.h @@ -24,6 +24,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) NSData *txHashData; @property (readonly) NSString *txHashHexString; +@property (readonly) NSDate *date; + (uint64_t)txMinOutputAmount; diff --git a/DashWallet/Sources/Categories/DSTransaction+DashWallet.m b/DashWallet/Sources/Categories/DSTransaction+DashWallet.m index b746b3b7a..5a4262b91 100644 --- a/DashWallet/Sources/Categories/DSTransaction+DashWallet.m +++ b/DashWallet/Sources/Categories/DSTransaction+DashWallet.m @@ -20,6 +20,15 @@ @implementation DSTransaction (DashWallet) +- (NSDate *)date { + DSChain *chain = self.chain; + NSTimeInterval now = [chain timestampForBlockHeight:TX_UNCONFIRMED]; + NSTimeInterval txTime = (self.timestamp > 1) ? self.timestamp : now; + NSDate *txDate = [NSDate dateWithTimeIntervalSince1970:txTime]; + + return txDate; +} + - (NSData *)txHashData { return [NSData dataWithBytes:self.txHash.u8 length:sizeof(UInt256)]; } diff --git a/DashWallet/Sources/Categories/Numbers+Dash.swift b/DashWallet/Sources/Categories/Numbers+Dash.swift index 720c225a1..d3f807cde 100644 --- a/DashWallet/Sources/Categories/Numbers+Dash.swift +++ b/DashWallet/Sources/Categories/Numbers+Dash.swift @@ -62,6 +62,10 @@ extension Decimal { rounded(sign == .minus ? .up : .down) } + var fractionDigits: Int { + max(-exponent, 0) + } + /// Converts `Decimal` to plain dash amount in duffs /// /// - Returns: Plain dash amount in duffs diff --git a/DashWallet/Sources/Categories/String+DashWallet.swift b/DashWallet/Sources/Categories/String+DashWallet.swift index 10f902f33..20cb84ebb 100644 --- a/DashWallet/Sources/Categories/String+DashWallet.swift +++ b/DashWallet/Sources/Categories/String+DashWallet.swift @@ -116,7 +116,6 @@ extension String { } let isCurrencySymbolAtTheBeginning = currencySymbolRange.lowerBound == format.startIndex - let isCurrencySymbolAtTheEnd = currencySymbolRange.upperBound == format.endIndex // special case to deal with RTL languages if format.hasPrefix("\u{0000200e}") || format.hasPrefix("\u{0000200f}") { diff --git a/DashWallet/Sources/Categories/UIViewController+Payments.swift b/DashWallet/Sources/Categories/UIViewController+Payments.swift deleted file mode 100644 index b3702ab7c..000000000 --- a/DashWallet/Sources/Categories/UIViewController+Payments.swift +++ /dev/null @@ -1,181 +0,0 @@ -// -// Created by tkhp -// 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. -// - -import UIKit - -// MARK: - AssociatedKeys - -private enum AssociatedKeys { - static var paymentProcessor: UInt8 = 0 - static var confirmViewController: UInt8 = 1 -} - -// MARK: - PaymentViewController - -protocol PaymentViewController: DWPaymentProcessorDelegate, - DWConfirmPaymentViewControllerDelegate where Self: UIViewController { } - -extension PaymentViewController { - fileprivate var paymentProcessor: DWPaymentProcessor { - get { - if let processor = objc_getAssociatedObject(self, &AssociatedKeys.paymentProcessor) as? DWPaymentProcessor { - return processor - } else { - let processor = DWPaymentProcessor(delegate: self) - self.paymentProcessor = processor - return processor - } - } - set { - objc_setAssociatedObject(self, - &AssociatedKeys.paymentProcessor, - newValue, - objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } - - fileprivate var confirmViewController: DWConfirmSendPaymentViewController? { - get { - if let vc = objc_getAssociatedObject(self, - &AssociatedKeys.confirmViewController) as? DWConfirmSendPaymentViewController { - return vc - } else { - return nil - } - } - set { - objc_setAssociatedObject(self, - &AssociatedKeys.confirmViewController, - newValue, - objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } - - private func showAlert(with title: String?, message: String?) { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - let okAction = UIAlertAction(title: NSLocalizedString("OK", comment: ""), style: .cancel) - alert.addAction(okAction) - show(modalController: alert) - } - - private func show(modalController: UIViewController) { - let presentingViewController = confirmViewController ?? presentingViewController - presentingViewController?.present(modalController, animated: true) - } -} - -// MARK: DWConfirmPaymentViewControllerDelegate -extension PaymentViewController { - func confirmPaymentViewControllerDidConfirm(_ controller: DWConfirmPaymentViewController) { - if let vc = controller as? DWConfirmSendPaymentViewController, let output = vc.paymentOutput { - paymentProcessor.confirmPaymentOutput(output) - } - } -} - -// MARK: DWPaymentProcessorDelegate -extension PaymentViewController { - func paymentProcessor(_ processor: DWPaymentProcessor, requestAmountWithDestination sendingDestination: String, - details: DSPaymentProtocolDetails?, contactItem: DWDPBasicUserItem) { - fatalError("Must be implemented") - } - - func paymentProcessor(_ processor: DWPaymentProcessor, requestUserActionTitle title: String?, message: String?, - actionTitle: String, cancel cancelBlock: (() -> Void)?, actionBlock: (() -> Void)? = nil) { - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - - let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel) { _ in - cancelBlock?() - -// assert(!self.confirmViewController || self.confirmViewController.sendingEnabled, "paymentProcessorDidCancelTransactionSigning: should be called") - } - - alert.addAction(cancelAction) - - let actionAction = UIAlertAction(title: actionTitle, style: .cancel) { _ in - actionBlock?() - - self.confirmViewController?.sendingEnabled = true - } - - alert.addAction(actionAction) - show(modalController: alert) - } - - func paymentProcessor(_ processor: DWPaymentProcessor, confirmPaymentOutput paymentOutput: DWPaymentOutput) { - if let vc = confirmViewController { - vc.paymentOutput = paymentOutput - } else { - let vc = DWConfirmSendPaymentViewController() - vc.paymentOutput = paymentOutput - vc.delegate = self - - // TODO: demo mode - - present(vc, animated: true) - confirmViewController = vc - } - } - - func paymentProcessorDidCancelTransactionSigning(_ processor: DWPaymentProcessor) { - confirmViewController?.sendingEnabled = true - } - - func paymentProcessor(_ processor: DWPaymentProcessor, didFailWithError error: Error?, title: String?, message: String?) { - guard let error = error as? NSError else { - return - } - - if error.domain == DSErrorDomain && - (error.code == DSErrorInsufficientFunds || error.code == DSErrorInsufficientFundsForNetworkFee) { - // show insufficient amount - } - - presentingViewController?.view.dw_hideProgressHUD() - showAlert(with: title, message: message) - - confirmViewController?.sendingEnabled = true - } - - func paymentProcessor(_ processor: DWPaymentProcessor, didSend protocolRequest: DSPaymentProtocolRequest, - transaction: DSTransaction, contactItem: DWDPBasicUserItem?) { - presentingViewController?.view.dw_hideProgressHUD() - - if let vc = confirmViewController { - dismiss(animated: true) - } else { } - - let vc = SuccessTxDetailViewController() - vc.modalPresentationStyle = .fullScreen - vc.model = TxDetailModel(transaction: transaction, dataProvider: DWTransactionListDataProvider()) - vc.contactItem = contactItem - // vc.delegate = self - present(vc, animated: true) - } - - func paymentProcessorDidFinishProcessingFile(_ processor: DWPaymentProcessor) { } - - func paymentInputProcessorHideProgressHUD(_ processor: DWPaymentProcessor) { - presentingViewController?.view.dw_hideProgressHUD() - } - - func paymentProcessor(_ processor: DWPaymentProcessor, showProgressHUDWithMessage message: String?) { - presentingViewController?.view.dw_showProgressHUD(withMessage: message) - } -} - - diff --git a/DashWallet/Sources/Infrastructure/Currency Exchanger/CurrencyExchanger.swift b/DashWallet/Sources/Infrastructure/Currency Exchanger/CurrencyExchanger.swift index 1c16a9d17..894c530bf 100644 --- a/DashWallet/Sources/Infrastructure/Currency Exchanger/CurrencyExchanger.swift +++ b/DashWallet/Sources/Infrastructure/Currency Exchanger/CurrencyExchanger.swift @@ -67,6 +67,12 @@ public final class CurrencyExchanger { if amount.isZero { return 0 } let rate = try rate(for: currency) + return try convertDash(amount: amount, to: currency, rate: rate) + } + + public func convertDash(amount: Decimal, to currency: String, rate: Decimal) throws -> Decimal { + if amount.isZero { return 0 } + let result = rate*amount let formatter = NumberFormatter.fiatFormatter(currencyCode: currency) @@ -83,6 +89,12 @@ public final class CurrencyExchanger { if amount.isZero { return 0 } let rate = try rate(for: currency) + return try convertToDash(amount: amount, currency: currency, rate: rate) + } + + public func convertToDash(amount: Decimal, currency: String, rate: Decimal) throws -> Decimal { + if amount.isZero { return 0 } + return amount/rate } @@ -90,8 +102,7 @@ public final class CurrencyExchanger { if amount.isZero { return 0 } if amountCurrency == kDashCurrency { - let rate = try rate(for: currency) - return amount/rate + return try convertToDash(amount: amount, currency: currency) } let dashAmount = try convertToDash(amount: amount, currency: amountCurrency) @@ -99,6 +110,7 @@ public final class CurrencyExchanger { return result } + static let shared = CurrencyExchanger(dataProvider: RatesProviderFactory.base) } diff --git a/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230208142504_update_tx_userinfo_table.sql b/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230208142504_update_tx_userinfo_table.sql new file mode 100644 index 000000000..e73563228 --- /dev/null +++ b/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230208142504_update_tx_userinfo_table.sql @@ -0,0 +1,3 @@ +CREATE TABLE backup_tx_userinfo AS SELECT * FROM tx_userinfo; +ALTER TABLE tx_userinfo ADD rate INT NULL; +ALTER TABLE tx_userinfo ADD rateCurrencyCode VARCHAR(3) NULL; diff --git a/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230212103028_add_rate_fraction_digits_into_userinfo_table.sql b/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230212103028_add_rate_fraction_digits_into_userinfo_table.sql new file mode 100644 index 000000000..b3a80bcaf --- /dev/null +++ b/DashWallet/Sources/Infrastructure/Database/Migrations.bundle/20230212103028_add_rate_fraction_digits_into_userinfo_table.sql @@ -0,0 +1 @@ +ALTER TABLE tx_userinfo ADD rateMaximumFractionDigits INT NULL; diff --git a/DashWallet/Sources/Models/Coinbase/Coinbase.swift b/DashWallet/Sources/Models/Coinbase/Coinbase.swift index a6690dd6d..29b67dc45 100644 --- a/DashWallet/Sources/Models/Coinbase/Coinbase.swift +++ b/DashWallet/Sources/Models/Coinbase/Coinbase.swift @@ -61,10 +61,13 @@ class Coinbase { paymentMethodsService = PaymentMethods(authInterop: auth) currencyExchanger.startExchangeRateFetching() - // Pre-fetch data + prefetchData() + } + + private func prefetchData() { Task { try await accountService.refreshAccount(kDashAccount) - try await paymentMethodsService.fetchPaymentMethods() + _ = try await paymentMethodsService.fetchPaymentMethods() } } diff --git a/DashWallet/Sources/Models/DWGlobalOptions.h b/DashWallet/Sources/Models/DWGlobalOptions.h index f012de460..4ffc11e46 100644 --- a/DashWallet/Sources/Models/DWGlobalOptions.h +++ b/DashWallet/Sources/Models/DWGlobalOptions.h @@ -49,6 +49,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) BOOL shouldDisplayOnboarding; @property (nonatomic, assign) BOOL shouldDisplayReclassifyYourTransactionsFlow; @property (nullable, nonatomic, strong) NSDate *dateReclassifyYourTransactionsFlowActivated; +@property (nullable, nonatomic, strong) NSDate *dateHistoricalRatesActivated; @property (nonatomic, assign) NSInteger paymentsScreenCurrentTab; @property (nullable, nonatomic, copy) NSString *dashpayUsername; @@ -71,6 +72,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setSpendingConfirmationDisabled:(BOOL)spendingConfirmationDisabled; - (void)setActivationDateForReclassifyYourTransactionsFlowIfNeeded:(NSDate *)date; +- (void)setActivationDateForHistoricalRates:(NSDate *)date; + // Methods - (void)restoreToDefaults; diff --git a/DashWallet/Sources/Models/DWGlobalOptions.m b/DashWallet/Sources/Models/DWGlobalOptions.m index b4a251004..5ca10cec5 100644 --- a/DashWallet/Sources/Models/DWGlobalOptions.m +++ b/DashWallet/Sources/Models/DWGlobalOptions.m @@ -44,6 +44,7 @@ @implementation DWGlobalOptions @dynamic selectedPaymentCurrency; @dynamic shouldDisplayReclassifyYourTransactionsFlow; @dynamic dateReclassifyYourTransactionsFlowActivated; +@dynamic dateHistoricalRatesActivated; @dynamic exploreDashMerchantsInfoShown; @dynamic coinbaseInfoShown; @@ -120,6 +121,12 @@ - (void)setActivationDateForReclassifyYourTransactionsFlowIfNeeded:(NSDate *)dat } } +- (void)setActivationDateForHistoricalRates:(NSDate *)date { + if (self.dateHistoricalRatesActivated == nil) { + self.dateHistoricalRatesActivated = date; + } +} + #pragma mark - Methods - (void)restoreToDefaults { @@ -137,6 +144,7 @@ - (void)restoreToDefaults { self.selectedPaymentCurrency = DWPaymentCurrencyDash; self.shouldDisplayReclassifyYourTransactionsFlow = YES; self.dateReclassifyYourTransactionsFlowActivated = nil; + self.dateHistoricalRatesActivated = nil; self.exploreDashMerchantsInfoShown = NO; self.coinbaseInfoShown = NO; } diff --git a/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/AtmDAO.swift b/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/AtmDAO.swift index 9363a13e7..988cc6782 100644 --- a/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/AtmDAO.swift +++ b/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/AtmDAO.swift @@ -43,7 +43,6 @@ class AtmDAO: PointOfUseDAO { let latitude = Expression("latitude") let longitude = Expression("longitude") let manufacturer = Expression("manufacturer") - let source = ExplorePointOfUse.source let offset = offset ?? 0 var queryFilter = Expression(value: true) diff --git a/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/MerchantDAO.swift b/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/MerchantDAO.swift index b9e25a224..4a95391ab 100644 --- a/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/MerchantDAO.swift +++ b/DashWallet/Sources/Models/Explore Dash/Infrastructure/DAO Impl/MerchantDAO.swift @@ -178,7 +178,6 @@ extension MerchantDAO { let merchantTable = Table("merchant") let merchantIdColumn = ExplorePointOfUse.merchantId - let name = ExplorePointOfUse.name var queryFilter = Expression(value: true) @@ -186,7 +185,7 @@ extension MerchantDAO { if let bounds { - var boundsFilter = Expression(literal: "latitude > \(bounds.swCoordinate.latitude)") && + let boundsFilter = Expression(literal: "latitude > \(bounds.swCoordinate.latitude)") && Expression(literal: "latitude < \(bounds.neCoordinate.latitude)") && Expression(literal: "longitude > \(bounds.swCoordinate.longitude)") && Expression(literal: "longitude < \(bounds.neCoordinate.longitude)") diff --git a/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift b/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift index 186000808..908ce8d3c 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/Entites/ExplorePointOfUse.swift @@ -187,7 +187,10 @@ extension ExplorePointOfUse: RowDecodable { let address4 = row[ExplorePointOfUse.address4] let latitude = row[ExplorePointOfUse.latitude] let longitude = row[ExplorePointOfUse.longitude] - let website = row[ExplorePointOfUse.website] + var website = row[ExplorePointOfUse.website] + if !website.hasPrefix("http") { + website = "https://" + website + } let phone: String? = row[ExplorePointOfUse.phone]?.digits let logoLocation = row[ExplorePointOfUse.logoLocation] let coverImage: String? = row[ExplorePointOfUse.coverImage] diff --git a/DashWallet/Sources/Models/Explore Dash/Services/DWLocationManager.swift b/DashWallet/Sources/Models/Explore Dash/Services/DWLocationManager.swift index 071e40434..0a82b3986 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/DWLocationManager.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/DWLocationManager.swift @@ -117,7 +117,7 @@ class DWLocationManager: NSObject { let loc = [placemark.country, placemark.administrativeArea, placemark.locality].compactMap { $0 } .joined(separator: ", ") completion(loc) - } else if let error { + } else if error != nil { completion("Location couldn't determined") } } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift b/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift index 18d223ab5..9e9f24d49 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift @@ -28,7 +28,7 @@ private let timestampKey = "Data-Timestamp" private let checksumKey = "Data-Checksum" // TODO: Move it to plist and note in release process -let bundleExploreDatabaseSyncTime: TimeInterval = 1675272692196/1000 +let bundleExploreDatabaseSyncTime: TimeInterval = 1676050324994/1000 // MARK: - ExploreDatabaseSyncManager diff --git a/DashWallet/Sources/Models/Taxes/Address/DAO/AddressUserInfoDAO.swift b/DashWallet/Sources/Models/Taxes/Address/DAO/AddressUserInfoDAO.swift index 702bb4dff..2426c799b 100644 --- a/DashWallet/Sources/Models/Taxes/Address/DAO/AddressUserInfoDAO.swift +++ b/DashWallet/Sources/Models/Taxes/Address/DAO/AddressUserInfoDAO.swift @@ -26,6 +26,7 @@ protocol AddressUserInfoDAO { func get(by address: String) -> AddressUserInfo? func update(dto: AddressUserInfo) func delete(dto: AddressUserInfo) + func deleteAll() } // MARK: - AddressUserInfoDAOImpl @@ -99,13 +100,23 @@ class AddressUserInfoDAOImpl: NSObject, AddressUserInfoDAO { cache[dto.address] = nil } + @objc + func deleteAll() { + do { + try db.run(AddressUserInfo.table.delete()) + cache = [:] + } catch { + print(error) + } + } + @objc static let shared = AddressUserInfoDAOImpl() } extension AddressUserInfoDAOImpl { @objc func dictionaryOfAllItems() -> [String: AddressUserInfo] { - all() + _ = all() return cache } } diff --git a/DashWallet/Sources/Models/Taxes/Taxes.swift b/DashWallet/Sources/Models/Taxes/Taxes.swift index 28f25cf45..cf12295fb 100644 --- a/DashWallet/Sources/Models/Taxes/Taxes.swift +++ b/DashWallet/Sources/Models/Taxes/Taxes.swift @@ -43,7 +43,7 @@ enum TxUserInfoTaxCategory: Int { class Taxes: NSObject { var addressesUserInfos: AddressUserInfoDAO = AddressUserInfoDAOImpl() - var txUserInfos: TxUserInfoDAO = TxUserInfoDAOImpl() + var txUserInfos: TxUserInfoDAO = TxUserInfoDAOImpl.shared @objc func initialize() { @@ -61,12 +61,13 @@ class Taxes: NSObject { func taxCategory(for tx: DSTransaction) -> TxUserInfoTaxCategory { var taxCategory: TxUserInfoTaxCategory = tx.defaultTaxCategory() - if let inputAddress = tx.inputAddresses.first as? String, let txCategory = self.taxCategory(for: inputAddress) { + if let txCategory = txUserInfos.get(by: tx.txHashData)?.taxCategory { + taxCategory = txCategory + } else if let inputAddress = tx.inputAddresses.first as? String, + let txCategory = self.taxCategory(for: inputAddress) { taxCategory = txCategory } - taxCategory = txUserInfos.get(by: tx.txHashData)?.taxCategory ?? taxCategory - return taxCategory } diff --git a/DashWallet/Sources/Models/Taxes/Tx/DAO/TxUserInfoDAO.swift b/DashWallet/Sources/Models/Taxes/Tx/DAO/TxUserInfoDAO.swift index 7a900185c..cc3f31ee8 100644 --- a/DashWallet/Sources/Models/Taxes/Tx/DAO/TxUserInfoDAO.swift +++ b/DashWallet/Sources/Models/Taxes/Tx/DAO/TxUserInfoDAO.swift @@ -26,6 +26,7 @@ protocol TxUserInfoDAO { func all() -> [TxUserInfo] func update(dto: TxUserInfo) func delete(dto: TxUserInfo) + func deleteAll() } // MARK: - TxUserInfoDAOImpl @@ -38,8 +39,12 @@ class TxUserInfoDAOImpl: NSObject, TxUserInfoDAO { @objc func create(dto: TxUserInfo) { do { - let txUserInfo = TxUserInfo.table.insert(or: .replace, TxUserInfo.txHashColumn <- dto.txHash, - TxUserInfo.txCategoryColumn <- dto.taxCategory.rawValue) + let txUserInfo = TxUserInfo.table.insert(or: .replace, + TxUserInfo.txHashColumn <- dto.txHash, + TxUserInfo.txCategoryColumn <- dto.taxCategory.rawValue, + TxUserInfo.txRateColumn <- dto.rate, + TxUserInfo.txRateCurrencyCodeColumn <- dto.rateCurrency, + TxUserInfo.txRateMaximumFractionDigitsColumn <- dto.rateMaximumFractionDigits) try db.run(txUserInfo) } catch { @@ -99,13 +104,23 @@ class TxUserInfoDAOImpl: NSObject, TxUserInfoDAO { cache[dto.txHash] = nil } + @objc + func deleteAll() { + do { + try db.run(TxUserInfo.table.delete()) + cache = [:] + } catch { + print(error) + } + } + @objc static let shared = TxUserInfoDAOImpl() } extension TxUserInfoDAOImpl { @objc func dictionaryOfAllItems() -> [Data: TxUserInfo] { - all() + _ = all() return cache } } diff --git a/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift b/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift index 83d1fd669..33adab628 100644 --- a/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift +++ b/DashWallet/Sources/Models/Taxes/Tx/TxUserInfo.swift @@ -57,18 +57,29 @@ extension TxUserInfoTaxCategory { @objc var txHash: Data @objc var taxCategory: TxUserInfoTaxCategory = .unknown + var rate: Int? + var rateCurrency: String? + var rateMaximumFractionDigits: Int? + @objc init(hash: Data, taxCategory: TxUserInfoTaxCategory) { txHash = hash - self.taxCategory = taxCategory } init(row: Row) { txHash = row[TxUserInfo.txHashColumn] taxCategory = TxUserInfoTaxCategory(rawValue: row[TxUserInfo.txCategoryColumn]) ?? .unknown - + rate = row[TxUserInfo.txRateColumn] + rateCurrency = row[TxUserInfo.txRateCurrencyCodeColumn] + rateMaximumFractionDigits = row[TxUserInfo.txRateMaximumFractionDigitsColumn] super.init() } + + func update(rate: Int, currency: String, maximumFractionDigits: Int) { + self.rate = rate + rateCurrency = currency + rateMaximumFractionDigits = maximumFractionDigits + } } @objc @@ -77,12 +88,36 @@ extension TxUserInfo { func taxCategoryString() -> String { taxCategory.stringValue } + + @objc + func fiatAmountString(from dashAmount: UInt64) -> String { + let notAvailableString = NSLocalizedString("Not available", comment: "Fiat amount"); + + if let rate, + let rateCurrency, + let rateMaximumFractionDigits { + let rate = Decimal(rate)/Decimal(pow(10, rateMaximumFractionDigits)) + let fiatAmount = try? CurrencyExchanger.shared.convertDash(amount: dashAmount.dashAmount, + to: rateCurrency, + rate: rate) + + if let fiatAmount { + let nf = NumberFormatter.fiatFormatter(currencyCode: rateCurrency) + return nf.string(from: fiatAmount as NSDecimalNumber) ?? notAvailableString + } + } + + return notAvailableString + } } extension TxUserInfo { static var table: Table { Table("tx_userinfo") } static var txCategoryColumn: Expression { Expression("taxCategory") } static var txHashColumn: Expression { Expression("txHash") } + static var txRateColumn: Expression { .init("rate") } + static var txRateCurrencyCodeColumn: Expression { .init("rateCurrencyCode") } + static var txRateMaximumFractionDigitsColumn: Expression { .init("rateMaximumFractionDigits") } } @objc @@ -109,3 +144,9 @@ extension DSTransaction { return category.stringValue } } + +func pow(_ base:Int, _ power:Int) -> Int { + var answer = 1 + for _ in 0.. activationDate else { + return + } + + guard let decimalRate = try? CurrencyExchanger.shared.rate(for: App.fiatCurrency) else { + return + } + + let maximumFractionDigits = decimalRate.fractionDigits + let rate = (decimalRate*pow(10, maximumFractionDigits) as NSDecimalNumber).intValue + + guard let userInfo = txUserInfos.get(by: transaction.txHashData) else { + set(rate: rate, currency: App.fiatCurrency, maximumFractionDigits: maximumFractionDigits, for: transaction) + return + } + + guard userInfo.rate != nil else { + set(rate: rate, currency: App.fiatCurrency, maximumFractionDigits: maximumFractionDigits, for: userInfo) + return + } + } + + private func set(rate: Int, currency: String, maximumFractionDigits: Int, for transaction: DSTransaction) { + set(rate: rate, currency: currency, maximumFractionDigits: maximumFractionDigits, for: .init(hash: transaction.txHashData, taxCategory: transaction.defaultTaxCategory())) + } + + private func set(rate: Int, currency: String, maximumFractionDigits: Int, for userInfo: TxUserInfo) { + userInfo.update(rate: rate, currency: currency, maximumFractionDigits: maximumFractionDigits) + txUserInfos.update(dto: userInfo) + } + + @objc + static let shared = Transaction() +} + +// MARK: Transaction.Transactions + +extension Transaction { + struct Transactions: AsyncSequence, AsyncIteratorProtocol { + // Obtain all transactions here and monitor for the new ones + + typealias Element = DSTransaction + + mutating func next() async throws -> Element? { + guard !Task.isCancelled else { + return nil + } + + return nil + } + + func makeAsyncIterator() -> Transactions { + self + } + } +} + diff --git a/DashWallet/Sources/Models/Uphold/DWUpholdTransactionObject.m b/DashWallet/Sources/Models/Uphold/DWUpholdTransactionObject.m index 2d46633ec..a01f9e8d9 100644 --- a/DashWallet/Sources/Models/Uphold/DWUpholdTransactionObject.m +++ b/DashWallet/Sources/Models/Uphold/DWUpholdTransactionObject.m @@ -79,8 +79,8 @@ - (nullable instancetype)initWithDictionary:(NSDictionary *)dictionary { - (void)mock { _identifier = @"Mock Dash Account"; _type = DWUpholdTransactionObjectTypeWithdrawal; - _amount = [NSDecimalNumber numberWithFloat:3.14]; - _fee = [NSDecimalNumber numberWithFloat:0.000123]; + _amount = [[NSDecimalNumber alloc] initWithString:@"3.14"]; + _fee = [[NSDecimalNumber alloc] initWithString:@"0.01"]; _total = [_amount decimalNumberByAdding:_fee]; _currency = @"DASH"; } diff --git a/DashWallet/Sources/UI/Coinbase/Base/CoinbaseAmountViewController.swift b/DashWallet/Sources/UI/Coinbase/Base/CoinbaseAmountViewController.swift index 0499763ee..6e909c717 100644 --- a/DashWallet/Sources/UI/Coinbase/Base/CoinbaseAmountViewController.swift +++ b/DashWallet/Sources/UI/Coinbase/Base/CoinbaseAmountViewController.swift @@ -17,6 +17,14 @@ import UIKit +// MARK: - CoinbaseAmountModel + +class CoinbaseAmountModel: SendAmountModel { + override var currencyExchanger: CurrencyExchanger { + Coinbase.shared.currencyExchanger + } +} + // MARK: - CoinbaseAmountViewController class CoinbaseAmountViewController: SendAmountViewController, NetworkReachabilityHandling { diff --git a/DashWallet/Sources/UI/Coinbase/Base/ViewModel+Coinbase.swift b/DashWallet/Sources/UI/Coinbase/Base/ViewModel+Coinbase.swift index 95a6c6aa4..c45b7ed35 100644 --- a/DashWallet/Sources/UI/Coinbase/Base/ViewModel+Coinbase.swift +++ b/DashWallet/Sources/UI/Coinbase/Base/ViewModel+Coinbase.swift @@ -59,7 +59,7 @@ extension CoinbaseTransactionSendable { func transferFromCoinbase(amount: UInt64, with verificationCode: String?) async throws { do { - let tx = try await Coinbase.shared.transferFromCoinbaseToDashWallet(verificationCode: verificationCode, amount: amount) + _ = try await Coinbase.shared.transferFromCoinbaseToDashWallet(verificationCode: verificationCode, amount: amount) await MainActor.run { self.transactionDelegate?.transferFromCoinbaseToWalletDidSucceed() } diff --git a/DashWallet/Sources/UI/Coinbase/Buy Dash/BuyDashViewController.swift b/DashWallet/Sources/UI/Coinbase/Buy Dash/BuyDashViewController.swift index 813886a44..1fd0aa2ef 100644 --- a/DashWallet/Sources/UI/Coinbase/Buy Dash/BuyDashViewController.swift +++ b/DashWallet/Sources/UI/Coinbase/Buy Dash/BuyDashViewController.swift @@ -23,7 +23,7 @@ import UIKit final class BuyDashViewController: CoinbaseAmountViewController { override var actionButtonTitle: String? { NSLocalizedString("Continue", comment: "Buy Dash") } - override var amountInputStyle: AmountInputControl.Style { .basic } + override var amountInputStyle: AmountInputControl.Style { .oppositeAmount } internal var buyDashModel: BuyDashModel { model as! BuyDashModel @@ -32,6 +32,8 @@ final class BuyDashViewController: CoinbaseAmountViewController { private var activePaymentMethodView: ActivePaymentMethodView! internal var cancellables = Set() + override var isMaxButtonHidden: Bool { true } + init() { super.init(model: BuyDashModel()) } diff --git a/DashWallet/Sources/UI/Coinbase/Buy Dash/Confirm Transaction Controller/Model/ConfirmOrderModel.swift b/DashWallet/Sources/UI/Coinbase/Buy Dash/Confirm Transaction Controller/Model/ConfirmOrderModel.swift index d5ad54cfe..468055b50 100644 --- a/DashWallet/Sources/UI/Coinbase/Buy Dash/Confirm Transaction Controller/Model/ConfirmOrderModel.swift +++ b/DashWallet/Sources/UI/Coinbase/Buy Dash/Confirm Transaction Controller/Model/ConfirmOrderModel.swift @@ -55,7 +55,7 @@ final class ConfirmOrderModel: OrderPreviewModel { Task { [weak self] in do { - let order = try await Coinbase.shared.commitCoinbaseBuyOrder(orderID: orderId) + let _ = try await Coinbase.shared.commitCoinbaseBuyOrder(orderID: orderId) try await self?.transferFromCoinbase(amount: amount, with: nil) } catch { await MainActor.run { [weak self] in diff --git a/DashWallet/Sources/UI/Coinbase/Buy Dash/Model/BuyDashModel.swift b/DashWallet/Sources/UI/Coinbase/Buy Dash/Model/BuyDashModel.swift index d713ecd9e..38c3d8ecb 100644 --- a/DashWallet/Sources/UI/Coinbase/Buy Dash/Model/BuyDashModel.swift +++ b/DashWallet/Sources/UI/Coinbase/Buy Dash/Model/BuyDashModel.swift @@ -33,7 +33,7 @@ enum BuyDashFailureReason { // MARK: - BuyDashModel -final class BuyDashModel: SendAmountModel { +final class BuyDashModel: CoinbaseAmountModel { weak var delegate: BuyDashModelDelegate? @Published var paymentMethods: [CoinbasePaymentMethod] = [] @@ -46,6 +46,10 @@ final class BuyDashModel: SendAmountModel { isAmountValidForProceeding } + override var canShowInsufficientFunds: Bool { + false + } + var dashPriceDisplayString: String { guard let rate = try? Coinbase.shared.currencyExchanger.rate(for: App.fiatCurrency), let fiatBalanceFormatted = localFormatter.string(from: rate as NSNumber) else { diff --git a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/CustodialSwapsViewController.swift b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/CustodialSwapsViewController.swift index 9be688f1f..3a5c1b3a5 100644 --- a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/CustodialSwapsViewController.swift +++ b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/CustodialSwapsViewController.swift @@ -25,6 +25,8 @@ final class CustodialSwapsViewController: CoinbaseAmountViewController { NSLocalizedString("Get Quote", comment: "Coinbase/Convert Crypto") } + override var amountInputStyle: AmountInputControl.Style { .basic } + private var custodialSwapsModel: CustodialSwapsModel { model as! CustodialSwapsModel } private var converterView: ConverterView! diff --git a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Model/CustodialSwapsModel.swift b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Model/CustodialSwapsModel.swift index d1871d917..2ba3bef76 100644 --- a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Model/CustodialSwapsModel.swift +++ b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Model/CustodialSwapsModel.swift @@ -25,7 +25,7 @@ protocol CustodialSwapsModelDelegate: AnyObject { // MARK: - CustodialSwapsModel -class CustodialSwapsModel: SendAmountModel { +class CustodialSwapsModel: CoinbaseAmountModel { public var hasAccount: Bool { selectedAccount != nil } @@ -113,7 +113,8 @@ class CustodialSwapsModel: SendAmountModel { let max = AmountObject(localAmountString: selectedAccount.info.balance.amount, fiatCurrencyCode: selectedAccount.info.balance.currency, - localFormatter: supplementaryNumberFormatter) + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) supplementaryAmount = max mainAmount = supplementaryAmount.dashAmount amountDidChange() diff --git a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Order Preview/Model/ConvertCryptoOrderPreviewModel.swift b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Order Preview/Model/ConvertCryptoOrderPreviewModel.swift index 6ca61fc81..9bb918814 100644 --- a/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Order Preview/Model/ConvertCryptoOrderPreviewModel.swift +++ b/DashWallet/Sources/UI/Coinbase/Custodial Swaps/Order Preview/Model/ConvertCryptoOrderPreviewModel.swift @@ -56,7 +56,7 @@ final class ConvertCryptoOrderPreviewModel: OrderPreviewModel { Task { [weak self] in do { - let order = try await Coinbase.shared.commitTradeOrder(origin: selectedAccount, orderID: orderId) + let _ = try await Coinbase.shared.commitTradeOrder(origin: selectedAccount, orderID: orderId) try await self?.transferFromCoinbase(amount: amountToTransfer, with: nil) } catch { await MainActor.run { [weak self] in diff --git a/DashWallet/Sources/UI/Coinbase/Transfer Amount/Model/TransferAmountModel.swift b/DashWallet/Sources/UI/Coinbase/Transfer Amount/Model/TransferAmountModel.swift index 40996e089..d0badea38 100644 --- a/DashWallet/Sources/UI/Coinbase/Transfer Amount/Model/TransferAmountModel.swift +++ b/DashWallet/Sources/UI/Coinbase/Transfer Amount/Model/TransferAmountModel.swift @@ -29,7 +29,7 @@ protocol TransferAmountModelDelegate: CoinbaseTransactionDelegate { // MARK: - TransferAmountModel -final class TransferAmountModel: SendAmountModel, CoinbaseTransactionSendable { +final class TransferAmountModel: CoinbaseAmountModel, CoinbaseTransactionSendable { enum TransferDirection { case toWallet case toCoinbase @@ -70,7 +70,7 @@ final class TransferAmountModel: SendAmountModel, CoinbaseTransactionSendable { super.init() userDidChangeListenerHandle = Coinbase.shared.addUserDidChangeListener { [weak self] user in - if let user { + if user != nil { self?.delegate?.coinbaseUserDidChange() } } @@ -84,7 +84,7 @@ final class TransferAmountModel: SendAmountModel, CoinbaseTransactionSendable { let maxAmount = AmountObject(plainAmount: balance, fiatCurrencyCode: localCurrencyCode, - localFormatter: localFormatter) + localFormatter: localFormatter, currencyExchanger: currencyExchanger) updateCurrentAmountObject(with: maxAmount) } } diff --git a/DashWallet/Sources/UI/Coinbase/Two Factor Auth/TwoFactorAuthViewController.swift b/DashWallet/Sources/UI/Coinbase/Two Factor Auth/TwoFactorAuthViewController.swift index 2d1b67f57..79aed5beb 100644 --- a/DashWallet/Sources/UI/Coinbase/Two Factor Auth/TwoFactorAuthViewController.swift +++ b/DashWallet/Sources/UI/Coinbase/Two Factor Auth/TwoFactorAuthViewController.swift @@ -89,7 +89,7 @@ final class TwoFactorAuthViewController: ActionButtonViewController { } override var actionButtonTitle: String? { - NSLocalizedString("Verfiy", comment: "Coinbase") + NSLocalizedString("Verify", comment: "Coinbase") } override func actionButtonAction(sender: UIView) { diff --git a/DashWallet/Sources/UI/DashPay/Items/Views/ContentViews/DWDPGenericContactRequestItemView.m b/DashWallet/Sources/UI/DashPay/Items/Views/ContentViews/DWDPGenericContactRequestItemView.m index 4112b9e6b..250fe20c2 100644 --- a/DashWallet/Sources/UI/DashPay/Items/Views/ContentViews/DWDPGenericContactRequestItemView.m +++ b/DashWallet/Sources/UI/DashPay/Items/Views/ContentViews/DWDPGenericContactRequestItemView.m @@ -67,7 +67,7 @@ - (void)setup_contactRequestItemView { [self.accessoryView addSubview:declineButton]; _declineButton = declineButton; - UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; activityIndicatorView.color = [UIColor dw_tertiaryTextColor]; [self.accessoryView addSubview:activityIndicatorView]; diff --git a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileContactActionsCell.m b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileContactActionsCell.m index e238a5814..6e3d3464b 100644 --- a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileContactActionsCell.m +++ b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileContactActionsCell.m @@ -75,7 +75,7 @@ - (instancetype)initWithFrame:(CGRect)frame { [mainButton addTarget:self action:@selector(secondaryButtonAction:) forControlEvents:UIControlEventTouchUpInside]; _secondaryButton = secondaryButton; - UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; activityIndicatorView.color = [UIColor dw_dashBlueColor]; activityIndicatorView.hidesWhenStopped = NO; diff --git a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileHeaderView.m b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileHeaderView.m index dc3fa41f8..b744acd12 100644 --- a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileHeaderView.m +++ b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileHeaderView.m @@ -122,7 +122,7 @@ - (instancetype)initWithFrame:(CGRect)frame { [bottomContentView addSubview:actionButton]; _actionButton = actionButton; - UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; activityIndicatorView.color = [UIColor dw_dashBlueColor]; [bottomContentView addSubview:activityIndicatorView]; diff --git a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileSendRequestCell.m b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileSendRequestCell.m index a753bf70d..9b648a2ce 100644 --- a/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileSendRequestCell.m +++ b/DashWallet/Sources/UI/DashPay/Profile/Views/DWUserProfileSendRequestCell.m @@ -76,7 +76,7 @@ - (instancetype)initWithFrame:(CGRect)frame { _sendRequestButton = sendRequestButton; // fire up activity indicator in advance to fix reuse issue - UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; activityIndicatorView.color = [UIColor dw_dashBlueColor]; [activityIndicatorView startAnimating]; diff --git a/DashWallet/Sources/UI/DashPay/Setup/CreateUsername/Views/DWUsernameValidationView.m b/DashWallet/Sources/UI/DashPay/Setup/CreateUsername/Views/DWUsernameValidationView.m index 2296165d7..805a4e3cc 100644 --- a/DashWallet/Sources/UI/DashPay/Setup/CreateUsername/Views/DWUsernameValidationView.m +++ b/DashWallet/Sources/UI/DashPay/Setup/CreateUsername/Views/DWUsernameValidationView.m @@ -46,7 +46,7 @@ - (instancetype)initWithFrame:(CGRect)frame { [self addSubview:iconImageView]; _iconImageView = iconImageView; - UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; activityIndicatorView.color = [UIColor dw_darkTitleColor]; [self addSubview:activityIndicatorView]; diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/Views/PointOfUseDetailsView.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/Views/PointOfUseDetailsView.swift index 7c86bea68..6aff41db1 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/Views/PointOfUseDetailsView.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/Views/PointOfUseDetailsView.swift @@ -116,6 +116,12 @@ class PointOfUseDetailsView: UIView { configureActionBlock() configureBottomButton() } + + override func layoutSubviews() { + super.layoutSubviews() + + containerView.setNeedsLayout() + } } extension PointOfUseDetailsView { @@ -281,14 +287,26 @@ class VerticalButton: DWTintedButton { super.init(frame: frame) imageView?.contentMode = .scaleAspectFit; - layer.cornerRadius = 9 titleLabel?.font = .dw_mediumFont(ofSize: 11) + + layer.cornerRadius = 9 + centerVertically(padding: 3) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + override func resetAppearance() { + super.resetAppearance() + + imageView?.contentMode = .scaleAspectFit; + titleLabel?.font = .dw_mediumFont(ofSize: 11) + + layer.cornerRadius = 9 + centerVertically(padding: 3) + } + override func awakeFromNib() { super.awakeFromNib() contentHorizontalAlignment = .left diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift index c25631853..579c95503 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift @@ -271,7 +271,6 @@ extension ExplorePointOfUseListViewController { appliedFiltersStackView.addArrangedSubview(appliedFiltersLabel) let appliedFilters = UIBarButtonItem(customView: appliedFiltersStackView) - let empty = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: self, action: nil) let filter = UIBarButtonItem(image: .init(systemName: "line.3.horizontal.decrease.circle.fill"), style: .plain, target: self, action: nil) filter.tintColor = .dw_dashBlue() diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/Locations List/Model/TerritoryListModel.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/Locations List/Model/TerritoryListModel.swift index 19ff14886..d38e1737e 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/Locations List/Model/TerritoryListModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/Locations List/Model/TerritoryListModel.swift @@ -46,7 +46,7 @@ final class TerritoriesListModel { DispatchQueue.main.async { self?.territoriesDidChange?() } - case .failure(let error): + case .failure: break } } diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/PointOfUseListFiltersViewController.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/PointOfUseListFiltersViewController.swift index 28f118465..d63ddbae8 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/PointOfUseListFiltersViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Filters/PointOfUseListFiltersViewController.swift @@ -227,19 +227,19 @@ extension PointOfUseListFiltersViewController: UITableViewDelegate { } func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { - if let filterCell = cell as? FilterItemSelectableCell, + if cell is FilterItemSelectableCell, let item = dataSource.itemIdentifier(for: indexPath) { selectedCells[item] = nil } - if let cell = cell as? FilterItemResetCell { + if cell is FilterItemResetCell { resetCell = nil return } } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { - if let filterCell = tableView.cellForRow(at: indexPath) as? FilterItemSelectableCell, + if tableView.cellForRow(at: indexPath) is FilterItemSelectableCell, let item = dataSource.itemIdentifier(for: indexPath) { let deselected = model.toggle(filter: item) if !deselected { diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Model/PointOfUseListModel.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Model/PointOfUseListModel.swift index 45b77bf88..d8104debe 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Model/PointOfUseListModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/Model/PointOfUseListModel.swift @@ -221,7 +221,7 @@ extension PointOfUseListModel { self?.itemsDidChange?() } break - case .failure(let error): + case .failure: self?.isFetching = false break // TODO: handler failure } @@ -243,7 +243,7 @@ extension PointOfUseListModel { self?.nextPageDidLoaded?(offset, count) } break - case .failure(let error): + case .failure: break // TODO: handler failure } } diff --git a/DashWallet/Sources/UI/Home/Models/DWHomeModel.m b/DashWallet/Sources/UI/Home/Models/DWHomeModel.m index 3913bd211..70198dc20 100644 --- a/DashWallet/Sources/UI/Home/Models/DWHomeModel.m +++ b/DashWallet/Sources/UI/Home/Models/DWHomeModel.m @@ -38,6 +38,7 @@ #import "DWTransactionListDataSource+DWProtected.h" #import "DWVersionManager.h" #import "UIDevice+DashWallet.h" +#import "dashwallet-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -158,7 +159,10 @@ - (instancetype)init { object:nil]; [self reloadTxDataSource]; - [[DWGlobalOptions sharedInstance] setActivationDateForReclassifyYourTransactionsFlowIfNeeded:[NSDate new]]; + + NSDate *date = [NSDate new]; + [[DWGlobalOptions sharedInstance] setActivationDateForReclassifyYourTransactionsFlowIfNeeded:date]; + [[DWGlobalOptions sharedInstance] setActivationDateForHistoricalRates:date]; } return self; } @@ -482,7 +486,7 @@ - (void)reloadTxDataSource { BOOL allowedToShowReclassifyYourTransactions = NO; BOOL shouldAnimate = YES; - DSTransaction *prevTransaction = self.dataSource.items.firstObject; + DSTransaction *prevTransaction = self.allDataSource.items.firstObject; DSTransaction *newTransaction = transactions.firstObject; if (!prevTransaction || prevTransaction == newTransaction) { @@ -496,6 +500,10 @@ - (void)reloadTxDataSource { allowedToShowReclassifyYourTransactions = [newTransaction.transactionDate compare:dateReclassifyYourTransactionsFlowActivated] == NSOrderedDescending; } + for (DSTransaction *tx in transactions) { + [Transaction.shared updateRateIfNeededFor:tx]; + } + self.allDataSource = [[DWTransactionListDataSource alloc] initWithTransactions:transactions registrationStatus:self.dashPayModel.registrationStatus dataProvider:self.dataProvider]; diff --git a/DashWallet/Sources/UI/Home/Models/Transactions/DWBaseTransactionListDataProvider.m b/DashWallet/Sources/UI/Home/Models/Transactions/DWBaseTransactionListDataProvider.m index 877422303..c1380c461 100644 --- a/DashWallet/Sources/UI/Home/Models/Transactions/DWBaseTransactionListDataProvider.m +++ b/DashWallet/Sources/UI/Home/Models/Transactions/DWBaseTransactionListDataProvider.m @@ -17,6 +17,7 @@ #import "DWBaseTransactionListDataProvider.h" +#import "DSTransaction+DashWallet.h" #import "DWDateFormatter.h" #import "DWEnvironment.h" #import "DWTransactionListDataItem.h" @@ -35,12 +36,7 @@ - (instancetype)init { } - (NSDate *)dateForTransaction:(DSTransaction *)transaction { - DSChain *chain = [DWEnvironment sharedInstance].currentChain; - NSTimeInterval now = [chain timestampForBlockHeight:TX_UNCONFIRMED]; - NSTimeInterval txTime = (transaction.timestamp > 1) ? transaction.timestamp : now; - NSDate *txDate = [NSDate dateWithTimeIntervalSince1970:txTime]; - - return txDate; + return transaction.date; } - (NSString *)formattedShortTxDate:(NSDate *)date { diff --git a/DashWallet/Sources/UI/Home/Models/Transactions/DWTransactionListDataProviderProtocol.h b/DashWallet/Sources/UI/Home/Models/Transactions/DWTransactionListDataProviderProtocol.h index de75fa447..94e281171 100644 --- a/DashWallet/Sources/UI/Home/Models/Transactions/DWTransactionListDataProviderProtocol.h +++ b/DashWallet/Sources/UI/Home/Models/Transactions/DWTransactionListDataProviderProtocol.h @@ -31,9 +31,6 @@ NS_ASSUME_NONNULL_BEGIN - (NSString *)dashAmountStringFrom:(id)transactionData; - (NSAttributedString *)dashAmountStringFrom:(id)transactionData font:(UIFont *)font; -- (NSAttributedString *)dashAmountStringFrom:(id)transactionData - tintColor:(UIColor *)color - font:(UIFont *)font; @end diff --git a/DashWallet/Sources/UI/Home/Views/Cells/DWTxListTableViewCell.m b/DashWallet/Sources/UI/Home/Views/Cells/DWTxListTableViewCell.m index 9fd3898b9..f00ef6ab8 100644 --- a/DashWallet/Sources/UI/Home/Views/Cells/DWTxListTableViewCell.m +++ b/DashWallet/Sources/UI/Home/Views/Cells/DWTxListTableViewCell.m @@ -20,6 +20,7 @@ #import #import "DWUIKit.h" +#import "dashwallet-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -95,7 +96,16 @@ - (void)configureWithTransaction:(DSTransaction *)transaction self.transactionData = [self.dataProvider transactionDataForTransaction:transaction]; self.dateLabel.text = [self.dataProvider shortDateStringForTransaction:transaction]; - self.fiatAmountLabel.text = self.transactionData.fiatAmount; + + TxUserInfo *userInfo = [TxUserInfoDAOImpl.shared getBy:transaction.txHashData]; + if (userInfo) { + self.fiatAmountLabel.text = [userInfo fiatAmountStringFrom:self.transactionData.dashAmount]; + } + else { + self.fiatAmountLabel.text = NSLocalizedString(@"Not available", "Fiat amount"); + } + + [self reloadAttributedData]; } diff --git a/DashWallet/Sources/UI/Menu/Settings/About/DWAboutViewController.m b/DashWallet/Sources/UI/Menu/Settings/About/DWAboutViewController.m index 6cc2ae131..527fd67a2 100644 --- a/DashWallet/Sources/UI/Menu/Settings/About/DWAboutViewController.m +++ b/DashWallet/Sources/UI/Menu/Settings/About/DWAboutViewController.m @@ -86,7 +86,7 @@ - (void)viewDidLoad { self.rateReviewLabel.text = NSLocalizedString(@"Help us improve your experience", nil); [self.rateReviewButton setTitle:NSLocalizedString(@"Review & Rate the app", nil) forState:UIControlStateNormal]; [self.contactSupportButton setTitle:NSLocalizedString(@"Contact Support", nil) forState:UIControlStateNormal]; - self.copyrightLabel.text = NSLocalizedString(@"Copyright © 2022 Dash Core", nil); + self.copyrightLabel.text = NSLocalizedString(@"Copyright © 2023 Dash Core", nil); self.exploreDashLastDeviceSyncLabel.text = [self.model exploreDashSyncState]; self.exploreDashLastServerUpdateLabel.text = [self.model exploreLastServerUpdateDate]; diff --git a/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m b/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m index fffc26cdf..e1e7cc2f0 100644 --- a/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m +++ b/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuModel.m @@ -124,7 +124,7 @@ + (void)rescanBlockchainActionFromController:(UIViewController *)controller #endif [actionSheet addAction:cancelAction]; - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { actionSheet.popoverPresentationController.sourceView = sourceView; actionSheet.popoverPresentationController.sourceRect = sourceRect; } diff --git a/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuViewController.m b/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuViewController.m index 6663a5a71..43366cc69 100644 --- a/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuViewController.m +++ b/DashWallet/Sources/UI/Menu/Settings/DWSettingsMenuViewController.m @@ -260,7 +260,7 @@ - (void)showChangeNetworkFromSourceView:(UIView *)sourceView sourceRect:(CGRect) [actionSheet addAction:testnet]; // [actionSheet addAction:evonet]; [actionSheet addAction:cancel]; - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { actionSheet.popoverPresentationController.sourceView = sourceView; actionSheet.popoverPresentationController.sourceRect = sourceRect; } diff --git a/DashWallet/Sources/UI/Payments/Amount/BaseAmountViewController.swift b/DashWallet/Sources/UI/Payments/Amount/BaseAmountViewController.swift index e3bb546fc..39d9fe1fc 100644 --- a/DashWallet/Sources/UI/Payments/Amount/BaseAmountViewController.swift +++ b/DashWallet/Sources/UI/Payments/Amount/BaseAmountViewController.swift @@ -214,8 +214,6 @@ extension BaseAmountViewController { extension BaseAmountViewController: DWLocalCurrencyViewControllerDelegate { func localCurrencyViewController(_ controller: DWLocalCurrencyViewController, didSelectCurrency currencyCode: String) { model.setupCurrencyCode(currencyCode) - amountView.amountInputControl.reloadData() - amountView.inputTypeSwitcher.reloadData() controller.dismiss(animated: true) } diff --git a/DashWallet/Sources/UI/Payments/Amount/Model/AmountObject.swift b/DashWallet/Sources/UI/Payments/Amount/Model/AmountObject.swift index 9c09f8bcf..b642f0cc8 100644 --- a/DashWallet/Sources/UI/Payments/Amount/Model/AmountObject.swift +++ b/DashWallet/Sources/UI/Payments/Amount/Model/AmountObject.swift @@ -22,15 +22,17 @@ import Foundation struct AmountObject { let amountType: AmountType let amountInternalRepresentation: String - let plainAmount: UInt64 + let plainAmount: UInt64 let mainFormatted: String + + let supplementaryAmount: Decimal let supplementaryFormatted: String let localFormatter: NumberFormatter let fiatCurrencyCode: String - init(dashAmountString: String, fiatCurrencyCode: String, localFormatter: NumberFormatter) { + init(dashAmountString: String, fiatCurrencyCode: String, localFormatter: NumberFormatter, currencyExchanger: CurrencyExchanger) { var dashAmountString = dashAmountString if dashAmountString.isEmpty { @@ -53,16 +55,19 @@ struct AmountObject { NSLocalizedString("Invalid Input", comment: "Invalid Amount Input") if plainAmount == 0 { + supplementaryAmount = 0 supplementaryFormatted = localFormatter.string(from: 0.0)! - } else if let localAmount = try? Coinbase.shared.currencyExchanger.convertDash(amount: dashNumber, to: fiatCurrencyCode), + } else if let localAmount = try? currencyExchanger.convertDash(amount: dashNumber, to: fiatCurrencyCode), let str = localFormatter.string(from: localAmount as NSNumber) { + supplementaryAmount = localAmount supplementaryFormatted = str } else { + supplementaryAmount = 0 supplementaryFormatted = NSLocalizedString("Updating Price", comment: "Updating Price") } } - init?(localAmountString: String, fiatCurrencyCode: String, localFormatter: NumberFormatter) { + init?(localAmountString: String, fiatCurrencyCode: String, localFormatter: NumberFormatter, currencyExchanger: CurrencyExchanger) { var localAmountString = localAmountString if localAmountString.isEmpty { @@ -77,27 +82,28 @@ struct AmountObject { let localNumber = Decimal(string: localAmountString, locale: .current)! let localCurrencyFormatted = localFormatter.inputString(from: localNumber as NSNumber, and: localAmountString)! supplementaryFormatted = localCurrencyFormatted + supplementaryAmount = localNumber if localNumber.isZero { plainAmount = 0 mainFormatted = NumberFormatter.dashFormatter.string(from: 0)! - } else if let dashAmount = try? Coinbase.shared.currencyExchanger.convertToDash(amount: localNumber, currency: fiatCurrencyCode), + } else if let dashAmount = try? currencyExchanger.convertToDash(amount: localNumber, currency: fiatCurrencyCode), let str = NumberFormatter.dashFormatter.string(from: dashAmount as NSNumber) { plainAmount = dashAmount.plainDashAmount mainFormatted = str } else { plainAmount = 0 - mainFormatted = "Error" + mainFormatted = NSLocalizedString("Updating Price", comment: "Updating Price") } } - init(plainAmount: UInt64, fiatCurrencyCode: String, localFormatter: NumberFormatter) { + init(plainAmount: UInt64, fiatCurrencyCode: String, localFormatter: NumberFormatter, currencyExchanger: CurrencyExchanger) { let plainNumber = Decimal(plainAmount) let duffsNumber = Decimal(DUFFS) let dashNumber = plainNumber/duffsNumber let dashAmounString = NSDecimalNumber(decimal: dashNumber).description(withLocale: Locale.current) - self.init(dashAmountString: dashAmounString, fiatCurrencyCode: fiatCurrencyCode, localFormatter: localFormatter) + self.init(dashAmountString: dashAmounString, fiatCurrencyCode: fiatCurrencyCode, localFormatter: localFormatter, currencyExchanger: currencyExchanger) } } @@ -105,35 +111,42 @@ extension AmountObject { var dashAmount: AmountObject { if amountType == .main { return self } - let dashAmount = NumberFormatter.dashFormatter.number(from: mainFormatted)! - let amountInternalRepresentation = NumberFormatter.dashDecimalFormatter.string(from: dashAmount)! - - return object(with: amountInternalRepresentation) + let amountInternalRepresentation = plainAmount.formattedDashAmountWithoutCurrencySymbol + return object(with: amountInternalRepresentation, amountType: .main) } var localAmount: AmountObject { if amountType == .supplementary { return self } - let localAmount = localFormatter.number(from: supplementaryFormatted)! - let amountInternalRepresentation = NumberFormatter.decimalFormatter.string(from: localAmount)! + let numberFormatter = localFormatter.copy() as! NumberFormatter + numberFormatter.numberStyle = .none + numberFormatter.minimumIntegerDigits = 1 + numberFormatter.minimumFractionDigits = 0 + numberFormatter.maximumFractionDigits = localFormatter.maximumFractionDigits + + guard let amountInternalRepresentation = numberFormatter.string(from: supplementaryAmount as NSDecimalNumber) else { + fatalError("Can't convert dash amount: \(plainAmount.formattedDashAmount) to local amount. Supplementary Amount = \(String(describing: supplementaryAmount))") + } - return object(with: amountInternalRepresentation) + return object(with: amountInternalRepresentation, amountType: .supplementary) } - private func object(with internalRepresentation: String) -> AmountObject { + private func object(with internalRepresentation: String, amountType: AmountType) -> AmountObject { AmountObject(amountInternalRepresentation: internalRepresentation, plainAmount: plainAmount, - amountType: .supplementary, + supplementaryAmount: supplementaryAmount, + amountType: amountType, mainFormatted: mainFormatted, supplementaryFormatted: supplementaryFormatted, localFormatter: localFormatter, fiatCurrencyCode: fiatCurrencyCode) } - init(amountInternalRepresentation: String, plainAmount: UInt64, amountType: AmountType, mainFormatted: String, + init(amountInternalRepresentation: String, plainAmount: UInt64, supplementaryAmount: Decimal, amountType: AmountType, mainFormatted: String, supplementaryFormatted: String, localFormatter: NumberFormatter, fiatCurrencyCode: String) { self.amountInternalRepresentation = amountInternalRepresentation self.plainAmount = plainAmount + self.supplementaryAmount = supplementaryAmount self.amountType = amountType self.mainFormatted = mainFormatted self.supplementaryFormatted = supplementaryFormatted diff --git a/DashWallet/Sources/UI/Payments/Amount/Model/BaseAmountModel.swift b/DashWallet/Sources/UI/Payments/Amount/Model/BaseAmountModel.swift index dc78cf3a8..3eac55235 100644 --- a/DashWallet/Sources/UI/Payments/Amount/Model/BaseAmountModel.swift +++ b/DashWallet/Sources/UI/Payments/Amount/Model/BaseAmountModel.swift @@ -33,7 +33,13 @@ struct AmountInputItem: Equatable { var isMain: Bool { currencyCode == kDashCurrency } static let dash = AmountInputItem(currencyName: kDashCurrency, currencyCode: kDashCurrency) - static var app: AmountInputItem { .init(currencyName: App.fiatCurrency, currencyCode: App.fiatCurrency) } + static var app: AmountInputItem { + .init(currencyName: App.fiatCurrency, currencyCode: App.fiatCurrency) + } + + static func custom(currencyName: String, currencyCode: String) -> AmountInputItem { + .init(currencyName: currencyName, currencyCode: currencyCode) + } } // MARK: - BaseAmountModel @@ -105,13 +111,17 @@ class BaseAmountModel { localFormatter } + internal var currencyExchanger: CurrencyExchanger { + CurrencyExchanger.shared + } + init() { localCurrencyCode = App.fiatCurrency localFormatter = NumberFormatter.fiatFormatter(currencyCode: localCurrencyCode) currentInputItem = .dash inputItems = [ - .app, + .custom(currencyName: localCurrencyCode, currencyCode: localCurrencyCode), .dash, ] @@ -132,7 +142,8 @@ class BaseAmountModel { } else if currentAmount.fiatCurrencyCode != supplementaryCurrencyCode { let mainAmount = AmountObject(plainAmount: currentAmount.plainAmount, fiatCurrencyCode: supplementaryCurrencyCode, - localFormatter: supplementaryNumberFormatter) + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) supplementaryAmount = mainAmount.localAmount } } else { @@ -151,12 +162,13 @@ class BaseAmountModel { func setupCurrencyCode(_ code: String) { guard let price = try? CurrencyExchanger.shared.rate(for: code) else { return } - localFormatter.currencyCode = code + localFormatter = NumberFormatter.fiatFormatter(currencyCode: code) localCurrencyCode = code - currentInputItem = currentInputItem.currencyCode == kDashCurrency ? .dash : .app + let newInputItem = AmountInputItem.custom(currencyName: localCurrencyCode, currencyCode: localCurrencyCode) + currentInputItem = currentInputItem.isMain ? .dash : newInputItem inputItems = [ - .app, + newInputItem, .dash, ] @@ -170,11 +182,13 @@ class BaseAmountModel { if activeAmountType == .main { mainAmount = AmountObject(dashAmountString: inputString, fiatCurrencyCode: supplementaryCurrencyCode, - localFormatter: supplementaryNumberFormatter) + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) supplementaryAmount = nil } else if let amount = AmountObject(localAmountString: inputString, fiatCurrencyCode: supplementaryCurrencyCode, - localFormatter: supplementaryNumberFormatter) { + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) { supplementaryAmount = amount mainAmount = nil } @@ -185,7 +199,8 @@ class BaseAmountModel { internal func updateCurrentAmountObject(with amount: UInt64) { let amountObject = AmountObject(plainAmount: amount, fiatCurrencyCode: supplementaryCurrencyCode, - localFormatter: supplementaryNumberFormatter) + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) updateCurrentAmountObject(with: amountObject) } @@ -289,7 +304,6 @@ extension BaseAmountModel { } func amountInputControlDidSwapInputs() { - assert(isSwapToLocalCurrencyAllowed, "Switching until price is not fetched is not allowed") assert(inputItems.count == 2, "Swap only if we have two input types") let inputItem = inputItems[0] == currentInputItem ? inputItems[1] : inputItems[0] @@ -297,31 +311,23 @@ extension BaseAmountModel { } func pasteFromClipboard() { - guard var string = UIPasteboard.general.string else { return } - string = string.localizedAmount() + guard let string = UIPasteboard.general.string else { return } - guard let decimal = Decimal(string: string, locale: .current) else { return } - let decimalNumber = NSDecimalNumber(decimal: decimal) + let originalFormatter = currentInputItem.isMain + ? NumberFormatter.dashFormatter + : localFormatter + let formatter = originalFormatter.copy() as! NumberFormatter + formatter.numberStyle = .decimal + formatter.minimumFractionDigits = 0 + formatter.maximumFractionDigits = originalFormatter.maximumFractionDigits - let formattedString: String? + guard let number = formatter.number(from: string) else { return } - var formatter: NumberFormatter - - if activeAmountType == .main { - formatter = NumberFormatter.dashFormatter.copy() as! NumberFormatter - formatter.numberStyle = .decimal - formatter.minimumFractionDigits = NumberFormatter.dashFormatter.minimumFractionDigits - formatter.maximumFractionDigits = NumberFormatter.dashFormatter.maximumFractionDigits - formattedString = formatter.string(from: decimalNumber) - } else { - formatter = localFormatter.copy() as! NumberFormatter - formatter.numberStyle = .decimal - formatter.minimumFractionDigits = localFormatter.minimumFractionDigits - formatter.maximumFractionDigits = localFormatter.maximumFractionDigits - formattedString = formatter.string(from: decimalNumber) - } + formatter.numberStyle = .none + formatter.minimumFractionDigits = 0 + formatter.maximumFractionDigits = originalFormatter.maximumFractionDigits - guard let string = formattedString else { return } + guard let string = formatter.string(from: number) else { return } updateAmountObjects(with: string) } diff --git a/DashWallet/Sources/UI/Payments/Amount/Model/Send/SendAmountModel.swift b/DashWallet/Sources/UI/Payments/Amount/Model/Send/SendAmountModel.swift index 3eefc886b..f762a2f41 100644 --- a/DashWallet/Sources/UI/Payments/Amount/Model/Send/SendAmountModel.swift +++ b/DashWallet/Sources/UI/Payments/Amount/Model/Send/SendAmountModel.swift @@ -112,7 +112,7 @@ class SendAmountModel: BaseAmountModel { else { authManager.authenticate(withPrompt: nil, usingBiometricAuthentication: true, - alertIfLockout: true) { [weak self] authenticatedOrSuccess, _, _ in + alertIfLockout: true) { authenticatedOrSuccess, _, _ in completionBlock(authenticatedOrSuccess) } } diff --git a/DashWallet/Sources/UI/Payments/Amount/Validation/DWAmountInputValidator.m b/DashWallet/Sources/UI/Payments/Amount/Validation/DWAmountInputValidator.m index 0665ac482..e63c58b4a 100644 --- a/DashWallet/Sources/UI/Payments/Amount/Validation/DWAmountInputValidator.m +++ b/DashWallet/Sources/UI/Payments/Amount/Validation/DWAmountInputValidator.m @@ -65,7 +65,6 @@ - (instancetype)initWithType:(DWAmountInputValidatorType)type locale:(nullable N } case DWAmountInputValidatorTypeLocalCurrency: { numberFormatter.maximumFractionDigits = 2; - break; } } @@ -107,6 +106,10 @@ - (nullable NSString *)validatedAmountStringFromNumberString:(NSString *)validNu NSNumberFormatter *nf = [numberFormatter copy]; nf.numberStyle = NSNumberFormatterNoStyle; + nf.roundingMode = NSNumberFormatterRoundDown; + nf.minimumIntegerDigits = 1; + nf.minimumFractionDigits = 0; + nf.maximumFractionDigits = numberFormatter.maximumFractionDigits; NSNumber *number = [nf numberFromString:validNumberString]; if (number == nil) { @@ -126,8 +129,8 @@ - (nullable NSString *)validatedAmountStringFromNumberString:(NSString *)validNu } NSString *fractionPart = [validNumberString substringFromIndex:separatorIndex + 1]; - if (fractionPart.length > numberFormatter.maximumFractionDigits || - (fractionPart.length == numberFormatter.maximumFractionDigits && fractionPart.integerValue == 0)) { + if (fractionPart.length > nf.maximumFractionDigits || + (fractionPart.length == nf.maximumFractionDigits && fractionPart.integerValue == 0)) { return nil; } diff --git a/DashWallet/Sources/UI/Setup/RecoverWallet/DWRecoverModel.m b/DashWallet/Sources/UI/Setup/RecoverWallet/DWRecoverModel.m index 3688a8184..2c7f40cb8 100644 --- a/DashWallet/Sources/UI/Setup/RecoverWallet/DWRecoverModel.m +++ b/DashWallet/Sources/UI/Setup/RecoverWallet/DWRecoverModel.m @@ -20,6 +20,7 @@ #import "DWAppGroupOptions.h" #import "DWEnvironment.h" #import "DWGlobalOptions.h" +#import "dashwallet-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -79,6 +80,8 @@ - (BOOL)phraseIsValid:(NSString *)phrase { } - (void)wipeWallet { + [[TxUserInfoDAOImpl shared] deleteAll]; + [[AddressUserInfoDAOImpl shared] deleteAll]; [[DWEnvironment sharedInstance] clearAllWallets]; [[DWGlobalOptions sharedInstance] restoreToDefaults]; diff --git a/DashWallet/Sources/UI/Tx/Details/Model/TxDetailModel.swift b/DashWallet/Sources/UI/Tx/Details/Model/TxDetailModel.swift index c7d1ba67e..b09f59835 100644 --- a/DashWallet/Sources/UI/Tx/Details/Model/TxDetailModel.swift +++ b/DashWallet/Sources/UI/Tx/Details/Model/TxDetailModel.swift @@ -36,9 +36,10 @@ class TxDetailModel: NSObject { } var fiatAmountString: String { - dataItem.fiatAmount; + userInfo?.fiatAmountString(from: dataItem.dashAmount) ?? NSLocalizedString("Not available", comment: ""); } + var userInfo: TxUserInfo? @objc init(transaction: DSTransaction, dataProvider: DWTransactionListDataProviderProtocol) { @@ -46,6 +47,7 @@ class TxDetailModel: NSObject { self.transaction = transaction self.dataProvider = dataProvider dataItem = dataProvider.transactionData(for: transaction) + userInfo = TxUserInfoDAOImpl.shared.get(by: transaction.txHashData) txTaxCategory = Taxes.shared.taxCategory(for: transaction) } diff --git a/DashWallet/Sources/UI/Uphold/Transfer/Model/UpholdAmountModel.swift b/DashWallet/Sources/UI/Uphold/Transfer/Model/UpholdAmountModel.swift index 5a6e1f531..fa3009a2f 100644 --- a/DashWallet/Sources/UI/Uphold/Transfer/Model/UpholdAmountModel.swift +++ b/DashWallet/Sources/UI/Uphold/Transfer/Model/UpholdAmountModel.swift @@ -66,7 +66,8 @@ final class UpholdAmountModel: BaseAmountModel { if allAvailableFunds > 0 { let maxAmount = AmountObject(plainAmount: allAvailableFunds, fiatCurrencyCode: supplementaryCurrencyCode, - localFormatter: supplementaryNumberFormatter) + localFormatter: supplementaryNumberFormatter, + currencyExchanger: currencyExchanger) updateCurrentAmountObject(with: maxAmount) } } diff --git a/DashWallet/Sources/UI/Uphold/Transfer/OTP/DWUpholdOTPViewController.m b/DashWallet/Sources/UI/Uphold/Transfer/OTP/DWUpholdOTPViewController.m index cc9973755..58a92099f 100644 --- a/DashWallet/Sources/UI/Uphold/Transfer/OTP/DWUpholdOTPViewController.m +++ b/DashWallet/Sources/UI/Uphold/Transfer/OTP/DWUpholdOTPViewController.m @@ -197,8 +197,7 @@ - (void)displayTextFieldMenuIfNeeded { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ UIMenuController *menu = [UIMenuController sharedMenuController]; - [menu setTargetRect:self.textField.bounds inView:self.textField]; - [menu setMenuVisible:YES animated:YES]; + [menu showMenuFromView:self.textField rect:self.textField.bounds]; }); } diff --git a/DashWallet/Sources/UI/Views/BalanceView/BalanceView.swift b/DashWallet/Sources/UI/Views/BalanceView/BalanceView.swift index 354b03dea..80e06ba2f 100644 --- a/DashWallet/Sources/UI/Views/BalanceView/BalanceView.swift +++ b/DashWallet/Sources/UI/Views/BalanceView/BalanceView.swift @@ -66,7 +66,6 @@ extension BalanceView { let supplementaryAmountString = dataSource?.supplementaryAmountString ?? NumberFormatter.fiatFormatter.string(from: 0)! let balanceColor = UIColor.label - let font = UIFont.dw_font(forTextStyle: .title1) let balanceString = mainAmountString.attributedAmountStringWithDashSymbol(tintColor: balanceColor) dashBalanceLabel.attributedText = balanceString fiatBalanceLabel.text = supplementaryAmountString diff --git a/DashWallet/Sources/UI/Views/BaseController/ActionButtonViewController.swift b/DashWallet/Sources/UI/Views/BaseController/ActionButtonViewController.swift index c8cb190bd..cec9c88c6 100644 --- a/DashWallet/Sources/UI/Views/BaseController/ActionButtonViewController.swift +++ b/DashWallet/Sources/UI/Views/BaseController/ActionButtonViewController.swift @@ -124,8 +124,6 @@ extension ActionButtonViewController { private func configureHierarchy() { view.backgroundColor = .dw_secondaryBackground() - let bottomPadding = deviceSpecificBottomPadding() - stackView = ActionButtonStackView() stackView.translatesAutoresizingMaskIntoConstraints = false stackView.axis = .vertical diff --git a/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.h b/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.h index adce2beae..aa5231fcd 100644 --- a/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.h +++ b/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.h @@ -29,6 +29,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)showActivityIndicator; - (void)hideActivityIndicator; +// NOTE: Internal usage only! +- (void)resetAppearance; + @end @interface DWTintedButton : DWActionButton diff --git a/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.m b/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.m index 7c8b6f588..dd6b4a7bb 100644 --- a/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.m +++ b/DashWallet/Sources/UI/Views/SharedViews/Buttons/DWActionButton.m @@ -50,8 +50,9 @@ - (instancetype)initWithFrame:(CGRect)frame { - (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection { [super traitCollectionDidChange:previousTraitCollection]; - - [self resetAppearance]; + if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass) || (self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) { + [self resetAppearance]; + } } - (void)setUsedOnDarkBackground:(BOOL)usedOnDarkBackground { @@ -146,6 +147,8 @@ - (void)setup_ActionButton { BOOL dark = self.usedOnDarkBackground; BOOL inverted = self.inverted; + + self.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 14.0); } - (void)resetAppearance { @@ -193,7 +196,6 @@ - (void)resetAppearance { [self setBorderColor:color forState:UIControlStateDisabled]; self.tintColor = self.accentColor; - self.imageEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 14.0); } #pragma mark - Styles diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index 9088cefb8..88f854451 100644 Binary files a/DashWallet/bg.lproj/Localizable.strings and b/DashWallet/bg.lproj/Localizable.strings differ diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index 7d83ec036..ccf07dcda 100644 Binary files a/DashWallet/cs.lproj/Localizable.strings and b/DashWallet/cs.lproj/Localizable.strings differ diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index f21477816..e5c727fd1 100644 Binary files a/DashWallet/de.lproj/Localizable.strings and b/DashWallet/de.lproj/Localizable.strings differ diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index f18e214fa..5c9969b47 100644 Binary files a/DashWallet/el.lproj/Localizable.strings and b/DashWallet/el.lproj/Localizable.strings differ diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index e262f7a1f..577ee3084 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -362,7 +362,7 @@ "Copy Logs" = "Copy Logs"; /* No comment provided by engineer. */ -"Copyright © 2022 Dash Core" = "Copyright © 2022 Dash Core"; +"Copyright © 2023 Dash Core" = "Copyright © 2023 Dash Core"; /* No comment provided by engineer. */ "Could not automatically recover missing or incorrect words" = "Could not automatically recover missing or incorrect words"; @@ -906,6 +906,9 @@ /* No comment provided by engineer. */ "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash." = "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash."; +/* Fiat amount */ +"Not available" = "Not available"; + /* Location Service Status */ "Not Determined" = "Not Determined"; @@ -1520,9 +1523,6 @@ /* No comment provided by engineer. */ "Validating username…" = "Validating username…"; -/* Coinbase */ -"Verfiy" = "Verfiy"; - /* No comment provided by engineer. */ "Verified Successfully" = "Verified Successfully"; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index 8ea357ad3..7ecd94f00 100644 Binary files a/DashWallet/es.lproj/Localizable.strings and b/DashWallet/es.lproj/Localizable.strings differ diff --git a/DashWallet/explore.db b/DashWallet/explore.db index dec48ec2e..9495801ee 100644 Binary files a/DashWallet/explore.db and b/DashWallet/explore.db differ diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index e5f4129c4..913fc40ec 100644 Binary files a/DashWallet/fr.lproj/Localizable.strings and b/DashWallet/fr.lproj/Localizable.strings differ diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index c45a763e3..2d359d83f 100644 Binary files a/DashWallet/id.lproj/Localizable.strings and b/DashWallet/id.lproj/Localizable.strings differ diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index 64340e5aa..99be04a43 100644 Binary files a/DashWallet/it.lproj/Localizable.strings and b/DashWallet/it.lproj/Localizable.strings differ diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index 366df7bef..3994dce07 100644 Binary files a/DashWallet/ja.lproj/Localizable.strings and b/DashWallet/ja.lproj/Localizable.strings differ diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index f9c8c7928..aaeba29b2 100644 Binary files a/DashWallet/ko.lproj/Localizable.strings and b/DashWallet/ko.lproj/Localizable.strings differ diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index 3babf9818..0c3668aed 100644 Binary files a/DashWallet/nl.lproj/Localizable.strings and b/DashWallet/nl.lproj/Localizable.strings differ diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index e2e6959d9..88386848a 100644 Binary files a/DashWallet/pl.lproj/Localizable.strings and b/DashWallet/pl.lproj/Localizable.strings differ diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index a1922f0bb..90756d7ef 100644 Binary files a/DashWallet/pt.lproj/Localizable.strings and b/DashWallet/pt.lproj/Localizable.strings differ diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index f9f3ca6b5..45d4aebbe 100644 Binary files a/DashWallet/ru.lproj/Localizable.strings and b/DashWallet/ru.lproj/Localizable.strings differ diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 587e9ab15..637fdde7f 100644 Binary files a/DashWallet/sk.lproj/Localizable.strings and b/DashWallet/sk.lproj/Localizable.strings differ diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index 7d07fb136..c77b74633 100644 Binary files a/DashWallet/sq.lproj/Localizable.strings and b/DashWallet/sq.lproj/Localizable.strings differ diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index 49cde423b..4b228731f 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -362,7 +362,7 @@ "Copy Logs" = "Kopiera Loggar"; /* No comment provided by engineer. */ -"Copyright © 2022 Dash Core" = "Copyright © 2022 Dash Core"; +"Copyright © 2023 Dash Core" = "Copyright © 2023 Dash Core"; /* No comment provided by engineer. */ "Could not automatically recover missing or incorrect words" = "Could not automatically recover missing or incorrect words"; @@ -906,6 +906,9 @@ /* No comment provided by engineer. */ "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash." = "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash."; +/* Fiat amount */ +"Not available" = "Not available"; + /* Location Service Status */ "Not Determined" = "Not Determined"; @@ -1520,9 +1523,6 @@ /* No comment provided by engineer. */ "Validating username…" = "Validating username…"; -/* Coinbase */ -"Verfiy" = "Verfiy"; - /* No comment provided by engineer. */ "Verified Successfully" = "Verified Successfully"; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index d076b56fc..c1a983e90 100644 Binary files a/DashWallet/th.lproj/Localizable.strings and b/DashWallet/th.lproj/Localizable.strings differ diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 9aa316d0b..8611585e0 100644 Binary files a/DashWallet/tr.lproj/Localizable.strings and b/DashWallet/tr.lproj/Localizable.strings differ diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index b0870274e..aa2993b80 100644 Binary files a/DashWallet/uk.lproj/Localizable.strings and b/DashWallet/uk.lproj/Localizable.strings differ diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index f91b2c39f..d8897733d 100644 Binary files a/DashWallet/vi.lproj/Localizable.strings and b/DashWallet/vi.lproj/Localizable.strings differ diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index 925c69102..f25dae3d7 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -362,7 +362,7 @@ "Copy Logs" = "Copy Logs"; /* No comment provided by engineer. */ -"Copyright © 2022 Dash Core" = "Copyright © 2022 Dash Core"; +"Copyright © 2023 Dash Core" = "Copyright © 2023 Dash Core"; /* No comment provided by engineer. */ "Could not automatically recover missing or incorrect words" = "Could not automatically recover missing or incorrect words"; @@ -906,6 +906,9 @@ /* No comment provided by engineer. */ "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash." = "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash."; +/* Fiat amount */ +"Not available" = "Not available"; + /* Location Service Status */ "Not Determined" = "Not Determined"; @@ -1520,9 +1523,6 @@ /* No comment provided by engineer. */ "Validating username…" = "Validating username…"; -/* Coinbase */ -"Verfiy" = "Verfiy"; - /* No comment provided by engineer. */ "Verified Successfully" = "Verified Successfully"; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index 2ed2beea1..c36965a85 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -362,7 +362,7 @@ "Copy Logs" = "Copy Logs"; /* No comment provided by engineer. */ -"Copyright © 2022 Dash Core" = "Copyright © 2022 Dash Core"; +"Copyright © 2023 Dash Core" = "Copyright © 2023 Dash Core"; /* No comment provided by engineer. */ "Could not automatically recover missing or incorrect words" = "Could not automatically recover missing or incorrect words"; @@ -906,6 +906,9 @@ /* No comment provided by engineer. */ "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash." = "Not all of the stores accept DASH directly, but you can buy a gift card with your Dash."; +/* Fiat amount */ +"Not available" = "Not available"; + /* Location Service Status */ "Not Determined" = "Not Determined"; @@ -1520,9 +1523,6 @@ /* No comment provided by engineer. */ "Validating username…" = "Validating username…"; -/* Coinbase */ -"Verfiy" = "Verfiy"; - /* No comment provided by engineer. */ "Verified Successfully" = "Verified Successfully"; diff --git a/DashWalletTests/AmountObjectTests.swift b/DashWalletTests/AmountObjectTests.swift index 4ff2a2429..e85efc3ee 100644 --- a/DashWalletTests/AmountObjectTests.swift +++ b/DashWalletTests/AmountObjectTests.swift @@ -18,9 +18,42 @@ import XCTest @testable import dashwallet +// MARK: - MockRatesProvider + +class MockRatesProvider: RatesProvider { + var updateHandler: (([DSCurrencyPriceObject]) -> Void)? + + func startExchangeRateFetching() { + if let path = Bundle(for: Self.self).path(forResource: "rates", ofType: "json") { + do { + let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) + let rates = try JSONDecoder().decode(BaseDataResponse.self, from: data).data.rates! + + var array: [DSCurrencyPriceObject] = [] + array.reserveCapacity(rates.count) + + for rate in rates { + let key = rate.key + let price = Decimal(string: rate.value)! as NSNumber + array.append(DSCurrencyPriceObject(code: key, name: key, price: price)!) + } + + updateHandler?(array) + } catch { + fatalError("Cannot read json") + } + } + } +} + +// MARK: - AmountObjectTests + final class AmountObjectTests: XCTestCase { + private var currencyExchanger = CurrencyExchanger(dataProvider: MockRatesProvider()) + override func setUpWithError() throws { + currencyExchanger.startExchangeRateFetching() // Put setup code here. This method is called before the invocation of each test method in the class. } @@ -36,6 +69,103 @@ final class AmountObjectTests: XCTestCase { } } -} + func testRetrieveLocalAmount() { + let inputFormats: [String] = [ + "0%@0", + "3%@", + "4%@0", + "56%@00", + "123%@45", + "34%@70", + ] + + let weirdLocaleIdentifiers: Set = ["fr_CH", "kea_CV", "pt_CV", "en_CV"] + + for item in Locale.availableIdentifiers { + if weirdLocaleIdentifiers.contains(item) { continue } + + let locale = Locale(identifier: item) + if locale.isNonArabicDigitsLocale { continue } + guard let currencyCode = locale.currencyCode else { continue } + + for inputFormat in inputFormats { + let input = String(format: inputFormat, locale.decimalSeparator!) + let inputNumber = Decimal(string: input, locale: locale)! + + let mainAmount = AmountObject(plainAmount: inputNumber.plainDashAmount, + fiatCurrencyCode: currencyCode, + localFormatter: NumberFormatter.fiatFormatter(currencyCode: currencyCode), + currencyExchanger: currencyExchanger) + XCTAssert(mainAmount.localAmount.plainAmount == mainAmount.plainAmount) + } + } + } + func testRetrieveDashAmount() { + let inputFormats: [String] = [ + "0%@0", + "3%@", + "4%@0", + "56%@00", + "123%@45", + "34%@70", + "3412323234%@70", + ] + let weirdLocaleIdentifiers: Set = ["fr_CH", "kea_CV", "pt_CV", "en_CV"] + + for item in Locale.availableIdentifiers { + if weirdLocaleIdentifiers.contains(item) { continue } + + let locale = Locale(identifier: item) + if locale.isNonArabicDigitsLocale { continue } + guard let currencyCode = locale.currencyCode else { continue } + + let localFormatter = NumberFormatter.fiatFormatter(currencyCode: currencyCode) + for inputFormat in inputFormats { + let input = String(format: inputFormat, locale.decimalSeparator!) + let inputNumber = Decimal(string: input, locale: locale)! + + let amount = AmountObject(plainAmount: inputNumber.plainDashAmount, + fiatCurrencyCode: currencyCode, + localFormatter: localFormatter, + currencyExchanger: currencyExchanger) + + let numberFormatter = localFormatter.copy() as! NumberFormatter + numberFormatter.numberStyle = .none + numberFormatter.minimumFractionDigits = localFormatter.minimumFractionDigits + numberFormatter.maximumFractionDigits = localFormatter.maximumFractionDigits + let inputValue = numberFormatter.string(from: amount.supplementaryAmount as NSDecimalNumber)! + + XCTAssert(amount.localAmount.amountInternalRepresentation == inputValue) + } + } + } + + func testSwapingFromMainToLocal() { + let numbers = ["1234.43"] + let currencyCode = "USD" + + for (i, item) in numbers.enumerated() { + let localFormatter = NumberFormatter.fiatFormatter(currencyCode: currencyCode) + + let amount = AmountObject(dashAmountString: item, + fiatCurrencyCode: currencyCode, + localFormatter: localFormatter, + currencyExchanger: currencyExchanger) + + XCTAssert(amount.plainAmount == Decimal(string: item)!.plainDashAmount) + + let localAmount = amount.localAmount + XCTAssert(amount.plainAmount == localAmount.plainAmount) + + let numberFormatter = localFormatter.copy() as! NumberFormatter + numberFormatter.numberStyle = .none + numberFormatter.minimumFractionDigits = localFormatter.minimumFractionDigits + numberFormatter.maximumFractionDigits = localFormatter.maximumFractionDigits + let input = numberFormatter.string(from: amount.supplementaryAmount as NSDecimalNumber)! + + XCTAssert(localAmount.amountInternalRepresentation == input) + } + } +} diff --git a/DashWalletTests/rates.json b/DashWalletTests/rates.json new file mode 100644 index 000000000..45e6fe743 --- /dev/null +++ b/DashWalletTests/rates.json @@ -0,0 +1 @@ +{"data":{"currency":"USD","rates":{"AED":"3.67298833331367","AFN":"90.002219","ALL":"108.2425629402191856","AMD":"396.6013438959404614","ANG":"1.7943210437982055","AOA":"504.3178","ARS":"189.5214998777596852","AWG":"1.8025","AZN":"1.6999999999999999","BAM":"1.8231760376429676","BBD":"2","BDT":"106.4968221816656379","BGN":"1.818905","BHD":"0.3769259998302054","BIF":"2071.4224267054227698","BMD":"1","BND":"1.3237949841176315","BOB":"6.9174480283790008","BRL":"5.210666666666666","BSD":"1","BTN":"82.643828","BWP":"12.9616094934892156","BYN":"2.5190889999999998","BYR":"25190.8999999731064471","BZD":"2.0128163280218717","CAD":"1.3378499945681649","CDF":"2058.435238","CHF":"0.9189593321135948","CLF":"0.0288270999996531","CLP":"794.6625372099690233","CNY":"6.7806599357584654","COP":"4747.5606276666666667","CRC":"574.1382009105623073","CUC":"1","CVE":"102.8793985","CZK":"22.129935","DJF":"177.6927143188012388","DKK":"6.9246499778656772","DOP":"56.3780145711897739","DZD":"136.4912999937964307","EGP":"30.352999988139531","ETB":"53.6282856666666542","EUR":"0.9304112737019323","FJD":"2.18686","FKP":"0.8271883578201767","GBP":"0.8271922387921436","GEL":"2.65","GHS":"12.182123754892678","GIP":"0.8271884546545822","GMD":"61.036049999999851","GNF":"8643.9565395389422656","GTQ":"7.8406713333333329","GYD":"210.8899968473398366","HKD":"7.8493666666666667","HNL":"24.6029969984226006","HRK":"7.0091433157218121","HTG":"150.3236933951202343","HUF":"362.7804282984118222","IDR":"15106.221431369182516","ILS":"3.4697674999999994","INR":"82.6063993333336034","IQD":"1456.5924279959419227","ISK":"141.5200000000006533","JMD":"154.3261520000007655","JOD":"0.7092666666666667","JPY":"130.9396363617765165","KES":"124.9166622198509185","KGS":"86.7636000000003079","KHR":"4091.8706505","KMF":"458.0563065","KRW":"1262.0948368442667386","KWD":"0.3055786661423291","KYD":"0.8325135","KZT":"455.3884676666729953","LAK":"16822.1089704009978752","LBP":"1515.250000000043071","LKR":"365.1361663333333333","LRD":"157.0960029999990297","LSL":"17.5721785435565338","LYD":"4.7753674999986904","MAD":"10.258420000000002","MDL":"18.8331956349026023","MGA":"4286.8044013333333333","MKD":"57.3147403538888468","MMK":"2097.0557567387024009","MNT":"3456.9826325005435995","MOP":"8.0763298828045714","MRO":"355.1019999999944591","MUR":"45.3463315000000339","MVR":"15.3657837535305651","MWK":"1024.400197","MXN":"18.8830066666666797","MYR":"4.2989199985112534","MZN":"63.8649813183669006","NAD":"17.5616543956450815","NGN":"459.8097432323506367","NIO":"36.4671164998088337","NOK":"10.2565276666666631","NPR":"132.1104253333333333","NZD":"1.5789156666666667","OMR":"0.3849615","PAB":"1","PEN":"3.8390046404731098","PGK":"3.5197445","PHP":"54.8016673333334802","PKR":"273.6022333333313221","PLN":"4.4125083433108395","PYG":"7302.437243","QAR":"3.6425","RON":"4.5578999999999997","RSD":"109.1978495704282373","RUB":"71.5316582358624342","RWF":"1081.14270299322956","SAR":"3.7511212928506848","SBD":"8.197271","SCR":"13.1405484982533138","SDG":"585.4999999999934424","SEK":"10.5413387983101386","SHP":"0.8271883581882155","SKK":"28.0299","SLL":"18645","SOS":"567.928793108923373","SRD":"32.2504495162083038","STD":"22924.1537473422569811","SVC":"8.7413705","SZL":"17.5716558476524299","THB":"33.508","TJS":"10.3083616954747243","TMT":"3.51","TND":"3.1046589095102197","TOP":"2.337135","TRY":"18.8339619954503201","TTD":"6.7766535000000002","TWD":"30.0537","TZS":"2337.3399505417852387","UAH":"36.7126773333333333","UGX":"3672.463108666592195","UYU":"39.2040166679066733","UZS":"11327.632816","VES":"23.2722206091180785","VND":"23600.4025419821785919","VUV":"115.5399868503000828","WST":"2.6961","XAF":"611.6424596666722265","XAG":"0.0445757347196631","XAU":"0.0005314539598912","XCD":"2.7012749999999999","XOF":"610.6254740975403442","XPD":"0.0005976725","XPF":"111.0282619950947963","XPT":"0.0010116291450431","YER":"250.1962913333333333","ZAR":"17.5311261678211963","ZMK":"5252.5500000001038954","ZMW":"19.1807401341893697","JEP":"0.8271884550267176","GGP":"0.8271884550267176","IMP":"0.8271884550267176","GBX":"719.0933670827820284","CNH":"6.7891854610100111","EEK":"14.5579999999999968","LTL":"3.2125599999999997","LVL":"0.653905","TMM":"17549.99999998674975","ZWD":"374.7999999999952925","VEF":"2311980","SGD":"1.3238870000000001","AUD":"1.4324116666666668","USD":"1.0","BTC":"0.0000431330464698","BCH":"0.0074388157405341","BSV":"0.0237428177976162","ETH":"0.0005983974915177","ETH2":"0.0005983974915177","ETC":"0.0436395374209033","LTC":"0.0098960910440376","ZRX":"3.9164618683481343","USDC":"1","BAT":"3.2356176794150003","LOOM":"18.1323662737987307","MANA":"1.2699218998031621","KNC":"1.0983579548574881","LINK":"0.1391497947540527","DNT":"20.8116545265348595","MKR":"0.0013001196110042","CVC":"7.9554494828957836","OMG":"0.6019744762822056","GNT":"5.3740003284589001","DAI":"1.0005503026664666","SNT":"32.7707684745207275","ZEC":"0.021713169037021","XRP":"2.49655375719357","REP":"0.1115448968209704","XLM":"10.9387049667189901","EOS":"0.9074410163339383","XTZ":"0.8176614881439084","ALGO":"3.5511363636363636","DASH":"0.0153527289475704","ATOM":"0.0674604513104193","OXT":"9.9255583126550868","COMP":"0.0174962820400665","ENJ":"1.9474196689386563","REPV2":"0.1115448968209704","BAND":"0.4408199250606127","NMR":"0.0430663221360896","CGLD":"1.2430080795525171","UMA":"0.462000462000462","LRC":"2.5833118057349522","YFI":"0.0001287132982075","UNI":"0.1446968600781363","BAL":"0.1427551748750892","REN":"9.9950024987506247","WBTC":"0.0000431584008259","NU":"5.9642042773364532","YFII":"0.0007487944409501","FIL":"0.1811266074986416","AAVE":"0.0112841345068833","BNT":"2.0751193193608632","GRT":"5.4333061668024993","SNX":"0.353356890459364","STORJ":"2.021018593371059","SUSHI":"0.6749232274828738","MATIC":"0.7838833581563063","SKL":"23.6127508854781582","ADA":"2.5144581342720644","ANKR":"31.3234142521534847","CRV":"0.8963384574015148","ICP":"0.1722801274872943","NKN":"8.2474226804123711","OGN":"6.8406471252180456","1INCH":"1.7421602787456446","USDT":"0.9999450030248336","FORTH":"0.2509410288582183","CTSI":"5.6721497447532615","TRB":"0.0518941359626362","POLY":"5.0543340914834471","MIR":"5.7786766830395839","RLC":"0.4546487838145033","DOT":"0.1456664238892935","SOL":"0.0424448217317487","DOGE":"10.9331438255070245","MLN":"0.0389483933787731","GTC":"0.4750593824228029","AMP":"191.0219675262655205","SHIB":"70871.7221828490432318","CHZ":"5.6963827969239533","KEEP":"4.6537602382725242","LPT":"0.099601593625498","QNT":"0.0071942446043165","BOND":"0.2127659574468085","RLY":"82.987551867219917","CLV":"12.4300807955251709","FARM":"0.0252429635239177","MASK":"0.2207505518763797","ANT":"0.3344481605351171","FET":"1.9594396002743215","PAX":"1.0038648797871806","ACH":"55.384785799340921","ASM":"68.3760683760683761","PLA":"3.7098868484511222","RAI":"0.3610108303249097","TRIBE":"3.9062307740204091","ORN":"0.9935419771485345","IOTX":"26.3261813873897591","UST":"32.7385824193812408","QUICK":"0.0170532060027285","AXS":"0.085726532361766","REQ":"8.7221979938944614","WLUNA":"5392.2890266918306821","TRU":"20.4081632653061224","RAD":"0.4819277108433735","COTI":"9.8522167487684729","DDX":"2.2106775726760252","SUKU":"12.3152709359605911","RGT":"2.396499045372943","XYO":"142.5516749821810406","ZEN":"0.0866551126516464","AST":"8.4925690021231423","AUCTION":"0.1596169193934557","BUSD":"1","JASMY":"128.0409731113956466","WCFG":"3.4129692832764505","BTRST":"0.9111617312072893","AGLD":"1.9247425656818401","AVAX":"0.0488878024932779","FX":"4.5085662759242561","TRAC":"2.5053238131028435","LCX":"8.5324232081911263","ARPA":"22.5479143179255919","BADGER":"0.3048780487804878","KRL":"3.1476235442241108","PERP":"1.4580447619741926","RARI":"0.4329004329004329","DESO":"0.1071237279057311","API3":"0.5372011818426001","NCT":"88.9679715302491103","SHPING":"177.0538243626062323","UPI":"366.282924256354093","CRO":"12.0336943441636582","MTL":"0.8932559178204556","ABT":"6.3512226103524929","CVX":"0.1529168896704641","AVT":"0.7407407407407407","MDT":"16.2985901719501263","VGX":"2.0050125313283208","ALCX":"0.0461254612546125","COVAL":"80.224628961091055","FOX":"26.3504611330698287","MUSD":"1.0054616002968236","CELR":"52.4246395806028834","GALA":"18.5632077222944125","POWR":"4.8019207683073229","GYEN":"131.2594342718382884","ALICE":"0.4738213693437574","INV":"0.0160578081091931","LQTY":"1.422475106685633","PRO":"2.0253164556962025","SPELL":"1178.0644401248748307","ENS":"0.0634316523945449","DIA":"2.4154589371980676","BLZ":"8.1433224755700326","CTX":"0.3929273084479371","ERN":"0.4175365344467641","IDEX":"17.421602787456446","MCO2":"0.5167958656330749","POLS":"2.1157304559399133","SUPER":"6.87616035205941","UNFI":"0.1626016260162602","STX":"3.1318509238960225","KSM":"0.0274536719286205","GODS":"3.2091396296652867","IMX":"0.8982708286548394","RBN":"3.7702414839670481","BICO":"2.4734108335394509","GFI":"1.5046644598254589","ATA":"5.6353902507748662","GLM":"3.7850113550340651","MPL":"0.1291989664082687","PLU":"0.101010101010101","SWFTC":"671.8172657037285858","SAND":"1.1144544745347153","OCEAN":"1.9646365422396857","GNO":"0.0080486136263029","FIDA":"2.2150847269908074","ORCA":"1.0874884454352673","CRPT":"7.4321813452248235","QSP":"61.3685179502915005","RNDR":"0.5181615627752733","NEST":"39.7219463753723932","PRQ":"5.9171597633136095","HOPR":"16.0384923817161187","JUP":"172.4732666436702311","MATH":"7.6452599388379205","SYN":"0.7961783439490446","AIOZ":"24.4498777506112469","WAMPL":"0.1579778830963665","AERGO":"6.7980965329707682","INDEX":"0.5633802816901408","TONE":"57.620282339383463","HIGH":"0.2374450908227472","GUSD":"1.0005002501250625","FLOW":"0.819672131147541","ROSE":"13.9528394028184736","OP":"0.3377237419790611","APE":"0.1699668564629897","MINA":"1.1918951132300358","MUSE":"0.1453382748346777","SYLO":"407.4149521287431249","CBETH":"0.0005925855693562","DREP":"2.4579083200196633","ELA":"0.7846214201647705","FORT":"6.3918184723553851","ALEPH":"13.0378096479791395","DEXT":"4.5454545454545455","FIS":"1.3362731342286363","BIT":"1.6701461377870564","GMT":"1.8811136192626035","GST":"44.1062961737788069","MEDIA":"0.0822368421052632","C98":"3.5329447094152977","00":"6.4683053040103493","APT":"0.0633312222925902","AUDIO":"3.2056419297964417","AURORA":"3.8095238095238095","AXL":"1.0623605651758207","BOBA":"3.5448422545196739","DAR":"4.0160642570281124","DYP":"3.7911098474078286","EGLD":"0.0213766566908935","GAL":"0.4008819402685909","GHST":"0.8896797153024911","HBAR":"13.4671065921486769","HFT":"1.7525411847178409","ILV":"0.0106275572559647","INJ":"0.2468526289804986","KAVA":"0.9732833714535987","LDO":"0.3946329913180742","LIT":"0.9222965183306433","LOKA":"1.2643823492224049","MAGIC":"0.5141916906622789","METIS":"0.0279017857142857","MNDE":"15.4511742892459827","MONA":"0.0018808305747818","MSOL":"0.0388575869438508","MXC":"32.4254215304798962","NEAR":"0.3930817610062893","OOKI":"211.5730455939913255","PNG":"17.7588350204226603","POND":"87.8348704435660957","PUNDIX":"2.0008003201280512","PYR":"0.2266032177656923","QI":"98.7898246480612497","RARE":"6.1068702290076336","RPL":"0.02426301103967","STG":"1.1887072808320951","T":"22.6090888537191951","TIME":"0.0178348492955235","WAXL":"1.068319000053416","XCN":"89.7666068222621185","XMON":"0.0000518096173008"}}} \ No newline at end of file diff --git a/Podfile b/Podfile index 0407a2c50..fd1c8c43d 100644 --- a/Podfile +++ b/Podfile @@ -1,5 +1,7 @@ +inhibit_all_warnings! + target 'dashwallet' do - platform :ios, '13.0' + platform :ios, '14.0' pod 'DashSync', :path => '../DashSync/' pod 'SQLite.swift', '~> 0.13.3' @@ -16,7 +18,7 @@ target 'dashwallet' do pod 'SDWebImage', '5.13.2' pod 'Moya', '~> 15.0' # Debugging purposes -# pod 'Reveal-SDK', :configurations => ['Debug'] + # pod 'Reveal-SDK', :configurations => ['Debug'] target 'DashWalletTests' do inherit! :search_paths @@ -36,46 +38,41 @@ target 'TodayExtension' do end target 'WatchApp' do - platform :watchos, '2.0' + platform :watchos, '4.0' end target 'WatchApp Extension' do - platform :watchos, '2.0' + platform :watchos, '4.0' end post_install do |installer| - installer.pods_project.targets.each do |target| - # fixes warnings about unsupported Deployment Target in Xcode 10 - if ["BoringSSL-GRPC", "abseil", "gRPC", "gRPC-Core", "gRPC-RxLibrary", "gRPC-ProtoRPC", "Protobuf", "DSJSONSchemaValidation", "!ProtoCompiler", "!ProtoCompiler-gRPCPlugin", "gRPC-gRPCCertificates", "UIViewController-KeyboardAdditions", "MMSegmentSlider", "MBProgressHUD", "KVO-MVVM", "CocoaLumberjack"].include? target.name - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0' - end - end - - # Hide warnings for specific pods - if ["gRPC"].include? target.name - target.build_configurations.each do |config| - config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES' - end - end - - # temporary solution to work with gRPC-Core - # see https://github.com/CocoaPods/CocoaPods/issues/8474 - if target.name == 'secp256k1_dash' - target.build_configurations.each do |config| - config.build_settings['HEADER_SEARCH_PATHS'] = '"${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/secp256k1_dash" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/secp256k1_dash" "${PODS_ROOT}/secp256k1_dash"' - end - end - if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" - target.build_configurations.each do |config| - config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' - end - end + installer.pods_project.targets.each do |target| + + # fixes warnings about unsupported Deployment Target in Xcode + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0' + + end + + # Hide warnings for specific pods + if ["gRPC"].include? target.name + target.build_configurations.each do |config| + config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES' + end + end + + # temporary solution to work with gRPC-Core + # see https://github.com/CocoaPods/CocoaPods/issues/8474 + if target.name == 'secp256k1_dash' + target.build_configurations.each do |config| + config.build_settings['HEADER_SEARCH_PATHS'] = '"${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/secp256k1_dash" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/secp256k1_dash" "${PODS_ROOT}/secp256k1_dash"' + end end - - # update info about current DashSync version - # the command runs in the background after 1 sec, when `pod install` updates Podfile.lock - system("(sleep 1; sh ./scripts/dashsync_version.sh) &") + end + + # update info about current DashSync version + # the command runs in the background after 1 sec, when `pod install` updates Podfile.lock + system("(sleep 1; sh ./scripts/dashsync_version.sh) &") end