From 524780133e686941a378c4f1b6747d172c95e7d0 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Sun, 29 Jun 2025 14:35:18 +0700 Subject: [PATCH] feat: piggycards terms --- DashWallet.xcodeproj/project.pbxproj | 54 ++++++++------ .../piggycards.logo.imageset/Contents.json | 23 ++++++ .../piggycards.logo.imageset/PiggyCards.png | Bin 0 -> 2722 bytes .../PiggyCards@2x.png | Bin 0 -> 5217 bytes .../PiggyCards@3x.png | Bin 0 -> 7786 bytes .../Explore Dash/Model/CTXConstants.swift | 2 +- .../Explore Dash/Model/GiftCardProvider.swift | 69 ++++++++++++++++++ .../Models/Uphold/DWUpholdMainnetConstants.m | 1 + .../DashPay/Voting/UsernameVoting.storyboard | 2 +- .../PointOfUseDetailsViewController.swift | 37 +++++----- .../Details/Views/PointOfUseDetailsView.swift | 47 ++++++++++-- .../Views/DashSpend/CTXSpendTermsScreen.swift | 7 +- .../DashSpend/CTXSpendUserAuthScreen.swift | 10 +-- ...iew.swift => DashSpendLoginInfoView.swift} | 8 +- .../Views/DashSpend/DashSpendPayScreen.swift | 6 +- .../DashSpend/DashSpendPayViewModel.swift | 14 ++-- ...swift => DashSpendUserAuthViewModel.swift} | 8 +- 17 files changed, 217 insertions(+), 71 deletions(-) create mode 100644 DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/Contents.json create mode 100644 DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards.png create mode 100644 DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards@2x.png create mode 100644 DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards@3x.png create mode 100644 DashWallet/Sources/Models/Explore Dash/Model/GiftCardProvider.swift rename DashWallet/Sources/UI/Explore Dash/Views/DashSpend/{CTXSpendLoginInfoView.swift => DashSpendLoginInfoView.swift} (92%) rename DashWallet/Sources/UI/Explore Dash/Views/DashSpend/{CTXSpendUserAuthViewModel.swift => DashSpendUserAuthViewModel.swift} (92%) diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index 20db4c830..7400bc699 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -574,8 +574,8 @@ 754565D22DABA5F300DA4E8E /* MerchantTypesDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754565D02DABA5EB00DA4E8E /* MerchantTypesDialog.swift */; }; 7545ED532DA91A2F0075F45C /* CTXConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED522DA91A2F0075F45C /* CTXConstants.swift */; }; 7545ED542DA91A2F0075F45C /* CTXConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED522DA91A2F0075F45C /* CTXConstants.swift */; }; - 7545ED572DA91AF10075F45C /* CTXSpendUserAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED562DA91AEA0075F45C /* CTXSpendUserAuthViewModel.swift */; }; - 7545ED582DA91AF10075F45C /* CTXSpendUserAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED562DA91AEA0075F45C /* CTXSpendUserAuthViewModel.swift */; }; + 7545ED572DA91AF10075F45C /* DashSpendUserAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED562DA91AEA0075F45C /* DashSpendUserAuthViewModel.swift */; }; + 7545ED582DA91AF10075F45C /* DashSpendUserAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED562DA91AEA0075F45C /* DashSpendUserAuthViewModel.swift */; }; 7545ED5D2DA91F590075F45C /* CTXSpendTermsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED5C2DA91F590075F45C /* CTXSpendTermsScreen.swift */; }; 7545ED5E2DA91F590075F45C /* CTXSpendTermsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED5C2DA91F590075F45C /* CTXSpendTermsScreen.swift */; }; 7545ED602DA91FC60075F45C /* NumericKeyboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7545ED5F2DA91FC60075F45C /* NumericKeyboardView.swift */; }; @@ -682,6 +682,8 @@ 75A8C1652AE5726B0042256E /* UsernameRequestsDAO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A8C1632AE5725C0042256E /* UsernameRequestsDAO.swift */; }; 75A8C1672AE5734A0042256E /* UsernameRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A8C1662AE5734A0042256E /* UsernameRequest.swift */; }; 75A8C1692AE6A1AC0042256E /* VotingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A8C1682AE6A1AC0042256E /* VotingViewModel.swift */; }; + 75A92B8C2E0FDDA900BFFA2D /* GiftCardProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A92B8B2E0FDDA900BFFA2D /* GiftCardProvider.swift */; }; + 75A92B8D2E0FDDA900BFFA2D /* GiftCardProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75A92B8B2E0FDDA900BFFA2D /* GiftCardProvider.swift */; }; 75AA33CC2BF9C82700F12465 /* ModalDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75AA33CB2BF9C82700F12465 /* ModalDialog.swift */; }; 75AA33CD2BF9C82700F12465 /* ModalDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75AA33CB2BF9C82700F12465 /* ModalDialog.swift */; }; 75AA33CF2BF9D44A00F12465 /* ButtonsGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75AA33CE2BF9D44A00F12465 /* ButtonsGroup.swift */; }; @@ -699,9 +701,9 @@ 75C1F0462AE26AC0006929CA /* CoinJoinLevelsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C1F0442AE26AC0006929CA /* CoinJoinLevelsViewModel.swift */; }; 75C1F09E2AFF675400FE675E /* EnterVotingKeyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C1F09D2AFF675400FE675E /* EnterVotingKeyViewController.swift */; }; 75C3EE002DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFE2DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift */; }; - 75C3EE022DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFD2DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift */; }; + 75C3EE022DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFD2DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift */; }; 75C3EE032DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFE2DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift */; }; - 75C3EE052DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFD2DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift */; }; + 75C3EE052DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C3EDFD2DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift */; }; 75CDD7802C0898E400F433D2 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CDD77F2C0898E400F433D2 /* Shape.swift */; }; 75CDD7812C0898E400F433D2 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CDD77F2C0898E400F433D2 /* Shape.swift */; }; 75CDD7832C0898FA00F433D2 /* Wrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CDD7822C0898FA00F433D2 /* Wrapper.swift */; }; @@ -2486,7 +2488,7 @@ 754565C72DAA52A000DA4E8E /* CTXSpendService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendService.swift; sourceTree = ""; }; 754565D02DABA5EB00DA4E8E /* MerchantTypesDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MerchantTypesDialog.swift; sourceTree = ""; }; 7545ED522DA91A2F0075F45C /* CTXConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXConstants.swift; sourceTree = ""; }; - 7545ED562DA91AEA0075F45C /* CTXSpendUserAuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendUserAuthViewModel.swift; sourceTree = ""; }; + 7545ED562DA91AEA0075F45C /* DashSpendUserAuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSpendUserAuthViewModel.swift; sourceTree = ""; }; 7545ED5C2DA91F590075F45C /* CTXSpendTermsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendTermsScreen.swift; sourceTree = ""; }; 7545ED5F2DA91FC60075F45C /* NumericKeyboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumericKeyboardView.swift; sourceTree = ""; }; 7549BE522DEAEA14004F0BAF /* MetadataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetadataProvider.swift; sourceTree = ""; }; @@ -2557,6 +2559,7 @@ 75A8C1632AE5725C0042256E /* UsernameRequestsDAO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsernameRequestsDAO.swift; sourceTree = ""; }; 75A8C1662AE5734A0042256E /* UsernameRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsernameRequest.swift; sourceTree = ""; }; 75A8C1682AE6A1AC0042256E /* VotingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VotingViewModel.swift; sourceTree = ""; }; + 75A92B8B2E0FDDA900BFFA2D /* GiftCardProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftCardProvider.swift; sourceTree = ""; }; 75AA33CB2BF9C82700F12465 /* ModalDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalDialog.swift; sourceTree = ""; }; 75AA33CE2BF9D44A00F12465 /* ButtonsGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonsGroup.swift; sourceTree = ""; }; 75AA33D12BF9E18E00F12465 /* Color+DWStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+DWStyle.swift"; sourceTree = ""; }; @@ -2565,7 +2568,7 @@ 75BDE7AB2BF3287400556791 /* Toast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = ""; }; 75C1F0442AE26AC0006929CA /* CoinJoinLevelsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinJoinLevelsViewModel.swift; sourceTree = ""; }; 75C1F09D2AFF675400FE675E /* EnterVotingKeyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterVotingKeyViewController.swift; sourceTree = ""; }; - 75C3EDFD2DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendLoginInfoView.swift; sourceTree = ""; }; + 75C3EDFD2DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashSpendLoginInfoView.swift; sourceTree = ""; }; 75C3EDFE2DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTXSpendUserAuthScreen.swift; sourceTree = ""; }; 75CDD77F2C0898E400F433D2 /* Shape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shape.swift; sourceTree = ""; }; 75CDD7822C0898FA00F433D2 /* Wrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wrapper.swift; sourceTree = ""; }; @@ -5653,6 +5656,7 @@ 47AE8B9628BFACE800490F5E /* Model */ = { isa = PBXGroup; children = ( + 75A92B8B2E0FDDA900BFFA2D /* GiftCardProvider.swift */, 7545ED522DA91A2F0075F45C /* CTXConstants.swift */, 47AE8B9A28BFAD2000490F5E /* Entites */, 47AE8B9928BFAD0B00490F5E /* DAO */, @@ -6088,9 +6092,9 @@ 753F75332DD0D41900D40DFE /* DashSpendPayScreen.swift */, 75EE9F412DE2F74B000AD1AD /* DashSpendConfirmationDialog.swift */, 753F75362DD0D75F00D40DFE /* DashSpendPayViewModel.swift */, - 75C3EDFD2DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift */, + 75C3EDFD2DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift */, 75C3EDFE2DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift */, - 7545ED562DA91AEA0075F45C /* CTXSpendUserAuthViewModel.swift */, + 7545ED562DA91AEA0075F45C /* DashSpendUserAuthViewModel.swift */, 7545ED5C2DA91F590075F45C /* CTXSpendTermsScreen.swift */, ); path = DashSpend; @@ -8635,7 +8639,7 @@ 2A9FFE882230FF4700956D5F /* DWPlaceholderFormCellModel.m in Sources */, 2A8B9E4F22FED47E00FF8653 /* DWOverlapControl.m in Sources */, 119E8D062905200300D406C1 /* CoinsToAddressTxFilter.swift in Sources */, - 7545ED572DA91AF10075F45C /* CTXSpendUserAuthViewModel.swift in Sources */, + 7545ED572DA91AF10075F45C /* DashSpendUserAuthViewModel.swift in Sources */, 2AB3417323A926C9004E37A7 /* DWDemoAppRootViewController.m in Sources */, 2A9FFE9B2230FF4700956D5F /* DWUpholdLogoutTutorialViewController.m in Sources */, 47CF46A529654E190067B6EE /* CBAccount.swift in Sources */, @@ -8853,7 +8857,7 @@ 2AC92C841FEB0A6D008CAEE0 /* DWQRScanViewController.m in Sources */, 2A9FFE802230FF4600956D5F /* DWSelectorFormTableViewCell.m in Sources */, 75C3EE032DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift in Sources */, - 75C3EE052DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift in Sources */, + 75C3EE052DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift in Sources */, 47305872295C971F004641DA /* UIViewController+AlertPresenting.swift in Sources */, 2A858A0F237EE89C0097A7B5 /* DSWatchTransactionDataObject.m in Sources */, 47FA3B0229364991008D58DC /* HTTPClient.swift in Sources */, @@ -8945,6 +8949,7 @@ 753F75352DD0D42300D40DFE /* DashSpendPayScreen.swift in Sources */, 47F005FF297164600029EB10 /* UITableView+DashWallet.swift in Sources */, 47C661B228FDC72700028A8D /* TransferAmountViewController.swift in Sources */, + 75A92B8C2E0FDDA900BFFA2D /* GiftCardProvider.swift in Sources */, C94F5E8E29D404850034FD57 /* ShortcutCell.swift in Sources */, 2A44312122CCA2A0009BAF7F /* UIColor+DWStyle.m in Sources */, FBEF3AF121823CD800917AB6 /* DWEnvironment.m in Sources */, @@ -9378,7 +9383,7 @@ C9D2C7322A320AA000D15901 /* CrowdNode+UserDefaults.swift in Sources */, C9D2C7342A320AA000D15901 /* DWPinView.m in Sources */, C9D2C7362A320AA000D15901 /* DWBaseReceiveModel.m in Sources */, - 7545ED582DA91AF10075F45C /* CTXSpendUserAuthViewModel.swift in Sources */, + 7545ED582DA91AF10075F45C /* DashSpendUserAuthViewModel.swift in Sources */, C943B52E2A40A54600AF23C5 /* DWNotificationsProvider.m in Sources */, C943B4F12A40A54600AF23C5 /* DWUserProfileContactActionsCell.m in Sources */, C9D2C7372A320AA000D15901 /* DWSegmentSlider.m in Sources */, @@ -9654,7 +9659,7 @@ C9D2C7F82A320AA000D15901 /* UIViewController+AlertPresenting.swift in Sources */, C9D2C7F92A320AA000D15901 /* DSWatchTransactionDataObject.m in Sources */, 75C3EE002DA7C63C00A4E9C0 /* CTXSpendUserAuthScreen.swift in Sources */, - 75C3EE022DA7C63C00A4E9C0 /* CTXSpendLoginInfoView.swift in Sources */, + 75C3EE022DA7C63C00A4E9C0 /* DashSpendLoginInfoView.swift in Sources */, C9D2C7FA2A320AA000D15901 /* HTTPClient.swift in Sources */, C956AF0C2A5B591A002FAB75 /* DashInputField.swift in Sources */, C9D2C7FB2A320AA000D15901 /* DWPasteboardAddressExtractor.m in Sources */, @@ -9818,6 +9823,7 @@ C9D2C8762A320AA000D15901 /* DWUpholdMainnetConstants.m in Sources */, C9D2C8792A320AA000D15901 /* Style.swift in Sources */, C9D2C87A2A320AA000D15901 /* PayViewController.swift in Sources */, + 75A92B8D2E0FDDA900BFFA2D /* GiftCardProvider.swift in Sources */, C9D2C87B2A320AA000D15901 /* DatabaseConnection.swift in Sources */, C9D2C87C2A320AA000D15901 /* DWSwitcherFormCellModel.m in Sources */, C9D2C87D2A320AA000D15901 /* DWIntrinsicTextView.m in Sources */, @@ -10407,7 +10413,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -10547,7 +10553,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -10721,7 +10727,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -10743,7 +10749,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -10768,7 +10774,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -10795,7 +10801,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -11535,7 +11541,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -11704,7 +11710,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -11729,7 +11735,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; @@ -11846,7 +11852,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -12013,7 +12019,7 @@ EXCLUDED_ARCHS = ""; IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; @@ -12038,7 +12044,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 8.4.0; + MARKETING_VERSION = 8.5.0; PRODUCT_BUNDLE_IDENTIFIER = org.dashfoundation.dash.watchkitapp.watchkitextension; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; diff --git a/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/Contents.json b/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/Contents.json new file mode 100644 index 000000000..811adf78d --- /dev/null +++ b/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "PiggyCards.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "PiggyCards@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "PiggyCards@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards.png b/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards.png new file mode 100644 index 0000000000000000000000000000000000000000..fbb59a4c7aa9fdfcebec3386664f2ce5731ee984 GIT binary patch literal 2722 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 literal 0 HcmV?d00001 diff --git a/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards@2x.png b/DashWallet/Resources/AppAssets.xcassets/Explore Dash/piggycards.logo.imageset/PiggyCards@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bd4c9a1c4dcb149b44f06c3bd4c8ee2715b8b8ec GIT binary patch literal 5217 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 literal 0 HcmV?d00001 diff --git a/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift b/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift index 98363b9ae..e6addaa27 100644 --- a/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift +++ b/DashWallet/Sources/Models/Explore Dash/Model/CTXConstants.swift @@ -17,6 +17,6 @@ class CTXConstants { static let baseURI = "https://spend.ctx.com/" - static let ctxGiftCardAgreementUrl = "https://ctx.com/gift-card-agreement/" + static let termsAndConditionsUrl = "https://ctx.com/gift-card-agreement/" static let supportEmail = "support@ctx.com" } diff --git a/DashWallet/Sources/Models/Explore Dash/Model/GiftCardProvider.swift b/DashWallet/Sources/Models/Explore Dash/Model/GiftCardProvider.swift new file mode 100644 index 000000000..f117a2abd --- /dev/null +++ b/DashWallet/Sources/Models/Explore Dash/Model/GiftCardProvider.swift @@ -0,0 +1,69 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2025 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +enum GiftCardProvider: CaseIterable { + case ctx + case piggyCards + + var displayName: String { + switch self { + case .ctx: + return "CTXSpend" + case .piggyCards: + return "PiggyCards" + } + } + + var logoName: String { + switch self { + case .ctx: + return "ctx.logo" + case .piggyCards: + return "piggycards.logo" + } + } + + var termsUrl: String { + switch self { + case .ctx: + return CTXConstants.termsAndConditionsUrl + case .piggyCards: + return "https://piggy.cards/index.php?route=information/information&information_id=5" + } + } + + var supportEmail: String { + switch self { + case .ctx: + return CTXConstants.supportEmail + case .piggyCards: + return "" // TODO: Confirm correct support email + } + } + + func isUserSignedIn() -> Bool { + switch self { + case .ctx: + return CTXSpendService.shared.isUserSignedIn + case .piggyCards: + // TODO: Implement PiggyCards authentication + return false + } + } +} diff --git a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m index a7f171e16..15830fe78 100644 --- a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m +++ b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m @@ -47,6 +47,7 @@ + (NSString *)transactionURLFormat { + (NSString *)logoutURLString { return @"https://uphold.com/"; + } @end diff --git a/DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard b/DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard index 8bd5ca9c6..7ffac5521 100644 --- a/DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard +++ b/DashWallet/Sources/UI/DashPay/Voting/UsernameVoting.storyboard @@ -646,7 +646,7 @@ - + diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift index c9dbc8240..70840b30c 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/Details/PointOfUseDetailsViewController.swift @@ -139,11 +139,11 @@ extension PointOfUseDetailsViewController { vc.sellDashHandler = wSelf.sellDashHandler wSelf.navigationController?.pushViewController(vc, animated: true) } - detailsView.buyGiftCardHandler = { [weak self] in - self?.showDashSpendPayScreen() + detailsView.buyGiftCardHandler = { [weak self] provider in + self?.showDashSpendPayScreen(provider: provider) } - detailsView.dashSpendAuthHandler = { [weak self] in - self?.showCTXSpendLoginInfo() + detailsView.dashSpendAuthHandler = { [weak self] provider in + self?.showDashSpendLoginInfo(provider: provider) } detailsView.translatesAutoresizingMaskIntoConstraints = false @@ -181,20 +181,23 @@ extension PointOfUseDetailsViewController { // Mark: DashSpend extension PointOfUseDetailsViewController { - private func showCTXSpendLoginInfo() { - let swiftUIView = CTXSpendLoginInfoView( + // TODO: This is a temporary UI element for testing/selecting between services + // Will be removed once service selection is finalized + private func showDashSpendLoginInfo(provider: GiftCardProvider) { + let swiftUIView = DashSpendLoginInfoView( + provider: provider, onCreateNewAccount: { [weak self] in self?.dismiss(animated: true) { - self?.showCTXSpendTerms() + self?.showDashSpendTerms(provider: provider) } }, onLogIn: { [weak self] in self?.dismiss(animated: true) { - self?.showCTXSpendAuth(authType: .signIn) + self?.showDashSpendAuth(authType: .signIn, provider: provider) } }, onTermsAndConditions: { - UIApplication.shared.open(URL(string: CTXConstants.ctxGiftCardAgreementUrl)!, options: [:], completionHandler: nil) + UIApplication.shared.open(URL(string: provider.termsUrl)!, options: [:], completionHandler: nil) } ) let hostingController = UIHostingController(rootView: swiftUIView) @@ -202,31 +205,31 @@ extension PointOfUseDetailsViewController { self.present(hostingController, animated: true) } - private func showCTXSpendTerms() { + private func showDashSpendTerms(provider: GiftCardProvider) { let hostingController = UIHostingController( - rootView: CTXSpendTermsScreen { + rootView: DashSpendTermsScreen(provider: provider) { self.navigationController?.popToViewController(ofType: PointOfUseDetailsViewController.self, animated: false) - self.showDashSpendPayScreen(justAuthenticated: true) + self.showDashSpendPayScreen(provider: provider, justAuthenticated: true) } ) hostingController.modalPresentationStyle = .fullScreen self.navigationController?.pushViewController(hostingController, animated: true) } - private func showCTXSpendAuth(authType: CTXSpendUserAuthType) { + private func showDashSpendAuth(authType: DashSpendUserAuthType, provider: GiftCardProvider) { let hostingController = UIHostingController( - rootView: CTXSpendUserAuthScreen(authType: authType) { + rootView: DashSpendUserAuthScreen(authType: authType) { self.navigationController?.popViewController(animated: false) - self.showDashSpendPayScreen(justAuthenticated: true) + self.showDashSpendPayScreen(provider: provider, justAuthenticated: true) } ) self.navigationController?.pushViewController(hostingController, animated: true) } - private func showDashSpendPayScreen(justAuthenticated: Bool = false) { + private func showDashSpendPayScreen(provider: GiftCardProvider, justAuthenticated: Bool = false) { let hostingController = UIHostingController( - rootView: DashSpendPayScreen(merchant: self.pointOfUse, justAuthenticated: justAuthenticated) { [weak self] txId in + rootView: DashSpendPayScreen(merchant: self.pointOfUse, provider: provider, justAuthenticated: justAuthenticated) { [weak self] txId in // Navigate back to home and show gift card details self?.onGiftCardPurchased?(txId) } 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 b0339c7bf..b48623ea2 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 @@ -32,8 +32,8 @@ class PointOfUseDetailsView: UIView, SyncingActivityMonitorObserver, NetworkReac public var payWithDashHandler: (()->())? public var sellDashHandler: (()->())? - public var dashSpendAuthHandler: (()->())? - public var buyGiftCardHandler: (()->())? + public var dashSpendAuthHandler: ((GiftCardProvider)->())? + public var buyGiftCardHandler: ((GiftCardProvider)->())? public var showAllLocationsActionBlock: (() -> ())? var containerView: UIStackView! @@ -47,6 +47,8 @@ class PointOfUseDetailsView: UIView, SyncingActivityMonitorObserver, NetworkReac var subLabel: UILabel! var addressLabel: UILabel! private var payButton: ActionButton! + private var piggyCardsCheckbox: UISwitch? + private var selectedProvider: GiftCardProvider = .piggyCards internal let merchant: ExplorePointOfUse internal var isShowAllHidden: Bool @@ -155,10 +157,10 @@ class PointOfUseDetailsView: UIView, SyncingActivityMonitorObserver, NetworkReac UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url) } else if case .merchant(let m) = merchant.category, m.paymentMethod == .giftCard { - if ctxSpendService.isUserSignedIn { - buyGiftCardHandler?() + if selectedProvider.isUserSignedIn() { + buyGiftCardHandler?(selectedProvider) } else { - dashSpendAuthHandler?() + dashSpendAuthHandler?(selectedProvider) } } else { payWithDashHandler?() @@ -340,6 +342,11 @@ extension PointOfUseDetailsView { @objc internal func configureBottomButton() { + // Add PiggyCards checkbox for CTXSpend merchants (temporary UI element) + if case .merchant(let m) = merchant.category, m.paymentMethod == .giftCard { + configurePiggyCardsCheckbox() + } + payButton = ActionButton() payButton.translatesAutoresizingMaskIntoConstraints = false payButton.addTarget(self, action: #selector(payAction), for: .touchUpInside) @@ -380,6 +387,36 @@ extension PointOfUseDetailsView { updateButtonState() } + private func configurePiggyCardsCheckbox() { + // TODO: This is a temporary UI element for testing PiggyCards + // Change to false to enable service selection + + let checkboxContainer = UIStackView() + checkboxContainer.axis = .horizontal + checkboxContainer.spacing = 8 + checkboxContainer.alignment = .center + + piggyCardsCheckbox = UISwitch() + piggyCardsCheckbox?.isOn = true + piggyCardsCheckbox?.addTarget(self, action: #selector(piggyCardsCheckboxTapped), for: .touchUpInside) + + let label = UILabel() + label.text = "Open PiggyCards" + label.font = .dw_font(forTextStyle: .footnote) + label.textColor = .dw_secondaryText() + + checkboxContainer.addArrangedSubview(piggyCardsCheckbox!) + checkboxContainer.addArrangedSubview(label) + checkboxContainer.addArrangedSubview(UIView()) // Spacer + + containerView.addArrangedSubview(checkboxContainer) + } + + @objc + private func piggyCardsCheckboxTapped() { + selectedProvider = piggyCardsCheckbox?.isOn == true ? .piggyCards : .ctx + } + private static func getEmailText() -> String { if let email = CTXSpendService.shared.userEmail, !email.isEmpty { let maskedEmail = maskEmail(email) diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift index 571e37294..eef02cf47 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendTermsScreen.swift @@ -17,13 +17,14 @@ import SwiftUI -struct CTXSpendTermsScreen: View { +struct DashSpendTermsScreen: View { @Environment(\.presentationMode) private var presentationMode @State private var isTermsAccepted: Bool = false @State private var hasViewedTerms: Bool = false @State private var shouldShakeLink: Bool = false @State private var navigateToCreateAccount: Bool = false + let provider: GiftCardProvider let onAuthSuccess: () -> Void var body: some View { @@ -53,7 +54,7 @@ struct CTXSpendTermsScreen: View { label: NSLocalizedString("Terms & conditions", comment: "Terms & conditions"), labelIcon: .custom("external.link"), linkAction: { - UIApplication.shared.open(URL(string: CTXConstants.ctxGiftCardAgreementUrl)!, options: [:], completionHandler: nil) + UIApplication.shared.open(URL(string: provider.termsUrl)!, options: [:], completionHandler: nil) hasViewedTerms = true shouldShakeLink = false }, @@ -116,7 +117,7 @@ struct CTXSpendTermsScreen: View { .edgesIgnoringSafeArea(.top) NavigationLink( - destination: CTXSpendUserAuthScreen( + destination: DashSpendUserAuthScreen( authType: .createAccount, onAuthSuccess: onAuthSuccess ).navigationBarHidden(true), diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift index be1ebe0c8..085ae6e7c 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthScreen.swift @@ -18,7 +18,7 @@ import SwiftUI import Combine -enum CTXSpendUserAuthType { +enum DashSpendUserAuthType { case createAccount case signIn case otp @@ -55,13 +55,13 @@ enum CTXSpendUserAuthType { } } -struct CTXSpendUserAuthScreen: View { +struct DashSpendUserAuthScreen: View { @Environment(\.presentationMode) private var presentationMode - @StateObject private var viewModel = CTXSpendUserAuthViewModel() + @StateObject private var viewModel = DashSpendUserAuthViewModel() @FocusState private var isTextFieldFocused: Bool @State private var navigateToOtp: Bool = false - let authType: CTXSpendUserAuthType + let authType: DashSpendUserAuthType let onAuthSuccess: () -> Void var body: some View { @@ -172,7 +172,7 @@ struct CTXSpendUserAuthScreen: View { } NavigationLink( - destination: CTXSpendUserAuthScreen( + destination: DashSpendUserAuthScreen( authType: .otp, onAuthSuccess: onAuthSuccess ).navigationBarHidden(true), diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendLoginInfoView.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendLoginInfoView.swift similarity index 92% rename from DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendLoginInfoView.swift rename to DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendLoginInfoView.swift index 1512ab232..7a789f4e1 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendLoginInfoView.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendLoginInfoView.swift @@ -17,7 +17,8 @@ import SwiftUI -struct CTXSpendLoginInfoView: View { +struct DashSpendLoginInfoView: View { + let provider: GiftCardProvider let onCreateNewAccount: () -> Void let onLogIn: () -> Void let onTermsAndConditions: () -> Void @@ -27,7 +28,7 @@ struct CTXSpendLoginInfoView: View { BottomSheet(showBackButton: .constant(false)) { VStack { TextIntro( - icon: .custom("ctx.logo", maxHeight: 60), + icon: .custom(provider.logoName, maxHeight: 60), inProgress: $inProgress ) { FeatureTopText( @@ -59,7 +60,8 @@ struct CTXSpendLoginInfoView: View { } #Preview { - CTXSpendLoginInfoView( + DashSpendLoginInfoView( + provider: .ctx, onCreateNewAccount: {}, onLogIn: {}, onTermsAndConditions: {} diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift index 675ae4b44..e36fb9a60 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayScreen.swift @@ -22,6 +22,7 @@ struct DashSpendPayScreen: View { @Environment(\.presentationMode) private var presentationMode @StateObject private var viewModel: DashSpendPayViewModel let merchant: ExplorePointOfUse + let provider: GiftCardProvider @State var justAuthenticated: Bool @State var showConfirmToast: Bool @State private var showConfirmationDialog = false @@ -31,9 +32,10 @@ struct DashSpendPayScreen: View { @State private var errorTitle = "" let onPurchaseSuccess: ((Data) -> Void)? - init(merchant: ExplorePointOfUse, justAuthenticated: Bool = false, onPurchaseSuccess: ((Data) -> Void)? = nil) { + init(merchant: ExplorePointOfUse, provider: GiftCardProvider = .ctx, justAuthenticated: Bool = false, onPurchaseSuccess: ((Data) -> Void)? = nil) { self.merchant = merchant - self._viewModel = .init(wrappedValue: DashSpendPayViewModel(merchant: merchant)) + self.provider = provider + self._viewModel = .init(wrappedValue: DashSpendPayViewModel(merchant: merchant, provider: provider)) self.justAuthenticated = justAuthenticated self.showConfirmToast = false self.onPurchaseSuccess = onPurchaseSuccess diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift index e5fff3828..15c3e7f4f 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendPayViewModel.swift @@ -25,6 +25,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand private var cancellableBag = Set() private let fiatFormatter = NumberFormatter.fiatFormatter(currencyCode: defaultCurrency) private let ctxSpendService = CTXSpendService.shared + private let giftCardProvider: GiftCardProvider private let customIconProvider = CustomIconMetadataProvider.shared private let txMetadataDao = TransactionMetadataDAOImpl.shared private let sendCoinsService = SendCoinsService() @@ -105,7 +106,8 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand var maximumLimitMessage: String { String.localizedStringWithFormat(NSLocalizedString("Max: %@", comment: "DashSpend"), fiatFormatter.string(for: maximumAmount) ?? "0.0" ) } var isMixing: Bool { CoinJoinService.shared.mixingState.isInProgress } - init(merchant: ExplorePointOfUse) { + init(merchant: ExplorePointOfUse, provider: GiftCardProvider = .ctx) { + self.giftCardProvider = provider merchantTitle = merchant.name merchantIconUrl = merchant.logoLocation ?? "" merchantUrl = merchant.website @@ -123,7 +125,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand super.init() // Initialize with current sign-in state - isUserSignedIn = ctxSpendService.isUserSignedIn + isUserSignedIn = provider.isUserSignedIn() // Set up network status change handler networkStatusDidChange = { [weak self] status in @@ -185,7 +187,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand } func contactCTXSupport() { - let subject = "CTX Issue: Spending Limit Problem" + let subject = "\(giftCardProvider.displayName) Issue: Spending Limit Problem" var body = "Merchant details\n" body += "name: \(merchantTitle)\n" @@ -205,7 +207,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand body += "Platform: iOS\n" body += "App version: \(Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown")\n" - if let emailURL = URL(string: "mailto:\(CTXConstants.supportEmail)?subject=\(subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")&body=\(body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") { + if let emailURL = URL(string: "mailto:\(giftCardProvider.supportEmail)?subject=\(subject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")&body=\(body.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") { UIApplication.shared.open(emailURL) } } @@ -253,7 +255,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand // MARK: - CTX Integration private func updateMerchantInfo() async { - guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { return } + guard !merchantId.isEmpty, giftCardProvider.isUserSignedIn() else { return } do { let merchantInfo = try await ctxSpendService.getMerchant(merchantId: merchantId) @@ -277,7 +279,7 @@ class DashSpendPayViewModel: NSObject, ObservableObject, NetworkReachabilityHand } private func purchaseGiftCardAPI() async throws -> GiftCardResponse { - guard !merchantId.isEmpty, ctxSpendService.isUserSignedIn else { + guard !merchantId.isEmpty, giftCardProvider.isUserSignedIn() else { DSLogger.log("Purchase gift card failed: User not signed in or merchant ID is empty") throw CTXSpendError.unauthorized } diff --git a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthViewModel.swift b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendUserAuthViewModel.swift similarity index 92% rename from DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthViewModel.swift rename to DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendUserAuthViewModel.swift index 61dd9da54..71badcdbf 100644 --- a/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/CTXSpendUserAuthViewModel.swift +++ b/DashWallet/Sources/UI/Explore Dash/Views/DashSpend/DashSpendUserAuthViewModel.swift @@ -19,17 +19,17 @@ import Foundation import Combine @MainActor -class CTXSpendUserAuthViewModel: ObservableObject { +class DashSpendUserAuthViewModel: ObservableObject { @Published var input = "" @Published var isLoading = false @Published var showError = false @Published var errorMessage = "" - @Published var screenType: CTXSpendUserAuthType = .createAccount + @Published var screenType: DashSpendUserAuthType = .createAccount @Published var isUserSignedIn: Bool = false private let service = CTXSpendService.shared - func setup(screenType: CTXSpendUserAuthType) { + func setup(screenType: DashSpendUserAuthType) { self.isUserSignedIn = service.isUserSignedIn self.screenType = screenType } @@ -68,7 +68,7 @@ class CTXSpendUserAuthViewModel: ObservableObject { } } - func isInputValid(authType: CTXSpendUserAuthType) -> Bool { + func isInputValid(authType: DashSpendUserAuthType) -> Bool { if authType == .otp { return !input.isEmpty }